mesh: rework setup and send of upper transport control pdus

This commit is contained in:
Matthias Ringwald 2020-04-03 12:28:47 +02:00
parent 734bae6528
commit 4802c66d6b
4 changed files with 28 additions and 47 deletions

View File

@ -1744,7 +1744,7 @@ static void config_heartbeat_publication_emit(mesh_heartbeat_publication_t * mes
uint8_t data[3];
data[0] = mesh_heartbeat_publication->ttl;
big_endian_store_16(data, 1, mesh_heartbeat_publication->active_features);
uint8_t status = mesh_upper_transport_setup_control_pdu((mesh_pdu_t *) network_pdu, mesh_heartbeat_publication->netkey_index,
uint8_t status = mesh_upper_transport_setup_unsegmented_control_pdu(network_pdu, mesh_heartbeat_publication->netkey_index,
mesh_heartbeat_publication->ttl, mesh_node_get_primary_element_address(), mesh_heartbeat_publication->destination,
MESH_TRANSPORT_OPCODE_HEARTBEAT, data, sizeof(data));
if (status){

View File

@ -1055,10 +1055,11 @@ void mesh_upper_transport_send_control_pdu(mesh_pdu_t * pdu){
mesh_upper_transport_run();
}
static uint8_t mesh_upper_transport_setup_unsegmented_control_pdu(mesh_network_pdu_t * network_pdu, uint16_t netkey_index, uint8_t ttl, uint16_t src, uint16_t dest, uint8_t opcode,
uint8_t mesh_upper_transport_setup_unsegmented_control_pdu(mesh_network_pdu_t * network_pdu, uint16_t netkey_index, uint8_t ttl, uint16_t src, uint16_t dest, uint8_t opcode,
const uint8_t * control_pdu_data, uint16_t control_pdu_len){
if (control_pdu_len > 11) return 1;
btstack_assert(network_pdu != NULL);
btstack_assert(control_pdu_len <= 11);
const mesh_network_key_t * network_key = mesh_network_key_list_get(netkey_index);
if (!network_key) return 1;
@ -1069,15 +1070,13 @@ static uint8_t mesh_upper_transport_setup_unsegmented_control_pdu(mesh_network_p
uint16_t transport_pdu_len = control_pdu_len + 1;
// setup network_pdu
network_pdu->pdu_header.pdu_type = MESH_PDU_TYPE_UPPER_UNSEGMENTED_CONTROL;
mesh_network_setup_pdu(network_pdu, netkey_index, network_key->nid, 1, ttl, 0, src, dest, transport_pdu_data, transport_pdu_len);
return 0;
}
static uint8_t mesh_upper_transport_setup_segmented_control_pdu(mesh_upper_transport_pdu_t * upper_pdu, uint16_t netkey_index, uint8_t ttl, uint16_t src, uint16_t dest, uint8_t opcode,
const uint8_t * control_pdu_data, uint16_t control_pdu_len){
if (control_pdu_len > 256) return 1;
uint8_t mesh_upper_transport_setup_segmented_control_pdu_header(mesh_upper_transport_pdu_t * upper_pdu, uint16_t netkey_index, uint8_t ttl, uint16_t src, uint16_t dest, uint8_t opcode){
const mesh_network_key_t * network_key = mesh_network_key_list_get(netkey_index);
if (!network_key) return 1;
@ -1088,30 +1087,9 @@ static uint8_t mesh_upper_transport_setup_segmented_control_pdu(mesh_upper_trans
upper_pdu->dst = dest;
upper_pdu->netkey_index = netkey_index;
upper_pdu->akf_aid_control = opcode;
// allocate segments
btstack_linked_list_t free_segments = NULL;
bool ok = mesh_segmented_allocate_segments( &free_segments, control_pdu_len);
if (!ok) return 1;
// store control pdu
mesh_segmented_store_payload(control_pdu_data, control_pdu_len, &free_segments, &upper_pdu->segments);
upper_pdu->len = control_pdu_len;
return 0;
}
uint8_t mesh_upper_transport_setup_control_pdu(mesh_pdu_t * pdu, uint16_t netkey_index,
uint8_t ttl, uint16_t src, uint16_t dest, uint8_t opcode, const uint8_t * control_pdu_data, uint16_t control_pdu_len){
switch (pdu->pdu_type){
case MESH_PDU_TYPE_UPPER_UNSEGMENTED_CONTROL:
return mesh_upper_transport_setup_unsegmented_control_pdu((mesh_network_pdu_t *) pdu, netkey_index, ttl, src, dest, opcode, control_pdu_data, control_pdu_len);
case MESH_PDU_TYPE_UPPER_SEGMENTED_CONTROL:
return mesh_upper_transport_setup_segmented_control_pdu((mesh_upper_transport_pdu_t *) pdu, netkey_index, ttl, src, dest, opcode, control_pdu_data, control_pdu_len);
default:
btstack_assert(0);
return 1;
}
}
static uint8_t mesh_upper_transport_setup_upper_access_pdu_header(mesh_upper_transport_pdu_t * upper_pdu, uint16_t netkey_index,
uint16_t appkey_index, uint8_t ttl, uint16_t src, uint16_t dest, uint8_t szmic){

View File

@ -65,28 +65,28 @@ mesh_upper_transport_pdu_t * mesh_upper_transport_message_finalize(mesh_upper_tr
void mesh_upper_transport_init(void);
void mesh_upper_transport_message_processed_by_higher_layer(mesh_pdu_t * pdu);
// Control PDUs
void mesh_upper_transport_register_control_message_handler(void (*callback)(mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu));
uint8_t mesh_upper_transport_setup_control_pdu(mesh_pdu_t * pdu, uint16_t netkey_index,
uint8_t ttl, uint16_t src, uint16_t dest, uint8_t opcode, const uint8_t * control_pdu_data, uint16_t control_pdu_len);
void mesh_upper_transport_send_control_pdu(mesh_pdu_t * pdu);
// Access PDUs
void mesh_upper_transport_register_access_message_handler(void (*callback)(mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu));
void mesh_upper_transport_message_processed_by_higher_layer(mesh_pdu_t * pdu);
void mesh_upper_transport_pdu_free(mesh_pdu_t * pdu);
// Control PDUs: setup and send
uint8_t mesh_upper_transport_setup_unsegmented_control_pdu(mesh_network_pdu_t * network_pdu, uint16_t netkey_index, uint8_t ttl, uint16_t src, uint16_t dest, uint8_t opcode,
const uint8_t * control_pdu_data, uint16_t control_pdu_len);
uint8_t mesh_upper_transport_setup_segmented_control_pdu_header(mesh_upper_transport_pdu_t * upper_pdu, uint16_t netkey_index, uint8_t ttl, uint16_t src, uint16_t dest, uint8_t opcode);
void mesh_upper_transport_send_control_pdu(mesh_pdu_t * pdu);
// Access PDUs: setup and send
uint8_t mesh_upper_transport_setup_access_pdu_header(mesh_pdu_t * pdu, uint16_t netkey_index, uint16_t appkey_index,
uint8_t ttl, uint16_t src, uint16_t dest, uint8_t szmic);
void mesh_upper_transport_send_access_pdu(mesh_pdu_t * pdu);
void mesh_upper_transport_pdu_free(mesh_pdu_t * pdu);
// test
void mesh_upper_transport_dump(void);

View File

@ -498,14 +498,17 @@ void test_send_control_message(uint16_t netkey_index, uint8_t ttl, uint16_t src,
mesh_pdu_t * pdu;
if (transport_pdu_len < 12){
// send as unsegmented control pdu
pdu = (mesh_pdu_t *) mesh_network_pdu_get();
pdu->pdu_type = MESH_PDU_TYPE_UPPER_UNSEGMENTED_CONTROL;
mesh_network_pdu_t * network_pdu = mesh_network_pdu_get();
mesh_upper_transport_setup_unsegmented_control_pdu(network_pdu, netkey_index, ttl, src, dest, opcode, transport_pdu_data+1, transport_pdu_len-1);
pdu = (mesh_pdu_t *) network_pdu;
} else {
// send as segmented control pdu
pdu = (mesh_pdu_t *) &upper_pdu;
upper_pdu.pdu_header.pdu_type = MESH_PDU_TYPE_UPPER_SEGMENTED_CONTROL;
mesh_upper_transport_builder_t builder;
mesh_upper_transport_message_init(&builder, MESH_PDU_TYPE_UPPER_SEGMENTED_CONTROL);
mesh_upper_transport_message_add_data(&builder, transport_pdu_data+1, transport_pdu_len-1);
mesh_upper_transport_pdu_t * upper_pdu = (mesh_upper_transport_pdu_t *) mesh_upper_transport_message_finalize(&builder);
mesh_upper_transport_setup_segmented_control_pdu_header(upper_pdu, netkey_index, ttl, src, dest, opcode);
pdu = (mesh_pdu_t *) upper_pdu;
}
mesh_upper_transport_setup_control_pdu(pdu, netkey_index, ttl, src, dest, opcode, transport_pdu_data+1, transport_pdu_len-1);
mesh_upper_transport_send_control_pdu(pdu);
// check for all network pdus