ble_mesh: add proxy client functionality

This commit is contained in:
lly 2019-09-27 17:07:05 +08:00
parent c6286529eb
commit 287f80ec01
45 changed files with 2038 additions and 1045 deletions

View File

@ -362,8 +362,8 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/mesh_core/provisioner_beacon.c"
"esp_ble_mesh/mesh_core/provisioner_main.c"
"esp_ble_mesh/mesh_core/provisioner_prov.c"
"esp_ble_mesh/mesh_core/provisioner_proxy.c"
"esp_ble_mesh/mesh_core/proxy.c"
"esp_ble_mesh/mesh_core/proxy_client.c"
"esp_ble_mesh/mesh_core/proxy_server.c"
"esp_ble_mesh/mesh_core/settings.c"
"esp_ble_mesh/mesh_core/test.c"
"esp_ble_mesh/mesh_core/transport.c"

View File

@ -158,17 +158,28 @@ if BLE_MESH
Enable this option to support BLE Mesh Proxy protocol used by PB-GATT
and other proxy pdu transmission.
config BLE_MESH_GATT_PROXY
bool "BLE Mesh GATT Proxy Service"
config BLE_MESH_GATT_PROXY_SERVER
bool "BLE Mesh GATT Proxy Server"
select BLE_MESH_PROXY
default y if BLE_MESH_NODE
default n if BLE_MESH_PROVISIONER
help
This option enables support for Mesh GATT Proxy Service, i.e. the
ability to act as a proxy between a Mesh GATT Client and a Mesh network.
This option should be enabled if a node is going to be a Proxy Server.
config BLE_MESH_GATT_PROXY_CLIENT
bool "BLE Mesh GATT Proxy Client"
select BLE_MESH_PROXY
default n
help
This option enables support for Mesh GATT Proxy Client. The Proxy Client
can use the GATT bearer to send mesh messages to a node that supports the
advertising bearer.
config BLE_MESH_NODE_ID_TIMEOUT
int "Node Identity advertising timeout"
depends on BLE_MESH_GATT_PROXY
depends on BLE_MESH_GATT_PROXY_SERVER
range 1 60
default 60
help
@ -185,7 +196,7 @@ if BLE_MESH
config BLE_MESH_PROXY_FILTER_SIZE
int "Maximum number of filter entries per Proxy Client"
default 1
default 3 if BLE_MESH_GATT_PROXY
default 3 if BLE_MESH_GATT_PROXY_SERVER
range 1 32767
help
This option specifies how many Proxy Filter entries the local node supports.

View File

@ -106,7 +106,7 @@ static esp_err_t ble_mesh_send_msg(esp_ble_mesh_model_t *model,
arg.model_send.msg_timeout = msg_timeout;
}
status = (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_model_args_t), btc_ble_mesh_prov_arg_deep_copy)
status = (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_model_args_t), btc_ble_mesh_model_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
osi_free(msg_data);

View File

@ -61,3 +61,117 @@ esp_err_t esp_ble_mesh_proxy_gatt_disable(void)
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_proxy_client_connect(esp_bd_addr_t addr,
esp_ble_addr_type_t addr_type, uint16_t net_idx)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
if (!addr || addr_type > BLE_ADDR_TYPE_RANDOM) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROXY_CLIENT_CONNECT;
memcpy(arg.proxy_client_connect.addr, addr, ESP_BD_ADDR_LEN);
arg.proxy_client_connect.addr_type = addr_type;
arg.proxy_client_connect.net_idx = net_idx;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_proxy_client_disconnect(uint8_t conn_handle)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROXY_CLIENT_DISCONNECT;
arg.proxy_client_disconnect.conn_handle = conn_handle;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_proxy_client_set_filter_type(uint8_t conn_handle,
uint16_t net_idx, uint8_t filter_type)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
if (filter_type > 0x01) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROXY_CLIENT_SET_FILTER_TYPE;
arg.proxy_client_set_filter_type.conn_handle = conn_handle;
arg.proxy_client_set_filter_type.net_idx = net_idx;
arg.proxy_client_set_filter_type.filter_type = filter_type;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_proxy_client_add_filter_addr(uint8_t conn_handle,
uint16_t net_idx, uint16_t *addr, uint16_t addr_num)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
if (!addr || addr_num == 0) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROXY_CLIENT_ADD_FILTER_ADDR;
arg.proxy_client_add_filter_addr.conn_handle = conn_handle;
arg.proxy_client_add_filter_addr.net_idx = net_idx;
arg.proxy_client_add_filter_addr.addr_num = addr_num;
arg.proxy_client_add_filter_addr.addr = addr;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), btc_ble_mesh_prov_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_proxy_client_remove_filter_addr(uint8_t conn_handle,
uint16_t net_idx, uint16_t *addr, uint16_t addr_num)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
if (!addr || addr_num == 0) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROXY_CLIENT_REMOVE_FILTER_ADDR;
arg.proxy_client_remove_filter_addr.conn_handle = conn_handle;
arg.proxy_client_remove_filter_addr.net_idx = net_idx;
arg.proxy_client_remove_filter_addr.addr_num = addr_num;
arg.proxy_client_remove_filter_addr.addr = addr;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), btc_ble_mesh_prov_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@ -49,5 +49,70 @@ esp_err_t esp_ble_mesh_proxy_gatt_enable(void);
*/
esp_err_t esp_ble_mesh_proxy_gatt_disable(void);
/**
* @brief Proxy Client creates a connection with the Proxy Server.
*
* @param[in] addr: Device address of the Proxy Server.
* @param[in] addr_type: Device address type(public or static random).
* @param[in] net_idx: NetKey Index related with Network ID in the Mesh Proxy
* advertising packet.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_client_connect(esp_bd_addr_t addr,
esp_ble_addr_type_t addr_type, uint16_t net_idx);
/**
* @brief Proxy Client terminates a connection with the Proxy Server.
*
* @param[in] conn_handle: Proxy connection handle.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_client_disconnect(uint8_t conn_handle);
/**
* @brief Proxy Client sets the filter type of the Proxy Server.
*
* @param[in] conn_handle: Proxy connection handle.
* @param[in] net_idx: Corresponding NetKey Index.
* @param[in] filter_type: whitelist or blacklist.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_client_set_filter_type(uint8_t conn_handle,
uint16_t net_idx, uint8_t filter_type);
/**
* @brief Proxy Client adds address to the Proxy Server filter list.
*
* @param[in] conn_handle: Proxy connection handle.
* @param[in] net_idx: Corresponding NetKey Index.
* @param[in] addr: Pointer to the filter address.
* @param[in] addr_num: Number of the filter address.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_client_add_filter_addr(uint8_t conn_handle,
uint16_t net_idx, uint16_t *addr, uint16_t addr_num);
/**
* @brief Proxy Client removes address from the Proxy Server filter list.
*
* @param[in] conn_handle: Proxy connection handle.
* @param[in] net_idx: Corresponding NetKey Index.
* @param[in] addr: Pointer to the filter address.
* @param[in] addr_num: Number of the filter address.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_client_remove_filter_addr(uint8_t conn_handle,
uint16_t net_idx, uint16_t *addr, uint16_t addr_num);
#endif /* _ESP_BLE_MESH_PROXY_API_H_ */

View File

