 /*******************************************************************
********************************************************************
****                                                              **
****    (C)Copyright 2008-2009, American Megatrends Inc.          **
****                                                              **
****    All Rights Reserved.                                      **
****                                                              **
****    5555 , Oakbrook Pkwy, Norcross,                           **
****                                                              **
****    Georgia - 30093, USA. Phone-(770)-246-8600.               **
****                                                              **
********************************************************************
********************************************************************
********************************************************************
**
** UDSIfc.c
** Unix Domain Socket Interface Handler
**
** Author: Suresh V (sureshv@amiindia.co.in)
*******************************************************************/

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/prctl.h>
#include "com_IPMI_App.h"
#include "com_IPMIDefs.h"
#include "com_Message.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

#include "main.h"

/*Function Prototypes*/
//void CloseUDSSocket(int Socket );
static int ProcessUDSReq(MsgPkt_T *pReq );
int InitUnixDomainSocket(void);
void *RecvUDSPkt(void *pArg);
//int AddUDSSocket (int Socket,uint8_t IsLoopBackSocket, uint8_t IsFixedSocket );
//int RemoveUDSSocket (int Socket );
int ReadUDSData(MsgPkt_T *MsgPkt,int Socket );
int SendUDSPkt (MsgPkt_T *pRes );
//int SetUDSFd(fd_set *newfd,int *maximum );
int FillUDSResponsePacket(MsgPkt_T *pReq, MsgPkt_T *pRes,uint8_t UDSCompletionCode );
//static int UpdateUDSTimeout (void);
//static void*  UDSTimer (void *pArg);
//int AddUDSInfo(MsgPkt_T *pUDSReq,MsgPkt_T *pUDSRes );
//uint8_t RemoveUDSSession(SOCKET Socket );
//int CheckReservedCmd(uint8_t Cmd);
void *UDSIfcTask(void* pArg);
static void ProcessUDSBridgeMsg (  MsgPkt_T* pReq );

// static uint8_t ReservedCmd[]={
//                       CMD_GET_DEV_ID,
//                       CMD_GET_USER_NAME,
//                       CMD_SET_USER_PASSWORD};

int gUDSSocket;
int gFdUdsIfc, gFdUdsRes;

/**
 * @fn UDSIfcTask
 * @brief This function is used to start the UDS Interface Task
 * @param Addr
**/
void *UDSIfcTask(void* pArg)
{
    MsgPkt_T Req;
    prctl(PR_SET_NAME,__FUNCTION__,0,0,0);

    printf("UDSIfcTask start...\n");

    //create UDS_IFC_Q
    if(-1 != access(UDS_IFC_Q, F_OK))
    {
        remove(UDS_IFC_Q);
    }
    if(0 != mkfifo (UDS_IFC_Q, 0777))
    {
        printf("%s: Create %s fifo failed! %s\n", __FUNCTION__, UDS_IFC_Q, strerror(errno));
        return (void*)UDS_FAILURE;
    }
    gFdUdsIfc = open (UDS_IFC_Q, O_RDWR);
    if(-1 == gFdUdsIfc)
    {
        printf("%s: Open %s fifo failed! %s\n", __FUNCTION__, UDS_IFC_Q, strerror(errno));
        return (void*)UDS_FAILURE;
    }

    //create UDS_RES_Q
    if(-1 != access(UDS_RES_Q, F_OK))
    {
        remove(UDS_RES_Q);
    }
    if(0 != mkfifo (UDS_RES_Q, 0777))
    {
        printf("%s: Create %s fifo failed! %s\n", __FUNCTION__, UDS_RES_Q, strerror(errno));
        return (void*)UDS_FAILURE;
    }
    gFdUdsRes = open (UDS_RES_Q, O_RDWR);
    if(-1 == gFdUdsRes)
    {
        printf("%s: Open %s fifo failed! %s\n", __FUNCTION__, UDS_RES_Q, strerror(errno));
        return (void*)UDS_FAILURE;
    }

    /* Open Unix Domain Socket */
    if(UDS_SUCCESS > InitUnixDomainSocket())
    {
        printf("%s: Open Unix Domain Socket failed\n", __FUNCTION__);
      return (void *)UDS_FAILURE;
    }

    /*Create a thread to recv UDS Pkt */
    gThreadIndex++;
    if(0 != pthread_create(&gThreadIDs[gThreadIndex],NULL,RecvUDSPkt,NULL))
    {
        printf("%s: Create RecvUDSPkt thread failed! %s\n", __FUNCTION__, strerror(errno));
        return (void *)UDS_FAILURE; 
    }
    
    // /* Create a thread to handle socket timeout */
    // IPMI_DBG_PRINT_1("UDSIfc.c: Creating UDSTimer thread with index %d\n", gthreadIndex);
    // OS_CREATE_TASK_THREAD(UDSTimer, (void*)&BMCInst, err, gthreadIDs[gthreadIndex]);

    printf("gFdUdsIfc %d, gFdUdsRes %d\n", gFdUdsIfc, gFdUdsRes);

    while(TRUE)
    {
        if(UDS_SUCCESS != GetMsg(gFdUdsIfc, &Req, WAIT_INFINITE))
        {
            printf("UDSIfc.c: Error Fetching Data from UDSIfcQ\n");
            continue;
        }
    
        switch(Req.Param)
        {
            case UDS_SMB_PARAM:
//                printf("---> UDS get request Message\n");
                ProcessUDSReq(&Req);
                break;
            case BRIDGING_REQUEST:
//                printf("---> UDS get bridge respose!\n");
                ProcessUDSBridgeMsg(&Req);
                break;
        }
    }

    return (void*)UDS_SUCCESS;
}

