int thread_management_get_current_keysequence(int8_t interface_id, uint32_t *sequencePtr)
{

    link_configuration_s *linkConfiguration;
    linkConfiguration = thread_joiner_application_get_config(interface_id);
    if (!linkConfiguration) {
        return -1;
    }
    protocol_interface_info_entry_t *cur;
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur) {
        return -1;
    }

    if (!cur->thread_info) {
        return -1;
    }

    if (!cur->thread_info->masterSecretMaterial.valid_Info) {
        return -1;
    }

    *sequencePtr = linkConfiguration->key_sequence;

    return 0;
}
/**
 * Thread key sequence & key synch
 *
 */
void thread_management_key_synch_req(int8_t interface_id, uint32_t keySequnce)
{
    protocol_interface_info_entry_t *cur;
    link_configuration_s *linkConfiguration;
    linkConfiguration = thread_joiner_application_get_config(interface_id);
    if (!linkConfiguration) {
        return;
    }
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur || !cur->thread_info) {
        return;
    }
    if (!cur->thread_info->masterSecretMaterial.valid_Info) {
        return;
    }
    //tr_debug("Sync key material by %"PRIu32, keySequnce);

    if (keySequnce <= linkConfiguration->key_sequence) {
        // Smaller or equal request ignored
        //tr_debug("Sync key material no change");
        return;
    }
    if ((cur->thread_info->masterSecretMaterial.keySwitchGuardTimer > 0)) {
        // Guard time prevent the change
        //tr_debug("Sync key material guard blocked");
        return;
    }
    // Calculate new keys
    tr_debug("Sync key material by %"PRIu32, keySequnce);
    thread_management_key_sets_calc(cur, linkConfiguration, keySequnce);
    thread_key_guard_timer_calculate(cur, linkConfiguration, false);
}
link_configuration_s *thread_management_configuration_get(int8_t interface_id)
{
#ifdef HAVE_THREAD
    return thread_joiner_application_get_config(interface_id);
#else
    (void) interface_id;
    return NULL;
#endif
}
static void thread_parse_annoucement(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg)
{
    uint64_t timestamp;
    uint16_t panid;
    uint8_t *ptr;
    uint8_t channel_page;
    uint16_t channel;
    link_configuration_s *linkConfiguration = thread_joiner_application_get_config(cur->id);


    tr_info("Recv Dataset Announce");
    if (8 > thread_tmfcop_tlv_data_get_uint64(mle_msg->data_ptr, mle_msg->data_length,MLE_TYPE_ACTIVE_TIMESTAMP,&timestamp)) {
        tr_error("Missing timestamp TLV");
        return;
    }
    if (2 > thread_tmfcop_tlv_data_get_uint16(mle_msg->data_ptr, mle_msg->data_length,MLE_TYPE_PANID,&panid)) {
        tr_error("Missing Panid TLV");
        return;
    }
    if (3 > thread_tmfcop_tlv_find(mle_msg->data_ptr, mle_msg->data_length,MLE_TYPE_CHANNEL,&ptr)) {
        tr_error("Missing Channel TLV");
        return;
    }
    channel_page = ptr[0];
    channel = common_read_16_bit(&ptr[1]);

    if (linkConfiguration->timestamp == timestamp) {
        // We received same timestamp
        tr_debug("Same timestamp");
        return;
    }

    if (cur->thread_info->announcement_info && cur->thread_info->announcement_info->timestamp == timestamp){
        // We received same timestamp again
        tr_debug("Processing announce with same timestamp");
        return;
    }


    if (linkConfiguration->timestamp > timestamp) {
        // We received older time stamp we just announce back to originator channel
        thread_bootstrap_announce_send(cur, linkConfiguration->channel_page, linkConfiguration->rfChannel, linkConfiguration->panId, linkConfiguration->timestamp, channel);
        return;
    }

    tr_debug("New configuration received");
    thread_bootstrap_temporary_attach(cur,channel_page, channel, panid, timestamp);
}
void thread_security_update_from_mac(protocol_interface_info_entry_t *cur)
{
    uint8_t *mleKey;
    uint8_t historyKeyId;
    link_configuration_s *linkConfiguration;
    linkConfiguration = thread_joiner_application_get_config(cur->id);
    if (!linkConfiguration) {
        return;
    }

    mleKey = mle_service_security_next_key_get(cur->id);
    if (!mleKey) {
        return;
    }
    historyKeyId = mle_service_security_next_key_id_get(cur->id);

    /* Set old secondary to history */
    thread_history_key_material_push(cur->thread_info, mleKey, historyKeyId);
    linkConfiguration->key_sequence++;
    mac_helper_link_frame_counter_set(cur->id, 0);
    thread_security_next_key_generate(cur, linkConfiguration->master_key, linkConfiguration->key_sequence);
    thread_key_guard_timer_calculate(cur, linkConfiguration, false);
}