/****************************************************************************
/*  F i l e   D a t a                                                        
/*                                                                           
/*  Module       :  MCMDManager                                                
/*  C.I. No.     :                                                           
/*  $Revision: 1.12 $
/*  $Date: 2005/02/21 08:58:29 $
/*  Belonging to :                                                           
/*               :                                                           
/*  $RCSfile: MA_MCMDArea_op.c,v $
/*  Program Type :                                                           
/*  Sub-modules  :                                                           
/*                                                                           
/****************************************************************************
/*  S W   D e v e l o p m e n t   E n v i r o n m e n t                      
/*                                                                           
/*  Host system  :                                                           
/*  SW Compiler  :                                                           
/*  $Author: sebastiani $
/*               :                                                           
/****************************************************************************
/*  U p d a t i n g                                                          
/*                                                                           
/*  $Log: MA_MCMDArea_op.c,v $
/*  Revision 1.12  2005/02/21 08:58:29  sebastiani
/*  all log comments completed
/*
/*  Revision 1.11  2004/09/17 15:01:00  faber
/*  LU_INFN_LOG flags fixing
/*
/*  Revision 1.10  2004/07/27 17:30:17  faber
/*  OBT can be now in second or milliseconds, depending of the situazion.
/*  OBT_s is used for FM compatibility, OBT_ms basically for MM infos
/*
/*  Revision 1.9  2004/05/10 12:59:17  faber
/*  __FILEID__ right value fixed: many .c files had the wrong value!
/*
/*  Revision 1.8  2004/02/26 11:23:09  faber
/*  SELECT_MODE min length is 8-only comment modified
/*
/*  Revision 1.7  2003/12/15 10:57:16  sebastiani
/*  last changes for the acceptance of TM tests in Rome of 9-12/Dec/2003
/*
/*  Revision 1.6  2003/12/07 15:07:11  sebastiani
/*  GAS_TEST renamed to GAS_CONTAINER_PURGE
/*
/*  Revision 1.5  2003/11/21 11:15:55  faber
/*  bugfixes:
/*  SELECT_MODE min length is 8, not 7
/*  CALIBRATE length is 6, not 15
/*
/*  Revision 1.4  2003/11/18 17:13:15  sebastiani
/*  GPT enabled to print a "\n" every 60s directly on UART, only to check if the CPU is
/*  alive
/*
/*  Revision 1.3  2003/11/18 09:01:14  alfarano
/*  laben patch fixes some problems
/*
/*  Revision 1.2  2003/10/21 16:09:12  alfarano
/*  LU_LOG_INFN replacement for all remaining original log functions
/*
/*  Revision 1.1.1.1  2003/08/04 09:40:21  sebastiani
/*  Imported sources laben rel. 19.06.2003 integrated with pam2
/*
/*  Revision 1.13  2002/11/14 09:50:19  zulia
/*  removed unsed status variable
/*
/*  Revision 1.12  2002/08/05 14:26:56  zulia
/*  Fixed max len of Patch MCMD to 504 and select mode to 504
/*
/*  Revision 1.11  2002/08/01 09:48:04  zulia
/*  set length downlink to 0x0a
/*
/*  Revision 1.10  2002/07/22 08:15:00  zulia
/*  correct the min length of MCMD SELECT_OPERATIVE_MODE from 9 to 7
/*
/*  Revision 1.9  2002/06/11 13:16:48  zulia
/*  changed lenght of DIRECT from 9 to 8
/*
/*  Revision 1.8  2002/05/15 13:46:34  zulia
/*  check of MCMD Lenght improved
/*
/*  Revision 1.7  2002/05/09 08:16:34  zulia
/*  *  acceptance release
/*
/*                                                                           
/*****************************************************************************/


/*============================= Include File ================================*/
  
#include <src/MCMDManager/MCMDArea/MA_MCMDArea_op.h>
#include <src/MCMDManager/MCMDArea/MA_MCMDArea_int.h>

#include <src/INFN/LU_SourceFileID_INFN.h>
#define __FILEID__ _MA_MCMDArea_op__c
#include <src/INFN/PRH_ParamHandler_INFN.h>
#include <src/INFN/LU_LogUtility_INFN.h>
#include <src/INFN/PRH_ParamHandler_INFN_auto.h>
LU_DECL_MASK();

/*============================== Local Variables ============================*/

