mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-13 04:13:54 +00:00
mesh: split mesh_upper_transport_process_segmented_message_done into control and access variant
This commit is contained in:
parent
84011563af
commit
7667b5d16d
@ -84,6 +84,10 @@ static mesh_transport_pdu_t incoming_transport_pdu_singleton;
|
||||
static mesh_transport_pdu_t * incoming_transport_pdu_raw;
|
||||
static mesh_transport_pdu_t * incoming_transport_pdu_decoded;
|
||||
static mesh_message_pdu_t incoming_message_pdu_singleton;
|
||||
|
||||
static mesh_access_pdu_t incoming_access_pdu_encrypted;
|
||||
static mesh_access_pdu_t incoming_access_pdu_decrypted;
|
||||
|
||||
static uint8_t application_nonce[13];
|
||||
static btstack_crypto_ccm_t ccm;
|
||||
static mesh_transport_key_and_virtual_address_iterator_t mesh_transport_key_it;
|
||||
@ -173,6 +177,11 @@ static void mesh_transport_key_and_virtual_address_iterator_next(mesh_transport_
|
||||
|
||||
// UPPER TRANSPORT
|
||||
|
||||
static uint16_t mesh_access_dst(mesh_access_pdu_t * access_pdu){
|
||||
return big_endian_read_16(access_pdu->network_header, 7);
|
||||
}
|
||||
|
||||
|
||||
// stub lower transport
|
||||
|
||||
static void mesh_upper_transport_dump_pdus(const char *name, btstack_linked_list_t *list){
|
||||
@ -305,17 +314,20 @@ static void mesh_upper_transport_process_unsegmented_message_done(mesh_pdu_t * p
|
||||
mesh_upper_transport_run();
|
||||
}
|
||||
|
||||
static void mesh_upper_transport_process_segmented_message_done(mesh_transport_pdu_t *transport_pdu){
|
||||
static void mesh_upper_transport_process_segmented_access_message_done(mesh_transport_pdu_t *transport_pdu){
|
||||
crypto_active = 0;
|
||||
if (mesh_transport_ctl(transport_pdu)) {
|
||||
btstack_assert(0);
|
||||
} else {
|
||||
mesh_transport_pdu_free(transport_pdu);
|
||||
incoming_transport_pdu_raw = NULL;
|
||||
}
|
||||
btstack_assert(mesh_transport_ctl(transport_pdu) == 0);
|
||||
mesh_transport_pdu_free(transport_pdu);
|
||||
incoming_transport_pdu_raw = NULL;
|
||||
mesh_upper_transport_run();
|
||||
}
|
||||
|
||||
static void mesh_upper_transport_process_segmented_control_message_done(mesh_transport_pdu_t *transport_pdu){
|
||||
crypto_active = 0;
|
||||
btstack_assert(mesh_transport_ctl(transport_pdu) != 0);
|
||||
btstack_assert(0);
|
||||
}
|
||||
|
||||
static void mesh_upper_transport_validate_unsegmented_message_ccm(void * arg){
|
||||
UNUSED(arg);
|
||||
|
||||
@ -393,16 +405,11 @@ static void mesh_upper_transport_validate_segmented_message_ccm(void * arg){
|
||||
}
|
||||
|
||||
// pass to upper layer
|
||||
if (mesh_access_message_handler){
|
||||
mesh_pdu_t * pdu = (mesh_pdu_t*) incoming_transport_pdu_decoded;
|
||||
incoming_network_pdu_decoded = NULL;
|
||||
mesh_access_message_handler(pdu);
|
||||
} else {
|
||||
printf("[!] Unhandled Segmented Access/Control message\n");
|
||||
// done
|
||||
mesh_upper_transport_process_segmented_message_done(incoming_transport_pdu_decoded);
|
||||
}
|
||||
|
||||
btstack_assert(mesh_access_message_handler != NULL);
|
||||
mesh_pdu_t * pdu = (mesh_pdu_t*) incoming_transport_pdu_decoded;
|
||||
incoming_network_pdu_decoded = NULL;
|
||||
mesh_access_message_handler(pdu);
|
||||
|
||||
printf("\n");
|
||||
|
||||
} else {
|
||||
@ -413,7 +420,7 @@ static void mesh_upper_transport_validate_segmented_message_ccm(void * arg){
|
||||
} else {
|
||||
printf("TransMIC does not match device key, done\n");
|
||||
// done
|
||||
mesh_upper_transport_process_segmented_message_done(incoming_transport_pdu_decoded);
|
||||
mesh_upper_transport_process_segmented_access_message_done(incoming_transport_pdu_decoded);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -483,12 +490,13 @@ static void mesh_upper_transport_validate_unsegmented_message(void){
|
||||
}
|
||||
|
||||
static void mesh_upper_transport_validate_segmented_message(void){
|
||||
#if 1
|
||||
uint8_t * upper_transport_pdu_data = incoming_transport_pdu_decoded->data;
|
||||
uint8_t upper_transport_pdu_len = incoming_transport_pdu_decoded->len - incoming_transport_pdu_decoded->transmic_len;
|
||||
|
||||
if (!mesh_transport_key_and_virtual_address_iterator_has_more(&mesh_transport_key_it)){
|
||||
printf("No valid transport key found\n");
|
||||
mesh_upper_transport_process_segmented_message_done(incoming_transport_pdu_decoded);
|
||||
mesh_upper_transport_process_segmented_access_message_done(incoming_transport_pdu_decoded);
|
||||
return;
|
||||
}
|
||||
mesh_transport_key_and_virtual_address_iterator_next(&mesh_transport_key_it);
|
||||
@ -519,6 +527,44 @@ static void mesh_upper_transport_validate_segmented_message(void){
|
||||
} else {
|
||||
mesh_upper_transport_validate_segmented_message_digest(NULL);
|
||||
}
|
||||
#else
|
||||
uint8_t * upper_transport_pdu_data = incoming_access_pdu_encrypted.data;
|
||||
uint8_t upper_transport_pdu_len = incoming_access_pdu_encrypted.len - incoming_access_pdu_encrypted.transmic_len;
|
||||
|
||||
if (!mesh_transport_key_and_virtual_address_iterator_has_more(&mesh_transport_key_it)){
|
||||
printf("No valid transport key found\n");
|
||||
mesh_upper_transport_process_segmented_message_done(&incoming_access_pdu_encrypted);
|
||||
return;
|
||||
}
|
||||
mesh_transport_key_and_virtual_address_iterator_next(&mesh_transport_key_it);
|
||||
const mesh_transport_key_t * message_key = mesh_transport_key_it.key;
|
||||
|
||||
if (message_key->akf){
|
||||
transport_segmented_setup_application_nonce(application_nonce, incoming_transport_pdu_raw);
|
||||
} else {
|
||||
transport_segmented_setup_device_nonce(application_nonce, incoming_transport_pdu_raw);
|
||||
}
|
||||
|
||||
// store application / device key index
|
||||
mesh_print_hex("AppOrDevKey", message_key->key, 16);
|
||||
incoming_transport_pdu_decoded->appkey_index = message_key->appkey_index;
|
||||
|
||||
mesh_print_hex("EncAccessPayload", upper_transport_pdu_data, upper_transport_pdu_len);
|
||||
|
||||
// decrypt ccm
|
||||
crypto_active = 1;
|
||||
uint16_t aad_len = 0;
|
||||
if (mesh_network_address_virtual(mesh_transport_dst(incoming_transport_pdu_decoded))){
|
||||
aad_len = 16;
|
||||
}
|
||||
btstack_crypto_ccm_init(&ccm, message_key->key, application_nonce, upper_transport_pdu_len, aad_len, incoming_transport_pdu_decoded->transmic_len);
|
||||
|
||||
if (aad_len){
|
||||
btstack_crypto_ccm_digest(&ccm, (uint8_t *) mesh_transport_key_it.address->label_uuid, aad_len, &mesh_upper_transport_validate_segmented_message_digest, NULL);
|
||||
} else {
|
||||
mesh_upper_transport_validate_segmented_message_digest(NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void mesh_upper_transport_process_unsegmented_access_message(void){
|
||||
@ -546,6 +592,7 @@ static void mesh_upper_transport_process_unsegmented_access_message(void){
|
||||
}
|
||||
|
||||
static void mesh_upper_transport_process_message(void){
|
||||
#if 1
|
||||
// copy original pdu
|
||||
(void)memcpy(incoming_transport_pdu_decoded, incoming_transport_pdu_raw,
|
||||
sizeof(mesh_transport_pdu_t));
|
||||
@ -564,6 +611,22 @@ static void mesh_upper_transport_process_message(void){
|
||||
mesh_transport_key_and_virtual_address_iterator_init(&mesh_transport_key_it, mesh_transport_dst(incoming_transport_pdu_decoded),
|
||||
incoming_transport_pdu_decoded->netkey_index, akf, aid);
|
||||
mesh_upper_transport_validate_segmented_message();
|
||||
#else
|
||||
uint8_t * upper_transport_pdu = incoming_access_pdu_encrypted.data;
|
||||
uint8_t upper_transport_pdu_len = incoming_access_pdu_encrypted.len - incoming_access_pdu_encrypted.transmic_len;
|
||||
mesh_print_hex("Upper Transport pdu", upper_transport_pdu, upper_transport_pdu_len);
|
||||
|
||||
uint8_t aid = incoming_access_pdu_encrypted.akf_aid_control & 0x3f;
|
||||
uint8_t akf = (incoming_access_pdu_encrypted.akf_aid_control & 0x40) >> 6;
|
||||
|
||||
printf("AKF: %u\n", akf);
|
||||
printf("AID: %02x\n", aid);
|
||||
|
||||
mesh_transport_key_and_virtual_address_iterator_init(&mesh_transport_key_it, mesh_access_dst(&incoming_access_pdu_encrypted),
|
||||
incoming_access_pdu_encrypted.netkey_index, akf, aid);
|
||||
mesh_upper_transport_validate_segmented_message();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void mesh_upper_transport_message_received(mesh_pdu_t * pdu){
|
||||
@ -1034,6 +1097,7 @@ static void mesh_upper_transport_run(void){
|
||||
(void) btstack_linked_list_pop(&upper_transport_incoming);
|
||||
mesh_lower_transport_message_processed_by_higher_layer(pdu);
|
||||
} else {
|
||||
#if 1
|
||||
incoming_transport_pdu_decoded = mesh_transport_pdu_get();
|
||||
if (!incoming_transport_pdu_decoded) return;
|
||||
|
||||
@ -1064,7 +1128,37 @@ static void mesh_upper_transport_run(void){
|
||||
(void)memcpy(transport_pdu->network_header, message_pdu->network_header, 9);
|
||||
|
||||
mesh_print_hex("Assembled payload", transport_pdu->data, transport_pdu->len);
|
||||
#else
|
||||
incoming_access_pdu_encrypted.pdu_header.pdu_type = MESH_PDU_TYPE_ACCESS;
|
||||
|
||||
// flatten segmented message into mesh_transport_pdu_t
|
||||
|
||||
// assemble payload
|
||||
while (message_pdu->segments){
|
||||
mesh_network_pdu_t * segment = (mesh_network_pdu_t *) btstack_linked_list_pop(&message_pdu->segments);
|
||||
// get segment n
|
||||
uint8_t * lower_transport_pdu = mesh_network_pdu_data(segment);
|
||||
uint8_t seg_o = ( big_endian_read_16(lower_transport_pdu, 2) >> 5) & 0x001f;
|
||||
uint8_t * segment_data = &lower_transport_pdu[4];
|
||||
(void)memcpy(&incoming_access_pdu_encrypted.data[seg_o * 12], segment_data, 12);
|
||||
}
|
||||
|
||||
// copy meta data into encrypted pdu buffer
|
||||
incoming_access_pdu_encrypted.len = message_pdu->len;
|
||||
incoming_access_pdu_encrypted.netkey_index = message_pdu->netkey_index;
|
||||
incoming_access_pdu_encrypted.transmic_len = message_pdu->transmic_len;
|
||||
incoming_access_pdu_encrypted.akf_aid_control = message_pdu->akf_aid_control;
|
||||
(void)memcpy(incoming_access_pdu_encrypted.network_header, message_pdu->network_header, 9);
|
||||
|
||||
mesh_print_hex("Assembled payload", incoming_access_pdu_encrypted.data, incoming_access_pdu_encrypted.len);
|
||||
|
||||
// copy meta data into decrypted pdu buffer
|
||||
incoming_access_pdu_decrypted.len = message_pdu->len;
|
||||
incoming_access_pdu_decrypted.netkey_index = message_pdu->netkey_index;
|
||||
incoming_access_pdu_decrypted.transmic_len = message_pdu->transmic_len;
|
||||
incoming_access_pdu_decrypted.akf_aid_control = message_pdu->akf_aid_control;
|
||||
(void)memcpy(incoming_access_pdu_decrypted.network_header, message_pdu->network_header, 9);
|
||||
#endif
|
||||
// free mesh message
|
||||
mesh_lower_transport_message_processed_by_higher_layer((mesh_pdu_t *)message_pdu);
|
||||
|
||||
@ -1146,7 +1240,7 @@ void mesh_upper_transport_message_processed_by_higher_layer(mesh_pdu_t * pdu){
|
||||
crypto_active = 0;
|
||||
switch (pdu->pdu_type){
|
||||
case MESH_PDU_TYPE_TRANSPORT:
|
||||
mesh_upper_transport_process_segmented_message_done((mesh_transport_pdu_t *) pdu);
|
||||
mesh_upper_transport_process_segmented_access_message_done((mesh_transport_pdu_t *) pdu);
|
||||
break;
|
||||
case MESH_PDU_TYPE_MESSAGE:
|
||||
mesh_upper_transport_process_message_done((mesh_message_pdu_t *) pdu);
|
||||
|
Loading…
x
Reference in New Issue
Block a user