mesh: track alloc error in message builder finalize

This commit is contained in:
Matthias Ringwald 2020-03-29 22:33:03 +02:00
parent eeaf8ec172
commit 923523a338
7 changed files with 85 additions and 90 deletions

View File

@ -617,12 +617,8 @@ static int mesh_access_setup_opcode(uint8_t * buffer, uint32_t opcode){
}
// mesh_message_t builder
bool mesh_access_message_add_data(mesh_upper_transport_pdu_t * pdu, const uint8_t * data, uint16_t data_len){
bool ok = mesh_upper_transport_message_add_data(pdu, data, data_len);
if (!ok) return false;
return true;
void mesh_access_message_add_data(mesh_upper_transport_pdu_t * pdu, const uint8_t * data, uint16_t data_len){
mesh_upper_transport_message_add_data(pdu, data, data_len);
}
mesh_upper_transport_pdu_t * mesh_access_message_init(uint32_t opcode) {
@ -632,37 +628,27 @@ mesh_upper_transport_pdu_t * mesh_access_message_init(uint32_t opcode) {
// add opcode
uint8_t opcode_buffer[3];
uint8_t opcode_len = mesh_access_setup_opcode(opcode_buffer, opcode);
bool ok = mesh_access_message_add_data(pdu, opcode_buffer, opcode_len);
if (!ok){
btstack_memory_mesh_upper_transport_pdu_free(pdu);
pdu = NULL;
}
mesh_access_message_add_data(pdu, opcode_buffer, opcode_len);
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);
void mesh_access_message_add_uint8(mesh_upper_transport_pdu_t * pdu, uint8_t value){
mesh_upper_transport_message_add_uint8(pdu, value);
}
bool mesh_access_message_add_uint16(mesh_upper_transport_pdu_t * pdu, uint16_t value){
uint8_t buffer[2];
little_endian_store_16(buffer, 0, value);
return mesh_access_message_add_data(pdu, buffer, sizeof(buffer));
void mesh_access_message_add_uint16(mesh_upper_transport_pdu_t * pdu, uint16_t value){
mesh_upper_transport_message_add_uint16(pdu, value);
}
bool mesh_access_message_add_uint24(mesh_upper_transport_pdu_t * pdu, uint16_t value){
uint8_t buffer[3];
little_endian_store_24(buffer, 0, value);
return mesh_access_message_add_data(pdu, buffer, sizeof(buffer));
void mesh_access_message_add_uint24(mesh_upper_transport_pdu_t * pdu, uint16_t value){
mesh_upper_transport_message_add_uint24(pdu, value);
}
bool mesh_access_message_add_uint32(mesh_upper_transport_pdu_t * pdu, uint16_t value){
uint8_t buffer[4];
little_endian_store_32(buffer, 0, value);
return mesh_access_message_add_data(pdu, buffer, sizeof(buffer));
void mesh_access_message_add_uint32(mesh_upper_transport_pdu_t * pdu, uint16_t value){
mesh_upper_transport_message_add_uint32(pdu, value);
}
bool mesh_access_message_add_model_identifier(mesh_upper_transport_pdu_t * pdu, uint32_t model_identifier){
void mesh_access_message_add_model_identifier(mesh_upper_transport_pdu_t * pdu, uint32_t model_identifier){
if (mesh_model_is_bluetooth_sig(model_identifier)){
return mesh_access_message_add_uint16( pdu, mesh_model_get_model_id(model_identifier) );
} else {
@ -670,7 +656,7 @@ bool mesh_access_message_add_model_identifier(mesh_upper_transport_pdu_t * pdu,
}
}
void mesh_access_message_finalize(mesh_upper_transport_pdu_t * pdu){
bool 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)){
@ -678,7 +664,7 @@ void mesh_access_message_finalize(mesh_upper_transport_pdu_t * pdu){
}
}
mesh_upper_transport_message_finalize(pdu);
return mesh_upper_transport_message_finalize(pdu);
}
// access message template
@ -694,33 +680,29 @@ mesh_upper_transport_pdu_t * mesh_access_setup_message(const mesh_access_message
const char * format = message_template->format;
uint16_t word;
uint32_t longword;
bool ok = true;
while (ok && *format){
while (*format){
switch (*format){
case '1':
word = va_arg(argptr, int); // minimal va_arg is int: 2 bytes on 8+16 bit CPUs
ok = mesh_access_message_add_uint8(upper_pdu, word);
mesh_access_message_add_uint8(upper_pdu, word);
break;
case '2':
word = va_arg(argptr, int); // minimal va_arg is int: 2 bytes on 8+16 bit CPUs
ok = mesh_access_message_add_uint16(upper_pdu, word);
mesh_access_message_add_uint16(upper_pdu, word);
break;
case '3':
longword = va_arg(argptr, uint32_t);
ok = mesh_access_message_add_uint24(upper_pdu, longword);
mesh_access_message_add_uint24(upper_pdu, longword);
break;
case '4':
longword = va_arg(argptr, uint32_t);
ok = mesh_access_message_add_uint32(upper_pdu, longword);
if (ok == false) break;
ok = mesh_access_message_add_uint32(upper_pdu, longword);
mesh_access_message_add_uint32(upper_pdu, longword);
break;
case 'm':
longword = va_arg(argptr, uint32_t);
ok = mesh_access_message_add_model_identifier(upper_pdu, longword);
mesh_access_message_add_model_identifier(upper_pdu, longword);
break;
default:
ok = false;
btstack_assert(false);
break;
}
@ -729,10 +711,9 @@ mesh_upper_transport_pdu_t * mesh_access_setup_message(const mesh_access_message
va_end(argptr);
if (ok){
// finalize
mesh_access_message_finalize(upper_pdu);
} else {
bool ok = mesh_access_message_finalize(upper_pdu);
if (!ok){
// memory alloc failed
mesh_upper_transport_pdu_free((mesh_pdu_t *) upper_pdu);
upper_pdu = NULL;

View File

@ -248,13 +248,13 @@ uint32_t mesh_access_parser_get_vendor_model_identifier(mesh_access_parser_state
uint32_t mesh_access_parser_get_model_identifier(mesh_access_parser_state_t * parser);
mesh_upper_transport_pdu_t * mesh_access_message_init(uint32_t opcode);
bool mesh_access_message_add_data(mesh_upper_transport_pdu_t * pdu, const uint8_t * data, uint16_t data_len);
bool mesh_access_message_add_uint8(mesh_upper_transport_pdu_t * pdu, uint8_t value);
bool mesh_access_message_add_uint16(mesh_upper_transport_pdu_t * pdu, uint16_t value);
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);
void mesh_access_message_add_data(mesh_upper_transport_pdu_t * pdu, const uint8_t * data, uint16_t data_len);
void mesh_access_message_add_uint8(mesh_upper_transport_pdu_t * pdu, uint8_t value);
void mesh_access_message_add_uint16(mesh_upper_transport_pdu_t * pdu, uint16_t value);
void mesh_access_message_add_uint24(mesh_upper_transport_pdu_t * pdu, uint16_t value);
void mesh_access_message_add_uint32(mesh_upper_transport_pdu_t * pdu, uint16_t value);
void mesh_access_message_add_model_identifier(mesh_upper_transport_pdu_t * pdu, uint32_t model_identifier);
bool 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

@ -245,9 +245,6 @@ 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 * upper_pdu = mesh_access_message_init(
MESH_FOUNDATION_OPERATION_COMPOSITION_DATA_STATUS);
if (!upper_pdu) return;
@ -303,7 +300,11 @@ static void config_composition_data_status(uint16_t netkey_index, uint16_t dest)
}
}
mesh_access_message_finalize(upper_pdu );
bool ok = mesh_access_message_finalize(upper_pdu);
if (!ok){
mesh_upper_transport_pdu_free((mesh_pdu_t*) upper_pdu);
return;
}
// send as segmented access pdu
config_server_send_message(netkey_index, dest, (mesh_pdu_t *) upper_pdu);
@ -569,9 +570,6 @@ static void config_netkey_status(mesh_model_t * mesh_model, uint16_t netkey_inde
static void config_netkey_list(mesh_model_t * mesh_model, uint16_t netkey_index, uint16_t dest) {
UNUSED(mesh_model);
btstack_assert(false);
// TODO: find num segments
mesh_upper_transport_pdu_t * upper_pdu = mesh_access_message_init(MESH_FOUNDATION_OPERATION_NETKEY_LIST);
if (!upper_pdu) return;
@ -583,7 +581,11 @@ static void config_netkey_list(mesh_model_t * mesh_model, uint16_t netkey_index,
mesh_access_message_add_uint16(upper_pdu, network_key->netkey_index);
}
mesh_access_message_finalize(upper_pdu );
bool ok = mesh_access_message_finalize(upper_pdu);
if (!ok){
mesh_upper_transport_pdu_free((mesh_pdu_t*) upper_pdu);
return;
}
// send as segmented access pdu
config_server_send_message(netkey_index, dest, (mesh_pdu_t *) upper_pdu);
@ -811,9 +813,6 @@ static void config_appkey_status(mesh_model_t * mesh_model, uint16_t netkey_inde
static void config_appkey_list(mesh_model_t * mesh_model, uint16_t netkey_index, uint16_t dest, uint32_t netkey_index_of_list){
UNUSED(mesh_model);
btstack_assert(false);
// TODO: find num segments
mesh_upper_transport_pdu_t * upper_pdu = mesh_access_message_init(MESH_FOUNDATION_OPERATION_APPKEY_LIST);
if (!upper_pdu) return;
@ -836,7 +835,11 @@ static void config_appkey_list(mesh_model_t * mesh_model, uint16_t netkey_index,
mesh_access_message_add_uint16(upper_pdu, transport_key->appkey_index);
}
mesh_access_message_finalize(upper_pdu );
bool ok = mesh_access_message_finalize(upper_pdu);
if (!ok){
mesh_upper_transport_pdu_free((mesh_pdu_t*) upper_pdu);
return;
}
// send as segmented access pdu
config_server_send_message(netkey_index, dest, (mesh_pdu_t *) upper_pdu);
@ -1050,9 +1053,6 @@ static void config_model_subscription_list(mesh_model_t * mesh_model, uint16_t n
opcode = MESH_FOUNDATION_OPERATION_VENDOR_MODEL_SUBSCRIPTION_LIST;
}
btstack_assert(false);
// TODO: find num segments
mesh_upper_transport_pdu_t * upper_pdu = mesh_access_message_init(opcode);
if (!upper_pdu) return;
@ -1075,7 +1075,11 @@ static void config_model_subscription_list(mesh_model_t * mesh_model, uint16_t n
}
}
mesh_access_message_finalize(upper_pdu );
bool ok = mesh_access_message_finalize(upper_pdu);
if (!ok){
mesh_upper_transport_pdu_free((mesh_pdu_t*) upper_pdu);
return;
}
config_server_send_message(netkey_index, dest, (mesh_pdu_t *) upper_pdu);
}
@ -1367,9 +1371,6 @@ static void config_model_app_list(mesh_model_t * config_server_model, uint16_t n
opcode = MESH_FOUNDATION_OPERATION_VENDOR_MODEL_APP_LIST;
}
btstack_assert(false);
// TODO: find num segments
mesh_upper_transport_pdu_t * upper_pdu = mesh_access_message_init(opcode);
if (!upper_pdu) return;
@ -1391,7 +1392,11 @@ static void config_model_app_list(mesh_model_t * config_server_model, uint16_t n
}
}
mesh_access_message_finalize(upper_pdu );
bool ok = mesh_access_message_finalize(upper_pdu);
if (!ok){
mesh_upper_transport_pdu_free((mesh_pdu_t*) upper_pdu);
return;
}
// send as segmented access pdu
config_server_send_message(netkey_index, dest, (mesh_pdu_t *) upper_pdu);

View File

@ -143,7 +143,11 @@ static mesh_pdu_t * health_fault_status(mesh_model_t * mesh_model, uint32_t opco
}
}
mesh_access_message_finalize(upper_pdu );
bool ok = mesh_access_message_finalize(upper_pdu);
if (!ok){
mesh_upper_transport_pdu_free((mesh_pdu_t*)upper_pdu);
return NULL;
}
return (mesh_pdu_t *) upper_pdu;
}

View File

@ -68,8 +68,8 @@ typedef enum {
} mesh_network_callback_type_t;
typedef enum {
MESH_PDU_TYPE_NETWORK = 0,
MESH_PDU_TYPE_TRANSPORT,
MESH_PDU_TYPE_INVALID,
MESH_PDU_TYPE_NETWORK,
MESH_PDU_TYPE_SEGMENTED,
MESH_PDU_TYPE_UNSEGMENTED,
MESH_PDU_TYPE_ACCESS,

View File

@ -1243,7 +1243,9 @@ mesh_upper_transport_pdu_t * mesh_upper_transport_message_init(mesh_pdu_type_t p
}
bool mesh_upper_transport_message_add_data(mesh_upper_transport_pdu_t * pdu, const uint8_t * data, uint16_t data_len){
void mesh_upper_transport_message_add_data(mesh_upper_transport_pdu_t * pdu, const uint8_t * data, uint16_t data_len){
if (pdu->pdu_header.pdu_type == MESH_PDU_TYPE_INVALID) return;
uint16_t bytes_current_segment = 0;
mesh_network_pdu_t * network_pdu = (mesh_network_pdu_t *) btstack_linked_list_get_last_item(&pdu->segments);
if (network_pdu){
@ -1252,7 +1254,10 @@ bool mesh_upper_transport_message_add_data(mesh_upper_transport_pdu_t * pdu, con
while (data_len > 0){
if (bytes_current_segment == 0){
network_pdu = (mesh_network_pdu_t *) mesh_network_pdu_get();
if (network_pdu == NULL) return false;
if (network_pdu == NULL) {
pdu->pdu_header.pdu_type = MESH_PDU_TYPE_INVALID;
return;
}
btstack_linked_list_add_tail(&pdu->segments, (btstack_linked_item_t *) network_pdu);
bytes_current_segment = MESH_NETWORK_PAYLOAD_MAX;
}
@ -1263,30 +1268,30 @@ bool mesh_upper_transport_message_add_data(mesh_upper_transport_pdu_t * pdu, con
data += bytes_to_copy;
data_len -= bytes_to_copy;
}
return true;
}
bool mesh_upper_transport_message_add_uint8(mesh_upper_transport_pdu_t * pdu, uint8_t value){
return mesh_upper_transport_message_add_data(pdu, &value, 1);
void mesh_upper_transport_message_add_uint8(mesh_upper_transport_pdu_t * pdu, uint8_t value){
mesh_upper_transport_message_add_data(pdu, &value, 1);
}
bool mesh_upper_transport_message_add_uint16(mesh_upper_transport_pdu_t * pdu, uint16_t value){
void mesh_upper_transport_message_add_uint16(mesh_upper_transport_pdu_t * pdu, uint16_t value){
uint8_t buffer[2];
little_endian_store_16(buffer, 0, value);
return mesh_upper_transport_message_add_data(pdu, buffer, sizeof(buffer));
mesh_upper_transport_message_add_data(pdu, buffer, sizeof(buffer));
}
bool mesh_upper_transport_message_add_uint24(mesh_upper_transport_pdu_t * pdu, uint16_t value){
void mesh_upper_transport_message_add_uint24(mesh_upper_transport_pdu_t * pdu, uint16_t value){
uint8_t buffer[3];
little_endian_store_24(buffer, 0, value);
return mesh_upper_transport_message_add_data(pdu, buffer, sizeof(buffer));
mesh_upper_transport_message_add_data(pdu, buffer, sizeof(buffer));
}
bool mesh_upper_transport_message_add_uint32(mesh_upper_transport_pdu_t * pdu, uint16_t value){
void mesh_upper_transport_message_add_uint32(mesh_upper_transport_pdu_t * pdu, uint16_t value){
uint8_t buffer[4];
little_endian_store_32(buffer, 0, value);
return mesh_upper_transport_message_add_data(pdu, buffer, sizeof(buffer));
mesh_upper_transport_message_add_data(pdu, buffer, sizeof(buffer));
}
void mesh_upper_transport_message_finalize(mesh_upper_transport_pdu_t * pdu){
bool mesh_upper_transport_message_finalize(mesh_upper_transport_pdu_t * pdu){
return pdu->pdu_header.pdu_type != MESH_PDU_TYPE_INVALID;
}

View File

@ -79,12 +79,12 @@ 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);
void mesh_upper_transport_message_add_data(mesh_upper_transport_pdu_t * pdu, const uint8_t * data, uint16_t data_len);
void mesh_upper_transport_message_add_uint8(mesh_upper_transport_pdu_t * pdu, uint8_t value);
void mesh_upper_transport_message_add_uint16(mesh_upper_transport_pdu_t * pdu, uint16_t value);
void mesh_upper_transport_message_add_uint24(mesh_upper_transport_pdu_t * pdu, uint16_t value);
void mesh_upper_transport_message_add_uint32(mesh_upper_transport_pdu_t * pdu, uint16_t value);
bool mesh_upper_transport_message_finalize(mesh_upper_transport_pdu_t * pdu);
// test
void mesh_upper_transport_dump(void);