///****************************************************************
// ****************************************************************
// **                                                            **
// **    (C)Copyright 2005-2006, American Megatrends Inc.        **
// **                                                            **
// **            All Rights Reserved.                            **
// **                                                            **
// **        6145-F, Northbelt Parkway, Norcross,                **
// **                                                            **
// **        Georgia - 30071, USA. Phone-(770)-246-8600.         **
// **                                                            **
// ****************************************************************
// ****************************************************************/
///*****************************************************************
// *
// * Session.c
// * Session related functions
// *
// * Author: Govind Kothandapani <govindk@ami.com>
// * 		 : Rama Bisa <ramab@ami.com>
// *       : Basavaraj Astekar <basavaraja@ami.com>
// *       : Bakka Ravinder Reddy <bakkar@ami.com>
// *
// *****************************************************************/
//#define ENABLE_DEBUG_MACROS    0
#include "com_IPMIDefs.h"
//#include "MsgHndlr.h"
#include "PMConfig.h"
//#include "SharedMem.h"
//#include "NVRAccess.h"
#include "Session.h"
//#include "Debug.h"
////#include "SerialRegs.h"
//#include "SensorEvent.h"
#include "com_IPMI_Sensor.h"
#include "Support.h"
//#include "Ethaddr.h"
#include "AppDevice.h"
#include "MsgHndlr.h"
#include <stdio.h>
#include "main.h"
#include <string.h>
#include <time.h>
#include "com_IPMI_SensorEvent.h"

//#define TOTAL_INFINITE_CMDS  sizeof(m_InfiniteCmdsTbl)/sizeof(IPMICmdsFilterTbl_T)

//static IPMICmdsFilterTbl_T m_InfiniteCmdsTbl [] =
//{     /* NetFn */       /*  Command#   */
//	{   NETFN_AMI,  CMD_AMI_YAFU_COMMON_NAK             },
//	{   NETFN_AMI,  CMD_AMI_YAFU_GET_FLASH_INFO         },	
//	{   NETFN_AMI,	CMD_AMI_YAFU_GET_FIRMWARE_INFO	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_GET_FMH_INFO	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_GET_STATUS,	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_ACTIVATE_FLASH	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_ALLOCATE_MEMORY	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_FREE_MEMORY	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_READ_FLASH	            },
//	{   NETFN_AMI,	CMD_AMI_YAFU_WRITE_FLASH	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_ERASE_FLASH	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_PROTECT_FLASH	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_ERASE_COPY_FLASH	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_VERIFY_FLASH	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_READ_MEMORY	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_WRITE_MEMORY	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_COPY_MEMORY	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_COMPARE_MEMORY	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_CLEAR_MEMORY	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_GET_BOOT_CONFIG	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_SET_BOOT_CONFIG	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_GET_BOOT_VARS	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_DEACTIVATE_FLASH_MODE  },
//	{   NETFN_AMI,	CMD_AMI_YAFU_RESET_DEVICE	    },
//	{   NETFN_AMI,	CMD_AMI_YAFU_GET_ECF_STATUS         },
//	{   NETFN_AMI,	CMD_AMI_YAFU_GET_VERIFY_STATUS	    },
//	{   NETFN_AMI,	CMD_AMI_GET_CHANNEL_NUM	            },
//	{   NETFN_AMI,	CMD_AMI_GET_ETH_INDEX	            },
//	{   NETFN_AMI,	CMD_AMI_START_TFTP_FW_UPDATE    },
//	{   NETFN_AMI,	CMD_AMI_GET_TFTP_FW_PROGRESS_STATUS },
//	{   NETFN_AMI,	CMD_AMI_SET_FW_CONFIGURATION    },
//       {   NETFN_AMI,       CMD_AMI_GET_FW_CONFIGURATION    },
//       {   NETFN_AMI,       CMD_AMI_SET_FW_PROTOCOL},
//       {   NETFN_AMI,       CMD_AMI_GET_FW_PROTOCOL},
//       {   NETFN_AMI,       CMD_AMI_YAFU_FIRMWARE_SELECT_FLASH},

//};

/*********************************************************************************************
   Name	:	SessionTimeOutTask
   Input	:	void
   Output	:	void
       This program  checks for session timeout
*********************************************************************************************/
void SessionTimerTask (void)
{
   	SessionTblInfo_T*	pSessionTblInfo = &g_BMCInfo.SessionTblInfo;
   uint8_t				Index;
//   char solsessionfile[MAXFILESIZE] = {0};
   struct stat fp;

//   printf("-> SessionTimerTask\n");
   for (Index=0; Index < g_BMCInfo.IpmiConfig.MaxSession; Index++)
   {
       if (FALSE == pSessionTblInfo->SessionTbl[Index].Used)
       {
           continue;
       }

       // if(g_BMCInfo.IpmiConfig.SerialIfcSupport == 1)
       // {
       //     if (g_BMCInfo.SERIALch == pSessionTblInfo->SessionTbl[Index].Channel)
       //     {
       //         continue;
       //         if (!(g_BMCInfo.SMConfig.SessionTermination & 0x02)) /* If Session Inactivity timeout disabled */
       //         {
       //             continue;
       //         }
       //         else if (0 == g_BMCInfo.SMConfig.SessionInactivity) /* Never Time Out */
       //         {
       //             continue;
       //         }
       //     }
       // }

      if (pSessionTblInfo->SessionTbl[Index].TimeOutValue > 0)
      {
         pSessionTblInfo->SessionTbl[Index].TimeOutValue--;
         continue;
      }
       

       printf ("\nSessionTimerTask: Session Time Out Occured\n");
       printf ("SessionID = 0x%lX  Num of Sessions = %X\n", pSessionTblInfo->SessionTbl[Index].SessionID,
                       pSessionTblInfo->Count);

       // if(pBMCInfo->IpmiConfig.SerialIfcSupport == 1)
       // {
       //     if (pBMCInfo->SERIALch == pSessionTblInfo->SessionTbl[Index].Channel)
       //     {
       //         BMC_GET_SHARED_MEM (BMCInst)->SerialSessionActive = FALSE;
       //     }
       // }

       /* Delete the Session from session table */
       DeleteSession (&pSessionTblInfo->SessionTbl[Index]);
   }
}