@ -22,7 +22,7 @@
#include "mesh_main.h"
#include "mesh.h"
#include "proxy.h"
#include "proxy_server.h"
#include "foundation.h"
#include "provisioner_main.h"
@ -1248,6 +1248,15 @@ typedef enum {
ESP_BLE_MESH_LPN_FRIENDSHIP_TERMINATE_EVT, /*!< Low Power Node terminates friendship event */
ESP_BLE_MESH_FRIEND_FRIENDSHIP_ESTABLISH_EVT, /*!< Friend Node establishes friendship event */
ESP_BLE_MESH_FRIEND_FRIENDSHIP_TERMINATE_EVT, /*!< Friend Node terminates friendship event */
ESP_BLE_MESH_PROXY_CLIENT_RECV_ADV_PKT_EVT, /*!< Proxy Client receives Network ID advertising packet event */
ESP_BLE_MESH_PROXY_CLIENT_CONNECTED_EVT, /*!< Proxy Client establishes connection successfully event */
ESP_BLE_MESH_PROXY_CLIENT_DISCONNECTED_EVT, /*!< Proxy Client terminates connection successfully event */
ESP_BLE_MESH_PROXY_CLIENT_RECV_FILTER_STATUS_EVT, /*!< Proxy Client receives Proxy Filter Status event */
ESP_BLE_MESH_PROXY_CLIENT_CONNECT_COMP_EVT, /*!< Proxy Client connect completion event */
ESP_BLE_MESH_PROXY_CLIENT_DISCONNECT_COMP_EVT, /*!< Proxy Client disconnect completion event */
ESP_BLE_MESH_PROXY_CLIENT_SET_FILTER_TYPE_COMP_EVT, /*!< Proxy Client set filter type completion event */
ESP_BLE_MESH_PROXY_CLIENT_ADD_FILTER_ADDR_COMP_EVT, /*!< Proxy Client add filter address completion event */
ESP_BLE_MESH_PROXY_CLIENT_REMOVE_FILTER_ADDR_COMP_EVT, /*!< Proxy Client remove filter address completion event */
ESP_BLE_MESH_PROV_EVT_MAX,
} esp_ble_mesh_prov_cb_event_t;
@ -1379,8 +1388,8 @@ typedef union {
*/
struct ble_mesh_provisioner_recv_unprov_adv_pkt_param {
uint8_t dev_uuid[16]; /*!< Device UUID of the unprovisoned device */
uint8_t addr[6]; /*!< Device address of the unprovisoned device */
esp_ble_mesh_addr_type_t addr_type; /*!< Device address type */
esp_ble_mesh_bd_addr_t addr; /*!< Device address of the unprovisoned device */
esp_ble_mesh_addr_type_t addr_type; /*!< Device address type */
uint16_t oob_info; /*!< OOB Info of the unprovisoned device */
uint8_t adv_type; /*!< Avertising type of the unprovisoned device */
esp_ble_mesh_prov_bearer_t bearer; /*!< Bearer of the unprovisoned device */
@ -1588,6 +1597,84 @@ typedef union {
ESP_BLE_MESH_FRND_FRIENDSHIP_TERMINATE_DISABLE, /*!< Friend feature disabled or corresponding NetKey is deleted */
} reason; /*!< Friendship terminated reason */
} frnd_friendship_terminate; /*!< Event parameter of ESP_BLE_MESH_FRIEND_FRIENDSHIP_TERMINATE_EVT */
/**
* @brief ESP_BLE_MESH_PROXY_CLIENT_RECV_ADV_PKT_EVT
*/
struct ble_mesh_proxy_client_recv_adv_pkt_param {
esp_bd_addr_t addr; /*!< Device address */
esp_ble_addr_type_t addr_type; /*!< Device address type */
uint16_t net_idx; /*!< Network ID related NetKey Index */
uint8_t net_id[8]; /*!< Network ID contained in the advertising packet */
} proxy_client_recv_adv_pkt; /*!< Event parameter of ESP_BLE_MESH_PROXY_CLIENT_RECV_ADV_PKT_EVT */
/**
* @brief ESP_BLE_MESH_PROXY_CLIENT_CONNECTED_EVT
*/
struct ble_mesh_proxy_client_connected_param {
esp_bd_addr_t addr; /*!< Device address of the Proxy Server */
esp_ble_addr_type_t addr_type; /*!< Device address type */
uint8_t conn_handle; /*!< Proxy connection handle */
uint16_t net_idx; /*!< Corresponding NetKey Index */
} proxy_client_connected; /*!< Event parameter of ESP_BLE_MESH_PROXY_CLIENT_CONNECTED_EVT */
/**
* @brief ESP_BLE_MESH_PROXY_CLIENT_DISCONNECTED_EVT
*/
struct ble_mesh_proxy_client_disconnected_param {
esp_bd_addr_t addr; /*!< Device address of the Proxy Server */
esp_ble_addr_type_t addr_type; /*!< Device address type */
uint8_t conn_handle; /*!< Proxy connection handle */
uint16_t net_idx; /*!< Corresponding NetKey Index */
uint8_t reason; /*!< Proxy disconnect reason */
} proxy_client_disconnected; /*!< Event parameter of ESP_BLE_MESH_PROXY_CLIENT_DISCONNECTED_EVT */
/**
* @brief ESP_BLE_MESH_PROXY_CLIENT_RECV_FILTER_STATUS_EVT
*/
struct ble_mesh_proxy_client_recv_filter_status_param {
uint8_t conn_handle; /*!< Proxy connection handle */
uint16_t server_addr; /*!< Proxy Server primary element address */
uint16_t net_idx; /*!< Corresponding NetKey Index */
uint8_t filter_type; /*!< Proxy Server filter type(whitelist or blacklist) */
uint16_t list_size; /*!< Number of addresses in the Proxy Server filter list */
} proxy_client_recv_filter_status; /*!< Event parameter of ESP_BLE_MESH_PROXY_CLIENT_RECV_FILTER_STATUS_EVT */
/**
* @brief ESP_BLE_MESH_PROXY_CLIENT_CONNECT_COMP_EVT
*/
struct ble_mesh_proxy_client_connect_comp_param {
int err_code; /*!< Indicate the result of Proxy Client connect */
esp_bd_addr_t addr; /*!< Device address of the Proxy Server */
esp_ble_addr_type_t addr_type; /*!< Device address type */
uint16_t net_idx; /*!< Corresponding NetKey Index */
} proxy_client_connect_comp; /*!< Event parameter of ESP_BLE_MESH_PROXY_CLIENT_CONNECT_COMP_EVT */
/**
* @brief ESP_BLE_MESH_PROXY_CLIENT_DISCONNECT_COMP_EVT
*/
struct ble_mesh_proxy_client_disconnect_comp_param {
int err_code; /*!< Indicate the result of Proxy Client disconnect */
uint8_t conn_handle; /*!< Proxy connection handle */
} proxy_client_disconnect_comp; /*!< Event parameter of ESP_BLE_MESH_PROXY_CLIENT_DISCONNECT_COMP_EVT */
/**
* @brief ESP_BLE_MESH_PROXY_CLIENT_SET_FILTER_TYPE_COMP_EVT
*/
struct ble_mesh_proxy_client_set_filter_type_comp_param {
int err_code; /*!< Indicate the result of Proxy Client set filter type */
uint8_t conn_handle; /*!< Proxy connection handle */
uint16_t net_idx; /*!< Corresponding NetKey Index */
} proxy_client_set_filter_type_comp; /*!< Event parameter of ESP_BLE_MESH_PROXY_CLIENT_SET_FILTER_TYPE_COMP_EVT */
/**
* @brief ESP_BLE_MESH_PROXY_CLIENT_ADD_FILTER_ADDR_COMP_EVT
*/
struct ble_mesh_proxy_client_add_filter_addr_comp_param {
int err_code; /*!< Indicate the result of Proxy Client add filter address */
uint8_t conn_handle; /*!< Proxy connection handle */
uint16_t net_idx; /*!< Corresponding NetKey Index */
} proxy_client_add_filter_addr_comp; /*!< Event parameter of ESP_BLE_MESH_PROXY_CLIENT_ADD_FILTER_ADDR_COMP_EVT */
/**
* @brief ESP_BLE_MESH_PROXY_CLIENT_REMOVE_FILTER_ADDR_COMP_EVT
*/
struct ble_mesh_proxy_client_remove_filter_addr_comp_param {
int err_code; /*!< Indicate the result of Proxy Client remove filter address */
uint8_t conn_handle; /*!< Proxy connection handle */
uint16_t net_idx; /*!< Corresponding NetKey Index */
} proxy_client_remove_filter_addr_comp; /*!< Event parameter of ESP_BLE_MESH_PROXY_CLIENT_REMOVE_FILTER_ADDR_COMP_EVT */
} esp_ble_mesh_prov_cb_param_t;
/**

View File

@ -37,8 +37,9 @@
#include "mesh.h"
#include "access.h"
#include "transport.h"
#include "proxy.h"
#include "proxy_server.h"
#include "prov.h"
#include "proxy_client.h"
#include "provisioner_prov.h"
#include "provisioner_main.h"
@ -82,6 +83,70 @@ static inline void btc_ble_mesh_model_cb_to_app(esp_ble_mesh_model_cb_event_t ev
}
void btc_ble_mesh_prov_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
btc_ble_mesh_prov_args_t *dst = (btc_ble_mesh_prov_args_t *)p_dest;
btc_ble_mesh_prov_args_t *src = (btc_ble_mesh_prov_args_t *)p_src;
if (!msg || !dst || !src) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
switch (msg->act) {
case BTC_BLE_MESH_ACT_PROXY_CLIENT_ADD_FILTER_ADDR:
LOG_DEBUG("%s, BTC_BLE_MESH_ACT_PROXY_CLIENT_ADD_FILTER_ADDR", __func__);
dst->proxy_client_add_filter_addr.addr = (uint16_t *)osi_calloc(src->proxy_client_add_filter_addr.addr_num << 1);
if (dst->proxy_client_add_filter_addr.addr) {
memcpy(dst->proxy_client_add_filter_addr.addr, src->proxy_client_add_filter_addr.addr,
src->proxy_client_add_filter_addr.addr_num << 1);
} else {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
}
break;
case BTC_BLE_MESH_ACT_PROXY_CLIENT_REMOVE_FILTER_ADDR:
LOG_DEBUG("%s, BTC_BLE_MESH_ACT_PROXY_CLIENT_REMOVE_FILTER_ADDR", __func__);
dst->proxy_client_remove_filter_addr.addr = osi_calloc(src->proxy_client_remove_filter_addr.addr_num << 1);
if (dst->proxy_client_remove_filter_addr.addr) {
memcpy(dst->proxy_client_remove_filter_addr.addr, src->proxy_client_remove_filter_addr.addr,
src->proxy_client_remove_filter_addr.addr_num << 1);
} else {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
}
break;
default:
LOG_DEBUG("%s, Unknown deep copy act %d", __func__, msg->act);
break;
}
}
static void btc_ble_mesh_prov_arg_deep_free(btc_msg_t *msg)
{
btc_ble_mesh_prov_args_t *arg = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
arg = (btc_ble_mesh_prov_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_PROXY_CLIENT_ADD_FILTER_ADDR:
if (arg->proxy_client_add_filter_addr.addr) {
osi_free(arg->proxy_client_add_filter_addr.addr);
}
break;
case BTC_BLE_MESH_ACT_PROXY_CLIENT_REMOVE_FILTER_ADDR:
if (arg->proxy_client_remove_filter_addr.addr) {
osi_free(arg->proxy_client_remove_filter_addr.addr);
}
break;
default:
break;
}
}
void btc_ble_mesh_model_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
btc_ble_mesh_model_args_t *dst = (btc_ble_mesh_model_args_t *)p_dest;
btc_ble_mesh_model_args_t *src = (btc_ble_mesh_model_args_t *)p_src;
@ -117,7 +182,7 @@ void btc_ble_mesh_prov_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
}
}
static void btc_ble_mesh_prov_arg_deep_free(btc_msg_t *msg)
static void btc_ble_mesh_model_arg_deep_free(btc_msg_t *msg)
{
btc_ble_mesh_model_args_t *arg = NULL;
@ -958,6 +1023,134 @@ static void btc_ble_mesh_heartbeat_msg_recv_cb(u8_t hops, u16_t feature)
return;
}
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
static void btc_ble_mesh_proxy_client_adv_recv_cb(const bt_mesh_addr_t *addr,
u8_t type, bt_mesh_proxy_adv_ctx_t *ctx)
{
esp_ble_mesh_prov_cb_param_t mesh_param = {0};
btc_msg_t msg = {0};
bt_status_t ret;
if (!addr || !ctx || type != BLE_MESH_PROXY_ADV_NET_ID) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
LOG_DEBUG("%s", __func__);
mesh_param.proxy_client_recv_adv_pkt.addr_type = addr->type;
memcpy(mesh_param.proxy_client_recv_adv_pkt.addr, addr->val, ESP_BD_ADDR_LEN);
mesh_param.proxy_client_recv_adv_pkt.net_idx = ctx->net_id.net_idx;
memcpy(mesh_param.proxy_client_recv_adv_pkt.net_id, ctx->net_id.net_id, 8);
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_PROV;
msg.act = ESP_BLE_MESH_PROXY_CLIENT_RECV_ADV_PKT_EVT;
ret = btc_transfer_context(&msg, &mesh_param,
sizeof(esp_ble_mesh_prov_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed", __func__);
}
return;
}
static void btc_ble_mesh_proxy_client_connect_cb(const bt_mesh_addr_t *addr,
u8_t conn_handle, u16_t net_idx)
{
esp_ble_mesh_prov_cb_param_t mesh_param = {0};
btc_msg_t msg = {0};
bt_status_t ret;
if (!addr || conn_handle >= BLE_MESH_MAX_CONN) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
LOG_DEBUG("%s", __func__);
mesh_param.proxy_client_connected.addr_type = addr->type;
memcpy(mesh_param.proxy_client_connected.addr, addr->val, ESP_BD_ADDR_LEN);
mesh_param.proxy_client_connected.conn_handle = conn_handle;
mesh_param.proxy_client_connected.net_idx = net_idx;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_PROV;
msg.act = ESP_BLE_MESH_PROXY_CLIENT_CONNECTED_EVT;
ret = btc_transfer_context(&msg, &mesh_param,
sizeof(esp_ble_mesh_prov_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed", __func__);
}
return;
}
static void btc_ble_mesh_proxy_client_disconnect_cb(const bt_mesh_addr_t *addr,
u8_t conn_handle, u16_t net_idx, u8_t reason)
{
esp_ble_mesh_prov_cb_param_t mesh_param = {0};
btc_msg_t msg = {0};
bt_status_t ret;
if (!addr || conn_handle >= BLE_MESH_MAX_CONN) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
LOG_DEBUG("%s", __func__);
mesh_param.proxy_client_disconnected.addr_type = addr->type;
memcpy(mesh_param.proxy_client_disconnected.addr, addr->val, ESP_BD_ADDR_LEN);
mesh_param.proxy_client_disconnected.conn_handle = conn_handle;
mesh_param.proxy_client_disconnected.net_idx = net_idx;
mesh_param.proxy_client_disconnected.reason = reason;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_PROV;
msg.act = ESP_BLE_MESH_PROXY_CLIENT_DISCONNECTED_EVT;
ret = btc_transfer_context(&msg, &mesh_param,
sizeof(esp_ble_mesh_prov_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed", __func__);
}
return;
}
static void btc_ble_mesh_proxy_client_filter_status_recv_cb(u8_t conn_handle,
u16_t src, u16_t net_idx, u8_t filter_type, u16_t list_size)
{
esp_ble_mesh_prov_cb_param_t mesh_param = {0};
btc_msg_t msg = {0};
bt_status_t ret;
if (conn_handle >= BLE_MESH_MAX_CONN) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
LOG_DEBUG("%s", __func__);
mesh_param.proxy_client_recv_filter_status.conn_handle = conn_handle;
mesh_param.proxy_client_recv_filter_status.server_addr = src;
mesh_param.proxy_client_recv_filter_status.net_idx = net_idx;
mesh_param.proxy_client_recv_filter_status.filter_type = filter_type;
mesh_param.proxy_client_recv_filter_status.list_size = list_size;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_PROV;
msg.act = ESP_BLE_MESH_PROXY_CLIENT_RECV_FILTER_STATUS_EVT;
ret = btc_transfer_context(&msg, &mesh_param,
sizeof(esp_ble_mesh_prov_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed", __func__);
}
return;
}
#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
int btc_ble_mesh_client_model_init(esp_ble_mesh_model_t *model)
{
__ASSERT(model && model->op, "%s, Invalid parameter", __func__);
@ -1309,6 +1502,12 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
arg->mesh_init.prov->provisioner_prov_comp = (esp_ble_mesh_cb_t)btc_ble_mesh_provisioner_prov_complete_cb;
bt_mesh_prov_adv_pkt_cb_register(btc_ble_mesh_provisioner_recv_unprov_adv_pkt_cb);
#endif /* CONFIG_BLE_MESH_PROVISIONER */
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
bt_mesh_proxy_client_set_adv_recv_cb(btc_ble_mesh_proxy_client_adv_recv_cb);
bt_mesh_proxy_client_set_conn_cb(btc_ble_mesh_proxy_client_connect_cb);
bt_mesh_proxy_client_set_disconn_cb(btc_ble_mesh_proxy_client_disconnect_cb);
bt_mesh_proxy_client_set_filter_status_cb(btc_ble_mesh_proxy_client_filter_status_recv_cb);
#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
err_code = bt_mesh_init((struct bt_mesh_prov *)arg->mesh_init.prov,
(struct bt_mesh_comp *)arg->mesh_init.comp);
/* Give the semaphore when BLE Mesh initialization is finished. */
@ -1350,7 +1549,7 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
act = ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT;
param.node_set_unprov_dev_name_comp.err_code = bt_mesh_set_device_name(arg->set_device_name.name);
break;
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
case BTC_BLE_MESH_ACT_PROXY_IDENTITY_ENABLE:
act = ESP_BLE_MESH_NODE_PROXY_IDENTITY_ENABLE_COMP_EVT;
param.node_proxy_identity_enable_comp.err_code = bt_mesh_proxy_identity_enable();
@ -1363,7 +1562,7 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
act = ESP_BLE_MESH_NODE_PROXY_GATT_DISABLE_COMP_EVT;
param.node_proxy_gatt_disable_comp.err_code = bt_mesh_proxy_gatt_disable();
break;
#endif /* CONFIG_BLE_MESH_GATT_PROXY */
#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */
#endif /* CONFIG_BLE_MESH_NODE */
#if CONFIG_BLE_MESH_PROVISIONER
case BTC_BLE_MESH_ACT_PROVISIONER_READ_OOB_PUB_KEY:
@ -1529,12 +1728,74 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
param.lpn_poll_comp.err_code = bt_mesh_lpn_poll();
break;
#endif /* CONFIG_BLE_MESH_LOW_POWER */
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
case BTC_BLE_MESH_ACT_PROXY_CLIENT_CONNECT:
act = ESP_BLE_MESH_PROXY_CLIENT_CONNECT_COMP_EVT;
memcpy(param.proxy_client_connect_comp.addr, arg->proxy_client_connect.addr, ESP_BD_ADDR_LEN);
param.proxy_client_connect_comp.addr_type = arg->proxy_client_connect.addr_type;
param.proxy_client_connect_comp.net_idx = arg->proxy_client_connect.net_idx;
param.proxy_client_connect_comp.err_code =
bt_mesh_proxy_client_connect(arg->proxy_client_connect.addr,
arg->proxy_client_connect.addr_type,
arg->proxy_client_connect.net_idx);
break;
case BTC_BLE_MESH_ACT_PROXY_CLIENT_DISCONNECT:
act = ESP_BLE_MESH_PROXY_CLIENT_DISCONNECT_COMP_EVT;
param.proxy_client_disconnect_comp.conn_handle = arg->proxy_client_disconnect.conn_handle;
param.proxy_client_disconnect_comp.err_code =
bt_mesh_proxy_client_disconnect(arg->proxy_client_disconnect.conn_handle);
break;
case BTC_BLE_MESH_ACT_PROXY_CLIENT_SET_FILTER_TYPE: {
struct bt_mesh_proxy_cfg_pdu pdu = {
.opcode = BLE_MESH_PROXY_CFG_FILTER_SET,
.set.filter_type = arg->proxy_client_set_filter_type.filter_type,
};
act = ESP_BLE_MESH_PROXY_CLIENT_SET_FILTER_TYPE_COMP_EVT;
param.proxy_client_set_filter_type_comp.conn_handle = arg->proxy_client_set_filter_type.conn_handle;
param.proxy_client_set_filter_type_comp.net_idx = arg->proxy_client_set_filter_type.net_idx;
param.proxy_client_set_filter_type_comp.err_code =
bt_mesh_proxy_client_send_cfg(arg->proxy_client_set_filter_type.conn_handle,
arg->proxy_client_set_filter_type.net_idx, &pdu);
break;
}
case BTC_BLE_MESH_ACT_PROXY_CLIENT_ADD_FILTER_ADDR: {
struct bt_mesh_proxy_cfg_pdu pdu = {
.opcode = BLE_MESH_PROXY_CFG_FILTER_ADD,
.add.addr = arg->proxy_client_add_filter_addr.addr,
.add.addr_num = arg->proxy_client_add_filter_addr.addr_num,
};
act = ESP_BLE_MESH_PROXY_CLIENT_ADD_FILTER_ADDR_COMP_EVT;
param.proxy_client_add_filter_addr_comp.conn_handle = arg->proxy_client_add_filter_addr.conn_handle;
param.proxy_client_add_filter_addr_comp.net_idx = arg->proxy_client_add_filter_addr.net_idx;
param.proxy_client_add_filter_addr_comp.err_code =
bt_mesh_proxy_client_send_cfg(arg->proxy_client_add_filter_addr.conn_handle,
arg->proxy_client_add_filter_addr.net_idx, &pdu);
break;
}
case BTC_BLE_MESH_ACT_PROXY_CLIENT_REMOVE_FILTER_ADDR: {
struct bt_mesh_proxy_cfg_pdu pdu = {
.opcode = BLE_MESH_PROXY_CFG_FILTER_REMOVE,
.remove.addr = arg->proxy_client_remove_filter_addr.addr,
.remove.addr_num = arg->proxy_client_remove_filter_addr.addr_num,
};
act = ESP_BLE_MESH_PROXY_CLIENT_REMOVE_FILTER_ADDR_COMP_EVT;
param.proxy_client_remove_filter_addr_comp.conn_handle = arg->proxy_client_remove_filter_addr.conn_handle;
param.proxy_client_remove_filter_addr_comp.net_idx = arg->proxy_client_remove_filter_addr.net_idx;
param.proxy_client_remove_filter_addr_comp.err_code =
bt_mesh_proxy_client_send_cfg(arg->proxy_client_remove_filter_addr.conn_handle,
arg->proxy_client_remove_filter_addr.net_idx, &pdu);
break;
}
#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
default:
LOG_WARN("%s, Invalid msg->act %d", __func__, msg->act);
return;
}
/* Callback operation completion events */
btc_ble_mesh_prov_set_complete_cb(&param, act);
btc_ble_mesh_prov_arg_deep_free(msg);
return;
}
@ -1631,7 +1892,7 @@ void btc_ble_mesh_model_call_handler(btc_msg_t *msg)
break;
}
btc_ble_mesh_prov_arg_deep_free(msg);
btc_ble_mesh_model_arg_deep_free(msg);
return;
}

View File

