From e222865b4f5165867bfe4ca1f30ed3516a0a0e26 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Wed, 30 Oct 2019 16:58:20 +0100 Subject: [PATCH] mesh/health_server: implement model publication for current fault state --- src/mesh/mesh.c | 5 +++- src/mesh/mesh_health_server.c | 54 ++++++++++++++++++++++++++--------- src/mesh/mesh_health_server.h | 7 +++++ 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/mesh/mesh.c b/src/mesh/mesh.c index eea909e7d..ad8787511 100644 --- a/src/mesh/mesh.c +++ b/src/mesh/mesh.c @@ -143,6 +143,7 @@ static mesh_model_t mesh_configuration_server_model; static mesh_configuration_server_model_context_t mesh_configuration_server_model_context; // Mandatory Health Server +static mesh_publication_model_t mesh_health_server_publication; static mesh_model_t mesh_health_server_model; static mesh_health_state_t mesh_health_server_model_context; @@ -1179,8 +1180,10 @@ static void mesh_node_setup_default_models(void){ // Config Health Server mesh_health_server_model.model_identifier = mesh_model_get_model_identifier_bluetooth_sig(MESH_SIG_MODEL_ID_HEALTH_SERVER); mesh_health_server_model.model_data = &mesh_health_server_model_context; - mesh_health_server_model.operations = mesh_health_server_get_operations(); + mesh_health_server_model.operations = mesh_health_server_get_operations(); + mesh_health_server_model.publication_model = &mesh_health_server_publication; mesh_element_add_model(mesh_node_get_primary_element(), &mesh_health_server_model); + mesh_health_server_set_publication_model(&mesh_health_server_model, &mesh_health_server_publication); } void mesh_init(void){ diff --git a/src/mesh/mesh_health_server.c b/src/mesh/mesh_health_server.c index 635602b07..91196cc93 100644 --- a/src/mesh/mesh_health_server.c +++ b/src/mesh/mesh_health_server.c @@ -89,41 +89,40 @@ const mesh_access_message_t mesh_foundation_health_attention_status = { static mesh_pdu_t * health_period_status(mesh_model_t * mesh_model){ mesh_health_state_t * state = (mesh_health_state_t *) mesh_model->model_data; // setup message - mesh_transport_pdu_t * transport_pdu = mesh_access_setup_segmented_message(&mesh_foundation_health_period_status, state->fast_period_divisor); + mesh_network_pdu_t * transport_pdu = mesh_access_setup_unsegmented_message(&mesh_foundation_health_period_status, state->fast_period_divisor); return (mesh_pdu_t *) transport_pdu; } static mesh_pdu_t * health_attention_status(void){ // setup message - mesh_transport_pdu_t * transport_pdu = mesh_access_setup_segmented_message(&mesh_foundation_health_attention_status, mesh_attention_timer_get()); + mesh_network_pdu_t * transport_pdu = mesh_access_setup_unsegmented_message(&mesh_foundation_health_attention_status, mesh_attention_timer_get()); return (mesh_pdu_t *) transport_pdu; } // 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); + mesh_network_pdu_t * transport_pdu = mesh_access_network_init(opcode); if (!transport_pdu) return NULL; mesh_health_fault_t * fault = mesh_health_server_fault_for_company_id(mesh_model, company_id); - if (fault != NULL){ - mesh_access_transport_add_uint8(transport_pdu, fault->test_id); - mesh_access_transport_add_uint16(transport_pdu, fault->company_id); + if (fault == NULL){ + // no fault state with company_id found + mesh_access_network_add_uint8(transport_pdu, 0); + mesh_access_network_add_uint16(transport_pdu, company_id); + } else { + mesh_access_network_add_uint8(transport_pdu, fault->test_id); + mesh_access_network_add_uint16(transport_pdu, fault->company_id); int i; if (registered_faults){ for (i = 0; i < fault->num_registered_faults; i++){ - mesh_access_transport_add_uint8(transport_pdu, fault->registered_faults[i]); + mesh_access_network_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]); + mesh_access_network_add_uint8(transport_pdu, fault->current_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; } @@ -345,6 +344,28 @@ static void health_attention_set_unacknowledged_handler(mesh_model_t *mesh_model mesh_access_message_processed(pdu); } +static mesh_pdu_t * mesh_health_server_publish_state_fn(struct mesh_model * mesh_model){ + // iterate over fault states and yield if fault state with current state that has fault registered + mesh_health_state_t * state = (mesh_health_state_t *) mesh_model->model_data; + btstack_linked_list_iterator_t it; + btstack_linked_list_iterator_init(&it, &state->faults); + uint16_t company_id = mesh_node_get_company_id(); + bool active_fault = false; + while (btstack_linked_list_iterator_has_next(&it)){ + mesh_health_fault_t * fault = (mesh_health_fault_t *) btstack_linked_list_iterator_next(&it); + if (fault->num_current_faults > 0){ + active_fault = true; + company_id = fault->company_id; + break; + } + } + // TODO: update fast period + UNUSED(active_fault); + + // create current status + return health_fault_status(mesh_model, MESH_FOUNDATION_OPERATION_HEALTH_CURRENT_STATUS, company_id, false); +} + // Health Message const static mesh_operation_t mesh_health_model_operations[] = { { MESH_FOUNDATION_OPERATION_HEALTH_FAULT_GET, 2, health_fault_get_handler }, @@ -443,3 +464,10 @@ void mesh_health_server_clear_fault(mesh_model_t *mesh_model, uint16_t company_i // TODO: } } + +void mesh_health_server_set_publication_model(mesh_model_t * mesh_model, mesh_publication_model_t * publication_model){ + btstack_assert(mesh_model != NULL); + btstack_assert(publication_model != NULL); + publication_model->publish_state_fn = &mesh_health_server_publish_state_fn; + mesh_model->publication_model = publication_model; +} diff --git a/src/mesh/mesh_health_server.h b/src/mesh/mesh_health_server.h index f2edb979b..dabe2cee7 100644 --- a/src/mesh/mesh_health_server.h +++ b/src/mesh/mesh_health_server.h @@ -56,6 +56,13 @@ const mesh_operation_t * mesh_health_server_get_operations(void); */ void mesh_health_server_register_packet_handler(mesh_model_t *mesh_model, btstack_packet_handler_t events_packet_handler); +/** + * @brief Setup model publication for health state + * @param mesh_model for health server + * @param publication_model + */ +void mesh_health_server_set_publication_model(mesh_model_t * mesh_model, mesh_publication_model_t * publication_model); + /** * @brief Notify health server that test was perfomed */