///*********************************************************************************************
//    Name	:	getChannelInfo
//    Input	:	ch	-	ChannelNumber
//    Output	:	channelInformations
//        This program  returns informations about the channel
//*********************************************************************************************/
// ChannelInfo_T* getChannelInfo (uint8_t ch )
//{
//    uint8_t Index;
//    ChcfgInfo_T *pChannelInfo=NULL;
//     BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];

//    if(IsLANChannel(ch, BMCInst))
//    {
//        if(pBMCInfo->IpmiConfig.LANIfcSupport != 1)
//        {
//            return NULL;
//        }
//    }else
//    {
//        if( PRIMARY_IPMB_CHANNEL == ch && pBMCInfo->IpmiConfig.PrimaryIPMBSupport != 1 )
//        {
//            return NULL;
//        }
//        else if (pBMCInfo->IpmiConfig.SecondaryIPMBSupport != 1 && (pBMCInfo->SecondaryIPMBCh != CH_NOT_USED && ch == pBMCInfo->SecondaryIPMBCh))
//        {
//            return NULL;
//        }
//        else if (pBMCInfo->IpmiConfig.SerialIfcSupport != 1 && (pBMCInfo->SERIALch != CH_NOT_USED && ch == pBMCInfo->SERIALch))
//        {
//            return NULL;
//        }
//        else if (pBMCInfo->IpmiConfig.ICMBIfcSupport != 1 && (pBMCInfo->ICMBCh != CH_NOT_USED && ch == pBMCInfo->ICMBCh))
//        {
//            return NULL;
//        }
//        else if (pBMCInfo->IpmiConfig.SMBUSIfcSupport !=1 && (pBMCInfo->SMBUSCh != CH_NOT_USED && ch == pBMCInfo->SMBUSCh))
//        {
//            return NULL;
//        }
//        else if (pBMCInfo->IpmiConfig.USBIfcSupport != 1 && (ch == USB_CHANNEL))
//        {
//            return NULL;
//        }
//        else if (pBMCInfo->IpmiConfig.SMMIfcSupport != 1 && (pBMCInfo->SMMCh != CH_NOT_USED && ch == pBMCInfo->SMMCh))
//        {
//            return NULL;
//        }
//        else if(pBMCInfo->IpmiConfig.SYSIfcSupport !=1 && ch == SYS_IFC_CHANNEL)
//        {
//            return NULL;
//        }
//    }

//    for(Index=0;Index<MAX_NUM_CHANNELS;Index++)
//    {
//        if(pBMCInfo->ChConfig[Index].ChType != 0xff)
//        {
//            pChannelInfo = &pBMCInfo->ChConfig[Index];
//            //printf("Channel numb is %x %x \n",pChannelInfo->ChannelInfo.ChannelNumber,ch);
//            if(pChannelInfo->ChannelInfo.ChannelNumber == ch)
//            {
//                return (ChannelInfo_T *)&pBMCInfo->ChConfig[Index].ChannelInfo;
//            }
//        }
//    }

//    return NULL;
//}

// int UpdateUserInfoTable(void)
// {
//     uint8_t buf[1000];
//     uint8_t UserNameLen = 0;
//     uint8_t PassWordLen = 0;
//     uint8_t *pUserName;
//     uint8_t *pPassword;
//     uint8_t *pStr;
//     uint8_t usercnt = 0;
//     uint32_t len = 0;
//     uint8_t     namesize = 0;
//     FILE *fp = NULL;


//     printf("\n\nUpdateUserInfoTable\n");

//     fp = fopen(AUTH_FILE_PATH, "r");
//     if(fp == NULL)
//     {
//         printf("Open %s fail!\n", AUTH_FILE_PATH);
//         return -1;
//     }

//     while(fgets(buf, 1000, fp) != NULL){
//         pStr = buf;

//         //remove blank
//         while(*pStr == ' ')
//         {
//             pStr++;
//         }

//         if(strncmp(pStr, "user name=", 10) == 0)
//         {
//             pStr+=10;
//             //get name
//             pUserName = pStr;
//             UserNameLen = 0;
//             while(*pStr != ' ')
//             {
//                 UserNameLen++;
//                 pStr++;
//             }

//             memset(g_BMCInfo.UserInfoTbl[usercnt].UserName, 0, MAX_USERNAME_LEN);
//             memcpy(g_BMCInfo.UserInfoTbl[usercnt].UserName, pUserName, UserNameLen);
            
//             //remove blank
//             while(*pStr == ' ')
//             {
//                 pStr++;
//             }
//             if(strncmp(pStr, "password=", 9) == 0)
//             {
//                 pStr += 9;
//                 //get password
//                 pPassword = pStr;
//                 PassWordLen = 0;
//                 while(*pStr != ' ')
//                 {
//                     PassWordLen++;
//                     pStr++;
//                 }

//                 memset(g_BMCInfo.UserInfoTbl[usercnt].UserPassword, 0, MAX_PASSWORD_LEN);
//                 memcpy(g_BMCInfo.UserInfoTbl[usercnt].UserPassword, pPassword, PassWordLen);
            
//                 g_BMCInfo.UserInfoTbl[usercnt].UserId = usercnt;