@ -58,6 +58,11 @@ typedef enum {
BTC_BLE_MESH_ACT_LPN_ENABLE,
BTC_BLE_MESH_ACT_LPN_DISABLE,
BTC_BLE_MESH_ACT_LPN_POLL,
BTC_BLE_MESH_ACT_PROXY_CLIENT_CONNECT,
BTC_BLE_MESH_ACT_PROXY_CLIENT_DISCONNECT,
BTC_BLE_MESH_ACT_PROXY_CLIENT_SET_FILTER_TYPE,
BTC_BLE_MESH_ACT_PROXY_CLIENT_ADD_FILTER_ADDR,
BTC_BLE_MESH_ACT_PROXY_CLIENT_REMOVE_FILTER_ADDR,
} btc_ble_mesh_prov_act_t;
typedef enum {
@ -168,6 +173,31 @@ typedef union {
struct ble_mesh_lpn_poll_args {
/* RFU */
} lpn_poll;
struct ble_mesh_proxy_client_connect_args {
uint8_t addr[6];
uint8_t addr_type;
uint16_t net_idx;
} proxy_client_connect;
struct ble_mesh_proxy_client_disconnect_args {
uint8_t conn_handle;
} proxy_client_disconnect;
struct ble_mesh_proxy_client_set_filter_type_args {
uint8_t conn_handle;
uint16_t net_idx;
uint8_t filter_type;
} proxy_client_set_filter_type;
struct ble_mesh_proxy_client_add_filter_addr_args {
uint8_t conn_handle;
uint16_t net_idx;
uint16_t addr_num;
uint16_t *addr;
} proxy_client_add_filter_addr;
struct ble_mesh_proxy_client_remove_filter_addr_args {
uint8_t conn_handle;
uint16_t net_idx;
uint16_t addr_num;
uint16_t *addr;
} proxy_client_remove_filter_addr;
} btc_ble_mesh_prov_args_t;
typedef union {
@ -189,6 +219,8 @@ typedef union {
void btc_ble_mesh_prov_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_model_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
int btc_ble_mesh_client_model_init(esp_ble_mesh_model_t *model);
int32_t btc_ble_mesh_model_pub_period_get(esp_ble_mesh_model_t *mod);

View File

@ -30,10 +30,10 @@
#include "foundation.h"
#include "beacon.h"
#include "prov.h"
#include "proxy.h"
#include "proxy_server.h"
#include "provisioner_prov.h"
#include "provisioner_proxy.h"
#include "proxy_client.h"
#include "provisioner_beacon.h"
/* Convert from ms to 0.625ms units */
@ -472,11 +472,112 @@ const bt_mesh_addr_t *bt_mesh_pba_get_addr(void)
return dev_addr;
}
#if (CONFIG_BLE_MESH_PROVISIONER && COFNIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
static bool bt_mesh_is_adv_flags_valid(struct net_buf_simple *buf)
{
u8_t flags;
if (buf->len != 1U) {
BT_DBG("%s, Unexpected flags length", __func__);
return false;
}
flags = net_buf_simple_pull_u8(buf);
BT_DBG("Received adv pkt with flags: 0x%02x", flags);
/* Flags context will not be checked curently */
return true;
}
static bool bt_mesh_is_adv_srv_uuid_valid(struct net_buf_simple *buf, u16_t *uuid)
{
if (buf->len != 2U) {
BT_DBG("Length not match mesh service uuid");
return false;
}
*uuid = net_buf_simple_pull_le16(buf);
BT_DBG("Received adv pkt with service UUID: %d", *uuid);
if (*uuid != BLE_MESH_UUID_MESH_PROV_VAL &&
*uuid != BLE_MESH_UUID_MESH_PROXY_VAL) {
return false;
}
if (*uuid == BLE_MESH_UUID_MESH_PROV_VAL &&
bt_mesh_is_provisioner_en() == false) {
return false;
}
if (*uuid == BLE_MESH_UUID_MESH_PROXY_VAL &&
!IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)) {
return false;
}
return true;
}
#define BLE_MESH_PROV_SRV_DATA_LEN 0x12
#define BLE_MESH_PROXY_SRV_DATA_LEN1 0x09
#define BLE_MESH_PROXY_SRV_DATA_LEN2 0x11
static void bt_mesh_adv_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr, u16_t uuid)
{
u16_t type;
if (!buf || !addr) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
type = net_buf_simple_pull_le16(buf);
if (type != uuid) {
BT_DBG("%s, Invalid Mesh Service Data UUID 0x%04x", __func__, type);
return;
}
switch (type) {
#if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
case BLE_MESH_UUID_MESH_PROV_VAL:
if (bt_mesh_is_provisioner_en()) {
if (buf->len != BLE_MESH_PROV_SRV_DATA_LEN) {
BT_WARN("%s, Invalid Mesh Prov Service Data length %d", __func__, buf->len);
return;
}
BT_DBG("Start to handle Mesh Prov Service Data");
provisioner_prov_adv_ind_recv(buf, addr);
}
break;
#endif
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
case BLE_MESH_UUID_MESH_PROXY_VAL:
if (buf->len != BLE_MESH_PROXY_SRV_DATA_LEN1 &&
buf->len != BLE_MESH_PROXY_SRV_DATA_LEN2) {
BT_WARN("%s, Invalid Mesh Proxy Service Data length %d", __func__, buf->len);
return;
}
BT_DBG("Start to handle Mesh Proxy Service Data");
proxy_client_adv_ind_recv(buf, addr);
break;
#endif
default:
break;
}
}
#endif
static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi,
u8_t adv_type, struct net_buf_simple *buf)
{
#if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
u16_t uuid = 0;
#if (CONFIG_BLE_MESH_PROVISIONER && COFNIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
u16_t uuid;
#endif
if (adv_type != BLE_MESH_ADV_NONCONN_IND && adv_type != BLE_MESH_ADV_IND) {
@ -548,30 +649,24 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi,
}
#endif
break;
#if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
#if (CONFIG_BLE_MESH_PROVISIONER && COFNIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
case BLE_MESH_DATA_FLAGS:
if (bt_mesh_is_provisioner_en()) {
if (!provisioner_flags_match(buf)) {
BT_DBG("Flags mismatch, ignore this adv pkt");
return;
}
if (!bt_mesh_is_adv_flags_valid(buf)) {
BT_DBG("Adv Flags mismatch, ignore this adv pkt");
return;
}
break;
case BLE_MESH_DATA_UUID16_ALL:
if (bt_mesh_is_provisioner_en()) {
uuid = provisioner_srv_uuid_recv(buf);
if (!uuid) {
BT_DBG("Service UUID mismatch, ignore this adv pkt");
return;
}
if (!bt_mesh_is_adv_srv_uuid_valid(buf, &uuid)) {
BT_DBG("Adv Service UUID mismatch, ignore this adv pkt");
return;
}
break;
case BLE_MESH_DATA_SVC_DATA16:
if (bt_mesh_is_provisioner_en()) {
provisioner_srv_data_recv(buf, addr, uuid);
}
bt_mesh_adv_srv_data_recv(buf, addr, uuid);
break;
#endif /* CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT */
#endif
default:
break;
}

View File

@ -25,6 +25,7 @@
#include "crypto.h"
#include "beacon.h"
#include "foundation.h"
#include "proxy_client.h"
#if CONFIG_BLE_MESH_NODE
@ -138,6 +139,18 @@ static int secure_beacon_send(void)
continue;
}
/**
* If a node enables the Proxy Client functionality, and it
* succeeds to send Secure Network Beacon with GATT bearer,
* here we will continue to send Secure Network Beacon of
* other subnets.
*/
#if defined(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)
if (bt_mesh_proxy_client_beacon_send(sub)) {
continue;
}
#endif
buf = bt_mesh_adv_create(BLE_MESH_ADV_BEACON, PROV_XMIT,
K_NO_WAIT);
if (!buf) {

View File

@ -81,13 +81,13 @@ static future_t *future_mesh;
static struct bt_mesh_gatt_attr *bt_mesh_gatts_find_attr_by_handle(u16_t handle);
#endif /* defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE */
#if defined(CONFIG_BLE_MESH_PROVISIONER) && CONFIG_BLE_MESH_PROVISIONER
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
#define BLE_MESH_GATTC_APP_UUID_BYTE 0x97
static struct gattc_prov_info {
/* Service to be found depends on the type of adv pkt received */
struct bt_mesh_conn conn;
BD_ADDR addr;
u8_t addr_type;
bt_mesh_addr_t addr;
u16_t service_uuid;
u16_t mtu;
bool wr_desc_done; /* Indicate if write char descriptor event is received */
@ -99,7 +99,7 @@ static struct gattc_prov_info {
} bt_mesh_gattc_info[BLE_MESH_MAX_CONN];
static struct bt_mesh_prov_conn_cb *bt_mesh_gattc_conn_cb;
static tBTA_GATTC_IF bt_mesh_gattc_if;
#endif /* defined(CONFIG_BLE_MESH_PROVISIONER) && CONFIG_BLE_MESH_PROVISIONER */
#endif
esp_err_t bt_mesh_host_init(void)
{
@ -1013,27 +1013,40 @@ int bt_mesh_gatts_service_start(struct bt_mesh_gatt_service *svc)
}
#endif /* defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE */
#if defined(CONFIG_BLE_MESH_PROVISIONER) && CONFIG_BLE_MESH_PROVISIONER
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
void bt_mesh_gattc_conn_cb_register(struct bt_mesh_prov_conn_cb *cb)
{
bt_mesh_gattc_conn_cb = cb;
}
u16_t bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn *conn)
u8_t bt_mesh_gattc_get_free_conn_count(void)
{
int i;
u8_t count = 0;
u8_t i;
for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
if (conn == &bt_mesh_gattc_info[i].conn) {
break;
for (i = 0U; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
if (bt_mesh_gattc_info[i].conn.handle == 0xFFFF &&
bt_mesh_gattc_info[i].service_uuid == 0x0000) {
++count;
}
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
return 0;
return count;
}
u16_t bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn *conn)
{
u8_t i;
for (i = 0U; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
if (conn == &bt_mesh_gattc_info[i].conn) {
return bt_mesh_gattc_info[i].service_uuid;
}
}
return bt_mesh_gattc_info[i].service_uuid;
BT_ERR("%s, Conn is not found", __func__);
return 0;
}
/** For provisioner acting as a GATT client, it may follow the procedures
@ -1065,7 +1078,7 @@ int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, u16_t service_uuid)
/* Check if already creating connection with the device */
for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
if (!memcmp(bt_mesh_gattc_info[i].addr, addr->val, BLE_MESH_ADDR_LEN)) {
if (!memcmp(bt_mesh_gattc_info[i].addr.val, addr->val, BLE_MESH_ADDR_LEN)) {
BT_WARN("%s, Already create connection with %s",
__func__, bt_hex(addr->val, BLE_MESH_ADDR_LEN));
return -EALREADY;
@ -1076,8 +1089,8 @@ int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, u16_t service_uuid)
for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
if ((bt_mesh_gattc_info[i].conn.handle == 0xFFFF) &&
(bt_mesh_gattc_info[i].service_uuid == 0x0000)) {
memcpy(bt_mesh_gattc_info[i].addr, addr->val, BLE_MESH_ADDR_LEN);
bt_mesh_gattc_info[i].addr_type = addr->type;
memcpy(bt_mesh_gattc_info[i].addr.val, addr->val, BLE_MESH_ADDR_LEN);
bt_mesh_gattc_info[i].addr.type = addr->type;
/* Service to be found after exhanging mtu size */
bt_mesh_gattc_info[i].service_uuid = service_uuid;
break;
@ -1104,15 +1117,12 @@ int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, u16_t service_uuid)
* Slave_latency: 0x0
* Supervision_timeout: 32 sec
*/
BTA_DmSetBlePrefConnParams(bt_mesh_gattc_info[i].addr, 0xC8, 0xC8, 0x00, 0xC80);
BTA_DmSetBlePrefConnParams(bt_mesh_gattc_info[i].addr.val, 0xC8, 0xC8, 0x00, 0xC80);
BTA_GATTC_Open(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr,
bt_mesh_gattc_info[i].addr_type, true, BTA_GATT_TRANSPORT_LE);
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);
/* Increment pbg_count */
provisioner_pbg_count_inc();
return 0;
return i;
}
void bt_mesh_gattc_exchange_mtu(u8_t index)
@ -1149,24 +1159,16 @@ int bt_mesh_gattc_write_no_rsp(struct bt_mesh_conn *conn, const struct bt_mesh_g
for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
if (conn == &bt_mesh_gattc_info[i].conn) {
break;
conn_id = BLE_MESH_GATT_CREATE_CONN_ID(bt_mesh_gattc_if, bt_mesh_gattc_info[i].conn.handle);
BTA_GATTC_WriteCharValue(conn_id, bt_mesh_gattc_info[i].data_in_handle,
BTA_GATTC_TYPE_WRITE_NO_RSP, len,
(u8_t *)data, BTA_GATT_AUTH_REQ_NONE);
return 0;
}
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
BT_ERR("%s, Conn is not found", __func__);
/** Here we return 0 for prov_send() return value check in provisioner.c
*/
return 0;
}
conn_id = BLE_MESH_GATT_CREATE_CONN_ID(bt_mesh_gattc_if, bt_mesh_gattc_info[i].conn.handle);
BTA_GATTC_WriteCharValue(conn_id, bt_mesh_gattc_info[i].data_in_handle,
BTA_GATTC_TYPE_WRITE_NO_RSP, len,
(u8_t *)data, BTA_GATT_AUTH_REQ_NONE);
return 0;
BT_ERR("%s, Conn is not found", __func__);
return -EEXIST;
}
void bt_mesh_gattc_disconnect(struct bt_mesh_conn *conn)
@ -1184,18 +1186,14 @@ void bt_mesh_gattc_disconnect(struct bt_mesh_conn *conn)
for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
if (conn == &bt_mesh_gattc_info[i].conn) {
break;
conn_id = BLE_MESH_GATT_CREATE_CONN_ID(bt_mesh_gattc_if, bt_mesh_gattc_info[i].conn.handle);
BTA_GATTC_Close(conn_id);
return;
}
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
BT_ERR("%s, Conn is not found", __func__);
return;
}
conn_id = BLE_MESH_GATT_CREATE_CONN_ID(bt_mesh_gattc_if, bt_mesh_gattc_info[i].conn.handle);
BTA_GATTC_Close(conn_id);
BT_ERR("%s, Conn is not found", __func__);
return;
}
/** Mesh Provisioning Service: 0x1827
@ -1235,25 +1233,16 @@ 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) {
bt_mesh_gattc_info[i].mtu = p_data->cfg_mtu.mtu;
/* Search Mesh Provisioning Service or Mesh Proxy Service */
tBT_UUID service_uuid = {
.len = sizeof(bt_mesh_gattc_info[i].service_uuid),
.uu.uuid16 = bt_mesh_gattc_info[i].service_uuid,
};
BTA_GATTC_ServiceSearchRequest(p_data->cfg_mtu.conn_id, &service_uuid);
break;
}
}
/** Once mtu exchanged accomplished, start to find services, and here
* need a flag to indicate which service to find(Mesh Prov Service or
* Mesh Proxy Service)
*/
if (i != ARRAY_SIZE(bt_mesh_gattc_info)) {
tBT_UUID service_uuid;
u16_t conn_id;
conn_id = BLE_MESH_GATT_CREATE_CONN_ID(bt_mesh_gattc_if, bt_mesh_gattc_info[i].conn.handle);
service_uuid.len = sizeof(bt_mesh_gattc_info[i].service_uuid);
service_uuid.uu.uuid16 = bt_mesh_gattc_info[i].service_uuid;
/* Search Mesh Provisioning Service or Mesh Proxy Service */
BTA_GATTC_ServiceSearchRequest(conn_id, &service_uuid);
}
}
break;
}
@ -1264,15 +1253,12 @@ 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) {
break;
}
}
if (i != ARRAY_SIZE(bt_mesh_gattc_info)) {
if (p_data->srvc_res.service_uuid.uuid.len == 2 &&
if (p_data->srvc_res.service_uuid.uuid.len == 2 &&
p_data->srvc_res.service_uuid.uuid.uu.uuid16 == bt_mesh_gattc_info[i].service_uuid) {
bt_mesh_gattc_info[i].start_handle = p_data->srvc_res.start_handle;
bt_mesh_gattc_info[i].end_handle = p_data->srvc_res.end_handle;
bt_mesh_gattc_info[i].start_handle = p_data->srvc_res.start_handle;
bt_mesh_gattc_info[i].end_handle = p_data->srvc_res.end_handle;
}
break;
}
}
break;
@ -1285,37 +1271,35 @@ 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) {
conn = &bt_mesh_gattc_info[i].conn;
break;
}
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
if (conn == NULL) {
BT_ERR("%s, Conn handle is not found", __func__);
return;
}
conn = &bt_mesh_gattc_info[i].conn;
if (bt_mesh_gattc_info[i].start_handle == 0x00 ||
bt_mesh_gattc_info[i].end_handle == 0x00 ||
bt_mesh_gattc_info[i].end_handle == 0x00 ||
(bt_mesh_gattc_info[i].start_handle > bt_mesh_gattc_info[i].end_handle)) {
bt_mesh_gattc_disconnect(conn);
return;
}
u16_t notify_en = BLE_MESH_GATT_CCC_NOTIFY;
btgatt_db_element_t *result = NULL;
tBT_UUID char_uuid = {0};
tBTA_GATT_STATUS status;
tBTA_GATT_UNFMT write;
int count = 0;
int num = 0;
u16_t conn_id;
tBT_UUID char_uuid;
btgatt_db_element_t *result = NULL;
tBTA_GATT_STATUS status;
u16_t notify_en = BLE_MESH_GATT_CCC_NOTIFY;
tBTA_GATT_UNFMT write;
/* Get the characteristic num within Mesh Provisioning/Proxy Service */
conn_id = BLE_MESH_GATT_CREATE_CONN_ID(bt_mesh_gattc_if, bt_mesh_gattc_info[i].conn.handle);
BTA_GATTC_GetDBSizeByType(conn_id, BTGATT_DB_CHARACTERISTIC, bt_mesh_gattc_info[i].start_handle,
bt_mesh_gattc_info[i].end_handle, BTA_GATTC_INVALID_HANDLE, &count);
BTA_GATTC_GetDBSizeByType(p_data->search_cmpl.conn_id, BTGATT_DB_CHARACTERISTIC,
bt_mesh_gattc_info[i].start_handle, bt_mesh_gattc_info[i].end_handle,
BTA_GATTC_INVALID_HANDLE, &count);
if (count != 2) {
bt_mesh_gattc_disconnect(conn);
return;
@ -1333,7 +1317,7 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
char_uuid.uu.uuid16 = BLE_MESH_UUID_MESH_PROXY_DATA_IN_VAL + j;
}
BTA_GATTC_GetCharByUUID(conn_id, bt_mesh_gattc_info[i].start_handle,
BTA_GATTC_GetCharByUUID(p_data->search_cmpl.conn_id, bt_mesh_gattc_info[i].start_handle,
bt_mesh_gattc_info[i].end_handle, char_uuid, &result, &num);
if (!result) {
@ -1362,12 +1346,13 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
}
bt_mesh_gattc_info[i].data_out_handle = result[0].attribute_handle;
}
osi_free(result);
result = NULL;
}
/* Register Notification fot Mesh Provisioning/Proxy Data Out Characteristic */
status = BTA_GATTC_RegisterForNotifications(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr,
status = BTA_GATTC_RegisterForNotifications(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr.val,
bt_mesh_gattc_info[i].data_out_handle);
if (status != BTA_GATT_OK) {
bt_mesh_gattc_disconnect(conn);
@ -1377,8 +1362,9 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
/** After notification is registered, get descriptor number of the
* Mesh Provisioning/Proxy Data Out Characteristic
*/
BTA_GATTC_GetDBSizeByType(conn_id, BTGATT_DB_DESCRIPTOR, bt_mesh_gattc_info[i].start_handle,
bt_mesh_gattc_info[i].end_handle, bt_mesh_gattc_info[i].data_out_handle, &num);
BTA_GATTC_GetDBSizeByType(p_data->search_cmpl.conn_id, BTGATT_DB_DESCRIPTOR,
bt_mesh_gattc_info[i].start_handle, bt_mesh_gattc_info[i].end_handle,
bt_mesh_gattc_info[i].data_out_handle, &num);
if (!num) {
bt_mesh_gattc_disconnect(conn);
return;
@ -1387,9 +1373,8 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
/* Get CCC of Mesh Provisioning/Proxy Data Out Characteristic */
char_uuid.len = 2;
char_uuid.uu.uuid16 = BLE_MESH_UUID_GATT_CCC_VAL;
BTA_GATTC_GetDescrByCharHandle(conn_id, bt_mesh_gattc_info[i].data_out_handle,
BTA_GATTC_GetDescrByCharHandle(p_data->search_cmpl.conn_id, bt_mesh_gattc_info[i].data_out_handle,
char_uuid, &result, &num);
if (!result) {
bt_mesh_gattc_disconnect(conn);
return;
@ -1408,7 +1393,7 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
*/
write.len = sizeof(notify_en);
write.p_value = (u8_t *)&notify_en;
BTA_GATTC_WriteCharDescr(conn_id, result[0].attribute_handle,
BTA_GATTC_WriteCharDescr(p_data->search_cmpl.conn_id, result[0].attribute_handle,
BTA_GATTC_TYPE_WRITE, &write, BTA_GATT_AUTH_REQ_NONE);
osi_free(result);
@ -1426,17 +1411,16 @@ 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) {
conn = &bt_mesh_gattc_info[i].conn;
break;
}
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
if (conn == NULL) {
BT_ERR("%s, Conn handle is not found", __func__);
return;
}
conn = &bt_mesh_gattc_info[i].conn;
if (bt_mesh_gattc_info[i].ccc_handle != p_data->write.handle) {
BT_WARN("%s, gattc ccc_handle is not matched", __func__);
bt_mesh_gattc_disconnect(conn);
@ -1445,7 +1429,7 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
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_write_descr != NULL) {
len = bt_mesh_gattc_conn_cb->prov_write_descr(&bt_mesh_gattc_info[i].conn, bt_mesh_gattc_info[i].addr);
len = bt_mesh_gattc_conn_cb->prov_write_descr(&bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn);
if (len < 0) {
BT_ERR("%s, prov_write_descr failed", __func__);
bt_mesh_gattc_disconnect(conn);
@ -1455,12 +1439,13 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
}
} else if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROXY_VAL) {
if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->proxy_write_descr != NULL) {
len = bt_mesh_gattc_conn_cb->proxy_write_descr(&bt_mesh_gattc_info[i].conn);
len = bt_mesh_gattc_conn_cb->proxy_write_descr(&bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn);
if (len < 0) {
BT_ERR("%s, proxy_write_descr failed", __func__);
bt_mesh_gattc_disconnect(conn);
return;
}
bt_mesh_gattc_info[i].wr_desc_done = true;
}
}
}
@ -1473,18 +1458,22 @@ 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");
return;
}
conn = &bt_mesh_gattc_info[i].conn;
break;
}
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
if (conn == NULL) {
BT_ERR("%s, Conn handle is not found", __func__);
return;
}
conn = &bt_mesh_gattc_info[i].conn;
if (memcmp(bt_mesh_gattc_info[i].addr, p_data->notify.bda, BLE_MESH_ADDR_LEN) ||
if (memcmp(bt_mesh_gattc_info[i].addr.val, p_data->notify.bda, BLE_MESH_ADDR_LEN) ||
bt_mesh_gattc_info[i].data_out_handle != p_data->notify.handle ||
p_data->notify.is_notify == false) {
BT_ERR("%s, Notification error", __func__);
@ -1560,9 +1549,9 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->connected != NULL) {
for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
if (!memcmp(bt_mesh_gattc_info[i].addr, p_data->connect.remote_bda, BLE_MESH_ADDR_LEN)) {
if (!memcmp(bt_mesh_gattc_info[i].addr.val, p_data->connect.remote_bda, BLE_MESH_ADDR_LEN)) {
bt_mesh_gattc_info[i].conn.handle = BLE_MESH_GATT_GET_CONN_ID(p_data->connect.conn_id);
(bt_mesh_gattc_conn_cb->connected)(bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn, i);
(bt_mesh_gattc_conn_cb->connected)(&bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn, i);
break;
}
}
@ -1581,24 +1570,36 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->disconnected != NULL) {
for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
if (!memcmp(bt_mesh_gattc_info[i].addr, p_data->disconnect.remote_bda, BLE_MESH_ADDR_LEN)) {
if (!memcmp(bt_mesh_gattc_info[i].addr.val, p_data->disconnect.remote_bda, BLE_MESH_ADDR_LEN)) {
if (bt_mesh_gattc_info[i].conn.handle == handle) {
(bt_mesh_gattc_conn_cb->disconnected)(&bt_mesh_gattc_info[i].conn, p_data->disconnect.reason);
(bt_mesh_gattc_conn_cb->disconnected)(&bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn, p_data->disconnect.reason);
if (!bt_mesh_gattc_info[i].wr_desc_done) {
/* Add this in case connection is established, connected event comes, but
* connection is terminated before server->filter_type is set to PROV.
*/
provisioner_clear_link_conn_info(bt_mesh_gattc_info[i].addr);
#if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
provisioner_clear_link_conn_info(bt_mesh_gattc_info[i].addr.val);
}
#endif
}
} else {
/* Add this in case connection is failed to be established, and here we
* need to clear some provision link info, like connecting flag, device
* uuid, address info, etc.
*/
provisioner_clear_link_conn_info(bt_mesh_gattc_info[i].addr);
#if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
provisioner_clear_link_conn_info(bt_mesh_gattc_info[i].addr.val);
}
#endif
}
/* Decrease prov pbg_count */
provisioner_pbg_count_dec();
#if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
/* Decrease provisioner pbg_count */
provisioner_pbg_count_dec();
}
#endif
/* Reset corresponding gattc info */
memset(&bt_mesh_gattc_info[i], 0, sizeof(bt_mesh_gattc_info[i]));
bt_mesh_gattc_info[i].conn.handle = 0xFFFF;
@ -1618,7 +1619,7 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
break;
}
}
#endif /* defined(CONFIG_BLE_MESH_PROVISIONER) && CONFIG_BLE_MESH_PROVISIONER */
#endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
struct bt_mesh_conn *bt_mesh_conn_ref(struct bt_mesh_conn *conn)
{
@ -1648,7 +1649,8 @@ void bt_mesh_gatt_init(void)
BTA_GATTS_AppRegister(&app_uuid, bt_mesh_bta_gatts_cb);
#endif
#if CONFIG_BLE_MESH_PROVISIONER
#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 = GATT_DEF_BLE_MTU_SIZE; /* Default MTU_SIZE 23 */

View File

@ -29,7 +29,7 @@
#include "crypto.h"
#include "access.h"
#include "beacon.h"
#include "proxy.h"
#include "proxy_server.h"
#include "foundation.h"
#include "friend.h"
#include "settings.h"
@ -96,7 +96,7 @@ static int comp_get_page_0(struct net_buf_simple *buf)
feat |= BLE_MESH_FEAT_RELAY;
}
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY)) {
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
feat |= BLE_MESH_FEAT_PROXY;
}
@ -797,7 +797,7 @@ static void gatt_proxy_set(struct bt_mesh_model *model,
return;
}
if (!IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY) ||
if (!IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) ||
bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_NOT_SUPPORTED) {
goto send_status;
}
@ -2166,7 +2166,7 @@ static void net_key_add(struct bt_mesh_model *model,
/* Make sure we have valid beacon data to be sent */
bt_mesh_net_beacon_update(sub);
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY)) {
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
sub->node_id = BLE_MESH_NODE_IDENTITY_STOPPED;
#if CONFIG_BLE_MESH_NODE
bt_mesh_proxy_beacon_send(sub);
@ -2416,7 +2416,7 @@ static void node_identity_set(struct bt_mesh_model *model,
* 0x00, the Node Identity state for all subnets shall be set
* to 0x00 and shall not be changed."
*/
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY) &&
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED) {
if (node_id) {
bt_mesh_proxy_identity_start(sub);
@ -3295,7 +3295,7 @@ int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary)
cfg->frnd = BLE_MESH_FRIEND_NOT_SUPPORTED;
}
if (!IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY)) {
if (!IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
cfg->gatt_proxy = BLE_MESH_GATT_PROXY_NOT_SUPPORTED;
}

View File

@ -17,7 +17,8 @@
/* BLE Mesh Max Connection Count */
#ifdef CONFIG_BT_BLUEDROID_ENABLED
#define BLE_MESH_MAX_CONN CONFIG_BT_ACL_CONNECTIONS
#define BLE_MESH_MAX_CONN \
MIN(CONFIG_BT_ACL_CONNECTIONS, CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN)
#define ADV_TASK_CORE TASK_PINNED_TO_CORE
#endif
@ -481,15 +482,15 @@ struct bt_mesh_conn_cb {
};
struct bt_mesh_prov_conn_cb {
void (*connected)(const u8_t addr[6], struct bt_mesh_conn *conn, int id);
void (*connected)(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn, int id);
void (*disconnected)(struct bt_mesh_conn *conn, u8_t reason);
void (*disconnected)(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn, u8_t reason);
ssize_t (*prov_write_descr)(struct bt_mesh_conn *conn, u8_t *addr);
ssize_t (*prov_write_descr)(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn);
ssize_t (*prov_notify)(struct bt_mesh_conn *conn, u8_t *data, u16_t len);
ssize_t (*proxy_write_descr)(struct bt_mesh_conn *conn);
ssize_t (*proxy_write_descr)(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn);
ssize_t (*proxy_notify)(struct bt_mesh_conn *conn, u8_t *data, u16_t len);
};
@ -682,6 +683,8 @@ int bt_mesh_gatts_service_start(struct bt_mesh_gatt_service *svc);
void bt_mesh_gattc_conn_cb_register(struct bt_mesh_prov_conn_cb *cb);
u8_t bt_mesh_gattc_get_free_conn_count(void);
u16_t bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn *conn);
int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, u16_t service_uuid);

