
/*------------------------------- includes --------------------------------*/
//#include "Global.h"
#include "Std_Types.h"
#include "DiagnosticR/Comp_HAL_Autosar_Wrappers/Timer.h"
#include "DiagnosticR/Comp_ISO_15765_3/Iso15765_3_Task.h"


/*------------------------------ user code --------------------------------*/

#include "DiagnosticR/Comp_ISO_15765_2/TP.h"
#include "DiagnosticR/UDS/Iso15765_layer3/Iso15765_3_CFG.h"
#include "Iso15765_3.h"

#define MAX_TIME_ACTION ((UI_16)10000)

/*-------------------------------- macros ---------------------------------*/





/*------------------------------- defines ---------------------------------*/
/* Maxim valor del compteig del temps */
#define MAX_COMPTADOR_TEMPS ((UI_16)65000)

/*---------------------------- tipus de dades -----------------------------*/

typedef enum {
    ESTAT_ISO15765_3_REQUESTRESPONDCTRL_WAITINGREQUEST = 1, 
    ESTAT_ISO15765_3_REQUESTRESPONDCTRL_REQUESTINPROGRES = 2, 
    ESTAT_ISO15765_3_REQUESTRESPONDCTRL_RESPONDING = 3, 
    ESTAT_ISO15765_3_REQUESTRESPONDCTRL_EXTTIMERESPOND = 4, 
    ESTAT_0_ISO15765_3_REQUESTRESPONDCTRL = 0
} t_estat_iso15765_3_requestrespondctrl;


/*------------------------------ variables --------------------------------*/

/* Variables d estat */
static t_estat_iso15765_3_requestrespondctrl estat_iso15765_3_requestrespondctrl = ESTAT_0_ISO15765_3_REQUESTRESPONDCTRL;

/* Timers implicits */
static t_clock temps_iso15765_3_requestrespondctrl = (t_clock)0;
static UI_8 p2extcounter = 0;
static BOOL response_sent = 0;


/*------------------------- capcaleres de funcions ------------------------*/

static void Iso15765_3_RequestRespondCtrl0(void);
static void WaitingRequest(void);
static void RequestInProgres(void);
static void Responding(void);
static void ExtTimeRespond(void);


/*----------------------- funcions d'inicialitzacio -----------------------*/
 
/**************************************************************************** 
| Funcionalitat:                                                              
|   Inicialitzacio del diagrama d estats Iso15765_3_RequestRespondCtrl 
|---------------------------------------------------------------------------- 
| Interficie:                                                                 
|   Entrades: - 
|   Sortides:
|       estat_iso15765_3_requestrespondctrl
|       temps_iso15765_3_requestrespondctrl
|       tp_frm
|       session_expired 
****************************************************************************/
void Iso15765_3_RequestRespondCtrlInicialitza(void)
{
    /* Inicialitzacio de la variable d estat */
    estat_iso15765_3_requestrespondctrl = ESTAT_0_ISO15765_3_REQUESTRESPONDCTRL;

    /* Inicialitzacio del timer implicit */
    temps_iso15765_3_requestrespondctrl= (t_clock)0;

    /* Execucio del cicle inicial de la maquina d estats */
    Iso15765_3_RequestRespondCtrl();
}


/*------------------------- rutines principals ---------------------------*/
 
/**************************************************************************** 
| Funcionalitat:                                                              
|   Rutina principal del diagrama d estats Iso15765_3_RequestRespondCtrl. 
|   Invoca a la funcio corresponent a l estat actual. 
|---------------------------------------------------------------------------- 
| Interficie:                                                                 
|   Entrades:
|       estat_iso15765_3_requestrespondctrl
|       temps_iso15765_3_requestrespondctrl
|       tp_frm 
|   Sortides:
|       estat_iso15765_3_requestrespondctrl
|       temps_iso15765_3_requestrespondctrl
|       tp_frm
|       session_expired 
****************************************************************************/
void Iso15765_3_RequestRespondCtrl(void)
{
    /* Estudi per casos del estat actual */
    switch (estat_iso15765_3_requestrespondctrl){
    case ESTAT_0_ISO15765_3_REQUESTRESPONDCTRL:
        Iso15765_3_RequestRespondCtrl0();
        break;
    case ESTAT_ISO15765_3_REQUESTRESPONDCTRL_WAITINGREQUEST:
        WaitingRequest();
        break;
    case ESTAT_ISO15765_3_REQUESTRESPONDCTRL_REQUESTINPROGRES:
        RequestInProgres();
        break;
    case ESTAT_ISO15765_3_REQUESTRESPONDCTRL_RESPONDING:
        Responding();
        break;
    case ESTAT_ISO15765_3_REQUESTRESPONDCTRL_EXTTIMERESPOND:
        ExtTimeRespond();
        break;
    default:
        estat_iso15765_3_requestrespondctrl = ESTAT_0_ISO15765_3_REQUESTRESPONDCTRL;
        break;
    }

    /* Increment del temps de cicle al timer implicit */
    if (temps_iso15765_3_requestrespondctrl < MAX_COMPTADOR_TEMPS) {
        temps_iso15765_3_requestrespondctrl += TimerDeltaCicleConsulta();
    }
}


