Merge branch 'feat/ble_mesh_4_1_new_features' into 'master'

ESP BLE Mesh 4.1 new features

Closes BLEMESH-1, BLEMESH-2, BLEMESH-3, BLEMESH-4, BLEMESH-39, and BLEMESH-43

See merge request espressif/esp-idf!6134
This commit is contained in:
Jiang Jiang Jian 2019-11-14 16:47:49 +08:00
commit e380c59c74
165 changed files with 23824 additions and 4114 deletions

View File

@ -311,12 +311,14 @@ if(CONFIG_BT_ENABLED)
if(CONFIG_BLE_MESH)
list(APPEND include_dirs
"esp_ble_mesh/mesh_common/include"
"esp_ble_mesh/mesh_core"
"esp_ble_mesh/mesh_core/include"
"esp_ble_mesh/mesh_core/settings"
"esp_ble_mesh/mesh_core/storage"
"esp_ble_mesh/btc/include"
"esp_ble_mesh/mesh_models/common/include"
"esp_ble_mesh/mesh_models/client/include"
"esp_ble_mesh/mesh_models/server/include"
"esp_ble_mesh/api/core/include"
"esp_ble_mesh/api/models/include"
"esp_ble_mesh/api")
@ -340,7 +342,13 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/btc/btc_ble_mesh_prov.c"
"esp_ble_mesh/btc/btc_ble_mesh_sensor_model.c"
"esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c"
"esp_ble_mesh/mesh_core/settings/settings_nvs.c"
"esp_ble_mesh/mesh_common/mesh_aes_encrypt.c"
"esp_ble_mesh/mesh_common/mesh_atomic.c"
"esp_ble_mesh/mesh_common/mesh_buf.c"
"esp_ble_mesh/mesh_common/mesh_common.c"
"esp_ble_mesh/mesh_common/mesh_kernel.c"
"esp_ble_mesh/mesh_common/mesh_util.c"
"esp_ble_mesh/mesh_core/storage/settings_nvs.c"
"esp_ble_mesh/mesh_core/access.c"
"esp_ble_mesh/mesh_core/adv.c"
"esp_ble_mesh/mesh_core/beacon.c"
@ -351,28 +359,30 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/mesh_core/health_cli.c"
"esp_ble_mesh/mesh_core/health_srv.c"
"esp_ble_mesh/mesh_core/lpn.c"
"esp_ble_mesh/mesh_core/mesh_aes_encrypt.c"
"esp_ble_mesh/mesh_core/mesh_atomic.c"
"esp_ble_mesh/mesh_core/mesh_buf.c"
"esp_ble_mesh/mesh_core/mesh_kernel.c"
"esp_ble_mesh/mesh_core/mesh_main.c"
"esp_ble_mesh/mesh_core/mesh_util.c"
"esp_ble_mesh/mesh_core/main.c"
"esp_ble_mesh/mesh_core/net.c"
"esp_ble_mesh/mesh_core/prov.c"
"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"
"esp_ble_mesh/mesh_models/common/mesh_common.c"
"esp_ble_mesh/mesh_models/client/client_common.c"
"esp_ble_mesh/mesh_models/client/generic_client.c"
"esp_ble_mesh/mesh_models/client/lighting_client.c"
"esp_ble_mesh/mesh_models/client/sensor_client.c"
"esp_ble_mesh/mesh_models/client/time_scene_client.c")
"esp_ble_mesh/mesh_models/client/time_scene_client.c"
"esp_ble_mesh/mesh_models/server/device_property.c"
"esp_ble_mesh/mesh_models/server/generic_server.c"
"esp_ble_mesh/mesh_models/server/lighting_server.c"
"esp_ble_mesh/mesh_models/server/sensor_server.c"
"esp_ble_mesh/mesh_models/server/server_common.c"
"esp_ble_mesh/mesh_models/server/state_binding.c"
"esp_ble_mesh/mesh_models/server/state_transition.c"
"esp_ble_mesh/mesh_models/server/time_scene_server.c")
endif()
if(CONFIG_BT_NIMBLE_ENABLED)

View File

@ -132,6 +132,10 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = {
[BTC_PID_LIGHTING_CLIENT] = {btc_ble_mesh_lighting_client_call_handler, btc_ble_mesh_lighting_client_cb_handler },
[BTC_PID_SENSOR_CLIENT] = {btc_ble_mesh_sensor_client_call_handler, btc_ble_mesh_sensor_client_cb_handler },
[BTC_PID_TIME_SCENE_CLIENT] = {btc_ble_mesh_time_scene_client_call_handler, btc_ble_mesh_time_scene_client_cb_handler},
[BTC_PID_GENERIC_SERVER] = {NULL, btc_ble_mesh_generic_server_cb_handler },
[BTC_PID_LIGHTING_SERVER] = {NULL, btc_ble_mesh_lighting_server_cb_handler },
[BTC_PID_SENSOR_SERVER] = {NULL, btc_ble_mesh_sensor_server_cb_handler },
[BTC_PID_TIME_SCENE_SERVER] = {NULL, btc_ble_mesh_time_scene_server_cb_handler},
#endif /* #if CONFIG_BLE_MESH */
};

View File

@ -81,6 +81,10 @@ typedef enum {
BTC_PID_LIGHTING_CLIENT,
BTC_PID_SENSOR_CLIENT,
BTC_PID_TIME_SCENE_CLIENT,
BTC_PID_GENERIC_SERVER,
BTC_PID_LIGHTING_SERVER,
BTC_PID_SENSOR_SERVER,
BTC_PID_TIME_SCENE_SERVER,
#endif /* CONFIG_BLE_MESH */
BTC_PID_NUM,
} btc_pid_t; //btc profile id

View File

@ -140,21 +140,24 @@ endif
endif
ifdef CONFIG_BLE_MESH
COMPONENT_ADD_INCLUDEDIRS += esp_ble_mesh/mesh_core \
COMPONENT_ADD_INCLUDEDIRS += esp_ble_mesh/mesh_common/include \
esp_ble_mesh/mesh_core \
esp_ble_mesh/mesh_core/include \
esp_ble_mesh/mesh_core/settings \
esp_ble_mesh/mesh_core/storage \
esp_ble_mesh/btc/include \
esp_ble_mesh/mesh_models/common/include \
esp_ble_mesh/mesh_models/client/include \
esp_ble_mesh/mesh_models/server/include \
esp_ble_mesh/api/core/include \
esp_ble_mesh/api/models/include \
esp_ble_mesh/api
COMPONENT_SRCDIRS += esp_ble_mesh/mesh_core \
esp_ble_mesh/mesh_core/settings \
COMPONENT_SRCDIRS += esp_ble_mesh/mesh_common \
esp_ble_mesh/mesh_core \
esp_ble_mesh/mesh_core/storage \
esp_ble_mesh/btc \
esp_ble_mesh/mesh_models/common \
esp_ble_mesh/mesh_models/client \
esp_ble_mesh/mesh_models/server \
esp_ble_mesh/api/core \
esp_ble_mesh/api/models
endif

View File

@ -60,7 +60,7 @@ if BLE_MESH
config BLE_MESH_MAX_STORED_NODES
int "Maximum number of nodes whose information can be stored"
default 20
range 1 1000
range BLE_MESH_MAX_PROV_NODES 1000
help
This option specifies the maximum number of nodes whose information can be
stored by a Provisioner in its upper layer.
@ -71,7 +71,7 @@ if BLE_MESH
config BLE_MESH_MAX_PROV_NODES
int "Maximum number of devices that can be provisioned by Provisioner"
default 20
range 1 100
range 1 1000
help
This option specifies how many devices can be provisioned by a Provisioner.
This value indicates the maximum number of unprovisioned devices which can be
@ -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
depends on BLE_MESH_NODE
default y
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.
@ -416,14 +427,39 @@ if BLE_MESH
config BLE_MESH_RELAY
bool "Relay support"
depends on BLE_MESH_NODE
default y
help
Support for acting as a Mesh Relay Node. Enabling this option will allow
a node to support the Relay feature, and the Relay feature can still
be enabled or disabled by proper configuration messages. Disabling this
option will let a node not support the Relay feature.
if BLE_MESH_RELAY
config BLE_MESH_RELAY_ADV_BUF
bool "Use separate advertising buffers for relay packets"
default n
help
When selected, self-send packets will be put in a high-priority
queue and relay packets will be put in a low-priority queue.
if BLE_MESH_RELAY_ADV_BUF
config BLE_MESH_RELAY_ADV_BUF_COUNT
int "Number of advertising buffers for relay packets"
default 60
range 6 256
help
Number of advertising buffers for relay packets available.
endif # BLE_MESH_RELAY_ADV_BUF
endif # BLE_MESH_RELAY
config BLE_MESH_LOW_POWER
bool "Support for Low Power features"
depends on BLE_MESH_NODE
help
Enable this option to operate as a Low Power Node. If low power consumption
is required by a node, this option should be enabled. And once the node
@ -434,7 +470,7 @@ if BLE_MESH
config BLE_MESH_LPN_ESTABLISHMENT
bool "Perform Friendship establishment using low power"
default y
default n
help
Perform the Friendship establishment using low power with the help of a
reduced scan duty cycle. The downside of this is that the node may miss
@ -446,7 +482,7 @@ if BLE_MESH
config BLE_MESH_LPN_AUTO
bool "Automatically start looking for Friend nodes once provisioned"
default y
default n
help
Once provisioned, automatically enable LPN functionality and start looking
for Friend nodes. If this option is disabled LPN mode needs to be manually
@ -465,8 +501,8 @@ if BLE_MESH
before starting to look for Friend nodes.
config BLE_MESH_LPN_RETRY_TIMEOUT
int "Retry timeout for Friend Requests"
default 8
int "Retry timeout for Friend requests"
default 6
range 1 3600
help
Time in seconds between Friend Requests, if a previous Friend Request did
@ -555,6 +591,7 @@ if BLE_MESH
config BLE_MESH_FRIEND
bool "Support for acting as a Friend Node"
depends on BLE_MESH_NODE
help
Enable this option to be able to act as a Friend Node.
@ -689,16 +726,6 @@ if BLE_MESH
endmenu #BLE Mesh NET BUF DEBUG LOG LEVEL
config BLE_MESH_IRQ_LOCK
bool "Used the IRQ lock instead of task lock"
help
To improve the real-time requirements of bt controller in BLE Mesh,
task lock is used to replace IRQ lock.
With this option enabled, interrupt lock instead of the mutex will
be used and the BLE Mesh stack will try to change interrupt level to
protect some critical situations. Users need to ensure that this option
is disabled so mutex will be used in the bottom layer.
config BLE_MESH_CLIENT_MSG_TIMEOUT
int "Timeout(ms) for client message response"
range 100 1200000

View File

@ -15,10 +15,51 @@
#include <stdint.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_err.h"
#include "btc_ble_mesh_prov.h"
#include "esp_ble_mesh_defs.h"
esp_err_t esp_ble_mesh_lpn_enable(void)
{
btc_msg_t msg = {0};
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_LPN_ENABLE;
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_lpn_disable(bool force)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_LPN_DISABLE;
arg.lpn_disable.force = force;
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_lpn_poll(void)
{
btc_msg_t msg = {0};
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_LPN_POLL;
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@ -25,7 +25,7 @@
#define ESP_BLE_MESH_TX_SDU_MAX ((CONFIG_BLE_MESH_ADV_BUF_COUNT - 3) * 12)
static esp_err_t ble_mesh_send_msg(esp_ble_mesh_model_t *model,
static esp_err_t ble_mesh_model_send_msg(esp_ble_mesh_model_t *model,
esp_ble_mesh_msg_ctx_t *ctx,
uint32_t opcode,
btc_ble_mesh_model_act_t act,
@ -41,7 +41,13 @@ static esp_err_t ble_mesh_send_msg(esp_ble_mesh_model_t *model,
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
if (ctx && ctx->addr == ESP_BLE_MESH_ADDR_UNASSIGNED) {
LOG_ERROR("%s, Invalid destination address 0x0000", __func__);
return ESP_ERR_INVALID_ARG;
}
if (device_role > ROLE_FAST_PROV) {
LOG_ERROR("%s, Invalid device role 0x%02x", __func__, device_role);
return ESP_ERR_INVALID_ARG;
}
@ -106,7 +112,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);
@ -165,7 +171,7 @@ esp_err_t esp_ble_mesh_server_model_send_msg(esp_ble_mesh_model_t *model,
if (!model || !ctx) {
return ESP_ERR_INVALID_ARG;
}
return ble_mesh_send_msg(model, ctx, opcode, BTC_BLE_MESH_ACT_SERVER_MODEL_SEND,
return ble_mesh_model_send_msg(model, ctx, opcode, BTC_BLE_MESH_ACT_SERVER_MODEL_SEND,
length, data, 0, false, ROLE_NODE);
}
@ -177,7 +183,7 @@ esp_err_t esp_ble_mesh_client_model_send_msg(esp_ble_mesh_model_t *model,
if (!model || !ctx) {
return ESP_ERR_INVALID_ARG;
}
return ble_mesh_send_msg(model, ctx, opcode, BTC_BLE_MESH_ACT_CLIENT_MODEL_SEND,
return ble_mesh_model_send_msg(model, ctx, opcode, BTC_BLE_MESH_ACT_CLIENT_MODEL_SEND,
length, data, msg_timeout, need_rsp, device_role);
}
@ -188,10 +194,35 @@ esp_err_t esp_ble_mesh_model_publish(esp_ble_mesh_model_t *model, uint32_t opcod
if (!model || !model->pub || !model->pub->msg) {
return ESP_ERR_INVALID_ARG;
}
return ble_mesh_send_msg(model, NULL, opcode, BTC_BLE_MESH_ACT_MODEL_PUBLISH,
return ble_mesh_model_send_msg(model, NULL, opcode, BTC_BLE_MESH_ACT_MODEL_PUBLISH,
length, data, 0, false, device_role);
}
esp_err_t esp_ble_mesh_server_model_update_state(esp_ble_mesh_model_t *model,
esp_ble_mesh_server_state_type_t type,
esp_ble_mesh_server_state_value_t *value)
{
btc_ble_mesh_model_args_t arg = {0};
btc_msg_t msg = {0};
if (!model || !value || type >= ESP_BLE_MESH_SERVER_MODEL_STATE_MAX) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
arg.model_update_state.model = model;
arg.model_update_state.type = type;
arg.model_update_state.value = value;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_MODEL;
msg.act = BTC_BLE_MESH_ACT_SERVER_MODEL_UPDATE_STATE;
return (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);
}
esp_err_t esp_ble_mesh_node_local_reset(void)
{
btc_msg_t msg = {0};

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_ble_mesh_bd_addr_t addr,
esp_ble_mesh_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 > ESP_BLE_MESH_ADDR_TYPE_RANDOM) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_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, 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_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_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, esp_ble_mesh_proxy_filter_type_t filter_type)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
if (filter_type > PROXY_FILTER_BLACKLIST) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_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_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_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_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_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

@ -17,4 +17,45 @@
#include "esp_ble_mesh_defs.h"
/**
* @brief Enable BLE Mesh device LPN functionality.
*
* @note This API enables LPN functionality. Once called, the proper
* Friend Request will be sent.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_lpn_enable(void);
/**
* @brief Disable BLE Mesh device LPN functionality.
*
* @param[in] force: when disabling LPN functionality, use this flag to indicate
* whether directly clear corresponding information or just
* send friend clear to disable it if friendship has already
* been established.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_lpn_disable(bool force);
/**
* @brief LPN tries to poll messages from the Friend Node.
*
* @note The Friend Poll message is sent by a Low Power node to ask the Friend
* node to send a message that it has stored for the Low Power node.
* Users can call this API to send Friend Poll message manually. If this
* API is not invoked, the bottom layer of the Low Power node will send
* Friend Poll before the PollTimeout timer expires.
* If the corresponding Friend Update is received and MD is set to 0,
* which means there are no messages for the Low Power node, then the
* Low Power node will stop scanning.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_lpn_poll(void);
#endif /* _ESP_BLE_MESH_LOW_POWER_API_H_ */

View File

@ -134,6 +134,25 @@ esp_err_t esp_ble_mesh_model_publish(esp_ble_mesh_model_t *model, uint32_t opcod
uint16_t length, uint8_t *data,
esp_ble_mesh_dev_role_t device_role);
/**
* @brief Update a server model state value. If the model publication
* state is set properly (e.g. publish address is set to a valid
* address), it will publish corresponding status message.
*
* @note Currently this API is used to update bound state value, not
* for all server model states.
*
* @param[in] model: Server model which is going to update the state.
* @param[in] type: Server model state type.
* @param[in] value: Server model state value.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_server_model_update_state(esp_ble_mesh_model_t *model,
esp_ble_mesh_server_state_type_t type,
esp_ble_mesh_server_state_value_t *value);
/**
* @brief Reset the provisioning procedure of the local BLE Mesh node.
*

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_ble_mesh_bd_addr_t addr,
esp_ble_mesh_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, esp_ble_mesh_proxy_filter_type_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_ */

File diff suppressed because it is too large Load Diff

View File

@ -70,3 +70,10 @@ esp_err_t esp_ble_mesh_generic_client_set_state(esp_ble_mesh_client_common_param
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_generic_client_args_t), btc_ble_mesh_generic_client_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_register_generic_server_callback(esp_ble_mesh_generic_server_cb_t callback)
{
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_GENERIC_SERVER, callback) == 0 ? ESP_OK : ESP_FAIL);
}

View File

@ -83,12 +83,16 @@ esp_err_t esp_ble_mesh_health_server_fault_update(esp_ble_mesh_elem_t *element)
btc_ble_mesh_health_server_args_t arg = {0};
btc_msg_t msg = {0};
if (element == NULL) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HEALTH_SERVER;
msg.act = BTC_BLE_MESH_ACT_HEALTH_SERVER_FAULT_UPDATE;
arg.fault_update.element = element;
arg.health_fault_update.element = element;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_health_server_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);

View File

@ -71,3 +71,9 @@ esp_err_t esp_ble_mesh_light_client_set_state(esp_ble_mesh_client_common_param_t
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_register_lighting_server_callback(esp_ble_mesh_lighting_server_cb_t callback)
{
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_LIGHTING_SERVER, callback) == 0 ? ESP_OK : ESP_FAIL);
}

View File

@ -71,3 +71,11 @@ esp_err_t esp_ble_mesh_sensor_client_set_state(esp_ble_mesh_client_common_param_
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_register_sensor_server_callback(esp_ble_mesh_sensor_server_cb_t callback)
{
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_SENSOR_SERVER, callback) == 0 ? ESP_OK : ESP_FAIL);
}

View File

@ -71,3 +71,10 @@ esp_err_t esp_ble_mesh_time_scene_client_set_state(esp_ble_mesh_client_common_pa
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_register_time_scene_server_callback(esp_ble_mesh_time_scene_server_cb_t callback)
{
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_TIME_SCENE_SERVER, callback) == 0 ? ESP_OK : ESP_FAIL);
}

View File

@ -79,8 +79,8 @@ typedef struct esp_ble_mesh_cfg_srv {
uint8_t min_hops; /*!< Minimum hops when receiving Heartbeat messages */
uint8_t max_hops; /*!< Maximum hops when receiving Heartbeat messages */
/** Optional subscription tracking function */
void (*func)(uint8_t hops, uint16_t feature);
/** Optional heartbeat subscription tracking function */
esp_ble_mesh_cb_t heartbeat_recv_cb;
} heartbeat_sub;
} esp_ble_mesh_cfg_srv_t;
@ -610,28 +610,135 @@ typedef enum {
ESP_BLE_MESH_CFG_CLIENT_EVT_MAX,
} esp_ble_mesh_cfg_client_cb_event_t;
/** Parameter of Config AppKey Add */
/**
* @brief Configuration Server model related context.
*/
typedef struct {
uint16_t app_idx; /*!< AppKey Index of the Config AppKey Add */
} esp_ble_mesh_cfg_srv_app_key_add_cb_t;
uint16_t element_addr; /*!< Element Address */
uint16_t pub_addr; /*!< Publish Address */
uint16_t app_idx; /*!< AppKey Index */
bool cred_flag; /*!< Friendship Credential Flag */
uint8_t pub_ttl; /*!< Publish TTL */
uint8_t pub_period; /*!< Publish Period */
uint8_t pub_retransmit; /*!< Publish Retransmit */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_state_change_cfg_mod_pub_set_t;
/** Parameters of Config Model Subscription Add */
typedef struct {
uint16_t element_addr; /*!< Element Address */
uint16_t sub_addr; /*!< Subscription Address */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_state_change_cfg_model_sub_add_t;
/** Parameters of Config Model Subscription Delete */
typedef struct {
uint16_t element_addr; /*!< Element Address */
uint16_t sub_addr; /*!< Subscription Address */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_state_change_cfg_model_sub_delete_t;
/** Parameters of Config NetKey Add */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
uint8_t net_key[16]; /*!< NetKey */
} esp_ble_mesh_state_change_cfg_netkey_add_t;
/** Parameters of Config NetKey Update */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
uint8_t net_key[16]; /*!< NetKey */
} esp_ble_mesh_state_change_cfg_netkey_update_t;
/** Parameter of Config NetKey Delete */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
} esp_ble_mesh_state_change_cfg_netkey_delete_t;
/** Parameters of Config AppKey Add */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
uint16_t app_idx; /*!< AppKey Index */
uint8_t app_key[16]; /*!< AppKey */
} esp_ble_mesh_state_change_cfg_appkey_add_t;
/** Parameters of Config AppKey Update */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
uint16_t app_idx; /*!< AppKey Index */
uint8_t app_key[16]; /*!< AppKey */
} esp_ble_mesh_state_change_cfg_appkey_update_t;
/** Parameters of Config AppKey Delete */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
uint16_t app_idx; /*!< AppKey Index */
} esp_ble_mesh_state_change_cfg_appkey_delete_t;
/** Parameters of Config Model App Bind */
typedef struct {
uint16_t element_addr; /*!< Element Address */
uint16_t app_idx; /*!< AppKey Index */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_state_change_cfg_model_app_bind_t;
/** Parameters of Config Model App Unbind */
typedef struct {
uint16_t element_addr; /*!< Element Address */
uint16_t app_idx; /*!< AppKey Index */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_state_change_cfg_model_app_unbind_t;
/** Parameters of Config Key Refresh Phase Set */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
uint8_t kr_phase; /*!< New Key Refresh Phase Transition */
} esp_ble_mesh_state_change_cfg_kr_phase_set_t;
/**
* @brief Configuration Server Model received message union
* @brief Configuration Server model state change value union
*/
typedef union {
esp_ble_mesh_cfg_srv_app_key_add_cb_t app_key_add; /*!< The Config AppKey Add event value */
} esp_ble_mesh_cfg_server_common_cb_param_t;
/**
* The recv_op in ctx can be used to decide which state is changed.
*/
esp_ble_mesh_state_change_cfg_mod_pub_set_t mod_pub_set; /*!< Config Model Publication Set */
esp_ble_mesh_state_change_cfg_model_sub_add_t mod_sub_add; /*!< Config Model Subscription Add */
esp_ble_mesh_state_change_cfg_model_sub_delete_t mod_sub_delete; /*!< Config Model Subscription Delete */
esp_ble_mesh_state_change_cfg_netkey_add_t netkey_add; /*!< Config NetKey Add */
esp_ble_mesh_state_change_cfg_netkey_update_t netkey_update; /*!< Config NetKey Update */
esp_ble_mesh_state_change_cfg_netkey_delete_t netkey_delete; /*!< Config NetKey Delete */
esp_ble_mesh_state_change_cfg_appkey_add_t appkey_add; /*!< Config AppKey Add */
esp_ble_mesh_state_change_cfg_appkey_update_t appkey_update; /*!< Config AppKey Update */
esp_ble_mesh_state_change_cfg_appkey_delete_t appkey_delete; /*!< Config AppKey Delete */
esp_ble_mesh_state_change_cfg_model_app_bind_t mod_app_bind; /*!< Config Model App Bind */
esp_ble_mesh_state_change_cfg_model_app_unbind_t mod_app_unbind; /*!< Config Model App Unbind */
esp_ble_mesh_state_change_cfg_kr_phase_set_t kr_phase_set; /*!< Config Key Refresh Phase Set */
} esp_ble_mesh_cfg_server_state_change_t;
/** Configuration Server Model callback parameters */
/**
* @brief Configuration Server model callback value union
*/
typedef union {
esp_ble_mesh_cfg_server_state_change_t state_change; /*!< ESP_BLE_MESH_CFG_SERVER_STATE_CHANGE_EVT */
} esp_ble_mesh_cfg_server_cb_value_t;
/** Configuration Server model callback parameters */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the server model structure */
esp_ble_mesh_msg_ctx_t ctx; /*!< The context of the received message */
esp_ble_mesh_cfg_server_common_cb_param_t status_cb; /*!< The received configuration message callback values */
esp_ble_mesh_msg_ctx_t ctx; /*!< Context of the received message */
esp_ble_mesh_cfg_server_cb_value_t value; /*!< Value of the received configuration messages */
} esp_ble_mesh_cfg_server_cb_param_t;
/** This enum value is the event of Configuration Server Model */
/** This enum value is the event of Configuration Server model */
typedef enum {
ESP_BLE_MESH_CFG_SERVER_RECV_MSG_EVT,
ESP_BLE_MESH_CFG_SERVER_STATE_CHANGE_EVT,
ESP_BLE_MESH_CFG_SERVER_EVT_MAX,
} esp_ble_mesh_cfg_server_cb_event_t;

View File