//                 if(usercnt < 10)
//                     usercnt++;
//                 else
//                     break;
//             }
//             else
//                 continue;
//         }
//         else
//             continue;
//     }

//     g_BMCInfo.CurrentNoUser = usercnt;
//     fclose(fp);

//     return 0;
// }
/*********************************************************************************************
    Name	:	CheckForDuplicateUsers
    Input	:	UserName - Name of the User
    Output	:	returns 0 for success and -1 for failure
        This program  returns Informations about the user
*********************************************************************************************/
uint8_t CheckForDuplicateUsers ( uint8_t* UserName)
{
	int i = 0;
    
    for(i=0; i<MAX_USER_NUM; i++)
    {
        if(g_BMCInfo.UserInfoTbl[i].UserId != 0)
        {
            if ((0 == strcmp(g_BMCInfo.UserInfoTbl[i].UserName, UserName)) \
              && (TRUE == g_BMCInfo.UserInfoTbl[i].UserStatus))
                return FALSE;
        }
    }	
    return TRUE;    
}

/*********************************************************************************************
    Name	:	getUserIdInfo
    Input	:	UserID - User ID
    Output	:	User information
        This program  returns Informations about the user
*********************************************************************************************/
UserInfo_T*	getUserIdInfo (uint8_t UserId)
{
    if (UserId == 0) { return NULL; }

    if (UserId <= MAX_USER_NUM)
    {
        return &g_BMCInfo.UserInfoTbl[UserId-1];
    }
    else
    {
        return NULL;
    }
}

/*********************************************************************************************
    Name	:	getUserNameInfo
    Input	:	UserName - User name
    Output	:	User information
        This program  returns Informations about the user
*********************************************************************************************/
UserInfo_T*	getUserNameInfo (uint8_t *UserName)
{
   int i = 0;

   if (UserName[0] == 0) { return NULL; }
   if( (UserName[0] >= '0') && (UserName[0] <= '9') ) {return NULL;}

	for (i = 0; i < MAX_USERNAME_LEN; i++)
	{
		if(UserName[i] > 127)
		{
			return NULL;
		}
	}    
	
    for(i=0; i < MAX_USER_NUM; i++)
    {
        //if(g_BMCInfo.UserInfoTbl[i].UserId != 0)
        {
            if (0 == strcmp(g_BMCInfo.UserInfoTbl[i].UserName, UserName))
            {
                return &g_BMCInfo.UserInfoTbl[i];
            }
        }
    }	

	return NULL;
}

///*********************************************************************************************
//    Name	:	getChUserPrivInfo
//    Input	:	userName - user name
//    			Role - requested role
//                chIndex - channel's user index
//                pChUserInfo - channel's user information
//    Output	:	channel's matching user Information

//This program returns information about the user for the given channel,
//        & Index of the user in Channel User Array.
//*********************************************************************************************/
// ChannelUserInfo_T* getChUserPrivInfo ( char *userName,  uint8_t Role,  uint8_t* chIndex,  ChannelUserInfo_T *pChUserInfo, int BMCInst)
//{
//     UserInfo_T* pUserTable = (UserInfo_T *) GetNVRUsrCfgAddr (NVRH_USERCONFIG, BMCInst);
//    int userIndex;
//     BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];

//    /* search the table */
//    for(userIndex = 0; userIndex < pBMCInfo->IpmiConfig.MaxUsers; userIndex++)
//    {
//        for(*chIndex = 0; *chIndex < pBMCInfo->IpmiConfig.MaxChUsers; (*chIndex)++)
//        {
//            if ((Role <= pChUserInfo[*chIndex].AccessLimit) &&
//                (1 == pUserTable[userIndex].UserStatus) &&
//                (pUserTable[userIndex].UserId == pChUserInfo[*chIndex].UserId))
//                {
//                    /* if userName is not NULL then it is username/privilege
//                    lookup else it is name_only lookup */
//                    if (0 != *userName)
//                    {
//                        if (0 != _fmemcmp(pUserTable[userIndex].UserName, userName, MAX_USERNAME_LEN))
//                        {
//                            continue;
//                        }
//                    }
//                    return (pChUserInfo + *chIndex);
//                }
//        }
//    }
//    return NULL;
//}

///*********************************************************************************************
//    Name	:	getChUserInfo
//    Input	:	userName - user name
//                chIndex - to return Index of user in channelUser Array
//                pChUserInfo - channel's user information
//    Output	:	channel's matching user Information

//This program returns information about the user for the given channel,
//        & Index of the user in Channel User Array.
//*********************************************************************************************/
// ChannelUserInfo_T* getChUserInfo ( char *userName,   uint8_t* chIndex,  ChannelUserInfo_T *pChUserInfo )
//{
//     UserInfo_T* pUserTable = (UserInfo_T *) GetNVRUsrCfgAddr (NVRH_USERCONFIG, BMCInst);
//     BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
//    int userIndex;

//    /* search the table */
//    for(userIndex = 0; userIndex < pBMCInfo->IpmiConfig.MaxUsers; userIndex++)
//    {
//        for(*chIndex = 0; *chIndex < pBMCInfo->IpmiConfig.MaxChUsers; (*chIndex)++)
//        {
//            if ((0 == _fmemcmp(pUserTable[userIndex].UserName, userName, MAX_USERNAME_LEN)) &&
//                /* Commented to return the pointer for disabled user */ 
//                /* (1 == pUserTable[userIndex].UserStatus) && */
//                (pUserTable[userIndex].UserId == pChUserInfo[*chIndex].UserId))
//            return (pChUserInfo + *chIndex);
//        }
//    }
//    return NULL;
//}

///*********************************************************************************************
//    Name	:	getChUserIdInfo
//    Input	:	userId - User ID
//                Index - to return Index of user in channelUser Array.
//                pChUserInfo - channel's user information
//    Output	:	channel's matching user Information