/*------------------------- funcions d'estats -----------------------------*/

 
/**************************************************************************** 
| Funcionalitat: 
|   Funcio corresponent a l estat inicial del proces Iso15765_3_RequestRespondCtrl 
|---------------------------------------------------------------------------- 
| Interficie: -                                                                
****************************************************************************/
static void Iso15765_3_RequestRespondCtrl0(void)
{
    /* Transicio per defecte */

    /* Inicialitzacio del timer implicit */
    temps_iso15765_3_requestrespondctrl= (t_clock)0;

    /* Canviem l estat inicial */
    estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_WAITINGREQUEST;
}
 
/**************************************************************************** 
| Funcionalitat:                                                              
|   Funcio corresponent a l estat WaitingRequest.                              
|---------------------------------------------------------------------------- 
| Interficie:                                                                 
|   Entrades:
|       estat_iso15765_3_requestrespondctrl
|       temps_iso15765_3_requestrespondctrl
|       tp_frm 
|   Sortides:
|       estat_iso15765_3_requestrespondctrl
|       temps_iso15765_3_requestrespondctrl
|       tp_frm
|       session_expired 
****************************************************************************/
static void WaitingRequest(void)
{
    if ((tp_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_IN_PRG)) {
        /* Cas en que executem la transicio ReqInProgNotif1 */

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_REQUESTINPROGRES;
    }
    else if ((tp_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF) || (tp_fun_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF)) {
        /* Cas en que executem la transicio ReqNotif1 */

        /* -- action de la transicio -- */
        Iso15765_3Servicios();
        response_sent = FALSE;
        

        /* -- entry de l estat Responding -- */
        if(tp_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF){ tp_frm[DIAG_ISO15765_2_HDL].sts_rx = TP_FRM_RX_IDLE; } if(tp_fun_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF){ tp_fun_frm[DIAG_ISO15765_2_HDL].sts_rx = TP_FRM_RX_IDLE; }

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_RESPONDING;
    }
    else if (temps_iso15765_3_requestrespondctrl >= TIMER_MS_TO_TICKS(S3_MAX)) {
        /* Cas en que executem la transicio SessionExpired */

        /* -- action de la transicio -- */
        session_expired = TRUE;

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_WAITINGREQUEST;
    }
    else if (force_response > (UI_8)0x00) {
        /* Cas en que executem la transicio ForceResponse */

        /* -- action de la transicio -- */
        tp_frm[DIAG_ISO15765_2_HDL].data_rx[0] = force_response;
        iso15765_3_current_service = force_response;
        iso15765_3_request_mode = ISO15765_3_PHY_REQUEST;
        
        tp_frm[DIAG_ISO15765_2_HDL].data_tx[0]= force_response + UDS_POS_RESP_CODE;
        Iso15765_3IncrementResponseSize((UI_8)1);
        force_response = (UI_8)0x00;
        response_sent = FALSE;    
        

        /* -- entry de l estat Responding -- */
        if(tp_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF){ tp_frm[DIAG_ISO15765_2_HDL].sts_rx = TP_FRM_RX_IDLE; } if(tp_fun_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF){ tp_fun_frm[DIAG_ISO15765_2_HDL].sts_rx = TP_FRM_RX_IDLE; }

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_RESPONDING;
    }
    else {

        /* No s ha activat cap transicio: ens quedem a l estat actual */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_WAITINGREQUEST;
    }
}
 