@ -523,6 +523,775 @@ esp_err_t esp_ble_mesh_generic_client_get_state(esp_ble_mesh_client_common_param
esp_err_t esp_ble_mesh_generic_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_generic_client_set_state_t *set_state);
/**
* @brief Generic Server Models related context.
*/
/** @def ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV
*
* @brief Define a new Generic OnOff Server Model.
*
* @note 1. The Generic OnOff Server Model is a root model.
* 2. This model shall support model publication and model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_onoff_srv_t.
*
* @return New Generic OnOff Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_GEN_LEVEL_SRV
*
* @brief Define a new Generic Level Server Model.
*
* @note 1. The Generic Level Server Model is a root model.
* 2. This model shall support model publication and model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_level_srv_t.
*
* @return New Generic Level Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_LEVEL_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LEVEL_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_SRV
*
* @brief Define a new Generic Default Transition Time Server Model.
*
* @note 1. The Generic Default Transition Time Server Model is a root model.
* 2. This model shall support model publication and model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_def_trans_time_srv_t.
*
* @return New Generic Default Transition Time Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_SRV
*
* @brief Define a new Generic Power OnOff Server Model.
*
* @note 1. The Generic Power OnOff Server model extends the Generic OnOff Server
* model. When this model is present on an element, the corresponding
* Generic Power OnOff Setup Server model shall also be present.
* 2. This model may be used to represent a variety of devices that do not
* fit any of the model descriptions that have been defined but support
* the generic properties of On/Off.
* 3. This model shall support model publication and model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_power_onoff_srv_t.
*
* @return New Generic Power OnOff Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_SETUP_SRV
*
* @brief Define a new Generic Power OnOff Setup Server Model.
*
* @note 1. The Generic Power OnOff Setup Server model extends the Generic Power
* OnOff Server model and the Generic Default Transition Time Server model.
* 2. This model shall support model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_power_onoff_setup_srv_t.
*
* @return New Generic Power OnOff Setup Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_SETUP_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_SRV
*
* @brief Define a new Generic Power Level Server Model.
*
* @note 1. The Generic Power Level Server model extends the Generic Power OnOff
* Server model and the Generic Level Server model. When this model is
* present on an Element, the corresponding Generic Power Level Setup
* Server model shall also be present.
* 2. This model shall support model publication and model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_power_level_srv_t.
*
* @return New Generic Power Level Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_SETUP_SRV
*
* @brief Define a new Generic Power Level Setup Server Model.
*
* @note 1. The Generic Power Level Setup Server model extends the Generic Power
* Level Server model and the Generic Power OnOff Setup Server model.
* 2. This model shall support model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_power_level_setup_srv_t.
*
* @return New Generic Power Level Setup Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_SETUP_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_GEN_BATTERY_SRV
*
* @brief Define a new Generic Battery Server Model.
*
* @note 1. The Generic Battery Server Model is a root model.
* 2. This model shall support model publication and model subscription.
* 3. The model may be used to represent an element that is powered by a battery.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_battery_srv_t.
*
* @return New Generic Battery Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_BATTERY_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_BATTERY_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_GEN_LOCATION_SRV
*
* @brief Define a new Generic Location Server Model.
*
* @note 1. The Generic Location Server model is a root model. When this model
* is present on an Element, the corresponding Generic Location Setup
* Server model shall also be present.
* 2. This model shall support model publication and model subscription.
* 3. The model may be used to represent an element that knows its
* location (global or local).
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_location_srv_t.
*
* @return New Generic Location Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_LOCATION_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LOCATION_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_GEN_LOCATION_SETUP_SRV
*
* @brief Define a new Generic Location Setup Server Model.
*
* @note 1. The Generic Location Setup Server model extends the Generic Location
* Server model.
* 2. This model shall support model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_location_setup_srv_t.
*
* @return New Generic Location Setup Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_LOCATION_SETUP_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LOCATION_SETUP_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_GEN_USER_PROP_SRV
*
* @brief Define a new Generic User Property Server Model.
*
* @note 1. The Generic User Property Server model is a root model.
* 2. This model shall support model publication and model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_user_prop_srv_t.
*
* @return New Generic User Property Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_USER_PROP_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_USER_PROP_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_GEN_ADMIN_PROP_SRV
*
* @brief Define a new Generic Admin Property Server Model.
*
* @note 1. The Generic Admin Property Server model extends the Generic User
* Property Server model.
* 2. This model shall support model publication and model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_admin_prop_srv_t.
*
* @return New Generic Admin Property Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_ADMIN_PROP_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_GEN_MANUFACTURER_PROP_SRV
*
* @brief Define a new Generic Manufacturer Property Server Model.
*
* @note 1. The Generic Manufacturer Property Server model extends the Generic
* User Property Server model.
* 2. This model shall support model publication and model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_manu_prop_srv_t.
*
* @return New Generic Manufacturer Property Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_MANUFACTURER_PROP_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_GEN_CLIENT_PROP_SRV
*
* @brief Define a new Generic User Property Server Model.
*
* @note 1. The Generic Client Property Server model is a root model.
* 2. This model shall support model publication and model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_gen_client_prop_srv_t.
*
* @return New Generic Client Property Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_CLIENT_PROP_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV, \
NULL, srv_pub, srv_data)
/** Parameters of Generic OnOff state */
typedef struct {
uint8_t onoff; /*!< The present value of the Generic OnOff state */
uint8_t target_onoff; /*!< The target value of the Generic OnOff state */
} esp_ble_mesh_gen_onoff_state_t;
/** User data of Generic OnOff Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic OnOff Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_gen_onoff_state_t state; /*!< Parameters of the Generic OnOff state */
esp_ble_mesh_last_msg_info_t last; /*!< Parameters of the last received set message */
esp_ble_mesh_state_transition_t transition; /*!< Parameters of state transition */
} esp_ble_mesh_gen_onoff_srv_t;
/** Parameters of Generic Level state */
typedef struct {
int16_t level; /*!< The present value of the Generic Level state */
int16_t target_level; /*!< The target value of the Generic Level state */
/**
* When a new transaction starts, level should be set to last_last, and use
* "level + incoming delta" to calculate the target level. In another word,
* "last_level" is used to record "level" of the last transaction, and
* "last_delta" is used to record the previously received delta_level value.
*/
int16_t last_level; /*!< The last value of the Generic Level state */
int32_t last_delta; /*!< The last delta change of the Generic Level state */
bool move_start; /*!< Indicate if the transition of the Generic Level state has been started */
bool positive; /*!< Indicate if the transition is positive or negative */
} esp_ble_mesh_gen_level_state_t;
/** User data of Generic Level Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Level Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_gen_level_state_t state; /*!< Parameters of the Generic Level state */
esp_ble_mesh_last_msg_info_t last; /*!< Parameters of the last received set message */
esp_ble_mesh_state_transition_t transition; /*!< Parameters of state transition */
int32_t tt_delta_level; /*!< Delta change value of level state transition */
} esp_ble_mesh_gen_level_srv_t;
/** Parameter of Generic Default Transition Time state */
typedef struct {
uint8_t trans_time; /*!< The value of the Generic Default Transition Time state */
} esp_ble_mesh_gen_def_trans_time_state_t;
/** User data of Generic Default Transition Time Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Default Transition Time Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_gen_def_trans_time_state_t state; /*!< Parameters of the Generic Default Transition Time state */
} esp_ble_mesh_gen_def_trans_time_srv_t;
/** Parameter of Generic OnPowerUp state */
typedef struct {
uint8_t onpowerup; /*!< The value of the Generic OnPowerUp state */
} esp_ble_mesh_gen_onpowerup_state_t;
/** User data of Generic Power OnOff Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Power OnOff Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_gen_onpowerup_state_t *state; /*!< Parameters of the Generic OnPowerUp state */
} esp_ble_mesh_gen_power_onoff_srv_t;
/** User data of Generic Power OnOff Setup Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Power OnOff Setup Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_gen_onpowerup_state_t *state; /*!< Parameters of the Generic OnPowerUp state */
} esp_ble_mesh_gen_power_onoff_setup_srv_t;
/** Parameters of Generic Power Level state */
typedef struct {
uint16_t power_actual; /*!< The present value of the Generic Power Actual state */
uint16_t target_power_actual; /*!< The target value of the Generic Power Actual state */
uint16_t power_last; /*!< The value of the Generic Power Last state */
uint16_t power_default; /*!< The value of the Generic Power Default state */
uint8_t status_code; /*!< The status code of setting Generic Power Range state */
uint16_t power_range_min; /*!< The minimum value of the Generic Power Range state */
uint16_t power_range_max; /*!< The maximum value of the Generic Power Range state */
} esp_ble_mesh_gen_power_level_state_t;
/** User data of Generic Power Level Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Power Level Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_gen_power_level_state_t *state; /*!< Parameters of the Generic Power Level state */
esp_ble_mesh_last_msg_info_t last; /*!< Parameters of the last received set message */
esp_ble_mesh_state_transition_t transition; /*!< Parameters of state transition */
int32_t tt_delta_level; /*!< Delta change value of level state transition */
} esp_ble_mesh_gen_power_level_srv_t;
/** User data of Generic Power Level Setup Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Power Level Setup Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_gen_power_level_state_t *state; /*!< Parameters of the Generic Power Level state */
} esp_ble_mesh_gen_power_level_setup_srv_t;
/** Parameters of Generic Battery state */
typedef struct {
uint32_t battery_level : 8, /*!< The value of the Generic Battery Level state */
time_to_discharge : 24; /*!< The value of the Generic Battery Time to Discharge state */
uint32_t time_to_charge : 24, /*!< The value of the Generic Battery Time to Charge state */
battery_flags : 8; /*!< The value of the Generic Battery Flags state */
} esp_ble_mesh_gen_battery_state_t;
/** User data of Generic Battery Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Battery Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_gen_battery_state_t state; /*!< Parameters of the Generic Battery state */
} esp_ble_mesh_gen_battery_srv_t;
/** Parameters of Generic Location state */
typedef struct {
int32_t global_latitude; /*!< The value of the Global Latitude field */
int32_t global_longitude; /*!< The value of the Global Longtitude field */
int16_t global_altitude; /*!< The value of the Global Altitude field */
int16_t local_north; /*!< The value of the Local North field */
int16_t local_east; /*!< The value of the Local East field */
int16_t local_altitude; /*!< The value of the Local Altitude field */
uint8_t floor_number; /*!< The value of the Floor Number field */
uint16_t uncertainty; /*!< The value of the Uncertainty field */
} esp_ble_mesh_gen_location_state_t;
/** User data of Generic Location Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Location Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_gen_location_state_t *state; /*!< Parameters of the Generic Location state */
} esp_ble_mesh_gen_location_srv_t;
/** User data of Generic Location Setup Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Location Setup Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_gen_location_state_t *state; /*!< Parameters of the Generic Location state */
} esp_ble_mesh_gen_location_setup_srv_t;
/** This enum value is the access vlue of Generic User Property */
typedef enum {
ESP_BLE_MESH_GEN_USER_ACCESS_PROHIBIT,
ESP_BLE_MESH_GEN_USER_ACCESS_READ,
ESP_BLE_MESH_GEN_USER_ACCESS_WRITE,
ESP_BLE_MESH_GEN_USER_ACCESS_READ_WRITE,
} esp_ble_mesh_gen_user_prop_access_t;
/** This enum value is the access value of Generic Admin Property */
typedef enum {
ESP_BLE_MESH_GEN_ADMIN_NOT_USER_PROP,
ESP_BLE_MESH_GEN_ADMIN_ACCESS_READ,
ESP_BLE_MESH_GEN_ADMIN_ACCESS_WRITE,
ESP_BLE_MESH_GEN_ADMIN_ACCESS_READ_WRITE,
} esp_ble_mesh_gen_admin_prop_access_t;
/** This enum value is the access value of Generic Manufacturer Property */
typedef enum {
ESP_BLE_MESH_GEN_MANU_NOT_USER_PROP,
ESP_BLE_MESH_GEN_MANU_ACCESS_READ,
} esp_ble_mesh_gen_manu_prop_access_t;
/** Parameters of Generic Property states */
typedef struct {
uint16_t id; /*!< The value of User/Admin/Manufacturer Property ID */
uint8_t user_access; /*!< The value of User Access field */
uint8_t admin_access; /*!< The value of Admin Access field */
uint8_t manu_access; /*!< The value of Manufacturer Access field */
struct net_buf_simple *val; /*!< The value of User/Admin/Manufacturer Property */
} esp_ble_mesh_generic_property_t;
/** User data of Generic User Property Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic User Property Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
uint8_t property_count; /*!< Generic User Property count */
esp_ble_mesh_generic_property_t *properties; /*!< Parameters of the Generic User Property state */
} esp_ble_mesh_gen_user_prop_srv_t;
/** User data of Generic Admin Property Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Admin Property Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
uint8_t property_count; /*!< Generic Admin Property count */
esp_ble_mesh_generic_property_t *properties; /*!< Parameters of the Generic Admin Property state */
} esp_ble_mesh_gen_admin_prop_srv_t;
/** User data of Generic Manufacturer Property Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Manufacturer Property Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
uint8_t property_count; /*!< Generic Manufacturer Property count */
esp_ble_mesh_generic_property_t *properties; /*!< Parameters of the Generic Manufacturer Property state */
} esp_ble_mesh_gen_manu_prop_srv_t;
/** User data of Generic Client Property Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Client Property Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
uint8_t id_count; /*!< Generic Client Property ID count */
uint16_t *property_ids; /*!< Parameters of the Generic Client Property state */
} esp_ble_mesh_gen_client_prop_srv_t;
/** Parameter of Generic OnOff Set state change event */
typedef struct {
uint8_t onoff; /*!< The value of Generic OnOff state */
} esp_ble_mesh_state_change_gen_onoff_set_t;
/** Parameter of Generic Level Set state change event */
typedef struct {
int16_t level; /*!< The value of Generic Level state */
} esp_ble_mesh_state_change_gen_level_set_t;
/** Parameter of Generic Delta Set state change event */
typedef struct {
int16_t level; /*!< The value of Generic Level state */
} esp_ble_mesh_state_change_gen_delta_set_t;
/** Parameter of Generic Move Set state change event */
typedef struct {
int16_t level; /*!< The value of Generic Level state */
} esp_ble_mesh_state_change_gen_move_set_t;
/** Parameter of Generic Default Transition Time Set state change event */
typedef struct {
uint8_t trans_time; /*!< The value of Generic Default Transition Time state */
} esp_ble_mesh_state_change_gen_def_trans_time_set_t;
/** Parameter of Generic OnPowerUp Set state change event */
typedef struct {
uint8_t onpowerup; /*!< The value of Generic OnPowerUp state */
} esp_ble_mesh_state_change_gen_onpowerup_set_t;
/** Parameter of Generic Power Level Set state change event */
typedef struct {
uint16_t power; /*!< The value of Generic Power Actual state */
} esp_ble_mesh_state_change_gen_power_level_set_t;
/** Parameter of Generic Power Default Set state change event */
typedef struct {
uint16_t power; /*!< The value of Generic Power Default state */
} esp_ble_mesh_state_change_gen_power_default_set_t;
/** Parameters of Generic Power Range Set state change event */
typedef struct {
uint16_t range_min; /*!< The minimum value of Generic Power Range state */
uint16_t range_max; /*!< The maximum value of Generic Power Range state */
} esp_ble_mesh_state_change_gen_power_range_set_t;
/** Parameters of Generic Location Global Set state change event */
typedef struct {
int32_t latitude; /*!< The Global Latitude value of Generic Location state */
int32_t longitude; /*!< The Global Longitude value of Generic Location state */
int16_t altitude; /*!< The Global Altitude value of Generic Location state */
} esp_ble_mesh_state_change_gen_loc_global_set_t;
/** Parameters of Generic Location Local Set state change event */
typedef struct {
int16_t north; /*!< The Local North value of Generic Location state */
int16_t east; /*!< The Local East value of Generic Location state */
int16_t altitude; /*!< The Local Altitude value of Generic Location state */
uint8_t floor_number; /*!< The Floor Number value of Generic Location state */
uint16_t uncertainty; /*!< The Uncertainty value of Generic Location state */
} esp_ble_mesh_state_change_gen_loc_local_set_t;
/** Parameters of Generic User Property Set state change event */
typedef struct {
uint16_t id; /*!< The property id of Generic User Property state */
struct net_buf_simple *value; /*!< The property value of Generic User Property state */
} esp_ble_mesh_state_change_gen_user_property_set_t;
/** Parameters of Generic Admin Property Set state change event */
typedef struct {
uint16_t id; /*!< The property id of Generic Admin Property state */
uint8_t access; /*!< The property access of Generic Admin Property state */
struct net_buf_simple *value; /*!< The property value of Generic Admin Property state */
} esp_ble_mesh_state_change_gen_admin_property_set_t;
/** Parameters of Generic Manufacturer Property Set state change event */
typedef struct {
uint16_t id; /*!< The property id of Generic Manufacturer Property state */
uint8_t access; /*!< The property value of Generic Manufacturer Property state */
} esp_ble_mesh_state_change_gen_manu_property_set_t;
/**
* @brief Generic Server Model state change value union
*/
typedef union {
/**
* The recv_op in ctx can be used to decide which state is changed.
*/
esp_ble_mesh_state_change_gen_onoff_set_t onoff_set; /*!< Generic OnOff Set */
esp_ble_mesh_state_change_gen_level_set_t level_set; /*!< Generic Level Set */
esp_ble_mesh_state_change_gen_delta_set_t delta_set; /*!< Generic Delta Set */
esp_ble_mesh_state_change_gen_move_set_t move_set; /*!< Generic Move Set */
esp_ble_mesh_state_change_gen_def_trans_time_set_t def_trans_time_set; /*!< Generic Default Transition Time Set */
esp_ble_mesh_state_change_gen_onpowerup_set_t onpowerup_set; /*!< Generic OnPowerUp Set */
esp_ble_mesh_state_change_gen_power_level_set_t power_level_set; /*!< Generic Power Level Set */
esp_ble_mesh_state_change_gen_power_default_set_t power_default_set; /*!< Generic Power Default Set */
esp_ble_mesh_state_change_gen_power_range_set_t power_range_set; /*!< Generic Power Range Set */
esp_ble_mesh_state_change_gen_loc_global_set_t loc_global_set; /*!< Generic Location Global Set */
esp_ble_mesh_state_change_gen_loc_local_set_t loc_local_set; /*!< Generic Location Local Set */
esp_ble_mesh_state_change_gen_user_property_set_t user_property_set; /*!< Generic User Property Set */
esp_ble_mesh_state_change_gen_admin_property_set_t admin_property_set; /*!< Generic Admin Property Set */
esp_ble_mesh_state_change_gen_manu_property_set_t manu_property_set; /*!< Generic Manufactuer Property Set */
} esp_ble_mesh_generic_server_state_change_t;
/** Context of the received Generic User Property Get message */
typedef struct {
uint16_t property_id; /*!< Property ID identifying a Generic User Property */
} esp_ble_mesh_server_recv_gen_user_property_get_t;
/** Context of the received Generic Admin Property Get message */
typedef struct {
uint16_t property_id; /*!< Property ID identifying a Generic Admin Property */
} esp_ble_mesh_server_recv_gen_admin_property_get_t;
/** Context of the received Generic Manufacturer Property message */
typedef struct {
uint16_t property_id; /*!< Property ID identifying a Generic Manufacturer Property */
} esp_ble_mesh_server_recv_gen_manufacturer_property_get_t;
/** Context of the received Generic Client Properties Get message */
typedef struct {
uint16_t property_id; /*!< A starting Client Property ID present within an element */
} esp_ble_mesh_server_recv_gen_client_properties_get_t;
/**
* @brief Generic Server Model received get message union
*/
typedef union {
esp_ble_mesh_server_recv_gen_user_property_get_t user_property; /*!< Generic User Property Get */
esp_ble_mesh_server_recv_gen_admin_property_get_t admin_property; /*!< Generic Admin Property Get */
esp_ble_mesh_server_recv_gen_manufacturer_property_get_t manu_property; /*!< Generic Manufacturer Property Get */
esp_ble_mesh_server_recv_gen_client_properties_get_t client_properties; /*!< Generic Client Properties Get */
} esp_ble_mesh_generic_server_recv_get_msg_t;
/** Context of the received Generic OnOff Set message */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint8_t onoff; /*!< Target value of Generic OnOff state */
uint8_t tid; /*!< Transaction ID */
uint8_t trans_time; /*!< Time to complete state transition (optional) */
uint8_t delay; /*!< Indicate message execution delay (C.1) */
} esp_ble_mesh_server_recv_gen_onoff_set_t;
/** Context of the received Generic Level Set message */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
int16_t level; /*!< Target value of Generic Level state */
uint8_t tid; /*!< Transaction ID */
uint8_t trans_time; /*!< Time to complete state transition (optional) */
uint8_t delay; /*!< Indicate message execution delay (C.1) */
} esp_ble_mesh_server_recv_gen_level_set_t;
/** Context of the received Generic Delta Set message */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
int32_t delta_level; /*!< Delta change of Generic Level state */
uint8_t tid; /*!< Transaction ID */
uint8_t trans_time; /*!< Time to complete state transition (optional) */
uint8_t delay; /*!< Indicate message execution delay (C.1) */
} esp_ble_mesh_server_recv_gen_delta_set_t;
/** Context of the received Generic Move Set message */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
int16_t delta_level; /*!< Delta Level step to calculate Move speed for Generic Level state */
uint8_t tid; /*!< Transaction ID */
uint8_t trans_time; /*!< Time to complete state transition (optional) */
uint8_t delay; /*!< Indicate message execution delay (C.1) */
} esp_ble_mesh_server_recv_gen_move_set_t;
/** Context of the received Generic Default Transition Time Set message */
typedef struct {
uint8_t trans_time; /*!< The value of the Generic Default Transition Time state */
} esp_ble_mesh_server_recv_gen_def_trans_time_set_t;
/** Context of the received Generic OnPowerUp Set message */
typedef struct {
uint8_t onpowerup; /*!< The value of the Generic OnPowerUp state */
} esp_ble_mesh_server_recv_gen_onpowerup_set_t;
/** Context of the received Generic Power Level Set message */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint16_t power; /*!< Target value of Generic Power Actual state */
uint8_t tid; /*!< Transaction ID */
uint8_t trans_time; /*!< Time to complete state transition (optional) */
uint8_t delay; /*!< Indicate message execution delay (C.1) */
} esp_ble_mesh_server_recv_gen_power_level_set_t;
/** Context of the received Generic Power Default Set message */
typedef struct {
uint16_t power; /*!< The value of the Generic Power Default state */
} esp_ble_mesh_server_recv_gen_power_default_set_t;
/** Context of the received Generic Power Range Set message */
typedef struct {
uint16_t range_min; /*!< Value of Range Min field of Generic Power Range state */
uint16_t range_max; /*!< Value of Range Max field of Generic Power Range state */
} esp_ble_mesh_server_recv_gen_power_range_set_t;
/** Context of the received Generic Location Global Set message */
typedef struct {
int32_t global_latitude; /*!< Global Coordinates (Latitude) */
int32_t global_longitude; /*!< Global Coordinates (Longitude) */
int16_t global_altitude; /*!< Global Altitude */
} esp_ble_mesh_server_recv_gen_loc_global_set_t;
/** Context of the received Generic Location Local Set message */
typedef struct {
int16_t local_north; /*!< Local Coordinates (North) */
int16_t local_east; /*!< Local Coordinates (East) */
int16_t local_altitude; /*!< Local Altitude */
uint8_t floor_number; /*!< Floor Number */
uint16_t uncertainty; /*!< Uncertainty */
} esp_ble_mesh_server_recv_gen_loc_local_set_t;
/** Context of the received Generic User Property Set message */
typedef struct {
uint16_t property_id; /*!< Property ID identifying a Generic User Property */
struct net_buf_simple *property_value; /*!< Raw value for the User Property */
} esp_ble_mesh_server_recv_gen_user_property_set_t;
/** Context of the received Generic Admin Property Set message */
typedef struct {
uint16_t property_id; /*!< Property ID identifying a Generic Admin Property */
uint8_t user_access; /*!< Enumeration indicating user accessn */
struct net_buf_simple *property_value; /*!< Raw value for the Admin Property */
} esp_ble_mesh_server_recv_gen_admin_property_set_t;
/** Context of the received Generic Manufacturer Property Set message */
typedef struct {
uint16_t property_id; /*!< Property ID identifying a Generic Manufacturer Property */
uint8_t user_access; /*!< Enumeration indicating user access */
} esp_ble_mesh_server_recv_gen_manufacturer_property_set_t;
/**
* @brief Generic Server Model received set message union
*/
typedef union {
esp_ble_mesh_server_recv_gen_onoff_set_t onoff; /*!< Generic OnOff Set/Generic OnOff Set Unack */
esp_ble_mesh_server_recv_gen_level_set_t level; /*!< Generic Level Set/Generic Level Set Unack */
esp_ble_mesh_server_recv_gen_delta_set_t delta; /*!< Generic Delta Set/Generic Delta Set Unack */
esp_ble_mesh_server_recv_gen_move_set_t move; /*!< Generic Move Set/Generic Move Set Unack */
esp_ble_mesh_server_recv_gen_def_trans_time_set_t def_trans_time; /*!< Generic Default Transition Time Set/Generic Default Transition Time Set Unack */
esp_ble_mesh_server_recv_gen_onpowerup_set_t onpowerup; /*!< Generic OnPowerUp Set/Generic OnPowerUp Set Unack */
esp_ble_mesh_server_recv_gen_power_level_set_t power_level; /*!< Generic Power Level Set/Generic Power Level Set Unack */
esp_ble_mesh_server_recv_gen_power_default_set_t power_default; /*!< Generic Power Default Set/Generic Power Default Set Unack */
esp_ble_mesh_server_recv_gen_power_range_set_t power_range; /*!< Generic Power Range Set/Generic Power Range Set Unack */
esp_ble_mesh_server_recv_gen_loc_global_set_t location_global; /*!< Generic Location Global Set/Generic Location Global Set Unack */
esp_ble_mesh_server_recv_gen_loc_local_set_t location_local; /*!< Generic Location Local Set/Generic Location Local Set Unack */
esp_ble_mesh_server_recv_gen_user_property_set_t user_property; /*!< Generic User Property Set/Generic User Property Set Unack */
esp_ble_mesh_server_recv_gen_admin_property_set_t admin_property; /*!< Generic Admin Property Set/Generic Admin Property Set Unack */
esp_ble_mesh_server_recv_gen_manufacturer_property_set_t manu_property; /*!< Generic Manufacturer Property Set/Generic Manufacturer Property Set Unack */
} esp_ble_mesh_generic_server_recv_set_msg_t;
/**
* @brief Generic Server Model callback value union
*/
typedef union {
esp_ble_mesh_generic_server_state_change_t state_change; /*!< ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT */
esp_ble_mesh_generic_server_recv_get_msg_t get; /*!< ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT */
esp_ble_mesh_generic_server_recv_set_msg_t set; /*!< ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT */
} esp_ble_mesh_generic_server_cb_value_t;
/** Generic Server Model callback parameters */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to Generic Server Models */
esp_ble_mesh_msg_ctx_t ctx; /*!< Context of the received messages */
esp_ble_mesh_generic_server_cb_value_t value; /*!< Value of the received Generic Messages */
} esp_ble_mesh_generic_server_cb_param_t;
/** This enum value is the event of Generic Server Model */
typedef enum {
/**
* 1. When get_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, no event will be
* callback to the application layer when Generic Get messages are received.
* 2. When set_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, this event will
* be callback to the application layer when Generic Set/Set Unack messages
* are received.
*/
ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT,
/**
* When get_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
* callback to the application layer when Generic Get messages are received.
*/
ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT,
/**
* When set_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
* callback to the application layer when Generic Set/Set Unack messages are received.
*/
ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT,
ESP_BLE_MESH_GENERIC_SERVER_EVT_MAX,
} esp_ble_mesh_generic_server_cb_event_t;
/**
* @brief Bluetooth Mesh Generic Server Model function.
*/
/**
* @brief Generic Server Model callback function type
* @param event: Event type
* @param param: Pointer to callback parameter
*/
typedef void (* esp_ble_mesh_generic_server_cb_t)(esp_ble_mesh_generic_server_cb_event_t event,
esp_ble_mesh_generic_server_cb_param_t *param);
/**
* @brief Register BLE Mesh Generic Server Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_generic_server_callback(esp_ble_mesh_generic_server_cb_t callback);
#endif /* _ESP_BLE_MESH_GENERIC_MODEL_API_H_ */

View File

@ -47,39 +47,123 @@
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_HEALTH_CLI, \
NULL, NULL, cli_data)
/** Health Server Model callbacks */
/** @def ESP_BLE_MESH_HEALTH_PUB_DEFINE
*
* A helper to define a health publication context
*
* @param _name Name given to the publication context variable.
* @param _max Maximum number of faults the element can have.
* @param _role Role of the device which contains the model.
*/
#define ESP_BLE_MESH_HEALTH_PUB_DEFINE(_name, _max, _role) \
ESP_BLE_MESH_MODEL_PUB_DEFINE(_name, (1 + 3 + (_max)), _role)
/**
* SIG identifier of Health Fault Test.
* 0x01 ~ 0xFF: Vendor Specific Test.
*/
#define ESP_BLE_MESH_HEALTH_STANDARD_TEST 0x00
/**
* Fault values of Health Fault Test.
* 0x33 ~ 0x7F: Reserved for Future Use.
* 0x80 ~ 0xFF: Vendor Specific Warning/Error.
*/
#define ESP_BLE_MESH_NO_FAULT 0x00
#define ESP_BLE_MESH_BATTERY_LOW_WARNING 0x01
#define ESP_BLE_MESH_BATTERY_LOW_ERROR 0x02
#define ESP_BLE_MESH_SUPPLY_VOLTAGE_TOO_LOW_WARNING 0x03
#define ESP_BLE_MESH_SUPPLY_VOLTAGE_TOO_LOW_ERROR 0x04
#define ESP_BLE_MESH_SUPPLY_VOLTAGE_TOO_HIGH_WARNING 0x05
#define ESP_BLE_MESH_SUPPLY_VOLTAGE_TOO_HIGH_ERROR 0x06
#define ESP_BLE_MESH_POWER_SUPPLY_INTERRUPTED_WARNING 0x07
#define ESP_BLE_MESH_POWER_SUPPLY_INTERRUPTED_ERROR 0x08
#define ESP_BLE_MESH_NO_LOAD_WARNING 0x09
#define ESP_BLE_MESH_NO_LOAD_ERROR 0x0A
#define ESP_BLE_MESH_OVERLOAD_WARNING 0x0B
#define ESP_BLE_MESH_OVERLOAD_ERROR 0x0C
#define ESP_BLE_MESH_OVERHEAT_WARNING 0x0D
#define ESP_BLE_MESH_OVERHEAT_ERROR 0x0E
#define ESP_BLE_MESH_CONDENSATION_WARNING 0x0F
#define ESP_BLE_MESH_CONDENSATION_ERROR 0x10
#define ESP_BLE_MESH_VIBRATION_WARNING 0x11
#define ESP_BLE_MESH_VIBRATION_ERROR 0x12
#define ESP_BLE_MESH_CONFIGURATION_WARNING 0x13
#define ESP_BLE_MESH_CONFIGURATION_ERROR 0x14
#define ESP_BLE_MESH_ELEMENT_NOT_CALIBRATED_WARNING 0x15
#define ESP_BLE_MESH_ELEMENT_NOT_CALIBRATED_ERROR 0x16
#define ESP_BLE_MESH_MEMORY_WARNING 0x17
#define ESP_BLE_MESH_MEMORY_ERROR 0x18
#define ESP_BLE_MESH_SELF_TEST_WARNING 0x19
#define ESP_BLE_MESH_SELF_TEST_ERROR 0x1A
#define ESP_BLE_MESH_INPUT_TOO_LOW_WARNING 0x1B
#define ESP_BLE_MESH_INPUT_TOO_LOW_ERROR 0x1C
#define ESP_BLE_MESH_INPUT_TOO_HIGH_WARNING 0x1D
#define ESP_BLE_MESH_INPUT_TOO_HIGH_ERROR 0x1E
#define ESP_BLE_MESH_INPUT_NO_CHANGE_WARNING 0x1F
#define ESP_BLE_MESH_INPUT_NO_CHANGE_ERROR 0x20
#define ESP_BLE_MESH_ACTUATOR_BLOCKED_WARNING 0x21
#define ESP_BLE_MESH_ACTUATOR_BLOCKED_ERROR 0x22
#define ESP_BLE_MESH_HOUSING_OPENED_WARNING 0x23
#define ESP_BLE_MESH_HOUSING_OPENED_ERROR 0x24
#define ESP_BLE_MESH_TAMPER_WARNING 0x25
#define ESP_BLE_MESH_TAMPER_ERROR 0x26
#define ESP_BLE_MESH_DEVICE_MOVED_WARNING 0x27
#define ESP_BLE_MESH_DEVICE_MOVED_ERROR 0x28
#define ESP_BLE_MESH_DEVICE_DROPPED_WARNING 0x29
#define ESP_BLE_MESH_DEVICE_DROPPED_ERROR 0x2A
#define ESP_BLE_MESH_OVERFLOW_WARNING 0x2B
#define ESP_BLE_MESH_OVERFLOW_ERROR 0x2C
#define ESP_BLE_MESH_EMPTY_WARNING 0x2D
#define ESP_BLE_MESH_EMPTY_ERROR 0x2E
#define ESP_BLE_MESH_INTERNAL_BUS_WARNING 0x2F
#define ESP_BLE_MESH_INTERNAL_BUS_ERROR 0x30
#define ESP_BLE_MESH_MECHANISM_JAMMED_WARNING 0x31
#define ESP_BLE_MESH_MECHANISM_JAMMED_ERROR 0x32
/** ESP BLE Mesh Health Server callback */
typedef struct {
/** Fetch current faults */
int (*fault_get_cur)(esp_ble_mesh_model_t *model, uint8_t *test_id,
uint16_t *company_id, uint8_t *faults, uint8_t *fault_count);
/** Clear health registered faults. Initialized by the stack. */
esp_ble_mesh_cb_t fault_clear;
/** Fetch registered faults */
int (*fault_get_reg)(esp_ble_mesh_model_t *model, uint16_t company_id,
uint8_t *test_id, uint8_t *faults, uint8_t *fault_count);
/** Run a specific health test. Initialized by the stack. */
esp_ble_mesh_cb_t fault_test;
/** Clear registered faults */
int (*fault_clear)(esp_ble_mesh_model_t *model, uint16_t company_id);
/** Health attention on callback. Initialized by the stack. */
esp_ble_mesh_cb_t attention_on;
/** Run a specific test */
int (*fault_test)(esp_ble_mesh_model_t *model, uint8_t test_id, uint16_t company_id);
/** Attention on */
void (*attn_on)(esp_ble_mesh_model_t *model);
/** Attention off */
void (*attn_off)(esp_ble_mesh_model_t *model);
/** Health attention off callback. Initialized by the stack. */
esp_ble_mesh_cb_t attention_off;
} esp_ble_mesh_health_srv_cb_t;
/** Health Server Model Context */
#define ESP_BLE_MESH_HEALTH_FAULT_ARRAY_SIZE 32
/** ESP BLE Mesh Health Server test Context */
typedef struct {
uint8_t id_count; /*!< Number of Health self-test ID */
const uint8_t *test_ids; /*!< Array of Health self-test IDs */
uint16_t company_id; /*!< Company ID used to identify the Health Fault state */
uint8_t prev_test_id; /*!< Current test ID of the health fault test */
uint8_t current_faults[ESP_BLE_MESH_HEALTH_FAULT_ARRAY_SIZE]; /*!< Array of current faults */
uint8_t registered_faults[ESP_BLE_MESH_HEALTH_FAULT_ARRAY_SIZE]; /*!< Array of registered faults */
} __attribute__((packed)) esp_ble_mesh_health_test_t;
/** ESP BLE Mesh Health Server Model Context */
typedef struct {
/** Pointer to Health Server Model */
esp_ble_mesh_model_t *model;
/** Optional callback struct */
const esp_ble_mesh_health_srv_cb_t *cb;
/** Health callback struct */
esp_ble_mesh_health_srv_cb_t health_cb;
/** Attention Timer state */
struct k_delayed_work attn_timer;
struct k_delayed_work attention_timer;
/** Attention Timer start flag */
bool attention_timer_start;
/** Health Server fault test */
esp_ble_mesh_health_test_t health_test;
} esp_ble_mesh_health_srv_t;
/** Parameter of Health Fault Get */
@ -186,14 +270,54 @@ typedef enum {
ESP_BLE_MESH_HEALTH_CLIENT_EVT_MAX,
} esp_ble_mesh_health_client_cb_event_t;
/** Health Server Model callback parameter */
/** Parameter of publishing Health Current Status completion event */
typedef struct {
int error_code; /*!< Appropriate error code */
int error_code; /*!< The result of publishing Health Current Status */
esp_ble_mesh_elem_t *element; /*!< Pointer to the element which contains the Health Server Model */
} esp_ble_mesh_health_fault_update_comp_cb_t;
/** Parameters of Health Fault Clear event */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Health Server Model */
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
} esp_ble_mesh_health_fault_clear_cb_t;
/** Parameters of Health Fault Test event */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Health Server Model */
uint8_t test_id; /*!< ID of a specific test to be performed */
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
} esp_ble_mesh_health_fault_test_cb_t;
/** Parameter of Health Attention On event */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Health Server Model */
uint8_t time; /*!< Duration of attention timer on (in seconds) */
} esp_ble_mesh_health_attention_on_cb_t;
/** Parameter of Health Attention Off event */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Health Server Model */
} esp_ble_mesh_health_attention_off_cb_t;
/**
* @brief Health Server Model callback parameters union
*/
typedef union {
esp_ble_mesh_health_fault_update_comp_cb_t fault_update_comp; /*!< ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMP_EVT */
esp_ble_mesh_health_fault_clear_cb_t fault_clear; /*!< ESP_BLE_MESH_HEALTH_SERVER_FAULT_CLEAR_EVT */
esp_ble_mesh_health_fault_test_cb_t fault_test; /*!< ESP_BLE_MESH_HEALTH_SERVER_FAULT_TEST_EVT */
esp_ble_mesh_health_attention_on_cb_t attention_on; /*!< ESP_BLE_MESH_HEALTH_SERVER_ATTENTION_ON_EVT */
esp_ble_mesh_health_attention_off_cb_t attention_off; /*!< ESP_BLE_MESH_HEALTH_SERVER_ATTENTION_OFF_EVT */
} esp_ble_mesh_health_server_cb_param_t;
/** This enum value is the event of Health Server Model */
typedef enum {
ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMPLETE_EVT,
ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMP_EVT,
ESP_BLE_MESH_HEALTH_SERVER_FAULT_CLEAR_EVT,
ESP_BLE_MESH_HEALTH_SERVER_FAULT_TEST_EVT,
ESP_BLE_MESH_HEALTH_SERVER_ATTENTION_ON_EVT,
ESP_BLE_MESH_HEALTH_SERVER_ATTENTION_OFF_EVT,
ESP_BLE_MESH_HEALTH_SERVER_EVT_MAX,
} esp_ble_mesh_health_server_cb_event_t;
@ -270,7 +394,7 @@ esp_err_t esp_ble_mesh_health_client_set_state(esp_ble_mesh_client_common_param_
esp_ble_mesh_health_client_set_state_t *set_state);
/**
* @brief This function is called by the Health Server Model to start to publish its Current Health Fault.
* @brief This function is called by the Health Server Model to update the context of its Health Current status.
*
* @param[in] element: The element to which the Health Server Model belongs.
*

View File

@ -255,6 +255,372 @@ esp_err_t esp_ble_mesh_sensor_client_get_state(esp_ble_mesh_client_common_param_
esp_err_t esp_ble_mesh_sensor_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_sensor_client_set_state_t *set_state);
/**
* @brief Sensor Server Models related context.
*/
/** @def ESP_BLE_MESH_MODEL_SENSOR_SRV
*
* @brief Define a new Sensor Server Model.
*
* @note 1. The Sensor Server model is a root model. When this model is present
* on an element, the corresponding Sensor Setup Server model shall
* also be present.
* 2. This model shall support model publication and model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_sensor_srv_t.
*
* @return New Sensor Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_SENSOR_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SENSOR_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_SENSOR_SETUP_SRV
*
* @brief Define a new Sensor Setup Server Model.
*
* @note 1. The Sensor Setup Server model extends the Sensor Server model.
* 2. This model shall support model publication and model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_sensor_setup_srv_t.
*
* @return New Sensor Setup Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_SENSOR_SETUP_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SENSOR_SETUP_SRV, \
NULL, srv_pub, srv_data)
#define ESP_BLE_MESH_INVALID_SENSOR_PROPERTY_ID 0x0000 /*!< Invalid Sensor Property ID */
#define ESP_BLE_MESH_SENSOR_PROPERTY_ID_LEN 0x02 /*!< Length of Sensor Property ID */
#define ESP_BLE_MESH_SENSOR_DESCRIPTOR_LEN 0x08 /*!< Length of Sensor Descriptor state */
#define ESP_BLE_MESH_SENSOR_UNSPECIFIED_POS_TOLERANCE 0x000 /*!< Unspecified Sensor Positive Tolerance */
#define ESP_BLE_MESH_SENSOR_UNSPECIFIED_NEG_TOLERANCE 0x000 /*!< Unspecified Sensor Negative Tolerance */
#define ESP_BLE_MESH_SENSOR_NOT_APPL_MEASURE_PERIOD 0x00 /*!< Not applicable Sensor Measurement Period */
#define ESP_BLE_MESH_SENSOR_NOT_APPL_UPDATE_INTERVAL 0x00 /*!< Not applicable Sensor Update Interval */
#define ESP_BLE_MESH_INVALID_SENSOR_SETTING_PROPERTY_ID 0x0000 /*!< Invalid Sensor Setting Property ID */
#define ESP_BLE_MESH_SENSOR_SETTING_PROPERTY_ID_LEN 0x02 /*!< Length of Sensor Setting Property ID */
#define ESP_BLE_MESH_SENSOR_SETTING_ACCESS_LEN 0x01 /*!< Length of Sensor Setting Access */
#define ESP_BLE_MESH_SENSOR_SETTING_ACCESS_READ 0x01 /*!< Sensor Setting Access - Read */
#define ESP_BLE_MESH_SENSOR_SETTING_ACCESS_READ_WRITE 0x03 /*!< Sensor Setting Access - Read & Write */
#define ESP_BLE_MESH_SENSOR_DIVISOR_TRIGGER_TYPE_LEN 0x01 /*!< Length of Sensor Divisor Trigger Type */
#define ESP_BLE_MESH_SENSOR_STATUS_MIN_INTERVAL_LEN 0x01 /*!< Length of Sensor Status Min Interval */
#define ESP_BLE_MESH_SENSOR_PERIOD_DIVISOR_MAX_VALUE 15 /*!< Maximum value of Sensor Period Divisor */
#define ESP_BLE_MESH_SENSOR_STATUS_MIN_INTERVAL_MAX 26 /*!< Maximum value of Sensor Status Min Interval */
/**
* Sensor Status Trigger Type - Format Type of the characteristic
* that the Sensor Property ID state references
*/
#define ESP_BLE_MESH_SENSOR_STATUS_TRIGGER_TYPE_CHAR 0
/** Sensor Status Trigger Type - Format Type "uint16" */
#define ESP_BLE_MESH_SENSOR_STATUS_TRIGGER_TYPE_UINT16 1
#define ESP_BLE_MESH_SENSOR_DATA_FORMAT_A 0x00 /*!< Sensor Data Format A */
#define ESP_BLE_MESH_SENSOR_DATA_FORMAT_B 0x01 /*!< Sensor Data Format B */
#define ESP_BLE_MESH_SENSOR_DATA_FORMAT_A_MPID_LEN 0x02 /*!< MPID length of Sensor Data Format A */
#define ESP_BLE_MESH_SENSOR_DATA_FORMAT_B_MPID_LEN 0x03 /*!< MPID length of Sensor Data Format B */
/**
* Zero length of Sensor Data.
*
* Note:
* The Length field is a 1-based uint7 value (valid range 0x00x7F,
* representing range of 1127). The value 0x7F represents a length
* of zero.
*/
#define ESP_BLE_MESH_SENSOR_DATA_ZERO_LEN 0x7F
/** This enum value is value of Sensor Sampling Function */
enum esp_ble_mesh_sensor_sample_func {
ESP_BLE_MESH_SAMPLE_FUNC_UNSPECIFIED,
ESP_BLE_MESH_SAMPLE_FUNC_INSTANTANEOUS,
ESP_BLE_MESH_SAMPLE_FUNC_ARITHMETIC_MEAN,
ESP_BLE_MESH_SAMPLE_FUNC_RMS,
ESP_BLE_MESH_SAMPLE_FUNC_MAXIMUM,
ESP_BLE_MESH_SAMPLE_FUNC_MINIMUM,
ESP_BLE_MESH_SAMPLE_FUNC_ACCUMULATED,
ESP_BLE_MESH_SAMPLE_FUNC_COUNT,
};
/** Parameters of Sensor Descriptor state */
typedef struct {
uint32_t positive_tolerance : 12, /*!< The value of Sensor Positive Tolerance field */
negative_tolerance : 12, /*!< The value of Sensor Negative Tolerance field */
sampling_function : 8; /*!< The value of Sensor Sampling Function field */
uint8_t measure_period; /*!< The value of Sensor Measurement Period field */
uint8_t update_interval; /*!< The value of Sensor Update Interval field */
} esp_ble_mesh_sensor_descriptor_t;
/** Parameters of Sensor Setting state */
typedef struct {
uint16_t property_id; /*!< The value of Sensor Setting Property ID field */
uint8_t access; /*!< The value of Sensor Setting Access field */
struct net_buf_simple *raw; /*!< The value of Sensor Setting Raw field */
} esp_ble_mesh_sensor_setting_t;
/** Parameters of Sensor Cadence state */
typedef struct {
uint8_t period_divisor : 7, /*!< The value of Fast Cadence Period Divisor field */
trigger_type : 1; /*!< The value of Status Trigger Type field */
/**
* Note:
* The parameter "size" in trigger_delta_down, trigger_delta_up, fast_cadence_low &
* fast_cadence_high indicates the exact length of these four parameters, and they
* are associated with the Sensor Property ID. Users need to initialize the "size"
* precisely.
*/
struct net_buf_simple *trigger_delta_down; /*!< The value of Status Trigger Delta Down field */
struct net_buf_simple *trigger_delta_up; /*!< The value of Status Trigger Delta Up field */
uint8_t min_interval; /*!< The value of Status Min Interval field */
struct net_buf_simple *fast_cadence_low; /*!< The value of Fast Cadence Low field */
struct net_buf_simple *fast_cadence_high; /*!< The value of Fast Cadence High field */
} esp_ble_mesh_sensor_cadence_t;
/** Parameters of Sensor Data state */
typedef struct {
/**
* Format A: The Length field is a 1-based uint4 value (valid range 0x00xF,
* representing range of 1 16).
* Format B: The Length field is a 1-based uint7 value (valid range 0x00x7F,
* representing range of 1 127). The value 0x7F represents a
* length of zero.
*/
uint8_t format : 1, /*!< The value of the Sensor Data format */
length : 7; /*!< The value of the Sensor Data length */
struct net_buf_simple *raw_value; /*!< The value of Sensor Data raw value */
} esp_ble_mesh_sensor_data_t;
/** Parameters of Sensor Series Column state */
typedef struct {
struct net_buf_simple *raw_value_x; /*!< The value of Sensor Raw Value X field */
struct net_buf_simple *column_width; /*!< The value of Sensor Column Width field */
struct net_buf_simple *raw_value_y; /*!< The value of Sensor Raw Value Y field */
} esp_ble_mesh_sensor_series_column_t;
/** Parameters of Sensor states */
typedef struct {
uint16_t sensor_property_id; /*!< The value of Sensor Property ID field */
/* Constant throughout the lifetime of an element */
esp_ble_mesh_sensor_descriptor_t descriptor; /*!< Parameters of the Sensor Descriptor state */
/**
* Multiple Sensor Setting states may be present for each sensor.
* The Sensor Setting Property ID values shall be unique for each
* Sensor Property ID that identifies a sensor within an element.
*/
const uint8_t setting_count; /*!< */
esp_ble_mesh_sensor_setting_t *settings; /*!< Parameters of the Sensor Setting state */
/**
* The Sensor Cadence state may be not supported by sensors based
* on device properties referencing "non-scalar characteristics"
* such as "histograms" or "composite characteristics".
*/
esp_ble_mesh_sensor_cadence_t *cadence; /*!< Parameters of the Sensor Cadence state */
esp_ble_mesh_sensor_data_t sensor_data; /*!< Parameters of the Sensor Data state */
esp_ble_mesh_sensor_series_column_t series_column; /*!< Parameters of the Sensor Series Column state */
} esp_ble_mesh_sensor_state_t;
/** User data of Sensor Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Sensor Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
const uint8_t state_count; /*!< Sensor state count */
esp_ble_mesh_sensor_state_t *states; /*!< Parameters of the Sensor states */
} esp_ble_mesh_sensor_srv_t;
/** User data of Sensor Setup Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Sensor Setup Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
const uint8_t state_count; /*!< Sensor state count */
esp_ble_mesh_sensor_state_t *states; /*!< Parameters of the Sensor states */
} esp_ble_mesh_sensor_setup_srv_t;
/** Parameters of Sensor Cadence Set state change event */
typedef struct {
uint16_t property_id; /*!< The value of Sensor Property ID state */
uint8_t period_divisor : 7, /*!< The value of Fast Cadence Period Divisor state */
trigger_type : 1; /*!< The value of Status Trigger Type state */
struct net_buf_simple *trigger_delta_down; /*!< The value of Status Trigger Delta Down state */
struct net_buf_simple *trigger_delta_up; /*!< The value of Status Trigger Delta Up state */
uint8_t min_interval; /*!< The value of Status Min Interval state */
struct net_buf_simple *fast_cadence_low; /*!< The value of Fast Cadence Low state */
struct net_buf_simple *fast_cadence_high; /*!< The value of Fast Cadence High state */
} esp_ble_mesh_state_change_sensor_cadence_set_t;
/** Parameters of Sensor Setting Set state change event */
typedef struct {
uint16_t property_id; /*!< The value of Sensor Property ID state */
uint16_t setting_property_id; /*!< The value of Sensor Setting Property ID state */
struct net_buf_simple *setting_value; /*!< The value of Sensor Property Value state */
} esp_ble_mesh_state_change_sensor_setting_set_t;
/**
* @brief Sensor Server Model state change value union
*/
typedef union {
/**
* The recv_op in ctx can be used to decide which state is changed.
*/
esp_ble_mesh_state_change_sensor_cadence_set_t sensor_cadence_set; /*!< Sensor Cadence Set */
esp_ble_mesh_state_change_sensor_setting_set_t sensor_setting_set; /*!< Sensor Setting Set */
} esp_ble_mesh_sensor_server_state_change_t;
/** Context of the received Sensor Descriptor Get message */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint16_t property_id; /*!< Property ID of a sensor (optional) */
} esp_ble_mesh_server_recv_sensor_descriptor_get_t;
/** Context of the received Sensor Cadence Get message */
typedef struct {
uint16_t property_id; /*!< Property ID of a sensor */
} esp_ble_mesh_server_recv_sensor_cadence_get_t;
/** Context of the received Sensor Settings Get message */
typedef struct {
uint16_t property_id; /*!< Property ID of a sensor */
} esp_ble_mesh_server_recv_sensor_settings_get_t;
/** Context of the received Sensor Setting Get message */
typedef struct {
uint16_t property_id; /*!< Property ID of a sensor */
uint16_t setting_property_id; /*!< Setting ID identifying a setting within a sensor */
} esp_ble_mesh_server_recv_sensor_setting_get_t;
/** Context of the received Sensor Get message */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint16_t property_id; /*!< Property ID for the sensor (optional) */
} esp_ble_mesh_server_recv_sensor_get_t;
/** Context of the received Sensor Column Get message */
typedef struct {
uint16_t property_id; /*!< Property identifying a sensor */
struct net_buf_simple *raw_value_x; /*!< Raw value identifying a column */
} esp_ble_mesh_server_recv_sensor_column_get_t;
/** Context of the received Sensor Series Get message */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint16_t property_id; /*!< Property identifying a sensor */
struct net_buf_simple *raw_value; /*!< Raw value containg X1 and X2 (optional) */
} esp_ble_mesh_server_recv_sensor_series_get_t;
/**
* @brief Sensor Server Model received get message union
*/
typedef union {
esp_ble_mesh_server_recv_sensor_descriptor_get_t sensor_descriptor; /*!< Sensor Descriptor Get */
esp_ble_mesh_server_recv_sensor_cadence_get_t sensor_cadence; /*!< Sensor Cadence Get */
esp_ble_mesh_server_recv_sensor_settings_get_t sensor_settings; /*!< Sensor Settings Get */
esp_ble_mesh_server_recv_sensor_setting_get_t sensor_setting; /*!< Sensor Setting Get */
esp_ble_mesh_server_recv_sensor_get_t sensor_data; /*!< Sensor Get */
esp_ble_mesh_server_recv_sensor_column_get_t sensor_column; /*!< Sensor Column Get */
esp_ble_mesh_server_recv_sensor_series_get_t sensor_series; /*!< Sensor Series Get */
} esp_ble_mesh_sensor_server_recv_get_msg_t;
/** Context of the received Sensor Cadence Set message */
typedef struct {
uint16_t property_id; /*!< Property ID for the sensor */
struct net_buf_simple *cadence; /*!< Value of Sensor Cadence state */
} esp_ble_mesh_server_recv_sensor_cadence_set_t;
/** Context of the received Sensor Setting Set message */
typedef struct {
uint16_t property_id; /*!< Property ID identifying a sensor */
uint16_t setting_property_id; /*!< Setting ID identifying a setting within a sensor */
struct net_buf_simple *setting_raw; /*!< Raw value for the setting */
} esp_ble_mesh_server_recv_sensor_setting_set_t;
/**
* @brief Sensor Server Model received set message union
*/
typedef union {
esp_ble_mesh_server_recv_sensor_cadence_set_t sensor_cadence; /*!< Sensor Cadence Set */
esp_ble_mesh_server_recv_sensor_setting_set_t sensor_setting; /*!< Sensor Setting Set */
} esp_ble_mesh_sensor_server_recv_set_msg_t;
/**
* @brief Sensor Server Model callback value union
*/
typedef union {
esp_ble_mesh_sensor_server_state_change_t state_change; /*!< ESP_BLE_MESH_SENSOR_SERVER_STATE_CHANGE_EVT */
esp_ble_mesh_sensor_server_recv_get_msg_t get; /*!< ESP_BLE_MESH_SENSOR_SERVER_RECV_GET_MSG_EVT */
esp_ble_mesh_sensor_server_recv_set_msg_t set; /*!< ESP_BLE_MESH_SENSOR_SERVER_RECV_SET_MSG_EVT */
} esp_ble_mesh_sensor_server_cb_value_t;
/** Sensor Server Model callback parameters */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to Sensor Server Models */
esp_ble_mesh_msg_ctx_t ctx; /*!< Context of the received messages */
esp_ble_mesh_sensor_server_cb_value_t value; /*!< Value of the received Sensor Messages */
} esp_ble_mesh_sensor_server_cb_param_t;
/** This enum value is the event of Sensor Server Model */
typedef enum {
/**
* 1. When get_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, no event will be
* callback to the application layer when Sensor Get messages are received.
* 2. When set_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, this event will
* be callback to the application layer when Sensor Set/Set Unack messages
* are received.
*/
ESP_BLE_MESH_SENSOR_SERVER_STATE_CHANGE_EVT,
/**
* When get_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
* callback to the application layer when Sensor Get messages are received.
*/
ESP_BLE_MESH_SENSOR_SERVER_RECV_GET_MSG_EVT,
/**
* When set_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
* callback to the application layer when Sensor Set/Set Unack messages are received.
*/
ESP_BLE_MESH_SENSOR_SERVER_RECV_SET_MSG_EVT,
ESP_BLE_MESH_SENSOR_SERVER_EVT_MAX,
} esp_ble_mesh_sensor_server_cb_event_t;
/**
* @brief Bluetooth Mesh Sensor Server Model function.
*/
/**
* @brief Sensor Server Model callback function type
* @param event: Event type
* @param param: Pointer to callback parameter
*/
typedef void (* esp_ble_mesh_sensor_server_cb_t)(esp_ble_mesh_sensor_server_cb_event_t event,
esp_ble_mesh_sensor_server_cb_param_t *param);
/**
* @brief Register BLE Mesh Sensor Server Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_sensor_server_callback(esp_ble_mesh_sensor_server_cb_t callback);
#endif /* _ESP_BLE_MESH_SENSOR_MODEL_API_H_ */