//This program returns information about the user for the given channel,
//                & Index of the user inChannel User Array.

//*********************************************************************************************/
// ChannelUserInfo_T* getChUserIdInfo (uint8_t userId,  uint8_t *Index,  ChannelUserInfo_T*	pChUserInfo, int BMCInst)
//{
//     BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];

//    if (userId == 0) { return NULL; }

//    for(*Index=0; *Index < pBMCInfo->IpmiConfig.MaxChUsers; (*Index)++)
//    {
//        if ((pChUserInfo->UserId == userId) && ((pChUserInfo->ID == USER_ID )))
//        {
//            return pChUserInfo;
//        }
//        pChUserInfo++;
//    }
//    return NULL;
//}

///*********************************************************************************************
//    Name	:	GetNVRChConfigs
//    Input	:	pChannelInfo -Channel Information
//                        Filename - Channel Name Information
//    Output	:	Respective Channel's Information

//This program returns information about the respective channel.

//*********************************************************************************************/
//ChannelInfo_T* GetNVRChConfigs(ChannelInfo_T *pChannelInfo, int BMCInst)
//{
//    int i=0;
//    ChannelInfo_T *pNVRChInfo=NULL;

//     BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
//    for(i=0;i<MAX_NUM_CHANNELS;i++)
//    {
//        if( pBMCInfo->NVRChcfgInfo[i].ChType != 0xff)
//        {
//            pNVRChInfo = &pBMCInfo->NVRChcfgInfo[i].ChannelInfo;
//            if(pChannelInfo->ChannelNumber == pNVRChInfo->ChannelNumber)
//            {
//                return (ChannelInfo_T *)&pBMCInfo->NVRChcfgInfo[i].ChannelInfo;
//            }
//        }
//    }
//    return NULL;
//}

///**
//*@fn GetNVRChUserConfigs 
//*@brief This function is invoked to get NVR User informations of the channel
//*@param pChannelInfo - Channel Information
//*@param Filename - Size of the SDR repository
//*@return Returns Address of user information for the channel on success
//*              Returns NULL on Failure
//*/
//ChannelUserInfo_T* GetNVRChUserConfigs(ChannelInfo_T *pChannelInfo, int BMCInst)
//{
//    int i=0;
//    ChannelInfo_T *pNVRChInfo = NULL;
//     BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];

//    for(i=0;i<MAX_NUM_CHANNELS;i++)
//    {
//        if(pBMCInfo->NVRChcfgInfo [i].ChType != 0xff)
//        {
//            pNVRChInfo = &pBMCInfo->NVRChcfgInfo[i].ChannelInfo;
//            if(pChannelInfo->ChannelNumber == pNVRChInfo->ChannelNumber)
//            {
//                return (ChannelUserInfo_T *)&pBMCInfo->NVRChcfgInfo[i].ChannelInfo.ChannelUserInfo[0];
//            }
//        }
//    }
//    return NULL;
//}



/*********************************************************************************************
    Name	:	getSessionInfo
    Input	:	Arg - Tells the type of data passed in Session
                Session - Either one of these: session ID, session handle, session index or
                channel number
    Output	:	Session Information

This program  returns the session information.
*********************************************************************************************/
SessionInfo_T* getSessionInfo (uint8_t Arg,  void *Session)
{
   uint8_t				Index;
   uint8_t				ActiveSesIndex = 0;
   SessionTblInfo_T*	pSessionTblInfo = &g_BMCInfo.SessionTblInfo;

   for (Index = 0; Index < g_BMCInfo.IpmiConfig.MaxSession; Index++)
   {
       if (FALSE == pSessionTblInfo->SessionTbl[Index].Used)
       {
           continue;
       }
       if (TRUE == pSessionTblInfo->SessionTbl[Index].Activated)
       {
           ActiveSesIndex++;
       }

       switch (Arg)
       {
       case SESSION_ID_INFO:
           if(pSessionTblInfo->SessionTbl[Index].SessionID == *((uint32_t *)Session) )
           {
               return &pSessionTblInfo->SessionTbl[Index];
           }
           break;

       // case SESSION_REMOTE_INFO:
       //     if(pSessionTblInfo->SessionTbl[Index].RemConSessionID == *((uint32_t *)Session) )
       //     {
       //         return &pSessionTblInfo->SessionTbl[Index];
       //     }
       //     break;

       case SESSION_HANDLE_INFO:
           if (pSessionTblInfo->SessionTbl[Index].SessionHandle == *(( uint8_t*)Session) && pSessionTblInfo->SessionTbl[Index].Activated)
           {
           	//printf("---> SessionHandle = %#x\n",pSessionTblInfo->SessionTbl[Index].SessionHandle);
               return &pSessionTblInfo->SessionTbl[Index];
           }
           break;

       case SESSION_INDEX_INFO:
           if (ActiveSesIndex == *(( uint8_t*)Session))
           {
               return &pSessionTblInfo->SessionTbl[Index];
           }
           break;

       case SESSION_CHANNEL_INFO:
           if (pSessionTblInfo->SessionTbl[Index].Channel == *(( uint8_t*)Session))
           {
               return &pSessionTblInfo->SessionTbl[Index];
           }
           break;

       default:
           return NULL;
       }
   }
   return NULL;
}

///*********************************************************************************************
//    Name	: AddChUser
//    Input	: ChannelUserInfo
//    Output	: Pointer to the free entry from the channel's user table.
//This program returns the free entry from the channel's user table.
//*********************************************************************************************/
// ChannelUserInfo_T* AddChUser ( ChannelUserInfo_T* pChUserInfo,  uint8_t*	Index, int BMCInst)
//{
//     BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];