View File

@ -280,7 +280,6 @@ struct bt_mesh_prov {
*
* @param bearer Provisioning bearer.
* @param reason Provisioning link close reason(disconnect reason)
* 0xFF: disconnect due to provisioner_pb_gatt_disable()
*/
void (*prov_link_close)(bt_mesh_prov_bearer_t bearer, u8_t reason);

View File

@ -28,11 +28,11 @@
#include "transport.h"
#include "access.h"
#include "foundation.h"
#include "proxy.h"
#include "proxy_server.h"
#include "settings.h"
#include "mesh.h"
#include "provisioner_prov.h"
#include "provisioner_proxy.h"
#include "proxy_client.h"
#include "provisioner_main.h"
static volatile bool provisioner_en = false;
@ -127,7 +127,7 @@ void bt_mesh_reset(void)
bt_mesh_friend_clear_net_idx(BLE_MESH_KEY_ANY);
}
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY)) {
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
bt_mesh_proxy_gatt_disable();
}
@ -296,7 +296,7 @@ int bt_mesh_init(const struct bt_mesh_prov *prov,
#if CONFIG_BLE_MESH_NODE
extern struct bt_mesh_gatt_service proxy_svc;
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY)) {
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
bt_mesh_gatts_service_register(&proxy_svc);
}
@ -340,8 +340,9 @@ int bt_mesh_init(const struct bt_mesh_prov *prov,
#if CONFIG_BLE_MESH_NODE
bt_mesh_proxy_init();
#endif
#if CONFIG_BLE_MESH_PROVISIONER
provisioner_proxy_init();
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
bt_mesh_proxy_prov_client_init();
#endif
}
@ -398,11 +399,6 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers)
bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_ADD,
BLE_MESH_EXCEP_INFO_MESH_PROV_ADV, NULL);
}
if (IS_ENABLED(CONFIG_BLE_MESH_PROXY)) {
bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_ADD,
BLE_MESH_EXCEP_INFO_MESH_PROXY_ADV, NULL);
}
#endif
if ((IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
@ -469,7 +465,7 @@ u8_t bt_mesh_set_fast_prov_action(u8_t action)
* here. The node needs to send some status messages to the phone
* while it is connected.
*/
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY)) {
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
bt_mesh_proxy_gatt_disable();
}
#endif
@ -490,7 +486,7 @@ u8_t bt_mesh_set_fast_prov_action(u8_t action)
}
#if 0
/* Mesh Proxy GATT will be re-enabled on application layer */
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY) &&
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
bt_mesh_gatt_proxy_get() != BLE_MESH_GATT_PROXY_NOT_SUPPORTED) {
bt_mesh_proxy_gatt_enable();
bt_mesh_adv_update();

View File

@ -26,7 +26,7 @@
#include "net.h"
#include "lpn.h"
#include "friend.h"
#include "proxy.h"
#include "proxy_server.h"
#include "transport.h"
#include "access.h"
#include "foundation.h"
@ -34,6 +34,7 @@
#include "settings.h"
#include "prov.h"
#include "provisioner_main.h"
#include "proxy_client.h"
/* Minimum valid Mesh Network PDU length. The Network headers
* themselves take up 9 bytes. After that there is a minumum of 1 byte
@ -191,7 +192,7 @@ int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys,
BT_DBG("NetID %s", bt_hex(keys->net_id, 8));
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
err = bt_mesh_identity_key(key, keys->identity);
if (err) {
BT_ERR("%s, Unable to generate IdentityKey", __func__);
@ -473,7 +474,7 @@ int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16],
sub->net_idx = idx;
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY)) {
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
sub->node_id = BLE_MESH_NODE_IDENTITY_STOPPED;
} else {
sub->node_id = BLE_MESH_NODE_IDENTITY_NOT_SUPPORTED;
@ -613,7 +614,7 @@ void bt_mesh_net_sec_update(struct bt_mesh_subnet *sub)
bt_mesh_friend_sec_update(sub ? sub->net_idx : BLE_MESH_KEY_ANY);
}
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY) &&
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED) {
#if CONFIG_BLE_MESH_NODE
bt_mesh_proxy_beacon_send(sub);
@ -789,7 +790,7 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf,
}
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY) &&
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
bt_mesh_proxy_relay(&buf->b, dst)) {
send_cb_finalize(cb, cb_data);
return 0;
@ -901,12 +902,29 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
*/
#if CONFIG_BLE_MESH_NODE
if (bt_mesh_is_provisioned()) {
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY) &&
tx->ctx->send_ttl != 1U) {
if (bt_mesh_proxy_relay(&buf->b, tx->ctx->addr) &&
BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) {
/* Notify completion if this only went
* through the Mesh Proxy.
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
tx->ctx->send_ttl != 1U) {
if (bt_mesh_proxy_relay(&buf->b, tx->ctx->addr) &&
BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) {
/* Notify completion if this only went
* through the Mesh Proxy.
*/
send_cb_finalize(cb, cb_data);
err = 0;
goto done;
}
}
}
#endif
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
if (tx->ctx->send_ttl != 1U) {
if (bt_mesh_proxy_client_send(&buf->b, tx->ctx->addr)) {
/* If Proxy Client succeeds to send messages with GATT bearer,
* we can directly finish here. And if not, which means no
* connection has been created with Proxy Client, here we will
* use advertising bearer for the messages.
*/
send_cb_finalize(cb, cb_data);
@ -914,7 +932,6 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
goto done;
}
}
}
#endif
/* Deliver to local network interface if necessary */
@ -1268,7 +1285,7 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf,
/* Sending to the GATT bearer should only happen if GATT Proxy
* is enabled or the message originates from the local node.
*/
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY) &&
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
(bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED ||
rx->net_if == BLE_MESH_NET_IF_LOCAL)) {
if (bt_mesh_proxy_relay(&buf->b, rx->ctx.recv_dst) &&
@ -1399,7 +1416,7 @@ void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi,
#if CONFIG_BLE_MESH_NODE
if (bt_mesh_is_provisioned()) {
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY) &&
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
net_if == BLE_MESH_NET_IF_PROXY) {
bt_mesh_proxy_addr_add(data, rx.ctx.addr);
}
@ -1474,7 +1491,7 @@ void bt_mesh_net_start(void)
bt_mesh_beacon_disable();
}
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY) &&
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
bt_mesh_gatt_proxy_get() != BLE_MESH_GATT_PROXY_NOT_SUPPORTED) {
bt_mesh_proxy_gatt_enable();
bt_mesh_adv_update();

View File

@ -67,7 +67,7 @@ struct bt_mesh_subnet {
u8_t nid; /* NID */
u8_t enc[16]; /* EncKey */
u8_t net_id[8]; /* Network ID */
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
u8_t identity[16]; /* IdentityKey */
#endif
u8_t privacy[16]; /* PrivacyKey */

View File

@ -24,7 +24,7 @@
#include "net.h"
#include "access.h"
#include "foundation.h"
#include "proxy.h"
#include "proxy_server.h"
#include "prov.h"
#if CONFIG_BLE_MESH_NODE
@ -1203,7 +1203,7 @@ static void prov_data(const u8_t *data)
link.expect = 0U;
/* Store info, since bt_mesh_provision() will end up clearing it */
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY)) {
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
identity_enable = is_pb_gatt();
} else {
identity_enable = false;
@ -1218,7 +1218,7 @@ static void prov_data(const u8_t *data)
/* After PB-GATT provisioning we should start advertising
* using Node Identity.
*/
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY) && identity_enable) {
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) && identity_enable) {
bt_mesh_proxy_identity_enable();
}
}

