/****************************************************************************
/*  F i l e   D a t a                                                        
/*                                                                           
/*  Module       : HKManager                                                   
/*  C.I. No.     :                                                           
/*  $Revision: 1.1.1.1 $
/*  $Date: 2006/04/25 09:00:20 $
/*  Belonging to :                                                           
/*               :                                                           
/*  $RCSfile: HA_HistoryArea_int.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: kusanagi $
/*               :                                                           
/****************************************************************************
/*  U p d a t i n g                                                          
/*                                                                           
/*  $Log: HA_HistoryArea_int.c,v $
/*  Revision 1.1.1.1  2006/04/25 09:00:20  kusanagi
/*  These program extract in an XML format the info contained into the ROOT files generated by YODA from the PAMELA data. To visualize the XML files in a more human readable format a collection of XSL files are given in the Data subfolder.
/*
/*  Revision 1.9  2005/02/21 08:58:28  sebastiani
/*  all log comments completed
/*
/*  Revision 1.8  2005/01/26 18:46:30  sebastiani
/*  *** empty log message ***
/*
/*  Revision 1.7  2004/09/17 15:01:00  faber
/*  LU_INFN_LOG flags fixing
/*
/*  Revision 1.6  2004/08/26 16:54:18  sebastiani
/*  fix some bug
/*
/*  Revision 1.5  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.4  2003/11/18 09:01:14  alfarano
/*  laben patch fixes some problems
/*
/*  Revision 1.3  2003/10/21 16:09:12  alfarano
/*  LU_LOG_INFN replacement for all remaining original log functions
/*
/*  Revision 1.2  2003/08/22 07:51:22  sebastiani
/*  Entry5 now used only for INFN-style logging.
/*  LOGANALIZER directive introduced
/*
/*  Revision 1.1.1.1  2003/08/04 09:40:21  sebastiani
/*  Imported sources laben rel. 19.06.2003 integrated with pam2
/*
/*  Revision 1.9  2003/06/13 08:23:20  aurora
/*  correct the type of entry (E ==> F) in case of HA full
/*
/*  Revision 1.8  2002/11/14 09:49:35  zulia
/*  removed unsed status variable
/*
/*  Revision 1.7  2002/06/11 13:14:25  zulia
/*  Added Entry Type 3 for Direct MCMD
/*
/*  Revision 1.6  2002/05/09 08:16:34  zulia
/*  *  acceptance release
/*
/*                                                                           
/*****************************************************************************/

 
/*============================= Include File ================================*/
  
#include <src/HKManager/HistoryArea/HA_HistoryArea_int.h>
#include <src/HKManager/ReportGenerator/RG_ReportGenerator_p.h>
#include <src/BasicSW/Bus1553B/BI_Bus1553B_p.h> 
#ifdef TEST_I
// #include <src/TestUtility/Test/TS_Test_p.h>
#endif

#include <src/INFN/LU_SourceFileID_INFN.h>
#define __FILEID__ _HA_HistoryArea_int__c
#include <src/INFN/PRH_ParamHandler_INFN_auto.h>
#include <src/INFN/PRH_ParamHandler_INFN.h>
#include <src/INFN/LU_LogUtility_INFN.h>

LU_DECL_MASK();


/*****************************************************************************/
/*===== H i s t o r y   A r e a     I N T E R N A L   F U N C T I O N S =====*/
/*****************************************************************************/

/*****************************************************************************/
/* @Function: HA_ifInit                                                      */
/* @Purpose :                                                                */
/*  This function initilizes all variables of History objects                */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* HistoryArea          IN      pointer to history area array                */
/* p                    IN      pointer to HA structure information          */
/* @@                                                                        */
/*****************************************************************************/
void HA_ifInit( HA_DATA_AREA* HistoryArea, HA_INFO* p )
{
    p->pFreeEntry      = (UWORD*)HistoryArea + OFFSET_FIRST_FREE_LOCATION;
    p->nWordsAvailable = HA_INIT_AVAIL_SIZE;
    p->AnomCounter     = 0;
    p->FullCondition   = FALSE;
    (HistoryArea->HA_DataArea)[HA_SIZE_IN_WORDS-1] = HA_END_FORMAT_ID;
}