//    *Index =0;
//    while (*Index <pBMCInfo->IpmiConfig.MaxChUsers)
//    {
//        if(FALSE == pChUserInfo->IPMIMessaging )
//        {
//            if(pChUserInfo->ID != USER_ID )
//                return pChUserInfo;
//        }
//        (*Index)++;
//        pChUserInfo++;
//    }
//    return NULL;
//}


/*---------------------------------------
* GetSelTimeStamp
*---------------------------------------*/
uint32_t
GetTimeStamp(void)
{
   return (time(NULL));
}

/*********************************************************************************************
   Name	:	GetNumOfActiveSessions
   Input	:	Nothing
   Output	:	Number of active Sessions

This program returns the number of active session(s) from the session table
*********************************************************************************************/
uint8_t GetNumOfActiveSessions (void)
{
   uint8_t				Index, Count = 0;
   SessionTblInfo_T*	pSessionTblInfo = &g_BMCInfo.SessionTblInfo;

   for (Index = 0; Index < g_BMCInfo.IpmiConfig.MaxSession; Index++)
   {
       if (FALSE == pSessionTblInfo->SessionTbl[Index].Used)
       {
           continue;
       }
       if (pSessionTblInfo->SessionTbl[Index].Activated)
           Count++;
   }

   return Count;
}

/*********************************************************************************************
   Name	:	GetNumOfUsedSessions
   Input	:	Nothing
   Output	:	Number of used Sessions

This program returns the number of used session(s) from the session table
*********************************************************************************************/
uint8_t GetNumOfUsedSessions (void)
{
   uint8_t				Index, Count = 0;
   	SessionTblInfo_T*	pSessionTblInfo = &g_BMCInfo.SessionTblInfo;

   for (Index = 0; Index < g_BMCInfo.IpmiConfig.MaxSession; Index++)
   {
       if (FALSE == pSessionTblInfo->SessionTbl[Index].Used)
       {
           continue;
       }
           Count++;
   }

   return Count;
}


/*********************************************************************************************
   Name	:	CleanSession
   Input	:	Nothing
   Output	:	None

This program delete the oldest session filled but not activate
*********************************************************************************************/
uint8_t  CleanSession(void)
{
   uint8_t			Index;
   OldSessionInfo_T     OldSession;
   SessionTblInfo_T*	pSessionTblInfo = &g_BMCInfo.SessionTblInfo;

   OldSession.Time=0xFFFFFFFF;
   OldSession.Index= 0xFF;

   for (Index = 0; Index < g_BMCInfo.IpmiConfig.MaxSession; Index++)
   {
       if (TRUE == pSessionTblInfo->SessionTbl[Index].Activated)
       {
           continue;
       }

       if(pSessionTblInfo->SessionTbl[Index].Time <OldSession.Time )
       {
           OldSession.Time=pSessionTblInfo->SessionTbl[Index].Time;
           OldSession.Index=Index;
       }
   }

   if(OldSession.Index !=0xFF)
   {
       pSessionTblInfo->SessionTbl[OldSession.Index].Used = FALSE;
       pSessionTblInfo->Count--;
       pSessionTblInfo->SessionTbl[OldSession.Index].Time=0xffffffff;
   }else
   {
       return FALSE;
   }

   return TRUE;
}


/*********************************************************************************************
   Name	:	DeleteSession
   Input	:	pSessionInfo - session information
   Output	:	Nothing

This program deletes the session from the session table
*********************************************************************************************/
void DeleteSession( SessionInfo_T*	pSessionInfo)
{
   uint8_t			Index;		 
   	SessionTblInfo_T*	pSessionTblInfo = &g_BMCInfo.SessionTblInfo;
   	UserInfo_T*		 pUserInfo;
      ChannelInfo_T *      pChannelInfo;


   for (Index = 0; Index < g_BMCInfo.IpmiConfig.MaxSession; Index++)
   {
       if (FALSE == pSessionTblInfo->SessionTbl[Index].Used)
       {
           continue;
       }

       if (0 == memcmp (&pSessionTblInfo->SessionTbl[Index], pSessionInfo , sizeof(SessionInfo_T)))
       {
           /* We have decrement  the Active session only .If session is activated */
           if(TRUE ==pSessionTblInfo->SessionTbl[Index].Activated)
           {
               // if(!pSessionTblInfo->SessionTbl[Index].IsLoopBack)
               // {
               //     pChannelInfo= getChannelInfo(pSessionInfo->Channel);
               //     if(NULL == pChannelInfo)
               //     {
               //         TDBG("Failed to get channel info while Deleting Session for Channel: %d\n",pSessionInfo->Channel);
               //         return;
               //     }

               //     if(pChannelInfo!=NULL)
               //     pChannelInfo->ActiveSession--;
               //     pUserInfo = getUserIdInfo (pSessionInfo->UserId);
               //     if (pUserInfo != NULL) { pUserInfo->CurrentSession--; }
               // }
               pSessionTblInfo->SessionTbl[Index].Activated=FALSE;
               pSessionTblInfo->SessionTbl[Index].EventFlag = 0;
           }

           pSessionTblInfo->SessionTbl[Index].Used = FALSE;
           pSessionTblInfo->Count--;
           pSessionTblInfo->SessionTbl[Index].Time=0xFFFFFFFF;

           //printf("DeleteSession: SessionID = %lX	Num Session %X\t%x\n",
           //pSessionInfo->SessionID, pSessionTblInfo->Count,Index);
           return;
       }
   }

   return;
}