/**
 * @fn InitUnixDomainSocket
 * @brief This function is used to create the Socket for each BMC
 * @param BMCInst
**/
int InitUnixDomainSocket(void)
{
    struct sockaddr_un server_addr;

    bzero(&server_addr, sizeof(server_addr));
    server_addr.sun_family = AF_UNIX;
    strcpy(server_addr.sun_path,UDS_SOCKET_PATH);
    int len = sizeof(server_addr.sun_family)+strlen(server_addr.sun_path);

    if(-1 != access(UDS_SOCKET_PATH, F_OK))
    {
        remove(UDS_SOCKET_PATH);
    }

    unlink(server_addr.sun_path);

    gUDSSocket=socket(AF_UNIX,SOCK_STREAM,0);
    if(UDS_FAILURE == gUDSSocket)
    {
        printf("UDSIfc.c : Unable to create the UNIX Domain Socket\n");
        return UDS_FAILURE;
    }

    int opt = 1;
    setsockopt(gUDSSocket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    /* Bind pBMCInfo->UDSConfig.UDSSocket to the particular socket file in the path*/
    if (UDS_FAILURE == bind(gUDSSocket,(struct sockaddr *)&server_addr,len))
    {
        printf("UDSIfc.c : Error binding  UNIX Domain Socket, %d, %s\n", errno, strerror(errno));
        return UDS_FAILURE;
    }
    if (UDS_FAILURE == listen(gUDSSocket,UDS_SOCKET_QUE_LEN))
    {
        printf ("UDSIfc.c : Error listen\n");
        return UDS_FAILURE;
    }
  
    return UDS_SUCCESS;
}

/**
 * @fn RecvUDSPkt
 * @brief This functon is used to Recv the UDS Pkt
 * @param BMCInst
**/
void *RecvUDSPkt(void *pArg)
{
    MsgPkt_T MsgPkt;
    struct timeval Timeout;
    struct sockaddr_un local;
    int RetVal,max,Index = 0;
    int UDSSocket=-1;
    prctl(PR_SET_NAME,__FUNCTION__,0,0,0);
    int curThreadIndex = 0;
    fd_set  fds;

    printf("RecvUDSPkt start...\n");

    memset(&local,0,sizeof(local));

    socklen_t locallen = sizeof(local);

    while(TRUE)
    {
        Timeout.tv_sec  =   SESSION_TIMEOUT; 
        Timeout.tv_usec  =   0; 

        FD_ZERO(&fds);
        if(gUDSSocket != -1)
            FD_SET(gUDSSocket,&fds);
        if(UDSSocket != -1)
            FD_SET(UDSSocket,&fds);
        
        max = (gUDSSocket > UDSSocket) ? gUDSSocket+1 : UDSSocket+1;

        /*Waits for an event to occur on socket*/
        RetVal = select (max, &fds, NULL, NULL, &Timeout);
        if (UDS_FAILURE == RetVal)
        {
            continue;
        }
        if (UDS_SUCCESS == RetVal)
        {
            /* Its due to timeout - continue */
            continue;
        }
        
        /*Accepting Connection*/
        if(FD_ISSET(gUDSSocket,&fds))
        {
            UDSSocket=accept(gUDSSocket,(struct sockaddr *)&local,&locallen);
            if(UDS_FAILURE == UDSSocket)
            {
                printf("UDSIfc.c:Accept Failed in UDSInterface");
                close(gUDSSocket);
                close(UDSSocket);
                gUDSSocket = -1;
                InitUnixDomainSocket();
                continue;
            }
        }

        if(FD_ISSET(UDSSocket,&fds))
        {
            if(UDS_SUCCESS ==  ReadUDSData( &MsgPkt,UDSSocket))
            {
                if (UDS_SUCCESS != PostMsg (gFdUdsIfc, &MsgPkt))
                {
                     printf("UDSIfc.c:Cannot Post Data to UDSIfcQ\n");
                }                
            }       
            else
            {
                close(gUDSSocket);
                close(UDSSocket);
                gUDSSocket = -1;
                UDSSocket = -1;
                InitUnixDomainSocket();
            }      
        }
   }
}

/**
 * @fn ReadUDSData
 * @brief This function is used to read the data from socket
 * @param MsgPkt,Socket,BMCInst
**/
int ReadUDSData(MsgPkt_T *MsgPkt,int Socket )
{
    uint8_t* pData =(uint8_t *) & MsgPkt->Data[0];
    uint16_t RecvdLen = 0,RemLen = 0,Len = 0;
    unsigned int SourceLen = 0;
    IPMIUDSMsg_T *pIPMIUDSMsg = (IPMIUDSMsg_T *)&pData[0];

    while (RecvdLen < sizeof(IPMIUDSMsg_T))
    {
        Len = recv (Socket, &pData[RecvdLen],sizeof(IPMIUDSMsg_T),0);
        if (Len <= 0)
        {
            return UDS_FAILURE;
        }
        
        // int i;
        // printf("---> server recv1 %#x: ", Len);
        // for(i=0;i<Len;i++)
        //     printf("%#x ", pData[RecvdLen+i]);
        // printf("\n");

        RecvdLen += Len;
    }

    if((pIPMIUDSMsg->IPMIMsgLen > MSG_PAYLOAD_SIZE) || (pIPMIUDSMsg->IPMIMsgLen < sizeof(IPMIUDSMsg_T)))
    {
        printf("Invalid UDS message len %d\n", pIPMIUDSMsg->IPMIMsgLen);
        return UDS_FAILURE;
    }
    RemLen = pIPMIUDSMsg->IPMIMsgLen-RecvdLen;

    while(RemLen>0)
    {
        Len = recv(Socket,&pData[RecvdLen],pIPMIUDSMsg->IPMIMsgLen-RecvdLen,0);
        if(Len <= 0)
        {
            return UDS_FAILURE;
        }

        // int i;
        // printf("---> server recv2 %#x: ", Len);
        // for(i=0;i<Len;i++)
        //     printf("%#x ", pData[RecvdLen+i]);
        // printf("\n");

        RecvdLen += Len;
        RemLen -= Len;
    }

    MsgPkt->SessionID   = pIPMIUDSMsg->SessionID;
    MsgPkt->Cmd         = pIPMIUDSMsg->Cmd;
    MsgPkt->NetFnLUN    = pIPMIUDSMsg->NetFnLUN;
 //   MsgPkt->Privilege   = pIPMIUDSMsg->Privilege;
    MsgPkt->Socket      = Socket;
    MsgPkt->Size        = RecvdLen;
    MsgPkt->Param       = PARAM_IFC;
    MsgPkt->Channel     = pIPMIUDSMsg->ChannelNum;
    MsgPkt->SessionType = UDS_SESSION_TYPE;
    MsgPkt->SrcQ = gFdUdsRes;

    return UDS_SUCCESS;
}

/**
 * @fn ProcessUDSReq
 * @brief This function is used to Process the Request
 * @param pReq,BMCInst
**/
static int ProcessUDSReq(MsgPkt_T *pReq )
{
    MsgPkt_T pRes;
    int RetVal = 0;

    /*Posting the request to Msg Handler for processing the command */
    if (UDS_SUCCESS != PostMsg (gFd_MsgHndlrIfc, pReq))
    {
        return UDS_FAILURE;
    }

    /* Get the response from the Message handler Task */
    memset(&pRes,0,sizeof(MsgPkt_T));
    if (UDS_SUCCESS != GetMsg (gFdUdsRes, &pRes, (DEFAULT_TIMEOUT>2)?(DEFAULT_TIMEOUT-2):1))
    {
        return UDS_FAILURE;
    }

    // int i;
    // printf("ProcessUDSReq Recv: ");
    // for(i=0;i<pRes.Size;i++)
    //     printf("%#x ", pRes.Data[i]);
    // printf("\n");

    /* Sending the Packet to the corresponding client*/
    if((UDS_SUCCESS == RetVal) || (UDS_FAILURE == RetVal))
    {
        SendUDSPkt(&pRes);
    }

  return UDS_SUCCESS;
}

/**
 * @fn SendUDSPkt
 * @brief This function sends the IPMI UDS Response to the requestor
 * @param pRes - Response message.
**/
int SendUDSPkt (MsgPkt_T *pRes)
{
    // int i;
    // printf("---> server Send size: %#x, socket: %d: ", pRes->Size, pRes->Socket);
    // for(i=0;i<pRes->Size;i++)
    //     printf("%#x ", pRes->Data[i]);
    // printf("\n");
    /* Send the UDS response packet */
     if(UDS_FAILURE == send(pRes->Socket,pRes->Data,pRes->Size,MSG_NOSIGNAL))
     {
       if((EBADF == errno) || (EPIPE == errno))
       {
               return UDS_SUCCESS;
       }
       else
       {
           printf("UDSIfc.c: Send UDS Pkt Failed\n");
           return UDS_FAILURE;
       }
     }
    return UDS_SUCCESS;
}


/**
 * @fn FillUDSResponsePacket
 * @brief This function fills the pRes when Error Occured
 * @param pReq,pRes,CompletionCode,BMCInst
**/
int FillUDSResponsePacket(MsgPkt_T *pReq,MsgPkt_T *pRes,uint8_t UDSCompletionCode )
{
    IPMIUDSMsg_T *pIPMIUDSMsgReq = (IPMIUDSMsg_T *)&pReq->Data[0];
    IPMIUDSMsg_T *pIPMIUDSMsgRes = (IPMIUDSMsg_T *)&pRes->Data[0];
    uint8_t *byCompletionCode = (uint8_t *)&pRes->Data[sizeof(IPMIUDSMsg_T)];


    pRes->Socket = pReq->Socket;
    pReq->Cmd = pIPMIUDSMsgReq->Cmd;

    pIPMIUDSMsgRes->SessionID = pIPMIUDSMsgReq->SessionID;
    pIPMIUDSMsgRes->Cmd = pIPMIUDSMsgReq->Cmd;
    pIPMIUDSMsgRes->NetFnLUN = pIPMIUDSMsgReq->NetFnLUN;
 //   pIPMIUDSMsgRes->Privilege = pIPMIUDSMsgReq->Privilege;
    pIPMIUDSMsgRes->IPMIMsgLen = sizeof(IPMIUDSMsg_T)+sizeof(uint8_t)+1;
    pIPMIUDSMsgRes->ChannelNum = pIPMIUDSMsgReq->ChannelNum;
//    pIPMIUDSMsgRes->AuthFlag = pIPMIUDSMsgReq->AuthFlag;
    
//    strcpy( (char *)pIPMIUDSMsgRes->UserName, (char *)pIPMIUDSMsgReq->UserName);
//    memcpy(pIPMIUDSMsgRes->IPAddr, pIPMIUDSMsgReq->IPAddr, 16);

    pRes->Size = pIPMIUDSMsgRes->IPMIMsgLen;

    *byCompletionCode = UDSCompletionCode; 

    return UDS_SUCCESS;
}

// /**
//  * @fn UpdateUDSTimeout
//  * @brief This function Updates the timeout value for each socket opened
//  * @param BMCInst
// **/
// static int
// UpdateUDSTimeout (void)
// {
//     int Index = 0;
//     int TimeOut=0;
//     _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
//     SocketTbl_T *SocketTable = pBMCInfo->pUDSocketTbl;

//     for (Index = 0; Index < (pBMCInfo->IpmiConfig.MaxSession + 1); Index++ )
//     {
//         if((SocketTable[Index].Valid))
//         {
//             TimeOut = pBMCInfo->IpmiConfig.SessionTimeOut;
//             if (SocketTable[Index].Time >= TimeOut)
//             {
//                 IPMI_DBG_PRINT("Local Socket Timed Out\n");
//                 close (SocketTable[Index].Socket);
//                 /* Acquire the UDS Socket Mutex Lock */
//                 OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->UDSSocketTblMutex, WAIT_INFINITE);
//                 SocketTable[Index].Socket = 0;
//                 SocketTable[Index].Valid  = 0;
//                 /* Release the UDS Socket Mutex Lock */
//                 OS_THREAD_MUTEX_RELEASE(&pBMCInfo->UDSSocketTblMutex);
//             }
//             else
//             {   /* update the time */
//                 /* Acquire the UDS Socket Mutex Lock */
//                 OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->UDSSocketTblMutex, WAIT_INFINITE);
//                 SocketTable[Index].Time += UDS_TIMER_INTERVAL;
//                 /* Release the UDS Socket Mutex Lock */
//                 OS_THREAD_MUTEX_RELEASE(&pBMCInfo->UDSSocketTblMutex);
//             }
//         }
//     }

//     return UDS_SUCCESS;
// }

// /**
//  * @fn  UDSTimer
//  * @brief This function handles the time out for uds connections.
//  * @param None
//  **/
// static
// void*  UDSTimer (void *pArg)
// {
//     int *inst = (int*)pArg;
//     int BMCInst= *inst;
//     prctl(PR_SET_NAME,__FUNCTION__,0,0,0);

//     while (TRUE)
//     {
//         UpdateUDSTimeout (BMCInst);
//         sleep (UDS_TIMER_INTERVAL);
//     }

//     return UDS_SUCCESS;
// }


// /**
//  * @fn  AddUDSInfo
//  * @brief This function adds the session information in Session Table
//  * @param UDS Request Packet,UDS Response Packet,BMCInst
//  **/
// int AddUDSInfo(MsgPkt_T *pUDSReq,MsgPkt_T *pUDSRes )
// {
//     uint8 *byCompletionCode = (uint8 *)&pUDSRes->Data[sizeof(IPMIUDSMsg_T)];
//     IPMIUDSMsg_T *pRes = (IPMIUDSMsg_T *)&pUDSRes->Data[0];
//     _FAR_ ChannelInfo_T *pChanneludsInfo = NULL;
//     _FAR_ ChannelUserInfo_T *pChUserInfo = NULL;
//     _FAR_ UserInfo_T *pUserInfo = NULL;
//     UDSSessionTbl_T UDSSessionInfo;
//     INT32U SessionID;
//     uint8_t UserID,Index,SessionHandle=0;
//     unsigned int seed=1;
//     _FAR_ BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst];
//     char   UserPswd[MAX_PASSWORD_LEN];
//     uint8_t ChannelNum = CH_NOT_USED;
//     uint8_t PwdEncKey[MAX_SIZE_KEY + 1] = {0};
//     _fmemset(&UDSSessionInfo,0,sizeof(UDSSessionTbl_T));

//     if(*byCompletionCode == CC_NORMAL)
//     {
//         if(ReservedCmd[0] == pRes->Cmd)
//         {
//             UserID = 0;
//         }
//         else
//         {
//             UserID = (uint8)pUDSReq->Data[sizeof(IPMIUDSMsg_T)];
//         }

//         if(pBMCInfo ->UDSSessionTblInfo.SessionCount >= pBMCInfo->IpmiConfig.MaxSession)
//         {
//             IPMI_WARNING("UDSIfc.c:Maximum Session Limit Reached\n");
//             FillUDSResponsePacket(pUDSReq,pUDSRes,CC_ACTIVATE_SESS_NO_SESSION_SLOT_AVAILABLE,BMCInst);
//             SendUDSPkt(pUDSRes,BMCInst);
//             CloseUDSSocket(pUDSRes->Socket,BMCInst);
//             return UDS_PARAM_FAILURE;
//         }

//         do
//         {
//             SessionID = ((INT32U)rand_r(&seed) >> 16);
//         } while ((NULL != GetUDSSessionInfo (UDS_SESSION_ID_INFO,&SessionID, BMCInst)) || (0 == SessionID));

//         SessionHandle = BMC_GET_SHARED_MEM(BMCInst)->UDSSessionHandle;
        
//         do
//         {
//             SessionHandle += 1;
//         } while (NULL != GetUDSSessionInfo (UDS_SESSION_HANDLE_INFO,&SessionHandle, BMCInst));

//        LOCK_BMC_SHARED_MEM(BMCInst);
//        BMC_GET_SHARED_MEM(BMCInst)->UDSSessionHandle = SessionHandle;
//        UNLOCK_BMC_SHARED_MEM(BMCInst);

//         pChanneludsInfo = GetLANChannelInfoForUDS(pUDSReq->Channel,&ChannelNum,&pRes->ChannelNum,BMCInst);
//         if(pChanneludsInfo == NULL)
//         {
//             IPMI_WARNING("UDSIfc.c:Invalid Channel\n");
//             FillUDSResponsePacket(pUDSReq,pUDSRes,CC_INV_DATA_FIELD,BMCInst);
//             SendUDSPkt(pUDSRes,BMCInst);
//             CloseUDSSocket(pUDSRes->Socket,BMCInst);
//             return UDS_PARAM_FAILURE;
//         }

//         if(0 != UserID)
//         {
//             pUserInfo = getUserIdInfo (UserID & 0x3F, BMCInst);
//             if (g_corefeatures.userpswd_encryption == ENABLED)
//             {
//                 /* Get Encryption Key from the MBMCInfo_t structure */
//                 LOCK_BMC_SHARED_MEM(BMCInst);
//                     memcpy(PwdEncKey, &(g_MBMCInfo.PwdEncKey), MAX_SIZE_KEY);
//                 UNLOCK_BMC_SHARED_MEM(BMCInst);
//                 if(DecryptPassword((INT8S *)(pBMCInfo->EncryptedUserInfo[(UserID - 1) & 0x3F].EncryptedPswd), MAX_PASSWORD_LEN, (INT8S *)UserPswd, MAX_PASSWORD_LEN, PwdEncKey))
//                 {
//                     TCRIT("Error in decrypting the user password for user ID:%d. .\n", UserID);
//                     FillUDSResponsePacket(pUDSReq, pUDSRes, CC_UNSPECIFIED_ERR, BMCInst);
//                     SendUDSPkt(pUDSRes,BMCInst);
//                     CloseUDSSocket(pUDSRes->Socket, BMCInst);
//                     return UDS_FAILURE;
//                 }
//             }
//             else
//             {
//                 _fmemcpy (UserPswd, pUserInfo->UserPassword, MAX_PASSWORD_LEN);
//             }

//             if (NULL == pUserInfo)
//             {
//                 FillUDSResponsePacket(pUDSReq,pUDSRes,CC_INV_DATA_FIELD,BMCInst);
//                 SendUDSPkt(pUDSRes,BMCInst);
//                 CloseUDSSocket(pUDSRes->Socket,BMCInst);
//                 return UDS_PARAM_FAILURE;
//             }
//             else if((strlen((char *)pUserInfo->UserName) != 0) && (strlen((char *)UserPswd)!= 0) && (pUserInfo->UserStatus == FALSE))
//             {
//                 FillUDSResponsePacket(pUDSReq,pUDSRes,CC_INV_CMD,BMCInst);
//                 SendUDSPkt(pUDSRes,BMCInst);
//                 CloseUDSSocket(pUDSRes->Socket,BMCInst);
//                 return UDS_PARAM_FAILURE;
//             }

//             OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->ChUserMutex,WAIT_INFINITE);
//             pChUserInfo = getChUserIdInfo (UserID & 0x3F, &Index, pChanneludsInfo->ChannelUserInfo, BMCInst);
//             if (NULL == pChUserInfo)
//             {
//                 OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
//                 FillUDSResponsePacket(pUDSReq,pUDSRes,CC_INV_DATA_FIELD,BMCInst);
//                 SendUDSPkt(pUDSRes,BMCInst);
//                 CloseUDSSocket(pUDSRes->Socket,BMCInst);
//                 return UDS_PARAM_FAILURE;
//             }
//             else if(pChUserInfo->AccessLimit == PRIV_LEVEL_NO_ACCESS)
//             {
//                 OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
//                 FillUDSResponsePacket(pUDSReq,pUDSRes,CC_INSUFFIENT_PRIVILEGE,BMCInst);
//                 SendUDSPkt(pUDSRes,BMCInst);
//                 CloseUDSSocket(pUDSRes->Socket,BMCInst);
//                 return UDS_PARAM_FAILURE;
//             }
//             else if((strlen((char *)pUserInfo->UserName) != 0) && (strlen((char *)pUserInfo->UserPassword)!= 0) && (pChUserInfo->IPMIMessaging == FALSE))
//             {
//                 OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
//                 FillUDSResponsePacket(pUDSReq,pUDSRes,CC_INV_CMD,BMCInst);
//                 SendUDSPkt(pUDSRes,BMCInst);
//                 CloseUDSSocket(pUDSRes->Socket,BMCInst);
//                 return UDS_PARAM_FAILURE;
//             }
//             OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
//         }

//         if(0 != UserID)
//         {
//             UDSSessionInfo.LoggedInPrivilege = pChUserInfo->AccessLimit;
//         }
//         else
//         {
//             UDSSessionInfo.LoggedInPrivilege = pUDSReq->Privilege;
//         }

//         UDSSessionInfo.Activated = TRUE;
//         UDSSessionInfo.UDSSocket = pUDSRes->Socket;
//         UDSSessionInfo.LoggedInUserID= UserID;
//         UDSSessionInfo.LoggedInPrivilege = pUDSReq->Privilege;
//         UDSSessionInfo.LoggedInChannel = ChannelNum;
//         UDSSessionInfo.SessionID = SessionID;
//         UDSSessionInfo.SessionTimeoutValue = pBMCInfo->IpmiConfig.SessionTimeOut;
//         UDSSessionInfo.AuthenticationMechanism = pRes->AuthFlag;
//         UDSSessionInfo.LoggedInSessionHandle = SessionHandle;
//         UDSSessionInfo.UDSChannelNum = UDS_CHANNEL;

//         _fmemcpy( (char *)UDSSessionInfo.LoggedInUsername, (char *)((IPMIUDSMsg_T *)&pUDSReq->Data[0])->UserName,MAX_USERNAME_LEN);
//         _fmemcpy( (char *)UDSSessionInfo.LoggedInPassword, UserPswd,MAX_PASSWORD_LEN);
//         _fmemcpy( (char *)UDSSessionInfo.IPAddr, (char *)((IPMIUDSMsg_T *)&pUDSReq->Data[0])->IPAddr,IP6_ADDR_LEN);

//         UDSSessionInfo.ProcessID = ((IPMIUDSMsg_T *)&pUDSReq->Data[0])->ProcessID;
//         UDSSessionInfo.ThreadID = ((IPMIUDSMsg_T *)&pUDSReq->Data[0])->ThreadID;
//         AddUDSSession(&UDSSessionInfo,BMCInst);

//         /*Assigning the Privilege Level and Session ID*/
//         pRes->SessionID = SessionID;
//         pRes->Privilege = UDSSessionInfo.LoggedInPrivilege;

//         return UDS_SUCCESS;
//     }
//   return UDS_FAILURE;
// }


// /**
//  * @fn  RemoveUDSSession
//  * @brief This function deletes the session information in Session Table
//  * @param Socket,BMCInst
//  **/
// uint8_t RemoveUDSSession(SOCKET Socket )
// {
//     _FAR_ UDSSessionTbl_T *pUDSSessionInfo = NULL;

//     pUDSSessionInfo = GetUDSSessionInfo(UDS_SOCKET_ID_INFO,&Socket,BMCInst);
//     if(NULL != pUDSSessionInfo)
//     {
//         DeleteUDSSession(pUDSSessionInfo,BMCInst);
//     }

//     return UDS_SUCCESS;
// }

// /**
//  * @fn  CloseUDSSocket
//  * @brief This function removes the socket and closes it
//  * @param Socket,BMCInst
//  **/
// void CloseUDSSocket(int Socket )
// {
//     close(Socket);
//     RemoveUDSSocket(Socket,BMCInst);
// }

// /**
//  * @fn CheckReservedCmd
//  * @brief This function is used to check whether the triggered command
//  *            belongs to Reserved List
//  * @param Cmd - Command Number
//  **/
// int CheckReservedCmd(uint8_t Cmd)
// {
//     int index = 0;

//     for(index = 0;index < sizeof(ReservedCmd); index++)
//     {
//         if(ReservedCmd[index] == Cmd)
//         {
//             return UDS_SUCCESS;
//         }
//     }

//   return UDS_CMD_FAILURE;
// }

// /**
//  * @fn GetLANChannelInfoForUDS
//  * @brief This function is used to get the LAN Channel Info
//  * @param - Requested UDS Channel number,BMC Instance and out pointer which points
//                    to LAN Channel Number.
// **/
// ChannelInfo_T* GetLANChannelInfoForUDS(uint8_t ReqUDSChannel,uint8_t *LANChannel,uint8_t *ResChannelNum )
// {
//     BMCInfo_t *pBMCInfo = (BMCInfo_t *)&g_BMCInfo[BMCInst];
//     uint8_t Ch = 0;
//     ChannelInfo_T *UDSChannelInfo = NULL;

//     for(Ch = 1;Ch <= MAX_LAN_CHANNELS; Ch++)
//     {
//         if(ReqUDSChannel == UDS_CHANNEL)
//         {
//              if((pBMCInfo->RMCPLAN1Ch != CH_NOT_USED) && (*LANChannel == CH_NOT_USED))
//              {
//                  *LANChannel = pBMCInfo->RMCPLAN1Ch;
//              }
//              else if((pBMCInfo->RMCPLAN2Ch != CH_NOT_USED) && (*LANChannel != pBMCInfo->RMCPLAN2Ch))
//              {
//                  *LANChannel = pBMCInfo->RMCPLAN2Ch;
//              }
//              else if((pBMCInfo->RMCPLAN3Ch != CH_NOT_USED) && (*LANChannel != pBMCInfo->RMCPLAN3Ch))
//              {
//                  *LANChannel = pBMCInfo->RMCPLAN3Ch;
//              }
//         }
//         else
//         {
//              *LANChannel = ReqUDSChannel;
//         }

//         UDSChannelInfo = getChannelInfo(*LANChannel,BMCInst);
//         if((UDSChannelInfo == NULL) || (UDSChannelInfo->ActiveSession >= UDSChannelInfo->SessionLimit))
//         {
//             if((ReqUDSChannel != UDS_CHANNEL) || (Ch == MAX_LAN_CHANNELS)) 
//             {
//                 *LANChannel = CH_NOT_USED;
//                 return NULL;
//             }
//         }
//         else if(UDSChannelInfo != NULL)
//         {
//             *ResChannelNum = *LANChannel;
//             return UDSChannelInfo;
//         }
//      }

//     *LANChannel = CH_NOT_USED;
//     return NULL;

// }


/*--------------------------------------------
 * ProcessBridgeMsg
 *--------------------------------------------*/
static void
ProcessUDSBridgeMsg (  MsgPkt_T* pReq )
{
    MsgPkt_T        ResPkt;

        
    /* Sent the response packet */
    SendUDSPkt(pReq);
    

    return;
}