/*****************************************************************************/
/* @Constant: MA_McmdId                                                      */
/* @Purpose :                                                                */
/*  Array of unsigned int.                                                   */
/*  Array whose content is the MCMDs identifier, and the index is MCMDs type */
/* @@                                                                        */
/*****************************************************************************/
const unsigned int MA_McmdId [] = {ID_NULL_MCMD,              
                                   ID_DOWN_LINK,
                                   ID_BITE,
                                   ID_TEST,
                                   ID_PATCH,
                                   ID_DUMP,
                                   ID_REBOOT,
                                   ID_DIRECT,
                                   ID_RESET_HISTORY,
                                   ID_DEL_MCMD_QUEUE,
                                   ID_EXE_MEM_CONF,
                                   ID_ABORT,
                                   ID_PURGE_TRD,
                                   ID_GAS_CONTAINER_PURGE,
                                   ID_CALIBRATE,
                                   ID_SELECT_MODE,
                                   ID_NEUTRON_DETECTOR,
                                   ID_TIME_SYNCHRONISE,      
                                   ID_ORBITAL_INFORMATION,  
                                   ID_INCLINATION_INFORMATION};
                                                                   
/**********************************************************************************/
/* @Constant: MA_McmdType                                                         */
/* @Purpose :                                                                     */
/*  Array of unsigned int.                                                        */
/*  Array whose content is the      MCMDs type, and the index is MCMDs identifier */
/* @@                                                                        */
/*****************************************************************************/
const unsigned int MA_McmdType [] ={
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//000
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//008
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//016
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//024

    PATCH,DUMP,RESET_HISTORY,DEL_MCMD_QUEUE,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//032
    REBOOT, EXE_MEM_CONF, NULL_MCMD ,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD ,ABORT,//040
    PURGE_TRD,GAS_CONTAINER_PURGE,CALIBRATE,SELECT_MODE,NULL_MCMD,NEUTRON_DETECTOR,NULL_MCMD,  //048
    NULL_MCMD,

    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//056
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//064
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//072
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//080
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//088
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//096
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//104
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//112
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//120

    BITE,NULL_MCMD, DOWN_LINK, NULL_MCMD, NULL_MCMD, NULL_MCMD, NULL_MCMD,NULL_MCMD,//128
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,TEST,     //136
    NULL_MCMD,NULL_MCMD, NULL_MCMD, NULL_MCMD, NULL_MCMD, NULL_MCMD,NULL_MCMD,NULL_MCMD,//144

    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//152
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//160
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//168
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//176
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//184
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//192
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//200
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//208
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//216

    TIME_SYNCHRONISE,ORBITAL_INFORMATION,INCLINATION_INFORMATION,NULL_MCMD,NULL_MCMD,//224
    NULL_MCMD,NULL_MCMD,NULL_MCMD,

    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//232
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,//240
    NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,NULL_MCMD,DIRECT//248
    };
    
/*****************************************************************************/
/* @Constant: MA_McmdLenght                                                  */
/* @Purpose :                                                                */
/*  Array of unsigned int.                                                   */
/*  Array whose content is the MCMDs lenght, and the index is MCMDs type     */
/* @@                                                                        */
/*****************************************************************************/
#define MIN_SELECT_MODE_LEN    8
#define MIN_PATCH_LEN         10
const unsigned int MA_McmdLenght [] = {
    0x00,  /* NULL_MCMD,                       */
    0x09,  /* DOWN_LINK,                       */ // changed since test for TM in Rome
    0x07,  /* BITE,                            */
    0x07,  /* TEST,                            */
    0x1f8, /* PATCH,                  10 - 504 */
    0x09,  /* DUMP,                            */ 
    0x06,  /* REBOOT,                          */ 
    0x08,  /* DIRECT,                          */ 
    0x06,  /* RESET_HISTORY,                   */
    0x09,  /* DEL_MCMD_QUEUE,                  */ 
    0x07,  /* EXE_MEM_CONF,                    */ 
    0x07,  /* ABORT,                           */ 
    0x07,  /* PURGE_TRD,                       */ 
    0x07,  /* GAS_CONTAINTER_PURGE,            */ 
    0x06,  /* CALIBRATE,               6       */ 
    0x1f8, /* SELECT_MODE,             8 - 504 */
    0x07,  /* NEUTRON_DETECTOR,                */
    0x08,  /* TIME_SYNCHRONISE,                */
    0x14,  /* ORBITAL_INFORMATION,     20      */       
    0x42   /* INCLINATION_INFORMATION  66      */       
    };
    

/*****************************************************************************/
/* @Variable: MA_HeaderMcmd                                                  */
/* @Purpose :                                                                */
/*   MA_HEADER_MCMD type                                                     */
/*   Pointer to timetag MCMD in top to the list                              */
/* @@                                                                        */
/*****************************************************************************/
static MA_HEADER_MCMD*   MA_HeaderMcmd;

/*****************************************************************************/
/* @Variable: MA_TimetagCounter                                              */
/* @Purpose :                                                                */
/*   unsigned int type                                                       */
/*   Counter of the timetag MCMD storend in the list                         */
/* @@                                                                        */
/*****************************************************************************/
static unsigned int      MA_TimetagCounter;

/*****************************************************************************/
/* @Variable: MA_TimetagBufFullFlag                                          */
/* @Purpose :                                                                */
/*   unsigned int type                                                       */
/*   Flag of timetag MCMD list full                                          */
/* @@                                                                        */
/*****************************************************************************/
static unsigned int      MA_TimetagBufFullFlag;