/*****************************************************************************/
/* @Function: HA_ifReset                                                     */
/* @Purpose :                                                                */
/*  This function resets all variables of History objects                    */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* HistoryArea          IN      pointer to history area array                */
/* p                    IN      pointer to HA structure information          */
/* PtrMcmd              IN      Pointer to MCMD header                       */
/* @@                                                                        */
/*****************************************************************************/
void HA_ifReset(MA_HEADER_MCMD* PtrMcmd, HA_DATA_AREA* HistoryArea, HA_INFO* p )
{
unsigned short* pMcmdInfo;
unsigned int    timetagFlag;

    /* Extract MCMD parameters and delete it from partition   */
    pMcmdInfo   =(unsigned short* )PtrMcmd->PtrMCMD;
    timetagFlag =(*(pMcmdInfo+1)&TIMETAG_MASK) ? TIMETAG_MCMD : IMMEDIATE_MCMD;
    MA_piDelBufferMCMD(PtrMcmd->PtrMCMD,timetagFlag);

    p->pFreeEntry      = (UWORD*)HistoryArea + OFFSET_FIRST_FREE_LOCATION;
    p->nWordsAvailable = HA_INIT_AVAIL_SIZE;
    p->AnomCounter     = 0;
    p->FullCondition   = FALSE;
    
    /* sets the whole block memory to 0-value
       It is not required by the SR (AU-SRD-3.1.3-0370)
       to fill with zeroes all the History Area          */
    memset(HistoryArea, 0, sizeof(HA_DATA_AREA));
    (HistoryArea->HA_DataArea)[HA_SIZE_IN_WORDS-1] = HA_END_FORMAT_ID;

    /*============= Entry 2 Log in History Area ==========*/
    /*@LOG LOG_INFN HA_piLogHistoryEntry2 (PtrMcmd->Type,HA_E2_MCMD_OK); */
    LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,HA_E2_MCMD_OK);
}



