mesh: introduce finalize function for access and upper transport builders

This commit is contained in:
Matthias Ringwald 2020-03-29 22:17:25 +02:00
parent d8b26ece66
commit eeaf8ec172
6 changed files with 94 additions and 60 deletions

View File

@ -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;

View File

@ -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, ...);

View File

@ -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;i<MAX_NR_MESH_APPKEYS_PER_MODEL;i++){
uint16_t appkey_index = mesh_model->appkey_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) {

View File

@ -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){

View File

@ -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){
}

View File

@ -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);