/*********************************************************************************************
   Name	:	AddSession
   Input	:	pSessionInfo - session information
   Output	:	Nothing

This program adds the session to the session table
*********************************************************************************************/
void AddSession ( SessionInfo_T* pSessionInfo)
{
   uint8_t Index;
   	SessionTblInfo_T*	pSessionTblInfo = &g_BMCInfo.SessionTblInfo;


   for (Index = 0; Index < g_BMCInfo.IpmiConfig.MaxSession; Index++)
   {
       if (FALSE == pSessionTblInfo->SessionTbl[Index].Used)
       {
           memcpy (&pSessionTblInfo->SessionTbl[Index], ( uint8_t*)pSessionInfo, sizeof (SessionInfo_T));
           pSessionTblInfo->SessionTbl[Index].Used = TRUE;
           pSessionTblInfo->Count++;
           pSessionTblInfo->SessionTbl[Index].Time= GetTimeStamp ();
           pSessionTblInfo->SessionTbl[Index].TimeOutValue=g_BMCInfo.IpmiConfig.SessionTimeOut;
//           printf ("AddSession: SessionID   = %lX  Num Session %X\t%x\n",pSessionInfo->SessionID, pSessionTblInfo->Count,Index);
           break;
       }
   }

}

// /*********************************************************************************************
//    Name	:	getPayloadActiveInst
//    Input	:	PayloadType
//    Output	:	Activated Instance information of a given payload type.

// This program returns the information about the activated instances of a given payload type.
// *********************************************************************************************/
// uint16_t getPayloadActiveInst (uint8_t PayloadType)
// {
//    uint8_t   PayloadIx;
//    uint8_t   Index;
//    uint16_t	ActivatedInst = 0;
//    	SessionTblInfo_T*	pSessionTblInfo = &g_BMCInfo.SessionTblInfo;


//    for (Index = 0; Index < g_BMCInfo.IpmiConfig.MaxSession; Index++)
//    {
//        if (FALSE == pSessionTblInfo->SessionTbl[Index].Used)
//        {
//            continue;
//        }
//        if (FALSE == pSessionTblInfo->SessionTbl[Index].Activated)
//        {
//            continue;
//        }

//        for (PayloadIx = 0; PayloadIx < MAX_PYLDS_SUPPORT; PayloadIx++)
//        {
//            if (pSessionTblInfo->SessionTbl[Index].SessPyldInfo [PayloadIx].Type == PayloadType)
//            {
//                ActivatedInst |= pSessionTblInfo->SessionTbl[Index].SessPyldInfo [PayloadIx].ActivatedInst;
//            }
//        }
//    }

//    return ActivatedInst;
// }

///*********************************************************************************************
//    Name	:	getPayloadInstInfo
//    Input	:	Payloadtype, PayloadInst
//    Output	:	sessionID

//This program  returns the session ID of the session that was activated under the given payload 
//type and payload instance.
//*********************************************************************************************/
// uint32_t getPayloadInstInfo (uint8_t PayloadType, uint16_t PayloadInst, int BMCInst)
//{
//    uint8_t   PayloadIx;
//    uint8_t   Index;
//     BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
//    	SessionTblInfo_T*	pSessionTblInfo = &pBMCInfo->SessionTblInfo;


//    for (Index = 0; Index < pBMCInfo->IpmiConfig.MaxSession; Index++)
//    {
//        if (FALSE == pSessionTblInfo->SessionTbl[Index].Used)
//        {
//            continue;
//        }
//        if (FALSE == pSessionTblInfo->SessionTbl[Index].Activated)
//        {
//            continue;
//        }

//        for (PayloadIx = 0; PayloadIx < MAX_PYLDS_SUPPORT; PayloadIx++)
//        {
//            if ((pSessionTblInfo->SessionTbl[Index].SessPyldInfo [PayloadIx].Type == PayloadType)
//                && (pSessionTblInfo->SessionTbl[Index].SessPyldInfo [PayloadIx].ActivatedInst & (1 << (PayloadInst - 1))))
//            {
//                return pSessionTblInfo->SessionTbl[Index].SessionID;
//            }
//        }
//    }

//    return 0;
//}

static
MsgPkt_T m_MsgPkt = {
   PARAM_IFC,
   0,                  /* Channel number not needed    */
   0,                /* Source queue not needed      */
   CMD_PLATFORM_EVENT, /* Cmd                          */
   (NETFN_SENSOR << 2),/* Net Function                 */
   PRIV_LOCAL,         /* Privilage                    */
   0,                  /* Session ID not needed        */
//   0,
   WAIT_INFINITE,
   0,
   {0},                /* IP Addr not needed           */
   0,                  /* UDPPort not needed           */
   0,                  /* Socket  not needed           */
   sizeof(SELEventRecord_T) + sizeof (IPMIMsgHdr_T) + 1,
   {
       0x20,               /* Generator ID             */
       IPMI_EVM_REVISION,  /* IPMI Version             */
       SENSOR_TYPE_SECUIRTY_VIOLATION,/*SensorType     */
       SECUIRTY_VIOLATION_SENSOR_NUMBER,
       SENSOR_SPECIFIC_READ_TYPE,
       PW_VIOLATION_OFFSET,
       0xff,
       0xff
   },
};

/*--------------------------------------------------------------------------*
* PasswordViolation														*
*--------------------------------------------------------------------------*/
void
PasswordViolation (void)
{
   /* Log the AC fail event to SEL	& send an alert */
   /* Post to Message Hndlr Queue	*/
   PostMsg ( gFd_MsgHndlrIfc, &m_MsgPkt);

   return;
}