/*****************************************************************************/
/* @Function: HA_ifTraceEvent                                                */
/* @Purpose :                                                                */
/*  This function writes a log into the history area space. It is invoked    */
/*  in reply of a reception of a message for storing a new log.              */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* msg                  IN      Pointer to the message structure.            */
/*                              The field msg.Info contains the entry to be  */
/*                              stored                                       */
/* p                    IN      pointer to the structure of information data */
/* @@                                                                        */
/*****************************************************************************/
void HA_ifTraceEvent(MsgTsk* msg, HA_INFO* p)
{
  TI_TIME        obt;
  HA_CLOSURENTRY cloe;
  
  LU_PutLog(msg);
  #ifdef TEST_I
  //  TS_piPutLog (msg);
  #endif

  /*  msg->LlInfo expresses the length in words of the field Msgtsk.Info
      checks for available space for a new log plus a closure entry  */
  
  /*  the following code switches onto the entry type of the message received and
      increases the anomalies counter (even under full condition)  */
  
  switch( msg->Info[0] >> 4 )
  {
      case HA_EVENT_01:
           if( ((UWORD*)(msg->Info))[3] != 0 ) /* checks the error report */
           {
               p->AnomCounter++;
           }
           break;
      case HA_EVENT_02:
           if( ((UWORD*)(msg->Info))[3] != 0 ) /* checks the error report */
           {
               p->AnomCounter++;
           }
           break;
      
      case HA_EVENT_04:      
      case HA_EVENT_05:
      case HA_EVENT_07:
      case HA_EVENT_10:
      case HA_EVENT_11:      
           p->AnomCounter++;
           break;

      case HA_EVENT_06:  /* checks the error report */
           if( !(((UWORD*)(msg->Info))[0] & 0x80) ) /* test the 7th bit (Type of test) */
           { 
               /* sub-System test - Boot / Init */
               if( ((UWORD*)(msg->Info))[3] != 0 )
               {
                   p->AnomCounter++;
               }
           }
           else
           {
               /* test macrocommand */
               if( (((UWORD*)(msg->Info))[3] & 0x0003) != 0 )
               {
                   p->AnomCounter++;
               }
           }
           break;

      default:
           break;
  }

  if( p->FullCondition == FALSE )
  {
      UBYTE msgwlen;
      
      /* extracts the length(# of words) of the message received */
      msgwlen = msg->Info[0] & 0x0F;

      if( p->nWordsAvailable >= msgwlen + SIZEW_CLOSURE_FULLCOND )
      {
         /* Stores a new log.
            As all entries have different size a general way of storing is used */
          memcpy(p->pFreeEntry, msg->Info, 2*msgwlen );
          p->pFreeEntry      += msgwlen; /* pointer get on of n-words */
          p->nWordsAvailable -= msgwlen; /* decreases the available space of n-words */
      }
      else
      { /* discard: can not store a new log of the current length 
           and the full condition is reached */
           
           p->FullCondition = TRUE;
           
           /* a Full Condition closure entry must be set into the History Area;
              in this case the OBT represents the istant when such condition is reached.
              History area closure due to a full condition implies a sub-type:0x01       */
              
           /* type:0xF, length:0x4, subtype:0x01 */
           cloe.Info = 0xF401;
    
           /* freezes the History Area */
#warning do we want OBT in s or in ms ? if ms, russian must be warned ?
           TI_piGetTimeInfo_ms(&obt);

           cloe.OBTHi  = (UWORD)(obt>>16);
           cloe.OBTLow = (UWORD)(obt & 0x0000FFFF);
           cloe.AnomCounter = p->AnomCounter;
    
           /* tails a Closure Entry in the history area space */
           *(HA_CLOSURENTRY*)(p->pFreeEntry) = cloe;
           /* decreases the available space of four (4) words */
           p->nWordsAvailable -= SIZEW_CLOSURE_FULLCOND;
           
           /* no more free space so the pointer is set to null */
           p->pFreeEntry = NULL_PTR;
      }
  }
}


/*****************************************************************************/
/* @Function: HA_ifPrepareFormat                                             */
/* @Purpose :                                                                */
/*  This function updates the history area buffer frozing it and preparing   */
/*  it accordingly to the telemetry format layout.                           */
/*  It is invoked in reply of a reception of a PREPARE FORMAT macrocommand.  */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* HistoryArea          IN      Pointer to the history area buffer.          */
/* p                    IN      pointer to the structure of information data */
/* @@                                                                        */
/*****************************************************************************/
void HA_ifPrepareFormat( UWORD* HistoryArea, HA_INFO* p )
{
    HA_CLOSURENTRY cloe;
    TI_TIME        obt;
    
    /* checks the full-condition flag: if false a closure entry must be added
       othewise the closure entry is already written but with a different sub-type (01) */

    if( p->FullCondition == FALSE )
    {
        /* type:0xE, length:0x4, subtype:0x00 */
        cloe.Info =CLOSURE_ENTRY;
    
        /* freezes the History Area */
#warning do we want OBT in s or in ms ? if ms, russian must be warned ? TM was in s
        TI_piGetTimeInfo_s(&obt);
        cloe.OBTHi  = (UWORD)(obt >> 16);
        cloe.OBTLow = (UWORD)obt;
        cloe.AnomCounter = p->AnomCounter;
    
        /* tails a Closure Entry in the history area space */
        *(HA_CLOSURENTRY*)(p->pFreeEntry) = cloe;
        
        /* decreases the available space of 4 words */        
        p->nWordsAvailable -= SIZEW_CLOSURE_FULLCOND;
        
        /* the pointer forwards of 4 words16 */
        p->pFreeEntry += SIZEW_CLOSURE_FULLCOND; 
    }

    /* writing the header into History buffer */
    RG_piPrepareHeader(HistoryArea, RG_FORMAT_HA);

    /* copying History into 1553B buffer */
    BI_pi1553BWriteHistory(HistoryArea);
}