View File

@ -314,5 +314,599 @@ esp_err_t esp_ble_mesh_time_scene_client_get_state(esp_ble_mesh_client_common_pa
esp_err_t esp_ble_mesh_time_scene_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_time_scene_client_set_state_t *set_state);
/**
* @brief Time Scene Server Models related context.
*/
/** @def ESP_BLE_MESH_MODEL_TIME_SRV
*
* @brief Define a new Time Server Model.
*
* @note 1. The Time Server model is a root model. When this model is present on an
* Element, the corresponding Time Setup Server model shall also be present.
* 2. This model shall support model publication and model subscription.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_time_srv_t.
*
* @return New Time Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_TIME_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_TIME_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_TIME_SETUP_SRV
*
* @brief Define a new Time Setup Server Model.
*
* @note 1. The Time Setup Server model extends the Time Server model. Time is
* sensitive information that is propagated across a mesh network.
* 2. Only an authorized Time Client should be allowed to change the Time
* and Time Role states. A dedicated application key Bluetooth SIG
* Proprietary should be used on the Time Setup Server to restrict
* access to the server to only authorized Time Clients.
* 3. This model does not support subscribing nor publishing.
*
* @param srv_data Pointer to the unique struct esp_ble_mesh_time_setup_srv_t.
*
* @return New Time Setup Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_TIME_SETUP_SRV(srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_TIME_SETUP_SRV, \
NULL, NULL, srv_data)
/** @def ESP_BLE_MESH_MODEL_SCENE_SRV
*
* @brief Define a new Scene Server Model.
*
* @note 1. The Scene Server model is a root model. When this model is present
* on an Element, the corresponding Scene Setup Server model shall
* also be present.
* 2. This model shall support model publication and model subscription.
* 3. The model may be present only on the Primary element of a node.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_scene_srv_t.
*
* @return New Scene Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_SCENE_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SCENE_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_SCENE_SETUP_SRV
*
* @brief Define a new Scene Setup Server Model.
*
* @note 1. The Scene Setup Server model extends the Scene Server model and
* the Generic Default Transition Time Server model.
* 2. This model shall support model subscription.
* 3. The model may be present only on the Primary element of a node.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_scene_setup_srv_t.
*
* @return New Scene Setup Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_SCENE_SETUP_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SCENE_SETUP_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_SCHEDULER_SRV
*
* @brief Define a new Scheduler Server Model.
*
* @note 1. The Scheduler Server model extends the Scene Server model. When
* this model is present on an Element, the corresponding Scheduler
* Setup Server model shall also be present.
* 2. This model shall support model publication and model subscription.
* 3. The model may be present only on the Primary element of a node.
* 4. The model requires the Time Server model shall be present on the element.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_scheduler_srv_t.
*
* @return New Scheduler Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_SCHEDULER_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SCHEDULER_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_SCHEDULER_SETUP_SRV
*
* @brief Define a new Scheduler Setup Server Model.
*
* @note 1. The Scheduler Setup Server model extends the Scheduler Server and
* the Scene Setup Server models.
* 2. This model shall support model subscription.
* 3. The model may be present only on the Primary element of a node.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_scheduler_setup_srv_t.
*
* @return New Scheduler Setup Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_SCHEDULER_SETUP_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SCHEDULER_SETUP_SRV, \
NULL, srv_pub, srv_data)
#define ESP_BLE_MESH_UNKNOWN_TAI_SECONDS 0x0000000000 /*!< Unknown TAI Seconds */
#define ESP_BLE_MESH_UNKNOWN_TAI_ZONE_CHANGE 0x0000000000 /*!< Unknown TAI of Zone Change */
#define ESP_BLE_MESH_UNKNOWN_TAI_DELTA_CHANGE 0x0000000000 /*!< Unknown TAI of Delta Change */
#define ESP_BLE_MESH_TAI_UTC_DELAT_MAX_VALUE 0x7FFF /*!< Maximum TAI-UTC Delta value */
#define ESP_BLE_MESH_TAI_SECONDS_LEN 0x05 /*!< Length of TAI Seconds */
#define ESP_BLE_MESH_TAI_OF_ZONE_CHANGE_LEN 0x05 /*!< Length of TAI of Zone Change */
#define ESP_BLE_MESH_TAI_OF_DELAT_CHANGE_LEN 0x05 /*!< Length of TAI of Delta Change */
#define ESP_BLE_MESH_INVALID_SCENE_NUMBER 0x0000 /*!< Invalid Scene Number */
#define ESP_BLE_MESH_SCENE_NUMBER_LEN 0x02 /*!< Length of the Scene Number */
#define ESP_BLE_MESH_SCHEDULE_YEAR_ANY_YEAR 0x64 /*!< Any year of the Scheduled year */
#define ESP_BLE_MESH_SCHEDULE_DAY_ANY_DAY 0x00 /*!< Any day of the Scheduled day */
#define ESP_BLE_MESH_SCHEDULE_HOUR_ANY_HOUR 0x18 /*!< Any hour of the Scheduled hour */
#define ESP_BLE_MESH_SCHEDULE_HOUR_ONCE_A_DAY 0x19 /*!< Any hour of the Scheduled Day */
#define ESP_BLE_MESH_SCHEDULE_SEC_ANY_OF_HOUR 0x3C /*!< Any minute of the Scheduled hour */
#define ESP_BLE_MESH_SCHEDULE_SEC_EVERY_15_MIN 0x3D /*!< Every 15 minutes of the Scheduled hour */
#define ESP_BLE_MESH_SCHEDULE_SEC_EVERY_20_MIN 0x3E /*!< Every 20 minutes of the Scheduled hour */
#define ESP_BLE_MESH_SCHEDULE_SEC_ONCE_AN_HOUR 0x3F /*!< Once of the Scheduled hour */
#define ESP_BLE_MESH_SCHEDULE_SEC_ANY_OF_MIN 0x3C /*!< Any second of the Scheduled minute */
#define ESP_BLE_MESH_SCHEDULE_SEC_EVERY_15_SEC 0x3D /*!< Every 15 seconds of the Scheduled minute */
#define ESP_BLE_MESH_SCHEDULE_SEC_EVERY_20_SEC 0x3E /*!< Every 20 seconds of the Scheduled minute */
#define ESP_BLE_MESH_SCHEDULE_SEC_ONCE_AN_MIN 0x3F /*!< Once of the Scheduled minute */
#define ESP_BLE_MESH_SCHEDULE_ACT_TURN_OFF 0x00 /*!< Scheduled Action - Turn Off */
#define ESP_BLE_MESH_SCHEDULE_ACT_TURN_ON 0x01 /*!< Scheduled Action - Turn On */
#define ESP_BLE_MESH_SCHEDULE_ACT_SCENE_RECALL 0x02 /*!< Scheduled Action - Scene Recall */
#define ESP_BLE_MESH_SCHEDULE_ACT_NO_ACTION 0x0F /*!< Scheduled Action - No Action */
#define ESP_BLE_MESH_SCHEDULE_SCENE_NO_SCENE 0x0000 /*!< Scheduled Scene - No Scene */
#define ESP_BLE_MESH_SCHEDULE_ENTRY_MAX_INDEX 0x0F /*!< Maximum number of Scheduled entries */
#define ESP_BLE_MESH_TIME_NONE 0x00 /*!< Time Role - None */
#define ESP_BLE_MESH_TIME_AUTHORITY 0x01 /*!< Time Role - Mesh Time Authority */
#define ESP_BLE_MESH_TIME_RELAY 0x02 /*!< Time Role - Mesh Time Relay */
#define ESP_BLE_MESH_TIME_CLINET 0x03 /*!< Time Role - Mesh Time Client */
#define ESP_BLE_MESH_SCENE_SUCCESS 0x00 /*!< Scene operation - Success */
#define ESP_BLE_MESH_SCENE_REG_FULL 0x01 /*!< Scene operation - Scene Register Full */
#define ESP_BLE_MESH_SCENE_NOT_FOUND 0x02 /*!< Scene operation - Scene Not Found */
/** Parameters of Time state */
typedef struct {
struct {
uint8_t tai_seconds[5]; /*!< The value of the TAI Seconds state */
uint8_t subsecond; /*!< The value of the Subsecond field */
uint8_t uncertainty; /*!< The value of the Uncertainty field */
uint8_t time_zone_offset_curr; /*!< The value of the Time Zone Offset Current field */
uint8_t time_zone_offset_new; /*!< The value of the Time Zone Offset New state */
uint8_t tai_zone_change[5]; /*!< The value of the TAI of Zone Chaneg field */
uint16_t time_authority : 1, /*!< The value of the Time Authority bit */
tai_utc_delta_curr : 15; /*!< The value of the TAI-UTC Delta Current state */
uint16_t tai_utc_delta_new : 15; /*!< The value of the TAI-UTC Delta New state */
uint8_t tai_delta_change[5]; /*!< The value of the TAI of Delta Change field */
} time; /*!< Parameters of the Time state */
uint8_t time_role; /*!< The value of the Time Role state */
} esp_ble_mesh_time_state_t;
/** User data of Time Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Time Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_time_state_t *state; /*!< Parameters of the Time state */
} esp_ble_mesh_time_srv_t;
/** User data of Time Setup Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Time Setup Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_time_state_t *state; /*!< Parameters of the Time state */
} esp_ble_mesh_time_setup_srv_t;
/**
* 1. Scene Store is an operation of storing values of a present state of an element.
* 2. The structure and meaning of the stored state is determined by a model. States
* to be stored are specified by each model.
* 3. The Scene Store operation shall persistently store all values of all states
* marked as Stored with Scene for all models present on all elements of a node.
* 4. If a model is extending another model, the extending model shall determine the
* Stored with Scene behavior of that model.
*/
/** Parameters of Scene Register state */
typedef struct {
uint16_t scene_number; /*!< The value of the Scene Number */
uint8_t scene_type; /*!< The value of the Scene Type */
/**
* Scene value may use a union to represent later, the union contains
* structures of all the model states which can be stored in a scene.
*/
struct net_buf_simple *scene_value; /*!< The value of the Scene Value */
} esp_ble_mesh_scene_register_t;
/**
* Parameters of Scenes state.
*
* Scenes serve as memory banks for storage of states (e.g., a power level
* or a light level/color). Values of states of an element can be stored
* as a scene and can be recalled later from the scene memory.
*
* A scene is represented by a Scene Number, which is a 16-bit non-zero,
* mesh-wide value. (There can be a maximum of 65535 scenes in a mesh
* network.) The meaning of a scene, as well as the state storage container
* associated with it, are determined by a model.
*
* The Scenes state change may start numerous parallel model transitions.
* In that case, each individual model handles the transition internally.
*
* The scene transition is defined as a group of individual model transitions
* started by a Scene Recall operation. The scene transition is in progress
* when at least one transition from the group of individual model transitions
* is in progress.
*/
typedef struct {
const uint16_t scene_count; /*!< The Scenes state's scene count */
esp_ble_mesh_scene_register_t *scenes; /*!< Parameters of the Scenes state */
/**
* The Current Scene state is a 16-bit value that contains either the Scene
* Number of the currently active scene or a value of 0x0000 when no scene
* is active.
*
* When a Scene Store operation or a Scene Recall operation completes with
* success, the Current Scene state value shall be to the Scene Number used
* during that operation.
*
* When the Current Scene Number is deleted from a Scene Register state as a
* result of Scene Delete operation, the Current Scene state shall be set to
* 0x0000.
*
* When any of the element's state that is marked as Stored with Scene has
* changed not as a result of a Scene Recall operation, the value of the
* Current Scene state shall be set to 0x0000.
*
* When a scene transition is in progress, the value of the Current Scene
* state shall be set to 0x0000.
*/
uint16_t current_scene; /*!< The value of the Current Scene state */
/**
* The Target Scene state is a 16-bit value that contains the target Scene
* Number when a scene transition is in progress.
*
* When the scene transition is in progress and the target Scene Number is
* deleted from a Scene Register state as a result of Scene Delete operation,
* the Target Scene state shall be set to 0x0000.
*
* When the scene transition is in progress and a new Scene Number is stored
* in the Scene Register as a result of Scene Store operation, the Target
* Scene state shall be set to the new Scene Number.
*
* When the scene transition is not in progress, the value of the Target Scene
* state shall be set to 0x0000.
*/
uint16_t target_scene; /*!< The value of the Target Scene state */
/* Indicate the status code for the last operation */
uint8_t status_code; /*!< The status code of the last scene operation */
/* Indicate if scene transition is in progress */
bool in_progress; /*!< Indicate if the scene transition is in progress */
} esp_ble_mesh_scenes_state_t;
/** User data of Scene Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Scene Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_scenes_state_t *state; /*!< Parameters of the Scenes state */
esp_ble_mesh_last_msg_info_t last; /*!< Parameters of the last received set message */
esp_ble_mesh_state_transition_t transition; /*!< Parameters of state transition */
} esp_ble_mesh_scene_srv_t;
/** User data of Scene Setup Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Scene Setup Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_scenes_state_t *state; /*!< Parameters of the Scenes state */
} esp_ble_mesh_scene_setup_srv_t;
/** Parameters of Scheduler Register state */
typedef struct {
bool in_use; /*!< Indicate if the registered schedule is in use */
uint64_t year : 7, /*!< The value of Scheduled year for the action */
month : 12, /*!< The value of Scheduled month for the action */
day : 5, /*!< The value of Scheduled day of the month for the action */
hour : 5, /*!< The value of Scheduled hour for the action */
minute : 6, /*!< The value of Scheduled minute for the action */
second : 6, /*!< The value of Scheduled second for the action */
day_of_week : 7, /*!< The value of Schedule days of the week for the action */
action : 4, /*!< The value of Action to be performed at the scheduled time */
trans_time : 8; /*!< The value of Transition time for this action */
uint16_t scene_number; /*!< The value of Scene Number to be used for some actions */
} esp_ble_mesh_schedule_register_t;
/** Parameters of Scheduler state */
typedef struct {
const uint8_t schedule_count; /*!< Scheduler count */
esp_ble_mesh_schedule_register_t *schedules; /*!< Up to 16 scheduled entries */
} esp_ble_mesh_scheduler_state_t;
/** User data of Scheduler Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Scheduler Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_scheduler_state_t *state; /*!< Parameters of the Scheduler state */
} esp_ble_mesh_scheduler_srv_t;
/** User data of Scheduler Setup Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Scheduler Setup Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_scheduler_state_t *state; /*!< Parameters of the Scheduler state */
} esp_ble_mesh_scheduler_setup_srv_t;
/** Parameters of Time Set state change event */
typedef struct {
uint8_t tai_seconds[5]; /*!< The current TAI time in seconds */
uint8_t subsecond; /*!< The sub-second time in units of 1/256 second */
uint8_t uncertainty; /*!< The estimated uncertainty in 10-millisecond steps */
uint16_t time_authority : 1; /*!< 0 = No Time Authority, 1 = Time Authority */
uint16_t tai_utc_delta_curr : 15; /*!< Current difference between TAI and UTC in seconds */
uint8_t time_zone_offset_curr; /*!< The local time zone offset in 15-minute increments */
} esp_ble_mesh_state_change_time_set_t;
/** Parameters of Time Status state change event */
typedef struct {
uint8_t tai_seconds[5]; /*!< The current TAI time in seconds */
uint8_t subsecond; /*!< The sub-second time in units of 1/256 second */
uint8_t uncertainty; /*!< The estimated uncertainty in 10-millisecond steps */
uint16_t time_authority : 1; /*!< 0 = No Time Authority, 1 = Time Authority */
uint16_t tai_utc_delta_curr : 15; /*!< Current difference between TAI and UTC in seconds */
uint8_t time_zone_offset_curr; /*!< The local time zone offset in 15-minute increments */
} esp_ble_mesh_state_change_time_status_t;
/** Parameters of Time Zone Set state change event */
typedef struct {
uint8_t time_zone_offset_new; /*!< Upcoming local time zone offset */
uint8_t tai_zone_change[5]; /*!< TAI Seconds time of the upcoming Time Zone Offset change */
} esp_ble_mesh_state_change_time_zone_set_t;
/** Parameters of TAI UTC Delta Set state change event */
typedef struct {
uint16_t tai_utc_delta_new : 15; /*!< Upcoming difference between TAI and UTC in seconds */
uint8_t tai_delta_change[5]; /*!< TAI Seconds time of the upcoming TAI-UTC Delta change */
} esp_ble_mesh_state_change_tai_utc_delta_set_t;
/** Parameter of Time Role Set state change event */
typedef struct {
uint8_t time_role; /*!< The Time Role for the element */
} esp_ble_mesh_state_change_time_role_set_t;
/** Parameter of Scene Store state change event */
typedef struct {
uint16_t scene_number; /*!< The number of scenes to be stored */
} esp_ble_mesh_state_change_scene_store_t;
/** Parameter of Scene Recall state change event */
typedef struct {
uint16_t scene_number; /*!< The number of scenes to be recalled */
} esp_ble_mesh_state_change_scene_recall_t;
/** Parameter of Scene Delete state change event */
typedef struct {
uint16_t scene_number; /*!< The number of scenes to be deleted */
} esp_ble_mesh_state_change_scene_delete_t;
/** Parameter of Scheduler Action Set state change event */
typedef struct {
uint64_t index : 4; /*!< Index of the Schedule Register entry to set */
uint64_t year : 7; /*!< Scheduled year for the action */
uint64_t month : 12; /*!< Scheduled month for the action */
uint64_t day : 5; /*!< Scheduled day of the month for the action */
uint64_t hour : 5; /*!< Scheduled hour for the action */
uint64_t minute : 6; /*!< Scheduled minute for the action */
uint64_t second : 6; /*!< Scheduled second for the action */
uint64_t day_of_week : 7; /*!< Schedule days of the week for the action */
uint64_t action : 4; /*!< Action to be performed at the scheduled time */
uint64_t trans_time : 8; /*!< Transition time for this action */
uint16_t scene_number; /*!< Scene number to be used for some actions */
} esp_ble_mesh_state_change_scheduler_act_set_t;
/**
* @brief Time Scene Server Model state change value union
*/
typedef union {
/**
* The recv_op in ctx can be used to decide which state is changed.
*/
esp_ble_mesh_state_change_time_set_t time_set; /*!< Time Set */
esp_ble_mesh_state_change_time_status_t time_status; /*!< Time Status */
esp_ble_mesh_state_change_time_zone_set_t time_zone_set; /*!< Time Zone Set */
esp_ble_mesh_state_change_tai_utc_delta_set_t tai_utc_delta_set; /*!< TAI UTC Delta Set */
esp_ble_mesh_state_change_time_role_set_t time_role_set; /*!< Time Role Set */
esp_ble_mesh_state_change_scene_store_t scene_store; /*!< Scene Store */
esp_ble_mesh_state_change_scene_recall_t scene_recall; /*!< Scene Recall */
esp_ble_mesh_state_change_scene_delete_t scene_delete; /*!< Scene Delete */
esp_ble_mesh_state_change_scheduler_act_set_t scheduler_act_set; /*!< Scheduler Action Set */
} esp_ble_mesh_time_scene_server_state_change_t;
/** Context of the received Scheduler Action Get message */
typedef struct {
uint8_t index; /*!< Index of the Schedule Register entry to get */
} esp_ble_mesh_server_recv_scheduler_act_get_t;
/**
* @brief Time Scene Server Model received get message union
*/
typedef union {
esp_ble_mesh_server_recv_scheduler_act_get_t scheduler_act; /*!< Scheduler Action Get */
} esp_ble_mesh_time_scene_server_recv_get_msg_t;
/** Context of the received Time Set message */
typedef struct {
uint8_t tai_seconds[5]; /*!< The current TAI time in seconds */
uint8_t subsecond; /*!< The sub-second time in units of 1/256 second */
uint8_t uncertainty; /*!< The estimated uncertainty in 10-millisecond steps */
uint16_t time_authority : 1; /*!< 0 = No Time Authority, 1 = Time Authority */
uint16_t tai_utc_delta : 15; /*!< Current difference between TAI and UTC in seconds */
uint8_t time_zone_offset; /*!< The local time zone offset in 15-minute increments */
} esp_ble_mesh_server_recv_time_set_t;
/** Context of the received Time Zone Set message */
typedef struct {
uint8_t time_zone_offset_new; /*!< Upcoming local time zone offset */
uint8_t tai_zone_change[5]; /*!< TAI Seconds time of the upcoming Time Zone Offset change */
} esp_ble_mesh_server_recv_time_zone_set_t;
/** Context of the received TAI UTC Delta Set message */
typedef struct {
uint16_t tai_utc_delta_new : 15; /*!< Upcoming difference between TAI and UTC in seconds */
uint16_t padding : 1; /*!< Always 0b0. Other values are Prohibited. */
uint8_t tai_delta_change[5]; /*!< TAI Seconds time of the upcoming TAI-UTC Delta change */
} esp_ble_mesh_server_recv_tai_utc_delta_set_t;
/** Context of the received Time Role Set message */
typedef struct {
uint8_t time_role; /*!< The Time Role for the element */
} esp_ble_mesh_server_recv_time_role_set_t;
/** Context of the received Scene Store message */
typedef struct {
uint16_t scene_number; /*!< The number of scenes to be stored */
} esp_ble_mesh_server_recv_scene_store_t;
/** Context of the received Scene Recall message */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint16_t scene_number; /*!< The number of scenes to be recalled */
uint8_t tid; /*!< Transaction ID */
uint8_t trans_time; /*!< Time to complete state transition (optional) */
uint8_t delay; /*!< Indicate message execution delay (C.1) */
} esp_ble_mesh_server_recv_scene_recall_t;
/** Context of the received Scene Delete message */
typedef struct {
uint16_t scene_number; /*!< The number of scenes to be deleted */
} esp_ble_mesh_server_recv_scene_delete_t;
/** Context of the received Scheduler Action Set message */
typedef struct {
uint64_t index : 4; /*!< Index of the Schedule Register entry to set */
uint64_t year : 7; /*!< Scheduled year for the action */
uint64_t month : 12; /*!< Scheduled month for the action */
uint64_t day : 5; /*!< Scheduled day of the month for the action */
uint64_t hour : 5; /*!< Scheduled hour for the action */
uint64_t minute : 6; /*!< Scheduled minute for the action */
uint64_t second : 6; /*!< Scheduled second for the action */
uint64_t day_of_week : 7; /*!< Schedule days of the week for the action */
uint64_t action : 4; /*!< Action to be performed at the scheduled time */
uint64_t trans_time : 8; /*!< Transition time for this action */
uint16_t scene_number; /*!< Scene number to be used for some actions */
} esp_ble_mesh_server_recv_scheduler_act_set_t;
/**
* @brief Time Scene Server Model received set message union
*/
typedef union {
esp_ble_mesh_server_recv_time_set_t time; /*!< Time Set */
esp_ble_mesh_server_recv_time_zone_set_t time_zone; /*!< Time Zone Set */
esp_ble_mesh_server_recv_tai_utc_delta_set_t tai_utc_delta; /*!< TAI-UTC Delta Set */
esp_ble_mesh_server_recv_time_role_set_t time_role; /*!< Time Role Set */
esp_ble_mesh_server_recv_scene_store_t scene_store; /*!< Scene Store/Scene Store Unack */
esp_ble_mesh_server_recv_scene_recall_t scene_recall; /*!< Scene Recall/Scene Recall Unack */
esp_ble_mesh_server_recv_scene_delete_t scene_delete; /*!< Scene Delete/Scene Delete Unack */
esp_ble_mesh_server_recv_scheduler_act_set_t scheduler_act; /*!< Scheduler Action Set/Scheduler Action Set Unack */
} esp_ble_mesh_time_scene_server_recv_set_msg_t;
/** Context of the received Time Status message */
typedef struct {
uint8_t tai_seconds[5]; /*!< The current TAI time in seconds */
uint8_t subsecond; /*!< The sub-second time in units of 1/256 second */
uint8_t uncertainty; /*!< The estimated uncertainty in 10-millisecond steps */
uint16_t time_authority : 1; /*!< 0 = No Time Authority, 1 = Time Authority */
uint16_t tai_utc_delta : 15; /*!< Current difference between TAI and UTC in seconds */
uint8_t time_zone_offset; /*!< The local time zone offset in 15-minute increments */
} esp_ble_mesh_server_recv_time_status_t;
/**
* @brief Time Scene Server Model received status message union
*/
typedef union {
esp_ble_mesh_server_recv_time_status_t time_status; /*!< Time Status */
} esp_ble_mesh_time_scene_server_recv_status_msg_t;
/**
* @brief Time Scene Server Model callback value union
*/
typedef union {
esp_ble_mesh_time_scene_server_state_change_t state_change; /*!< ESP_BLE_MESH_TIME_SCENE_SERVER_STATE_CHANGE_EVT */
esp_ble_mesh_time_scene_server_recv_get_msg_t get; /*!< ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_GET_MSG_EVT */
esp_ble_mesh_time_scene_server_recv_set_msg_t set; /*!< ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_SET_MSG_EVT */
esp_ble_mesh_time_scene_server_recv_status_msg_t status; /*!< ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_STATUS_MSG_EVT */
} esp_ble_mesh_time_scene_server_cb_value_t;
/** Time Scene Server Model callback parameters */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to Time and Scenes Server Models */
esp_ble_mesh_msg_ctx_t ctx; /*!< Context of the received messages */
esp_ble_mesh_time_scene_server_cb_value_t value; /*!< Value of the received Time and Scenes Messages */
} esp_ble_mesh_time_scene_server_cb_param_t;
/** This enum value is the event of Time Scene Server Model */
typedef enum {
/**
* 1. When get_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, no event will be
* callback to the application layer when Time Scene Get messages are received.
* 2. When set_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, this event will
* be callback to the application layer when Time Scene Set/Set Unack messages
* are received.
*/
ESP_BLE_MESH_TIME_SCENE_SERVER_STATE_CHANGE_EVT,
/**
* When get_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
* callback to the application layer when Time Scene Get messages are received.
*/
ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_GET_MSG_EVT,
/**
* When set_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
* callback to the application layer when Time Scene Set/Set Unack messages are received.
*/
ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_SET_MSG_EVT,
/**
* When status_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will
* be callback to the application layer when TIme Status message is received.
*/
ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_STATUS_MSG_EVT,
ESP_BLE_MESH_TIME_SCENE_SERVER_EVT_MAX,
} esp_ble_mesh_time_scene_server_cb_event_t;
/**
* @brief Bluetooth Mesh Time and Scenes Server Model function.
*/
/**
* @brief Time Scene Server Model callback function type
* @param event: Event type
* @param param: Pointer to callback parameter
*/
typedef void (* esp_ble_mesh_time_scene_server_cb_t)(esp_ble_mesh_time_scene_server_cb_event_t event,
esp_ble_mesh_time_scene_server_cb_param_t *param);
/**
* @brief Register BLE Mesh Time and Scenes Server Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_time_scene_server_callback(esp_ble_mesh_time_scene_server_cb_t callback);
#endif /* _ESP_BLE_MESH_TIME_SCENE_MODEL_API_H_ */

View File

