|
@@ -145,9 +145,18 @@ void *MsgHndlrTask( void *pArg )
|
|
|
pthread_setspecific(g_tls.CurSessionType,&reqMsgPkt.SessionType);
|
|
|
pthread_setspecific(g_tls.OwnerLUN,&reqMsgPkt.NetFnLUN);
|
|
|
|
|
|
+ SwapIPMIMsgHdr ((IPMIMsgHdr_T*)reqMsgPkt.Data, (IPMIMsgHdr_T*)resMsgPkt.Data);
|
|
|
ProcessIPMIReq(&reqMsgPkt, &resMsgPkt);
|
|
|
+
|
|
|
+ /* Skip current request if no response from Command Handler */
|
|
|
+ if ( (sizeof(IPMIMsgHdr_T) == resMsgPkt.Size) && (NORMAL_RESPONSE == resMsgPkt.Param) )
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
//update checksum2
|
|
|
- resMsgPkt.Data[resMsgPkt.Size-1] = CalculateCheckSum2(resMsgPkt.Data, resMsgPkt.Size-1);
|
|
|
+ resMsgPkt.Data[resMsgPkt.Size] = CalculateCheckSum2(resMsgPkt.Data, resMsgPkt.Size);
|
|
|
+ resMsgPkt.Size++;
|
|
|
+
|
|
|
if(g_BMCInfo.IpmiConfig.UDSIfcSupport == 0x01 && (reqMsgPkt.SrcQ == gFdUdsRes))
|
|
|
{
|
|
|
if (resMsgPkt.Size == sizeof(IPMIUDSMsg_T) && (NORMAL_RESPONSE == resMsgPkt.Param) )
|
|
@@ -168,7 +177,8 @@ void *MsgHndlrTask( void *pArg )
|
|
|
|
|
|
resMsgPkt.SessionID = reqMsgPkt.SessionID;
|
|
|
}
|
|
|
- // printf("Mtx: ");
|
|
|
+ // int i;
|
|
|
+ // printf("===> Mtx to %d: ", resMsgPkt.SrcQ);
|
|
|
// for(i=0;i<resMsgPkt.Size;i++)
|
|
|
// printf("%#x ", resMsgPkt.Data[i]);
|
|
|
// printf("\n");
|
|
@@ -179,6 +189,87 @@ void *MsgHndlrTask( void *pArg )
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+/**
|
|
|
+*@fn ValidateMsgHdr
|
|
|
+*@brief Validates the Message header and keeps track of the messages that has been bridged
|
|
|
+*@param pReq Request packet of the command to be executed
|
|
|
+*@return Returns -1 in case of the response to the bridged message
|
|
|
+* Returns 0 otherwise
|
|
|
+*/
|
|
|
+int
|
|
|
+ValidateMsgHdr (MsgPkt_T* pReq)
|
|
|
+{
|
|
|
+ int j;
|
|
|
+ uint8_t PBTbl = PRIMARY_PB_TBL;
|
|
|
+ IPMIMsgHdr_T* pIPMIMsgReq = (IPMIMsgHdr_T*)&pReq->Data;
|
|
|
+ ChannelInfo_T* pChannelInfo;
|
|
|
+ uint8_t SeqNum = NET_FN(pIPMIMsgReq->RqSeqLUN);
|
|
|
+ int Queuefd = 0;
|
|
|
+
|
|
|
+ /* Check for the request message LUN */
|
|
|
+ switch (pReq->NetFnLUN & 0x03)
|
|
|
+ {
|
|
|
+ case BMC_LUN_00:
|
|
|
+ if (0 == (pReq->NetFnLUN & 0x04))
|
|
|
+ {
|
|
|
+ return 0; //IPMB做从
|
|
|
+ }
|
|
|
+
|
|
|
+ PBTbl = ( (pReq->Channel == SECONDARY_IPMB_CHANNEL) ? SECONDARY_PB_TBL : PRIMARY_PB_TBL );
|
|
|
+
|
|
|
+
|
|
|
+ if ( (TRUE == m_PendingBridgedResTbl[PBTbl][SeqNum].Used) &&
|
|
|
+ (NET_FN(pIPMIMsgReq->NetFnLUN) == NET_FN((m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr.NetFnLUN + 0x04))) &&
|
|
|
+ (pIPMIMsgReq->Cmd == m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr.Cmd) &&
|
|
|
+ (pIPMIMsgReq->ReqAddr == m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr.ResAddr))
|
|
|
+ {
|
|
|
+
|
|
|
+ /* Change the requester's address, sequence number and LUN */
|
|
|
+ pIPMIMsgReq->ResAddr = m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr.ReqAddr;
|
|
|
+ pIPMIMsgReq->RqSeqLUN = m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr.RqSeqLUN;
|
|
|
+
|
|
|
+ /* Calculate the Second CheckSum */
|
|
|
+ pReq->Data[ pReq->Size - 1 ] = CalculateCheckSum2( pReq->Data, pReq->Size - 1 );
|
|
|
+ pReq->Data[2] = (~(pReq->Data[0] + pReq->Data[1])) +1; //2's complement checksum
|
|
|
+
|
|
|
+ pReq->Param = BRIDGING_REQUEST;
|
|
|
+
|
|
|
+
|
|
|
+ if (m_PendingBridgedResTbl[PBTbl][SeqNum].DestQ == gFd_LanIfcQ)
|
|
|
+ {
|
|
|
+ for (j=pReq->Size - 1; j>=0; j--)
|
|
|
+ {
|
|
|
+ pReq->Data[j+1] = pReq->Data[j];
|
|
|
+ }
|
|
|
+ pReq->Data[0] = m_PendingBridgedResTbl[PBTbl][SeqNum].SrcSessionHandle;
|
|
|
+ pReq->Size++;
|
|
|
+ pReq->Cmd = PAYLOAD_IPMI_MSG;
|
|
|
+ Queuefd = gFd_LanIfcQ;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //TODO:其它接口转发
|
|
|
+ printf("Invalid interface!\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Post the data to Destination Interface queue */
|
|
|
+ //printf("===> ValidateMsgHdr post message to %d\n", Queuefd);
|
|
|
+ PostMsg (Queuefd, pReq);
|
|
|
+
|
|
|
+ m_PendingBridgedResTbl[PBTbl][SeqNum].Used = FALSE;
|
|
|
+ m_PendingBridgedResTbl[PBTbl][SeqNum].ResDataOk = 0;
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
+ case BMC_LUN_01:
|
|
|
+ case BMC_LUN_10:
|
|
|
+ case BMC_LUN_11:
|
|
|
+ //TODO:
|
|
|
+ default:
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
*@fn ProcessIPMIReq
|
|
|
*@brief Processes the requested IPMI command
|
|
@@ -283,48 +374,48 @@ ProcessIPMIReq (MsgPkt_T* pReq, MsgPkt_T* pRes)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- pRes->Size = pCmdHndlrMap->CmdHndlr (&pReq->Data [HdrOffset], pReq->Size, &pRes->Data [HdrOffset]) + HdrOffset + 1;
|
|
|
+ pRes->Size = pCmdHndlrMap->CmdHndlr (&pReq->Data [HdrOffset], pReq->Size, &pRes->Data [HdrOffset]) + HdrOffset;
|
|
|
|
|
|
- // //send message command
|
|
|
- // if( (CMD_SEND_MSG == pReq->Cmd) && (NETFN_APP == pReq->NetFnLUN >> 2))
|
|
|
- // {
|
|
|
- // printf("log 4\n");
|
|
|
- // int Offset = 0;
|
|
|
- // uint8_t SeqNum = g_BMCInfo.SendMsgSeqNum;
|
|
|
- // if ((0 == pRes->Size) &&
|
|
|
- // ((g_BMCInfo.IpmiConfig.PrimaryIPMBSupport == 0x01 && PRIMARY_IPMB_CHANNEL == pRes->Channel) ||
|
|
|
- // (g_BMCInfo.IpmiConfig.SecondaryIPMBSupport == 0x01 && SECONDARY_IPMB_CHANNEL == pRes->Channel)) )
|
|
|
- // {
|
|
|
- // pRes->Param = PARAM_NO_RESPONSE;
|
|
|
- // Offset = HdrOffset + 2;
|
|
|
- // }
|
|
|
- // else if (HdrOffset == pRes->Size)
|
|
|
- // {
|
|
|
- // Offset = HdrOffset + 1;
|
|
|
- // }
|
|
|
-
|
|
|
- // PBTbl = ( ((pReq->Data[sizeof (IPMIMsgHdr_T)] & 0x0F) == SECONDARY_IPMB_CHANNEL) ? SECONDARY_PB_TBL : PRIMARY_PB_TBL );
|
|
|
- // while(TRUE)
|
|
|
- // {
|
|
|
- // if ( (TRUE == m_PendingBridgedResTbl[PBTbl][SeqNum].Used) &&
|
|
|
- // (0 == memcmp (&m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr, &pReq->Data[Offset], sizeof (IPMIMsgHdr_T))) )
|
|
|
- // {
|
|
|
- // printf("---> log 4.1\n");
|
|
|
- // memcpy (&m_PendingBridgedResTbl[PBTbl][SeqNum].ResMsgHdr, pRes->Data, sizeof (IPMIMsgHdr_T));
|
|
|
- // break;
|
|
|
- // }
|
|
|
- // else
|
|
|
- // {
|
|
|
- // SeqNum = (SeqNum - 1) & 0x3F;
|
|
|
- // if(SeqNum == g_BMCInfo.SendMsgSeqNum)
|
|
|
- // {
|
|
|
- // break;
|
|
|
- // }
|
|
|
- // }
|
|
|
- // }
|
|
|
- // }
|
|
|
-
|
|
|
-// printf("log 5\n");
|
|
|
+ //prepare response data for send message command
|
|
|
+ if( (CMD_SEND_MSG == pReq->Cmd) && (NETFN_APP == pReq->NetFnLUN >> 2))
|
|
|
+ {
|
|
|
+ //printf("log 4, size %d, Channel %d\n",pRes->Size, pRes->Channel);
|
|
|
+ int Offset = 0;
|
|
|
+ uint8_t SeqNum = g_BMCInfo.SendMsgSeqNum;
|
|
|
+ if ((0 == pRes->Size) &&
|
|
|
+ ((g_BMCInfo.IpmiConfig.PrimaryIPMBSupport == 0x01 && PRIMARY_IPMB_CHANNEL == pRes->Channel) ||
|
|
|
+ (g_BMCInfo.IpmiConfig.SecondaryIPMBSupport == 0x01 && SECONDARY_IPMB_CHANNEL == pRes->Channel)) )
|
|
|
+ {
|
|
|
+ pRes->Param = PARAM_NO_RESPONSE;
|
|
|
+ Offset = HdrOffset + 2;
|
|
|
+ }
|
|
|
+ else if (HdrOffset == pRes->Size)
|
|
|
+ {
|
|
|
+ Offset = HdrOffset + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ PBTbl = ( ((pReq->Data[sizeof (IPMIMsgHdr_T)] & 0x0F) == SECONDARY_IPMB_CHANNEL) ? SECONDARY_PB_TBL : PRIMARY_PB_TBL );
|
|
|
+
|
|
|
+ int i;
|
|
|
+ while(TRUE)
|
|
|
+ {
|
|
|
+ if ( (TRUE == m_PendingBridgedResTbl[PBTbl][SeqNum].Used)
|
|
|
+ && (0 == memcmp (&m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr, &pReq->Data[Offset], sizeof (IPMIMsgHdr_T))) )
|
|
|
+ {
|
|
|
+ memcpy (&m_PendingBridgedResTbl[PBTbl][SeqNum].ResMsgHdr, pRes->Data, sizeof (IPMIMsgHdr_T));
|
|
|
+ m_PendingBridgedResTbl[PBTbl][SeqNum].ResDataOk = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ SeqNum = (SeqNum - 1) & 0x3F;
|
|
|
+ if(SeqNum == g_BMCInfo.SendMsgSeqNum)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
return;
|
|
|
}
|
|
@@ -478,18 +569,34 @@ void RespondSendMessage ( MsgPkt_T* pReq, uint8_t Status)
|
|
|
MsgPkt_T ResPkt;
|
|
|
IPMIMsgHdr_T* pIPMIResHdr = ( IPMIMsgHdr_T*)ResPkt.Data;
|
|
|
IPMIMsgHdr_T* pIPMIReqHdr = ( IPMIMsgHdr_T*)pReq->Data;
|
|
|
- uint8_t SeqNum = NET_FN(pIPMIReqHdr->RqSeqLUN);
|
|
|
+ uint8_t SeqNum = NET_FN(pIPMIReqHdr->RqSeqLUN); //IPMB的sequence
|
|
|
int QueueFd;
|
|
|
|
|
|
+ // printf("---> RespondSendMessage Status = %d\n");
|
|
|
+ // printf("Req: SeqNum %d, NetFn %#x, Cmd %#x, ResAddr %#x\n", SeqNum, NET_FN(pIPMIReqHdr->NetFnLUN), pIPMIReqHdr->Cmd, pIPMIReqHdr->ResAddr );
|
|
|
+ // printf("Tbl: SeqNum %d, NetFn %#x, Cmd %#x, ResAddr %#x\n",m_PendingBridgedResTbl[PBTbl][SeqNum].SeqNum,
|
|
|
+ // NET_FN(m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr.NetFnLUN ),
|
|
|
+ // m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr.Cmd,m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr.ResAddr);
|
|
|
/* Check for pending responses */
|
|
|
PBTbl = ( (pReq->Channel == SECONDARY_IPMB_CHANNEL) ? SECONDARY_PB_TBL : PRIMARY_PB_TBL );
|
|
|
- if ( (TRUE == m_PendingBridgedResTbl[PBTbl][SeqNum].Used) &&
|
|
|
- (NET_FN(pIPMIReqHdr->RqSeqLUN) == SeqNum) &&
|
|
|
+ if ( (TRUE == m_PendingBridgedResTbl[PBTbl][SeqNum].Used) &&
|
|
|
(NET_FN(pIPMIReqHdr->NetFnLUN) == NET_FN(m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr.NetFnLUN )) &&
|
|
|
(pIPMIReqHdr->Cmd == m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr.Cmd) &&
|
|
|
(pIPMIReqHdr->ResAddr == m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr.ResAddr) )
|
|
|
{
|
|
|
-
|
|
|
+ // printf("---> RespondSendMessage/ m_PendingBridgedResTbl: PBTbl: %d, SeqNum %d\n", PBTbl, SeqNum);
|
|
|
+ // int i;
|
|
|
+ // for(i=0;i<6;i++)
|
|
|
+ // printf("%#x ", ((uint8_t*)&m_PendingBridgedResTbl[PBTbl][SeqNum].ResMsgHdr.IPMIMsgHdr)[i]);
|
|
|
+ // printf("\n");
|
|
|
+ uint32_t tcnt = 0;
|
|
|
+ while(m_PendingBridgedResTbl[PBTbl][SeqNum].ResDataOk == 0)
|
|
|
+ {
|
|
|
+ usleep(1);
|
|
|
+ tcnt++;
|
|
|
+ if(tcnt > 100000) break; //100ms
|
|
|
+ }
|
|
|
+
|
|
|
memcpy (pIPMIResHdr, &m_PendingBridgedResTbl[PBTbl][SeqNum].ResMsgHdr.IPMIMsgHdr, sizeof (IPMIMsgHdr_T));
|
|
|
|
|
|
|
|
@@ -553,11 +660,16 @@ void RespondSendMessage ( MsgPkt_T* pReq, uint8_t Status)
|
|
|
if (STATUS_OK != Status)
|
|
|
{
|
|
|
m_PendingBridgedResTbl[PBTbl][SeqNum].Used = FALSE;
|
|
|
+ m_PendingBridgedResTbl[PBTbl][SeqNum].ResDataOk = 0;
|
|
|
}
|
|
|
|
|
|
/* Post the data to Destination Interface queue */
|
|
|
+ //int i;
|
|
|
+ // printf("===> RespondSendMessage post to %d: ", QueueFd);
|
|
|
+ // for(i=0;i<ResPkt.Size;i++)
|
|
|
+ // printf("%#x ", ResPkt.Data[i]);
|
|
|
+ // printf("\n");
|
|
|
PostMsg (QueueFd, &ResPkt);
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
|