/*****************************************************************************/
/* @Variable: MA_1553IsLocked                                                */
/* @Purpose :                                                                */
/*   unsigned int type                                                       */
/*   arbiter of 1553 MCMD Buffer                                             */
/* @@                                                                        */
/*****************************************************************************/
static unsigned int      MA_1553IsLocked;

/*****************************************************************************/

/*====== M C M D A r e a   O P E R A T I O N A L   F U N C T I O N S ========*/

/*****************************************************************************/
/* @Function: MA_opInit                                                      */
/* @Purpose :                                                                */
/*  Inialialization function of the MCMDArea object.                         */
/*  The following initialization are performed:                              */
/*  To get from a OS partition a pointer to a buffer for storing the timetag */
/*  MCMD header list.                                                        */
/*  Initialize object variable.                                              */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code MA_opInitMCMDArea (void)
{
status_code status;

    /* Get partition buffer for the timetag MCMD header list */
    status =OS_piPartGetBuffer(MA_TAB_PART,(void*)&MA_HeaderMcmd);
    /* Initialize object variable                            */
    MA_TimetagCounter     =0;
    MA_TimetagBufFullFlag =FALSE;
    MA_opRelease1553();
    return (status);

}



/*****************************************************************************/
/* @Function: MA_opGetMCMDType                                               */
/* @Purpose :                                                                */
/*  The function converts the MCMD code in the MCMD type (enumarate).        */
/*  If MCMD type is not found an internal error HA_E10_MCMD_ERR is returned. */ 
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  McmdId               IN      MCMD code identifier                        */
/*  McmdType             OUT     MCMD type (enumerate)                       */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code MA_opGetMCMDType (unsigned int  McmdId, unsigned int* McmdType)
{
status_code status;

    /* Check MCMD identification validity   */
    if (McmdId <= MAX_MCMD_ID)
    {
        /* Get MCMD type                    */
        *McmdType =MA_McmdType[McmdId];
    }
    else
    {
        /* MCMD type not identified         */
        *McmdType =NULL_MCMD;
    }
    /* Check if MCMD type has been found    */
    if (*McmdType != NULL_MCMD)
    {
        status =SUCCESSFUL;
    }
    else
    {
        status =HA_E10_MCMD_ERR;
    }
    
    return (status);

}



/*****************************************************************************/
/* @Function: MA_opGetMCMDId                                                 */
/* @Purpose :                                                                */
/*  The function converts the MCMD type (enumarate) in the MCMD code.        */
/*  If MCMD type is not a valid enumerate an internal error HA_E10_MCMD_ERR  */
/*  is returned.                                                             */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  McmdType             IN      MCMD type (enumerate)                       */
/*  McmdId               OUT     MCMD code identifier                        */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code MA_opGetMCMDId (unsigned int McmdType,unsigned int* McmdId)
{
status_code status;
    
    /* Check MCMD type identification validity   */
    if (McmdType <= MAX_MCMD)
    {
        /* Get MCMD identification               */
        *McmdId =MA_McmdId[McmdType];
        status  =SUCCESSFUL;
    }
    else
    {
        /* MCMD not identified                   */
        *McmdId =NULL_MCMD;
        status  =HA_E10_MCMD_ERR;
    }
    return (status);

}

/*****************************************************************************/
/* @Function: MA_opGetMCMDLenght                                             */
/* @Purpose :                                                                */
/*  The function checks the MCMD lenght.                                     */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  McmdType             IN      MCMD type (enumerate)                       */
/*  McmdLen              OUT     MCMD lenght                                 */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code MA_opGetMCMDLenght (unsigned int McmdType,
                                unsigned int McmdLen)
{
status_code  status;
unsigned int len;

    /* Check MCMD type identification validity   */
    if (McmdType <= MAX_MCMD)
    {
        /* Get MCMD lenght                       */
        status =UNSATISFIED;
	len =MA_McmdLenght[McmdType];
	if (McmdType == SELECT_MODE)
	{
	    if (McmdLen >= MIN_SELECT_MODE_LEN && McmdLen<=len)
	    {
	        status =SUCCESSFUL;
	    }  
	}
	else if (McmdType == PATCH)
	{
	    if (McmdLen >= MIN_PATCH_LEN && McmdLen<=len)
	    {
	        status =SUCCESSFUL;
	    }  	    
	}
        else
	{
	    if (McmdLen==len)
	    {
	        status  =SUCCESSFUL;
	    }
	}
    }
    else
    {
        /* MCMD not identified                   */
        status  =HA_E10_MCMD_ERR;
    }
    
    return (status);

}