@ -288,6 +288,11 @@ static void btc_ble_mesh_config_client_callback(esp_ble_mesh_cfg_client_cb_param
LOG_DEBUG("%s", __func__);
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_CONFIG_CLIENT)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_CONFIG_CLIENT;
msg.act = act;
@ -687,6 +692,11 @@ static void btc_ble_mesh_config_server_callback(esp_ble_mesh_cfg_server_cb_param
LOG_DEBUG("%s", __func__);
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_CONFIG_SERVER)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_CONFIG_SERVER;
msg.act = act;
@ -709,8 +719,8 @@ void bt_mesh_config_server_cb_evt_to_btc(u8_t evt_type,
}
switch (evt_type) {
case BTC_BLE_MESH_EVT_CONFIG_SERVER_RECV_MSG:
act = ESP_BLE_MESH_CFG_SERVER_RECV_MSG_EVT;
case BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE:
act = ESP_BLE_MESH_CFG_SERVER_STATE_CHANGE_EVT;
break;
default:
LOG_ERROR("%s, Unknown config server event type %d", __func__, evt_type);
@ -726,8 +736,8 @@ void bt_mesh_config_server_cb_evt_to_btc(u8_t evt_type,
cb_params.ctx.recv_dst = ctx->recv_dst;
if (val && len) {
length = (len <= sizeof(cb_params.status_cb)) ? len : sizeof(cb_params.status_cb);
memcpy(&cb_params.status_cb, val, length);
length = (len <= sizeof(cb_params.value)) ? len : sizeof(cb_params.value);
memcpy(&cb_params.value, val, length);
}
btc_ble_mesh_config_server_callback(&cb_params, act);

View File

@ -361,6 +361,11 @@ static void btc_ble_mesh_generic_client_callback(esp_ble_mesh_generic_client_cb_
LOG_DEBUG("%s", __func__);
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_GENERIC_CLIENT)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GENERIC_CLIENT;
msg.act = act;
@ -534,3 +539,232 @@ void btc_ble_mesh_generic_client_cb_handler(btc_msg_t *msg)
btc_ble_mesh_generic_client_free_req_data(msg);
return;
}
/* Generic Server Models related functions */
static inline void btc_ble_mesh_generic_server_cb_to_app(
esp_ble_mesh_generic_server_cb_event_t event,
esp_ble_mesh_generic_server_cb_param_t *param)
{
esp_ble_mesh_generic_server_cb_t btc_ble_mesh_cb =
(esp_ble_mesh_generic_server_cb_t)btc_profile_cb_get(BTC_PID_GENERIC_SERVER);
if (btc_ble_mesh_cb) {
btc_ble_mesh_cb(event, param);
}
}
static void btc_ble_mesh_generic_server_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
{
esp_ble_mesh_generic_server_cb_param_t *p_dest_data = (esp_ble_mesh_generic_server_cb_param_t *)p_dest;
esp_ble_mesh_generic_server_cb_param_t *p_src_data = (esp_ble_mesh_generic_server_cb_param_t *)p_src;
u16_t length;
if (!msg || !p_src_data || !p_dest_data) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
switch (msg->act) {
case ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT:
switch (p_src_data->ctx.recv_op) {
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK:
if (p_src_data->value.state_change.user_property_set.value) {
length = p_src_data->value.state_change.user_property_set.value->len;
p_dest_data->value.state_change.user_property_set.value = bt_mesh_alloc_buf(length);
if (p_dest_data->value.state_change.user_property_set.value == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.state_change.user_property_set.value,
p_src_data->value.state_change.user_property_set.value->data,
p_src_data->value.state_change.user_property_set.value->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK:
if (p_src_data->value.state_change.admin_property_set.value) {
length = p_src_data->value.state_change.admin_property_set.value->len;
p_dest_data->value.state_change.admin_property_set.value = bt_mesh_alloc_buf(length);
if (p_dest_data->value.state_change.admin_property_set.value == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.state_change.admin_property_set.value,
p_src_data->value.state_change.admin_property_set.value->data,
p_src_data->value.state_change.admin_property_set.value->len);
}
break;
default:
break;
}
break;
case ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT:
switch (p_src_data->ctx.recv_op) {
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK:
if (p_src_data->value.set.user_property.property_value) {
length = p_src_data->value.set.user_property.property_value->len;
p_dest_data->value.set.user_property.property_value = bt_mesh_alloc_buf(length);
if (p_dest_data->value.set.user_property.property_value == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.set.user_property.property_value,
p_src_data->value.set.user_property.property_value->data,
p_src_data->value.set.user_property.property_value->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK:
if (p_src_data->value.set.admin_property.property_value) {
length = p_src_data->value.set.admin_property.property_value->len;
p_dest_data->value.set.admin_property.property_value = bt_mesh_alloc_buf(length);
if (p_dest_data->value.set.admin_property.property_value == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.set.admin_property.property_value,
p_src_data->value.set.admin_property.property_value->data,
p_src_data->value.set.admin_property.property_value->len);
}
break;
default:
break;
}
break;
default:
break;
}
}
static void btc_ble_mesh_generic_server_free_req_data(btc_msg_t *msg)
{
esp_ble_mesh_generic_server_cb_param_t *arg = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
arg = (esp_ble_mesh_generic_server_cb_param_t *)(msg->arg);
switch (msg->act) {
case ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT:
switch (arg->ctx.recv_op) {
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK:
bt_mesh_free_buf(arg->value.state_change.user_property_set.value);
break;
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK:
bt_mesh_free_buf(arg->value.state_change.admin_property_set.value);
break;
default:
break;
}
break;
case ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT:
switch (arg->ctx.recv_op) {
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK:
bt_mesh_free_buf(arg->value.set.user_property.property_value);
break;
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK:
bt_mesh_free_buf(arg->value.set.admin_property.property_value);
break;
default:
break;
}
break;
default:
break;
}
}
static void btc_ble_mesh_generic_server_callback(esp_ble_mesh_generic_server_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
LOG_DEBUG("%s", __func__);
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_GENERIC_SERVER)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GENERIC_SERVER;
msg.act = act;
btc_transfer_context(&msg, cb_params,
sizeof(esp_ble_mesh_generic_server_cb_param_t), btc_ble_mesh_generic_server_copy_req_data);
}
void bt_mesh_generic_server_cb_evt_to_btc(u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len)
{
esp_ble_mesh_generic_server_cb_param_t cb_params = {0};
size_t length;
uint8_t act;
if (model == NULL || ctx == NULL) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
switch (evt_type) {
case BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE:
act = ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT;
break;
case BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG:
act = ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT;
break;
case BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG:
act = ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT;
break;
default:
LOG_ERROR("%s, Unknown Generic Server event type", __func__);
return;
}
cb_params.model = (esp_ble_mesh_model_t *)model;
cb_params.ctx.net_idx = ctx->net_idx;
cb_params.ctx.app_idx = ctx->app_idx;
cb_params.ctx.addr = ctx->addr;
cb_params.ctx.recv_ttl = ctx->recv_ttl;
cb_params.ctx.recv_op = ctx->recv_op;
cb_params.ctx.recv_dst = ctx->recv_dst;
if (val && len) {
length = (len <= sizeof(cb_params.value)) ? len : sizeof(cb_params.value);
memcpy(&cb_params.value, val, length);
}
btc_ble_mesh_generic_server_callback(&cb_params, act);
return;
}
void btc_ble_mesh_generic_server_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_generic_server_cb_param_t *param = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
param = (esp_ble_mesh_generic_server_cb_param_t *)(msg->arg);
if (msg->act < ESP_BLE_MESH_GENERIC_SERVER_EVT_MAX) {
btc_ble_mesh_generic_server_cb_to_app(msg->act, param);
} else {
LOG_ERROR("%s, Unknown msg->act = %d", __func__, msg->act);
}
btc_ble_mesh_generic_server_free_req_data(msg);
return;
}

View File

@ -229,6 +229,11 @@ static void btc_ble_mesh_health_client_callback(esp_ble_mesh_health_client_cb_pa
LOG_DEBUG("%s", __func__);
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_HEALTH_CLIENT)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_HEALTH_CLIENT;
msg.act = act;
@ -517,7 +522,7 @@ static void btc_ble_mesh_health_server_copy_req_data(btc_msg_t *msg, void *p_des
}
switch (msg->act) {
case ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMPLETE_EVT:
case ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMP_EVT:
break;
default:
break;
@ -532,7 +537,7 @@ static void btc_ble_mesh_health_server_free_req_data(btc_msg_t *msg)
}
switch (msg->act) {
case ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMPLETE_EVT:
case ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMP_EVT:
break;
default:
break;
@ -545,6 +550,11 @@ static void btc_ble_mesh_health_server_callback(esp_ble_mesh_health_server_cb_pa
LOG_DEBUG("%s", __func__);
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_HEALTH_SERVER)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_HEALTH_SERVER;
msg.act = act;
@ -555,7 +565,7 @@ static void btc_ble_mesh_health_server_callback(esp_ble_mesh_health_server_cb_pa
void btc_ble_mesh_health_server_call_handler(btc_msg_t *msg)
{
esp_ble_mesh_health_server_cb_param_t health_server_cb = {0};
esp_ble_mesh_health_server_cb_param_t param = {0};
btc_ble_mesh_health_server_args_t *arg = NULL;
if (!msg || !msg->arg) {
@ -567,10 +577,10 @@ void btc_ble_mesh_health_server_call_handler(btc_msg_t *msg)
switch (msg->act) {
case BTC_BLE_MESH_ACT_HEALTH_SERVER_FAULT_UPDATE:
health_server_cb.error_code =
bt_mesh_fault_update((struct bt_mesh_elem *)arg->fault_update.element);
btc_ble_mesh_health_server_callback(
&health_server_cb, ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMPLETE_EVT);
param.fault_update_comp.element = arg->health_fault_update.element;
param.fault_update_comp.error_code =
bt_mesh_fault_update((struct bt_mesh_elem *)arg->health_fault_update.element);
btc_ble_mesh_health_server_callback(&param, ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMP_EVT);
break;
default:
break;
@ -600,3 +610,43 @@ void btc_ble_mesh_health_server_cb_handler(btc_msg_t *msg)
btc_ble_mesh_health_server_free_req_data(msg);
return;
}
void btc_ble_mesh_health_server_fault_clear(struct bt_mesh_model *model, u16_t company_id)
{
esp_ble_mesh_health_server_cb_param_t param = {0};
param.fault_clear.model = (esp_ble_mesh_model_t *)model;
param.fault_clear.company_id = company_id;
btc_ble_mesh_health_server_callback(&param, ESP_BLE_MESH_HEALTH_SERVER_FAULT_CLEAR_EVT);
}
void btc_ble_mesh_health_server_fault_test(struct bt_mesh_model *model, u8_t test_id, u16_t company_id)
{
esp_ble_mesh_health_server_cb_param_t param = {0};
param.fault_test.model = (esp_ble_mesh_model_t *)model;
param.fault_test.test_id = test_id;
param.fault_test.company_id = company_id;
btc_ble_mesh_health_server_callback(&param, ESP_BLE_MESH_HEALTH_SERVER_FAULT_TEST_EVT);
}
void btc_ble_mesh_health_server_attention_on(struct bt_mesh_model *model, u8_t time)
{
esp_ble_mesh_health_server_cb_param_t param = {0};
param.attention_on.model = (esp_ble_mesh_model_t *)model;
param.attention_on.time = time;
btc_ble_mesh_health_server_callback(&param, ESP_BLE_MESH_HEALTH_SERVER_ATTENTION_ON_EVT);
}
void btc_ble_mesh_health_server_attention_off(struct bt_mesh_model *model)
{
esp_ble_mesh_health_server_cb_param_t param = {0};
param.attention_off.model = (esp_ble_mesh_model_t *)model;
btc_ble_mesh_health_server_callback(&param, ESP_BLE_MESH_HEALTH_SERVER_ATTENTION_OFF_EVT);
}

View File

@ -205,6 +205,11 @@ static void btc_ble_mesh_lighting_client_callback(esp_ble_mesh_light_client_cb_p
LOG_DEBUG("%s", __func__);
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_LIGHTING_CLIENT)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_LIGHTING_CLIENT;
msg.act = act;
@ -379,3 +384,202 @@ void btc_ble_mesh_lighting_client_cb_handler(btc_msg_t *msg)
return;
}
/* Lighting Server Models related functions */
static inline void btc_ble_mesh_lighting_server_cb_to_app(
esp_ble_mesh_lighting_server_cb_event_t event,
esp_ble_mesh_lighting_server_cb_param_t *param)
{
esp_ble_mesh_lighting_server_cb_t btc_ble_mesh_cb =
(esp_ble_mesh_lighting_server_cb_t)btc_profile_cb_get(BTC_PID_LIGHTING_SERVER);
if (btc_ble_mesh_cb) {
btc_ble_mesh_cb(event, param);
}
}
static void btc_ble_mesh_lighting_server_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
{
esp_ble_mesh_lighting_server_cb_param_t *p_dest_data = (esp_ble_mesh_lighting_server_cb_param_t *)p_dest;
esp_ble_mesh_lighting_server_cb_param_t *p_src_data = (esp_ble_mesh_lighting_server_cb_param_t *)p_src;
u16_t length;
if (!msg || !p_src_data || !p_dest_data) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
switch (msg->act) {
case ESP_BLE_MESH_LIGHTING_SERVER_STATE_CHANGE_EVT:
if (p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET ||
p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK) {
if (p_src_data->value.state_change.lc_property_set.property_value) {
length = p_src_data->value.state_change.lc_property_set.property_value->len;
p_dest_data->value.state_change.lc_property_set.property_value = bt_mesh_alloc_buf(length);
if (p_dest_data->value.state_change.lc_property_set.property_value == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.state_change.lc_property_set.property_value,
p_src_data->value.state_change.lc_property_set.property_value->data,
p_src_data->value.state_change.lc_property_set.property_value->len);
}
}
break;
case ESP_BLE_MESH_LIGHTING_SERVER_RECV_SET_MSG_EVT:
if (p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET ||
p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK) {
if (p_src_data->value.set.lc_property.property_value) {
length = p_src_data->value.set.lc_property.property_value->len;
p_dest_data->value.set.lc_property.property_value = bt_mesh_alloc_buf(length);
if (p_dest_data->value.set.lc_property.property_value == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.set.lc_property.property_value,
p_src_data->value.set.lc_property.property_value->data,
p_src_data->value.set.lc_property.property_value->len);
}
}
break;
case ESP_BLE_MESH_LIGHTING_SERVER_RECV_STATUS_MSG_EVT:
if (p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_STATUS) {
if (p_src_data->value.status.sensor_status.data) {
length = p_src_data->value.status.sensor_status.data->len;
p_dest_data->value.status.sensor_status.data = bt_mesh_alloc_buf(length);
if (p_dest_data->value.status.sensor_status.data == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.status.sensor_status.data,
p_src_data->value.status.sensor_status.data->data,
p_src_data->value.status.sensor_status.data->len);
}
}
break;
default:
break;
}
}
static void btc_ble_mesh_lighting_server_free_req_data(btc_msg_t *msg)
{
esp_ble_mesh_lighting_server_cb_param_t *arg = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
arg = (esp_ble_mesh_lighting_server_cb_param_t *)(msg->arg);
switch (msg->act) {
case ESP_BLE_MESH_LIGHTING_SERVER_STATE_CHANGE_EVT:
if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET ||
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK) {
bt_mesh_free_buf(arg->value.state_change.lc_property_set.property_value);
}
break;
case ESP_BLE_MESH_LIGHTING_SERVER_RECV_SET_MSG_EVT:
if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET ||
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK) {
bt_mesh_free_buf(arg->value.set.lc_property.property_value);
}
break;
case ESP_BLE_MESH_LIGHTING_SERVER_RECV_STATUS_MSG_EVT:
if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_STATUS) {
bt_mesh_free_buf(arg->value.status.sensor_status.data);
}
break;
default:
break;
}
}
static void btc_ble_mesh_lighting_server_callback(esp_ble_mesh_lighting_server_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
LOG_DEBUG("%s", __func__);
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_LIGHTING_SERVER)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_LIGHTING_SERVER;
msg.act = act;
btc_transfer_context(
&msg, cb_params, sizeof(esp_ble_mesh_lighting_server_cb_param_t), btc_ble_mesh_lighting_server_copy_req_data);
}
void bt_mesh_lighting_server_cb_evt_to_btc(u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len)
{
esp_ble_mesh_lighting_server_cb_param_t cb_params = {0};
size_t length;
uint8_t act;
if (model == NULL || ctx == NULL) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
switch (evt_type) {
case BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE:
act = ESP_BLE_MESH_LIGHTING_SERVER_STATE_CHANGE_EVT;
break;
case BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG:
act = ESP_BLE_MESH_LIGHTING_SERVER_RECV_GET_MSG_EVT;
break;
case BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG:
act = ESP_BLE_MESH_LIGHTING_SERVER_RECV_SET_MSG_EVT;
break;
case BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_STATUS_MSG:
act = ESP_BLE_MESH_LIGHTING_SERVER_RECV_STATUS_MSG_EVT;
break;
default:
LOG_ERROR("%s, Unknown Lighting Server event type", __func__);
return;
}
cb_params.model = (esp_ble_mesh_model_t *)model;
cb_params.ctx.net_idx = ctx->net_idx;
cb_params.ctx.app_idx = ctx->app_idx;
cb_params.ctx.addr = ctx->addr;
cb_params.ctx.recv_ttl = ctx->recv_ttl;
cb_params.ctx.recv_op = ctx->recv_op;
cb_params.ctx.recv_dst = ctx->recv_dst;
if (val && len) {
length = (len <= sizeof(cb_params.value)) ? len : sizeof(cb_params.value);
memcpy(&cb_params.value, val, length);
}
btc_ble_mesh_lighting_server_callback(&cb_params, act);
return;
}
void btc_ble_mesh_lighting_server_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_lighting_server_cb_param_t *param = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
param = (esp_ble_mesh_lighting_server_cb_param_t *)(msg->arg);
if (msg->act < ESP_BLE_MESH_LIGHTING_SERVER_EVT_MAX) {
btc_ble_mesh_lighting_server_cb_to_app(msg->act, param);
} else {
LOG_ERROR("%s, Unknown msg->act = %d", __func__, msg->act);
}
btc_ble_mesh_lighting_server_free_req_data(msg);
return;
}

File diff suppressed because it is too large Load Diff

View File

@ -450,6 +450,11 @@ static void btc_ble_mesh_sensor_client_callback(esp_ble_mesh_sensor_client_cb_pa
LOG_DEBUG("%s", __func__);
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_SENSOR_CLIENT)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_SENSOR_CLIENT;
msg.act = act;
@ -624,3 +629,281 @@ void btc_ble_mesh_sensor_client_cb_handler(btc_msg_t *msg)
return;
}
/* Sensor Server Models related functions */
static inline void btc_ble_mesh_sensor_server_cb_to_app(
esp_ble_mesh_sensor_server_cb_event_t event,
esp_ble_mesh_sensor_server_cb_param_t *param)
{
esp_ble_mesh_sensor_server_cb_t btc_ble_mesh_cb =
(esp_ble_mesh_sensor_server_cb_t)btc_profile_cb_get(BTC_PID_SENSOR_SERVER);
if (btc_ble_mesh_cb) {
btc_ble_mesh_cb(event, param);
}
}
static void btc_ble_mesh_sensor_server_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
{
esp_ble_mesh_sensor_server_cb_param_t *p_dest_data = (esp_ble_mesh_sensor_server_cb_param_t *)p_dest;
esp_ble_mesh_sensor_server_cb_param_t *p_src_data = (esp_ble_mesh_sensor_server_cb_param_t *)p_src;
u16_t length;
if (!msg || !p_src_data || !p_dest_data) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
switch (msg->act) {
case ESP_BLE_MESH_SENSOR_SERVER_STATE_CHANGE_EVT:
if (p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET ||
p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET_UNACK) {
if (p_src_data->value.state_change.sensor_cadence_set.trigger_delta_down) {
length = p_src_data->value.state_change.sensor_cadence_set.trigger_delta_down->len;
p_dest_data->value.state_change.sensor_cadence_set.trigger_delta_down = bt_mesh_alloc_buf(length);
if (p_dest_data->value.state_change.sensor_cadence_set.trigger_delta_down == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.state_change.sensor_cadence_set.trigger_delta_down,
p_src_data->value.state_change.sensor_cadence_set.trigger_delta_down->data,
p_src_data->value.state_change.sensor_cadence_set.trigger_delta_down->len);
}
if (p_src_data->value.state_change.sensor_cadence_set.trigger_delta_up) {
length = p_src_data->value.state_change.sensor_cadence_set.trigger_delta_up->len;
p_dest_data->value.state_change.sensor_cadence_set.trigger_delta_up = bt_mesh_alloc_buf(length);
if (p_dest_data->value.state_change.sensor_cadence_set.trigger_delta_up == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.state_change.sensor_cadence_set.trigger_delta_up,
p_src_data->value.state_change.sensor_cadence_set.trigger_delta_up->data,
p_src_data->value.state_change.sensor_cadence_set.trigger_delta_up->len);
}
if (p_src_data->value.state_change.sensor_cadence_set.fast_cadence_low) {
length = p_src_data->value.state_change.sensor_cadence_set.fast_cadence_low->len;
p_dest_data->value.state_change.sensor_cadence_set.fast_cadence_low = bt_mesh_alloc_buf(length);
if (p_dest_data->value.state_change.sensor_cadence_set.fast_cadence_low == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.state_change.sensor_cadence_set.fast_cadence_low,
p_src_data->value.state_change.sensor_cadence_set.fast_cadence_low->data,
p_src_data->value.state_change.sensor_cadence_set.fast_cadence_low->len);
}
if (p_src_data->value.state_change.sensor_cadence_set.fast_cadence_high) {
length = p_src_data->value.state_change.sensor_cadence_set.fast_cadence_high->len;
p_dest_data->value.state_change.sensor_cadence_set.fast_cadence_high = bt_mesh_alloc_buf(length);
if (p_dest_data->value.state_change.sensor_cadence_set.fast_cadence_high == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.state_change.sensor_cadence_set.fast_cadence_high,
p_src_data->value.state_change.sensor_cadence_set.fast_cadence_high->data,
p_src_data->value.state_change.sensor_cadence_set.fast_cadence_high->len);
}
} else if (p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET ||
p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET_UNACK) {
if (p_src_data->value.state_change.sensor_setting_set.setting_value) {
length = p_src_data->value.state_change.sensor_setting_set.setting_value->len;
p_dest_data->value.state_change.sensor_setting_set.setting_value = bt_mesh_alloc_buf(length);
if (p_dest_data->value.state_change.sensor_setting_set.setting_value == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.state_change.sensor_setting_set.setting_value,
p_src_data->value.state_change.sensor_setting_set.setting_value->data,
p_src_data->value.state_change.sensor_setting_set.setting_value->len);
}
}
break;
case ESP_BLE_MESH_SENSOR_SERVER_RECV_GET_MSG_EVT:
if (p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET) {
if (p_src_data->value.get.sensor_column.raw_value_x) {
length = p_src_data->value.get.sensor_column.raw_value_x->len;
p_dest_data->value.get.sensor_column.raw_value_x = bt_mesh_alloc_buf(length);
if (p_dest_data->value.get.sensor_column.raw_value_x == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.get.sensor_column.raw_value_x,
p_src_data->value.get.sensor_column.raw_value_x->data,
p_src_data->value.get.sensor_column.raw_value_x->len);
}
} else if (p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_GET) {
if (p_src_data->value.get.sensor_series.raw_value) {
length = p_src_data->value.get.sensor_series.raw_value->len;
p_dest_data->value.get.sensor_series.raw_value = bt_mesh_alloc_buf(length);
if (p_dest_data->value.get.sensor_series.raw_value == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.get.sensor_series.raw_value,
p_src_data->value.get.sensor_series.raw_value->data,
p_src_data->value.get.sensor_series.raw_value->len);
}
}
break;
case ESP_BLE_MESH_SENSOR_SERVER_RECV_SET_MSG_EVT:
if (p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET ||
p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET_UNACK) {
if (p_src_data->value.set.sensor_cadence.cadence) {
length = p_src_data->value.set.sensor_cadence.cadence->len;
p_dest_data->value.set.sensor_cadence.cadence = bt_mesh_alloc_buf(length);
if (p_dest_data->value.set.sensor_cadence.cadence == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.set.sensor_cadence.cadence,
p_src_data->value.set.sensor_cadence.cadence->data,
p_src_data->value.set.sensor_cadence.cadence->len);
}
} else if (p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET ||
p_src_data->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET_UNACK) {
if (p_src_data->value.set.sensor_setting.setting_raw) {
length = p_src_data->value.set.sensor_setting.setting_raw->len;
p_dest_data->value.set.sensor_setting.setting_raw = bt_mesh_alloc_buf(length);
if (p_dest_data->value.set.sensor_setting.setting_raw == NULL) {
LOG_ERROR("%s, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
net_buf_simple_add_mem(p_dest_data->value.set.sensor_setting.setting_raw,
p_src_data->value.set.sensor_setting.setting_raw->data,
p_src_data->value.set.sensor_setting.setting_raw->len);
}
}
break;
default:
break;
}
}
static void btc_ble_mesh_sensor_server_free_req_data(btc_msg_t *msg)
{
esp_ble_mesh_sensor_server_cb_param_t *arg = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
arg = (esp_ble_mesh_sensor_server_cb_param_t *)(msg->arg);
switch (msg->act) {
case ESP_BLE_MESH_SENSOR_SERVER_STATE_CHANGE_EVT:
if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET ||
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET_UNACK) {
bt_mesh_free_buf(arg->value.state_change.sensor_cadence_set.trigger_delta_down);
bt_mesh_free_buf(arg->value.state_change.sensor_cadence_set.trigger_delta_up);
bt_mesh_free_buf(arg->value.state_change.sensor_cadence_set.fast_cadence_low);
bt_mesh_free_buf(arg->value.state_change.sensor_cadence_set.fast_cadence_high);
} else if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET ||
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET_UNACK) {
bt_mesh_free_buf(arg->value.state_change.sensor_setting_set.setting_value);
}
break;
case ESP_BLE_MESH_SENSOR_SERVER_RECV_GET_MSG_EVT:
if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET) {
bt_mesh_free_buf(arg->value.get.sensor_column.raw_value_x);
} else if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_GET) {
bt_mesh_free_buf(arg->value.get.sensor_series.raw_value);
}
break;
case ESP_BLE_MESH_SENSOR_SERVER_RECV_SET_MSG_EVT:
if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET ||
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET_UNACK) {
bt_mesh_free_buf(arg->value.set.sensor_cadence.cadence);
} else if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET ||
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET_UNACK) {
bt_mesh_free_buf(arg->value.set.sensor_setting.setting_raw);
}
break;
default:
break;
}
}
static void btc_ble_mesh_sensor_server_callback(esp_ble_mesh_sensor_server_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
LOG_DEBUG("%s", __func__);
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_SENSOR_SERVER)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_SENSOR_SERVER;
msg.act = act;
btc_transfer_context(
&msg, cb_params, sizeof(esp_ble_mesh_sensor_server_cb_param_t), btc_ble_mesh_sensor_server_copy_req_data);
}
void bt_mesh_sensor_server_cb_evt_to_btc(u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len)
{
esp_ble_mesh_sensor_server_cb_param_t cb_params = {0};
size_t length;
uint8_t act;
if (model == NULL || ctx == NULL) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
switch (evt_type) {
case BTC_BLE_MESH_EVT_SENSOR_SERVER_STATE_CHANGE:
act = ESP_BLE_MESH_SENSOR_SERVER_STATE_CHANGE_EVT;
break;
case BTC_BLE_MESH_EVT_SENSOR_SERVER_RECV_GET_MSG:
act = ESP_BLE_MESH_SENSOR_SERVER_RECV_GET_MSG_EVT;
break;
case BTC_BLE_MESH_EVT_SENSOR_SERVER_RECV_SET_MSG:
act = ESP_BLE_MESH_SENSOR_SERVER_RECV_SET_MSG_EVT;
break;
default:
LOG_ERROR("%s, Unknown Sensor Server event type", __func__);
return;
}
cb_params.model = (esp_ble_mesh_model_t *)model;
cb_params.ctx.net_idx = ctx->net_idx;
cb_params.ctx.app_idx = ctx->app_idx;
cb_params.ctx.addr = ctx->addr;
cb_params.ctx.recv_ttl = ctx->recv_ttl;
cb_params.ctx.recv_op = ctx->recv_op;
cb_params.ctx.recv_dst = ctx->recv_dst;
if (val && len) {
length = (len <= sizeof(cb_params.value)) ? len : sizeof(cb_params.value);
memcpy(&cb_params.value, val, length);
}
btc_ble_mesh_sensor_server_callback(&cb_params, act);
return;
}
void btc_ble_mesh_sensor_server_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_sensor_server_cb_param_t *param = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
param = (esp_ble_mesh_sensor_server_cb_param_t *)(msg->arg);
if (msg->act < ESP_BLE_MESH_SENSOR_SERVER_EVT_MAX) {
btc_ble_mesh_sensor_server_cb_to_app(msg->act, param);
} else {
LOG_ERROR("%s, Unknown msg->act = %d", __func__, msg->act);
}
btc_ble_mesh_sensor_server_free_req_data(msg);
return;
}

View File

@ -207,6 +207,11 @@ static void btc_ble_mesh_time_scene_client_callback(esp_ble_mesh_time_scene_clie
LOG_DEBUG("%s", __func__);
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_TIME_SCENE_CLIENT)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_TIME_SCENE_CLIENT;
msg.act = act;
@ -381,3 +386,104 @@ void btc_ble_mesh_time_scene_client_cb_handler(btc_msg_t *msg)
return;
}
/* Time and Scenes Server Models related functions */
static inline void btc_ble_mesh_time_scene_server_cb_to_app(
esp_ble_mesh_time_scene_server_cb_event_t event,
esp_ble_mesh_time_scene_server_cb_param_t *param)
{
esp_ble_mesh_time_scene_server_cb_t btc_ble_mesh_cb =
(esp_ble_mesh_time_scene_server_cb_t)btc_profile_cb_get(BTC_PID_TIME_SCENE_SERVER);
if (btc_ble_mesh_cb) {
btc_ble_mesh_cb(event, param);
}
}
static void btc_ble_mesh_time_scene_server_callback(esp_ble_mesh_time_scene_server_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
LOG_DEBUG("%s", __func__);
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_TIME_SCENE_SERVER)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_TIME_SCENE_SERVER;
msg.act = act;
btc_transfer_context(
&msg, cb_params, sizeof(esp_ble_mesh_time_scene_server_cb_param_t), NULL);
}
void bt_mesh_time_scene_server_cb_evt_to_btc(u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len)
{
esp_ble_mesh_time_scene_server_cb_param_t cb_params = {0};
size_t length;
uint8_t act;
if (model == NULL || ctx == NULL) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
switch (evt_type) {
case BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_STATE_CHANGE:
act = ESP_BLE_MESH_TIME_SCENE_SERVER_STATE_CHANGE_EVT;
break;
case BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_GET_MSG:
act = ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_GET_MSG_EVT;
break;
case BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_SET_MSG:
act = ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_SET_MSG_EVT;
break;
case BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_STATUS_MSG:
act = ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_STATUS_MSG_EVT;
break;
default:
LOG_ERROR("%s, Unknown Time Scene Server event type", __func__);
return;
}
cb_params.model = (esp_ble_mesh_model_t *)model;
cb_params.ctx.net_idx = ctx->net_idx;
cb_params.ctx.app_idx = ctx->app_idx;
cb_params.ctx.addr = ctx->addr;
cb_params.ctx.recv_ttl = ctx->recv_ttl;
cb_params.ctx.recv_op = ctx->recv_op;
cb_params.ctx.recv_dst = ctx->recv_dst;
if (val && len) {
length = (len <= sizeof(cb_params.value)) ? len : sizeof(cb_params.value);
memcpy(&cb_params.value, val, length);
}
btc_ble_mesh_time_scene_server_callback(&cb_params, act);
return;
}
void btc_ble_mesh_time_scene_server_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_time_scene_server_cb_param_t *param = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s, Invalid parameter", __func__);
return;
}
param = (esp_ble_mesh_time_scene_server_cb_param_t *)(msg->arg);
if (msg->act < ESP_BLE_MESH_TIME_SCENE_SERVER_EVT_MAX) {
btc_ble_mesh_time_scene_server_cb_to_app(msg->act, param);
} else {
LOG_ERROR("%s, Unknown msg->act = %d", __func__, msg->act);
}
return;
}

View File