View File

@ -30,7 +30,7 @@
#include "access.h"
#include "provisioner_prov.h"
#include "provisioner_proxy.h"
#include "proxy_client.h"
#include "provisioner_main.h"
#if CONFIG_BLE_MESH_PROVISIONER
@ -256,7 +256,9 @@ int provisioner_upper_init(void)
BT_DBG("netkey: %s, nid: 0x%x", bt_hex(sub->keys[0].net, 16), sub->keys[0].nid);
BT_DBG("enckey: %s", bt_hex(sub->keys[0].enc, 16));
BT_DBG("network id: %s", bt_hex(sub->keys[0].net_id, 8));
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
BT_DBG("identity: %s", bt_hex(sub->keys[0].identity, 16));
#endif
BT_DBG("privacy: %s", bt_hex(sub->keys[0].privacy, 16));
BT_DBG("beacon: %s", bt_hex(sub->keys[0].beacon, 16));

View File

@ -27,15 +27,13 @@
#include "adv.h"
#include "mesh.h"
#include "provisioner_prov.h"
#include "provisioner_proxy.h"
#include "proxy_client.h"
#include "provisioner_main.h"
#if CONFIG_BLE_MESH_PROVISIONER
/* Service data length has minus 1 type length & 2 uuid length*/
#define BLE_MESH_PROV_SRV_DATA_LEN 0x12
#define BLE_MESH_PROXY_SRV_DATA_LEN1 0x09
#define BLE_MESH_PROXY_SRV_DATA_LEN2 0x11
_Static_assert(BLE_MESH_MAX_CONN >= CONFIG_BLE_MESH_PBG_SAME_TIME,
"Too large BLE Mesh PB-GATT count");
/* 3 transmissions, 20ms interval */
#define PROV_XMIT BLE_MESH_TRANSMIT(2, 20)
@ -378,14 +376,14 @@ void provisioner_pbg_count_dec(void)
}
}
void provisioner_pbg_count_inc(void)
static inline void provisioner_pbg_count_inc(void)
{
prov_ctx.pbg_count++;
}
#if defined(CONFIG_BLE_MESH_PB_GATT)
void provisioner_clear_link_conn_info(const u8_t addr[6])
{
#if defined(CONFIG_BLE_MESH_PB_GATT)
u8_t i;
if (!addr) {
@ -411,9 +409,9 @@ void provisioner_clear_link_conn_info(const u8_t addr[6])
}
BT_WARN("%s, Address %s is not found", __func__, bt_hex(addr, BLE_MESH_ADDR_LEN));
#endif
return;
}
#endif
const struct bt_mesh_prov *provisioner_get_prov_info(void)
{
@ -671,7 +669,7 @@ static int provisioner_start_prov_pb_gatt(const u8_t uuid[16],
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)) {
if (bt_mesh_gattc_conn_create(&link[i].addr, BLE_MESH_UUID_MESH_PROV_VAL) < 0) {
memset(link[i].uuid, 0, 16);
link[i].oob_info = 0x0;
memset(&link[i].addr, 0, sizeof(bt_mesh_addr_t));
@ -680,6 +678,7 @@ static int provisioner_start_prov_pb_gatt(const u8_t uuid[16],
}
/* If creating connection successfully, set connecting flag to 1 */
link[i].connecting = true;
provisioner_pbg_count_inc();
osi_mutex_unlock(&prov_ctx.pb_gatt_lock);
return 0;
}
@ -1424,7 +1423,7 @@ static int prov_send_gatt(const u8_t idx, struct net_buf_simple *msg)
return -ENOTCONN;
}
err = provisioner_proxy_send(link[idx].conn, BLE_MESH_PROXY_PROV, msg);
err = bt_mesh_proxy_prov_client_send(link[idx].conn, BLE_MESH_PROXY_PROV, msg);
if (err) {
BT_ERR("%s, Failed to send PB-GATT pdu", __func__);
return err;
@ -3153,85 +3152,7 @@ void provisioner_unprov_beacon_recv(struct net_buf_simple *buf)
#endif /* CONFIG_BLE_MESH_PB_ADV */
}
bool provisioner_flags_match(struct net_buf_simple *buf)
{
u8_t flags;
if (buf->len != 1) {
BT_DBG("%s, Unexpected flags length", __func__);
return false;
}
flags = net_buf_simple_pull_u8(buf);
BT_DBG("Received adv pkt with flags: 0x%02x", flags);
/* Flags context will not be checked curently */
return true;
}
u16_t provisioner_srv_uuid_recv(struct net_buf_simple *buf)
{
u16_t uuid;
if (buf->len != 2) {
BT_DBG("Length not match mesh service uuid");
return false;
}
uuid = net_buf_simple_pull_le16(buf);
BT_DBG("Received adv pkt with service UUID: %d", uuid);
if ((uuid != BLE_MESH_UUID_MESH_PROV_VAL) && (uuid != BLE_MESH_UUID_MESH_PROXY_VAL)) {
return false;
}
return uuid;
}
static void provisioner_prov_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr);
void provisioner_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr, u16_t uuid)
{
u16_t uuid_type;
if (!buf || !addr) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
uuid_type = net_buf_simple_pull_le16(buf);
if (uuid_type != uuid) {
BT_DBG("%s, Invalid Mesh Service Data UUID 0x%04x", __func__, uuid_type);
return;
}
switch (uuid) {
case BLE_MESH_UUID_MESH_PROV_VAL:
if (buf->len != BLE_MESH_PROV_SRV_DATA_LEN) {
BT_WARN("%s, Invalid Mesh Prov Service Data length %d", __func__, buf->len);
return;
}
BT_DBG("Start to deal with Mesh Prov Service Data");
provisioner_prov_srv_data_recv(buf, addr);
break;
case BLE_MESH_UUID_MESH_PROXY_VAL:
if (buf->len != BLE_MESH_PROXY_SRV_DATA_LEN1 &&
buf->len != BLE_MESH_PROXY_SRV_DATA_LEN2) {
BT_ERR("%s, Invalid Mesh Proxy Service Data length %d", __func__, buf->len);
return;
}
BT_DBG("Start to deal with Mesh Proxy Service Data");
provisioner_proxy_srv_data_recv(buf);
break;
default:
break;
}
}
static void provisioner_prov_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr)
void provisioner_prov_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr)
{
#if defined(CONFIG_BLE_MESH_PB_GATT)
const u8_t *uuid = NULL;
@ -3242,6 +3163,11 @@ static void provisioner_prov_srv_data_recv(struct net_buf_simple *buf, const bt_
return;
}
if (bt_mesh_gattc_get_free_conn_count() == 0) {
BT_WARN("%s, max connections", __func__);
return;
}
uuid = buf->data;
net_buf_simple_pull(buf, 16);
/* Mesh beacon uses big-endian to send beacon data */

View File

@ -75,13 +75,6 @@ struct bt_mesh_prov_data_info {
*/
void provisioner_pbg_count_dec(void);
/**
* @brief This function increments the current PB-GATT count.
*
* @return None
*/
void provisioner_pbg_count_inc(void);
/**
* @brief This function clears the part of the link info of the proper device.
*
@ -165,37 +158,7 @@ int provisioner_prov_init(const struct bt_mesh_prov *prov_info);
*/
void provisioner_unprov_beacon_recv(struct net_buf_simple *buf);
/**
* @brief This function parses the flags part of the
* received connectable mesh provisioning advertising packets.
*
* @param[in] buf: Pointer to the buffer containing advertising flags part
*
* @return True - success, False - fail
*/
bool provisioner_flags_match(struct net_buf_simple *buf);
/**
* @brief This function parses the service UUID part of the
* received connectable mesh provisioning advertising packets.
*
* @param[in] buf: Pointer to the buffer containing service UUID part
*
* @return Zero - fail, otherwise - Service UUID(0x1827 or 0x1828)
*/
u16_t provisioner_srv_uuid_recv(struct net_buf_simple *buf);
/**
* @brief This function parses the service data part of the
* received connectable mesh provisioning advertising packets.
*
* @param[in] buf: Pointer to the buffer containing the remianing service data part
* @param[in] addr: Pointer to the received device address
* @param[in] uuid: Service UUID contained in the service UUID part
*
* @return None
*/
void provisioner_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr, u16_t uuid);
void provisioner_prov_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr);
/**
* @brief This function gets the bt_mesh_prov pointer.

View File

@ -1,608 +0,0 @@
// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include <errno.h>
#include "sdkconfig.h"
#include "mesh_bearer_adapt.h"
#include "mesh_trace.h"
#include "net.h"
#include "beacon.h"
#include "foundation.h"
#include "provisioner_prov.h"
#include "provisioner_proxy.h"
#include "provisioner_beacon.h"
#if CONFIG_BLE_MESH_PROVISIONER
#define PDU_TYPE(data) (data[0] & BIT_MASK(6))
#define PDU_SAR(data) (data[0] >> 6)
#define SAR_COMPLETE 0x00
#define SAR_FIRST 0x01
#define SAR_CONT 0x02
#define SAR_LAST 0x03
#define CFG_FILTER_SET 0x00
#define CFG_FILTER_ADD 0x01
#define CFG_FILTER_REMOVE 0x02
#define CFG_FILTER_STATUS 0x03
#define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6)))
#define SERVER_BUF_SIZE 68
#define ID_TYPE_NET 0x00
#define ID_TYPE_NODE 0x01
#define NODE_ID_LEN 19
#define NET_ID_LEN 11
#define CLOSE_REASON_PROXY 0xFF
static int conn_count;
static struct bt_mesh_proxy_server {
struct bt_mesh_conn *conn;
/* Provisioner can use filter to double check the dst within mesh messages */
u16_t filter[CONFIG_BLE_MESH_PROXY_FILTER_SIZE];
enum __packed {
NONE,
WHITELIST,
BLACKLIST,
PROV,
} filter_type;
u8_t msg_type;
struct net_buf_simple buf;
} servers[BLE_MESH_MAX_CONN];
static u8_t server_buf_data[SERVER_BUF_SIZE * BLE_MESH_MAX_CONN];
static struct bt_mesh_proxy_server *find_server(struct bt_mesh_conn *conn)
{
int i;
for (i = 0; i < ARRAY_SIZE(servers); i++) {
if (servers[i].conn == conn) {
return &servers[i];
}
}
return NULL;
}
static int filter_status(struct bt_mesh_proxy_server *server,
struct net_buf_simple *buf)
{
/* TODO: Deal with received proxy configuration status messages */
return 0;
}
#if 0
static void send_filter_set(struct bt_mesh_proxy_server *server,
struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf)
{
/* TODO: Act as proxy client, send proxy configuration set messages */
}
static void send_filter_add(struct bt_mesh_proxy_server *server,
struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf)
{
/* TODO: Act as proxy client, send proxy configuration add messages */
}
static void send_filter_remove(struct bt_mesh_proxy_server *server,
struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf)
{
/* TODO: Act as proxy client, send proxy configuration remove messages */
}
#endif
static void proxy_cfg(struct bt_mesh_proxy_server *server)
{
NET_BUF_SIMPLE_DEFINE(buf, 29);
struct bt_mesh_net_rx rx;
u8_t opcode;
int err;
/** In order to deal with proxy configuration messages, provisioner should
* do sth. like create mesh network after each device is provisioned.
*/
err = bt_mesh_net_decode(&server->buf, BLE_MESH_NET_IF_PROXY_CFG,
&rx, &buf);
if (err) {
BT_ERR("%s, Failed to decode Proxy Configuration (err %d)", __func__, err);
return;
}
/* Remove network headers */
net_buf_simple_pull(&buf, BLE_MESH_NET_HDR_LEN);
BT_DBG("%u bytes: %s", buf.len, bt_hex(buf.data, buf.len));
if (buf.len < 1) {
BT_WARN("Too short proxy configuration PDU");
return;
}
opcode = net_buf_simple_pull_u8(&buf);
switch (opcode) {
case CFG_FILTER_STATUS:
filter_status(server, &buf);
break;
default:
BT_WARN("Unhandled configuration OpCode 0x%02x", opcode);
break;
}
}
static void proxy_complete_pdu(struct bt_mesh_proxy_server *server)
{
switch (server->msg_type) {
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
case BLE_MESH_PROXY_NET_PDU:
BT_DBG("Mesh Network PDU");
bt_mesh_net_recv(&server->buf, 0, BLE_MESH_NET_IF_PROXY);
break;
case BLE_MESH_PROXY_BEACON:
BT_DBG("Mesh Beacon PDU");
provisioner_beacon_recv(&server->buf);
break;
case BLE_MESH_PROXY_CONFIG:
BT_DBG("Mesh Configuration PDU");
proxy_cfg(server);
break;
#endif
#if defined(CONFIG_BLE_MESH_PB_GATT)
case BLE_MESH_PROXY_PROV:
BT_DBG("Mesh Provisioning PDU");
provisioner_pb_gatt_recv(server->conn, &server->buf);
break;
#endif
default:
BT_WARN("Unhandled Message Type 0x%02x", server->msg_type);
break;
}
net_buf_simple_reset(&server->buf);
}
#define ATTR_IS_PROV(uuid) (uuid == BLE_MESH_UUID_MESH_PROV_VAL)
static ssize_t proxy_recv(struct bt_mesh_conn *conn,
const struct bt_mesh_gatt_attr *attr, const void *buf,
u16_t len, u16_t offset, u8_t flags)
{
struct bt_mesh_proxy_server *server = find_server(conn);
const u8_t *data = buf;
u16_t srvc_uuid = 0;
if (!server) {
return -ENOTCONN;
}
if (len < 1) {
BT_WARN("Too small Proxy PDU");
return -EINVAL;
}
srvc_uuid = bt_mesh_gattc_get_service_uuid(conn);
if (!srvc_uuid) {
BT_ERR("%s, No service uuid found", __func__);
return -ENOTCONN;
}
if (ATTR_IS_PROV(srvc_uuid) != (PDU_TYPE(data) == BLE_MESH_PROXY_PROV)) {
BT_WARN("Proxy PDU type doesn't match GATT service uuid");
return -EINVAL;
}
if (len - 1 > net_buf_simple_tailroom(&server->buf)) {
BT_WARN("Too big proxy PDU");
return -EINVAL;
}
switch (PDU_SAR(data)) {
case SAR_COMPLETE:
if (server->buf.len) {
BT_WARN("Complete PDU while a pending incomplete one");
return -EINVAL;
}
server->msg_type = PDU_TYPE(data);
net_buf_simple_add_mem(&server->buf, data + 1, len - 1);
proxy_complete_pdu(server);
break;
case SAR_FIRST:
if (server->buf.len) {
BT_WARN("First PDU while a pending incomplete one");
return -EINVAL;
}
server->msg_type = PDU_TYPE(data);
net_buf_simple_add_mem(&server->buf, data + 1, len - 1);
break;
case SAR_CONT:
if (!server->buf.len) {
BT_WARN("Continuation with no prior data");
return -EINVAL;
}
if (server->msg_type != PDU_TYPE(data)) {
BT_WARN("Unexpected message type in continuation");
return -EINVAL;
}
net_buf_simple_add_mem(&server->buf, data + 1, len - 1);
break;
case SAR_LAST:
if (!server->buf.len) {
BT_WARN("Last SAR PDU with no prior data");
return -EINVAL;
}
if (server->msg_type != PDU_TYPE(data)) {
BT_WARN("Unexpected message type in last SAR PDU");
return -EINVAL;
}
net_buf_simple_add_mem(&server->buf, data + 1, len - 1);
proxy_complete_pdu(server);
break;
}
return len;
}
static void proxy_prov_connected(const u8_t addr[6], struct bt_mesh_conn *conn, int id)
{
struct bt_mesh_proxy_server *server = NULL;
conn_count++;
if (!servers[id].conn) {
server = &servers[id];
}
if (!server) {
BT_ERR("%s, No matching Proxy Client objects", __func__);
/** Disconnect current connection, clear part of prov_link
* information, like uuid, dev_addr, linking flag, etc.
*/
return;
}
server->conn = bt_mesh_conn_ref(conn);
server->filter_type = NONE;
memset(server->filter, 0, sizeof(server->filter));
net_buf_simple_reset(&server->buf);
#if defined(CONFIG_BLE_MESH_PB_GATT)
if (provisioner_set_prov_conn(addr, server->conn)) {
BT_ERR("%s, provisioner_set_prov_conn failed", __func__);
bt_mesh_gattc_disconnect(server->conn);
return;
}
#endif
bt_mesh_gattc_exchange_mtu(id);
}
static void proxy_prov_disconnected(struct bt_mesh_conn *conn, u8_t reason)
{
struct bt_mesh_proxy_server *server = NULL;
int i;
BT_DBG("conn %p, handle is %d, reason 0x%02x", conn, conn->handle, reason);
if (conn_count) {
conn_count--;
}
for (i = 0; i < ARRAY_SIZE(servers); i++) {
server = &servers[i];
if (server->conn == conn) {
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
server->filter_type == PROV) {
provisioner_pb_gatt_close(conn, reason);
}
server->conn = NULL;
break;
}
}
}
#if defined(CONFIG_BLE_MESH_PB_GATT)
static ssize_t prov_write_ccc_descr(struct bt_mesh_conn *conn, u8_t *addr)
{
struct bt_mesh_proxy_server *server;
server = find_server(conn);
if (!server) {
BT_ERR("%s, No Proxy Server found", __func__);
return -ENOTCONN;
}
if (server->filter_type == NONE) {
server->filter_type = PROV;
return provisioner_pb_gatt_open(conn, addr);
}
return -EINVAL;
}
static ssize_t prov_notification(struct bt_mesh_conn *conn, u8_t *data, u16_t len)
{
struct bt_mesh_proxy_server *server;
server = find_server(conn);
if (!server) {
BT_ERR("%s, No Proxy Server found", __func__);
return -ENOTCONN;
}
if (server->filter_type == PROV) {
return proxy_recv(conn, NULL, data, len, 0, 0);
}
return -EINVAL;
}
int provisioner_pb_gatt_enable(void)
{
int i;
BT_DBG("%s", __func__);
for (i = 0; i < ARRAY_SIZE(servers); i++) {
if (servers[i].conn) {
servers[i].filter_type = PROV;
}
}
return 0;
}
int provisioner_pb_gatt_disable(void)
{
int i;
BT_DBG("%s", __func__);
for (i = 0; i < ARRAY_SIZE(servers); i++) {
struct bt_mesh_proxy_server *server = &servers[i];
if (server->conn && server->filter_type == PROV) {
bt_mesh_gattc_disconnect(server->conn);
server->filter_type = NONE;
}
}
return 0;
}
#endif /* CONFIG_BLE_MESH_PB_GATT */
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
static ssize_t proxy_write_ccc_descr(struct bt_mesh_conn *conn)
{
struct bt_mesh_proxy_server *server;
server = find_server(conn);
if (!server) {
BT_ERR("%s, No Proxy Server found", __func__);
return -ENOTCONN;
}
if (server->filter_type == NONE) {
server->filter_type = WHITELIST;
return 0;
}
return -EINVAL;
}
static ssize_t proxy_notification(struct bt_mesh_conn *conn, u8_t *data, u16_t len)
{
return proxy_recv(conn, NULL, data, len, 0, 0);
}
/** Currently provisioner does't need bt_mesh_provisioner_proxy_enable()
* and bt_mesh_provisioner_proxy_disable() functions, and once they are
* used, provisioner can be enabled to parse node_id_adv and net_id_adv
* in order to support proxy client role.
* And if gatt_proxy is disabled, provisioner can stop dealing with
* these two kinds of connectable advertising packets.
*/
int bt_mesh_provisioner_proxy_enable(void)
{
int i;
BT_DBG("%s", __func__);
for (i = 0; i < ARRAY_SIZE(servers); i++) {
if (servers[i].conn) {
servers[i].filter_type = WHITELIST;
}
}
/** TODO: Once at leat one device has been provisioned, provisioner
* can be set to allow receiving and parsing node_id & net_id adv
* packets, and we may use a global flag to indicate this.
*/
return 0;
}
static void bt_mesh_proxy_gatt_proxy_disconnect(void)
{
int i;
BT_DBG("%s", __func__);
for (i = 0; i < ARRAY_SIZE(servers); i++) {
struct bt_mesh_proxy_server *server = &servers[i];
if (server->conn && (server->filter_type == WHITELIST ||
server->filter_type == BLACKLIST)) {
server->filter_type = NONE;
bt_mesh_gattc_disconnect(server->conn);
}
}
}
int bt_mesh_provisioner_proxy_disable(void)
{
BT_DBG("%s", __func__);
/** TODO: Once this function is invoked, provisioner shall stop
* receiving and parsing node_id & net_id adv packets, and if
* proxy connection exists, we should disconnect it.
*/
bt_mesh_proxy_gatt_proxy_disconnect();
return 0;
}
#endif /* CONFIG_BLE_MESH_GATT_PROXY */
static int proxy_send(struct bt_mesh_conn *conn, const void *data, u16_t len)
{
BT_DBG("%u bytes: %s", len, bt_hex(data, len));
#if defined(CONFIG_BLE_MESH_GATT_PROXY) || defined(CONFIG_BLE_MESH_PB_GATT)
return bt_mesh_gattc_write_no_rsp(conn, NULL, data, len);
#endif
return 0;
}
static int proxy_prov_segment_and_send(struct bt_mesh_conn *conn, u8_t type,
struct net_buf_simple *msg)
{
u16_t mtu;
if (conn == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
BT_DBG("conn %p type 0x%02x len %u: %s", conn, type, msg->len,
bt_hex(msg->data, msg->len));
mtu = bt_mesh_gattc_get_mtu_info(conn);
if (!mtu) {
BT_ERR("%s, Conn used to get mtu does not exist", __func__);
return -ENOTCONN;
}
/* ATT_MTU - OpCode (1 byte) - Handle (2 bytes) */
mtu -= 3;
if (mtu > msg->len) {
net_buf_simple_push_u8(msg, PDU_HDR(SAR_COMPLETE, type));
return proxy_send(conn, msg->data, msg->len);
}
net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type));
proxy_send(conn, msg->data, mtu);
net_buf_simple_pull(msg, mtu);
while (msg->len) {
if (msg->len + 1 < mtu) {
net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type));
proxy_send(conn, msg->data, msg->len);
break;
}
net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type));
proxy_send(conn, msg->data, mtu);
net_buf_simple_pull(msg, mtu);
}
return 0;
}
int provisioner_proxy_send(struct bt_mesh_conn *conn, u8_t type,
struct net_buf_simple *msg)
{
struct bt_mesh_proxy_server *server = find_server(conn);
if (!server) {
BT_ERR("$%s, No Proxy Server found", __func__);
return -ENOTCONN;
}
if ((server->filter_type == PROV) != (type == BLE_MESH_PROXY_PROV)) {
BT_ERR("%s, Invalid PDU type for Proxy Client", __func__);
return -EINVAL;
}
return proxy_prov_segment_and_send(conn, type, msg);
}
static struct bt_mesh_prov_conn_cb conn_callbacks = {
.connected = proxy_prov_connected,
.disconnected = proxy_prov_disconnected,
#if defined(CONFIG_BLE_MESH_PB_GATT)
.prov_write_descr = prov_write_ccc_descr,
.prov_notify = prov_notification,
#endif /* CONFIG_BLE_MESH_PB_GATT */
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
.proxy_write_descr = proxy_write_ccc_descr,
.proxy_notify = proxy_notification,
#endif /* CONFIG_BLE_MESH_GATT_PROXY */
};
void provisioner_proxy_srv_data_recv(struct net_buf_simple *buf)
{
/** TODO: Parse node_id_adv or net_id_adv pkts. Currently we
* don't support this function, and if realized later, proxy
* client need to check if there is server structure left
* before create connection with a server.
* check conn_count & CONFIG_BLE_MESH_PBG_SAME_TIME
*/
}
int provisioner_proxy_init(void)
{
int i;
/* Initialize the server receive buffers */
for (i = 0; i < ARRAY_SIZE(servers); i++) {
struct bt_mesh_proxy_server *server = &servers[i];
server->buf.size = SERVER_BUF_SIZE;
server->buf.__buf = server_buf_data + (i * SERVER_BUF_SIZE);
}
bt_mesh_gattc_conn_cb_register(&conn_callbacks);
return 0;
}
#endif /* CONFIG_BLE_MESH_PROVISIONER */