/*****************************************************************************/
/* @Function: MA_opPutMCMDtimetag                                            */
/* @Purpose :                                                                */
/*  The function inserts a MCMD with timetag in the timetag MCMD list.       */
/*  The MCMD is not inserted in the list if his timetag already  exists.     */
/*  After having searched for the first free position in the list, if the    */
/*  MCMD timetag in top to the list is older than the MCMD timetag to insert,*/
/*  is moved in the free position and the new MCMD is inserted in his        */
/*  position. Otherwise the new MCMD  is inserted in the free position.      */
/*  During checks between timetag and OBT, for times close to the threshold  */
/*  overflow (2^ 32 bit), it is managed the cases in which one of the times  */
/*  exceeds the values limit of the variable.                                */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  Mcmd                 IN      Pointer to MCMD header structure            */
/*  Obt                  IN      On Board Time                               */
/*  Option               IN      Flag which defines if await or no the       */
/*                               resource availability (WAIT, NO_WAIT)       */
/*  Timeout              IN      Timeout value for WAIT option               */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code MA_opPutMCMDtimetag (MA_HEADER_MCMD* Mcmd, TI_TIME Obt,
                                 unsigned int Option,  unsigned int Timeout)
{
status_code     status;
status_code     statusOper;
MA_HEADER_MCMD* pt;
MA_HEADER_MCMD* pFreePos;
unsigned int    swapFlag;
unsigned int    sameTimetagFlag;
unsigned short  i;

    if ((status =OS_piResourceObtain (MA_RES,Option,Timeout))==SUCCESSFUL)
    {
        /* Search a free position, and check if the                        */           
        /* new timetag already exists                                      */
        sameTimetagFlag =FALSE;
        pFreePos        =NULL;
        for (i=0, pt =MA_HeaderMcmd;(!sameTimetagFlag)&&(i<MAX_MCMD_TIMETAG); i++,pt++)
        {
            if(pt->Type == NULL_MCMD)
            {
                if (!pFreePos)
                {
                    /* Found fFree position                                */
                    pFreePos =pt;
                }
            }
            else
            {
                if (pt->TimeTag == Mcmd->TimeTag)
                {
                    /* Same timetag found, the Mcmd  must be refused       */
                    sameTimetagFlag =TRUE;
                    statusOper      =HA_E2_TIMETAG_ALREADY_EXIST;
                }
            }
        }

        if (pFreePos && !sameTimetagFlag)
        {
            /* The Mcmd must be inserted into timetag queue. Check if      */
            /* must be inserted in the header or in the free position      */
            swapFlag =FALSE;
            if (MA_HeaderMcmd->TimeTag < Obt)
            {
                /* Timetag which expires after the obt counter overflow    */
                if (Mcmd->TimeTag < Obt)
                {
                    if(MA_HeaderMcmd->TimeTag > Mcmd->TimeTag)
                    {
                        swapFlag =TRUE;
                    }        
                }
                else
                {
                    swapFlag =TRUE;
                }
            }
            else
            {
                /* Timetag which expires before the obt counter overflow   */
                if (Mcmd->TimeTag > Obt)
                {
                    if(MA_HeaderMcmd->TimeTag > Mcmd->TimeTag)
                    {
                        swapFlag =TRUE;
                    }        
                }
            }
            /* Check if the header MCMD must be replaced with the new MCMD  */
            if (swapFlag)
            {
                /* The new MCMD is more recent, then is put in the header   */
                /* position and the less recent is put in the free position */ 
                *pFreePos      =*MA_HeaderMcmd;
                *MA_HeaderMcmd =*Mcmd;
                Mcmd->Type     =NULL_MCMD;            
            }
            else
            {
                /* The new MCMD is put in the free position                 */ 
                *pFreePos    =*Mcmd;
                Mcmd->Type   =NULL_MCMD;            
            }
            statusOper =SUCCESSFUL;
            /* Increment timetag counter                                    */
            MA_TimetagCounter++;
            if (MA_TimetagCounter >= MAX_MCMD_TIMETAG)
            {
                /* MCMD timetag list full                                   */
                MA_TimetagBufFullFlag =TRUE;
            }
        }
        else
        {
            if (!pFreePos && !sameTimetagFlag)
            {
                /* MCMD timetag list full                                   */
                MA_TimetagBufFullFlag =TRUE;
                statusOper            =HA_E2_MCMD_QUEUE_FULL;
            }                
        }
        /* Release MCMDArea resource                                        */
        status =OS_piResourceRelease (MA_RES);    
    }
    else
    {
        if (status==UNSATISFIED || status==INVALID_ID)
        {
            /* Semaphore error                                              */
            /*@LOG LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_MA,HA_E10_SEMAPHORE_ERR,status); */
	    LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
            status =HA_E10_SEMAPHORE_ERR;
        }
    }
    
    /* If resource is correctly obtaneid return operation status            */
    if(status == SUCCESSFUL)
    {
        status =statusOper;
    }
    return (status);
}




