ble_mesh: modify health server model callbacks
This commit is contained in:
parent
729af38346
commit
2511024e44
7 changed files with 436 additions and 250 deletions
|
@ -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_ble_mesh_health_server_args_t arg = {0};
|
||||||
btc_msg_t msg = {0};
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (element == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_HEALTH_SERVER;
|
msg.pid = BTC_PID_HEALTH_SERVER;
|
||||||
msg.act = BTC_BLE_MESH_ACT_HEALTH_SERVER_FAULT_UPDATE;
|
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)
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_health_server_args_t), NULL)
|
||||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
|
|
@ -47,39 +47,123 @@
|
||||||
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_HEALTH_CLI, \
|
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_HEALTH_CLI, \
|
||||||
NULL, NULL, cli_data)
|
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 {
|
typedef struct {
|
||||||
/** Fetch current faults */
|
/** Clear health registered faults. Initialized by the stack. */
|
||||||
int (*fault_get_cur)(esp_ble_mesh_model_t *model, uint8_t *test_id,
|
esp_ble_mesh_cb_t fault_clear;
|
||||||
uint16_t *company_id, uint8_t *faults, uint8_t *fault_count);
|
|
||||||
|
|
||||||
/** Fetch registered faults */
|
/** Run a specific health test. Initialized by the stack. */
|
||||||
int (*fault_get_reg)(esp_ble_mesh_model_t *model, uint16_t company_id,
|
esp_ble_mesh_cb_t fault_test;
|
||||||
uint8_t *test_id, uint8_t *faults, uint8_t *fault_count);
|
|
||||||
|
|
||||||
/** Clear registered faults */
|
/** Health attention on callback. Initialized by the stack. */
|
||||||
int (*fault_clear)(esp_ble_mesh_model_t *model, uint16_t company_id);
|
esp_ble_mesh_cb_t attention_on;
|
||||||
|
|
||||||
/** Run a specific test */
|
/** Health attention off callback. Initialized by the stack. */
|
||||||
int (*fault_test)(esp_ble_mesh_model_t *model, uint8_t test_id, uint16_t company_id);
|
esp_ble_mesh_cb_t attention_off;
|
||||||
|
|
||||||
/** Attention on */
|
|
||||||
void (*attn_on)(esp_ble_mesh_model_t *model);
|
|
||||||
|
|
||||||
/** Attention off */
|
|
||||||
void (*attn_off)(esp_ble_mesh_model_t *model);
|
|
||||||
} esp_ble_mesh_health_srv_cb_t;
|
} 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 {
|
typedef struct {
|
||||||
/** Pointer to Health Server Model */
|
/** Pointer to Health Server Model */
|
||||||
esp_ble_mesh_model_t *model;
|
esp_ble_mesh_model_t *model;
|
||||||
|
|
||||||
/** Optional callback struct */
|
/** Health callback struct */
|
||||||
const esp_ble_mesh_health_srv_cb_t *cb;
|
esp_ble_mesh_health_srv_cb_t health_cb;
|
||||||
|
|
||||||
/** Attention Timer state */
|
/** 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;
|
} esp_ble_mesh_health_srv_t;
|
||||||
|
|
||||||
/** Parameter of Health Fault Get */
|
/** Parameter of Health Fault Get */
|
||||||
|
@ -186,14 +270,54 @@ typedef enum {
|
||||||
ESP_BLE_MESH_HEALTH_CLIENT_EVT_MAX,
|
ESP_BLE_MESH_HEALTH_CLIENT_EVT_MAX,
|
||||||
} esp_ble_mesh_health_client_cb_event_t;
|
} esp_ble_mesh_health_client_cb_event_t;
|
||||||
|
|
||||||
/** Health Server Model callback parameter */
|
/** Parameter of publishing Health Current Status completion event */
|
||||||
typedef struct {
|
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;
|
} esp_ble_mesh_health_server_cb_param_t;
|
||||||
|
|
||||||
/** This enum value is the event of Health Server Model */
|
/** This enum value is the event of Health Server Model */
|
||||||
typedef enum {
|
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_EVT_MAX,
|
||||||
} esp_ble_mesh_health_server_cb_event_t;
|
} 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);
|
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.
|
* @param[in] element: The element to which the Health Server Model belongs.
|
||||||
*
|
*
|
||||||
|
|
|
@ -517,7 +517,7 @@ static void btc_ble_mesh_health_server_copy_req_data(btc_msg_t *msg, void *p_des
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (msg->act) {
|
switch (msg->act) {
|
||||||
case ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMPLETE_EVT:
|
case ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMP_EVT:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -532,7 +532,7 @@ static void btc_ble_mesh_health_server_free_req_data(btc_msg_t *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (msg->act) {
|
switch (msg->act) {
|
||||||
case ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMPLETE_EVT:
|
case ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMP_EVT:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -555,7 +555,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)
|
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;
|
btc_ble_mesh_health_server_args_t *arg = NULL;
|
||||||
|
|
||||||
if (!msg || !msg->arg) {
|
if (!msg || !msg->arg) {
|
||||||
|
@ -567,10 +567,10 @@ void btc_ble_mesh_health_server_call_handler(btc_msg_t *msg)
|
||||||
|
|
||||||
switch (msg->act) {
|
switch (msg->act) {
|
||||||
case BTC_BLE_MESH_ACT_HEALTH_SERVER_FAULT_UPDATE:
|
case BTC_BLE_MESH_ACT_HEALTH_SERVER_FAULT_UPDATE:
|
||||||
health_server_cb.error_code =
|
param.fault_update_comp.element = arg->health_fault_update.element;
|
||||||
bt_mesh_fault_update((struct bt_mesh_elem *)arg->fault_update.element);
|
param.fault_update_comp.error_code =
|
||||||
btc_ble_mesh_health_server_callback(
|
bt_mesh_fault_update((struct bt_mesh_elem *)arg->health_fault_update.element);
|
||||||
&health_server_cb, ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMPLETE_EVT);
|
btc_ble_mesh_health_server_callback(¶m, ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMP_EVT);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -600,3 +600,43 @@ void btc_ble_mesh_health_server_cb_handler(btc_msg_t *msg)
|
||||||
btc_ble_mesh_health_server_free_req_data(msg);
|
btc_ble_mesh_health_server_free_req_data(msg);
|
||||||
return;
|
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(¶m, 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(¶m, 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(¶m, 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(¶m, ESP_BLE_MESH_HEALTH_SERVER_ATTENTION_OFF_EVT);
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "mesh_proxy.h"
|
#include "mesh_proxy.h"
|
||||||
#include "cfg_cli.h"
|
#include "cfg_cli.h"
|
||||||
#include "health_cli.h"
|
#include "health_cli.h"
|
||||||
|
#include "health_srv.h"
|
||||||
|
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "access.h"
|
#include "access.h"
|
||||||
|
@ -975,6 +976,13 @@ static void btc_ble_mesh_model_op_add(esp_ble_mesh_model_t *model)
|
||||||
}
|
}
|
||||||
case BLE_MESH_MODEL_ID_HEALTH_SRV: {
|
case BLE_MESH_MODEL_ID_HEALTH_SRV: {
|
||||||
model->op = (esp_ble_mesh_model_op_t *)bt_mesh_health_srv_op;
|
model->op = (esp_ble_mesh_model_op_t *)bt_mesh_health_srv_op;
|
||||||
|
struct bt_mesh_health_srv *srv = (struct bt_mesh_health_srv *)model->user_data;
|
||||||
|
if (srv) {
|
||||||
|
srv->cb.fault_clear = btc_ble_mesh_health_server_fault_clear;
|
||||||
|
srv->cb.fault_test = btc_ble_mesh_health_server_fault_test;
|
||||||
|
srv->cb.attn_on = btc_ble_mesh_health_server_attention_on;
|
||||||
|
srv->cb.attn_off = btc_ble_mesh_health_server_attention_off;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BLE_MESH_MODEL_ID_HEALTH_CLI: {
|
case BLE_MESH_MODEL_ID_HEALTH_CLI: {
|
||||||
|
|
|
@ -68,7 +68,7 @@ typedef enum {
|
||||||
typedef union {
|
typedef union {
|
||||||
struct ble_mesh_health_server_fault_update_args {
|
struct ble_mesh_health_server_fault_update_args {
|
||||||
esp_ble_mesh_elem_t *element;
|
esp_ble_mesh_elem_t *element;
|
||||||
} fault_update;
|
} health_fault_update;
|
||||||
} btc_ble_mesh_health_server_args_t;
|
} btc_ble_mesh_health_server_args_t;
|
||||||
|
|
||||||
void btc_ble_mesh_health_server_call_handler(btc_msg_t *msg);
|
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_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_ */
|
#endif /* _BTC_BLE_MESH_HEALTH_MODEL_H_ */
|
||||||
|
|
|
@ -27,130 +27,112 @@
|
||||||
#include "foundation.h"
|
#include "foundation.h"
|
||||||
#include "mesh_common.h"
|
#include "mesh_common.h"
|
||||||
|
|
||||||
|
#include "btc_ble_mesh_health_model.h"
|
||||||
|
|
||||||
#define HEALTH_TEST_STANDARD 0x00
|
#define HEALTH_TEST_STANDARD 0x00
|
||||||
|
|
||||||
/* Maximum message length is 384 in BLE Mesh. Here for health fault status,
|
#define HEALTH_NO_FAULT 0x00
|
||||||
* 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
|
|
||||||
|
|
||||||
/* Health Server context of the primary element */
|
/* Health Server context of the primary element */
|
||||||
struct bt_mesh_health_srv *health_srv;
|
struct bt_mesh_health_srv *health_srv;
|
||||||
|
|
||||||
static void health_get_registered(struct bt_mesh_model *mod,
|
/**
|
||||||
u16_t company_id,
|
* When an Element receives a Health Fault Get, or a Health Fault Test, or
|
||||||
struct net_buf_simple *msg)
|
* 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;
|
struct bt_mesh_health_srv *srv = model->user_data;
|
||||||
u8_t *test_id;
|
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) {
|
return count;
|
||||||
BT_ERR("%s, No Health Server context provided", __func__);
|
}
|
||||||
|
|
||||||
|
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;
|
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);
|
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);
|
err = bt_mesh_model_send(model, ctx, msg, NULL, NULL);
|
||||||
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);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
BT_ERR("%s, Failed to get faults (err %d)", __func__, err);
|
BT_ERR("%s, Failed to send Health Fault Status response", __func__);
|
||||||
*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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
bt_mesh_free_buf(msg);
|
||||||
|
return err;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void health_fault_get(struct bt_mesh_model *model,
|
static void health_fault_get(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
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;
|
struct bt_mesh_health_srv *srv = model->user_data;
|
||||||
u16_t company_id;
|
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);
|
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);
|
BT_DBG("company_id 0x%04x", company_id);
|
||||||
|
|
||||||
if (srv->cb && srv->cb->fault_clear) {
|
health_send_fault_status(model, ctx);
|
||||||
srv->cb->fault_clear(model, company_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void health_fault_clear(struct bt_mesh_model *model,
|
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 net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
struct bt_mesh_health_srv *srv = model->user_data;
|
struct bt_mesh_health_srv *srv = model->user_data;
|
||||||
struct net_buf_simple *sdu = NULL;
|
|
||||||
u16_t company_id;
|
u16_t company_id;
|
||||||
|
|
||||||
if (!srv) {
|
if (!srv) {
|
||||||
|
@ -183,49 +166,21 @@ static void health_fault_clear(struct bt_mesh_model *model,
|
||||||
}
|
}
|
||||||
|
|
||||||
company_id = net_buf_simple_pull_le16(buf);
|
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);
|
BT_DBG("company_id 0x%04x", company_id);
|
||||||
|
|
||||||
if (srv->cb && srv->cb->fault_clear) {
|
memset(srv->test.reg_faults, HEALTH_NO_FAULT, ARRAY_SIZE(srv->test.reg_faults));
|
||||||
srv->cb->fault_clear(model, company_id);
|
|
||||||
|
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 (ctx->recv_op == OP_HEALTH_FAULT_CLEAR) {
|
||||||
if (!sdu) {
|
health_send_fault_status(model, ctx);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +189,6 @@ static void health_fault_test(struct bt_mesh_model *model,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
struct bt_mesh_health_srv *srv = model->user_data;
|
struct bt_mesh_health_srv *srv = model->user_data;
|
||||||
struct net_buf_simple *sdu = NULL;
|
|
||||||
u16_t company_id;
|
u16_t company_id;
|
||||||
u8_t test_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);
|
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);
|
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);
|
BT_DBG("test 0x%02x company 0x%04x", test_id, company_id);
|
||||||
|
|
||||||
if (srv->cb && srv->cb->fault_test) {
|
srv->test.prev_test_id = test_id;
|
||||||
int err;
|
|
||||||
|
|
||||||
err = srv->cb->fault_test(model, test_id, company_id);
|
if (srv->cb.fault_test) {
|
||||||
if (err) {
|
srv->cb.fault_test(model, test_id, company_id);
|
||||||
BT_WARN("Running fault test failed with err %d", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sdu = bt_mesh_alloc_buf(MIN(BLE_MESH_TX_SDU_MAX, HEALTH_FAULT_MAX_LEN));
|
if (ctx->recv_op == OP_HEALTH_FAULT_TEST) {
|
||||||
if (!sdu) {
|
health_send_fault_status(model, ctx);
|
||||||
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 send_attention_status(struct bt_mesh_model *model,
|
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_DBG("%u second%s", time, (time == 1U) ? "" : "s");
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, OP_ATTENTION_STATUS);
|
bt_mesh_model_msg_init(&msg, OP_ATTENTION_STATUS);
|
||||||
|
|
||||||
net_buf_simple_add_u8(&msg, time);
|
net_buf_simple_add_u8(&msg, time);
|
||||||
|
|
||||||
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
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);
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
|
@ -329,9 +276,11 @@ static void attention_set(struct bt_mesh_model *model,
|
||||||
{
|
{
|
||||||
BT_DBG("%s", __func__);
|
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);
|
send_attention_status(model, ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_health_period_status(struct bt_mesh_model *model,
|
static void send_health_period_status(struct bt_mesh_model *model,
|
||||||
|
@ -341,7 +290,6 @@ static void send_health_period_status(struct bt_mesh_model *model,
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_STATUS);
|
bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_STATUS);
|
||||||
|
|
||||||
net_buf_simple_add_u8(&msg, model->pub->period_div);
|
net_buf_simple_add_u8(&msg, model->pub->period_div);
|
||||||
|
|
||||||
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
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);
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
|
@ -381,34 +329,64 @@ static void health_period_set(struct bt_mesh_model *model,
|
||||||
{
|
{
|
||||||
BT_DBG("%s", __func__);
|
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);
|
send_health_period_status(model, ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct bt_mesh_model_op bt_mesh_health_srv_op[] = {
|
const struct bt_mesh_model_op bt_mesh_health_srv_op[] = {
|
||||||
{ OP_HEALTH_FAULT_GET, 2, health_fault_get },
|
{ OP_HEALTH_FAULT_GET, 2, health_fault_get },
|
||||||
{ OP_HEALTH_FAULT_CLEAR, 2, health_fault_clear },
|
{ 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, 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_GET, 0, health_period_get },
|
||||||
{ OP_HEALTH_PERIOD_SET, 1, health_period_set },
|
{ 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_GET, 0, attention_get },
|
||||||
{ OP_ATTENTION_SET, 1, attention_set },
|
{ 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,
|
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;
|
size_t count;
|
||||||
|
|
||||||
BT_DBG("%s", __func__);
|
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) {
|
if (count) {
|
||||||
pub->fast_period = 1U;
|
pub->fast_period = 1U;
|
||||||
} else {
|
} 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)
|
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);
|
model = bt_mesh_model_find(elem, BLE_MESH_MODEL_ID_HEALTH_SRV);
|
||||||
if (!mod) {
|
if (!model) {
|
||||||
BT_ERR("%s, Health Server does not exist", __func__);
|
BT_ERR("%s, Health Server does not exist", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mod->pub) {
|
if (!model->pub) {
|
||||||
BT_ERR("%s, Health Server has no publication support", __func__);
|
BT_ERR("%s, Health Server has no publication support", __func__);
|
||||||
return -EIO;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Let periodic publishing, if enabled, take care of sending the
|
/* Let periodic publishing, if enabled, take care of sending the
|
||||||
* Health Current Status.
|
* Health Current Status.
|
||||||
*/
|
*/
|
||||||
if (bt_mesh_model_pub_period_get(mod)) {
|
if (bt_mesh_model_pub_period_get(model)) {
|
||||||
return 0;
|
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)
|
static void attention_off(struct k_work *work)
|
||||||
|
@ -457,17 +435,23 @@ static void attention_off(struct k_work *work)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srv->cb && srv->cb->attn_off) {
|
if (srv->cb.attn_off) {
|
||||||
srv->cb->attn_off(srv->model);
|
srv->cb.attn_off(srv->model);
|
||||||
}
|
}
|
||||||
|
srv->attn_timer_start = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary)
|
int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary)
|
||||||
{
|
{
|
||||||
struct bt_mesh_health_srv *srv = model->user_data;
|
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 (!srv) {
|
||||||
if (!primary) {
|
if (!primary) {
|
||||||
|
/* If Health Server is in the secondary element with NULL user_data. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,6 +459,11 @@ int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary)
|
||||||
return -EINVAL;
|
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) {
|
if (!model->pub) {
|
||||||
BT_ERR("%s, Health Server has no publication support", __func__);
|
BT_ERR("%s, Health Server has no publication support", __func__);
|
||||||
return -EINVAL;
|
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);
|
k_delayed_work_init(&srv->attn_timer, attention_off);
|
||||||
|
|
||||||
srv->model = model;
|
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) {
|
if (primary) {
|
||||||
health_srv = srv;
|
health_srv = srv;
|
||||||
|
@ -514,16 +507,20 @@ void bt_mesh_attention(struct bt_mesh_model *model, u8_t time)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (time) {
|
if (time) {
|
||||||
if (srv->cb && srv->cb->attn_on) {
|
if (srv->cb.attn_on) {
|
||||||
srv->cb->attn_on(model);
|
srv->cb.attn_on(model, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
k_delayed_work_submit(&srv->attn_timer, time * 1000U);
|
k_delayed_work_submit(&srv->attn_timer, time * 1000U);
|
||||||
|
srv->attn_timer_start = true;
|
||||||
} else {
|
} else {
|
||||||
k_delayed_work_cancel(&srv->attn_timer);
|
k_delayed_work_cancel(&srv->attn_timer);
|
||||||
|
|
||||||
if (srv->cb && srv->cb->attn_off) {
|
if (srv->attn_timer_start == true) {
|
||||||
srv->cb->attn_off(model);
|
if (srv->cb.attn_off) {
|
||||||
|
srv->cb.attn_off(model);
|
||||||
|
}
|
||||||
|
srv->attn_timer_start = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,25 +21,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct bt_mesh_health_srv_cb {
|
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 */
|
/* 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 */
|
/* 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);
|
u16_t company_id);
|
||||||
|
|
||||||
/* Attention on */
|
/* Attention on */
|
||||||
void (*attn_on)(struct bt_mesh_model *model);
|
void (*attn_on)(struct bt_mesh_model *model, u8_t time);
|
||||||
|
|
||||||
/* Attention off */
|
/* Attention off */
|
||||||
void (*attn_off)(struct bt_mesh_model *model);
|
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) \
|
#define BLE_MESH_HEALTH_PUB_DEFINE(_name, _max_faults) \
|
||||||
BLE_MESH_MODEL_PUB_DEFINE(_name, NULL, (1 + 3 + (_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 */
|
/** Mesh Health Server Model Context */
|
||||||
struct bt_mesh_health_srv {
|
struct bt_mesh_health_srv {
|
||||||
struct bt_mesh_model *model;
|
struct bt_mesh_model *model;
|
||||||
|
|
||||||
/* Optional callback struct */
|
/* Optional callback struct */
|
||||||
const struct bt_mesh_health_srv_cb *cb;
|
struct bt_mesh_health_srv_cb cb;
|
||||||
|
|
||||||
/* Attention Timer state */
|
/* Attention Timer state */
|
||||||
struct k_delayed_work attn_timer;
|
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[];
|
extern const struct bt_mesh_model_op bt_mesh_health_srv_op[];
|
||||||
|
|
Loading…
Reference in a new issue