View File

@ -1,89 +0,0 @@
// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _PROVISIONER_PROXY_H_
#define _PROVISIONER_PROXY_H_
#include "mesh_buf.h"
#define BLE_MESH_PROXY_NET_PDU 0x00
#define BLE_MESH_PROXY_BEACON 0x01
#define BLE_MESH_PROXY_CONFIG 0x02
#define BLE_MESH_PROXY_PROV 0x03
/**
* @brief This function is called to send proxy protocol messages.
*
* @param[in] conn: Pointer to bt_conn structure
* @param[in] type: Proxy protocol message type
* @param[in] msg: Pointer to the buffer contains sending message.
*
* @return Zero-success, other-fail
*/
int provisioner_proxy_send(struct bt_mesh_conn *conn, u8_t type, struct net_buf_simple *msg);
/**
* @brief This function is called to parse received node identity and net
* id adv pkts and create connection if deceided to.
*
* @param[in] buf: Pointer to the buffer contains received message.
*
* @return None
*/
void provisioner_proxy_srv_data_recv(struct net_buf_simple *buf);
/**
* @brief This function is called to initialize proxy provisioner structure
* and register proxy connection related callbacks.
*
* @return Zero-success, other-fail
*/
int provisioner_proxy_init(void);
/**
* @brief This function is called to enable dealing with proxy provisioning
* messages.
*
* @return Zero-success, other-fail
*/
int provisioner_pb_gatt_enable(void);
/**
* @brief This function is called to disable dealing with proxy provisioning
* messages and if proxy provisioning connections exist, the connections
* will be disconnected.
*
* @return Zero-success, other-fail
*/
int provisioner_pb_gatt_disable(void);
/* The following APIs are for application use */
/**
* @brief This function is called to enable receiving node identity and net
* id adv pkts.
*
* @return Zero-success, other-fail
*/
int bt_mesh_provisioner_proxy_enable(void);
/**
* @brief This function is called to disable receiving node identity and net
* id adv pkts, and if proxy connections exist, these connections will
* be disconnected.
*
* @return Zero-success, other-fail
*/
int bt_mesh_provisioner_proxy_disable(void);
#endif /* _PROVISIONER_PROXY_H_ */

View File