/*****************************************************************************/
/* @Function: MA_opGetMCMDtimetag                                            */
/* @Purpose :                                                                */
/*  The function returns the MCMD with the most recent timetag into the list.*/
/*  The MCMD with most recent timetag of the list is always located in the   */
/*  header position.                                                         */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  Mcmd                 IN      Pointer to MCMD header structure            */
/*  Option               IN      Flag which defines if await or no the       */
/*                               resource availability (WAIT, NO_WAIT)       */
/*  Timeout              IN      Timeout value for WAIT option               */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code MA_opGetMCMDtimetag (MA_HEADER_MCMD* Mcmd, unsigned int Option, 
                                 unsigned int Timeout)
{
status_code status;

    if ((status =OS_piResourceObtain (MA_RES,Option,Timeout))==SUCCESSFUL)
    {
        /* Get the MCMD in the header position (most recent)  */
        *Mcmd   =*MA_HeaderMcmd;
        /* Release MCMDArea resource                          */
        status  =OS_piResourceRelease (MA_RES);    
    }
    else
    {
        /* Check if there is a resource error                 */
        if (status==UNSATISFIED || status==INVALID_ID)
        {
            /* Semaphore error                                */
            /*@LOG LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_MA,HA_E10_SEMAPHORE_ERR,status); */
	    LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
            status =HA_E10_SEMAPHORE_ERR;
        }
    }
    return (status);

}



/*****************************************************************************/
/* @Function: MA_opUpdateMCMDtimetag                                         */
/* @Purpose :                                                                */
/*  The function first takes a MCMDArea resource then call a function that   */
/*  updates the header position in the timetag MCMD list with most recent    */
/*  MCMD. At the end it releases the MCMDArea resource.                      */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  Obt                  IN      On Board Time                               */
/*  Option               IN      Flag which defines if await or no the       */
/*                               resource availability (WAIT, NO_WAIT)       */
/*  Timeout              IN      Timeout value for WAIT option               */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code MA_opUpdateMCMDtimetag (TI_TIME Obt, unsigned int Option, 
                                    unsigned int Timeout)
{
status_code     status;

    if ((status =OS_piResourceObtain (MA_RES,Option,Timeout))==SUCCESSFUL)
    {
        /* Update the MCMD in the header position (most recent)  */
        MA_ifUpdateMcmdHeader(MA_HeaderMcmd,Obt);
        
        /* Release MCMDArea resource                             */
        status  =OS_piResourceRelease (MA_RES);    
    }
    else
    {
        /* Check if there is a resource error                    */
        if (status==UNSATISFIED || status==INVALID_ID)
        {
            /*@LOG Semaphore error LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_MA,HA_E10_SEMAPHORE_ERR,status); */
	    LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
            status =HA_E10_SEMAPHORE_ERR;
        }
    }
 
    return (status);

}



/*****************************************************************************/
/* @Function: MA_opDelMCMDtimetag                                            */
/* @Purpose :                                                                */
/*  The function searches and deletes the MCMD in the timetag MCMD list.     */
/*  If MCMD deleted was in the header position call the function to update   */
/*  the header position with the most recent MCMD.                           */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  Mcmd                 IN      Pointer to MCMD header structure            */
/*  Obt                  IN      On Board Time                               */
/*  Option               IN      Flag which defines if await or no the       */
/*                               resource availability (WAIT, NO_WAIT)       */
/*  Timeout              IN      Timeout value for WAIT option               */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code MA_opDelMCMDtimetag (MA_HEADER_MCMD* Mcmd, TI_TIME Obt,
                                 unsigned int Option, unsigned int Timeout)
{
status_code     status;
status_code     statusOper;
MA_HEADER_MCMD* pt;
MA_HEADER_MCMD* pHOverObt;
MA_HEADER_MCMD* pHUnderObt;
unsigned int    ttOverObt,ttUnderObt;
unsigned int    ttOverFlag,ttUnderFlag;
unsigned int    mcmdFoundFlag;
unsigned short  i;

    if ((status =OS_piResourceObtain (MA_RES,Option,Timeout))==SUCCESSFUL)
    {
        /* Search the MCMD into timetag list                   */ 
        mcmdFoundFlag =FALSE;
        for (i=0, pt =MA_HeaderMcmd; i < MAX_MCMD_TIMETAG; i++,pt++)
        {
            if (Mcmd->PtrMCMD == pt->PtrMCMD)
            {
                /* Delete the specify MCMD into Timetag queue  */
                pt->Type     =NULL_MCMD;
                pt->TimeTag  =0;
                pt->PtrMCMD  =NULL;
                pt->Length   =0;
                mcmdFoundFlag =TRUE;
                break; /* MCMD found, exit from the loop       */
            }
        }    
        /* Check if deleted MCMD was the Header MCMD           */
        if(mcmdFoundFlag && MA_HeaderMcmd->Type==NULL_MCMD)
        {
            /* Search the more recent MCMD to execute,         */
            /* and put it in the header position               */
            MA_ifUpdateMcmdHeader(MA_HeaderMcmd,Obt);          
        }                                                      
        if(mcmdFoundFlag)                                      
        {                                                      
            /* MCMD found                                      */
            statusOper =SUCCESSFUL;                            
            /* Decrements the MCMD timetag counter             */
            MA_TimetagCounter--;                               
            /* MCMD timetag buffer not full                    */
            MA_TimetagBufFullFlag =FALSE;
        }
        else
        {
            statusOper =HA_E10_MCMD_ERR;        
        }
                    
        /* Release MCMDArea resource                           */
        status =OS_piResourceRelease (MA_RES);    
    }
    else
    {
        if (status==UNSATISFIED || status==INVALID_ID)
        {
            /*@LOG Semaphore error LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_MA,HA_E10_SEMAPHORE_ERR,status); */
	    LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
            status =HA_E10_SEMAPHORE_ERR;
        }
    }
    /* If resource is correctly obtaneid return operation status */
    if(status == SUCCESSFUL)
    {
        status =statusOper;
    }
    return (status);

}



