From b30b4f6e7dcc64a06814136269b2ffe754ef91d4 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Wed, 1 Apr 2020 20:48:55 +0200 Subject: [PATCH] mesh: use MESH_TRANSPORT_FLAG_TRANSMIC_64 to store transmic_len in mesh_segmented_pdu --- src/mesh/mesh_lower_transport.c | 15 +++++--- src/mesh/mesh_network.h | 3 +- src/mesh/mesh_upper_transport.c | 61 +++++++++++++++++++-------------- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/mesh/mesh_lower_transport.c b/src/mesh/mesh_lower_transport.c index 7642fbf28..1ec723d3c 100644 --- a/src/mesh/mesh_lower_transport.c +++ b/src/mesh/mesh_lower_transport.c @@ -340,9 +340,10 @@ static mesh_segmented_pdu_t * mesh_lower_transport_incoming_pdu_for_segmented_me pdu->seq = seq_auth; // get akf_aid & transmic - uint8_t * lower_transport_pdu = mesh_network_pdu_data(network_pdu); - pdu->akf_aid_control = lower_transport_pdu[0] & 0x7f; - pdu->transmic_len = lower_transport_pdu[1] & 0x80 ? 8 : 4; + pdu->akf_aid_control = network_pdu->data[9] & 0x7f; + if ((network_pdu->data[10] & 0x80) != 0){ + pdu->flags |= MESH_TRANSPORT_FLAG_TRANSMIC_64; + } // store meta data in new pdu pdu->netkey_index = network_pdu->netkey_index; @@ -386,7 +387,8 @@ static void mesh_lower_transport_incoming_process_segment(mesh_segmented_pdu_t * uint8_t * segment_data = &lower_transport_pdu[4]; #ifdef LOG_LOWER_TRANSPORT - printf("mesh_lower_transport_incoming_process_segment: seq zero %04x, seg_o %02x, seg_n %02x, transmic len: %u\n", seq_zero, seg_o, seg_n, message_pdu->transmic_len * 8); + uint8_t transmic_len = ((message_pdu->flags & MESH_TRANSPORT_FLAG_TRANSMIC_64) != 0) ? 64 : 32; + printf("mesh_lower_transport_incoming_process_segment: seq zero %04x, seg_o %02x, seg_n %02x, transmic len: %u bit\n", seq_zero, seg_o, seg_n, transmic_len); mesh_print_hex("Segment", segment_data, segment_len); #endif @@ -605,12 +607,15 @@ static void mesh_lower_transport_outgoing_setup_segment(mesh_segmented_pdu_t *me } uint16_t seq_zero = message_pdu->seq & 0x01fff; uint8_t seg_n = (message_pdu->len - 1) / max_segment_len; - uint8_t szmic = ((!ctl) && (message_pdu->transmic_len == 8)) ? 1 : 0; // only 1 for access messages with 64 bit TransMIC + uint8_t szmic = ((message_pdu->flags & MESH_TRANSPORT_FLAG_TRANSMIC_64) != 0) ? 1 : 0; uint8_t nid = message_pdu->ivi_nid & 0x7f; uint8_t ttl = message_pdu->ctl_ttl & 0x7f; uint16_t src = message_pdu->src; uint16_t dest = message_pdu->dst; + // only 1 for access messages with 64 bit TransMIC + btstack_assert((szmic == 0) || !ctl); + // current segment. uint16_t seg_offset = seg_o * max_segment_len; diff --git a/src/mesh/mesh_network.h b/src/mesh/mesh_network.h index fc5c39e7a..fbbea9388 100644 --- a/src/mesh/mesh_network.h +++ b/src/mesh/mesh_network.h @@ -108,6 +108,7 @@ typedef struct mesh_network_pdu { #define MESH_TRANSPORT_FLAG_SEQ_RESERVED 1 #define MESH_TRANSPORT_FLAG_CONTROL 2 +#define MESH_TRANSPORT_FLAG_TRANSMIC_64 4 typedef struct { mesh_pdu_t pdu_header; @@ -126,8 +127,6 @@ typedef struct { uint32_t block_ack; // meta data network layer uint16_t netkey_index; - // transmic size - uint8_t transmic_len; // akf - aid for access, opcode for control uint8_t akf_aid_control; // MESH_TRANSPORT_FLAG diff --git a/src/mesh/mesh_upper_transport.c b/src/mesh/mesh_upper_transport.c index 5188994f2..31f8ddfaf 100644 --- a/src/mesh/mesh_upper_transport.c +++ b/src/mesh/mesh_upper_transport.c @@ -516,7 +516,6 @@ static void mesh_upper_transport_send_access_segmented(mesh_upper_transport_pdu_ // copy meta segmented_pdu->len = upper_pdu->len; segmented_pdu->netkey_index = upper_pdu->netkey_index; - segmented_pdu->transmic_len = upper_pdu->transmic_len; segmented_pdu->akf_aid_control = upper_pdu->akf_aid_control; segmented_pdu->flags = upper_pdu->flags; @@ -529,6 +528,17 @@ static void mesh_upper_transport_send_access_segmented(mesh_upper_transport_pdu_ segmented_pdu->src = upper_pdu->src; segmented_pdu->dst = upper_pdu->dst; + switch (upper_pdu->transmic_len){ + case 4: + break; + case 8: + segmented_pdu->flags |= MESH_TRANSPORT_FLAG_TRANSMIC_64; + break; + default: + btstack_assert(false); + break; + } + // queue up upper_pdu->lower_pdu = (mesh_pdu_t *) segmented_pdu; btstack_linked_list_add(&upper_transport_outgoing_active, (btstack_linked_item_t *) upper_pdu); @@ -698,10 +708,11 @@ static void mesh_upper_transport_send_segmented_control_pdu(mesh_upper_transport // copy meta segmented_pdu->len = upper_pdu->len; segmented_pdu->netkey_index = upper_pdu->netkey_index; - segmented_pdu->transmic_len = 0; // no TransMIC for control segmented_pdu->akf_aid_control = upper_pdu->akf_aid_control; segmented_pdu->flags = upper_pdu->flags; + btstack_assert((upper_pdu->flags & MESH_TRANSPORT_FLAG_TRANSMIC_64) == 0); + // setup segmented_pdu header // TODO: use fields in mesh_segmented_pdu_t and setup network header in lower transport segmented_pdu->ivi_nid = upper_pdu->ivi_nid; @@ -726,7 +737,7 @@ static void mesh_upper_transport_run(void){ // get next message mesh_pdu_t * pdu = (mesh_pdu_t *) btstack_linked_list_pop(&upper_transport_incoming); mesh_network_pdu_t * network_pdu; - mesh_segmented_pdu_t * message_pdu; + mesh_segmented_pdu_t * segmented_pdu; switch (pdu->pdu_type){ case MESH_PDU_TYPE_UNSEGMENTED: network_pdu = (mesh_network_pdu_t *) pdu; @@ -781,30 +792,30 @@ static void mesh_upper_transport_run(void){ } break; case MESH_PDU_TYPE_SEGMENTED: - message_pdu = (mesh_segmented_pdu_t *) pdu; - uint8_t ctl = message_pdu->ctl_ttl >> 7; + segmented_pdu = (mesh_segmented_pdu_t *) pdu; + uint8_t ctl = segmented_pdu->ctl_ttl >> 7; if (ctl){ incoming_control_pdu= &incoming_pdu_singleton.control; incoming_control_pdu->pdu_header.pdu_type = MESH_PDU_TYPE_CONTROL; // flatten - mesh_segmented_pdu_flatten(&message_pdu->segments, 8, incoming_control_pdu->data); + mesh_segmented_pdu_flatten(&segmented_pdu->segments, 8, incoming_control_pdu->data); // copy meta data into encrypted pdu buffer incoming_control_pdu->flags = 0; - incoming_control_pdu->len = message_pdu->len; - incoming_control_pdu->netkey_index = message_pdu->netkey_index; - incoming_control_pdu->akf_aid_control = message_pdu->akf_aid_control; - incoming_access_decrypted->ivi_nid = message_pdu->ivi_nid; - incoming_access_decrypted->ctl_ttl = message_pdu->ctl_ttl; - incoming_access_decrypted->seq = message_pdu->seq; - incoming_access_decrypted->src = message_pdu->src; - incoming_access_decrypted->dst = message_pdu->dst; + incoming_control_pdu->len = segmented_pdu->len; + incoming_control_pdu->netkey_index = segmented_pdu->netkey_index; + incoming_control_pdu->akf_aid_control = segmented_pdu->akf_aid_control; + incoming_access_decrypted->ivi_nid = segmented_pdu->ivi_nid; + incoming_access_decrypted->ctl_ttl = segmented_pdu->ctl_ttl; + incoming_access_decrypted->seq = segmented_pdu->seq; + incoming_access_decrypted->src = segmented_pdu->src; + incoming_access_decrypted->dst = segmented_pdu->dst; mesh_print_hex("Assembled payload", incoming_control_pdu->data, incoming_control_pdu->len); // free mesh message - mesh_lower_transport_message_processed_by_higher_layer((mesh_pdu_t *)message_pdu); + mesh_lower_transport_message_processed_by_higher_layer((mesh_pdu_t *)segmented_pdu); btstack_assert(mesh_control_message_handler != NULL); mesh_pdu_t * pdu = (mesh_pdu_t*) incoming_control_pdu; @@ -812,19 +823,19 @@ static void mesh_upper_transport_run(void){ } else { - incoming_access_encrypted = (mesh_pdu_t *) message_pdu; + incoming_access_encrypted = (mesh_pdu_t *) segmented_pdu; incoming_access_decrypted = &incoming_pdu_singleton.access; incoming_access_decrypted->pdu_header.pdu_type = MESH_PDU_TYPE_ACCESS; - incoming_access_decrypted->len = message_pdu->len; - incoming_access_decrypted->netkey_index = message_pdu->netkey_index; - incoming_access_decrypted->transmic_len = message_pdu->transmic_len; - incoming_access_decrypted->akf_aid_control = message_pdu->akf_aid_control; - incoming_access_decrypted->ivi_nid = message_pdu->ivi_nid; - incoming_access_decrypted->ctl_ttl = message_pdu->ctl_ttl; - incoming_access_decrypted->seq = message_pdu->seq; - incoming_access_decrypted->src = message_pdu->src; - incoming_access_decrypted->dst = message_pdu->dst; + incoming_access_decrypted->len = segmented_pdu->len; + incoming_access_decrypted->netkey_index = segmented_pdu->netkey_index; + incoming_access_decrypted->transmic_len = ((segmented_pdu->flags & MESH_TRANSPORT_FLAG_TRANSMIC_64) != 0) ? 8 : 4; + incoming_access_decrypted->akf_aid_control = segmented_pdu->akf_aid_control; + incoming_access_decrypted->ivi_nid = segmented_pdu->ivi_nid; + incoming_access_decrypted->ctl_ttl = segmented_pdu->ctl_ttl; + incoming_access_decrypted->seq = segmented_pdu->seq; + incoming_access_decrypted->src = segmented_pdu->src; + incoming_access_decrypted->dst = segmented_pdu->dst; mesh_upper_transport_process_access_message(); }