@ -0,0 +1,998 @@
// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include <errno.h>
#include "sdkconfig.h"
#include "mesh.h"
#include "mesh_bearer_adapt.h"
#include "mesh_trace.h"
#include "mesh_common.h"
#include "net.h"
#include "access.h"
#include "beacon.h"
#include "foundation.h"
#include "provisioner_prov.h"
#include "proxy_client.h"
#include "provisioner_beacon.h"
#include "provisioner_main.h"
#define PDU_TYPE(data) (data[0] & BIT_MASK(6))
#define PDU_SAR(data) (data[0] >> 6)
#define PROXY_SAR_TIMEOUT K_SECONDS(20)
#define SAR_COMPLETE 0x00
#define SAR_FIRST 0x01
#define SAR_CONT 0x02
#define SAR_LAST 0x03
#define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6)))
#define SERVER_BUF_SIZE 68
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
static struct bt_mesh_proxy_server {
struct bt_mesh_conn *conn;
enum __packed {
NONE,
PROV,
PROXY,
} conn_type;
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
u16_t net_idx;
#endif
u8_t msg_type;
struct k_delayed_work sar_timer;
struct net_buf_simple buf;
} servers[BLE_MESH_MAX_CONN];
static u8_t server_buf_data[SERVER_BUF_SIZE * BLE_MESH_MAX_CONN];
static struct bt_mesh_proxy_server *find_server(struct bt_mesh_conn *conn)
{
u8_t i;
for (i = 0U; i < ARRAY_SIZE(servers); i++) {
if (servers[i].conn == conn) {
return &servers[i];
}
}
return NULL;
}
static void proxy_sar_timeout(struct k_work *work)
{
struct bt_mesh_proxy_server *server = NULL;
BT_DBG("%s", __func__);
server = CONTAINER_OF(work, struct bt_mesh_proxy_server, sar_timer.work);
if (!server || !server->conn) {
BT_ERR("%s, Invalid proxy server parameter", __func__);
return;
}
net_buf_simple_reset(&server->buf);
bt_mesh_gattc_disconnect(server->conn);
}
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
/**
* The following callbacks are used to notify proper information
* to the application layer.
*/
static proxy_client_recv_adv_cb_t proxy_client_adv_recv_cb;
static proxy_client_connect_cb_t proxy_client_connect_cb;
static proxy_client_disconnect_cb_t proxy_client_disconnect_cb;
static proxy_client_recv_filter_status_cb_t proxy_client_filter_status_recv_cb;
void bt_mesh_proxy_client_set_adv_recv_cb(proxy_client_recv_adv_cb_t cb)
{
proxy_client_adv_recv_cb = cb;
}
void bt_mesh_proxy_client_set_conn_cb(proxy_client_connect_cb_t cb)
{
proxy_client_connect_cb = cb;
}
void bt_mesh_proxy_client_set_disconn_cb(proxy_client_disconnect_cb_t cb)
{
proxy_client_disconnect_cb = cb;
}
void bt_mesh_proxy_client_set_filter_status_cb(proxy_client_recv_filter_status_cb_t cb)
{
proxy_client_filter_status_recv_cb = cb;
}
static void filter_status(struct bt_mesh_proxy_server *server,
struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf)
{
u8_t filter_type;
u16_t list_size;
if (buf->len != 3) {
BT_ERR("%s, Invalid Proxy Filter Status length %d", __func__, buf->len);
return;
}
filter_type = net_buf_simple_pull_u8(buf);
if (filter_type > 0x01) {
BT_ERR("%s, Invalid filter type 0x%02x", __func__, filter_type);
return;
}
list_size = net_buf_simple_pull_be16(buf);
BT_DBG("%s, filter_type 0x%02x list_size %d", __func__, filter_type, list_size);
if (proxy_client_filter_status_recv_cb) {
proxy_client_filter_status_recv_cb(server - servers, rx->ctx.addr, server->net_idx, filter_type, list_size);
}
return;
}
static void proxy_cfg(struct bt_mesh_proxy_server *server)
{
NET_BUF_SIMPLE_DEFINE(buf, 29);
struct bt_mesh_net_rx rx = {0};
u8_t opcode;
int err;
err = bt_mesh_net_decode(&server->buf, BLE_MESH_NET_IF_PROXY_CFG,
&rx, &buf);
if (err) {
BT_ERR("%s, Failed to decode Proxy Configuration (err %d)", __func__, err);
return;
}
if (!BLE_MESH_ADDR_IS_UNICAST(rx.ctx.addr)) {
BT_ERR("%s, Proxy Configuration from non-unicast addr 0x%04x", __func__, rx.ctx.addr);
return;
}
/* Remove network headers */
net_buf_simple_pull(&buf, BLE_MESH_NET_HDR_LEN);
BT_DBG("%u bytes: %s", buf.len, bt_hex(buf.data, buf.len));
if (buf.len < 3) {
BT_WARN("Too short proxy configuration PDU");
return;
}
opcode = net_buf_simple_pull_u8(&buf);
switch (opcode) {
case BLE_MESH_PROXY_CFG_FILTER_STATUS:
filter_status(server, &rx, &buf);
break;
default:
BT_WARN("Unknown Proxy Configuration OpCode 0x%02x", opcode);
break;
}
}
#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
static void proxy_complete_pdu(struct bt_mesh_proxy_server *server)
{
switch (server->msg_type) {
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
case BLE_MESH_PROXY_NET_PDU:
BT_DBG("Mesh Network PDU");
bt_mesh_net_recv(&server->buf, 0, BLE_MESH_NET_IF_PROXY);
break;
case BLE_MESH_PROXY_BEACON:
BT_DBG("Mesh Beacon PDU");
if (bt_mesh_is_provisioner_en()) {
#if CONFIG_BLE_MESH_PROVISIONER
provisioner_beacon_recv(&server->buf);
#endif
} else {
#if CONFIG_BLE_MESH_NODE
bt_mesh_beacon_recv(&server->buf);
#endif
}
break;
case BLE_MESH_PROXY_CONFIG:
BT_DBG("Mesh Configuration PDU");
proxy_cfg(server);
break;
#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
#if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
case BLE_MESH_PROXY_PROV:
BT_DBG("Mesh Provisioning PDU");
provisioner_pb_gatt_recv(server->conn, &server->buf);
break;
#endif
default:
BT_WARN("Unhandled Message Type 0x%02x", server->msg_type);
break;
}
net_buf_simple_reset(&server->buf);
}
#define ATTR_IS_PROV(uuid) (uuid == BLE_MESH_UUID_MESH_PROV_VAL)
static ssize_t proxy_recv(struct bt_mesh_conn *conn,
const struct bt_mesh_gatt_attr *attr, const void *buf,
u16_t len, u16_t offset, u8_t flags)
{
struct bt_mesh_proxy_server *server = find_server(conn);
const u8_t *data = buf;
u16_t srvc_uuid;
if (!server) {
BT_ERR("%s, No Proxy Server object found", __func__);
return -ENOTCONN;
}
if (len < 1) {
BT_WARN("Too small Proxy PDU");
return -EINVAL;
}
srvc_uuid = bt_mesh_gattc_get_service_uuid(conn);
if (!srvc_uuid) {
BT_ERR("%s, No service uuid found", __func__);
return -ENOTCONN;
}
if (ATTR_IS_PROV(srvc_uuid) != (PDU_TYPE(data) == BLE_MESH_PROXY_PROV)) {
BT_WARN("Proxy PDU type doesn't match GATT service uuid");
return -EINVAL;
}
if (len - 1 > net_buf_simple_tailroom(&server->buf)) {
BT_WARN("Too big proxy PDU");
return -EINVAL;
}
switch (PDU_SAR(data)) {
case SAR_COMPLETE:
if (server->buf.len) {
BT_WARN("Complete PDU while a pending incomplete one");
return -EINVAL;
}
server->msg_type = PDU_TYPE(data);
net_buf_simple_add_mem(&server->buf, data + 1, len - 1);
proxy_complete_pdu(server);
break;
case SAR_FIRST:
if (server->buf.len) {
BT_WARN("First PDU while a pending incomplete one");
return -EINVAL;
}
k_delayed_work_submit(&server->sar_timer, PROXY_SAR_TIMEOUT);
server->msg_type = PDU_TYPE(data);
net_buf_simple_add_mem(&server->buf, data + 1, len - 1);
break;
case SAR_CONT:
if (!server->buf.len) {
BT_WARN("Continuation with no prior data");
return -EINVAL;
}
if (server->msg_type != PDU_TYPE(data)) {
BT_WARN("Unexpected message type in continuation");
return -EINVAL;
}
k_delayed_work_submit(&server->sar_timer, PROXY_SAR_TIMEOUT);
net_buf_simple_add_mem(&server->buf, data + 1, len - 1);
break;
case SAR_LAST:
if (!server->buf.len) {
BT_WARN("Last SAR PDU with no prior data");
return -EINVAL;
}
if (server->msg_type != PDU_TYPE(data)) {
BT_WARN("Unexpected message type in last SAR PDU");
return -EINVAL;
}
k_delayed_work_cancel(&server->sar_timer);
net_buf_simple_add_mem(&server->buf, data + 1, len - 1);
proxy_complete_pdu(server);
break;
}
return len;
}
static int proxy_send(struct bt_mesh_conn *conn, const void *data, u16_t len)
{
BT_DBG("%u bytes: %s", len, bt_hex(data, len));
return bt_mesh_gattc_write_no_rsp(conn, NULL, data, len);
}
static int proxy_segment_and_send(struct bt_mesh_conn *conn, u8_t type,
struct net_buf_simple *msg)
{
u16_t mtu;
int err;
if (conn == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
BT_DBG("conn %p type 0x%02x len %u: %s", conn, type, msg->len,
bt_hex(msg->data, msg->len));
mtu = bt_mesh_gattc_get_mtu_info(conn);
if (!mtu) {
BT_ERR("%s, Conn used to get mtu does not exist", __func__);
return -ENOTCONN;
}
/* ATT_MTU - OpCode (1 byte) - Handle (2 bytes) */
mtu -= 3;
if (mtu > msg->len) {
net_buf_simple_push_u8(msg, PDU_HDR(SAR_COMPLETE, type));
return proxy_send(conn, msg->data, msg->len);
}
net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type));
err = proxy_send(conn, msg->data, mtu);
net_buf_simple_pull(msg, mtu);
while (msg->len) {
if (msg->len + 1 < mtu) {
net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type));
err = proxy_send(conn, msg->data, msg->len);
break;
}
net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type));
err = proxy_send(conn, msg->data, mtu);
net_buf_simple_pull(msg, mtu);
}
return err;
}
int bt_mesh_proxy_prov_client_send(struct bt_mesh_conn *conn, u8_t type,
struct net_buf_simple *msg)
{
struct bt_mesh_proxy_server *server = find_server(conn);
if (!server) {
BT_ERR("$%s, No Proxy Server object found", __func__);
return -ENOTCONN;
}
if ((server->conn_type == PROV) != (type == BLE_MESH_PROXY_PROV)) {
BT_ERR("%s, Invalid PDU type for Proxy Server", __func__);
return -EINVAL;
}
return proxy_segment_and_send(conn, type, msg);
}
static void proxy_connected(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn, int id)
{
struct bt_mesh_proxy_server *server = NULL;
if (!servers[id].conn) {
server = &servers[id];
}
if (!server) {
BT_ERR("%s, No free Proxy Server objects", __func__);
/** Disconnect current connection, clear part of prov_link
* information, like uuid, dev_addr, linking flag, etc.
*/
bt_mesh_gattc_disconnect(conn);
return;
}
server->conn = bt_mesh_conn_ref(conn);
server->conn_type = NONE;
net_buf_simple_reset(&server->buf);
bt_mesh_gattc_exchange_mtu(id);
return;
}
static void proxy_disconnected(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn, u8_t reason)
{
struct bt_mesh_proxy_server *server = find_server(conn);
BT_DBG("conn %p, handle is %d, reason 0x%02x", conn, conn->handle, reason);
if (!server) {
BT_ERR("%s, No Proxy Server object found", __func__);
return;
}
#if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
if (server->conn_type == PROV) {
provisioner_pb_gatt_close(conn, reason);
}
#endif
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
if (server->conn_type == PROXY) {
if (proxy_client_disconnect_cb) {
proxy_client_disconnect_cb(addr, server - servers, server->net_idx, reason);
}
}
#endif
k_delayed_work_cancel(&server->sar_timer);
server->conn = NULL;
server->conn_type = NONE;
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
server->net_idx = BLE_MESH_KEY_UNUSED;
#endif
return;
}
#if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
static ssize_t prov_write_ccc(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn)
{
struct bt_mesh_proxy_server *server = find_server(conn);
if (!server) {
BT_ERR("%s, No Proxy Server object found", __func__);
return -ENOTCONN;
}
if (server->conn_type == NONE) {
server->conn_type = PROV;
if (provisioner_set_prov_conn(addr->val, server->conn)) {
BT_ERR("%s, provisioner_set_prov_conn failed", __func__);
bt_mesh_gattc_disconnect(server->conn);
return -EIO;
}
return provisioner_pb_gatt_open(conn, addr->val);
}
return -ENOMEM;
}
static ssize_t prov_recv_ntf(struct bt_mesh_conn *conn, u8_t *data, u16_t len)
{
struct bt_mesh_proxy_server *server = find_server(conn);
if (!server) {
BT_ERR("%s, No Proxy Server object found", __func__);
return -ENOTCONN;
}
if (server->conn_type == PROV) {
return proxy_recv(conn, NULL, data, len, 0, 0);
}
return -EINVAL;
}
int provisioner_pb_gatt_enable(void)
{
u8_t i;
BT_DBG("%s", __func__);
for (i = 0U; i < ARRAY_SIZE(servers); i++) {
if (servers[i].conn) {
servers[i].conn_type = PROV;
}
}
return 0;
}
int provisioner_pb_gatt_disable(void)
{
u8_t i;
BT_DBG("%s", __func__);
for (i = 0U; i < ARRAY_SIZE(servers); i++) {
struct bt_mesh_proxy_server *server = &servers[i];
if (server->conn && server->conn_type == PROV) {
bt_mesh_gattc_disconnect(server->conn);
server->conn_type = NONE;
}
}
return 0;
}
#endif /* CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT */
#if defined(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)
static ssize_t proxy_write_ccc(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn)
{
struct bt_mesh_proxy_server *server = find_server(conn);
if (!server) {
BT_ERR("%s, No Proxy Server object found", __func__);
return -ENOTCONN;
}
if (server->conn_type == NONE) {
server->conn_type = PROXY;
if (proxy_client_connect_cb) {
proxy_client_connect_cb(addr, server - servers, server->net_idx);
}
return 0;
}
return -EINVAL;
}
static ssize_t proxy_recv_ntf(struct bt_mesh_conn *conn, u8_t *data, u16_t len)
{
struct bt_mesh_proxy_server *server = find_server(conn);
if (!server) {
BT_ERR("%s, No Proxy Server object found", __func__);
return -ENOTCONN;
}
if (server->conn_type == PROXY) {
return proxy_recv(conn, NULL, data, len, 0, 0);
}
return -EINVAL;
}
/**
* Currently proxy client does't need bt_mesh_proxy_client_enable() and
* bt_mesh_proxy_client_disable() functions, and once they are used,
* proxy client can be enabled to parse node_id_adv and net_id_adv in
* order to support proxy client role.
* And if gatt proxy is disabled, proxy client can stop handling these
* two kinds of connectable advertising packets.
*/
int bt_mesh_proxy_client_enable(void)
{
u8_t i;
BT_DBG("%s", __func__);
for (i = 0U; i < ARRAY_SIZE(servers); i++) {
if (servers[i].conn) {
servers[i].conn_type = PROXY;
}
}
/**
* TODO:
* Once at leat one device has been provisioned, proxy client can be
* set to allow receiving and parsing node_id & net_id adv packets,
* and we may use a global flag to indicate this.
*/
return 0;
}
int bt_mesh_proxy_client_disable(void)
{
u8_t i;
BT_DBG("%s", __func__);
/**
* TODO:
* Once this function is invoked, proxy client shall stop handling
* node_id & net_id adv packets, and if proxy connection exists,
* it should be disconnected.
*/
for (i = 0U; i < ARRAY_SIZE(servers); i++) {
struct bt_mesh_proxy_server *server = &servers[i];
if (server->conn && server->conn_type == PROXY) {
bt_mesh_gattc_disconnect(server->conn);
server->conn_type = NONE;
}
}
return 0;
}
#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
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
.prov_write_descr = prov_write_ccc,
.prov_notify = prov_recv_ntf,
#endif /* CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT */
#if defined(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)
.proxy_write_descr = proxy_write_ccc,
.proxy_notify = proxy_recv_ntf,
#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
};
#if defined(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)
static struct bt_mesh_subnet *bt_mesh_is_net_id_exist(const u8_t net_id[8])
{
struct bt_mesh_subnet *sub = NULL;
size_t size, i;
size = bt_mesh_rx_netkey_size();
for (i = 0U; i < size; i++) {
sub = bt_mesh_rx_netkey_get(i);
if (sub && !memcmp(sub->keys[sub->kr_flag].net_id, net_id, 8)) {
return sub;
}
}
return NULL;
}
void proxy_client_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr)
{
bt_mesh_proxy_adv_ctx_t ctx = {0};
u8_t type;
/* Check if connection reaches the maximum limitation */
if (bt_mesh_gattc_get_free_conn_count() == 0) {
BT_WARN("%s, max connections", __func__);
return;
}
type = net_buf_simple_pull_u8(buf);
switch (type) {
case BLE_MESH_PROXY_ADV_NET_ID: {
struct bt_mesh_subnet *sub = NULL;
sub = bt_mesh_is_net_id_exist(buf->data);
if (!sub) {
return;
}
memcpy(ctx.net_id.net_id, buf->data, buf->len);
ctx.net_id.net_idx = sub->net_idx;
break;
}
case BLE_MESH_PROXY_ADV_NODE_ID:
/* Gets node identity information.
* hash = aes-ecb(identity key, 16 octets(padding + random + src)) mod 2^64,
* If Proxy Client wants to get src, it may encrypts multiple times and compare
* the hash value (8 octets) with the received one.
*/
return;
default:
BT_DBG("%s, Unknwon Mesh Proxy adv type 0x%02x", __func__, type);
return;
}
if (proxy_client_adv_recv_cb) {
proxy_client_adv_recv_cb(addr, type, &ctx);
}
}
int bt_mesh_proxy_client_connect(const u8_t addr[6], u8_t addr_type, u16_t net_idx)
{
bt_mesh_addr_t remote_addr = {0};
int result;
if (!addr || addr_type > BLE_MESH_ADDR_RANDOM) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
memcpy(remote_addr.val, addr, BLE_MESH_ADDR_LEN);
remote_addr.type = addr_type;
result = bt_mesh_gattc_conn_create(&remote_addr, BLE_MESH_UUID_MESH_PROXY_VAL);
if (result < 0) {
return result;
}
/* Store corresponding net_idx which can be used for sending Proxy Configuration */
servers[result].net_idx = net_idx;
return 0;
}
int bt_mesh_proxy_client_disconnect(u8_t conn_handle)
{
struct bt_mesh_conn *conn;
if (conn_handle >= BLE_MESH_MAX_CONN) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
BT_DBG("conn_handle %d", conn_handle);
conn = servers[conn_handle].conn;
if (!conn) {
BT_ERR("%s, Not connected, conn_handle %d", __func__, conn_handle);
return -ENOTCONN;
}
bt_mesh_gattc_disconnect(conn);
return 0;
}
bool bt_mesh_proxy_client_send(struct net_buf_simple *buf, u16_t dst)
{
bool send = false;
int err;
u8_t i;
BT_DBG("%u bytes to dst 0x%04x", buf->len, dst);
for (i = 0U; i < ARRAY_SIZE(servers); i++) {
struct bt_mesh_proxy_server *server = &servers[i];
NET_BUF_SIMPLE_DEFINE(msg, 32);
if (!server->conn || server->conn_type != PROXY) {
continue;
}
/* Proxy PDU sending modifies the original buffer,
* so we need to make a copy.
*/
net_buf_simple_init(&msg, 1);
net_buf_simple_add_mem(&msg, buf->data, buf->len);
err = bt_mesh_proxy_prov_client_send(server->conn, BLE_MESH_PROXY_NET_PDU, &msg);
if (err) {
BT_ERR("%s, Failed to send proxy net message (err %d)", __func__, err);
} else {
send = true;
}
}
return send;
}
static int beacon_send(struct bt_mesh_conn *conn, struct bt_mesh_subnet *sub)
{
NET_BUF_SIMPLE_DEFINE(buf, 23);
net_buf_simple_init(&buf, 1);
bt_mesh_beacon_create(sub, &buf);
return bt_mesh_proxy_prov_client_send(conn, BLE_MESH_PROXY_BEACON, &buf);
}
bool bt_mesh_proxy_client_beacon_send(struct bt_mesh_subnet *sub)
{
bool send = false;
int err;
u8_t i;
/* NULL means we send Secure Network Beacon on all subnets */
if (!sub) {
if (bt_mesh_is_provisioner_en()) {
#if CONFIG_BLE_MESH_PROVISIONER
for (i = 0U; i < ARRAY_SIZE(bt_mesh.p_sub); i++) {
if (bt_mesh.p_sub[i] && bt_mesh.p_sub[i]->net_idx != BLE_MESH_KEY_UNUSED) {
send = bt_mesh_proxy_client_beacon_send(bt_mesh.p_sub[i]);
}
}
#endif
} else {
#if CONFIG_BLE_MESH_NODE
for (i = 0U; i < ARRAY_SIZE(bt_mesh.sub); i++) {
if (bt_mesh.sub[i].net_idx != BLE_MESH_KEY_UNUSED) {
send = bt_mesh_proxy_client_beacon_send(&bt_mesh.sub[i]);
}
}
#endif
}
return send;
}
for (i = 0U; i < ARRAY_SIZE(servers); i++) {
if (servers[i].conn && servers[i].conn_type == PROXY) {
err = beacon_send(servers[i].conn, sub);
if (err) {
BT_ERR("%s, Failed to send proxy beacon message (err %d)", __func__, err);
} else {
send = true;
}
}
}
return send;
}
static int send_proxy_cfg(struct bt_mesh_conn *conn, u16_t net_idx, struct bt_mesh_proxy_cfg_pdu *cfg)
{
struct bt_mesh_msg_ctx ctx = {
.net_idx = net_idx,
.app_idx = BLE_MESH_KEY_UNUSED, /* CTL shall be set to 1 */
.addr = BLE_MESH_ADDR_UNASSIGNED, /* DST shall be set to the unassigned address */
.send_ttl = 0U, /* TTL shall be set to 0 */
};
struct bt_mesh_net_tx tx = {
.ctx = &ctx,
.src = bt_mesh_primary_addr(),
};
struct net_buf_simple *buf = NULL;
u16_t alloc_len;
int err;
if (bt_mesh_is_provisioner_en()) {
#if CONFIG_BLE_MESH_PROVISIONER
tx.sub = provisioner_subnet_get(net_idx);
#endif
} else {
#if CONFIG_BLE_MESH_NODE
tx.sub = bt_mesh_subnet_get(net_idx);
#endif
}
if (!tx.sub) {
BT_ERR("%s, Failed to find subnet", __func__);
return -EIO;
}
switch (cfg->opcode) {
case BLE_MESH_PROXY_CFG_FILTER_SET:
if (cfg->set.filter_type > 0x01) {
BT_ERR("%s, Invalid filter type 0x%02x", __func__, cfg->set.filter_type);
return -EINVAL;
}
alloc_len = sizeof(cfg->opcode) + sizeof(cfg->set.filter_type);
break;
case BLE_MESH_PROXY_CFG_FILTER_ADD:
if (cfg->add.addr == NULL || cfg->add.addr_num == 0) {
BT_ERR("%s, Add address list is NULL", __func__);
return -EINVAL;
}
alloc_len = sizeof(cfg->opcode) + (cfg->add.addr_num << 1);
break;
case BLE_MESH_PROXY_CFG_FILTER_REMOVE:
if (cfg->remove.addr == NULL || cfg->remove.addr_num == 0) {
BT_ERR("%s, Remove address list is NULL", __func__);
return -EINVAL;
}
alloc_len = sizeof(cfg->opcode) + (cfg->remove.addr_num << 1);
break;
default:
BT_ERR("%s, Unknown Proxy Configuration opcode 0x%02x", __func__, cfg->opcode);
return -EINVAL;
}
/**
* For Proxy Configuration PDU:
* 1 octet Proxy PDU type + 9 octets network pdu header + Tranport PDU + 8 octets NetMIC
*/
buf = bt_mesh_alloc_buf(1 + BLE_MESH_NET_HDR_LEN + alloc_len + 8);
if (!buf) {
return -ENOMEM;
}
net_buf_simple_reset(buf);
net_buf_simple_reserve(buf, 10);
net_buf_simple_add_u8(buf, cfg->opcode);
switch (cfg->opcode) {
case BLE_MESH_PROXY_CFG_FILTER_SET:
net_buf_simple_add_u8(buf, cfg->set.filter_type);
break;
case BLE_MESH_PROXY_CFG_FILTER_ADD:
for (u16_t i = 0U; i < cfg->add.addr_num; i++) {
net_buf_simple_add_le16(buf, cfg->add.addr[i]);
}
break;
case BLE_MESH_PROXY_CFG_FILTER_REMOVE:
for (u16_t i = 0U; i < cfg->remove.addr_num; i++) {
net_buf_simple_add_le16(buf, cfg->remove.addr[i]);
}
break;
}
BT_DBG("%s, len %u bytes: %s", __func__, buf->len, bt_hex(buf->data, buf->len));
err = bt_mesh_net_encode(&tx, buf, true);
if (err) {
BT_ERR("%s, Encoding Proxy message failed (err %d)", __func__, err);
bt_mesh_free_buf(buf);
return err;
}
err = bt_mesh_proxy_prov_client_send(conn, BLE_MESH_PROXY_CONFIG, buf);
if (err) {
BT_ERR("%s, Failed to send proxy cfg message (err %d)", __func__, err);
}
bt_mesh_free_buf(buf);
return err;
}
int bt_mesh_proxy_client_send_cfg(u8_t conn_handle, u16_t net_idx, struct bt_mesh_proxy_cfg_pdu *pdu)
{
struct bt_mesh_conn *conn;
if (conn_handle >= BLE_MESH_MAX_CONN || !pdu || pdu->opcode > BLE_MESH_PROXY_CFG_FILTER_REMOVE) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
BT_DBG("conn_handle %d, net_idx 0x%04x", conn_handle, net_idx);
conn = servers[conn_handle].conn;
if (!conn) {
BT_ERR("%s, Not connected, conn_handle %d", __func__, conn_handle);
return -ENOTCONN;
}
/**
* Check if net_idx used to encrypt Proxy Configuration are the same
* with the one added when creating proxy connection.
*/
if (servers[conn_handle].net_idx != net_idx) {
BT_ERR("%s, NetKey Index 0x%04x mismatch, expect 0x%04x",
__func__, net_idx, servers[conn_handle].net_idx);
return -EIO;
}
return send_proxy_cfg(conn, net_idx, pdu);
}
#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
int bt_mesh_proxy_prov_client_init(void)
{
u8_t i;
/* Initialize the server receive buffers */
for (i = 0U; i < ARRAY_SIZE(servers); i++) {
struct bt_mesh_proxy_server *server = &servers[i];
k_delayed_work_init(&server->sar_timer, proxy_sar_timeout);
server->buf.size = SERVER_BUF_SIZE;
server->buf.__buf = server_buf_data + (i * SERVER_BUF_SIZE);
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
server->net_idx = BLE_MESH_KEY_UNUSED;
#endif
}
bt_mesh_gattc_conn_cb_register(&conn_callbacks);
#if CONFIG_BLE_MESH_USE_DUPLICATE_SCAN && CONFIG_BLE_MESH_GATT_PROXY_CLIENT
bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_ADD,
BLE_MESH_EXCEP_INFO_MESH_PROXY_ADV, NULL);
#endif
return 0;
}
#endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_CLIENT */