/*****************************************************************************/
/* @Function: MA_opDelAllMCMDtimetag                                         */
/* @Purpose :                                                                */
/*  Provided Interface to delete all or a specific MCMD in the list of the   */
/*  MCMD with timetag. DelAllMcmdFlag parameter establishes if must be       */
/*  deleted all the MCDM of the list or only the MCMD that has the same      */
/*  timetag value of the function parameter  Timetag.  In this case if MCMD  */
/*  deleted was in the header position is called the function to update the  */
/*  header position with the most recent MCMD.                               */
/*                                                                           */
/* @@                                                                        */
/*  DelAllMcmdFlag       IN      Flag to indicate delete all or a MCMD       */
/*  Timetag              IN      Timetag value                               */
/*  Option               IN      Flag which defines if await or no the       */
/*                               resource availability (WAIT, NO_WAIT)       */
/*  Timeout              IN      Timeout value for WAIT option               */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code MA_opDelAllMCMDtimetag (unsigned int DelAllMcmdFlag,
                                    unsigned int Timetag,
                                    unsigned int Option, 
                                    unsigned int Timeout)
{
status_code     status;
status_code     statusOper;
MA_HEADER_MCMD* pt;
unsigned int    mcdmDeleteFlag;
TI_TIME         obt;
unsigned short  i;

    if ((status =OS_piResourceObtain (MA_RES,Option,Timeout))==SUCCESSFUL)
    {
        statusOper      =SUCCESSFUL;
        mcdmDeleteFlag =FALSE;
        if (DelAllMcmdFlag)
        {
            /* Search all timetag MCMDs and delete them                  */ 
            for (i=0, pt =MA_HeaderMcmd; i < MAX_MCMD_TIMETAG; i++,pt++)
            {
                if (pt->Type != NULL_MCMD)
                {
                    /* Release the buffer partition                      */
                    statusOper =OS_piPartReturnBuffer(MA_PART_TT,pt->PtrMCMD);
                    if (statusOper != SUCCESSFUL)
                    {
                        /*@LOG Error during MCMD buffer ereasing - LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_MA,HA_E10_PARTITION_ERR,statusOper);  */
			LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,statusOper);
                        statusOper =HA_E10_PARTITION_ERR;
                        break; 
                    }        
                    pt->Type       =NULL_MCMD;
                    pt->PtrMCMD    =NULL;
                    pt->TimeTag    =0;
                    pt->Length     =0;
                    MA_TimetagCounter--;
                    mcdmDeleteFlag =TRUE;
                }
            }
        }
        else
        { 
            /* Search the timetag MCMD and delete it                     */
            mcdmDeleteFlag =FALSE;
#warning do we want OBT in s or in ms ? if ms, russian must be warned ? TM was in s
            TI_piGetTimeInfo_s(&obt);
            /* Check if timetag to delete is out the OBT window (6 timetag ticks) */
            if (abs(obt - Timetag) > TT_WINDOW_REQUIREMENT)
            {
                for (i=0,pt=MA_HeaderMcmd;(!mcdmDeleteFlag)&&(i<MAX_MCMD_TIMETAG);i++,pt++)
                {
                    /* Check if timetag is found                         */
                    if (pt->TimeTag == Timetag)
                    {
                        /* MCMD found                                    */
                        /* Release the buffer partition                  */
                        statusOper =OS_piPartReturnBuffer(MA_PART_TT,pt->PtrMCMD);
                        if (statusOper != SUCCESSFUL)
                        {
                            /*@LOG Error during MCMD buffer ereasing LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_MA,HA_E10_PARTITION_ERR,statusOper); */
			    LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,statusOper);
                            statusOper =HA_E10_PARTITION_ERR;
                        }        
                        pt->Type       =NULL_MCMD;
                        pt->PtrMCMD    =NULL;
                        pt->TimeTag    =0;
                        pt->Length     =0;
                        MA_TimetagCounter--;
                        mcdmDeleteFlag =TRUE;
                    }
                }
            }
            if (!mcdmDeleteFlag)
            {
                /* MCMD not found, timetag not correct.                  */
                statusOper =HA_E10_MCMD_ERR;
            }
            else 
            {
                /* Check if MCMD in header position has been deleted     */
                if(mcdmDeleteFlag && MA_HeaderMcmd->Type==NULL_MCMD)
                {
                    /* Search the more recent MCMD to execute,           */
                    /* and put it in the header position                 */
                    MA_ifUpdateMcmdHeader(MA_HeaderMcmd,obt);
                }
            }
        }
        if (mcdmDeleteFlag)
        {
            /* MCMD Timetag buffer not full                              */
            MA_TimetagBufFullFlag =FALSE;
        }
        
        /* Release MCMDArea resource                                     */
        status =OS_piResourceRelease (MA_RES);    
    }
    else
    {
        if (status==UNSATISFIED || status==INVALID_ID)
        {
            /*@LOG Semaphore error LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_MA,HA_E10_SEMAPHORE_ERR,status); */
	    LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
            status =HA_E10_SEMAPHORE_ERR;
        }
    }
    /* If resource is correctly obtaneid return operation status         */
    if(status == SUCCESSFUL)
    {
        status =statusOper;
    }
    return (status);

}



