diff --git a/src/mesh/mesh_access.c b/src/mesh/mesh_access.c index 9ae1e104f..bf8300452 100644 --- a/src/mesh/mesh_access.c +++ b/src/mesh/mesh_access.c @@ -74,8 +74,7 @@ static uint8_t mesh_transaction_id_counter = 0; void mesh_access_init(void){ // register with upper transport - mesh_upper_transport_register_access_message_handler(&mesh_access_message_process_handler); - mesh_upper_transport_set_higher_layer_handler(&mesh_access_upper_transport_handler); + mesh_upper_transport_register_access_message_handler(&mesh_access_upper_transport_handler); } void mesh_access_emit_state_update_bool(btstack_packet_handler_t event_handler, uint8_t element_index, uint32_t model_identifier, @@ -308,6 +307,9 @@ static void mesh_access_acknowledged_received(uint16_t rx_src, uint32_t opcode){ static void mesh_access_upper_transport_handler(mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu){ UNUSED(status); switch (callback_type){ + case MESH_TRANSPORT_PDU_RECEIVED: + mesh_access_message_process_handler(pdu); + break; case MESH_TRANSPORT_PDU_SENT: // unacknowledged -> free if (mesh_access_message_ack_opcode(pdu) == MESH_ACCESS_OPCODE_INVALID){ diff --git a/src/mesh/mesh_network.h b/src/mesh/mesh_network.h index a2aa50609..75e0051c1 100644 --- a/src/mesh/mesh_network.h +++ b/src/mesh/mesh_network.h @@ -101,7 +101,7 @@ typedef struct mesh_network_pdu { } mesh_network_pdu_t; #define MESH_TRANSPORT_FLAG_SEQ_RESERVED 1 -#define MESH_TRANSPORT_FLAG_SEGMENTED 2 +#define MESH_TRANSPORT_FLAG_CONTROL 2 typedef struct { mesh_pdu_t pdu_header; diff --git a/src/mesh/mesh_upper_transport.c b/src/mesh/mesh_upper_transport.c index e5162c137..947b747ef 100644 --- a/src/mesh/mesh_upper_transport.c +++ b/src/mesh/mesh_upper_transport.c @@ -98,7 +98,6 @@ static mesh_transport_key_and_virtual_address_iterator_t mesh_transport_key_it; // upper transport callbacks - in access layer static void (*mesh_access_message_handler)( mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu); static void (*mesh_control_message_handler)( mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu); -static void (*higher_layer_handler)( mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu); // incoming unsegmented (network) and segmented (transport) control and access messages static btstack_linked_list_t upper_transport_incoming; @@ -886,6 +885,7 @@ static void mesh_upper_transport_send_unsegmented_control_pdu(mesh_network_pdu_t // wrap into mesh-unsegmented-pdu outgoing_unsegmented_pdu.pdu_header.pdu_type = MESH_PDU_TYPE_UNSEGMENTED; outgoing_unsegmented_pdu.segment = network_pdu; + outgoing_unsegmented_pdu.flags = MESH_TRANSPORT_FLAG_CONTROL; // send mesh_lower_transport_send_pdu((mesh_pdu_t *) &outgoing_unsegmented_pdu); @@ -1016,34 +1016,29 @@ static void mesh_upper_transport_run(void){ (void) btstack_linked_list_pop(&upper_transport_outgoing); - if (mesh_pdu_ctl(pdu)){ - switch (pdu->pdu_type){ - case MESH_PDU_TYPE_NETWORK: - mesh_upper_transport_send_unsegmented_control_pdu((mesh_network_pdu_t *) pdu); - break; - case MESH_PDU_TYPE_SEGMENTED: - btstack_assert(0); - break; - case MESH_PDU_TYPE_TRANSPORT: + mesh_unsegmented_pdu_t * unsegmented_pdu; + mesh_transport_pdu_t * transport_pdu; + + switch (pdu->pdu_type){ + case MESH_PDU_TYPE_NETWORK: + btstack_assert(mesh_pdu_ctl(pdu) != 0); + mesh_upper_transport_send_unsegmented_control_pdu((mesh_network_pdu_t *) pdu); + break; + case MESH_PDU_TYPE_UNSEGMENTED: + unsegmented_pdu = ( mesh_unsegmented_pdu_t *) pdu; + btstack_assert((unsegmented_pdu->flags & MESH_TRANSPORT_FLAG_CONTROL) == 0); + mesh_upper_transport_send_unsegmented_access_pdu(unsegmented_pdu); + break; + case MESH_PDU_TYPE_TRANSPORT: + if (mesh_pdu_ctl(pdu) != 0){ mesh_upper_transport_send_segmented_control_pdu((mesh_transport_pdu_t *) pdu); - break; - default: - break; - } - } else { - switch (pdu->pdu_type){ - case MESH_PDU_TYPE_NETWORK: - btstack_assert(0); - break; - case MESH_PDU_TYPE_UNSEGMENTED: - mesh_upper_transport_send_unsegmented_access_pdu((mesh_unsegmented_pdu_t *) pdu); - break; - case MESH_PDU_TYPE_TRANSPORT: + } else { mesh_upper_transport_send_segmented_access_pdu((mesh_transport_pdu_t *) pdu); - break; - default: - break; - } + } + break; + default: + btstack_assert(false); + break; } } } @@ -1051,8 +1046,8 @@ static void mesh_upper_transport_run(void){ static void mesh_upper_transport_pdu_handler(mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu){ - mesh_transport_pdu_t * transport_pdu; - mesh_network_pdu_t * network_pdu; + mesh_pdu_t * pdu_to_report; + mesh_unsegmented_pdu_t * unsegmented_pdu; switch (callback_type){ case MESH_TRANSPORT_PDU_RECEIVED: mesh_upper_transport_message_received(pdu); @@ -1066,22 +1061,25 @@ static void mesh_upper_transport_pdu_handler(mesh_transport_callback_type_t call mesh_network_pdu_free(network_pdu); } // notify upper layer but use transport pdu - transport_pdu = (mesh_transport_pdu_t *) outgoing_segmented_pdu; + pdu_to_report = (mesh_pdu_t *) outgoing_segmented_pdu; outgoing_segmented_pdu = NULL; - if (higher_layer_handler){ - higher_layer_handler(callback_type, status, (mesh_pdu_t*) transport_pdu); + if (mesh_pdu_ctl(pdu_to_report)){ + mesh_control_message_handler(callback_type, status, pdu_to_report); } else { - mesh_transport_pdu_free(transport_pdu); + mesh_access_message_handler(callback_type, status, pdu_to_report); } break; case MESH_PDU_TYPE_UNSEGMENTED: - // notify upper layer but use network pdu - network_pdu = outgoing_unsegmented_pdu.segment; - outgoing_unsegmented_pdu.segment = NULL; - if (higher_layer_handler){ - higher_layer_handler(callback_type, status, (mesh_pdu_t*) network_pdu); + unsegmented_pdu = (mesh_unsegmented_pdu_t *) pdu; + if (unsegmented_pdu == &outgoing_unsegmented_pdu){ + // notify upper layer but use network pdu (control pdu) + btstack_assert((unsegmented_pdu->flags & MESH_TRANSPORT_FLAG_CONTROL) != 0); + mesh_network_pdu_t * network_pdu = outgoing_unsegmented_pdu.segment; + outgoing_unsegmented_pdu.segment = NULL; + mesh_control_message_handler(callback_type, status, (mesh_pdu_t *) network_pdu); } else { - mesh_network_pdu_free(network_pdu); + btstack_assert((unsegmented_pdu->flags & MESH_TRANSPORT_FLAG_CONTROL) == 0); + mesh_access_message_handler(callback_type, status, pdu); } break; default: @@ -1142,10 +1140,6 @@ void mesh_upper_transport_register_control_message_handler(void (*callback)(mesh mesh_control_message_handler = callback; } -void mesh_upper_transport_set_higher_layer_handler(void (*pdu_handler)( mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu)){ - higher_layer_handler = pdu_handler; -} - void mesh_upper_transport_init(){ mesh_lower_transport_set_higher_layer_handler(&mesh_upper_transport_pdu_handler); } diff --git a/src/mesh/mesh_upper_transport.h b/src/mesh/mesh_upper_transport.h index 86e8fd23c..74f563b6b 100644 --- a/src/mesh/mesh_upper_transport.h +++ b/src/mesh/mesh_upper_transport.h @@ -52,8 +52,6 @@ void mesh_upper_transport_init(void); void mesh_upper_transport_message_processed_by_higher_layer(mesh_pdu_t * pdu); -void mesh_upper_transport_set_higher_layer_handler(void (*pdu_handler)( mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, 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)); diff --git a/test/mesh/mesh_message_test.cpp b/test/mesh/mesh_message_test.cpp index 5df0f31c0..99cf59677 100644 --- a/test/mesh/mesh_message_test.cpp +++ b/test/mesh/mesh_message_test.cpp @@ -109,7 +109,10 @@ uint16_t mesh_pdu_dst(mesh_pdu_t * pdu){ return mesh_transport_dst((mesh_transport_pdu_t*) pdu); case MESH_PDU_TYPE_NETWORK: return mesh_network_dst((mesh_network_pdu_t *) pdu); + case MESH_PDU_TYPE_UNSEGMENTED: + return mesh_network_dst(((mesh_unsegmented_pdu_t *) pdu)->segment); default: + btstack_assert(false); return MESH_ADDRESS_UNSASSIGNED; } } @@ -120,6 +123,7 @@ uint16_t mesh_pdu_ctl(mesh_pdu_t * pdu){ case MESH_PDU_TYPE_NETWORK: return mesh_network_control((mesh_network_pdu_t *) pdu); default: + btstack_assert(false); return 0; } } @@ -259,9 +263,15 @@ static void test_proxy_server_callback_handler(mesh_network_callback_type_t call } static void test_upper_transport_access_message_handler(mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu){ + + // ignore pdu sent + if (callback_type == MESH_TRANSPORT_PDU_SENT) return; + + // process pdu received mesh_access_pdu_t * access_pdu; mesh_network_pdu_t * network_pdu; mesh_segmented_pdu_t * message_pdu; + switch(pdu->pdu_type){ case MESH_PDU_TYPE_ACCESS: access_pdu = (mesh_access_pdu_t *) pdu; @@ -285,6 +295,10 @@ static void test_upper_transport_access_message_handler(mesh_transport_callback_ } static void test_upper_transport_control_message_handler(mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu){ + // ignore pdu sent + if (callback_type == MESH_TRANSPORT_PDU_SENT) return; + + // process pdu received mesh_transport_pdu_t * transport_pdu; mesh_network_pdu_t * network_pdu; mesh_unsegmented_pdu_t * unsegmented_incoming_pdu; @@ -442,6 +456,7 @@ void test_send_access_message(uint16_t netkey_index, uint16_t appkey_index, uin unsegmented_pdu.pdu_header.pdu_type = MESH_PDU_TYPE_UNSEGMENTED; mesh_network_pdu_t * segment = mesh_network_pdu_get(); unsegmented_pdu.segment = segment; + unsegmented_pdu.flags = 0; pdu = (mesh_pdu_t*) &unsegmented_pdu; } else { // send as segmented access pdu