diff --git a/source/6LoWPAN/Thread/thread_constants.h b/source/6LoWPAN/Thread/thread_constants.h index 4150f4cc237..971a1fa1c97 100644 --- a/source/6LoWPAN/Thread/thread_constants.h +++ b/source/6LoWPAN/Thread/thread_constants.h @@ -145,6 +145,7 @@ #define THREAD_DEFAULT_KEY_SWITCH_GUARD_TIME 624 // Hours #define THREAD_DEFAULT_KEY_ROTATION 672 // Hours #define THREAD_COMMISSIONER_KEEP_ALIVE_INTERVAL 50000 // Default thread commissioner keep-alive message interval (milliseconds) +#define THREAD_DELAY_JOIN_ENT 50 // Minimum delay for Joiner router before sending joiner entrust (milliseconds) #define THREAD_FAILED_CHILD_TRANSMISSIONS 4 #define THREAD_FAILED_ROUTER_TRANSMISSIONS 4 diff --git a/source/6LoWPAN/Thread/thread_management_server.c b/source/6LoWPAN/Thread/thread_management_server.c index 8a4ae139fd6..5b17d2eca30 100644 --- a/source/6LoWPAN/Thread/thread_management_server.c +++ b/source/6LoWPAN/Thread/thread_management_server.c @@ -100,6 +100,9 @@ typedef struct announce { typedef struct thread_management_server { scan_query_t *scan_ptr; announce_t *announce_ptr; + timeout_t *join_ent_timer; + uint8_t destination_address[16]; + uint8_t one_time_key[16]; uint16_t relay_port_joiner; uint16_t external_commissioner_port; int8_t interface_id; @@ -994,7 +997,6 @@ static int thread_management_server_energy_scan_cb(int8_t service_id, uint8_t so return -1; } - static void thread_announce_timeout_cb(void* arg) { link_configuration_s *linkConfiguration; @@ -1132,6 +1134,9 @@ int thread_management_server_init(int8_t interface_id) this->relay_port_joiner = 0; this->scan_ptr = NULL; this->announce_ptr = NULL; + this->join_ent_timer = NULL; + memset(this->destination_address,0,16); + memset(this->one_time_key,0,16); this->external_commissioner_port = THREAD_COMMISSIONING_PORT; #ifdef HAVE_THREAD_ROUTER @@ -1312,6 +1317,19 @@ static int thread_management_server_entrust_send(thread_management_server_t *thi ns_dyn_mem_free(response_ptr); return 0; } + +static void thread_join_ent_timeout_cb(void *arg) +{ + thread_management_server_t *this = arg; + if(!this || !this->join_ent_timer) { + return; + } + + this->join_ent_timer = NULL; + thread_management_server_entrust_send(this, this->destination_address, this->one_time_key); + return; +} + void joiner_router_recv_commission_msg(void *cb_res) { socket_callback_t *sckt_data = 0; @@ -1412,7 +1430,13 @@ static int thread_management_server_relay_tx_cb(int8_t service_id, uint8_t sourc if (0 < thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_JOINER_ROUTER_KEK, &kek_ptr)) { // KEK present in relay set pairwise key and send entrust tr_debug("Kek received"); - thread_management_server_entrust_send(this, destination_address.address, kek_ptr); + if (this->join_ent_timer) { + eventOS_timeout_cancel(this->join_ent_timer); + thread_management_server_entrust_send(this, this->destination_address, this->one_time_key); + } + memcpy(this->destination_address, destination_address.address, 16); + memcpy(this->one_time_key, kek_ptr, 16); + this->join_ent_timer = eventOS_timeout_ms(thread_join_ent_timeout_cb, THREAD_DELAY_JOIN_ENT, this); } tr_debug("Relay TX sendto addr:%s port:%d, length:%d", trace_ipv6(destination_address.address), port, udp_data_len); thci_trace("joinerrouterJoinerDataRelayedOutbound");