/*********************************************************************************************
   Name	:	UDSSessionTimeOutTask
   Input	:	void
   Output	:	void
       This program  checks for UDS session timeout
*********************************************************************************************/
void UDSSessionTimerTask (void)
{
   uint8_t Index=0;
   UDSSessionTblInfo_T *pUDSSessionTblInfo = &g_BMCInfo.UDSSessionTblInfo;

//   printf("-> UDSSessionTimerTask\n");
   for(Index=0;Index<g_BMCInfo.IpmiConfig.MaxSession;Index++)
  {
       if(FALSE == pUDSSessionTblInfo->UDSSessionTbl[Index].Activated)
       {
          /* Continue until we find the Next Slot which is being used to reduce the timeout */
           continue;
       }

       if(pUDSSessionTblInfo->UDSSessionTbl[Index].SessionTimeoutValue > 0)
       {
          /* Reduce the Session Timeout Value if the session is not used */
           pUDSSessionTblInfo->UDSSessionTbl[Index].SessionTimeoutValue--;
           continue;
       }
       
      DeleteUDSSession(&pUDSSessionTblInfo->UDSSessionTbl[Index]);
  }
}



/*********************************************************************************************
   Name	:	GetUDSSessionInfo
   Input	:	Session - session ID
   Output	:	Session Information

This program  returns the session information.
*********************************************************************************************/
UDSSessionTbl_T* GetUDSSessionInfo (uint8_t Type,void* Data )
{
   uint8_t Index;
    UDSSessionTblInfo_T*	pUDSSessionTblInfo = &g_BMCInfo.UDSSessionTblInfo;


   for(Index=0;Index<g_BMCInfo.IpmiConfig.MaxSession;Index++)
   {

       if(FALSE == pUDSSessionTblInfo->UDSSessionTbl[Index].Activated)
       {
           continue;
       }

       switch(Type)
       {
           case UDS_SESSION_ID_INFO:
               if(*((uint32_t *)Data) == pUDSSessionTblInfo->UDSSessionTbl[Index].SessionID)
               {
                    return &pUDSSessionTblInfo->UDSSessionTbl[Index];
               }
               break;
            case UDS_SESSION_HANDLE_INFO:
               if(*((uint8_t *)Data) == pUDSSessionTblInfo->UDSSessionTbl[Index].LoggedInSessionHandle)
               {
                    return &pUDSSessionTblInfo->UDSSessionTbl[Index];
               }
               break;
            case UDS_SESSION_INDEX_INFO:
               if((*((uint8_t *)Data) < g_BMCInfo.IpmiConfig.MaxSession) && ((Index) == *((uint8_t *)Data )))
               {
                   return &pUDSSessionTblInfo->UDSSessionTbl[Index];
               }
               break;
            case UDS_SOCKET_ID_INFO:
               if(*((int *)Data) == pUDSSessionTblInfo->UDSSessionTbl[Index].UDSSocket)
               {
                    return &pUDSSessionTblInfo->UDSSessionTbl[Index];
               }
               break;

           default:
               break;
       }
   }

   return NULL;
}

/*********************************************************************************************
   Name	:	AddUDSSession
   Input	:	pUDSSessionInfo - session information
   Output	:	return 0 on success ,-1 on failure

This program adds the session to the UDS session table
*********************************************************************************************/
int AddUDSSession ( UDSSessionTbl_T* pUDSSessionInfo)
{

   uint8_t Index;
    UDSSessionTblInfo_T*	pUDSSessionTblInfo = &g_BMCInfo.UDSSessionTblInfo;

   for (Index = 0; Index < g_BMCInfo.IpmiConfig.MaxSession; Index++)
   {
           if(TRUE == pUDSSessionTblInfo->UDSSessionTbl[Index].Activated)
           {
                /* Continue Inorder to get the next Free Slot in UDS Session Table */
                continue;
           }

           /* Copy the Session Information to Global BMC Info UDS Session Table */
           memcpy (&pUDSSessionTblInfo->UDSSessionTbl[Index], ( uint8_t*)pUDSSessionInfo, sizeof (UDSSessionTbl_T));
           pUDSSessionTblInfo->SessionCount++;
           pUDSSessionTblInfo->UDSSessionTbl[Index].LoggedInTime = GetTimeStamp ();
           pUDSSessionTblInfo->UDSSessionTbl[Index].SessionTimeoutValue = g_BMCInfo.IpmiConfig.SessionTimeOut;
           break;
   }

   if(Index == g_BMCInfo.IpmiConfig.MaxSession)
   {
       printf("Add Session Failed for UDS\n");
       return -1;
   }

   return 0;
}

/*********************************************************************************************
   Name	:	DeleteUDSSession
   Input	:	pUDSSessionInfo - session information
   Output	:	return 0 on success,-1 on failure

This program deletes the session from the UDS session table
*********************************************************************************************/
int DeleteUDSSession( UDSSessionTbl_T *pUDSSessionInfo )
{
   uint8_t Index;
    UDSSessionTblInfo_T*	pUDSSessionTblInfo = &g_BMCInfo.UDSSessionTblInfo;

   for(Index=0;Index<g_BMCInfo.IpmiConfig.MaxSession;Index++)
   {
       if(FALSE == pUDSSessionTblInfo->UDSSessionTbl[Index].Activated)
       {
           /* Continue to get the Next Occupied Session Slot in UDS Session Slot*/
           continue;
       }

       if (0 == memcmp (&pUDSSessionTblInfo->UDSSessionTbl[Index], pUDSSessionInfo , sizeof(UDSSessionTbl_T)))
       {
            /* Resetting the UDS Session Table Slot as the session is no longer required */
            pUDSSessionTblInfo->UDSSessionTbl[Index].Activated = FALSE;
            pUDSSessionTblInfo->UDSSessionTbl[Index].LoggedInTime = 0xFFFFFFFF;
            pUDSSessionTblInfo->UDSSessionTbl[Index].SessionTimeoutValue = 0;
            pUDSSessionTblInfo->UDSSessionTbl[Index].LoggedInUserID =  0;
            pUDSSessionTblInfo->UDSSessionTbl[Index].LoggedInChannel = 0xFF;
            pUDSSessionTblInfo->UDSSessionTbl[Index].LoggedInPrivilege = 0xFF;
            pUDSSessionTblInfo->SessionCount--;
            break;
       }
   }

   if(Index == g_BMCInfo.IpmiConfig.MaxSession)
   {
       printf("Delete Session Failed for UDS\n");
       return -1;
   }

   return 0;
}