/*****************************************************************************/
/* @Function: MA_opGetTlmTimetagRTE                                          */
/* @Purpose :                                                                */
/*  The function returns the MCMD identifier and timetag in the RTE          */
/*  telemetry format. The maximum number of returned MCMD is defined by the  */
/*  constant MAX_TLM_MCMD_TIMETAG and is the first met in the list.          */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  McmdBuffer           OUT     Buffer where MCMD are stored                */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code MA_opGetTlmTimetagRTE (MA_TLM_TIMETAG_RTE* McmdBuffer)
{
MA_HEADER_MCMD*  pH;
MA_TLM_MCMD*     pB;
unsigned short   i;
unsigned int     tt;

    /* Initialize buffer area                            */
    for (i=0, pB =&McmdBuffer->Mcmd[0]; i<MAX_TLM_MCMD_TIMETAG; i++,pB++)
    {
        pB->Id         =0;
        pB->TimetagMsw =0;
        pB->TimetagLsw =0;
    }
    
    /* Copy in Telemetry buffer area the MCMDs           */
    for (i=0,pH =MA_HeaderMcmd,pB =&McmdBuffer->Mcmd[0],tt=0;
         (tt<MA_TimetagCounter)&&(i<MAX_TLM_MCMD_TIMETAG); i++,pH++,pB++)
    {
        /* Check if valid MCMD                           */
        if(pH->Type)
        {
            /* Put MCMD ID and timetag in telemetry area */
            pB->Id         =(unsigned short)(MA_McmdId[pH->Type]);
            pB->TimetagMsw =(unsigned short)(pH->TimeTag>>16);
            pB->TimetagLsw =(unsigned short)(pH->TimeTag&0xffff);
            tt++;
        }
    }
    
    return (SUCCESSFUL);
}



/*****************************************************************************/
/* @Function: MA_opGetMcmdTimetagQueueFull                                   */
/* @Purpose :                                                                */
/*  The function returns the timetag MCMD queue full flag.                   */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  QueueFullFlag        OUT     Variable where flag is stored               */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code MA_opGetMcmdTimetagQueueFull (unsigned int* QueueFullFlag)
{

    *QueueFullFlag =MA_TimetagBufFullFlag;
    return (SUCCESSFUL);

}



