static int thread_host_child_update_response_send(protocol_interface_info_entry_t *cur, uint8_t *dst_address, mle_tlv_info_t *challengeTlv, mle_tlv_info_t *requestTlv) { uint16_t len = 150 + 64; uint8_t mode; uint32_t keySequence; uint8_t *ptr; if (!thread_info(cur)) { return -1; } uint16_t bufId = mle_service_msg_allocate(cur->id, len, false, MLE_COMMAND_CHILD_UPDATE_RESPONSE); if (bufId == 0) { return -1; } tr_debug("MLE Child update response"); thread_management_get_current_keysequence(cur->id, &keySequence); mle_service_msg_update_security_params(bufId, 5, 2, keySequence); ptr = mle_service_get_data_pointer(bufId); mode = thread_mode_get_by_interface_ptr(cur); //Write Mode Allways ptr = mle_tlv_write_mode(ptr, mode); //Set SRC ptr = mle_general_write_source_address(ptr, cur); //SET leader data ptr = thread_leader_data_tlv_write(ptr, cur); //Set Addresss TLV if (requestTlv && mle_tlv_requested(requestTlv->dataPtr,requestTlv->tlvLen,MLE_TYPE_ADDRESS_REGISTRATION) && (mode & MLE_FFD_DEV) == 0) { ptr = thread_address_registration_tlv_write(ptr, cur); } if (requestTlv && mle_tlv_requested(requestTlv->dataPtr,requestTlv->tlvLen,MLE_TYPE_TIMEOUT)) { ptr = mle_tlv_write_timeout(ptr, cur->thread_info->host_link_timeout); } if (challengeTlv && challengeTlv->tlvLen) { ptr = mle_tlv_write_response(ptr, challengeTlv->dataPtr, challengeTlv->tlvLen); ptr = mle_general_write_link_layer_framecounter(ptr, cur); //SET MLE Frame Counter ptr = mle_tlv_write_framecounter(ptr, mle_service_security_get_frame_counter(cur->id)); } if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { tr_debug("Buffer overflow at message write"); } mle_service_set_msg_destination_address(bufId, dst_address); mle_service_send_message(bufId); return 0; }
static void nwk_nvm_params_update_cb(nwk_wpan_nvm_api_t *api, bool if_down_call) { uint32_t mac_counter; uint32_t mlme_counter; if (api->params.pan_id == 0xffff) { return; } //Read first current values and compare different to last read opration if (mac_helper_link_frame_counter_read(api->interface->id, &mac_counter) != 0) { return; } mlme_counter = mle_service_security_get_frame_counter(api->interface->id); if (if_down_call) { api->params.mac_security_frame_counter = mac_counter; api->params.mle_securit_counter = mlme_counter; return; } bool push_new_data = false; if (api->params.mac_security_frame_counter < mac_counter) { if (mac_counter - api->params.mac_security_frame_counter > COUNTER_NVM_UPDATE_INCREMENT - 50) { push_new_data = true; api->params.mac_security_frame_counter = mac_counter; } } if (api->params.mle_securit_counter < mlme_counter) { if (mlme_counter - api->params.mle_securit_counter > COUNTER_NVM_UPDATE_INCREMENT - 50) { push_new_data = true; api->params.mle_securit_counter = mlme_counter; } } if (push_new_data) { api->NVM_PUSH(&api->params); } }