/**************************************************************************** 
| Funcionalitat:                                                              
|   Funcio corresponent a l estat RequestInProgres.                              
|---------------------------------------------------------------------------- 
| Interficie:                                                                 
|   Entrades:
|       estat_iso15765_3_requestrespondctrl
|       temps_iso15765_3_requestrespondctrl
|       tp_frm 
|   Sortides:
|       estat_iso15765_3_requestrespondctrl
|       temps_iso15765_3_requestrespondctrl
|       tp_frm
|       session_expired 
****************************************************************************/
static void RequestInProgres(void)
{
    if ((tp_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_ERR_NOTIF)) {
        /* Cas en que executem la transicio RxError */

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_WAITINGREQUEST;
    }
    else if ((tp_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF)) {
        /* Cas en que executem la transicio ReqNotif2 */

        /* -- action de la transicio -- */
        Iso15765_3Servicios();
        response_sent = FALSE;
        

        /* -- entry de l estat Responding -- */
        if(tp_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF){ tp_frm[DIAG_ISO15765_2_HDL].sts_rx = TP_FRM_RX_IDLE; } if(tp_fun_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF){ tp_fun_frm[DIAG_ISO15765_2_HDL].sts_rx = TP_FRM_RX_IDLE; }

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_RESPONDING;
    }
    else if (temps_iso15765_3_requestrespondctrl >= TIMER_MS_TO_TICKS(MAX_TIME_ACTION)) {
        /* Cas en que executem la transicio UnknowProblem */

        /* -- action de la transicio -- */
        Iso15765_3AbortResponse();

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_WAITINGREQUEST;
    }
    else {

        /* No s ha activat cap transicio: ens quedem a l estat actual */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_REQUESTINPROGRES;
    }
}
 
/**************************************************************************** 
| Funcionalitat:                                                              
|   Funcio corresponent a l estat Responding.                              
|---------------------------------------------------------------------------- 
| Interficie:                                                                 
|   Entrades:
|       estat_iso15765_3_requestrespondctrl
|       temps_iso15765_3_requestrespondctrl
|       tp_frm 
|   Sortides:
|       estat_iso15765_3_requestrespondctrl
|       temps_iso15765_3_requestrespondctrl
|       tp_frm
|       session_expired 
****************************************************************************/
static void Responding(void)
{
    /* -- during de l estat actual -- */
    
    if ((pending_response == TRUE) && (pending_response_mode != UDS_ERR_RESPONSE_PENDING) &&
       ((tp_frm[DIAG_ISO15765_2_HDL].sts_tx == TP_FRM_TX_ERR_NOTIF) || (tp_frm[DIAG_ISO15765_2_HDL].sts_tx == TP_FRM_TX_IDLE))) {
        Iso15765_3SendResponseSync(pending_response_mode);
        response_sent = TRUE;
    }
    

    if (((Iso15765_3QueryRequestMode()==ISO15765_3_PHY_REQUEST) && (response_sent == TRUE) && ((tp_frm[DIAG_ISO15765_2_HDL].sts_tx == TP_FRM_TX_IDLE) || (tp_frm[DIAG_ISO15765_2_HDL].sts_tx == TP_FRM_TX_ERR_NOTIF)))) {
        /* Cas en que executem la transicio PhyRespondEnd */

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_WAITINGREQUEST;
    }
    else if ((pending_response == TRUE) && (pending_response_mode == UDS_ERR_RESPONSE_PENDING) && ((tp_frm[DIAG_ISO15765_2_HDL].sts_tx == TP_FRM_TX_ERR_NOTIF) || (tp_frm[DIAG_ISO15765_2_HDL].sts_tx == TP_FRM_TX_IDLE))) {
        /* Cas en que executem la transicio NegRespExtTime */

        /* -- action de la transicio -- */
        Iso15765_3SendResponseSync(pending_response_mode);
        p2extcounter = 0;

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_EXTTIMERESPOND;
    }
    else if (((Iso15765_3QueryRequestMode()==ISO15765_3_FUN_REQUEST) && (response_sent == TRUE) && ((tp_frm[DIAG_ISO15765_2_HDL].sts_tx == TP_FRM_TX_IDLE) || (tp_frm[DIAG_ISO15765_2_HDL].sts_tx == TP_FRM_TX_ERR_NOTIF)) && (tp_frm[DIAG_ISO15765_2_HDL].sts_tx != TP_FRM_TX_REQ))) {
        /* Cas en que executem la transicio FunRequestEnd */

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_WAITINGREQUEST;
    }
    else if ((tp_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_IN_PRG)) {
        /* Cas en que executem la transicio RxInprogressWhilewaiting for TxConfirmation */

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_REQUESTINPROGRES;
    }
    else if ((pending_response == FALSE) && ( (tp_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF) )) {
        /* Cas en que executem la transicio RxOKWhileWaitingTxConfirmation */

        /* -- action de la transicio -- */
        Iso15765_3Servicios();
        response_sent = FALSE;

        /* -- entry de l estat Responding -- */
        if(tp_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF){ tp_frm[DIAG_ISO15765_2_HDL].sts_rx = TP_FRM_RX_IDLE; } if(tp_fun_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF){ tp_fun_frm[DIAG_ISO15765_2_HDL].sts_rx = TP_FRM_RX_IDLE; }

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_RESPONDING;
    }
    else if (temps_iso15765_3_requestrespondctrl >= TIMER_MS_TO_TICKS(MAX_TIME_ACTION)) {
        /* Cas en que executem la transicio UnknowProblem */

        /* -- action de la transicio -- */
        Iso15765_3AbortResponse();

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_WAITINGREQUEST;
    }
    else if ((pending_response == FALSE) && (tp_frm[DIAG_ISO15765_2_HDL].sts_tx == TP_FRM_TX_ERR_NOTIF)) {
        /* Cas en que executem la transicio  */

        /* -- action de la transicio -- */
        Iso15765_3AbortResponse();

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_WAITINGREQUEST;
    }
    else {

        /* No s ha activat cap transicio: ens quedem a l estat actual */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_RESPONDING;
    }
}
 