@ -63,7 +63,7 @@ void bt_mesh_config_client_cb_evt_to_btc(u32_t opcode, u8_t evt_type,
void btc_ble_mesh_config_server_cb_handler(btc_msg_t *msg);
typedef enum {
BTC_BLE_MESH_EVT_CONFIG_SERVER_RECV_MSG,
BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
BTC_BLE_MESH_EVT_CONFIG_SERVER_MAX,
} btc_ble_mesh_config_server_evt_t;

View File

@ -60,4 +60,18 @@ void bt_mesh_generic_client_cb_evt_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
typedef enum {
BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE,
BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG,
BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG,
BTC_BLE_MESH_EVT_GENERIC_SERVER_MAX,
} btc_ble_mesh_generic_server_evt_t;
void bt_mesh_generic_server_cb_evt_to_btc(u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
void btc_ble_mesh_generic_server_cb_handler(btc_msg_t *msg);
#endif /* _BTC_BLE_MESH_GENERIC_MODEL_H_ */

View File

@ -68,7 +68,7 @@ typedef enum {
typedef union {
struct ble_mesh_health_server_fault_update_args {
esp_ble_mesh_elem_t *element;
} fault_update;
} health_fault_update;
} btc_ble_mesh_health_server_args_t;
void btc_ble_mesh_health_server_call_handler(btc_msg_t *msg);
@ -77,4 +77,12 @@ void btc_ble_mesh_health_server_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_health_server_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_health_server_fault_clear(struct bt_mesh_model *model, u16_t company_id);
void btc_ble_mesh_health_server_fault_test(struct bt_mesh_model *model, u8_t test_id, u16_t company_id);
void btc_ble_mesh_health_server_attention_on(struct bt_mesh_model *model, u8_t time);
void btc_ble_mesh_health_server_attention_off(struct bt_mesh_model *model);
#endif /* _BTC_BLE_MESH_HEALTH_MODEL_H_ */

View File

@ -60,5 +60,20 @@ void bt_mesh_lighting_client_cb_evt_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
typedef enum {
BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG,
BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_STATUS_MSG,
BTC_BLE_MESH_EVT_LIGHTING_SERVER_MAX,
} btc_ble_mesh_lighting_server_evt_t;
void bt_mesh_lighting_server_cb_evt_to_btc(u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
void btc_ble_mesh_lighting_server_cb_handler(btc_msg_t *msg);
#endif /* _BTC_BLE_MESH_LIGHTING_MODEL_H_ */

View File

@ -55,12 +55,21 @@ typedef enum {
BTC_BLE_MESH_ACT_PROVISIONER_ADD_LOCAL_NET_KEY,
BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO,
BTC_BLE_MESH_ACT_SET_FAST_PROV_ACTION,
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 {
BTC_BLE_MESH_ACT_MODEL_PUBLISH,
BTC_BLE_MESH_ACT_SERVER_MODEL_SEND,
BTC_BLE_MESH_ACT_CLIENT_MODEL_SEND,
BTC_BLE_MESH_ACT_SERVER_MODEL_UPDATE_STATE,
} btc_ble_mesh_model_act_t;
typedef union {
@ -156,6 +165,40 @@ typedef union {
struct ble_mesh_set_fast_prov_action_args {
uint8_t action;
} set_fast_prov_action;
struct ble_mesh_lpn_enable_args {
/* RFU */
} lpn_enable;
struct ble_mesh_lpn_disable_args {
bool force;
} lpn_disable;
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 {
@ -173,10 +216,17 @@ typedef union {
uint8_t device_role;
int32_t msg_timeout;
} model_send;
struct ble_mesh_server_model_update_state_args {
esp_ble_mesh_model_t *model;
esp_ble_mesh_server_state_type_t type;
esp_ble_mesh_server_state_value_t *value;
} model_update_state;
} btc_ble_mesh_model_args_t;
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

@ -60,5 +60,19 @@ void bt_mesh_sensor_client_cb_evt_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
typedef enum {
BTC_BLE_MESH_EVT_SENSOR_SERVER_STATE_CHANGE,
BTC_BLE_MESH_EVT_SENSOR_SERVER_RECV_GET_MSG,
BTC_BLE_MESH_EVT_SENSOR_SERVER_RECV_SET_MSG,
BTC_BLE_MESH_EVT_SENSOR_SERVER_MAX,
} btc_ble_mesh_sensor_server_evt_t;
void bt_mesh_sensor_server_cb_evt_to_btc(u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
void btc_ble_mesh_sensor_server_cb_handler(btc_msg_t *msg);
#endif /* _BTC_BLE_MESH_SENSOR_MODEL_H_ */

View File

@ -60,5 +60,20 @@ void bt_mesh_time_scene_client_cb_evt_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
typedef enum {
BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_STATE_CHANGE,
BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_GET_MSG,
BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_SET_MSG,
BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_STATUS_MSG,
BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_MAX,
} btc_ble_mesh_time_scene_server_evt_t;
void bt_mesh_time_scene_server_cb_evt_to_btc(u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
void btc_ble_mesh_time_scene_server_cb_handler(btc_msg_t *msg);
#endif /* _BTC_BLE_MESH_TIME_SCENE_MODEL_H_ */

View File

@ -182,6 +182,8 @@ struct k_delayed_work {
*/
int k_delayed_work_submit(struct k_delayed_work *work, s32_t delay);
int k_delayed_work_submit_periodic(struct k_delayed_work *work, s32_t period);
/**
* @brief Get time remaining before a delayed work gets scheduled.
*

View File

@ -39,25 +39,16 @@ typedef struct alarm_t {
unsigned int bt_mesh_irq_lock(void)
{
#if defined(CONFIG_BLE_MESH_IRQ_LOCK) && CONFIG_BLE_MESH_IRQ_LOCK
unsigned int key = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL);
return key;
#else
/* Change by Espressif. In BLE Mesh, in order to improve the real-time
* requirements of bt controller, we use task lock to replace IRQ lock.
/* Changed by Espressif. In BLE Mesh, in order to improve the real-time
* requirements of bt controller, we use task lock instead of IRQ lock.
*/
osi_mutex_lock(&bm_irq_lock, OSI_MUTEX_MAX_TIMEOUT);
return 0;
#endif
}
void bt_mesh_irq_unlock(unsigned int key)
{
#if defined(CONFIG_BLE_MESH_IRQ_LOCK) && CONFIG_BLE_MESH_IRQ_LOCK
XTOS_RESTORE_INTLEVEL(key);
#else
osi_mutex_unlock(&bm_irq_lock);
#endif
}
s64_t k_uptime_get(void)
@ -124,8 +115,7 @@ void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler)
return;
}
int k_delayed_work_submit(struct k_delayed_work *work,
s32_t delay)
int k_delayed_work_submit(struct k_delayed_work *work, s32_t delay)
{
assert(work != NULL && bm_alarm_hash_map != NULL);
@ -141,6 +131,23 @@ int k_delayed_work_submit(struct k_delayed_work *work,
return 0;
}
int k_delayed_work_submit_periodic(struct k_delayed_work *work, s32_t period)
{
assert(work != NULL && bm_alarm_hash_map != NULL);
osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
if (alarm == NULL) {
BT_WARN("%s, Unable to find expected alarm in hash map", __func__);
return -EINVAL;
}
/* Cancel the alarm first before starting it. */
osi_alarm_cancel(alarm);
osi_alarm_set_periodic(alarm, period);
return 0;
}
int k_delayed_work_cancel(struct k_delayed_work *work)
{
assert(work != NULL && bm_alarm_hash_map != NULL);

View File

@ -27,13 +27,18 @@
#include "transport.h"
#include "access.h"
#include "foundation.h"
#include "mesh_common.h"
#include "provisioner_main.h"
#include "generic_client.h"
#include "sensor_client.h"
#include "time_scene_client.h"
#include "lighting_client.h"
#include "provisioner_main.h"
#include "generic_server.h"
#include "sensor_server.h"
#include "time_scene_server.h"
#include "lighting_server.h"
#define BLE_MESH_SDU_MAX_LEN 384
@ -103,6 +108,41 @@ static const struct {
#if defined(CONFIG_BLE_MESH_LIGHT_LC_CLI)
{ BLE_MESH_MODEL_ID_LIGHT_LC_CLI, bt_mesh_light_lc_cli_init },
#endif
{ BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, bt_mesh_gen_onoff_srv_init },
{ BLE_MESH_MODEL_ID_GEN_LEVEL_SRV, bt_mesh_gen_level_srv_init },
{ BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV, bt_mesh_gen_def_trans_time_srv_init },
{ BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV, bt_mesh_gen_power_onoff_srv_init },
{ BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV, bt_mesh_gen_power_onoff_setup_srv_init },
{ BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV, bt_mesh_gen_power_level_srv_init },
{ BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV, bt_mesh_gen_power_level_setup_srv_init },
{ BLE_MESH_MODEL_ID_GEN_BATTERY_SRV, bt_mesh_gen_battery_srv_init },
{ BLE_MESH_MODEL_ID_GEN_LOCATION_SRV, bt_mesh_gen_location_srv_init },
{ BLE_MESH_MODEL_ID_GEN_LOCATION_SETUP_SRV, bt_mesh_gen_location_setup_srv_init },
{ BLE_MESH_MODEL_ID_GEN_USER_PROP_SRV, bt_mesh_gen_user_prop_srv_init },
{ BLE_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV, bt_mesh_gen_admin_prop_srv_init },
{ BLE_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV, bt_mesh_gen_manu_prop_srv_init },
{ BLE_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV, bt_mesh_gen_client_prop_srv_init },
{ BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV, bt_mesh_light_lightness_srv_init },
{ BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV, bt_mesh_light_lightness_setup_srv_init },
{ BLE_MESH_MODEL_ID_LIGHT_CTL_SRV, bt_mesh_light_ctl_srv_init },
{ BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV, bt_mesh_light_ctl_setup_srv_init },
{ BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV, bt_mesh_light_ctl_temp_srv_init },
{ BLE_MESH_MODEL_ID_LIGHT_HSL_SRV, bt_mesh_light_hsl_srv_init },
{ BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV, bt_mesh_light_hsl_hue_srv_init },
{ BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV, bt_mesh_light_hsl_sat_srv_init },
{ BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV, bt_mesh_light_hsl_setup_srv_init },
{ BLE_MESH_MODEL_ID_LIGHT_XYL_SRV, bt_mesh_light_xyl_srv_init },
{ BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV, bt_mesh_light_xyl_setup_srv_init },
{ BLE_MESH_MODEL_ID_LIGHT_LC_SRV, bt_mesh_light_lc_srv_init },
{ BLE_MESH_MODEL_ID_LIGHT_LC_SETUP_SRV, bt_mesh_light_lc_setup_srv_init },
{ BLE_MESH_MODEL_ID_TIME_SRV, bt_mesh_time_srv_init },
{ BLE_MESH_MODEL_ID_TIME_SETUP_SRV, bt_mesh_time_setup_srv_init },
{ BLE_MESH_MODEL_ID_SCENE_SRV, bt_mesh_scene_srv_init },
{ BLE_MESH_MODEL_ID_SCENE_SETUP_SRV, bt_mesh_scene_setup_srv_init },
{ BLE_MESH_MODEL_ID_SCHEDULER_SRV, bt_mesh_scheduler_srv_init },
{ BLE_MESH_MODEL_ID_SCHEDULER_SETUP_SRV, bt_mesh_scheduler_setup_srv_init },
{ BLE_MESH_MODEL_ID_SENSOR_SRV, bt_mesh_sensor_srv_init },
{ BLE_MESH_MODEL_ID_SENSOR_SETUP_SRV, bt_mesh_sensor_setup_srv_init },
};
void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *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 */
@ -55,7 +55,6 @@
#define ADV_STACK_SIZE 768
#endif
static xQueueHandle xBleMeshQueue;
static const bt_mesh_addr_t *dev_addr;
static const u8_t adv_type[] = {
@ -70,6 +69,27 @@ NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BLE_MESH_ADV_BUF_COUNT + 3 * CONFIG_BLE
static struct bt_mesh_adv adv_pool[CONFIG_BLE_MESH_ADV_BUF_COUNT + 3 * CONFIG_BLE_MESH_PBA_SAME_TIME];
static QueueHandle_t xBleMeshQueue;
#define BLE_MESH_QUEUE_SIZE 150
#if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
NET_BUF_POOL_DEFINE(relay_adv_buf_pool, CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT,
BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
static struct bt_mesh_adv relay_adv_pool[CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT];
static QueueHandle_t xBleMeshRelayQueue;
#define BLE_MESH_RELAY_QUEUE_SIZE 150
static QueueSetHandle_t xBleMeshQueueSet;
#define BLE_MESH_QUEUE_SET_SIZE (BLE_MESH_QUEUE_SIZE + BLE_MESH_RELAY_QUEUE_SIZE)
#define BLE_MESH_RELAY_TIME_INTERVAL K_SECONDS(6)
#define BLE_MESH_MAX_TIME_INTERVAL 0xFFFFFFFF
static bool ignore_relay_packet(u32_t timestamp);
#endif /* defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
static struct bt_mesh_adv *adv_alloc(int id)
{
return &adv_pool[id];
@ -147,48 +167,111 @@ static inline int adv_send(struct net_buf *buf)
static void adv_thread(void *p)
{
struct net_buf **buf = NULL;
#if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
QueueSetMemberHandle_t handle;
#endif
bt_mesh_msg_t msg = {0};
int status;
BT_DBG("started");
struct net_buf **buf;
buf = (struct net_buf **)(&msg.arg);
BT_DBG("%s, starts", __func__);
while (1) {
*buf = NULL;
#if !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
#if CONFIG_BLE_MESH_NODE
if (IS_ENABLED(CONFIG_BLE_MESH_PROXY)) {
xQueueReceive(xBleMeshQueue, &msg, K_NO_WAIT);
while (!(*buf)) {
s32_t timeout;
BT_DBG("Proxy advertising start");
BT_DBG("Mesh Proxy Advertising start");
timeout = bt_mesh_proxy_adv_start();
BT_DBG("Proxy Advertising up to %d ms", timeout);
BT_DBG("Mesh Proxy Advertising up to %d ms", timeout);
xQueueReceive(xBleMeshQueue, &msg, timeout);
BT_DBG("Proxy advertising stop");
BT_DBG("Mesh Proxy Advertising stop");
bt_mesh_proxy_adv_stop();
}
} else {
xQueueReceive(xBleMeshQueue, &msg, (portTickType)portMAX_DELAY);
xQueueReceive(xBleMeshQueue, &msg, portMAX_DELAY);
}
#else
xQueueReceive(xBleMeshQueue, &msg, (portTickType)portMAX_DELAY);
xQueueReceive(xBleMeshQueue, &msg, portMAX_DELAY);
#endif
#else /* !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
#if CONFIG_BLE_MESH_NODE
if (IS_ENABLED(CONFIG_BLE_MESH_PROXY)) {
handle = xQueueSelectFromSet(xBleMeshQueueSet, K_NO_WAIT);
if (handle) {
if (uxQueueMessagesWaiting(xBleMeshQueue)) {
xQueueReceive(xBleMeshQueue, &msg, K_NO_WAIT);
} else if (uxQueueMessagesWaiting(xBleMeshRelayQueue)) {
xQueueReceive(xBleMeshRelayQueue, &msg, K_NO_WAIT);
}
} else {
while (!(*buf)) {
s32_t timeout;
BT_DBG("Mesh Proxy Advertising start");
timeout = bt_mesh_proxy_adv_start();
BT_DBG("Mesh Proxy Advertising up to %d ms", timeout);
handle = xQueueSelectFromSet(xBleMeshQueueSet, timeout);
BT_DBG("Mesh Proxy Advertising stop");
bt_mesh_proxy_adv_stop();
if (handle) {
if (uxQueueMessagesWaiting(xBleMeshQueue)) {
xQueueReceive(xBleMeshQueue, &msg, K_NO_WAIT);
} else if (uxQueueMessagesWaiting(xBleMeshRelayQueue)) {
xQueueReceive(xBleMeshRelayQueue, &msg, K_NO_WAIT);
}
}
}
}
} else {
handle = xQueueSelectFromSet(xBleMeshQueueSet, portMAX_DELAY);
if (handle) {
if (uxQueueMessagesWaiting(xBleMeshQueue)) {
xQueueReceive(xBleMeshQueue, &msg, K_NO_WAIT);
} else if (uxQueueMessagesWaiting(xBleMeshRelayQueue)) {
xQueueReceive(xBleMeshRelayQueue, &msg, K_NO_WAIT);
}
}
}
#else
handle = xQueueSelectFromSet(xBleMeshQueueSet, portMAX_DELAY);
if (handle) {
if (uxQueueMessagesWaiting(xBleMeshQueue)) {
xQueueReceive(xBleMeshQueue, &msg, K_NO_WAIT);
} else if (uxQueueMessagesWaiting(xBleMeshRelayQueue)) {
xQueueReceive(xBleMeshRelayQueue, &msg, K_NO_WAIT);
}
}
#endif
#endif /* !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
if (!(*buf)) {
if (*buf == NULL) {
continue;
}
/* busy == 0 means this was canceled */
if (BLE_MESH_ADV(*buf)->busy) {
BLE_MESH_ADV(*buf)->busy = 0U;
status = adv_send(*buf);
if (status) {
if (xQueueSendToFront(xBleMeshQueue, &msg, K_NO_WAIT) != pdTRUE) {
BT_ERR("%s, xQueueSendToFront failed", __func__);
#if !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
if (adv_send(*buf)) {
BT_WARN("%s, Failed to send adv packet", __func__);
}
#else /* !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
if (msg.relay && ignore_relay_packet(msg.timestamp)) {
/* If the interval between "current time - msg.timestamp" is bigger than
* BLE_MESH_RELAY_TIME_INTERVAL, this relay packet will not be sent.
*/
BT_DBG("%s, Ignore relay packet", __func__);
net_buf_unref(*buf);
} else {
if (adv_send(*buf)) {
BT_WARN("%s, Failed to send adv packet", __func__);
}
}
#endif
} else {
net_buf_unref(*buf);
}
@ -198,13 +281,6 @@ static void adv_thread(void *p)
}
}
void bt_mesh_adv_update(void)
{
BT_DBG("%s", __func__);
bt_mesh_msg_t msg = {0};
bt_mesh_task_post(&msg, 0);
}
struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *pool,
bt_mesh_adv_alloc_t get_id,
enum bt_mesh_adv_type type,
@ -244,17 +320,35 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit,
xmit, timeout);
}
void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout)
static void bt_mesh_unref_buf(bt_mesh_msg_t *msg)
{
struct net_buf *buf;
if (msg->arg) {
buf = (struct net_buf *)msg->arg;
BLE_MESH_ADV(buf)->busy = 0U;
net_buf_unref(buf);
}
return;
}
static void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout)
{
BT_DBG("%s", __func__);
if (xQueueSend(xBleMeshQueue, msg, timeout) != pdTRUE) {
BT_ERR("%s, Failed to post msg to queue", __func__);
BT_ERR("%s, Failed to send item to queue", __func__);
bt_mesh_unref_buf(msg);
}
}
void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
void *cb_data)
{
bt_mesh_msg_t msg = {
.relay = false,
};
BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, buf->len,
bt_hex(buf->data, buf->len));
@ -262,21 +356,228 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
BLE_MESH_ADV(buf)->cb_data = cb_data;
BLE_MESH_ADV(buf)->busy = 1U;
bt_mesh_msg_t msg = {0};
msg.arg = (void *)net_buf_ref(buf);
bt_mesh_task_post(&msg, portMAX_DELAY);
}
void bt_mesh_adv_update(void)
{
bt_mesh_msg_t msg = {
.relay = false,
.arg = NULL,
};
BT_DBG("%s", __func__);
bt_mesh_task_post(&msg, K_NO_WAIT);
}
#if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
static bool ignore_relay_packet(u32_t timestamp)
{
u32_t now = k_uptime_get_32();
u32_t interval;
if (now > timestamp) {
interval = now - timestamp;
} else if (now == timestamp) {
interval = BLE_MESH_MAX_TIME_INTERVAL;
} else {
interval = BLE_MESH_MAX_TIME_INTERVAL - (timestamp - now) + 1;
}
return (interval >= BLE_MESH_RELAY_TIME_INTERVAL) ? true : false;
}
static struct bt_mesh_adv *relay_adv_alloc(int id)
{
return &relay_adv_pool[id];
}
struct net_buf *bt_mesh_relay_adv_create(enum bt_mesh_adv_type type, u8_t xmit,
s32_t timeout)
{
return bt_mesh_adv_create_from_pool(&relay_adv_buf_pool, relay_adv_alloc, type,
xmit, timeout);
}
static void ble_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout)
{
QueueSetMemberHandle_t handle;
bt_mesh_msg_t old_msg = {0};
BT_DBG("%s", __func__);
if (xQueueSend(xBleMeshRelayQueue, msg, timeout) == pdTRUE) {
return;
}
/**
* If failed to send packet to the relay queue(queue is full), we will
* remove the oldest packet in the queue and put the new one into it.
*/
handle = xQueueSelectFromSet(xBleMeshQueueSet, K_NO_WAIT);
if (handle && uxQueueMessagesWaiting(xBleMeshRelayQueue)) {
BT_DBG("%s, Full queue, remove the oldest relay packet", __func__);
/* Remove the oldest relay packet from queue */
if (xQueueReceive(xBleMeshRelayQueue, &old_msg, K_NO_WAIT) != pdTRUE) {
BT_ERR("%s, Failed to remove item from queue", __func__);
bt_mesh_unref_buf(msg);
return;
}
/* Unref buf used for the oldest relay packet */
bt_mesh_unref_buf(&old_msg);
/* Send the latest relay packet to queue */
if (xQueueSend(xBleMeshRelayQueue, msg, K_NO_WAIT) != pdTRUE) {
BT_ERR("%s, Failed to send item to relay queue", __func__);
bt_mesh_unref_buf(msg);
return;
}
} else {
BT_WARN("%s, Empty queue, but failed to send the relay packet", __func__);
bt_mesh_unref_buf(msg);
}
}
void bt_mesh_relay_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
void *cb_data, u16_t src, u16_t dst)
{
bt_mesh_msg_t msg = {
.relay = true,
};
BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, buf->len,
bt_hex(buf->data, buf->len));
BLE_MESH_ADV(buf)->cb = cb;
BLE_MESH_ADV(buf)->cb_data = cb_data;
BLE_MESH_ADV(buf)->busy = 1U;
msg.arg = (void *)net_buf_ref(buf);
msg.src = src;
msg.dst = dst;
msg.timestamp = k_uptime_get_32();
/* Use K_NO_WAIT here, if xBleMeshRelayQueue is full return immediately */
ble_mesh_relay_task_post(&msg, K_NO_WAIT);
}
u16_t bt_mesh_get_stored_relay_count(void)
{
return (u16_t)uxQueueMessagesWaiting(xBleMeshRelayQueue);
}
#endif /* #if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
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) {
@ -348,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");
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");
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;
}
@ -385,8 +680,16 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi,
void bt_mesh_adv_init(void)
{
xBleMeshQueue = xQueueCreate(150, sizeof(bt_mesh_msg_t));
xBleMeshQueue = xQueueCreate(BLE_MESH_QUEUE_SIZE, sizeof(bt_mesh_msg_t));
configASSERT(xBleMeshQueue);
#if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
xBleMeshRelayQueue = xQueueCreate(BLE_MESH_RELAY_QUEUE_SIZE, sizeof(bt_mesh_msg_t));
configASSERT(xBleMeshRelayQueue);
xBleMeshQueueSet = xQueueCreateSet(BLE_MESH_QUEUE_SET_SIZE);
configASSERT(xBleMeshQueueSet);
xQueueAddToSet(xBleMeshQueue, xBleMeshQueueSet);
xQueueAddToSet(xBleMeshRelayQueue, xBleMeshQueueSet);
#endif /* defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
int ret = xTaskCreatePinnedToCore(adv_thread, "BLE_Mesh_ADV_Task", 3072, NULL,
configMAX_PRIORITIES - 7, NULL, ADV_TASK_CORE);
configASSERT(ret == pdTRUE);

View File

@ -21,11 +21,11 @@
#define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf))
typedef struct bt_mesh_msg {
uint8_t sig; //event signal
uint8_t aid; //application id
uint8_t pid; //profile id
uint8_t act; //profile action, defined in seprerate header files
void *arg; //param for btc function or function param
bool relay; /* Flag indicates if the packet is a relayed one */
void *arg; /* Pointer to the struct net_buf */
u16_t src; /* Source address for relay packets */
u16_t dst; /* Destination address for relay packets */
u32_t timestamp; /* Timestamp recorded when the relay packet is posted to queue */
} bt_mesh_msg_t;
enum bt_mesh_adv_type {
@ -73,6 +73,14 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
const bt_mesh_addr_t *bt_mesh_pba_get_addr(void);
struct net_buf *bt_mesh_relay_adv_create(enum bt_mesh_adv_type type, u8_t xmit,
s32_t timeout);
void bt_mesh_relay_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
void *cb_data, u16_t src, u16_t dst);
u16_t bt_mesh_get_stored_relay_count(void);
void bt_mesh_adv_update(void);
void bt_mesh_adv_init(void);
@ -81,6 +89,4 @@ int bt_mesh_scan_enable(void);
int bt_mesh_scan_disable(void);
void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout);
#endif /* _ADV_H_ */

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,28 +1013,41 @@ 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;
}
u8_t bt_mesh_gattc_get_free_conn_count(void)
{
u8_t count = 0;
u8_t i;
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;
}
}
return count;
}
u16_t bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn *conn)
{
int i;
u8_t i;
for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
for (i = 0U; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
if (conn == &bt_mesh_gattc_info[i].conn) {
break;
}
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
return 0;
}
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
* listed below.
@ -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,25 +1159,17 @@ 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;
}
}
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;
}
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
BT_ERR("%s, Conn is not found", __func__);
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;
}
}
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,24 +1233,15 @@ 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;
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);
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;
}
}
}
break;
@ -1264,16 +1253,13 @@ 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 &&
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;
}
break;
}
}
break;
}
@ -1285,17 +1271,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].start_handle == 0x00 ||
bt_mesh_gattc_info[i].end_handle == 0x00 ||
(bt_mesh_gattc_info[i].start_handle > bt_mesh_gattc_info[i].end_handle)) {
@ -1303,19 +1288,18 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
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) {
break;
}
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
BT_ERR("%s, Conn handle is not found", __func__);
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 (memcmp(bt_mesh_gattc_info[i].addr, p_data->notify.bda, BLE_MESH_ADDR_LEN) ||
if (conn == NULL) {
BT_ERR("%s, Conn handle is not found", __func__);
return;
}
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);
}
/* Decrease prov pbg_count */
#endif
}
#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;
}
@ -472,10 +472,14 @@ static void app_key_add(struct bt_mesh_model *model,
return;
}
#if defined(CONFIG_BLE_MESH_FAST_PROV)
bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_RECV_MSG,
model, ctx, (u8_t *)&key_app_idx, sizeof(u16_t));
#endif
if (status == STATUS_SUCCESS) {
bt_mesh_cfg_server_state_change_t change = {0};
change.cfg_appkey_add.net_idx = key_net_idx;
change.cfg_appkey_add.app_idx = key_app_idx;
memcpy(change.cfg_appkey_add.app_key, buf->data, 16);
bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
model, ctx, (const u8_t *)&change, sizeof(change));
}
}
static void app_key_update(struct bt_mesh_model *model,
@ -501,6 +505,15 @@ static void app_key_update(struct bt_mesh_model *model,
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
BT_ERR("%s, Unable to send Config AppKey Status", __func__);
}
if (status == STATUS_SUCCESS) {
bt_mesh_cfg_server_state_change_t change = {0};
change.cfg_appkey_update.net_idx = key_net_idx;
change.cfg_appkey_update.app_idx = key_app_idx;
memcpy(change.cfg_appkey_update.app_key, buf->data, 16);
bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
model, ctx, (const u8_t *)&change, sizeof(change));
}
}
struct unbind_data {
@ -577,6 +590,14 @@ send_status:
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
BT_ERR("%s, Unable to send Config AppKey Status", __func__);
}
if (status == STATUS_SUCCESS) {
bt_mesh_cfg_server_state_change_t change = {0};
change.cfg_appkey_delete.net_idx = key_net_idx;
change.cfg_appkey_delete.app_idx = key_app_idx;
bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
model, ctx, (const u8_t *)&change, sizeof(change));
}
}
/* Index list length: 3 bytes for every pair and 2 bytes for an odd idx */
@ -797,7 +818,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;
}
@ -1124,6 +1145,21 @@ static void mod_pub_set(struct bt_mesh_model *model,
send_status:
send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
status, mod_id);
if (status == STATUS_SUCCESS && mod->pub) {
bt_mesh_cfg_server_state_change_t change = {0};
change.cfg_mod_pub_set.elem_addr = elem_addr;
change.cfg_mod_pub_set.pub_addr = mod->pub->addr;
change.cfg_mod_pub_set.app_idx = mod->pub->key;
change.cfg_mod_pub_set.cred_flag = mod->pub->cred;
change.cfg_mod_pub_set.ttl = mod->pub->ttl;
change.cfg_mod_pub_set.period = mod->pub->period;
change.cfg_mod_pub_set.transmit = mod->pub->retransmit;
change.cfg_mod_pub_set.cid = vnd ? mod->vnd.company : 0xFFFF;
change.cfg_mod_pub_set.mod_id = vnd ? mod->vnd.id : mod->id;
bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
model, ctx, (const u8_t *)&change, sizeof(change));
}
}
#if CONFIG_BLE_MESH_LABEL_COUNT > 0
@ -1447,6 +1483,16 @@ static void mod_sub_add(struct bt_mesh_model *model,
send_status:
send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
mod_id, vnd);
if (status == STATUS_SUCCESS) {
bt_mesh_cfg_server_state_change_t change = {0};
change.cfg_mod_sub_add.elem_addr = elem_addr;
change.cfg_mod_sub_add.sub_addr = sub_addr;
change.cfg_mod_sub_add.cid = vnd ? mod->vnd.company : 0xFFFF;
change.cfg_mod_sub_add.mod_id = vnd ? mod->vnd.id : mod->id;
bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
model, ctx, (const u8_t *)&change, sizeof(change));
}
}
static void mod_sub_del(struct bt_mesh_model *model,
@ -1513,6 +1559,16 @@ static void mod_sub_del(struct bt_mesh_model *model,
send_status:
send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
mod_id, vnd);
if (status == STATUS_SUCCESS) {
bt_mesh_cfg_server_state_change_t change = {0};
change.cfg_mod_sub_delete.elem_addr = elem_addr;
change.cfg_mod_sub_delete.sub_addr = sub_addr;
change.cfg_mod_sub_delete.cid = vnd ? mod->vnd.company : 0xFFFF;
change.cfg_mod_sub_delete.mod_id = vnd ? mod->vnd.id : mod->id;
bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
model, ctx, (const u8_t *)&change, sizeof(change));
}
}
static void mod_sub_overwrite(struct bt_mesh_model *model,
@ -2166,7 +2222,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);
@ -2177,6 +2233,12 @@ static void net_key_add(struct bt_mesh_model *model,
}
send_net_key_status(model, ctx, idx, STATUS_SUCCESS);
bt_mesh_cfg_server_state_change_t change = {0};
change.cfg_netkey_add.net_idx = sub->net_idx;
memcpy(change.cfg_netkey_add.net_key, sub->keys[0].net, 16);
bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
model, ctx, (const u8_t *)&change, sizeof(change));
}
static void net_key_update(struct bt_mesh_model *model,
@ -2246,6 +2308,12 @@ static void net_key_update(struct bt_mesh_model *model,
bt_mesh_net_beacon_update(sub);
send_net_key_status(model, ctx, idx, STATUS_SUCCESS);
bt_mesh_cfg_server_state_change_t change = {0};
change.cfg_netkey_update.net_idx = sub->net_idx;
memcpy(change.cfg_netkey_update.net_key, sub->keys[1].net, 16);
bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
model, ctx, (const u8_t *)&change, sizeof(change));
}
static void hb_pub_disable(struct bt_mesh_cfg_srv *cfg)
@ -2298,6 +2366,13 @@ static void net_key_del(struct bt_mesh_model *model,
send_status:
send_net_key_status(model, ctx, del_idx, status);
if (status == STATUS_SUCCESS) {
bt_mesh_cfg_server_state_change_t change = {0};
change.cfg_netkey_delete.net_idx = sub->net_idx;
bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
model, ctx, (const u8_t *)&change, sizeof(change));
}
}
static void net_key_get(struct bt_mesh_model *model,
@ -2416,7 +2491,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);
@ -2503,6 +2578,16 @@ send_status:
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
BT_ERR("%s, Unable to send Config Model App Bind Status", __func__);
}
if (status == STATUS_SUCCESS) {
bt_mesh_cfg_server_state_change_t change = {0};
change.cfg_mod_app_bind.elem_addr = elem_addr;
change.cfg_mod_app_bind.app_idx = key_app_idx;
change.cfg_mod_app_bind.cid = vnd ? mod->vnd.company : 0xFFFF;
change.cfg_mod_app_bind.mod_id = vnd ? mod->vnd.id : mod->id;
bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
model, ctx, (const u8_t *)&change, sizeof(change));
}
}
static void mod_app_unbind(struct bt_mesh_model *model,
@ -2549,6 +2634,16 @@ send_status:
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
BT_ERR("%s, Unable to send Config Model App Unbind Status", __func__);
}
if (status == STATUS_SUCCESS) {
bt_mesh_cfg_server_state_change_t change = {0};
change.cfg_mod_app_unbind.elem_addr = elem_addr;
change.cfg_mod_app_unbind.app_idx = key_app_idx;
change.cfg_mod_app_unbind.cid = vnd ? mod->vnd.company : 0xFFFF;
change.cfg_mod_app_unbind.mod_id = vnd ? mod->vnd.id : mod->id;
bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
model, ctx, (const u8_t *)&change, sizeof(change));
}
}
#define KEY_LIST_LEN (CONFIG_BLE_MESH_MODEL_KEY_COUNT * 2)
@ -2857,6 +2952,12 @@ static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
}
send_krp_status(model, ctx, idx, sub->kr_phase, STATUS_SUCCESS);
bt_mesh_cfg_server_state_change_t change = {0};
change.cfg_kr_phase_set.net_idx = idx;
change.cfg_kr_phase_set.kr_phase = phase;
bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
model, ctx, (const u8_t *)&change, sizeof(change));
}
static u8_t hb_log(u16_t val)
@ -3295,7 +3396,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

