From eeaf8ec17259404afe65e4956247d506ef528342 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Sun, 29 Mar 2020 22:17:25 +0200 Subject: [PATCH] mesh: introduce finalize function for access and upper transport builders --- src/mesh/mesh_access.c | 24 ++++--- src/mesh/mesh_access.h | 1 + src/mesh/mesh_configuration_server.c | 96 ++++++++++++++++------------ src/mesh/mesh_health_server.c | 21 +++--- src/mesh/mesh_upper_transport.c | 3 + src/mesh/mesh_upper_transport.h | 9 +++ 6 files changed, 94 insertions(+), 60 deletions(-) diff --git a/src/mesh/mesh_access.c b/src/mesh/mesh_access.c index ad68d5bae..176627bfc 100644 --- a/src/mesh/mesh_access.c +++ b/src/mesh/mesh_access.c @@ -622,13 +622,6 @@ bool mesh_access_message_add_data(mesh_upper_transport_pdu_t * pdu, const uint8_ bool ok = mesh_upper_transport_message_add_data(pdu, data, data_len); if (!ok) return false; - // upgrade to segmented if needed - if (pdu->pdu_header.pdu_type == MESH_PDU_TYPE_UPPER_UNSEGMENTED_ACCESS) { - if ((pdu->transmic_len == 8 ) || (pdu->len > 11)){ - pdu->pdu_header.pdu_type = MESH_PDU_TYPE_UPPER_SEGMENTED_ACCESS; - } - } - return true; } @@ -647,7 +640,6 @@ mesh_upper_transport_pdu_t * mesh_access_message_init(uint32_t opcode) { return pdu; } - bool mesh_access_message_add_uint8(mesh_upper_transport_pdu_t * pdu, uint8_t value){ return mesh_access_message_add_data(pdu, &value, 1); } @@ -678,6 +670,17 @@ bool mesh_access_message_add_model_identifier(mesh_upper_transport_pdu_t * pdu, } } +void mesh_access_message_finalize(mesh_upper_transport_pdu_t * pdu){ + // upgrade to segmented if needed + if (pdu->pdu_header.pdu_type == MESH_PDU_TYPE_UPPER_UNSEGMENTED_ACCESS) { + if ((pdu->transmic_len == 8 ) || (pdu->len > 11)){ + pdu->pdu_header.pdu_type = MESH_PDU_TYPE_UPPER_SEGMENTED_ACCESS; + } + } + + mesh_upper_transport_message_finalize(pdu); +} + // access message template mesh_upper_transport_pdu_t * mesh_access_setup_message(const mesh_access_message_t *message_template, ...){ @@ -726,7 +729,10 @@ mesh_upper_transport_pdu_t * mesh_access_setup_message(const mesh_access_message va_end(argptr); - if (ok == false){ + if (ok){ + // finalize + mesh_access_message_finalize(upper_pdu); + } else { // memory alloc failed mesh_upper_transport_pdu_free((mesh_pdu_t *) upper_pdu); upper_pdu = NULL; diff --git a/src/mesh/mesh_access.h b/src/mesh/mesh_access.h index e08432ac2..f8124183f 100644 --- a/src/mesh/mesh_access.h +++ b/src/mesh/mesh_access.h @@ -254,6 +254,7 @@ bool mesh_access_message_add_uint16(mesh_upper_transport_pdu_t * pdu, uint16_t v bool mesh_access_message_add_uint24(mesh_upper_transport_pdu_t * pdu, uint16_t value); bool mesh_access_message_add_uint32(mesh_upper_transport_pdu_t * pdu, uint16_t value); bool mesh_access_message_add_model_identifier(mesh_upper_transport_pdu_t * pdu, uint32_t model_identifier); +void mesh_access_message_finalize(mesh_upper_transport_pdu_t * pdu); // message builder using template mesh_upper_transport_pdu_t * mesh_access_setup_message(const mesh_access_message_t *message_template, ...); diff --git a/src/mesh/mesh_configuration_server.c b/src/mesh/mesh_configuration_server.c index 4a3dc6989..ef8924e91 100644 --- a/src/mesh/mesh_configuration_server.c +++ b/src/mesh/mesh_configuration_server.c @@ -246,22 +246,23 @@ static void config_composition_data_status(uint16_t netkey_index, uint16_t dest) printf("Received Config Composition Data Get -> send Config Composition Data Status\n"); btstack_assert(false); + // TODO: figure out num segments - mesh_upper_transport_pdu_t * transport_pdu = mesh_access_message_init( + mesh_upper_transport_pdu_t * upper_pdu = mesh_access_message_init( MESH_FOUNDATION_OPERATION_COMPOSITION_DATA_STATUS); - if (!transport_pdu) return; + if (!upper_pdu) return; // page 0 - mesh_access_message_add_uint8(transport_pdu, 0); + mesh_access_message_add_uint8(upper_pdu, 0); // CID - mesh_access_message_add_uint16(transport_pdu, mesh_node_get_company_id()); + mesh_access_message_add_uint16(upper_pdu, mesh_node_get_company_id()); // PID - mesh_access_message_add_uint16(transport_pdu, mesh_node_get_product_id()); + mesh_access_message_add_uint16(upper_pdu, mesh_node_get_product_id()); // VID - mesh_access_message_add_uint16(transport_pdu, mesh_node_get_product_version_id()); + mesh_access_message_add_uint16(upper_pdu, mesh_node_get_product_version_id()); // CRPL - number of protection list entries - mesh_access_message_add_uint16(transport_pdu, 1); + mesh_access_message_add_uint16(upper_pdu, 1); // Features - Relay, Proxy, Friend, Lower Power, ... uint16_t features = 0; #ifdef ENABLE_MESH_RELAY @@ -270,7 +271,7 @@ static void config_composition_data_status(uint16_t netkey_index, uint16_t dest) #ifdef ENABLE_MESH_PROXY_SERVER features |= 2; #endif - mesh_access_message_add_uint16(transport_pdu, features); + mesh_access_message_add_uint16(upper_pdu, features); mesh_element_iterator_t element_it; mesh_element_iterator_init(&element_it); @@ -278,32 +279,34 @@ static void config_composition_data_status(uint16_t netkey_index, uint16_t dest) mesh_element_t * element = mesh_element_iterator_next(&element_it); // Loc - mesh_access_message_add_uint16(transport_pdu, element->loc); + mesh_access_message_add_uint16(upper_pdu, element->loc); // NumS - mesh_access_message_add_uint8( transport_pdu, element->models_count_sig); + mesh_access_message_add_uint8(upper_pdu, element->models_count_sig); // NumV - mesh_access_message_add_uint8( transport_pdu, element->models_count_vendor); + mesh_access_message_add_uint8(upper_pdu, element->models_count_vendor); mesh_model_iterator_t model_it; - + // SIG Models mesh_model_iterator_init(&model_it, element); while (mesh_model_iterator_has_next(&model_it)){ mesh_model_t * model = mesh_model_iterator_next(&model_it); if (!mesh_model_is_bluetooth_sig(model->model_identifier)) continue; - mesh_access_message_add_model_identifier(transport_pdu, model->model_identifier); + mesh_access_message_add_model_identifier(upper_pdu, model->model_identifier); } // Vendor Models mesh_model_iterator_init(&model_it, element); while (mesh_model_iterator_has_next(&model_it)){ mesh_model_t * model = mesh_model_iterator_next(&model_it); if (mesh_model_is_bluetooth_sig(model->model_identifier)) continue; - mesh_access_message_add_model_identifier(transport_pdu, model->model_identifier); + mesh_access_message_add_model_identifier(upper_pdu, model->model_identifier); } } - + + mesh_access_message_finalize(upper_pdu ); + // send as segmented access pdu - config_server_send_message(netkey_index, dest, (mesh_pdu_t *) transport_pdu); + config_server_send_message(netkey_index, dest, (mesh_pdu_t *) upper_pdu); } static void config_composition_data_get_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu){ @@ -569,19 +572,21 @@ static void config_netkey_list(mesh_model_t * mesh_model, uint16_t netkey_index, btstack_assert(false); // TODO: find num segments - mesh_upper_transport_pdu_t * transport_pdu = mesh_access_message_init(MESH_FOUNDATION_OPERATION_NETKEY_LIST); - if (!transport_pdu) return; + mesh_upper_transport_pdu_t * upper_pdu = mesh_access_message_init(MESH_FOUNDATION_OPERATION_NETKEY_LIST); + if (!upper_pdu) return; // add list of netkey indexes mesh_network_key_iterator_t it; mesh_network_key_iterator_init(&it); while (mesh_network_key_iterator_has_more(&it)){ mesh_network_key_t * network_key = mesh_network_key_iterator_get_next(&it); - mesh_access_message_add_uint16(transport_pdu, network_key->netkey_index); + mesh_access_message_add_uint16(upper_pdu, network_key->netkey_index); } + mesh_access_message_finalize(upper_pdu ); + // send as segmented access pdu - config_server_send_message(netkey_index, dest, (mesh_pdu_t *) transport_pdu); + config_server_send_message(netkey_index, dest, (mesh_pdu_t *) upper_pdu); } static void config_netkey_add_derived(void * arg){ @@ -809,8 +814,8 @@ static void config_appkey_list(mesh_model_t * mesh_model, uint16_t netkey_index, btstack_assert(false); // TODO: find num segments - mesh_upper_transport_pdu_t * transport_pdu = mesh_access_message_init(MESH_FOUNDATION_OPERATION_APPKEY_LIST); - if (!transport_pdu) return; + mesh_upper_transport_pdu_t * upper_pdu = mesh_access_message_init(MESH_FOUNDATION_OPERATION_APPKEY_LIST); + if (!upper_pdu) return; // check netkey_index is valid mesh_network_key_t * network_key = mesh_network_key_list_get(netkey_index_of_list); @@ -820,19 +825,21 @@ static void config_appkey_list(mesh_model_t * mesh_model, uint16_t netkey_index, } else { status = MESH_FOUNDATION_STATUS_SUCCESS; } - mesh_access_message_add_uint8(transport_pdu, status); - mesh_access_message_add_uint16(transport_pdu, netkey_index_of_list); + mesh_access_message_add_uint8(upper_pdu, status); + mesh_access_message_add_uint16(upper_pdu, netkey_index_of_list); // add list of appkey indexes mesh_transport_key_iterator_t it; mesh_transport_key_iterator_init(&it, netkey_index_of_list); while (mesh_transport_key_iterator_has_more(&it)){ mesh_transport_key_t * transport_key = mesh_transport_key_iterator_get_next(&it); - mesh_access_message_add_uint16(transport_pdu, transport_key->appkey_index); + mesh_access_message_add_uint16(upper_pdu, transport_key->appkey_index); } + mesh_access_message_finalize(upper_pdu ); + // send as segmented access pdu - config_server_send_message(netkey_index, dest, (mesh_pdu_t *) transport_pdu); + config_server_send_message(netkey_index, dest, (mesh_pdu_t *) upper_pdu); } static void config_appkey_add_or_update_aid(void *arg){ @@ -1046,13 +1053,13 @@ static void config_model_subscription_list(mesh_model_t * mesh_model, uint16_t n btstack_assert(false); // TODO: find num segments - mesh_upper_transport_pdu_t * transport_pdu = mesh_access_message_init(opcode); - if (!transport_pdu) return; + mesh_upper_transport_pdu_t * upper_pdu = mesh_access_message_init(opcode); + if (!upper_pdu) return; // setup segmented message - mesh_access_message_add_uint8(transport_pdu, status); - mesh_access_message_add_uint16(transport_pdu, element_address); - mesh_access_message_add_model_identifier(transport_pdu, model_identifier); + mesh_access_message_add_uint8(upper_pdu, status); + mesh_access_message_add_uint16(upper_pdu, element_address); + mesh_access_message_add_model_identifier(upper_pdu, model_identifier); if (target_model != NULL){ uint16_t i; @@ -1064,10 +1071,13 @@ static void config_model_subscription_list(mesh_model_t * mesh_model, uint16_t n if (virtual_address == NULL) continue; address = virtual_address->hash; } - mesh_access_message_add_uint16(transport_pdu, address); + mesh_access_message_add_uint16(upper_pdu, address); } - } - config_server_send_message(netkey_index, dest, (mesh_pdu_t *) transport_pdu); + } + + mesh_access_message_finalize(upper_pdu ); + + config_server_send_message(netkey_index, dest, (mesh_pdu_t *) upper_pdu); } static void config_model_subscription_get_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu){ @@ -1360,15 +1370,15 @@ static void config_model_app_list(mesh_model_t * config_server_model, uint16_t n btstack_assert(false); // TODO: find num segments - mesh_upper_transport_pdu_t * transport_pdu = mesh_access_message_init(opcode); - if (!transport_pdu) return; + mesh_upper_transport_pdu_t * upper_pdu = mesh_access_message_init(opcode); + if (!upper_pdu) return; - mesh_access_message_add_uint8(transport_pdu, status); - mesh_access_message_add_uint16(transport_pdu, element_address); + mesh_access_message_add_uint8(upper_pdu, status); + mesh_access_message_add_uint16(upper_pdu, element_address); if (mesh_model_is_bluetooth_sig(model_identifier)) { - mesh_access_message_add_uint16(transport_pdu, mesh_model_get_model_id(model_identifier)); + mesh_access_message_add_uint16(upper_pdu, mesh_model_get_model_id(model_identifier)); } else { - mesh_access_message_add_uint32(transport_pdu, model_identifier); + mesh_access_message_add_uint32(upper_pdu, model_identifier); } // add list of appkey indexes @@ -1377,12 +1387,14 @@ static void config_model_app_list(mesh_model_t * config_server_model, uint16_t n for (i=0;iappkey_indices[i]; if (appkey_index == MESH_APPKEY_INVALID) continue; - mesh_access_message_add_uint16(transport_pdu, appkey_index); + mesh_access_message_add_uint16(upper_pdu, appkey_index); } } + mesh_access_message_finalize(upper_pdu ); + // send as segmented access pdu - config_server_send_message(netkey_index, dest, (mesh_pdu_t *) transport_pdu); + config_server_send_message(netkey_index, dest, (mesh_pdu_t *) upper_pdu); } static void config_model_app_bind_handler(mesh_model_t *config_server_model, mesh_pdu_t * pdu) { diff --git a/src/mesh/mesh_health_server.c b/src/mesh/mesh_health_server.c index aa26f59aa..6ba48fc06 100644 --- a/src/mesh/mesh_health_server.c +++ b/src/mesh/mesh_health_server.c @@ -120,29 +120,32 @@ static mesh_pdu_t * health_attention_status(void){ // 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_upper_transport_pdu_t * message_pdu = mesh_access_message_init(opcode); - if (!message_pdu) return NULL; + mesh_upper_transport_pdu_t * upper_pdu = mesh_access_message_init(opcode); + if (!upper_pdu) return NULL; mesh_health_fault_t * fault = mesh_health_server_fault_for_company_id(mesh_model, company_id); if (fault == NULL){ // no fault state with company_id found - mesh_access_message_add_uint8(message_pdu, 0); - mesh_access_message_add_uint16(message_pdu, company_id); + mesh_access_message_add_uint8(upper_pdu, 0); + mesh_access_message_add_uint16(upper_pdu, company_id); } else { - mesh_access_message_add_uint8(message_pdu, fault->test_id); - mesh_access_message_add_uint16(message_pdu, fault->company_id); + mesh_access_message_add_uint8(upper_pdu, fault->test_id); + mesh_access_message_add_uint16(upper_pdu, fault->company_id); int i; if (registered_faults){ for (i = 0; i < fault->num_registered_faults; i++){ - mesh_access_message_add_uint8(message_pdu, fault->registered_faults[i]); + mesh_access_message_add_uint8(upper_pdu, fault->registered_faults[i]); } } else { for (i = 0; i < fault->num_current_faults; i++){ - mesh_access_message_add_uint8(message_pdu, fault->current_faults[i]); + mesh_access_message_add_uint8(upper_pdu, fault->current_faults[i]); } } } - return (mesh_pdu_t *) message_pdu; + + mesh_access_message_finalize(upper_pdu ); + + return (mesh_pdu_t *) upper_pdu; } static void health_fault_get_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu){ diff --git a/src/mesh/mesh_upper_transport.c b/src/mesh/mesh_upper_transport.c index 7adcfc4ce..307f9f102 100644 --- a/src/mesh/mesh_upper_transport.c +++ b/src/mesh/mesh_upper_transport.c @@ -1287,3 +1287,6 @@ bool mesh_upper_transport_message_add_uint32(mesh_upper_transport_pdu_t * pdu, u little_endian_store_32(buffer, 0, value); return mesh_upper_transport_message_add_data(pdu, buffer, sizeof(buffer)); } + +void mesh_upper_transport_message_finalize(mesh_upper_transport_pdu_t * pdu){ +} diff --git a/src/mesh/mesh_upper_transport.h b/src/mesh/mesh_upper_transport.h index 74f563b6b..67ba151c4 100644 --- a/src/mesh/mesh_upper_transport.h +++ b/src/mesh/mesh_upper_transport.h @@ -77,6 +77,15 @@ void mesh_upper_transport_send_access_pdu(mesh_pdu_t * pdu); void mesh_upper_transport_pdu_free(mesh_pdu_t * pdu); +// upper transport message builder +mesh_upper_transport_pdu_t * mesh_upper_transport_message_init(mesh_pdu_type_t pdu_type); +bool mesh_upper_transport_message_add_data(mesh_upper_transport_pdu_t * pdu, const uint8_t * data, uint16_t data_len); +bool mesh_upper_transport_message_add_uint8(mesh_upper_transport_pdu_t * pdu, uint8_t value); +bool mesh_upper_transport_message_add_uint16(mesh_upper_transport_pdu_t * pdu, uint16_t value); +bool mesh_upper_transport_message_add_uint24(mesh_upper_transport_pdu_t * pdu, uint16_t value); +bool mesh_upper_transport_message_add_uint32(mesh_upper_transport_pdu_t * pdu, uint16_t value); +void mesh_upper_transport_message_finalize(mesh_upper_transport_pdu_t * pdu); + // test void mesh_upper_transport_dump(void); void mesh_upper_transport_reset(void);