/*****************************************************************************/
/* @Function: MA_opGetBufferMCMD                                             */
/* @Purpose :                                                                */
/*  The function returns a MCMD buffer from partition resource.              */
/*  In the TimetagFlag parameter is specified if the buffer to obtain        */
/*  belongs to the partition of the immediate MCMD or with timetag           */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  TimetagFlag          IN      Flag to indicate which partition use        */
/*  Option               IN      Flag which defines if await or no the       */
/*                               resource availability (WAIT, NO_WAIT)       */
/*  Timeout              IN      Timeout value for WAIT option               */
/*  BufMCMD              OUT     Pointer to partition buffer                 */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code MA_opGetBufferMCMD (void**       BufMCMD,
                                unsigned int TimeTagFalg)
{
status_code status;
status_code statusOper;

 if (((status = MA_opLock1553())==SUCCESSFUL))
   {
        /* Check if immediate or timetag MCMD  */
        if (TimeTagFalg == IMMEDIATE_MCMD)
        {
            /* Get the Immadiate MCMDs buffer  */
            statusOper =OS_piPartGetBuffer(MA_PART_IM,BufMCMD);
            if (statusOper != SUCCESSFUL)
            {
                /*@LOG Partition not obtained LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_MA,HA_E10_PARTITION_ERR,statusOper); */
		LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,statusOper);
                statusOper =HA_E10_PARTITION_ERR;
            }
        }
        else if (TimeTagFalg == TIMETAG_MCMD)
        {
            /* Get the Timetag MCMD buffer     */
            statusOper =OS_piPartGetBuffer(MA_PART_TT,BufMCMD);
            if (statusOper != SUCCESSFUL)
            {
                /*@LOG Partition not obtained LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_MA,HA_E10_PARTITION_ERR,statusOper); */
		LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,statusOper);
                statusOper =HA_E10_PARTITION_ERR;
            }
        }
        else 
        {
            statusOper =HA_E10_PARTITION_ERR;
        }
        
        /* Release MCMDArea resource           */
	MA_opRelease1553();
    }
    else
    {
        if (status==UNSATISFIED || status==INVALID_ID)
        {
            /*@LOG Semaphore error  LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_MA,HA_E10_SEMAPHORE_ERR,status); */
	    LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
            status =HA_E10_SEMAPHORE_ERR;
        }
    }
    /* If resource is correctly obtaneid return operation status */
    if(status == SUCCESSFUL)
    {
        status =statusOper;
    }
    return (status);
    
        

}



/*****************************************************************************/
/* @Function: MA_opDelBufferMCMD                                             */
/* @Purpose :                                                                */
/*  The function releases a MCMD buffer from partition resource.             */
/*  In the TimetagFlag parameter is specified if the buffer to release       */
/*  belongs to the partition of the immediate MCMD or with timetag.          */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  BufMCMD              IN      Pointer to the buffer that must be released */
/*  TimetagFlag          IN      Flag to indicate which partition use        */
/*  Option               IN      Flag which defines if await or no the       */
/*                               resource availability (WAIT, NO_WAIT)       */
/*  Timeout              IN      Timeout value for WAIT option               */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code MA_opDelBufferMCMD (void*        BufMCMD,
				unsigned int TimetagFalg)
{
status_code status;
status_code statusOper;


 if (((status = MA_opLock1553())==SUCCESSFUL))
    {
        /* Checks if immediate or timetag MCMD    */
         if (TimetagFalg == IMMEDIATE_MCMD)
        {
            /* Deletes the Immadiate MCMDs buffer */
            statusOper =OS_piPartReturnBuffer(MA_PART_IM,BufMCMD);
            if (statusOper != SUCCESSFUL)
            {
                /*@LOG Partition not released LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_MA,HA_E10_PARTITION_ERR,statusOper); */
		LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,statusOper);
                statusOper =HA_E10_PARTITION_ERR;
            }
        }
        else if (TimetagFalg == TIMETAG_MCMD)
        {
            /* Delete the Timetag MCMDs buffer    */
            statusOper =OS_piPartReturnBuffer(MA_PART_TT,BufMCMD);
            if(statusOper != SUCCESSFUL)
            {

	      /*@LOG Partition not released LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_MA,HA_E10_PARTITION_ERR,statusOper); */
		LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,statusOper);
                statusOper =HA_E10_PARTITION_ERR;
            }
        }
        else 
        {
            statusOper =HA_E10_PARTITION_ERR;
        }
 
        /* Release MCMDArea resource              */
	MA_opRelease1553();
    }
    else
    {
      /*@LOG  Semaphore error LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_MA,HA_E10_SEMAPHORE_ERR,status); */
      LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
      status =HA_E10_SEMAPHORE_ERR;
    }
    /* If resource is correctly obtaneid return operation status */
    if(status == SUCCESSFUL)
    {
        status =statusOper;
    }
    return (status);

}

/*****************************************************************************/
/* @Function: MA_opLock1553                                                  */
/* @Purpose :                                                                */
/*  This function lock the 1553 Buffer shared resource                       */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* SM_EXITCODE          OUT     Lock HBUS request result                     */
/* @@                                                                        */
/*****************************************************************************/
status_code MA_opLock1553()
{
status_code status = SUCCESSFUL;    
unsigned int intLevel;
    
    OS_piInterDisable(&intLevel);
    if (MA_1553IsLocked)
        status = UNSATISFIED;
    else
        MA_1553IsLocked = TRUE;
    OS_piInterEnable(intLevel);
    return status;
}

/*****************************************************************************/
/* @Function: MA_opRelease1553                                               */
/* @Purpose :                                                                */
/*  This function release the 1553 Buffer shared resource                    */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* @@                                                                        */
/*****************************************************************************/
void MA_opRelease1553()
{
unsigned int intLevel;
    
    OS_piInterDisable(&intLevel);
    MA_1553IsLocked = FALSE;
    OS_piInterEnable(intLevel);
}