///*---------------------------------------------------
// * @fn UpdateGetMsgTime
// * @brief Updates the Current Uptime and timeout value
// *        for an IPMI Message
// * 
// * @param pReq       : IPMI Message Packet
// * @param ResTimeOut : Timeout Macro string
// * @param BMCInst    : BMC Instance
// * 
// * @return none
// *----------------------------------------------------*/
//void UpdateGetMsgTime (MsgPkt_T* pReq,IfcType_T IfcType, int BMCInst)
//{
//    pReq->ReqTime    = 0;
//    pReq->ResTimeOut = WAIT_INFINITE;

//    if( g_corefeatures.ipmi_res_timeout == ENABLED )
//    {
//        int i;
//        struct sysinfo sys_info;
//        
//        for( i = 0; i < TOTAL_INFINITE_CMDS; i++)
//        {
//            if( NET_FN(pReq->NetFnLUN) == m_InfiniteCmdsTbl[i].NetFn && pReq->Cmd == m_InfiniteCmdsTbl[i].Cmd )
//            {
//                return;
//            }
//        }
//        
//        if(g_PDKCmdsHandle[PDKCMDS_PDKISINFINITECOMMAND]  != NULL)
//        {
//            if( ((BOOL(*)(uint8_t,uint8_t))g_PDKCmdsHandle[PDKCMDS_PDKISINFINITECOMMAND])(NET_FN(pReq->NetFnLUN), pReq->Cmd))
//            {
//                return;
//            }
//        }
//        
//        /* Request UpTime */
//        if(!sysinfo(&sys_info))
//        {
//            pReq->ReqTime    = sys_info.uptime;
//            if(IfcType == IPMB_IFC)
//            {
//                pReq->ResTimeOut = g_coremacros.ipmb_res_timeout;
//            }
//            else if(IfcType == LAN_IFC)
//            {
//                pReq->ResTimeOut = g_coremacros.lan_res_timeout;
//            }
//            else if(IfcType == KCS_IFC)
//            {
//                pReq->ResTimeOut = g_coremacros.kcs_res_timeout;
//            }
//            else if(IfcType == SERIAL_IFC)
//            {
//                pReq->ResTimeOut = g_coremacros.serial_res_timeout;
//            }
//        }
//    }
//}

///*---------------------------------------------------
// * @fn IsMsgTimedOut
// * @brief Checks if the time taken to process 
// *        the IPMI Command expires
// * 
// * @param pReq     : IPMI Message Packet
// * 
// * @return 1 if timed out
// *         0 if error or timeout not set 
// *----------------------------------------------------*/
//BOOL IsMsgTimedOut (MsgPkt_T* pReq)
//{
//    struct sysinfo sys_info;
//    
//    if( pReq->ReqTime && (!sysinfo(&sys_info)) )
//    {
//        return ( (sys_info.uptime - pReq->ReqTime) > pReq->ResTimeOut) ? TRUE : FALSE;
//    }
//    
//    return FALSE;
//}

///*-----------------------------------------------------
// * @fn IsResponseMatch
// * @brief Checks if the Response Message corresponds to 
// *        the Request Message
// * 
// * @param pReq    : IPMI Request Message Packet
// * @param pRes    : IPMI Response Message Packet
// * 
// * @return  1 if match
// *          0 if mismatch
// *----------------------------------------------------*/
//BOOL IsResponseMatch (MsgPkt_T* pReq, MsgPkt_T* pRes)
//{

//    if( ( ((((IPMIMsgHdr_T*)pRes->Data)->RqSeqLUN) >> 2) != ((((IPMIMsgHdr_T*)pReq->Data)->RqSeqLUN) >> 2) ) && 
//        ( (pReq->NetFnLUN & 0x4) && (NO_RESPONSE != pRes->Param) ) )
//    {
//        return FALSE;
//    }
//  
//    return TRUE;
//}

/*-------------------------------------------------------
 * @fn FillIPMIResFailure
 * @brief Frames the Response packet when the time taken 
 *        to process an IPMI Command expires
 * 
 * @param pReq    : IPMI Request Message Packet
 * @param pRes    : IPMI Response Message Packet
 *        BMCInst : BMC Instance Number
 * 
 * @return  none
 *------------------------------------------------------*/
void FillIPMIResFailure ( MsgPkt_T* pReq,  MsgPkt_T* pRes)
{  
    /* Set the Cmd and Net function in response packet */
    pRes->Cmd      = pReq->Cmd;
    pRes->NetFnLUN = pReq->NetFnLUN & 0xFC;
    
    /* Normal IPMI Command response */
    pRes->Param = PARAM_NORMAL_RESPONSE;
  
 
	pRes->Size  = sizeof (IPMIMsgHdr_T) + sizeof (uint8_t);
	pRes->Data[sizeof (IPMIMsgHdr_T)] = CC_TIMEOUT;
	
	/* Check for Request Message */
	if (0 == (pReq->NetFnLUN & 0x04))
	{
		/* Swap the header and copy in response */
		SwapIPMIMsgHdr (( IPMIMsgHdr_T*)pReq->Data, ( IPMIMsgHdr_T*)pRes->Data);
		
		/* Calculate Checksum 2 */
		pRes->Data[pRes->Size] = CalculateCheckSum2 (pRes->Data, pRes->Size);
		pRes->Size++;
	}
}