View File

@ -0,0 +1,102 @@
// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _PROVISIONER_PROXY_H_
#define _PROVISIONER_PROXY_H_
#include "mesh_buf.h"
#include "net.h"
#define BLE_MESH_PROXY_ADV_NET_ID 0x00
#define BLE_MESH_PROXY_ADV_NODE_ID 0x01
#define BLE_MESH_PROXY_NET_PDU 0x00
#define BLE_MESH_PROXY_BEACON 0x01
#define BLE_MESH_PROXY_CONFIG 0x02
#define BLE_MESH_PROXY_PROV 0x03
#define BLE_MESH_PROXY_CFG_FILTER_SET 0x00
#define BLE_MESH_PROXY_CFG_FILTER_ADD 0x01
#define BLE_MESH_PROXY_CFG_FILTER_REMOVE 0x02
#define BLE_MESH_PROXY_CFG_FILTER_STATUS 0x03
typedef union {
struct {
u8_t net_id[8];
u16_t net_idx;
} net_id;
struct {
u16_t src;
} node_id;
} bt_mesh_proxy_adv_ctx_t;
struct bt_mesh_proxy_net_pdu {
struct net_buf_simple *val;
};
struct bt_mesh_proxy_cfg_pdu {
u8_t opcode;
union {
struct cfg_filter_set {
u8_t filter_type;
} set;
struct cfg_addr_add {
u16_t *addr;
u16_t addr_num;
} add;
struct cfg_addr_remove {
u16_t *addr;
u16_t addr_num;
} remove;
};
};
typedef struct {
u8_t type;
union {
struct bt_mesh_proxy_net_pdu net;
struct bt_mesh_proxy_cfg_pdu cfg;
};
} bt_mesh_proxy_client_pdu_t;
int bt_mesh_proxy_prov_client_send(struct bt_mesh_conn *conn, u8_t type, struct net_buf_simple *msg);
int provisioner_pb_gatt_enable(void);
int provisioner_pb_gatt_disable(void);
int bt_mesh_proxy_client_enable(void);
int bt_mesh_proxy_client_disable(void);
typedef void (*proxy_client_recv_adv_cb_t)(const bt_mesh_addr_t *addr, u8_t type, bt_mesh_proxy_adv_ctx_t *ctx);
typedef void (*proxy_client_connect_cb_t)(const bt_mesh_addr_t *addr, u8_t conn_handle, u16_t net_idx);
typedef void (*proxy_client_disconnect_cb_t)(const bt_mesh_addr_t *addr, u8_t conn_handle, u16_t net_idx, u8_t reason);
typedef void (*proxy_client_recv_filter_status_cb_t)(u8_t conn_handle, u16_t src, u16_t net_idx, u8_t filter_type, u16_t list_size);
void bt_mesh_proxy_client_set_adv_recv_cb(proxy_client_recv_adv_cb_t cb);
void bt_mesh_proxy_client_set_conn_cb(proxy_client_connect_cb_t cb);
void bt_mesh_proxy_client_set_disconn_cb(proxy_client_disconnect_cb_t cb);
void bt_mesh_proxy_client_set_filter_status_cb(proxy_client_recv_filter_status_cb_t cb);
void proxy_client_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr);
int bt_mesh_proxy_client_connect(const u8_t addr[6], u8_t addr_type, u16_t net_idx);
int bt_mesh_proxy_client_disconnect(u8_t conn_handle);
bool bt_mesh_proxy_client_beacon_send(struct bt_mesh_subnet *sub);
bool bt_mesh_proxy_client_send(struct net_buf_simple *buf, u16_t dst);
int bt_mesh_proxy_client_send_cfg(u8_t conn_handle, u16_t net_idx, struct bt_mesh_proxy_cfg_pdu *pdu);
int bt_mesh_proxy_prov_client_init(void);
#endif /* _PROVISIONER_PROXY_H_ */

View File

@ -24,10 +24,14 @@
#include "beacon.h"
#include "foundation.h"
#include "access.h"
#include "proxy.h"
#include "proxy_server.h"
#if CONFIG_BLE_MESH_NODE
/* 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");
#define PDU_TYPE(data) (data[0] & BIT_MASK(6))
#define PDU_SAR(data) (data[0] >> 6)
@ -67,7 +71,7 @@ static const struct bt_mesh_adv_param fast_adv_param = {
static bool proxy_adv_enabled;
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
static void proxy_send_beacons(struct k_work *work);
static u16_t proxy_ccc_val;
#endif
@ -87,14 +91,14 @@ static struct bt_mesh_proxy_client {
PROV,
} filter_type;
u8_t msg_type;
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
struct k_work send_beacons;
#endif
struct k_delayed_work sar_timer;
struct net_buf_simple buf;
} clients[BLE_MESH_MAX_CONN] = {
[0 ... (BLE_MESH_MAX_CONN - 1)] = {
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
.send_beacons = _K_WORK_INITIALIZER(proxy_send_beacons),
#endif
},
@ -158,7 +162,7 @@ static void proxy_sar_timeout(struct k_work *work)
bt_mesh_gatts_disconnect(client->conn, 0x13);
}
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
/* Next subnet in queue to be advertised */
static int next_idx;
@ -439,7 +443,7 @@ int bt_mesh_proxy_identity_enable(void)
static void proxy_complete_pdu(struct bt_mesh_proxy_client *client)
{
switch (client->msg_type) {
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
case BLE_MESH_PROXY_NET_PDU:
BT_DBG("Mesh Network PDU");
bt_mesh_net_recv(&client->buf, 0, BLE_MESH_NET_IF_PROXY);
@ -761,7 +765,7 @@ int bt_mesh_proxy_prov_disable(bool disconnect)
#endif /* CONFIG_BLE_MESH_PB_GATT */
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
static ssize_t proxy_ccc_write(struct bt_mesh_conn *conn,
const struct bt_mesh_gatt_attr *attr,
const void *buf, u16_t len,
@ -968,13 +972,13 @@ bool bt_mesh_proxy_relay(struct net_buf_simple *buf, u16_t dst)
return relayed;
}
#endif /* CONFIG_BLE_MESH_GATT_PROXY */
#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */
static int proxy_send(struct bt_mesh_conn *conn, const void *data, u16_t len)
{
BT_DBG("%u bytes: %s", len, bt_hex(data, len));
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
if (gatt_svc == MESH_GATT_PROXY) {
return bt_mesh_gatts_notify(conn, &proxy_attrs[4], data, len);
}
@ -1051,7 +1055,7 @@ static const struct bt_mesh_adv_data prov_ad[] = {
};
#endif /* PB_GATT */
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
#define ID_TYPE_NET 0x00
#define ID_TYPE_NODE 0x01
@ -1360,7 +1364,7 @@ s32_t bt_mesh_proxy_adv_start(void)
}
#endif /* PB_GATT */
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
if (bt_mesh_is_provisioned()) {
return gatt_proxy_advertise(next_sub());
}

View File

@ -27,7 +27,7 @@
#include "transport.h"
#include "access.h"
#include "foundation.h"
#include "proxy.h"
#include "proxy_server.h"
#include "cfg_srv.h"
#include "settings_nvs.h"
@ -743,7 +743,7 @@ static int subnet_init(struct bt_mesh_subnet *sub)
}
}
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY)) {
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
sub->node_id = BLE_MESH_NODE_IDENTITY_STOPPED;
} else {
sub->node_id = BLE_MESH_NODE_IDENTITY_NOT_SUPPORTED;

View File

@ -49,7 +49,7 @@ static esp_ble_mesh_cfg_srv_t config_server = {
#else
.friend_state = ESP_BLE_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_NOT_SUPPORTED,

View File

@ -23,7 +23,7 @@ CONFIG_BLE_MESH_PROV=y
CONFIG_BLE_MESH_NET_BUF_POOL_USAGE=y
CONFIG_BLE_MESH_PROXY=y
CONFIG_BLE_MESH_PB_GATT=y
CONFIG_BLE_MESH_GATT_PROXY=y
CONFIG_BLE_MESH_GATT_PROXY_SERVER=y
CONFIG_BLE_MESH_NODE_ID_TIMEOUT=60
CONFIG_BLE_MESH_PROXY_FILTER_SIZE=1
CONFIG_BLE_MESH_IV_UPDATE_TEST=

View File

@ -53,7 +53,7 @@ esp_ble_mesh_cfg_srv_t cfg_srv = {
#else
.friend_state = ESP_BLE_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_NOT_SUPPORTED,

View File

@ -26,7 +26,7 @@ CONFIG_BLE_MESH_PROV=y
CONFIG_BLE_MESH_NET_BUF_POOL_USAGE=y
CONFIG_BLE_MESH_PROXY=y
CONFIG_BLE_MESH_PB_GATT=y
CONFIG_BLE_MESH_GATT_PROXY=y
CONFIG_BLE_MESH_GATT_PROXY_SERVER=y
CONFIG_BLE_MESH_NODE_ID_TIMEOUT=60
CONFIG_BLE_MESH_PROXY_FILTER_SIZE=1
CONFIG_BLE_MESH_SUBNET_COUNT=1

View File

@ -50,7 +50,7 @@ esp_ble_mesh_cfg_srv_t cfg_srv = {
#else
.friend_state = ESP_BLE_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_NOT_SUPPORTED,

View File

@ -21,13 +21,13 @@ CONFIG_BLE_MESH_PROVISIONER=y
CONFIG_BLE_MESH_WAIT_FOR_PROV_MAX_DEV_NUM=20
CONFIG_BLE_MESH_MAX_PROV_NODES=20
CONFIG_BLE_MESH_PBA_SAME_TIME=10
CONFIG_BLE_MESH_PBG_SAME_TIME=4
CONFIG_BLE_MESH_PBG_SAME_TIME=3
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_PB_GATT=y
CONFIG_BLE_MESH_GATT_PROXY=y
CONFIG_BLE_MESH_GATT_PROXY_SERVER=y
CONFIG_BLE_MESH_RELAY=y
CONFIG_BLE_MESH_LOW_POWER=
CONFIG_BLE_MESH_FRIEND=

View File

@ -52,7 +52,7 @@ static esp_ble_mesh_cfg_srv_t config_server = {
#else
.friend_state = ESP_BLE_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_NOT_SUPPORTED,

View File

@ -28,7 +28,7 @@ CONFIG_BLE_MESH_PROVISIONER_APP_KEY_COUNT=3
CONFIG_BLE_MESH_PB_ADV=y
CONFIG_BLE_MESH_NET_BUF_POOL_USAGE=y
CONFIG_BLE_MESH_PB_GATT=y
CONFIG_BLE_MESH_GATT_PROXY=y
CONFIG_BLE_MESH_GATT_PROXY_SERVER=n
CONFIG_BLE_MESH_RELAY=y
CONFIG_BLE_MESH_LOW_POWER=
CONFIG_BLE_MESH_FRIEND=

View File

@ -58,7 +58,7 @@ esp_ble_mesh_cfg_srv_t config_server = {
#else
.friend_state = ESP_BLE_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_NOT_SUPPORTED,

View File

@ -36,7 +36,7 @@ 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_GATT_PROXY_SERVER=y
CONFIG_BLE_MESH_RELAY=y
CONFIG_BLE_MESH_LOW_POWER=
CONFIG_BLE_MESH_FRIEND=

View File

@ -36,7 +36,7 @@ static esp_ble_mesh_cfg_srv_t config_server = {
#else
.friend_state = ESP_BLE_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_NOT_SUPPORTED,

View File

@ -23,7 +23,7 @@ CONFIG_BLE_MESH_PROV=y
CONFIG_BLE_MESH_NET_BUF_POOL_USAGE=y
CONFIG_BLE_MESH_PROXY=y
CONFIG_BLE_MESH_PB_GATT=y
CONFIG_BLE_MESH_GATT_PROXY=y
CONFIG_BLE_MESH_GATT_PROXY_SERVER=y
CONFIG_BLE_MESH_NODE_ID_TIMEOUT=60
CONFIG_BLE_MESH_PROXY_FILTER_SIZE=1
CONFIG_BLE_MESH_SUBNET_COUNT=1

View File

@ -73,7 +73,7 @@ static esp_ble_mesh_cfg_srv_t config_server = {
#else
.friend_state = ESP_BLE_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_NOT_SUPPORTED,

View File

@ -28,7 +28,7 @@ CONFIG_BLE_MESH_PROVISIONER_APP_KEY_COUNT=3
CONFIG_BLE_MESH_PB_ADV=y
CONFIG_BLE_MESH_NET_BUF_POOL_USAGE=y
CONFIG_BLE_MESH_PB_GATT=y
CONFIG_BLE_MESH_GATT_PROXY=y
CONFIG_BLE_MESH_GATT_PROXY_SERVER=n
CONFIG_BLE_MESH_RELAY=y
CONFIG_BLE_MESH_LOW_POWER=
CONFIG_BLE_MESH_FRIEND=

View File

@ -16,7 +16,7 @@ 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_PB_GATT=y
CONFIG_BLE_MESH_GATT_PROXY=y
CONFIG_BLE_MESH_GATT_PROXY_SERVER=y
CONFIG_BLE_MESH_RELAY=y
CONFIG_BLE_MESH_LOW_POWER=
CONFIG_BLE_MESH_FRIEND=

View File

@ -70,7 +70,7 @@ esp_ble_mesh_cfg_srv_t config_server = {
#else
.friend_state = ESP_BLE_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_NOT_SUPPORTED,

View File

@ -36,7 +36,7 @@ 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_PB_GATT=y
CONFIG_BLE_MESH_GATT_PROXY=y
CONFIG_BLE_MESH_GATT_PROXY_SERVER=y
CONFIG_BLE_MESH_RELAY=y
CONFIG_BLE_MESH_LOW_POWER=
CONFIG_BLE_MESH_FRIEND=