/**************************************************************************** 
| Funcionalitat:                                                              
|   Funcio corresponent a l estat ExtTimeRespond.                              
|---------------------------------------------------------------------------- 
| Interficie:                                                                 
|   Entrades:
|       estat_iso15765_3_requestrespondctrl
|       temps_iso15765_3_requestrespondctrl
|       tp_frm 
|   Sortides:
|       estat_iso15765_3_requestrespondctrl
|       temps_iso15765_3_requestrespondctrl
|       tp_frm
|       session_expired 
****************************************************************************/
static void ExtTimeRespond(void)
{
    if ((temps_iso15765_3_requestrespondctrl >= TIMER_MS_TO_TICKS(P2_EXT_MAX*10)) &&
        ((pending_response == FALSE) && ((tp_frm[DIAG_ISO15765_2_HDL].sts_tx == TP_FRM_TX_ERR_NOTIF) || (tp_frm[DIAG_ISO15765_2_HDL].sts_tx == TP_FRM_TX_IDLE)))) {
        /* Cas en que executem la transicio TimerP2TimeOut */

        /* -- action de la transicio -- */
        Iso15765_3SendResponseSync(UDS_ERR_RESPONSE_PENDING);
        p2extcounter++;

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_EXTTIMERESPOND;
    }
    else if ((pending_response == TRUE) && (tp_frm[DIAG_ISO15765_2_HDL].sts_tx != TP_FRM_TX_REQ) && (pending_response_mode != UDS_ERR_RESPONSE_PENDING)) {
        /* Cas en que executem la transicio FinalResponseAfterExtTime */

        /* -- action de la transicio -- */
        response_sent = FALSE;

        /* -- entry de l estat Responding -- */
        if(tp_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF){ tp_frm[DIAG_ISO15765_2_HDL].sts_rx = TP_FRM_RX_IDLE; } if(tp_fun_frm[DIAG_ISO15765_2_HDL].sts_rx == TP_FRM_RX_NOTIF){ tp_fun_frm[DIAG_ISO15765_2_HDL].sts_rx = TP_FRM_RX_IDLE; }

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_RESPONDING;
    }
    else if (p2extcounter > P2_EXT_MAX_COUNTER) {
        /* Cas en que executem la transicio p2ExtTimesExhausted */

        /* -- action de la transicio -- */
        Iso15765_3AbortResponse();

        /* Inicialitzacio del timer implicit */
        temps_iso15765_3_requestrespondctrl= (t_clock)0;

        /* -- canviem l estat -- */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_WAITINGREQUEST;
    }
    else {

        /* No s ha activat cap transicio: ens quedem a l estat actual */
        estat_iso15765_3_requestrespondctrl = ESTAT_ISO15765_3_REQUESTRESPONDCTRL_EXTTIMERESPOND;
    }
}


/********************************** FI **************************************/
