/*
 * ftfci_decode.c
 *
 *  Created on: 05-Oct-2022
 *      Author: Invcuser52
 */


#include "ftfci_decode.h"
#include "get_input.h"
#include "file_transfer.h"
#include "suspend_resume.h"
#include "notify_apps.h"
//#include "sample_app_dwnld.h"
//#include "sample_app_upload.h"
#include "ftds_decode.h"
#include "ftsr.h"
#include "ftci_decode.h"
#include "ft_receiver.h"
#include "ft_debug.h"
#include "message_frame_def.h"

s_string_info ftfci_rxd_frame;
static uint8_t ftfci_rx_buff_tc[10];
ft_flag_def ftfci_decode_avail;
tc_tm_id_e_ft tctm_id_inform_ftfci = FT_TC_FTFCI;

uint8_t continous_ping_only_receive_cntr =0;
#ifdef FT_SUSRES_TEST
extern ftm_db_params ftm_db_test;
#endif
void ftfci_clear_continous_ping_cntr(void)
{
	continous_ping_only_receive_cntr  = 0;
}


void check_ftfci_response_code(e_ftfci_response_code response, uint16_t waiting_time)
{
	static uint8_t report_sel_cntr = 0;
	ft_receiver_ping_rest();
	ft_debug_save_prev_frame_info(tctm_id_inform_ftfci ,response);

	switch (response)
	{
		case ftfci_suspend:
			ft_set_master_slave(sus_res_slave);
			ft_suspend(Suspend_Timeout_Mode_rqst,waiting_time,1);
			//prepare_sts_and_notify_receiver_app(transfer_suspended);
			break;

		case ftfci_suspend_savecontext:
			ft_set_master_slave(sus_res_slave);
			ft_suspend(Suspend_Savecontext_Mode_rqst,waiting_time,3);
			if(s_sus_res_info.sus_savctxt_ack_sent != 1)
			{
				prepare_sts_and_notify_receiver_app(transfer_suspended_savecontext);
			}
			else
			{
				/* already context saved so just send ACK */
				printf("FTM - send ACK only\n");
				ft_savecontext_ack(1);
			}
			break;

		case ftfci_resume:
			ft_set_master_slave(sus_res_slave);
			ft_resume(Resume_Timeout_Mode_rqst,1);
//			prepare_sts_and_notify_receiver_app(transfer_resumed);
			break;

		case ftfci_resume_savecontext:
			ft_set_master_slave(sus_res_slave);
			set_file_transfer_state(ft_download);
			//sample_app_regisration_dwld();
			prepare_sts_and_notify_receiver_app(transfer_resumed_restorecontext);
			break;


		case ftfci_ack:
#ifdef FT_SUSRES_TEST
			if(ftm_db_test.dont_send_ack_for_sus_rqst != 1 &&
			   ftm_db_test.dont_send_ack_for_res_rqst != 1 &&
			   ftm_db_test.skip_all_sus_ack_ != 1 &&
			   ftm_db_test.skip_all_res_ack_ != 1)
#endif
			{
				printf("Suspend/ Resume ACK received\n");
				ft_acceptance_received(prepare_sts_and_notify_receiver_app);
			}
#ifdef FT_SUSRES_TEST
			else
			{
				printf("[FT-DB-Test] Suspend/ Resume ACK received\n");
				ftm_db_test.dont_send_ack_for_sus_rqst = 0;
				ftm_db_test.dont_send_ack_for_res_rqst = 0;
			}
#endif
			break;

		case ftfci_nak:
			printf(" Warning !!! Suspend/ Resume not ACK received\n");
			ft_acceptance_nack(prepare_sts_and_notify_receiver_app);
			break;

		case ftfci_cancelled_by_susp_timeoout:
			ft_terminate(T_SuspendTimeout, 0);
			prepare_sts_and_notify_receiver_app(tx_terminated_suspend_timeout_expired);
			break;

		case ftfci_ping:
			printf("FTM-PG\n");
			if(dwnld_rqst.dwnld_cmp_sts != 0)
			{
				send_ftsr(dwnld_rqst.dwnld_cmp_sts,0);
			}
			else
			{
				if(continous_ping_only_receive_cntr < 3)
				{
					continous_ping_only_receive_cntr++;
					send_ftsr(ftsr_ping,0);
				}
				else
				{
					/* if ping request is received continuously without FTDS receive
					 * send head change request to sender
					* check data loss
					 *  */
					continous_ping_only_receive_cntr =0;
					report_sel_cntr++;
					if(report_sel_cntr <  2)
	                                {
					ft_fsm_change_state(FT_Report_Head_Change);
					}
					else if(report_sel_cntr < 4)
					{
						set_resend_flag(&dwnld_rqst);
ft_fsm_change_state(FT_Report_Sequence_loss);
                                   printf("\nLRQST\n");
					}
					else
					{
report_sel_cntr = 0;
					}
				}
			}
			break;


		case ftfci_cancelled_by_txnode:
			ft_terminate(T_Txnode, 0);
			prepare_sts_and_notify_receiver_app(transmission_terminated_by_tx_node);
			break;

		default:
			break;
	}
}

void decode_ftfci_frame()
{
	s_file_tx_framework_ctrl_info *ftfci = (s_file_tx_framework_ctrl_info*)ftfci_rxd_frame.str_ptr;
	uint8_t sid = ft_rx_session_id_read();

  if(ftfci->ctrl.bit.file_tx_session_id != sid && ftfci->ctrl.bit.response_code != ftfci_cancelled_by_txnode)
	{
		printf("FTFCI: invalid session id rxd, RCV:%d != STR:%d\n",ftfci->ctrl.bit.file_tx_session_id, sid);
		send_ftsr(ftsr_invalid_session_id,0);
	}
	else
	{
		check_ftfci_response_code(ftfci->ctrl.bit.response_code,ftfci->suspend_wait_timeout);
	}
}

void ft_receive_ftfci(uint8_t *ftfci_data, uint16_t ftfci_data_length)
{
	uint16_t u16cnt;
	eSystemState currentState;

	currentState = ft_fsm_read_state();
	ftfci_rxd_frame.str_ptr =  ftfci_rx_buff_tc;

	if (ftfci_rxd_frame.str_ptr != NULL)
	{
		ftfci_rxd_frame.size = ftfci_data_length;
		for (u16cnt = 0; u16cnt < ftfci_data_length; u16cnt++)
		{
			ftfci_rxd_frame.str_ptr[u16cnt] = ftfci_data[u16cnt];
		}
		if(currentState == FT_Inactive)
		{
			decode_ftfci_frame();
		}
		else
		{
			ftfci_decode_avail = e_ft_flag_set;
		}
		//decode_ftfci_frame();

	}
	else
	{
		printf("\n malloc error");
	}
}



void ft_decode_ftfci_frame(void)
{
	if(ftfci_decode_avail == e_ft_flag_set)
	{
		decode_ftfci_frame();
		ftfci_decode_avail = e_ft_flasg_clear;
	}
}

void ft_clear_ftfci_queue_flag(void)
{
     ftfci_decode_avail = e_ft_flasg_clear;
}