@ -65,6 +65,18 @@ static struct friend_adv {
u64_t seq_auth;
} adv_pool[FRIEND_BUF_COUNT];
enum {
BLE_MESH_FRIENDSHIP_TERMINATE_ESTABLISH_FAIL,
BLE_MESH_FRIENDSHIP_TERMINATE_POLL_TIMEOUT,
BLE_MESH_FRIENDSHIP_TERMINATE_RECV_FRND_REQ,
BLE_MESH_FRIENDSHIP_TERMINATE_RECV_FRND_CLEAR,
BLE_MESH_FRIENDSHIP_TERMINATE_DISABLE,
};
static void (*friend_cb)(bool establish, u16_t lpn_addr, u8_t reason);
static struct bt_mesh_adv *adv_alloc(int id)
{
return &adv_pool[id].adv;
@ -137,7 +149,7 @@ static s32_t recv_delay(struct bt_mesh_friend *frnd)
#endif
}
static void friend_clear(struct bt_mesh_friend *frnd)
static void friend_clear(struct bt_mesh_friend *frnd, u8_t reason)
{
int i;
@ -145,6 +157,12 @@ static void friend_clear(struct bt_mesh_friend *frnd)
k_delayed_work_cancel(&frnd->timer);
if (frnd->established) {
if (friend_cb) {
friend_cb(false, frnd->lpn, reason);
}
}
friend_cred_del(frnd->net_idx, frnd->lpn);
if (frnd->last) {
@ -189,7 +207,7 @@ void bt_mesh_friend_clear_net_idx(u16_t net_idx)
}
if (net_idx == BLE_MESH_KEY_ANY || frnd->net_idx == net_idx) {
friend_clear(frnd);
friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_DISABLE);
}
}
}
@ -262,7 +280,7 @@ int bt_mesh_friend_clear(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR_CFM, &cfm,
sizeof(cfm), NULL, NULL, NULL);
friend_clear(frnd);
friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_RECV_FRND_CLEAR);
return 0;
}
@ -568,6 +586,9 @@ int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
if (!frnd->established) {
BT_DBG("Friendship established with 0x%04x", frnd->lpn);
frnd->established = 1U;
if (friend_cb) {
friend_cb(true, frnd->lpn, 0);
}
}
if (msg->fsn == frnd->fsn && frnd->last) {
@ -828,7 +849,7 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
frnd = bt_mesh_friend_find(rx->sub->net_idx, rx->ctx.addr, true, false);
if (frnd) {
BT_WARN("%s, Existing LPN re-requesting Friendship", __func__);
friend_clear(frnd);
friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_RECV_FRND_REQ);
goto init_friend;
}
@ -857,6 +878,13 @@ init_friend:
BT_DBG("LPN 0x%04x rssi %d recv_delay %u poll_to %ums",
frnd->lpn, rx->rssi, frnd->recv_delay, frnd->poll_to);
/**
* Spec says:
* After a friendship has been established, if the PreviousAddress field
* of the Friend Request message contains a valid unicast address that is
* not the Friend nodes own unicast address, then the Friend node shall
* begin sending Friend Clear messages to that unicast address.
*/
if (BLE_MESH_ADDR_IS_UNICAST(frnd->clear.frnd) &&
!bt_mesh_elem_find(frnd->clear.frnd)) {
clear_procedure_start(frnd);
@ -1010,14 +1038,14 @@ static void friend_timeout(struct k_work *work)
if (frnd->established && !frnd->pending_req) {
BT_WARN("%s, Friendship lost with 0x%04x", __func__, frnd->lpn);
friend_clear(frnd);
friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_POLL_TIMEOUT);
return;
}
frnd->last = (void *)sys_slist_get(&frnd->queue);
if (!frnd->last) {
BT_WARN("%s, Friendship not established with 0x%04x", __func__, frnd->lpn);
friend_clear(frnd);
friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_ESTABLISH_FAIL);
return;
}
@ -1035,6 +1063,11 @@ send_last:
bt_mesh_adv_send(frnd->last, &buf_sent_cb, frnd);
}
void bt_mesh_friend_set_cb(void (*cb)(bool establish, u16_t lpn_addr, u8_t reason))
{
friend_cb = cb;
}
int bt_mesh_friend_init(void)
{
int i;

View File

@ -27,130 +27,112 @@
#include "foundation.h"
#include "mesh_common.h"
#include "btc_ble_mesh_health_model.h"
#define HEALTH_TEST_STANDARD 0x00
/* Maximum message length is 384 in BLE Mesh. Here for health fault status,
* due to 1 octet opcode and 4 octets TransMIC, 379 octets can be used to
* store health fault status.
*/
#define HEALTH_FAULT_MAX_LEN 379
#define HEALTH_NO_FAULT 0x00
/* Health Server context of the primary element */
struct bt_mesh_health_srv *health_srv;
static void health_get_registered(struct bt_mesh_model *mod,
u16_t company_id,
struct net_buf_simple *msg)
/**
* When an Element receives a Health Fault Get, or a Health Fault Test, or
* a Health Fault Test Unacknowledged, or a Health Fault Clear, or a Health
* Fault Clear Unacknowledged message that is not successfully processed
* (i.e. the Company ID field that does not identify any Health Fault state
* present in the node), it shall ignore the message.
* The Health Fault state is identified by Company ID and may be present in
* the node for more than one Company ID.
*/
static u8_t health_get_curr_fault_count(struct bt_mesh_model *model)
{
struct bt_mesh_health_srv *srv = mod->user_data;
u8_t *test_id;
struct bt_mesh_health_srv *srv = model->user_data;
u8_t count = 0;
size_t i;
BT_DBG("Company ID 0x%04x", company_id);
for (i = 0U; i < ARRAY_SIZE(srv->test.curr_faults); i++) {
if (srv->test.curr_faults[i] != HEALTH_NO_FAULT) {
count++;
}
}
if (!srv) {
BT_ERR("%s, No Health Server context provided", __func__);
return count;
}
static void health_get_fault_value(struct bt_mesh_model *model,
struct net_buf_simple *msg,
bool current)
{
struct bt_mesh_health_srv *srv = model->user_data;
size_t array_size;
size_t i;
array_size = current ? ARRAY_SIZE(srv->test.curr_faults) : ARRAY_SIZE(srv->test.reg_faults);
for (i = 0U; i < array_size; i++) {
if (net_buf_simple_tailroom(msg) == 0) {
return;
}
u8_t fault = current ? srv->test.curr_faults[i] : srv->test.reg_faults[i];
if (fault != HEALTH_NO_FAULT) {
net_buf_simple_add_u8(msg, fault);
}
}
}
static bool health_is_test_id_exist(struct bt_mesh_model *model, u8_t test_id)
{
struct bt_mesh_health_srv *srv = model->user_data;
u8_t i;
for (i = 0U; i < srv->test.id_count; i++) {
if (srv->test.test_ids[i] == test_id) {
return true;
}
}
return false;
}
static int health_send_fault_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx)
{
struct bt_mesh_health_srv *srv = model->user_data;
struct net_buf_simple *msg = NULL;
int err;
msg = bt_mesh_alloc_buf(4 + ARRAY_SIZE(srv->test.reg_faults) + 4);
if (!msg) {
BT_ERR("%s, Failed to allocate memory", __func__);
return -ENOMEM;
}
bt_mesh_model_msg_init(msg, OP_HEALTH_FAULT_STATUS);
net_buf_simple_add_u8(msg, srv->test.prev_test_id);
net_buf_simple_add_le16(msg, srv->test.company_id);
if (ctx->recv_op != OP_HEALTH_FAULT_CLEAR) {
/**
* For Health Fault Clear, the FaultArray field in Health Fault Status
* shall be empty.
*/
health_get_fault_value(model, msg, false);
}
test_id = net_buf_simple_add(msg, 1);
net_buf_simple_add_le16(msg, company_id);
if (srv->cb && srv->cb->fault_get_reg) {
u8_t fault_count = net_buf_simple_tailroom(msg) - 4;
int err;
err = srv->cb->fault_get_reg(mod, company_id, test_id,
net_buf_simple_tail(msg),
&fault_count);
err = bt_mesh_model_send(model, ctx, msg, NULL, NULL);
if (err) {
BT_ERR("%s, Failed to get faults (err %d)", __func__, err);
*test_id = HEALTH_TEST_STANDARD;
} else {
net_buf_simple_add(msg, fault_count);
}
} else {
BT_WARN("No callback for getting faults");
*test_id = HEALTH_TEST_STANDARD;
}
BT_ERR("%s, Failed to send Health Fault Status response", __func__);
}
static size_t health_get_current(struct bt_mesh_model *mod,
struct net_buf_simple *msg)
{
struct bt_mesh_health_srv *srv = mod->user_data;
const struct bt_mesh_comp *comp;
u8_t *test_id, *company_ptr;
u16_t company_id;
u8_t fault_count;
int err;
if (!srv) {
BT_ERR("%s, No Health Server context provided", __func__);
return 0;
}
bt_mesh_model_msg_init(msg, OP_HEALTH_CURRENT_STATUS);
test_id = net_buf_simple_add(msg, 1);
company_ptr = net_buf_simple_add(msg, sizeof(company_id));
comp = bt_mesh_comp_get();
if (srv->cb && srv->cb->fault_get_cur) {
fault_count = net_buf_simple_tailroom(msg);
err = srv->cb->fault_get_cur(mod, test_id, &company_id,
net_buf_simple_tail(msg),
&fault_count);
if (err) {
BT_ERR("%s, Failed to get faults (err %d)", __func__, err);
sys_put_le16(comp->cid, company_ptr);
*test_id = HEALTH_TEST_STANDARD;
fault_count = 0U;
} else {
sys_put_le16(company_id, company_ptr);
net_buf_simple_add(msg, fault_count);
}
} else {
BT_WARN("No callback for getting faults");
sys_put_le16(comp->cid, company_ptr);
*test_id = HEALTH_TEST_STANDARD;
fault_count = 0U;
}
return fault_count;
bt_mesh_free_buf(msg);
return err;
}
static void health_fault_get(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct net_buf_simple *sdu = NULL;
u16_t company_id;
company_id = net_buf_simple_pull_le16(buf);
BT_DBG("company_id 0x%04x", company_id);
sdu = bt_mesh_alloc_buf(MIN(BLE_MESH_TX_SDU_MAX, HEALTH_FAULT_MAX_LEN));
if (!sdu) {
BT_ERR("%s, Failed to allocate memory", __func__);
return;
}
health_get_registered(model, company_id, sdu);
if (bt_mesh_model_send(model, ctx, sdu, NULL, NULL)) {
BT_ERR("%s, Unable to send Health Current Status", __func__);
}
bt_mesh_free_buf(sdu);
return;
}
static void health_fault_clear_unrel(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_health_srv *srv = model->user_data;
u16_t company_id;
@ -161,12 +143,14 @@ static void health_fault_clear_unrel(struct bt_mesh_model *model,
}
company_id = net_buf_simple_pull_le16(buf);
if (company_id != srv->test.company_id) {
BT_ERR("%s, Unknown Company ID 0x%04x", __func__, company_id);
return;
}
BT_DBG("company_id 0x%04x", company_id);
if (srv->cb && srv->cb->fault_clear) {
srv->cb->fault_clear(model, company_id);
}
health_send_fault_status(model, ctx);
}
static void health_fault_clear(struct bt_mesh_model *model,
@ -174,7 +158,6 @@ static void health_fault_clear(struct bt_mesh_model *model,
struct net_buf_simple *buf)
{
struct bt_mesh_health_srv *srv = model->user_data;
struct net_buf_simple *sdu = NULL;
u16_t company_id;
if (!srv) {
@ -183,49 +166,21 @@ static void health_fault_clear(struct bt_mesh_model *model,
}
company_id = net_buf_simple_pull_le16(buf);
if (company_id != srv->test.company_id) {
BT_ERR("%s, Unknown Company ID 0x%04x", __func__, company_id);
return;
}
BT_DBG("company_id 0x%04x", company_id);
if (srv->cb && srv->cb->fault_clear) {
srv->cb->fault_clear(model, company_id);
memset(srv->test.reg_faults, HEALTH_NO_FAULT, ARRAY_SIZE(srv->test.reg_faults));
if (srv->cb.fault_clear) {
srv->cb.fault_clear(model, company_id);
}
sdu = bt_mesh_alloc_buf(MIN(BLE_MESH_TX_SDU_MAX, HEALTH_FAULT_MAX_LEN));
if (!sdu) {
BT_ERR("%s, Failed to allocate memory", __func__);
return;
}
health_get_registered(model, company_id, sdu);
if (bt_mesh_model_send(model, ctx, sdu, NULL, NULL)) {
BT_ERR("%s, Unable to send Health Current Status", __func__);
}
bt_mesh_free_buf(sdu);
return;
}
static void health_fault_test_unrel(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_health_srv *srv = model->user_data;
u16_t company_id;
u8_t test_id;
if (!srv) {
BT_ERR("%s, No Health Server context provided", __func__);
return;
}
test_id = net_buf_simple_pull_u8(buf);
company_id = net_buf_simple_pull_le16(buf);
BT_DBG("test 0x%02x company 0x%04x", test_id, company_id);
if (srv->cb && srv->cb->fault_test) {
srv->cb->fault_test(model, test_id, company_id);
if (ctx->recv_op == OP_HEALTH_FAULT_CLEAR) {
health_send_fault_status(model, ctx);
}
}
@ -234,7 +189,6 @@ static void health_fault_test(struct bt_mesh_model *model,
struct net_buf_simple *buf)
{
struct bt_mesh_health_srv *srv = model->user_data;
struct net_buf_simple *sdu = NULL;
u16_t company_id;
u8_t test_id;
@ -246,34 +200,28 @@ static void health_fault_test(struct bt_mesh_model *model,
}
test_id = net_buf_simple_pull_u8(buf);
if (health_is_test_id_exist(model, test_id) == false) {
BT_ERR("%s, Unknown Test ID 0x%02x", __func__, test_id);
return;
}
company_id = net_buf_simple_pull_le16(buf);
if (company_id != srv->test.company_id) {
BT_ERR("%s, Unknown Company ID 0x%04x", __func__, company_id);
return;
}
BT_DBG("test 0x%02x company 0x%04x", test_id, company_id);
if (srv->cb && srv->cb->fault_test) {
int err;
srv->test.prev_test_id = test_id;
err = srv->cb->fault_test(model, test_id, company_id);
if (err) {
BT_WARN("Running fault test failed with err %d", err);
return;
}
if (srv->cb.fault_test) {
srv->cb.fault_test(model, test_id, company_id);
}
sdu = bt_mesh_alloc_buf(MIN(BLE_MESH_TX_SDU_MAX, HEALTH_FAULT_MAX_LEN));
if (!sdu) {
BT_ERR("%s, Failed to allocate memory", __func__);
return;
if (ctx->recv_op == OP_HEALTH_FAULT_TEST) {
health_send_fault_status(model, ctx);
}
health_get_registered(model, company_id, sdu);
if (bt_mesh_model_send(model, ctx, sdu, NULL, NULL)) {
BT_ERR("%s, Unable to send Health Current Status", __func__);
}
bt_mesh_free_buf(sdu);
return;
}
static void send_attention_status(struct bt_mesh_model *model,
@ -293,7 +241,6 @@ static void send_attention_status(struct bt_mesh_model *model,
BT_DBG("%u second%s", time, (time == 1U) ? "" : "s");
bt_mesh_model_msg_init(&msg, OP_ATTENTION_STATUS);
net_buf_simple_add_u8(&msg, time);
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
@ -310,7 +257,7 @@ static void attention_get(struct bt_mesh_model *model,
send_attention_status(model, ctx);
}
static void attention_set_unrel(struct bt_mesh_model *model,
static void health_set_attention(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
@ -329,10 +276,12 @@ static void attention_set(struct bt_mesh_model *model,
{
BT_DBG("%s", __func__);
attention_set_unrel(model, ctx, buf);
health_set_attention(model, ctx, buf);
if (ctx->recv_op == OP_ATTENTION_SET) {
send_attention_status(model, ctx);
}
}
static void send_health_period_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx)
@ -341,7 +290,6 @@ static void send_health_period_status(struct bt_mesh_model *model,
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_STATUS);
net_buf_simple_add_u8(&msg, model->pub->period_div);
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
@ -358,7 +306,7 @@ static void health_period_get(struct bt_mesh_model *model,
send_health_period_status(model, ctx);
}
static void health_period_set_unrel(struct bt_mesh_model *model,
static void health_set_period(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
@ -381,34 +329,64 @@ static void health_period_set(struct bt_mesh_model *model,
{
BT_DBG("%s", __func__);
health_period_set_unrel(model, ctx, buf);
health_set_period(model, ctx, buf);
if (ctx->recv_op == OP_HEALTH_PERIOD_SET) {
send_health_period_status(model, ctx);
}
}
const struct bt_mesh_model_op bt_mesh_health_srv_op[] = {
{ OP_HEALTH_FAULT_GET, 2, health_fault_get },
{ OP_HEALTH_FAULT_CLEAR, 2, health_fault_clear },
{ OP_HEALTH_FAULT_CLEAR_UNREL, 2, health_fault_clear_unrel },
{ OP_HEALTH_FAULT_CLEAR_UNREL, 2, health_fault_clear },
{ OP_HEALTH_FAULT_TEST, 3, health_fault_test },
{ OP_HEALTH_FAULT_TEST_UNREL, 3, health_fault_test_unrel },
{ OP_HEALTH_FAULT_TEST_UNREL, 3, health_fault_test },
{ OP_HEALTH_PERIOD_GET, 0, health_period_get },
{ OP_HEALTH_PERIOD_SET, 1, health_period_set },
{ OP_HEALTH_PERIOD_SET_UNREL, 1, health_period_set_unrel },
{ OP_HEALTH_PERIOD_SET_UNREL, 1, health_period_set },
{ OP_ATTENTION_GET, 0, attention_get },
{ OP_ATTENTION_SET, 1, attention_set },
{ OP_ATTENTION_SET_UNREL, 1, attention_set_unrel },
{ OP_ATTENTION_SET_UNREL, 1, attention_set },
BLE_MESH_MODEL_OP_END,
};
static int health_pub_update(struct bt_mesh_model *mod)
static size_t health_get_current(struct bt_mesh_model *model,
struct net_buf_simple *msg)
{
struct bt_mesh_model_pub *pub = mod->pub;
struct bt_mesh_health_srv *srv = model->user_data;
if (!srv) {
BT_ERR("%s, No Health Server context provided", __func__);
return 0;
}
if (msg->size < 4) {
BT_ERR("%s, Too small health publication msg size %d", __func__, msg->size);
return 0;
}
bt_mesh_model_msg_init(msg, OP_HEALTH_CURRENT_STATUS);
net_buf_simple_add_u8(msg, srv->test.prev_test_id);
net_buf_simple_add_le16(msg, srv->test.company_id);
health_get_fault_value(model, msg, true);
return health_get_curr_fault_count(model);
}
static int health_pub_update(struct bt_mesh_model *model)
{
struct bt_mesh_model_pub *pub = model->pub;
size_t count;
BT_DBG("%s", __func__);
count = health_get_current(mod, pub->msg);
if (!pub || !pub->msg) {
BT_ERR("%s, Invalid health publication context", __func__);
return -EINVAL;
}
count = health_get_current(model, pub->msg);
if (count) {
pub->fast_period = 1U;
} else {
@ -420,29 +398,29 @@ static int health_pub_update(struct bt_mesh_model *mod)
int bt_mesh_fault_update(struct bt_mesh_elem *elem)
{
struct bt_mesh_model *mod;
struct bt_mesh_model *model;
mod = bt_mesh_model_find(elem, BLE_MESH_MODEL_ID_HEALTH_SRV);
if (!mod) {
model = bt_mesh_model_find(elem, BLE_MESH_MODEL_ID_HEALTH_SRV);
if (!model) {
BT_ERR("%s, Health Server does not exist", __func__);
return -EINVAL;
}
if (!mod->pub) {
if (!model->pub) {
BT_ERR("%s, Health Server has no publication support", __func__);
return -EIO;
return -EINVAL;
}
/* Let periodic publishing, if enabled, take care of sending the
* Health Current Status.
*/
if (bt_mesh_model_pub_period_get(mod)) {
if (bt_mesh_model_pub_period_get(model)) {
return 0;
}
health_pub_update(mod);
health_pub_update(model);
return bt_mesh_model_publish(mod);
return bt_mesh_model_publish(model);
}
static void attention_off(struct k_work *work)
@ -457,17 +435,23 @@ static void attention_off(struct k_work *work)
return;
}
if (srv->cb && srv->cb->attn_off) {
srv->cb->attn_off(srv->model);
if (srv->cb.attn_off) {
srv->cb.attn_off(srv->model);
}
srv->attn_timer_start = false;
}
int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary)
{
struct bt_mesh_health_srv *srv = model->user_data;
/* Health Server Model shall be supported by a primary element and may be
* supported by any secondary elements.
*/
if (!srv) {
if (!primary) {
/* If Health Server is in the secondary element with NULL user_data. */
return 0;
}
@ -475,6 +459,11 @@ int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary)
return -EINVAL;
}
if (srv->test.id_count == 0 || !srv->test.test_ids) {
BT_ERR("%s, No Health Test ID provided", __func__);
return -EINVAL;
}
if (!model->pub) {
BT_ERR("%s, Health Server has no publication support", __func__);
return -EINVAL;
@ -485,6 +474,10 @@ int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary)
k_delayed_work_init(&srv->attn_timer, attention_off);
srv->model = model;
srv->attn_timer_start = false;
memset(srv->test.curr_faults, HEALTH_NO_FAULT, ARRAY_SIZE(srv->test.curr_faults));
memset(srv->test.reg_faults, HEALTH_NO_FAULT, ARRAY_SIZE(srv->test.reg_faults));
if (primary) {
health_srv = srv;
@ -514,16 +507,20 @@ void bt_mesh_attention(struct bt_mesh_model *model, u8_t time)
}
if (time) {
if (srv->cb && srv->cb->attn_on) {
srv->cb->attn_on(model);
if (srv->cb.attn_on) {
srv->cb.attn_on(model, time);
}
k_delayed_work_submit(&srv->attn_timer, time * 1000U);
srv->attn_timer_start = true;
} else {
k_delayed_work_cancel(&srv->attn_timer);
if (srv->cb && srv->cb->attn_off) {
srv->cb->attn_off(model);
if (srv->attn_timer_start == true) {
if (srv->cb.attn_off) {
srv->cb.attn_off(model);
}
srv->attn_timer_start = false;
}
}
}

View File

@ -65,6 +65,149 @@ extern const struct bt_mesh_model_op bt_mesh_cfg_srv_op[];
BLE_MESH_MODEL(BLE_MESH_MODEL_ID_CFG_SRV, \
bt_mesh_cfg_srv_op, NULL, srv_data)
typedef union {
struct {
u8_t beacon;
} cfg_beacon_set;
struct {
u8_t ttl;
} cfg_default_ttl_set;
struct {
u8_t gatt_proxy;
} cfg_gatt_proxy_set;
struct {
u8_t relay;
u8_t retransmit;
} cfg_relay_set;
struct {
u16_t elem_addr;
u16_t pub_addr;
u16_t app_idx;
bool cred_flag;
u8_t ttl;
u8_t period;
u8_t transmit;
u16_t cid;
u16_t mod_id;
} cfg_mod_pub_set;
struct {
u16_t elem_addr;
u8_t pub_addr[16];
u16_t app_idx;
bool cred_flag;
u8_t ttl;
u8_t period;
u8_t transmit;
u16_t cid;
u16_t mod_id;
} cfg_mod_pub_va_set;
struct {
u16_t elem_addr;
u16_t sub_addr;
u16_t cid;
u16_t mod_id;
} cfg_mod_sub_add;
struct {
u16_t elem_addr;
u8_t sub_addr[16];
u16_t cid;
u16_t mod_id;
} cfg_mod_sub_va_add;
struct {
u16_t elem_addr;
u16_t sub_addr;
u16_t cid;
u16_t mod_id;
} cfg_mod_sub_delete;
struct {
u16_t elem_addr;
u8_t sub_addr[16];
u16_t cid;
u16_t mod_id;
} cfg_mod_sub_va_delete;
struct {
u16_t elem_addr;
u16_t sub_addr;
u16_t cid;
u16_t mod_id;
} cfg_mod_sub_overwrite;
struct {
u16_t elem_addr;
u8_t sub_addr[16];
u16_t cid;
u16_t mod_id;
} cfg_mod_sub_va_overwrite;
struct {
u16_t elem_addr;
u16_t cid;
u16_t mod_id;
} cfg_mod_sub_delete_all;
struct {
u16_t net_idx;
u8_t net_key[16];
} cfg_netkey_add;
struct {
u16_t net_idx;
u8_t net_key[16];
} cfg_netkey_update;
struct {
u16_t net_idx;
} cfg_netkey_delete;
struct {
u16_t net_idx;
u16_t app_idx;
u8_t app_key[16];
} cfg_appkey_add;
struct {
u16_t net_idx;
u16_t app_idx;
u8_t app_key[16];
} cfg_appkey_update;
struct {
u16_t net_idx;
u16_t app_idx;
} cfg_appkey_delete;
struct {
u16_t net_idx;
u8_t identity;
} cfg_node_identity_set;
struct {
u16_t elem_addr;
u16_t app_idx;
u16_t cid;
u16_t mod_id;
} cfg_mod_app_bind;
struct {
u16_t elem_addr;
u16_t app_idx;
u16_t cid;
u16_t mod_id;
} cfg_mod_app_unbind;
struct {
u8_t frnd;
} cfg_friend_set;
struct {
u16_t net_idx;
u8_t kr_phase;
} cfg_kr_phase_set;
struct {
u16_t dst;
u8_t count;
u8_t period;
u8_t ttl;
u16_t feat;
u16_t net_idx;
} cfg_hb_pub_set;
struct {
u16_t src;
u16_t dst;
u8_t period;
} cfg_hb_sub_set;
struct {
u8_t transmit;
} cfg_net_transmit_set;
} bt_mesh_cfg_server_state_change_t;
/**
* @}
*/

View File

@ -21,25 +21,15 @@
*/
struct bt_mesh_health_srv_cb {
/* Fetch current faults */
int (*fault_get_cur)(struct bt_mesh_model *model, u8_t *test_id,
u16_t *company_id, u8_t *faults,
u8_t *fault_count);
/* Fetch registered faults */
int (*fault_get_reg)(struct bt_mesh_model *model, u16_t company_id,
u8_t *test_id, u8_t *faults,
u8_t *fault_count);
/* Clear registered faults */
int (*fault_clear)(struct bt_mesh_model *model, u16_t company_id);
void (*fault_clear)(struct bt_mesh_model *model, u16_t company_id);
/* Run a specific test */
int (*fault_test)(struct bt_mesh_model *model, u8_t test_id,
void (*fault_test)(struct bt_mesh_model *model, u8_t test_id,
u16_t company_id);
/* Attention on */
void (*attn_on)(struct bt_mesh_model *model);
void (*attn_on)(struct bt_mesh_model *model, u8_t time);
/* Attention off */
void (*attn_off)(struct bt_mesh_model *model);
@ -55,15 +45,30 @@ struct bt_mesh_health_srv_cb {
#define BLE_MESH_HEALTH_PUB_DEFINE(_name, _max_faults) \
BLE_MESH_MODEL_PUB_DEFINE(_name, NULL, (1 + 3 + (_max_faults)))
struct bt_mesh_health_test {
u8_t id_count; /* Number of Health self-test ID */
const u8_t *test_ids; /* Array of Health self-test IDs */
u16_t company_id; /* Company ID used to identify the Health Fault state */
u8_t prev_test_id; /* Most currently performed test id */
u8_t curr_faults[32]; /* Array of current faults */
u8_t reg_faults[32]; /* Array of registered faults */
} __attribute__((packed));
/** Mesh Health Server Model Context */
struct bt_mesh_health_srv {
struct bt_mesh_model *model;
/* Optional callback struct */
const struct bt_mesh_health_srv_cb *cb;
struct bt_mesh_health_srv_cb cb;
/* Attention Timer state */
struct k_delayed_work attn_timer;
/* Attention Timer start flag */
bool attn_timer_start;
/* Health Server fault test */
struct bt_mesh_health_test test;
};
extern const struct bt_mesh_model_op bt_mesh_health_srv_op[];

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);
@ -555,10 +554,13 @@ bool bt_mesh_iv_update(void);
* from a battery power source.
*
* @param enable true to enable LPN functionality, false to disable it.
* @param force when disable LPN functionality, use this flag to indicate
* whether directly clear corresponding information or sending
* friend clear to disable it.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_lpn_set(bool enable);
int bt_mesh_lpn_set(bool enable, bool force);
/** @brief Send out a Friend Poll message.
*
@ -578,6 +580,15 @@ int bt_mesh_lpn_poll(void);
*/
void bt_mesh_lpn_set_cb(void (*cb)(u16_t friend_addr, bool established));
/** @brief Register a callback for Friendship changes of friend node.
*
* Registers a callback that will be called whenever Friendship gets
* established or is terminated.
*
* @param cb Function to call when the Friendship status of friend node changes.
*/
void bt_mesh_friend_set_cb(void (*cb)(bool establish, u16_t lpn_addr, u8_t reason));
/**
* @}
*/

View File

@ -55,8 +55,11 @@
#define POLL_TIMEOUT_MAX(lpn) ((CONFIG_BLE_MESH_LPN_POLL_TIMEOUT * 100) - \
REQ_RETRY_DURATION(lpn))
/* Update 4 to 20 for BQB test case MESH/NODE/FRND/LPM/BI-02-C */
#define REQ_ATTEMPTS(lpn) (POLL_TIMEOUT_MAX(lpn) < K_SECONDS(3) ? 2 : 4)
/**
* 1. Should use 20 attempts for BQB test case MESH/NODE/FRND/LPM/BI-02-C.
* 2. We should use more specific value for each PollTimeout range.
*/
#define REQ_ATTEMPTS(lpn) (POLL_TIMEOUT_MAX(lpn) < K_SECONDS(3) ? 2 : 6)
#define CLEAR_ATTEMPTS 2
@ -70,9 +73,10 @@
/* 2 transmissions, 20ms interval */
#define POLL_XMIT BLE_MESH_TRANSMIT(1, 20)
#define FIRST_POLL_ATTEMPTS 6
static void (*lpn_cb)(u16_t friend_addr, bool established);
#if defined(CONFIG_BLE_MESH_DEBUG_LOW_POWER)
static const char *state2str(int state)
{
switch (state) {
@ -94,17 +98,16 @@ static const char *state2str(int state)
return "recv delay";
case BLE_MESH_LPN_WAIT_UPDATE:
return "wait update";
case BLE_MESH_LPN_OFFER_RECV:
return "offer recv";
default:
return "(unknown)";
}
}
#endif /* CONFIG_BLE_MESH_DEBUG_LOW_POWER */
static inline void lpn_set_state(int state)
{
#if defined(CONFIG_BLE_MESH_DEBUG_LOW_POWER)
BT_DBG("%s -> %s", state2str(bt_mesh.lpn.state), state2str(state));
#endif
bt_mesh.lpn.state = state;
}
@ -149,6 +152,8 @@ static inline void group_clear(bt_mesh_atomic_t *target, bt_mesh_atomic_t *sourc
static void clear_friendship(bool force, bool disable);
static bool scan_after_clear;
static void friend_clear_sent(int err, void *user_data)
{
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
@ -156,7 +161,10 @@ static void friend_clear_sent(int err, void *user_data)
/* We're switching away from Low Power behavior, so permanently
* enable scanning.
*/
if (scan_after_clear == false) {
bt_mesh_scan_enable();
scan_after_clear = true;
}
lpn->req_attempts++;
@ -261,6 +269,11 @@ static void clear_friendship(bool force, bool disable)
lpn_set_state(BLE_MESH_LPN_ENABLED);
k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT);
scan_after_clear = false;
if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
bt_mesh_scan_disable();
}
}
static void friend_req_sent(u16_t duration, int err, void *user_data)
@ -269,6 +282,10 @@ static void friend_req_sent(u16_t duration, int err, void *user_data)
if (err) {
BT_ERR("%s, Sending Friend Request failed (err %d)", __func__, err);
if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
bt_mesh_scan_enable();
}
return;
}
@ -322,10 +339,8 @@ static void req_sent(u16_t duration, int err, void *user_data)
{
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
#if defined(CONFIG_BLE_MESH_DEBUG_LOW_POWER)
BT_DBG("req 0x%02x duration %u err %d state %s",
lpn->sent_req, duration, err, state2str(lpn->state));
#endif
if (err) {
BT_ERR("%s, Sending request failed (err %d)", __func__, err);
@ -346,6 +361,12 @@ static void req_sent(u16_t duration, int err, void *user_data)
LPN_RECV_DELAY - SCAN_LATENCY);
} else {
lpn_set_state(BLE_MESH_LPN_OFFER_RECV);
/**
* Friend Update is replied by Friend Node with TTL set to 0 and Network
* Transmit set to 30ms which will cause the packet easy to be missed.
* Regarding this situation, here we can reduce the duration of receiving
* the first Friend Update.
*/
k_delayed_work_submit(&lpn->timer,
LPN_RECV_DELAY + duration +
lpn->recv_win);
@ -404,7 +425,7 @@ void bt_mesh_lpn_disable(bool force)
clear_friendship(force, true);
}
int bt_mesh_lpn_set(bool enable)
int bt_mesh_lpn_set(bool enable, bool force)
{
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
@ -442,7 +463,7 @@ int bt_mesh_lpn_set(bool enable)
k_delayed_work_cancel(&lpn->timer);
lpn_set_state(BLE_MESH_LPN_DISABLED);
} else {
bt_mesh_lpn_disable(false);
bt_mesh_lpn_disable(force);
}
}
@ -543,6 +564,10 @@ int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx,
lpn->counter++;
if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
bt_mesh_scan_disable();
}
return 0;
}
@ -720,7 +745,7 @@ static void update_timeout(struct bt_mesh_lpn *lpn)
bt_mesh_scan_disable();
}
if (lpn->req_attempts < 6) {
if (lpn->req_attempts < FIRST_POLL_ATTEMPTS) {
BT_WARN("Retrying first Friend Poll");
lpn->sent_req = 0U;
if (send_friend_poll() == 0) {
@ -737,9 +762,7 @@ static void lpn_timeout(struct k_work *work)
{
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
#if defined(CONFIG_BLE_MESH_DEBUG_LOW_POWER)
BT_DBG("state: %s", state2str(lpn->state));
#endif
switch (lpn->state) {
case BLE_MESH_LPN_DISABLED:
@ -774,10 +797,16 @@ static void lpn_timeout(struct k_work *work)
k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT);
break;
case BLE_MESH_LPN_OFFER_RECV:
BT_WARN("No Friend Update received after the first Friend Poll");
if (lpn->req_attempts < FIRST_POLL_ATTEMPTS) {
BT_WARN("Retrying the first Friend Poll, %d attempts", lpn->req_attempts);
lpn->sent_req = 0U;
send_friend_poll();
break;
}
BT_ERR("Timeout waiting for the first Friend Update");
clear_friendship(true, false);
break;
case BLE_MESH_LPN_ESTABLISHED:
if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) {
u8_t req = lpn->sent_req;
@ -1047,9 +1076,7 @@ int bt_mesh_lpn_init(void)
k_delayed_work_init(&lpn->timer, lpn_timeout);
if (lpn->state == BLE_MESH_LPN_ENABLED) {
if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
bt_mesh_scan_disable();
} else {
if (!IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
bt_mesh_scan_enable();
}

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
@ -89,6 +90,10 @@ struct bt_mesh_net bt_mesh = {
static u32_t dup_cache[4];
static int dup_cache_next;
#if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
#define BLE_MESH_MAX_STORED_RELAY_COUNT (CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT / 2)
#endif
static bool check_dup(struct net_buf_simple *data)
{
const u8_t *tail = net_buf_simple_tail(data);
@ -187,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__);
@ -469,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;
@ -609,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);
@ -785,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;
@ -897,7 +902,7 @@ 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) &&
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)) {
@ -913,6 +918,22 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
}
#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);
err = 0;
goto done;
}
}
#endif
/* Deliver to local network interface if necessary */
if (bt_mesh_fixed_group_match(tx->ctx->addr) ||
bt_mesh_elem_find(tx->ctx->addr)) {
@ -1202,7 +1223,25 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf,
transmit = bt_mesh_net_transmit_get();
}
/**
* When the node tries to relay a Segment ACK message, in this case
* the corresponding segment packets (if exist) can be removed from
* the relay queue.
*/
#if !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
buf = bt_mesh_adv_create(BLE_MESH_ADV_DATA, transmit, K_NO_WAIT);
#else
/**
* Check if the number of relay packets in queue is too large, if so
* use minimum relay retransmit value for later relay packets.
*/
if (bt_mesh_get_stored_relay_count() >= BLE_MESH_MAX_STORED_RELAY_COUNT) {
transmit = BLE_MESH_TRANSMIT(0, 20);
}
buf = bt_mesh_relay_adv_create(BLE_MESH_ADV_DATA, transmit, K_NO_WAIT);
#endif
if (!buf) {
BT_ERR("%s, Out of relay buffers", __func__);
return;
@ -1246,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) &&
@ -1256,7 +1295,11 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf,
}
if (relay_to_adv(rx->net_if)) {
#if !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
bt_mesh_adv_send(buf, NULL, NULL);
#else
bt_mesh_relay_adv_send(buf, NULL, NULL, rx->ctx.addr, rx->ctx.recv_dst);
#endif
}
done:
@ -1373,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);
}
@ -1448,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

@ -128,12 +128,12 @@ void bt_mesh_hci_init(void)
}
static struct ble_gap_disc_params scan_param;
#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
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 */
@ -175,7 +175,7 @@ static int ble_on_subscribe(uint16_t conn_handle,
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);
@ -185,12 +185,13 @@ static int ble_on_subscribe(uint16_t conn_handle,
}
} 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 0;
}
bt_mesh_gattc_info[i].wr_desc_done = true;
}
}
@ -370,13 +371,14 @@ static int svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
}
#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 */
static int disc_cb(struct ble_gap_event *event, void *arg)
{
struct ble_gap_disc_desc *desc;
#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
int rc, i;
uint8_t notif_data[100];
uint16_t notif_len;
@ -401,7 +403,8 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
}
osi_free(buf);
break;
#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
case BLE_GAP_EVENT_CONNECT:
if (event->connect.status == 0) {
/* Connection successfully established. */
@ -412,9 +415,9 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
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, conn_desc.peer_id_addr.val, BLE_MESH_ADDR_LEN)) {
if (!memcmp(bt_mesh_gattc_info[i].addr.val, conn_desc.peer_id_addr.val, BLE_MESH_ADDR_LEN)) {
bt_mesh_gattc_info[i].conn.handle = event->connect.conn_handle;
(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;
}
}
@ -441,24 +444,36 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
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++) {
memcpy(&conn_desc, &event->disconnect.conn, sizeof(conn_desc));
if (!memcmp(bt_mesh_gattc_info[i].addr, conn_desc.peer_ota_addr.val, BLE_MESH_ADDR_LEN)) {
if (!memcmp(bt_mesh_gattc_info[i].addr.val, conn_desc.peer_ota_addr.val, BLE_MESH_ADDR_LEN)) {
if (bt_mesh_gattc_info[i].conn.handle == event->disconnect.conn.conn_handle) {
(bt_mesh_gattc_conn_cb->disconnected)(&bt_mesh_gattc_info[i].conn, event->disconnect.reason);
(bt_mesh_gattc_conn_cb->disconnected)(&bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn, event->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
}
#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 prov 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;
@ -515,7 +530,7 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
return 0;
}
if (memcmp(bt_mesh_gattc_info[i].addr, conn_desc.peer_id_addr.val, BLE_MESH_ADDR_LEN) ||
if (memcmp(bt_mesh_gattc_info[i].addr.val, conn_desc.peer_id_addr.val, BLE_MESH_ADDR_LEN) ||
(bt_mesh_gattc_info[i].data_out_handle != event->notify_rx.attr_handle) ||
(event->notify_rx.indication != 0)) {
BT_ERR("%s, Notification error", __func__);
@ -1186,12 +1201,28 @@ 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;
}
u8_t bt_mesh_gattc_get_free_conn_count(void)
{
u8_t count = 0;
u8_t i;
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;
}
}
return count;
}
u16_t bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn *conn)
{
int i;
@ -1238,7 +1269,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;
@ -1249,8 +1280,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;
@ -1300,10 +1331,8 @@ int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, u16_t service_uuid)
rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &peer_addr, BLE_HS_FOREVER, &conn_params,
disc_cb, NULL);
/* Increment pbg_count */
provisioner_pbg_count_inc();
return 0;
return i;
}
static int mtu_cb(uint16_t conn_handle,
@ -1417,7 +1446,7 @@ void bt_mesh_gattc_disconnect(struct bt_mesh_conn *conn)
* Mesh Proxy Data In: 0x2ADD
* Mesh PROXY Data Out: 0x2ADE
*/
#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)
{
@ -1474,12 +1503,13 @@ static int dummy_access_cb(uint16_t conn_handle, uint16_t attr_handle,
}
static const struct ble_gatt_svc_def svc_defs [] = {
#ifdef CONFIG_BLE_MESH_GATT_PROXY
#ifdef CONFIG_BLE_MESH_GATT_PROXY_SERVER
{
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL),
.includes = NULL,
.characteristics = (struct ble_gatt_chr_def[]) { {
.characteristics = (struct ble_gatt_chr_def[])
{ {
.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_IN_VAL),
.access_cb = proxy_char_access_cb,
.flags = BLE_GATT_CHR_F_WRITE_NO_RSP,
@ -1489,7 +1519,8 @@ static const struct ble_gatt_svc_def svc_defs [] = {
.flags = BLE_GATT_CHR_F_NOTIFY,
}, {
0, /* No more characteristics in this service. */
} },
}
},
},
#endif
#ifdef CONFIG_BLE_MESH_PB_GATT
@ -1497,7 +1528,8 @@ static const struct ble_gatt_svc_def svc_defs [] = {
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL),
.includes = NULL,
.characteristics = (struct ble_gatt_chr_def[]) { {
.characteristics = (struct ble_gatt_chr_def[])
{ {
.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL),
.access_cb = proxy_char_access_cb,
.flags = BLE_GATT_CHR_F_WRITE_NO_RSP,
@ -1507,7 +1539,8 @@ static const struct ble_gatt_svc_def svc_defs [] = {
.flags = BLE_GATT_CHR_F_NOTIFY,
}, {
0, /* No more characteristics in this service. */
} },
}
},
},
#endif
{
@ -1551,7 +1584,8 @@ void bt_mesh_gatt_init(void)
ble_gatts_svc_set_visibility(proxy_svc_start_handle, 0);
#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 = BLE_ATT_MTU_DFLT;

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

@ -26,6 +26,24 @@
#include "mesh.h"
#include "client_common.h"
static bt_mesh_client_node_t *bt_mesh_client_pick_node(sys_slist_t *list, u16_t tx_dst)
{
if (sys_slist_is_empty(list)) {
return NULL;
}
sys_snode_t *cur = NULL; bt_mesh_client_node_t *node = NULL;
for (cur = sys_slist_peek_head(list);
cur != NULL; cur = sys_slist_peek_next(cur)) {
node = (bt_mesh_client_node_t *)cur;
if (node->ctx.addr == tx_dst) {
return node;
}
}
return NULL;
}
bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
@ -34,7 +52,6 @@ bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(
bt_mesh_client_internal_data_t *data = NULL;
bt_mesh_client_user_data_t *cli = NULL;
bt_mesh_client_node_t *node = NULL;
u32_t rsp;
if (!model || !ctx || !buf) {
BT_ERR("%s, Invalid parameter", __func__);
@ -47,16 +64,14 @@ bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(
return NULL;
}
rsp = ctx->recv_op;
/** If the received message address is not a unicast address,
* the address may be a group/virtual address, and we push
* this message to the application layer.
*/
if (!BLE_MESH_ADDR_IS_UNICAST(ctx->recv_dst)) {
BT_DBG("Unexpected status message 0x%x", rsp);
BT_DBG("Unexpected status message 0x%x", ctx->recv_op);
if (cli->publish_status && need_pub) {
cli->publish_status(rsp, model, ctx, buf);
cli->publish_status(ctx->recv_op, model, ctx, buf);
}
return NULL;
}
@ -73,17 +88,17 @@ bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(
}
if ((node = bt_mesh_client_pick_node(&data->queue, ctx->addr)) == NULL) {
BT_DBG("Unexpected status message 0x%x", rsp);
BT_DBG("Unexpected status message 0x%x", ctx->recv_op);
if (cli->publish_status && need_pub) {
cli->publish_status(rsp, model, ctx, buf);
cli->publish_status(ctx->recv_op, model, ctx, buf);
}
return NULL;
}
if (node->op_pending != rsp) {
BT_DBG("Unexpected status message 0x%x", rsp);
if (node->op_pending != ctx->recv_op) {
BT_DBG("Unexpected status message 0x%x", ctx->recv_op);
if (cli->publish_status && need_pub) {
cli->publish_status(rsp, model, ctx, buf);
cli->publish_status(ctx->recv_op, model, ctx, buf);
}
return NULL;
}
@ -91,26 +106,7 @@ bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(
return node;
}
bool bt_mesh_client_find_opcode_in_list(sys_slist_t *list, u32_t opcode)
{
if (sys_slist_is_empty(list)) {
return false;
}
sys_snode_t *cur = NULL; bt_mesh_client_node_t *node = NULL;
for (cur = sys_slist_peek_head(list);
cur != NULL; cur = sys_slist_peek_next(cur)) {
node = (bt_mesh_client_node_t *)cur;
if (node->op_pending == opcode) {
return true;
}
return NULL;
}
return node;
}
bool bt_mesh_client_check_node_in_list(sys_slist_t *list, u16_t tx_dst)
static bool bt_mesh_client_check_node_in_list(sys_slist_t *list, u16_t tx_dst)
{
if (sys_slist_is_empty(list)) {
return false;
@ -128,24 +124,6 @@ bool bt_mesh_client_check_node_in_list(sys_slist_t *list, u16_t tx_dst)
return false;
}
bt_mesh_client_node_t *bt_mesh_client_pick_node(sys_slist_t *list, u16_t tx_dst)
{
if (sys_slist_is_empty(list)) {
return NULL;
}
sys_snode_t *cur = NULL; bt_mesh_client_node_t *node = NULL;
for (cur = sys_slist_peek_head(list);
cur != NULL; cur = sys_slist_peek_next(cur)) {
node = (bt_mesh_client_node_t *)cur;
if (node->ctx.addr == tx_dst) {
return node;
}
}
return NULL;
}
static u32_t bt_mesh_client_get_status_op(const bt_mesh_client_op_pair_t *op_pair,
int size, u32_t opcode)
{

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _MODEL_COMMON_H_
#define _MODEL_COMMON_H_
#ifndef _CLIENT_COMMON_H_
#define _CLIENT_COMMON_H_
#include "mesh_access.h"
@ -98,12 +98,6 @@ bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf, bool need_pub);
bool bt_mesh_client_find_opcode_in_list(sys_slist_t *list, u32_t opcode);
bool bt_mesh_client_check_node_in_list(sys_slist_t *list, uint16_t tx_dst);
bt_mesh_client_node_t *bt_mesh_client_pick_node(sys_slist_t *list, u16_t tx_dst);
int bt_mesh_client_send_msg(struct bt_mesh_model *model,
u32_t opcode,
struct bt_mesh_msg_ctx *ctx,
@ -136,5 +130,5 @@ typedef struct {
*/
int bt_mesh_set_client_model_role(bt_mesh_role_param_t *common);
#endif /* _MODEL_COMMON_H_ */
#endif /* _CLIENT_COMMON_H_ */

View File

@ -0,0 +1,150 @@
// 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 <stdint.h>
#include "mesh_types.h"
#include "server_common.h"
#include "device_property.h"
static struct bt_mesh_dev_prop {
u16_t prop_id;
u8_t len;
} device_properties [] = {
{ BLE_MESH_INVALID_DEVICE_PROPERTY_ID, 0xFF },
{ BLE_MESH_AVERAGE_AMBIENT_TEMPERATURE_IN_A_PERIOD_OF_DAY, 0x03 },
{ BLE_MESH_AVERAGE_INPUT_CURRENT, 0x03 },
{ BLE_MESH_AVERAGE_INPUT_VOLTAGE, 0x03 },
{ BLE_MESH_AVERAGE_OUTPUT_CURRENT, 0x03 },
{ BLE_MESH_AVERAGE_OUTPUT_VOLTAGE, 0x03 },
{ BLE_MESH_CENTER_BEAM_INTENSITY_AT_FULL_POWER, 0x02 },
{ BLE_MESH_CHROMATICITY_TOLERANCE, 0x01 },
{ BLE_MESH_COLOR_RENDERING_INDEX_R9, 0x01 },
{ BLE_MESH_COLOR_RENDERING_INDEX_RA, 0x01 },
{ BLE_MESH_DEVICE_APPEARANCE, 0x02 },
{ BLE_MESH_DEVICE_COUNTRY_OF_ORIGIN, 0x02 },
{ BLE_MESH_DEVICE_DATE_OF_MANUFACTURE, 0x04 },
{ BLE_MESH_DEVICE_ENERGY_USE_SINCE_TURN_ON, 0x04 },
{ BLE_MESH_DEVICE_FIRMWARE_REVISION, 0x08 },
{ BLE_MESH_DEVICE_GLOBAL_TRADE_ITEM_NUMBER, 0x08 },
{ BLE_MESH_DEVICE_HARDWARE_REVISION, 0x16 },
{ BLE_MESH_DEVICE_MANUFACTURER_NAME, 0x36 },
{ BLE_MESH_DEVICE_MODEL_NUMBER, 0x24 },
{ BLE_MESH_DEVICE_OPERATING_TEMPERATURE_RANGE_SPECIFICATION, 0x04 },
{ BLE_MESH_DEVICE_OPERATING_TEMPERATURE_STATISTICAL_VALUES, 0x09 },
{ BLE_MESH_DEVICE_OVER_TEMPERATURE_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_DEVICE_POWER_RANGE_SPECIFICATION, 0x12 },
{ BLE_MESH_DEVICE_RUNTIME_SINCE_TURN_ON, 0x04 },
{ BLE_MESH_DEVICE_RUNTIME_WARRANTY, 0x04 },
{ BLE_MESH_DEVICE_SERIAL_NUMBER, 0x16 },
{ BLE_MESH_DEVICE_SOFTWARE_REVISION, 0x08 },
{ BLE_MESH_DEVICE_UNDER_TEMPERATURE_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_INDOOR_AMBIENT_TEMPERATURE_STATISTICAL_VALUES, 0x05 },
{ BLE_MESH_INITIAL_CIE_1931_CHROMATICITY_COORDINATES, 0x04 },
{ BLE_MESH_INITIAL_CORRELATED_COLOR_TEMPERATURE, 0x02 },
{ BLE_MESH_INITIAL_LUMINOUS_FLUX, 0x02 },
{ BLE_MESH_INITIAL_PLANCKIAN_DISTANCE, 0x02 },
{ BLE_MESH_INPUT_CURRENT_RANGE_SPECIFICATION, 0x06 },
{ BLE_MESH_INPUT_CURRENT_STATISTICS, 0x09 },
{ BLE_MESH_INPUT_OVER_CURRENT_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_INPUT_OVER_RIPPLE_VOLTAGE_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_INPUT_OVER_VOLTAGE_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_INPUT_UNDER_CURRENT_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_INPUT_UNDER_VOLTAGE_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_INPUT_VOLTAGE_RANGE_SPECIFICATION, 0x06 },
{ BLE_MESH_INPUT_VOLTAGE_RIPPLE_SPECIFICATION, 0x01 },
{ BLE_MESH_INPUT_VOLTAGE_STATISTICS, 0x09 },
{ BLE_MESH_LIGHT_CONTROL_AMBIENT_LUXLEVEL_ON, 0x04 },
{ BLE_MESH_LIGHT_CONTROL_AMBIENT_LUXLEVEL_PROLONG, 0x04 },
{ BLE_MESH_LIGHT_CONTROL_AMBIENT_LUXLEVEL_STANDBY, 0x04 },
{ BLE_MESH_LIGHT_CONTROL_LIGHTNESS_ON, 0x02 },
{ BLE_MESH_LIGHT_CONTROL_LIGHTNESS_PROLONG, 0x02 },
{ BLE_MESH_LIGHT_CONTROL_LIGHTNESS_STANDBY, 0x02 },
{ BLE_MESH_LIGHT_CONTROL_REGULATOR_ACCURACY, 0x01 },
{ BLE_MESH_LIGHT_CONTROL_REGULATOR_KID, 0x04 },
{ BLE_MESH_LIGHT_CONTROL_REGULATOR_KIU, 0x04 },
{ BLE_MESH_LIGHT_CONTROL_REGULATOR_KPD, 0x04 },
{ BLE_MESH_LIGHT_CONTROL_REGULATOR_KPU, 0x04 },
{ BLE_MESH_LIGHT_CONTROL_TIME_FADE, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_TIME_FADE_ON, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_TIME_FADE_STANDBY_AUTO, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_TIME_FADE_STANDBY_MANUAL, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_TIME_OCCUPANCY_DELAY, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_TIME_PROLONG, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_TIME_RUN_ON, 0x03 },
{ BLE_MESH_LUMEN_MAINTENANCE_FACTOR, 0x01 },
{ BLE_MESH_LUMINOUS_EFFICACY, 0x02 },
{ BLE_MESH_LUMINOUS_ENERGY_SINCE_TURN_ON, 0x04 },
{ BLE_MESH_LUMINOUS_EXPOSURE, 0x04 },
{ BLE_MESH_LUMINOUS_FLUX_RANGE, 0x04 },
{ BLE_MESH_MOTION_SENSED, 0x01 },
{ BLE_MESH_MOTION_THRESHOLD, 0x01 },
{ BLE_MESH_OPEN_CIRCUIT_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_OUTDOOR_STATISTICAL_VALUES, 0x05 },
{ BLE_MESH_OUTPUT_CURRENT_RANGE, 0x04 },
{ BLE_MESH_OUTPUT_CURRENT_STATISTICS, 0x09 },
{ BLE_MESH_OUTPUT_RIPPLE_VOLTAGE_SPECIFICATION, 0x01 },
{ BLE_MESH_OUTPUT_VOLTAGE_RANGE, 0x06 },
{ BLE_MESH_OUTPUT_VOLTAGE_STATISTICS, 0x09 },
{ BLE_MESH_OVER_OUTPUT_RIPPLE_VOLTAGE_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_PEOPLE_COUNT, 0x02 },
{ BLE_MESH_PRESENCE_DETECTED, 0x01 },
{ BLE_MESH_PRESENT_AMBIENT_LIGHT_LEVEL, 0x04 },
{ BLE_MESH_PRESENT_AMBIENT_TEMPERATURE, 0x01 },
{ BLE_MESH_PRESENT_CIE_1931_CHROMATICITY, 0x04 },
{ BLE_MESH_PRESENT_CORRELATED_COLOR_TEMPERATURE, 0x02 },
{ BLE_MESH_PRESENT_DEVICE_INPUT_POWER, 0x04 },
{ BLE_MESH_PRESENT_DEVICE_OPERATING_EFFICIENCY, 0x01 },
{ BLE_MESH_PRESENT_DEVICE_OPERATING_TEMPERATURE, 0x02 },
{ BLE_MESH_PRESENT_ILLUMINANCE, 0x04 },
{ BLE_MESH_PRESENT_INDOOR_AMBIENT_TEMPERATURE, 0x01 },
{ BLE_MESH_PRESENT_INPUT_CURRENT, 0x02 },
{ BLE_MESH_PRESENT_INPUT_RIPPLE_VOLTAGE, 0x01 },
{ BLE_MESH_PRESENT_INPUT_VOLTAGE, 0x02 },
{ BLE_MESH_PRESENT_LUMINOUS_FLUX, 0x02 },
{ BLE_MESH_PRESENT_OUTDOOR_AMBIENT_TEMPERATURE, 0x01 },
{ BLE_MESH_PRESENT_OUTPUT_CURRENT, 0x02 },
{ BLE_MESH_PRESENT_OUTPUT_VOLTAGE, 0x02 },
{ BLE_MESH_PRESENT_PLANCKIAN_DISTANCE, 0x02 },
{ BLE_MESH_PRESENT_RELATIVE_OUTPUT_RIPPLE_VOLTAGE, 0x01 },
{ BLE_MESH_RELATIVE_DEVICE_ENERGY_USE_IN_A_PERIOD_OF_DAY, 0x06 },
{ BLE_MESH_RELATIVE_DEVICE_RUNTIME_IN_A_GENERIC_LEVEL_RANGE, 0x05 },
{ BLE_MESH_RELATIVE_EXPOSURE_TIME_IN_AN_ILLUMINANCE_RANGE, 0x09 },
{ BLE_MESH_RELATIVE_RUNTIME_IN_A_CORRELATED_COLOR_TEMPERATURE_RANGE, 0x04 },
{ BLE_MESH_RELATIVE_RUNTIME_IN_A_DEVICE_OPERATING_TEMPERATURE_RANGE, 0x05 },
{ BLE_MESH_RELATIVE_RUNTIME_IN_AN_INPUT_CURRENT_RANGE, 0x05 },
{ BLE_MESH_RELATIVE_RUNTIME_IN_AN_INPUT_VOLTAGE_RANGE, 0x05 },
{ BLE_MESH_SHORT_CIRCUIT_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_TIME_SINCE_MOTION_SENSED, 0x02 },
{ BLE_MESH_TIME_SINCE_PRESENCE_DETECTED, 0x02 },
{ BLE_MESH_TOTAL_DEVICE_ENERGY_USE, 0x04 },
{ BLE_MESH_TOTAL_DEVICE_OFF_ON_CYCLES, 0x04 },
{ BLE_MESH_TOTAL_DEVICE_POWER_ON_CYCLES, 0x04 },
{ BLE_MESH_TOTAL_DEVICE_POWER_ON_TIME, 0x04 },
{ BLE_MESH_TOTAL_DEVICE_RUNTIME, 0x04 },
{ BLE_MESH_TOTAL_LIGHT_EXPOSURE_TIME, 0x04 },
{ BLE_MESH_TOTAL_LUMINOUS_ENERGY, 0x04 },
};
u8_t bt_mesh_get_dev_prop_len(u16_t prop_id)
{
if (prop_id > BLE_MESH_TOTAL_LUMINOUS_ENERGY) {
BT_ERR("%s, Unknown Device Property ID 0x%04x", __func__, prop_id);
return UINT8_MAX;
}
return device_properties[prop_id].len;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,374 @@
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
*
* Copyright (c) 2018 Vikrant More
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _GENERIC_SERVER_H_
#define _GENERIC_SERVER_H_
#include "server_common.h"
struct bt_mesh_gen_onoff_state {
u8_t onoff;
u8_t target_onoff;
};
struct bt_mesh_gen_onoff_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_onoff_state state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
};
struct bt_mesh_gen_level_state {
s16_t level;
s16_t target_level;
s16_t last_level;
s32_t last_delta;
bool move_start;
bool positive;
};
struct bt_mesh_gen_level_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_level_state state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
s32_t tt_delta_level;
};
struct bt_mesh_gen_def_trans_time_state {
u8_t trans_time;
};
struct bt_mesh_gen_def_trans_time_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_def_trans_time_state state;
};
struct bt_mesh_gen_onpowerup_state {
u8_t onpowerup;
};
struct bt_mesh_gen_power_onoff_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_onpowerup_state *state;
};
struct bt_mesh_gen_power_onoff_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_onpowerup_state *state;
};
struct bt_mesh_gen_power_level_state {
u16_t power_actual;
u16_t target_power_actual;
u16_t power_last;
u16_t power_default;
u8_t status_code;
u16_t power_range_min;
u16_t power_range_max;
};
struct bt_mesh_gen_power_level_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_power_level_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
s32_t tt_delta_level;
};
struct bt_mesh_gen_power_level_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_power_level_state *state;
};
struct bt_mesh_gen_battery_state {
u32_t battery_level : 8,
time_to_discharge : 24;
u32_t time_to_charge : 24,
battery_flags : 8;
};
struct bt_mesh_gen_battery_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_battery_state state;
};
struct bt_mesh_gen_location_state {
s32_t global_latitude;
s32_t global_longitude;
s16_t global_altitude;
s16_t local_north;
s16_t local_east;
s16_t local_altitude;
u8_t floor_number;
u16_t uncertainty;
};
struct bt_mesh_gen_location_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_location_state *state;
};
struct bt_mesh_gen_location_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_location_state *state;
};
/**
* According to the hierarchy of Generic Property states (Model Spec section 3.1.8),
* the Manufacturer Properties and Admin Properties may contain multiple Property
* states. User Properties just a collection of which can be accessed.
*
* property_count: Number of the properties contained in the table
* properties: Table of the properties
*
* These variables need to be initialized in the application layer, the precise
* number of the properties should be set and memories used to store the property
* values should be allocated.
*/
enum bt_mesh_gen_user_prop_access {
USER_ACCESS_PROHIBIT,
USER_ACCESS_READ,
USER_ACCESS_WRITE,
USER_ACCESS_READ_WRITE,
};
enum bt_mesh_gen_admin_prop_access {
ADMIN_NOT_USER_PROP,
ADMIN_ACCESS_READ,
ADMIN_ACCESS_WRITE,
ADMIN_ACCESS_READ_WRITE,
};
enum bt_mesh_gen_manu_prop_access {
MANU_NOT_USER_PROP,
MANU_ACCESS_READ,
};
struct bt_mesh_generic_property {
u16_t id;
u8_t user_access;
u8_t admin_access;
u8_t manu_access;
struct net_buf_simple *val;
};
struct bt_mesh_gen_user_prop_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
u8_t property_count;
struct bt_mesh_generic_property *properties;
};
struct bt_mesh_gen_admin_prop_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
u8_t property_count;
struct bt_mesh_generic_property *properties;
};
struct bt_mesh_gen_manu_prop_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
u8_t property_count;
struct bt_mesh_generic_property *properties;
};
struct bt_mesh_gen_client_prop_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
u8_t id_count;
u16_t *property_ids;
};
typedef union {
struct {
u8_t onoff;
} gen_onoff_set;
struct {
s16_t level;
} gen_level_set;
struct {
s16_t level;
} gen_delta_set;
struct {
s16_t level;
} gen_move_set;
struct {
u8_t trans_time;
} gen_def_trans_time_set;
struct {
u8_t onpowerup;
} gen_onpowerup_set;
struct {
u16_t power;
} gen_power_level_set;
struct {
u16_t power;
} gen_power_default_set;
struct {
u16_t range_min;
u16_t range_max;
} gen_power_range_set;
struct {
s32_t latitude;
s32_t longitude;
s16_t altitude;
} gen_loc_global_set;
struct {
s16_t north;
s16_t east;
s16_t altitude;
u8_t floor_number;
u16_t uncertainty;
} gen_loc_local_set;
struct {
u16_t id;
struct net_buf_simple *value;
} gen_user_prop_set;
struct {
u16_t id;
u8_t access;
struct net_buf_simple *value;
} gen_admin_prop_set;
struct {
u16_t id;
u8_t access;
} gen_manu_prop_set;
} bt_mesh_gen_server_state_change_t;
typedef union {
struct {
u16_t id;
} user_property_get;
struct {
u16_t id;
} admin_property_get;
struct {
u16_t id;
} manu_property_get;
struct {
u16_t id;
} client_properties_get;
} bt_mesh_gen_server_recv_get_msg_t;
typedef union {
struct {
bool op_en;
u8_t onoff;
u8_t tid;
u8_t trans_time;
u8_t delay;
} onoff_set;
struct {
bool op_en;
s16_t level;
u8_t tid;
u8_t trans_time;
u8_t delay;
} level_set;
struct {
bool op_en;
s32_t delta_level;
u8_t tid;
u8_t trans_time;
u8_t delay;
} delta_set;
struct {
bool op_en;
s16_t delta_level;
u8_t tid;
u8_t trans_time;
u8_t delay;
} move_set;
struct {
u8_t trans_time;
} def_trans_time_set;
struct {
u8_t onpowerup;
} onpowerup_set;
struct {
bool op_en;
u16_t power;
u8_t tid;
u8_t trans_time;
u8_t delay;
} power_level_set;
struct {
u16_t power;
} power_default_set;
struct {
u16_t range_min;
u16_t range_max;
} power_range_set;
struct {
s32_t latitude;
s32_t longitude;
s16_t altitude;
} loc_global_set;
struct {
s16_t north;
s16_t east;
s16_t altitude;
u8_t floor_number;
u16_t uncertainty;
} loc_local_set;
struct {
u16_t id;
struct net_buf_simple *value;
} user_property_set;
struct {
u16_t id;
u8_t access;
struct net_buf_simple *value;
} admin_property_set;
struct {
u16_t id;
u8_t access;
} manu_property_set;
} bt_mesh_gen_server_recv_set_msg_t;
void bt_mesh_generic_server_lock(void);
void bt_mesh_generic_server_unlock(void);
void gen_onoff_publish(struct bt_mesh_model *model);
void gen_level_publish(struct bt_mesh_model *model);
void gen_onpowerup_publish(struct bt_mesh_model *model);
void gen_power_level_publish(struct bt_mesh_model *model, u16_t opcode);
int bt_mesh_gen_onoff_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_gen_level_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_gen_def_trans_time_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_gen_power_onoff_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_gen_power_onoff_setup_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_gen_power_level_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_gen_power_level_setup_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_gen_battery_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_gen_location_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_gen_location_setup_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_gen_user_prop_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_gen_admin_prop_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_gen_manu_prop_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_gen_client_prop_srv_init(struct bt_mesh_model *model, bool primary);
#endif /* _GENERIC_SERVER_H_ */

