mesh/health_server: combine current fault + registered fault into a single { company id, current faults, registered faults } struct

This commit is contained in:
Matthias Ringwald 2019-10-29 18:03:46 +01:00
parent 4439045c0d
commit 63ad364382
2 changed files with 28 additions and 69 deletions

View File

@ -88,7 +88,7 @@ typedef enum {
MODEL_STATE_ID_GENERIC_LEVEL = (BLUETOOTH_COMPANY_ID_BLUETOOTH_SIG_INC << 16) | 1u,
} model_state_id_t;
#define MESH_MAX_NUM_FAULTS 3
#define MESH_MAX_NUM_FAULTS 5
typedef struct {
// linked list item
@ -100,9 +100,19 @@ typedef struct {
} mesh_fault_t;
typedef struct {
btstack_linked_list_t current_faults;
btstack_linked_list_t registered_faults;
// linked list item
btstack_linked_item_t item;
uint8_t test_id;
uint16_t company_id;
uint16_t num_current_faults;
uint16_t num_registered_faults;
uint8_t current_faults[MESH_MAX_NUM_FAULTS];
uint8_t registered_faults[MESH_MAX_NUM_FAULTS];
} mesh_health_fault_t;
typedef struct {
// linked list of mesh_health_fault items
btstack_linked_list_t faults;
uint8_t fast_period_divisor;
} mesh_health_state_t;

View File

@ -87,26 +87,28 @@ static mesh_pdu_t * health_attention_status(void){
return (mesh_pdu_t *) transport_pdu;
}
// dynamic
static mesh_pdu_t * health_current_status(mesh_model_t * mesh_model, uint32_t opcode, uint16_t company_id){
// report fault status - used for both current as well as registered faults, see registered_faults param
static mesh_pdu_t * health_fault_status(mesh_model_t * mesh_model, uint32_t opcode, uint16_t company_id, bool registered_faults){
mesh_transport_pdu_t * transport_pdu = mesh_access_transport_init(opcode);
if (!transport_pdu) return NULL;
mesh_health_state_t * state = (mesh_health_state_t *) mesh_model->model_data;
if (state == NULL){
log_error("health_current_status state == NULL");
}
btstack_linked_list_iterator_t it;
btstack_linked_list_iterator_init(&it, &state->registered_faults);
btstack_linked_list_iterator_init(&it, &state->faults);
while (btstack_linked_list_iterator_has_next(&it)){
mesh_fault_t * fault = (mesh_fault_t *) btstack_linked_list_iterator_next(&it);
mesh_health_fault_t * fault = (mesh_health_fault_t *) btstack_linked_list_iterator_next(&it);
if (fault->company_id != company_id) continue;
mesh_access_transport_add_uint8(transport_pdu, fault->test_id);
mesh_access_transport_add_uint16(transport_pdu, fault->company_id);
int i;
for (i = 0; i < fault->num_faults; i++){
mesh_access_transport_add_uint8(transport_pdu, fault->faults[i]);
if (registered_faults){
for (i = 0; i < fault->num_registered_faults; i++){
mesh_access_transport_add_uint8(transport_pdu, fault->registered_faults[i]);
}
} else {
for (i = 0; i < fault->num_current_faults; i++){
mesh_access_transport_add_uint8(transport_pdu, fault->current_faults[i]);
}
}
return (mesh_pdu_t *) transport_pdu;
}
@ -116,38 +118,12 @@ static mesh_pdu_t * health_current_status(mesh_model_t * mesh_model, uint32_t op
return (mesh_pdu_t *) transport_pdu;
}
// dynamic
static mesh_pdu_t * health_fault_status(btstack_linked_list_t * faults, uint32_t opcode, uint8_t test_id, uint16_t company_id){
mesh_transport_pdu_t * transport_pdu = mesh_access_transport_init(opcode);
if (!transport_pdu) return NULL;
mesh_access_transport_add_uint8(transport_pdu, test_id);
btstack_linked_list_iterator_t it;
btstack_linked_list_iterator_init(&it, faults);
while (btstack_linked_list_iterator_has_next(&it)){
mesh_fault_t * fault = (mesh_fault_t *) btstack_linked_list_iterator_next(&it);
if (fault->company_id != company_id) continue;
mesh_access_transport_add_uint8(transport_pdu, fault->test_id);
mesh_access_transport_add_uint16(transport_pdu, fault->company_id);
int i;
for (i = 0; i < fault->num_faults; i++){
mesh_access_transport_add_uint8(transport_pdu, fault->faults[i]);
}
return (mesh_pdu_t *) transport_pdu;
}
// no company with company_id found
mesh_access_transport_add_uint8(transport_pdu, 0);
mesh_access_transport_add_uint16(transport_pdu, company_id);
return (mesh_pdu_t *) transport_pdu;
}
static void health_fault_get_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu){
mesh_access_parser_state_t parser;
mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu);
uint16_t company_id = mesh_access_parser_get_u16(&parser);
mesh_transport_pdu_t * transport_pdu = (mesh_transport_pdu_t *) health_current_status(mesh_model, MESH_FOUNDATION_OPERATION_HEALTH_FAULT_STATUS, company_id);
mesh_transport_pdu_t * transport_pdu = (mesh_transport_pdu_t *) health_fault_status(mesh_model, MESH_FOUNDATION_OPERATION_HEALTH_FAULT_STATUS, company_id, true);
if (!transport_pdu) return;
health_server_send_message(mesh_access_get_element_address(mesh_model), mesh_pdu_src(pdu), mesh_pdu_netkey_index(pdu), mesh_pdu_appkey_index(pdu),(mesh_pdu_t *) transport_pdu);
mesh_access_message_processed(pdu);
@ -157,32 +133,13 @@ static uint16_t process_message_fault_clear(mesh_model_t *mesh_model, mesh_pdu_t
mesh_access_parser_state_t parser;
mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu);
uint16_t company_id = mesh_access_parser_get_u16(&parser);
mesh_health_state_t * state = (mesh_health_state_t *) mesh_model->model_data;
if (state == NULL){
log_error("health_fault_status state == NULL");
}
uint8_t event[6];
int pos = 0;
event[pos++] = HCI_EVENT_MESH_META;
// reserve for size
pos++;
event[pos++] = MESH_SUBEVENT_HEALTH_CLEAR_REGISTERED_FAULTS;
// element index
event[pos++] = mesh_model->element->element_index;
little_endian_store_16(event, pos, company_id);
pos += 2;
event[1] = pos - 2;
(*mesh_model->model_packet_handler)(HCI_EVENT_PACKET, 0, event, pos);
return company_id;
}
static void health_fault_clear_handler(mesh_model_t * mesh_model, mesh_pdu_t * pdu){
uint16_t company_id = process_message_fault_clear(mesh_model, pdu);
mesh_transport_pdu_t * transport_pdu = (mesh_transport_pdu_t *) health_current_status(mesh_model, MESH_FOUNDATION_OPERATION_HEALTH_FAULT_STATUS, company_id);
mesh_transport_pdu_t * transport_pdu = (mesh_transport_pdu_t *) health_fault_status(mesh_model, MESH_FOUNDATION_OPERATION_HEALTH_FAULT_STATUS, company_id, true);
if (!transport_pdu) return;
health_server_send_message(mesh_access_get_element_address(mesh_model), mesh_pdu_src(pdu), mesh_pdu_netkey_index(pdu), mesh_pdu_appkey_index(pdu),(mesh_pdu_t *) transport_pdu);
mesh_access_message_processed(pdu);
@ -200,10 +157,6 @@ static void health_fault_test_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu
uint8_t test_id = mesh_access_parser_get_u8(&parser);
uint16_t company_id = mesh_access_parser_get_u16(&parser);
mesh_health_state_t * state = (mesh_health_state_t *) mesh_model->model_data;
if (state == NULL){
log_error("mesh_health_state == NULL");
}
processed_pdu = pdu;
uint8_t event[17];
@ -239,8 +192,7 @@ void mesh_health_server_report_test_done(uint16_t element_index, uint16_t dest,
mesh_model_t * mesh_model = mesh_model_get_by_identifier(element, mesh_model_get_model_identifier_bluetooth_sig(MESH_SIG_MODEL_ID_HEALTH_SERVER));
if (mesh_model == NULL) return;
mesh_health_state_t * state = (mesh_health_state_t *) mesh_model->model_data;
mesh_transport_pdu_t * transport_pdu = (mesh_transport_pdu_t *) health_fault_status(&state->registered_faults, MESH_FOUNDATION_OPERATION_HEALTH_FAULT_STATUS, test_id, company_id);
mesh_transport_pdu_t * transport_pdu = (mesh_transport_pdu_t *) health_fault_status(mesh_model, MESH_FOUNDATION_OPERATION_HEALTH_FAULT_STATUS, test_id, company_id);
if (!transport_pdu) return;
health_server_send_message(element_index, dest, netkey_index, appkey_index, (mesh_pdu_t *) transport_pdu);
mesh_access_message_processed(processed_pdu);
@ -264,9 +216,6 @@ static void process_message_period_set(mesh_model_t *mesh_model, mesh_pdu_t * pd
uint8_t fast_period_divisor = mesh_access_parser_get_u8(&parser);
mesh_health_state_t * state = (mesh_health_state_t *) mesh_model->model_data;
if (state == NULL){
log_error("health_fault_status state == NULL");
}
if (state->fast_period_divisor != fast_period_divisor){
state->fast_period_divisor = fast_period_divisor;