View File

@ -0,0 +1,516 @@
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
*
* Copyright (c) 2018 Vikrant More
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _LIGHTING_SERVER_H_
#define _LIGHTING_SERVER_H_
#include "server_common.h"
struct bt_mesh_light_lightness_state {
u16_t lightness_linear;
u16_t target_lightness_linear;
u16_t lightness_actual;
u16_t target_lightness_actual;
u16_t lightness_last;
u16_t lightness_default;
u8_t status_code;
u16_t lightness_range_min;
u16_t lightness_range_max;
};
struct bt_mesh_light_lightness_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_lightness_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition actual_transition;
struct bt_mesh_state_transition linear_transition;
s32_t tt_delta_lightness_actual;
s32_t tt_delta_lightness_linear;
};
struct bt_mesh_light_lightness_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_lightness_state *state;
};
struct bt_mesh_light_ctl_state {
u16_t lightness;
u16_t target_lightness;
u16_t temperature;
u16_t target_temperature;
s16_t delta_uv;
s16_t target_delta_uv;
u8_t status_code;
u16_t temperature_range_min;
u16_t temperature_range_max;
u16_t lightness_default;
u16_t temperature_default;
s16_t delta_uv_default;
};
struct bt_mesh_light_ctl_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_ctl_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
s32_t tt_delta_lightness;
s32_t tt_delta_temperature;
s32_t tt_delta_delta_uv;
};
struct bt_mesh_light_ctl_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_ctl_state *state;
};
struct bt_mesh_light_ctl_temp_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_ctl_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
s32_t tt_delta_temperature;
s32_t tt_delta_delta_uv;
};
struct bt_mesh_light_hsl_state {
u16_t lightness;
u16_t target_lightness;
u16_t hue;
u16_t target_hue;
u16_t saturation;
u16_t target_saturation;
u16_t lightness_default;
u16_t hue_default;
u16_t saturation_default;
u8_t status_code;
u16_t hue_range_min;
u16_t hue_range_max;
u16_t saturation_range_min;
u16_t saturation_range_max;
};
struct bt_mesh_light_hsl_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_hsl_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
s32_t tt_delta_lightness;
s32_t tt_delta_hue;
s32_t tt_delta_saturation;
};
struct bt_mesh_light_hsl_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_hsl_state *state;
};
struct bt_mesh_light_hsl_hue_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_hsl_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
s32_t tt_delta_hue;
};
struct bt_mesh_light_hsl_sat_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_hsl_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
s32_t tt_delta_saturation;
};
struct bt_mesh_light_xyl_state {
u16_t lightness;
u16_t target_lightness;
u16_t x;
u16_t target_x;
u16_t y;
u16_t target_y;
u16_t lightness_default;
u16_t x_default;
u16_t y_default;
u8_t status_code;
u16_t x_range_min;
u16_t x_range_max;
u16_t y_range_min;
u16_t y_range_max;
};
struct bt_mesh_light_xyl_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_xyl_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
s32_t tt_delta_lightness;
s32_t tt_delta_x;
s32_t tt_delta_y;
};
struct bt_mesh_light_xyl_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_xyl_state *state;
};
struct bt_mesh_light_lc_state {
u32_t mode : 1, /* default 0 */
occupancy_mode : 1, /* default 1 */
light_onoff : 1,
target_light_onoff : 1,
occupancy : 1,
ambient_luxlevel : 24; /* 0x000000 ~ 0xFFFFFF */
u16_t linear_output; /* 0x0000 ~ 0xFFFF */
};
struct bt_mesh_light_lc_property_state {
u32_t time_occupancy_delay; /* 0x003A */
u32_t time_fade_on; /* 0x0037 */
u32_t time_run_on; /* 0x003C */
u32_t time_fade; /* 0x0036 */
u32_t time_prolong; /* 0x003B */
u32_t time_fade_standby_auto; /* 0x0038 */
u32_t time_fade_standby_manual; /* 0x0039 */
u16_t lightness_on; /* 0x002E */
u16_t lightness_prolong; /* 0x002F */
u16_t lightness_standby; /* 0x0030 */
u16_t ambient_luxlevel_on; /* 0x002B, 0x0000 ~ 0xFFFF */
u16_t ambient_luxlevel_prolong; /* 0x002C, 0x0000 ~ 0xFFFF */
u16_t ambient_luxlevel_standby; /* 0x002D, 0x0000 ~ 0xFFFF */
float regulator_kiu; /* 0x0033, 0.0 ~ 1000.0, default 250.0 */
float regulator_kid; /* 0x0032, 0.0 ~ 1000.0, default 25.0 */
float regulator_kpu; /* 0x0035, 0.0 ~ 1000.0, default 80.0 */
float regulator_kpd; /* 0x0034, 0.0 ~ 1000.0, default 80.0 */
s8_t regulator_accuracy; /* 0x0031, 0.0 ~ 100.0, default 2.0 */
u32_t set_occupancy_to_1_delay;
};
typedef enum {
LC_OFF,
LC_STANDBY,
LC_FADE_ON,
LC_RUN,
LC_FADE,
LC_PROLONG,
LC_FADE_STANDBY_AUTO,
LC_FADE_STANDBY_MANUAL,
} bt_mesh_lc_state;
struct bt_mesh_light_lc_state_machine {
struct {
u8_t fade_on;
u8_t fade;
u8_t fade_standby_auto;
u8_t fade_standby_manual;
} trans_time;
bt_mesh_lc_state state;
struct k_delayed_work timer;
};
struct bt_mesh_light_control {
struct bt_mesh_light_lc_state state;
struct bt_mesh_light_lc_property_state prop_state;
struct bt_mesh_light_lc_state_machine state_machine;
};
struct bt_mesh_light_lc_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_control *lc;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
};
struct bt_mesh_light_lc_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_control *lc;
};
typedef union {
struct {
u16_t lightness;
} lightness_set;
struct {
u16_t lightness;
} lightness_linear_set;
struct {
u16_t lightness;
} lightness_default_set;
struct {
u16_t range_min;
u16_t range_max;
} lightness_range_set;
struct {
u16_t lightness;
u16_t temperature;
s16_t delta_uv;
} ctl_set;
struct {
u16_t temperature;
s16_t delta_uv;
} ctl_temp_set;
struct {
u16_t range_min;
u16_t range_max;
} ctl_temp_range_set;
struct {
u16_t lightness;
u16_t temperature;
s16_t delta_uv;
} ctl_default_set;
struct {
u16_t lightness;
u16_t hue;
u16_t saturation;
} hsl_set;
struct {
u16_t hue;
} hsl_hue_set;
struct {
u16_t saturation;
} hsl_saturation_set;
struct {
u16_t lightness;
u16_t hue;
u16_t saturation;
} hsl_default_set;
struct {
u16_t hue_range_min;
u16_t hue_range_max;
u16_t sat_range_min;
u16_t sat_range_max;
} hsl_range_set;
struct {
u16_t lightness;
u16_t x;
u16_t y;
} xyl_set;
struct {
u16_t lightness;
u16_t x;
u16_t y;
} xyl_default_set;
struct {
u16_t x_range_min;
u16_t x_range_max;
u16_t y_range_min;
u16_t y_range_max;
} xyl_range_set;
struct {
u8_t mode;
} lc_mode_set;
struct {
u8_t mode;
} lc_om_set;
struct {
u8_t onoff;
} lc_light_onoff_set;
struct {
u16_t id;
struct net_buf_simple *value;
} lc_property_set;
struct {
u16_t property_id;
union {
u8_t occupancy;
u32_t set_occupancy_to_1_delay;
u32_t ambient_luxlevel;
} state;
} sensor_status;
} bt_mesh_light_server_state_change_t;
typedef union {
struct {
u16_t id;
} lc_property_get;
} bt_mesh_light_server_recv_get_msg_t;
typedef union {
struct {
bool op_en;
u16_t lightness;
u8_t tid;
u8_t trans_time;
u8_t delay;
} lightness_set;
struct {
bool op_en;
u16_t lightness;
u8_t tid;
u8_t trans_time;
u8_t delay;
} lightness_linear_set;
struct {
u16_t lightness;
} lightness_default_set;
struct {
u16_t range_min;
u16_t range_max;
} lightness_range_set;
struct {
bool op_en;
u16_t lightness;
u16_t temperature;
s16_t delta_uv;
u8_t tid;
u8_t trans_time;
u8_t delay;
} ctl_set;
struct {
bool op_en;
u16_t temperature;
s16_t delta_uv;
u8_t tid;
u8_t trans_time;
u8_t delay;
} ctl_temp_set;
struct {
u16_t range_min;
u16_t range_max;
} ctl_temp_range_set;
struct {
u16_t lightness;
u16_t temperature;
s16_t delta_uv;
} ctl_default_set;
struct {
bool op_en;
u16_t lightness;
u16_t hue;
u16_t saturation;
u8_t tid;
u8_t trans_time;
u8_t delay;
} hsl_set;
struct {
bool op_en;
u16_t hue;
u8_t tid;
u8_t trans_time;
u8_t delay;
} hsl_hue_set;
struct {
bool op_en;
u16_t saturation;
u8_t tid;
u8_t trans_time;
u8_t delay;
} hsl_saturation_set;
struct {
u16_t lightness;
u16_t hue;
u16_t saturation;
} hsl_default_set;
struct {
u16_t hue_range_min;
u16_t hue_range_max;
u16_t sat_range_min;
u16_t sat_range_max;
} hsl_range_set;
struct {
bool op_en;
u16_t lightness;
u16_t x;
u16_t y;
u8_t tid;
u8_t trans_time;
u8_t delay;
} xyl_set;
struct {
u16_t lightness;
u16_t x;
u16_t y;
} xyl_default_set;
struct {
u16_t x_range_min;
u16_t x_range_max;
u16_t y_range_min;
u16_t y_range_max;
} xyl_range_set;
struct {
u8_t mode;
} lc_mode_set;
struct {
u8_t mode;
} lc_om_set;
struct {
bool op_en;
u8_t light_onoff;
u8_t tid;
u8_t trans_time;
u8_t delay;
} lc_light_onoff_set;
struct {
u16_t id;
struct net_buf_simple *value;
} lc_property_set;
} bt_mesh_light_server_recv_set_msg_t;
typedef union {
struct {
struct net_buf_simple *data;
} sensor_status;
} bt_mesh_light_server_recv_status_msg_t;
void bt_mesh_light_server_lock(void);
void bt_mesh_light_server_unlock(void);
u8_t *bt_mesh_get_lc_prop_value(struct bt_mesh_model *model, u16_t prop_id);
void light_lightness_publish(struct bt_mesh_model *model, u16_t opcode);
void light_ctl_publish(struct bt_mesh_model *model, u16_t opcode);
void light_hsl_publish(struct bt_mesh_model *model, u16_t opcode);
void light_xyl_publish(struct bt_mesh_model *model, u16_t opcode);
void light_lc_publish(struct bt_mesh_model *model, u16_t opcode);
int bt_mesh_light_lightness_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_light_lightness_setup_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_light_ctl_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_light_ctl_setup_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_light_ctl_temp_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_light_hsl_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_light_hsl_setup_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_light_hsl_hue_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_light_hsl_sat_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_light_xyl_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_light_xyl_setup_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_light_lc_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_light_lc_setup_srv_init(struct bt_mesh_model *model, bool primary);
#endif /* _LIGHTING_SERVER_H_ */

View File

@ -0,0 +1,249 @@
// 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 _SENSOR_SERVER_H_
#define _SENSOR_SERVER_H_
#include "server_common.h"
/* Sensor Property ID related */
#define INVALID_SENSOR_PROPERTY_ID 0x0000
#define SENSOR_PROPERTY_ID_LEN 0x02
/* Sensor Descriptor state related */
#define SENSOR_DESCRIPTOR_LEN 0x08
#define SENSOR_UNSPECIFIED_POS_TOLERANCE 0x000
#define SENSOR_UNSPECIFIED_NEG_TOLERANCE 0x000
#define SENSOR_NOT_APPL_MEASURE_PERIOD 0x00
#define SENSOR_NOT_APPL_UPDATE_INTERVAL 0x00
/* Sensor Setting state related */
#define INVALID_SENSOR_SETTING_PROPERTY_ID 0x0000
#define SENSOR_SETTING_PROPERTY_ID_LEN 0x02
#define SENSOR_SETTING_ACCESS_LEN 0x01
#define SENSOR_SETTING_ACCESS_READ 0x01
#define SENSOR_SETTING_ACCESS_READ_WRITE 0x03
/* Sensor Cadence state related */
#define SENSOR_DIVISOR_TRIGGER_TYPE_LEN 0x01
#define SENSOR_STATUS_MIN_INTERVAL_LEN 0x01
#define SENSOR_PERIOD_DIVISOR_MAX_VALUE 15
#define SENSOR_STATUS_MIN_INTERVAL_MAX 26
#define SENSOR_STATUS_TRIGGER_TYPE_CHAR 0
#define SENSOR_STATUS_TRIGGER_TYPE_UINT16 1
#define SENSOR_STATUS_TRIGGER_UINT16_LEN 0x02
/* Sensor Data state related */
#define SENSOR_DATA_FORMAT_A 0x00
#define SENSOR_DATA_FORMAT_B 0x01
#define SENSOR_DATA_FORMAT_A_MPID_LEN 0x02
#define SENSOR_DATA_FORMAT_B_MPID_LEN 0x03
#define SENSOR_DATA_ZERO_LEN 0x7F
enum bt_mesh_sensor_sample_func {
UNSPECIFIED,
INSTANTANEOUS,
ARITHMETIC_MEAN,
RMS,
MAXIMUM,
MINIMUM,
ACCUMULATED,
COUNT,
};
struct sensor_descriptor {
u32_t positive_tolerance : 12,
negative_tolerance : 12,
sample_function : 8;
u8_t measure_period;
u8_t update_interval;
};
struct sensor_setting {
u16_t property_id;
u8_t access;
/* Or use union to include all possible types */
struct net_buf_simple *raw;
};
struct sensor_cadence {
u8_t period_divisor : 7,
trigger_type : 1;
struct net_buf_simple *trigger_delta_down;
struct net_buf_simple *trigger_delta_up;
u8_t min_interval;
struct net_buf_simple *fast_cadence_low;
struct net_buf_simple *fast_cadence_high;
};
struct sensor_data {
/**
* Format A: The Length field is a 1-based uint4 value (valid range 0x00xF,
* representing range of 1 16).
* Format B: The Length field is a 1-based uint7 value (valid range 0x00x7F,
* representing range of 1 127). The value 0x7F represents a
* length of zero.
*/
u8_t format : 1,
length : 7;
struct net_buf_simple *raw_value;
};
struct sensor_series_column {
struct net_buf_simple *raw_value_x;
struct net_buf_simple *column_width;
struct net_buf_simple *raw_value_y;
};
struct bt_mesh_sensor_state {
u16_t sensor_property_id;
/* Constant throughout the lifetime of an element */
struct sensor_descriptor descriptor;
/* Multiple Sensor Setting states may be present for each sensor.
* The Sensor Setting Property ID values shall be unique for each
* Sensor Property ID that identifies a sensor within an element.
*/
const u8_t setting_count;
struct sensor_setting *settings;
/* The Sensor Cadence state may be not supported by sensors based
* on device properties referencing "non-scalar characteristics"
* such as "histograms" or "composite characteristics".
*/
struct sensor_cadence *cadence;
struct sensor_data sensor_data;
/* Values measured by sensors may be organized as arrays (and
* represented as series of columns, such as histograms).
* 1. The Sensor Raw Value X field has a size and representation
* defined by the Sensor Property ID and represents the left
* corner of the column on the X axis.
* 2. The Sensor Column Width field has a size and representation
* defined by the Sensor Property ID and represents the width
* of the column on the X axis.
* 3. The Sensor Raw Value Y field has a size and representation
* defined by the Sensor Property ID and represents the height
* of the column on the Y axis.
* Note: Values outside the bins defined by a Sensor Property are
* not included. For example, if the histogram is defined as 3 bins
* representing lamp operating hours in a given temperature range
* and the bins are [40,60), [60, 80), and [80,100], then any hours
* outside that [40, 100] range would not be included.
*/
struct sensor_series_column series_column;
};
/* 1. Multiple instances of the Sensor states may be present within the
* same model, provided that each instance has a unique value of the
* Sensor Property ID to allow the instances to be differentiated.
* 2. Note: The number of sensors within a multisensor is limited by the
* size of the message payload for the Sensor Descriptor Status message.
* A single Sensor Descriptor may be sent using a single Unsegmented
* Access message. Using Segmentation and Reassembly (SAR), up to 38
* Sensor Descriptor states may be sent.
*/
struct bt_mesh_sensor_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
const u8_t state_count;
struct bt_mesh_sensor_state *states;
};
struct bt_mesh_sensor_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
const u8_t state_count;
struct bt_mesh_sensor_state *states;
};
typedef union {
struct {
u16_t id;
u8_t period_divisor : 7,
trigger_type : 1;
struct net_buf_simple *trigger_delta_down;
struct net_buf_simple *trigger_delta_up;
u8_t min_interval;
struct net_buf_simple *fast_cadence_low;
struct net_buf_simple *fast_cadence_high;
} sensor_cadence_set;
struct {
u16_t id;
u16_t setting_id;
struct net_buf_simple *value;
} sensor_setting_set;
} bt_mesh_sensor_server_state_change_t;
typedef union {
struct {
bool op_en;
u16_t id;
} sensor_descriptor_get;
struct {
u16_t id;
} sensor_cadence_get;
struct {
u16_t id;
} sensor_settings_get;
struct {
u16_t id;
u16_t setting_id;
} sensor_setting_get;
struct {
bool op_en;
u16_t id;
} sensor_get;
struct {
u16_t id;
struct net_buf_simple *raw_x;
} sensor_column_get;
struct {
bool op_en;
u16_t id;
struct net_buf_simple *raw;
} sensor_series_get;
} bt_mesh_sensor_server_recv_get_msg_t;
typedef union {
struct {
u16_t id;
struct net_buf_simple *cadence;
} sensor_cadence_set;
struct {
u16_t id;
u16_t setting_id;
struct net_buf_simple *raw;
} sensor_setting_set;
} bt_mesh_sensor_server_recv_set_msg_t;
int bt_mesh_sensor_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_sensor_setup_srv_init(struct bt_mesh_model *model, bool primary);
#endif /* _SENSOR_SERVER_H_ */

View File

@ -0,0 +1,128 @@
// 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 _SERVER_COMMON_H_
#define _SERVER_COMMON_H_
#include <string.h>
#include <stdint.h>
#include "mesh_buf.h"
#include "mesh_access.h"
#include "mesh_kernel.h"
#define BLE_MESH_SERVER_RSP_MAX_LEN 384
#define BLE_MESH_SERVER_TRANS_MIC_SIZE 4
#define BLE_MESH_CHECK_SEND_STATUS(_func) do { \
int __status = (_func); \
if (__status) { \
BT_ERR("%s, Send failed, err %d", __func__, __status); \
} \
} while(0);
#define BLE_MESH_STATE_OFF 0x00
#define BLE_MESH_STATE_ON 0x01
#define BLE_MESH_STATE_RESTORE 0x02
/* Following 4 values are as per Mesh Model specification */
#define BLE_MESH_LIGHTNESS_MIN 0x0001
#define BLE_MESH_LIGHTNESS_MAX 0xFFFF
#define BLE_MESH_TEMPERATURE_MIN 0x0320
#define BLE_MESH_TEMPERATURE_MAX 0x4E20
#define BLE_MESH_TEMPERATURE_UNKNOWN 0xFFFF
/* Refer 7.2 of Mesh Model Specification */
#define BLE_MESH_RANGE_UPDATE_SUCCESS 0x00
#define BLE_MESH_CANNOT_SET_RANGE_MIN 0x01
#define BLE_MESH_CANNOT_SET_RANGE_MAX 0x02
#define BLE_MESH_UNKNOWN_REMAIN_TIME 0x3F
#define BLE_MESH_DEVICE_SPECIFIC_RESOLUTION 10
#define BLE_MESH_INVALID_DEVICE_PROPERTY_ID 0x0000
enum {
BLE_MESH_TRANS_TIMER_START, /* Proper transition timer has been started */
BLE_MESH_TRANS_FLAG_MAX,
};
struct bt_mesh_state_transition {
bool just_started;
u8_t trans_time;
u8_t remain_time;
u8_t delay;
u32_t quo_tt;
u32_t counter;
u32_t total_duration;
s64_t start_timestamp;
BLE_MESH_ATOMIC_DEFINE(flag, BLE_MESH_TRANS_FLAG_MAX);
struct k_delayed_work timer;
};
struct bt_mesh_last_msg_info {
u8_t tid;
u16_t src;
u16_t dst;
s64_t timestamp;
};
#define BLE_MESH_SERVER_RSP_BY_APP 0
#define BLE_MESH_SERVER_AUTO_RSP 1
struct bt_mesh_server_rsp_ctrl {
/**
* @brief BLE Mesh Server Response Option
* 1. If get_auto_rsp is set to BLE_MESH_SERVER_RSP_BY_APP, then the response
* of Client Get messages need to be replied by the application;
* 2. If get_auto_rsp is set to BLE_MESH_SERVER_AUTO_RSP, then the response
* of Client Get messages will be replied by the server models;
* 3. If set_auto_rsp is set to BLE_MESH_SERVER_RSP_BY_APP, then the response
* of Client Set messages need to be replied by the application;
* 4. If set_auto_rsp is set to BLE_MESH_SERVER_AUTO_RSP, then the response
* of Client Set messages will be replied by the server models;
* 5. If status_auto_rsp is set to BLE_MESH_SERVER_RSP_BY_APP, then the response
* of Server Status messages need to be replied by the application;
* 6. If status_auto_rsp is set to BLE_MESH_SERVER_AUTO_RSP, then the response
* of Server status messages will be replied by the server models;
*/
u8_t get_auto_rsp : 1, /* Response for Client Get messages */
set_auto_rsp : 1, /* Response for Client Set messages */
status_auto_rsp : 1; /* Response for Server Status messages */
};
u8_t bt_mesh_get_default_trans_time(struct bt_mesh_model *model);
int bt_mesh_get_light_lc_trans_time(struct bt_mesh_model *model, u8_t *trans_time);
int bt_mesh_server_get_optional(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf,
u8_t *trans_time, u8_t *delay,
bool *optional);
void bt_mesh_server_alloc_ctx(struct k_work *work);
bool bt_mesh_is_server_recv_last_msg(struct bt_mesh_last_msg_info *last,
u8_t tid, u16_t src, u16_t dst, s64_t *now);
void bt_mesh_server_update_last_msg(struct bt_mesh_last_msg_info *last,
u8_t tid, u16_t src, u16_t dst, s64_t *now);
struct net_buf_simple *bt_mesh_server_get_pub_msg(struct bt_mesh_model *model, u16_t msg_len);
#endif /* _SERVER_COMMON_H_ */

View File

@ -0,0 +1,92 @@
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
*
* Copyright (c) 2018 Vikrant More
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STATE_BINDING_H_
#define _STATE_BINDING_H_
typedef enum {
GENERIC_ONOFF_STATE,
GENERIC_LEVEL_STATE,
GENERIC_ONPOWERUP_STATE,
GENERIC_POWER_ACTUAL_STATE,
LIGHT_LIGHTNESS_ACTUAL_STATE,
LIGHT_LIGHTNESS_LINEAR_STATE,
LIGHT_CTL_LIGHTNESS_STATE,
LIGHT_CTL_TEMP_DELTA_UV_STATE,
LIGHT_HSL_LIGHTNESS_STATE,
LIGHT_HSL_HUE_STATE,
LIGHT_HSL_SATURATION_STATE,
LIGHT_XYL_LIGHTNESS_STATE,
LIGHT_LC_LIGHT_ONOFF_STATE,
BIND_STATE_MAX,
} bt_mesh_server_state_type_t;
typedef union {
struct {
u8_t onoff;
} gen_onoff;
struct {
s16_t level;
} gen_level;
struct {
u8_t onpowerup;
} gen_onpowerup;
struct {
u16_t power;
} gen_power_actual;
struct {
u16_t lightness;
} light_lightness_actual;
struct {
u16_t lightness;
} light_lightness_linear;
struct {
u16_t lightness;
} light_ctl_lightness;
struct {
u16_t temperature;
s16_t delta_uv;
} light_ctl_temp_delta_uv;
struct {
u16_t lightness;
} light_hsl_lightness;
struct {
u16_t hue;
} light_hsl_hue;
struct {
u16_t saturation;
} light_hsl_saturation;
struct {
u16_t lightness;
} light_xyl_lightness;
struct {
u8_t onoff;
} light_lc_light_onoff;
} bt_mesh_server_state_value_t;
u16_t bt_mesh_convert_lightness_actual_to_linear(u16_t actual);
u16_t bt_mesh_convert_lightness_linear_to_actual(u16_t linear);
s16_t bt_mesh_convert_temperature_to_gen_level(u16_t temp, u16_t min, u16_t max);
u16_t bt_mesh_covert_gen_level_to_temperature(s16_t level, u16_t min, u16_t max);
s16_t bt_mesh_convert_hue_to_level(u16_t hue);
u16_t bt_mesh_convert_level_to_hue(s16_t level);
s16_t bt_mesh_convert_saturation_to_level(u16_t saturation);
u16_t bt_mesh_convert_level_to_saturation(s16_t level);
int bt_mesh_update_binding_state(struct bt_mesh_model *model,
bt_mesh_server_state_type_t type,
bt_mesh_server_state_value_t *value);
#endif /* _STATE_BINDING_H_ */

View File

@ -0,0 +1,91 @@
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
*
* Copyright (c) 2018 Vikrant More
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STATE_TRANSITION_H_
#define _STATE_TRANSITION_H_
#include "server_common.h"
#include "generic_server.h"
#include "lighting_server.h"
#include "time_scene_server.h"
void bt_mesh_server_calc_remain_time(struct bt_mesh_state_transition *transition);
/* APIs used to get server model transtion time values */
void generic_onoff_tt_values(struct bt_mesh_gen_onoff_srv *srv,
u8_t trans_time, u8_t delay);
void generic_level_tt_values(struct bt_mesh_gen_level_srv *srv,
u8_t trans_time, u8_t delay);
void generic_power_level_tt_values(struct bt_mesh_gen_power_level_srv *srv,
u8_t trans_time, u8_t delay);
void light_lightness_actual_tt_values(struct bt_mesh_light_lightness_srv *srv,
u8_t trans_time, u8_t delay);
void light_lightness_linear_tt_values(struct bt_mesh_light_lightness_srv *srv,
u8_t trans_time, u8_t delay);
void light_ctl_tt_values(struct bt_mesh_light_ctl_srv *srv,
u8_t trans_time, u8_t delay);
void light_ctl_temp_tt_values(struct bt_mesh_light_ctl_temp_srv *srv,
u8_t trans_time, u8_t delay);
void light_hsl_tt_values(struct bt_mesh_light_hsl_srv *srv,
u8_t trans_time, u8_t delay);
void light_hsl_hue_tt_values(struct bt_mesh_light_hsl_hue_srv *srv,
u8_t trans_time, u8_t delay);
void light_hsl_sat_tt_values(struct bt_mesh_light_hsl_sat_srv *srv,
u8_t trans_time, u8_t delay);
void light_xyl_tt_values(struct bt_mesh_light_xyl_srv *srv,
u8_t trans_time, u8_t delay);
void light_lc_tt_values(struct bt_mesh_light_lc_srv *srv,
u8_t trans_time, u8_t delay);
void scene_tt_values(struct bt_mesh_scene_srv *srv, u8_t trans_time, u8_t delay);
/* Server model transtion timer handlers */
void generic_onoff_work_handler(struct k_work *work);
void generic_level_work_handler(struct k_work *work);
void generic_power_level_work_handler(struct k_work *work);
void light_lightness_actual_work_handler(struct k_work *work);
void light_lightness_linear_work_handler(struct k_work *work);
void light_ctl_work_handler(struct k_work *work);
void light_ctl_temp_work_handler(struct k_work *work);
void light_hsl_work_handler(struct k_work *work);
void light_hsl_hue_work_handler(struct k_work *work);
void light_hsl_sat_work_handler(struct k_work *work);
void light_xyl_work_handler(struct k_work *work);
void light_lc_work_handler(struct k_work *work);
void scene_recall_work_handler(struct k_work *work);
void bt_mesh_server_stop_transition(struct bt_mesh_state_transition *transition);
void bt_mesh_server_start_transition(struct bt_mesh_state_transition *transition);
#endif /* _STATE_TRANSITION_H_ */

View File

@ -0,0 +1,393 @@
// 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 _TIME_SCENE_SERVER_H_
#define _TIME_SCENE_SERVER_H_
#include "mesh_slist.h"
#include "mesh_kernel.h"
#include "server_common.h"
/**
* 1. Mesh defines times based on International Atomic Time (TAI). The base
* representation of times is the number of seconds after 00:00:00 TAI
* on 2000-01-01 (that is, 1999-12-31 T23:59:28 UTC).
* 2. UTC: Coordinated Universal Time. For more information, please refer
* to https://time.is/zh/UTC
* 3. For the algorithm used for the transfer between TAI and UTC, please
* refer to Mesh Model Spec Section 5.1.1
*/
#define UNKNOWN_TAI_SECONDS 0x0000000000
#define UNKNOWN_TAI_ZONE_CHANGE 0x0000000000
#define UNKNOWN_TAI_DELTA_CHANGE 0x0000000000
#define TAI_UTC_DELAT_MAX_VALUE 0x7FFF
#define TAI_SECONDS_LEN 0x05
#define TAI_OF_ZONE_CHANGE_LEN 0x05
#define TAI_OF_DELTA_CHANGE_LEN 0x05
#define INVALID_SCENE_NUMBER 0x0000
#define SCENE_NUMBER_LEN 0x02
#define SCHEDULE_YEAR_ANY_YEAR 0x64
#define SCHEDULE_DAY_ANY_DAY 0x00
#define SCHEDULE_HOUR_ANY_HOUR 0x18
#define SCHEDULE_HOUR_ONCE_A_DAY 0x19
#define SCHEDULE_SEC_ANY_OF_HOUR 0x3C
#define SCHEDULE_SEC_EVERY_15_MIN 0x3D
#define SCHEDULE_SEC_EVERY_20_MIN 0x3E
#define SCHEDULE_SEC_ONCE_AN_HOUR 0x3F
#define SCHEDULE_SEC_ANY_OF_MIN 0x3C
#define SCHEDULE_SEC_EVERY_15_SEC 0x3D
#define SCHEDULE_SEC_EVERY_20_SEC 0x3E
#define SCHEDULE_SEC_ONCE_AN_MIN 0x3F
#define SCHEDULE_ACT_TURN_OFF 0x00
#define SCHEDULE_ACT_TURN_ON 0x01
#define SCHEDULE_ACT_SCENE_RECALL 0x02
#define SCHEDULE_ACT_NO_ACTION 0x0F
#define SCHEDULE_SCENE_NO_SCENE 0x0000
#define SCHEDULE_ENTRY_MAX_INDEX 0x0F
#define TIME_NONE 0x00
#define TIME_AUTHORITY 0x01
#define TIME_RELAY 0x02
#define TIME_CLINET 0x03
#define SCENE_SUCCESS 0x00
#define SCENE_REG_FULL 0x01
#define SCENE_NOT_FOUND 0x02
/**
* The Time state represents the present TAI time, the current TAI-UTC Delta
* and local time zone offset, and the next change to each of the latter
* (e.g., because of a switch from winter to summer time or an announced leap
* second). It consists of 10 fields with a total size of 183 bits.
*/
struct bt_mesh_time_state {
struct {
u8_t tai_seconds[5];
u8_t subsecond;
u8_t uncertainty;
u8_t time_zone_offset_curr;
u8_t time_zone_offset_new;
u8_t tai_zone_change[5];
u16_t time_authority : 1,
tai_utc_delta_curr : 15;
u16_t tai_utc_delta_new : 15;
u8_t tai_delta_change[5];
} time;
u8_t time_role;
};
struct bt_mesh_time_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_time_state *state;
};
struct bt_mesh_time_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_time_state *state;
};
struct scene_register {
u16_t scene_number;
u8_t scene_type; /* Indicate the type of scene value */
/**
* Scene value may use a union to represent later, the union contains
* structures of all the model states which can be stored in a scene.
*/
struct net_buf_simple *scene_value;
};
/**
* Scenes serve as memory banks for storage of states (e.g., a power level
* or a light level/color). Values of states of an element can be stored
* as a scene and can be recalled later from the scene memory.
*
* A scene is represented by a Scene Number, which is a 16-bit non-zero,
* mesh-wide value. (There can be a maximum of 65535 scenes in a mesh
* network.) The meaning of a scene, as well as the state storage container
* associated with it, are determined by a model.
*
* The Scenes state change may start numerous parallel model transitions.
* In that case, each individual model handles the transition internally.
*
* The scene transition is defined as a group of individual model transitions
* started by a Scene Recall operation. The scene transition is in progress
* when at least one transition from the group of individual model transitions
* is in progress.
*/
struct bt_mesh_scenes_state {
const u16_t scene_count;
struct scene_register *scenes;
/**
* The Current Scene state is a 16-bit value that contains either the Scene
* Number of the currently active scene or a value of 0x0000 when no scene
* is active.
*
* When a Scene Store operation or a Scene Recall operation completes with
* success, the Current Scene state value shall be to the Scene Number used
* during that operation.
*
* When the Current Scene Number is deleted from a Scene Register state as a
* result of Scene Delete operation, the Current Scene state shall be set to
* 0x0000.
*
* When any of the element's state that is marked as Stored with Scene has
* changed not as a result of a Scene Recall operation, the value of the
* Current Scene state shall be set to 0x0000.
*
* When a scene transition is in progress, the value of the Current Scene
* state shall be set to 0x0000.
*/
u16_t current_scene;
/**
* The Target Scene state is a 16-bit value that contains the target Scene
* Number when a scene transition is in progress.
*
* When the scene transition is in progress and the target Scene Number is
* deleted from a Scene Register state as a result of Scene Delete operation,
* the Target Scene state shall be set to 0x0000.
*
* When the scene transition is in progress and a new Scene Number is stored
* in the Scene Register as a result of Scene Store operation, the Target
* Scene state shall be set to the new Scene Number.
*
* When the scene transition is not in progress, the value of the Target Scene
* state shall be set to 0x0000.
*/
u16_t target_scene;
/* Indicate the status code for the last operation */
u8_t status_code;
/* Indicate if scene transition is in progress */
bool in_progress;
};
struct bt_mesh_scene_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_scenes_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
};
struct bt_mesh_scene_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_scenes_state *state;
};
struct schedule_register {
bool in_use;
u64_t year : 7,
month : 12,
day : 5,
hour : 5,
minute : 6,
second : 6,
day_of_week : 7,
action : 4,
trans_time : 8;
u16_t scene_number;
};
struct bt_mesh_scheduler_state {
const u8_t schedule_count;
struct schedule_register *schedules; /* Up to 16 scheduled entries */
/**
* A recommended implementation of the Scheduler should calculate the
* value of the TAI Seconds of the next scheduled event and put it in
* a queue of scheduled events sorted by time.
*
* Every second, the first event in the queue is compared with the value
* of the Time state. The first event is executed if it is less than or
* equal to the Time state and then removed from the queue. After
* execution, the Repeat Flag shall be checked, and the next occurrence
* of the scheduled event is calculated and put in the queue.
*
* One second timeout value, and compare the first event in queue with the
* Time state. If it is satisfied, then execute the first event. Also the
* Repeat Flag need to be checked, if it is set then the event needs to
* be put into the end of queue.
*
* sys_slist_t event_queue;
*
* For each event_queue item, it can use the following struct:
* struct schedule_event {
* sys_snode_t node;
* u8_t event_index;
* };
*
* Also we need a "struct k_delayed_work track_timer" which can be used to
* track the schedule timer and handle proper scheduled events.
*/
};
struct bt_mesh_scheduler_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_scheduler_state *state;
};
struct bt_mesh_scheduler_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_scheduler_state *state;
};
typedef union {
struct {
u8_t tai_seconds[5];
u8_t subsecond;
u8_t uncertainty;
u16_t time_authority : 1;
u16_t tai_utc_delta_curr : 15;
u8_t time_zone_offset_curr;
} time_set;
struct {
u8_t tai_seconds[5];
u8_t subsecond;
u8_t uncertainty;
u16_t time_authority : 1;
u16_t tai_utc_delta_curr : 15;
u8_t time_zone_offset_curr;
} time_status;
struct {
u8_t time_zone_offset_new;
u8_t tai_zone_change[5];
} time_zone_set;
struct {
u16_t tai_utc_delta_new : 15;
u8_t tai_delta_change[5];
} tai_utc_delta_set;
struct {
u8_t role;
} time_role_set;
struct {
u16_t scene_number;
} scene_store;
struct {
u16_t scene_number;
} scene_recall;
struct {
u16_t scene_number;
} scene_delete;
struct {
u64_t index : 4,
year : 7,
month : 12,
day : 5,
hour : 5,
minute : 6,
second : 6,
day_of_week : 7,
action : 4,
trans_time : 8;
u16_t scene_number;
} scheduler_act_set;
} bt_mesh_time_scene_server_state_change_t;
typedef union {
struct {
u8_t index;
} scheduler_act_get;
} bt_mesh_time_scene_server_recv_get_msg_t;
typedef union {
struct {
u8_t tai_seconds[5];
u8_t subsecond;
u8_t uncertainty;
u16_t time_authority : 1;
u16_t tai_utc_delta : 15;
u8_t time_zone_offset;
} time_set;
struct {
u8_t time_zone_offset_new;
u8_t tai_zone_change[5];
} time_zone_set;
struct {
u16_t tai_utc_delta_new : 15;
u16_t padding : 1;
u8_t tai_delta_change[5];
} tai_utc_delta_set;
struct {
u8_t time_role;
} time_role_set;
struct {
u16_t scene_number;
} scene_store;
struct {
bool op_en;
u16_t scene_number;
u8_t tid;
u8_t trans_time;
u8_t delay;
} scene_recall;
struct {
u16_t scene_number;
} scene_delete;
struct {
u64_t index : 4,
year : 7,
month : 12,
day : 5,
hour : 5,
minute : 6,
second : 6,
day_of_week : 7,
action : 4,
trans_time : 8;
u16_t scene_number;
} scheduler_act_set;
} bt_mesh_time_scene_server_recv_set_msg_t;
typedef union {
struct {
u8_t tai_seconds[5];
u8_t subsecond;
u8_t uncertainty;
u16_t time_authority : 1;
u16_t tai_utc_delta : 15;
u8_t time_zone_offset;
} time_status;
} bt_mesh_time_scene_server_recv_status_msg_t;
void bt_mesh_time_scene_server_lock(void);
void bt_mesh_time_scene_server_unlock(void);
void scene_publish(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, u16_t opcode);
int bt_mesh_time_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_time_setup_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_scene_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_scene_setup_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_scheduler_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_scheduler_setup_srv_init(struct bt_mesh_model *model, bool primary);
#endif /* _TIME_SCENE_SERVER_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,256 @@
// 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 <stdbool.h>
#include "osi/allocator.h"
#include "mesh_types.h"
#include "mesh_kernel.h"
#include "mesh_trace.h"
#include "mesh.h"
#include "access.h"
#include "model_opcode.h"
#include "server_common.h"
#include "state_binding.h"
#include "state_transition.h"
/**
* According to Mesh Model Spec:
* If the Transition Time field is not present and the Generic Default Transition
* Time state is supported, the Generic Default Transition Time state shall be
* used. Otherwise the transition shall be instantaneous.
*/
#define INSTANTANEOUS_TRANS_TIME 0
u8_t bt_mesh_get_default_trans_time(struct bt_mesh_model *model)
{
/**
* 1. If a Generic Default Transition Time Server model is present on the
* main element of the model, that model instance shall be used.
* 2. If a Generic Default Transition Time Server model is not present on
* the main element of the model, then the Generic Default Transition
* Time Server model instance that is present on the element with the
* largest address that is smaller than the address of the main element
* of the node shall be used; if no model instance is present on any
* element with an address smaller than the address of the main element,
* then the Generic Default Transition Time Server is not supported.
*/
struct bt_mesh_elem *element = bt_mesh_model_elem(model);
struct bt_mesh_gen_def_trans_time_srv *state = NULL;
u16_t primary_addr = bt_mesh_primary_addr();
struct bt_mesh_model *srv = NULL;
for (u16_t addr = element->addr; addr >= primary_addr; addr--) {
element = bt_mesh_elem_find(addr);
if (element) {
srv = bt_mesh_model_find(element, BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV);
if (srv) {
state = (struct bt_mesh_gen_def_trans_time_srv *)srv->user_data;
if (state) {
return state->state.trans_time;
}
}
}
}
return INSTANTANEOUS_TRANS_TIME;
}
int bt_mesh_get_light_lc_trans_time(struct bt_mesh_model *model, u8_t *trans_time)
{
struct bt_mesh_light_lc_srv *srv = NULL;
u32_t value;
if (model == NULL || trans_time == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
if (model->id != BLE_MESH_MODEL_ID_LIGHT_LC_SRV) {
BT_ERR("%s, Not a Light LC Server", __func__);
return -EINVAL;
}
srv = (struct bt_mesh_light_lc_srv *)model->user_data;
if (srv == NULL) {
BT_ERR("%s, Invalid Light LC Server user_data", __func__);
return -EINVAL;
}
/**
* 1. Set transition time to 0x54 for BQB test case MESH/SR/LLC/BV-04-C.
* Light LC Property Set: 0x3C, 0x004E20 -> Light LC Time Run On
* Light LC Property Set: 0x37, 0x004E20 -> Light LC Time Fade On
* Light LC Property Set: 0x39, 0x004E20 -> Light LC Time Fade Standby Manual
*
* 2. Set transition time to 0x0 for BQB test case MESH/SR/LLC/BV-08-C.
*
* TODO: Based on Light LC state and choose property property value as the
* transition time. Currently directly use Light LC Time Run On property value.
* Unit: Millisecond, range: [0, 16777214(0xFFFFFE)]
*/
value = srv->lc->prop_state.time_run_on & 0xFFFFFF;
/**
* Convert value into Default Transition Time state format.
* 0b00: 0 ~ 6.2s, 100 millisecond step resolution
* 0b01: 0 ~ 62s, 1 second step resolution
* 0b10: 0 ~ 620s, 10 seconds step resolution
* 0b11: 0 ~ 620m, 10 minutes step resolution
*/
if (value <= 6200) {
*trans_time = (0 << 6) | (value / 100);
} else if (value <= 62000) {
*trans_time = (1 << 6) | (value / 1000);
} else if (value <= 620000) {
*trans_time = (2 << 6) | (value / 10000);
} else {
*trans_time = (3 << 6) | (value / 600000);
}
return 0;
}
int bt_mesh_server_get_optional(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf,
u8_t *trans_time, u8_t *delay,
bool *optional)
{
if (model == NULL || buf == NULL || trans_time == NULL ||
delay == NULL || optional == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
if (buf->len != 0x00 && buf->len != 0x02) {
BT_ERR("%s, Invalid optional message length %d", __func__, buf->len);
return -EINVAL;
}
/* Currently we only get optional msg info which dst is set to a unicast address */
if (!BLE_MESH_ADDR_IS_UNICAST(ctx->recv_dst)) {
*trans_time = 0U;
*delay = 0U;
*optional = false;
return 0;
}
/* No optional fields are available */
if (buf->len == 0x00) {
if (model->id == BLE_MESH_MODEL_ID_LIGHT_LC_SRV) {
/**
* Both messages(i.e. Light LC OnOff Set/Set Unack) may optionally include
* a Transition Time field indicating the transition time to the target state.
* If the Transition Time is not included, the Light LC Server shall use
* its appropriate transition times defined by the Light LC Property states.
*/
if (bt_mesh_get_light_lc_trans_time(model, trans_time)) {
BT_ERR("%s, Failed to get Light LC transition time", __func__);
return -EIO;
}
} else {
*trans_time = bt_mesh_get_default_trans_time(model);
}
*delay = 0U;
*optional = false;
return 0;
}
/* Optional fields are available */
*trans_time = net_buf_simple_pull_u8(buf);
if ((*trans_time & 0x3F) == 0x3F) {
BT_ERR("%s, Invalid Transaction Number of Steps 0x3F", __func__);
return -EINVAL;
}
*delay = net_buf_simple_pull_u8(buf);
*optional = true;
return 0;
}
void bt_mesh_server_alloc_ctx(struct k_work *work)
{
/**
* This function is used to allocate memory for storing "struct bt_mesh_msg_ctx"
* of the received messages, because some server models will callback the "struct
* bt_mesh_msg_ctx" info to the application layer after a certain delay.
* Here we use the allocated heap memory to store the "struct bt_mesh_msg_ctx".
*/
__ASSERT(work, "%s, Invalid parameter", __func__);
work->_reserved = osi_calloc(sizeof(struct bt_mesh_msg_ctx));
__ASSERT(work->_reserved, "%s, Failed to allocate memory", __func__);
}
bool bt_mesh_is_server_recv_last_msg(struct bt_mesh_last_msg_info *last,
u8_t tid, u16_t src, u16_t dst, s64_t *now)
{
*now = k_uptime_get();
/* Currently we only compare msg info which dst is set to a unicast address */
if (!BLE_MESH_ADDR_IS_UNICAST(dst)) {
return false;
}
if (last->tid == tid && last->src == src && last->dst == dst &&
(*now - last->timestamp <= K_SECONDS(6))) {
return true;
}
return false;
}
void bt_mesh_server_update_last_msg(struct bt_mesh_last_msg_info *last,
u8_t tid, u16_t src, u16_t dst, s64_t *now)
{
/* Currently we only update msg info which dst is set to a unicast address */
if (!BLE_MESH_ADDR_IS_UNICAST(dst)) {
return;
}
last->tid = tid;
last->src = src;
last->dst = dst;
last->timestamp = *now;
return;
}
struct net_buf_simple *bt_mesh_server_get_pub_msg(struct bt_mesh_model *model, u16_t msg_len)
{
struct net_buf_simple *buf = NULL;
if (model == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return NULL;
}
if (model->pub == NULL || model->pub->msg == NULL ||
model->pub->addr == BLE_MESH_ADDR_UNASSIGNED) {
BT_DBG("%s, Model 0x%04x has no publication support", __func__, model->id);
return NULL;
}
buf = model->pub->msg;
if (buf->size < msg_len) {
BT_ERR("%s, Too small publication msg size %d, model 0x%04x",
__func__, buf->size, model->id);
return NULL;
}
return buf;
}

View File

@ -0,0 +1,342 @@
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
*
* Copyright (c) 2018 Vikrant More
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <stdbool.h>
#include "mesh_types.h"
#include "mesh_kernel.h"
#include "mesh_trace.h"
#include "mesh.h"
#include "model_opcode.h"
#include "server_common.h"
#include "state_binding.h"
#include "state_transition.h"
#include "generic_server.h"
#include "lighting_server.h"
#define MINDIFF (2.25e-308)
static float bt_mesh_sqrt(float square)
{
float root, last, diff;
root = square / 3.0;
diff = 1;
if (square <= 0) {
return 0;
}
do {
last = root;
root = (root + square / root) / 2.0;
diff = root - last;
} while (diff > MINDIFF || diff < -MINDIFF);
return root;
}
static s32_t bt_mesh_ceiling(float num)
{
s32_t inum = (s32_t)num;
if (num == (float)inum) {
return inum;
}
return inum + 1;
}
u16_t bt_mesh_convert_lightness_actual_to_linear(u16_t actual)
{
float tmp = ((float) actual / UINT16_MAX);
return bt_mesh_ceiling(UINT16_MAX * tmp * tmp);
}
u16_t bt_mesh_convert_lightness_linear_to_actual(u16_t linear)
{
return (u16_t) (UINT16_MAX * bt_mesh_sqrt(((float) linear / UINT16_MAX)));
}
s16_t bt_mesh_convert_temperature_to_gen_level(u16_t temp, u16_t min, u16_t max)
{
float tmp = (temp - min) * UINT16_MAX / (max - min);
return (s16_t) (tmp + INT16_MIN);
}
u16_t bt_mesh_covert_gen_level_to_temperature(s16_t level, u16_t min, u16_t max)
{
float diff = (float) (max - min) / UINT16_MAX;
u16_t tmp = (u16_t) ((level - INT16_MIN) * diff);
return (u16_t) (min + tmp);
}
s16_t bt_mesh_convert_hue_to_level(u16_t hue)
{
return (s16_t) (hue + INT16_MIN);
}
u16_t bt_mesh_convert_level_to_hue(s16_t level)
{
return (u16_t) (level - INT16_MIN);
}
s16_t bt_mesh_convert_saturation_to_level(u16_t saturation)
{
return (s16_t) (saturation + INT16_MIN);
}
u16_t bt_mesh_convert_level_to_saturation(s16_t level)
{
return (u16_t) (level - INT16_MIN);
}
int bt_mesh_update_binding_state(struct bt_mesh_model *model,
bt_mesh_server_state_type_t type,
bt_mesh_server_state_value_t *value)
{
if (model == NULL || model->user_data == NULL ||
value == NULL || type > BIND_STATE_MAX) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
switch (type) {
case GENERIC_ONOFF_STATE: {
if (model->id != BLE_MESH_MODEL_ID_GEN_ONOFF_SRV) {
BT_ERR("%s, Not a Generic OnOff Server Model, id 0x%04x", __func__, model->id);
return -EINVAL;
}
struct bt_mesh_gen_onoff_srv *srv = model->user_data;
bt_mesh_server_stop_transition(&srv->transition);
srv->state.onoff = value->gen_onoff.onoff;
gen_onoff_publish(model);
break;
}
case GENERIC_LEVEL_STATE: {
if (model->id != BLE_MESH_MODEL_ID_GEN_LEVEL_SRV) {
BT_ERR("%s, Not a Generic Level Server Model, id 0x%04x", __func__, model->id);
return -EINVAL;
}
struct bt_mesh_gen_level_srv *srv = model->user_data;
bt_mesh_server_stop_transition(&srv->transition);
srv->state.level = value->gen_level.level;
gen_level_publish(model);
break;
}
case GENERIC_ONPOWERUP_STATE: {
if (model->id != BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV) {
BT_ERR("%s, Not a Generic Power OnOff Server Model, id 0x%04x", __func__, model->id);
return -EINVAL;
}
struct bt_mesh_gen_power_onoff_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("%s, Invalid Generic Power OnOff Server state", __func__);
return -EINVAL;
}
srv->state->onpowerup = value->gen_onpowerup.onpowerup;
gen_onpowerup_publish(model);
break;
}
case GENERIC_POWER_ACTUAL_STATE: {
if (model->id != BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV) {
BT_ERR("%s, Not a Generic Power Level Server Model, id 0x%04x", __func__, model->id);
return -EINVAL;
}
struct bt_mesh_gen_power_level_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("%s, Invalid Generic Power Level Server state", __func__);
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->power_actual = value->gen_power_actual.power;
/**
* Whenever the Generic Power Actual state is changed to a non-zero value
* as a result of a non-transactional message or a completed sequence of
* transactional messages, the value of the Generic Power Last state shall
* be set to the value of the Generic Power Actual state.
*/
if (srv->state->power_actual) {
srv->state->power_last = srv->state->power_actual;
}
gen_power_level_publish(model, BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS);
break;
}
case LIGHT_LIGHTNESS_ACTUAL_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV) {
BT_ERR("%s, Not a Light Lightness Server Model, id 0x%04x", __func__, model->id);
return -EINVAL;
}
struct bt_mesh_light_lightness_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("%s, Invalid Light Lightness Server state", __func__);
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->actual_transition);
srv->state->lightness_actual = value->light_lightness_actual.lightness;
light_lightness_publish(model, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
break;
}
case LIGHT_LIGHTNESS_LINEAR_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV) {
BT_ERR("%s, Not a Light Lightness Server Model, id 0x%04x", __func__, model->id);
return -EINVAL;
}
struct bt_mesh_light_lightness_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("%s, Invalid Light Lightness Server state", __func__);
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->linear_transition);
srv->state->lightness_linear = value->light_lightness_linear.lightness;
light_lightness_publish(model, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
break;
}
case LIGHT_CTL_LIGHTNESS_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_CTL_SRV) {
BT_ERR("%s, Not a Light CTL Server Model, id 0x%04x", __func__, model->id);
return -EINVAL;
}
struct bt_mesh_light_ctl_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("%s, Invalid Light CTL Server state", __func__);
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->lightness = value->light_ctl_lightness.lightness;
light_ctl_publish(model, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
break;
}
case LIGHT_CTL_TEMP_DELTA_UV_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV) {
BT_ERR("%s, Not a Light CTL Temperature Server Model, id 0x%04x", __func__, model->id);
return -EINVAL;
}
struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("%s, Invalid Light CTL Temperature Server state", __func__);
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->temperature = value->light_ctl_temp_delta_uv.temperature;
srv->state->delta_uv = value->light_ctl_temp_delta_uv.delta_uv;
light_ctl_publish(model, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
break;
}
case LIGHT_HSL_LIGHTNESS_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_HSL_SRV) {
BT_ERR("%s, Not a Light HSL Server Model, id 0x%04x", __func__, model->id);
return -EINVAL;
}
struct bt_mesh_light_hsl_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("%s, Invalid Light HSL Server state", __func__);
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->lightness = value->light_hsl_lightness.lightness;
light_hsl_publish(model, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
break;
}
case LIGHT_HSL_HUE_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV) {
BT_ERR("%s, Not a Light HSL Hue Server Model, id 0x%04x", __func__, model->id);
return -EINVAL;
}
struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("%s, Invalid Light HSL Hue Server state", __func__);
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->hue = value->light_hsl_hue.hue;
light_hsl_publish(model, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
break;
}
case LIGHT_HSL_SATURATION_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV) {
BT_ERR("%s, Not a Light HSL Saturation Server Model, id 0x%04x", __func__, model->id);
return -EINVAL;
}
struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("%s, Invalid Light HSL Saturation Server state", __func__);
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->saturation = value->light_hsl_saturation.saturation;
light_hsl_publish(model, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
break;
}
case LIGHT_XYL_LIGHTNESS_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_XYL_SRV) {
BT_ERR("%s, Not a Light xyL Server Model, id 0x%04x", __func__, model->id);
return -EINVAL;
}
struct bt_mesh_light_xyl_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("%s, Invalid Light xyL Server state", __func__);
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->lightness = value->light_xyl_lightness.lightness;
light_xyl_publish(model, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
break;
}
case LIGHT_LC_LIGHT_ONOFF_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_LC_SRV) {
BT_ERR("%s, Not a Light LC Server Model, id 0x%04x", __func__, model->id);
return -EINVAL;
}
struct bt_mesh_light_lc_srv *srv = model->user_data;
if (srv->lc == NULL) {
BT_ERR("%s, Invalid Light LC Server state", __func__);
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->lc->state.light_onoff = value->light_lc_light_onoff.onoff;
light_lc_publish(model, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
break;
}
default:
BT_WARN("%s, Unknown binding state type 0x%02x", __func__, type);
return -EINVAL;
}
return 0;
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More