|
@@ -642,3 +642,181 @@ int getSensorHistory(uint8_t sensorNum, uint8_t *phistoryBuf)
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+pthread_mutex_t api_bridge_mutex;
|
|
|
+int API_BridgeInternal(MsgPkt_T* pReqPkt, MsgPkt_T* pResPkt, uint8_t DestAddr, int Channel)
|
|
|
+{
|
|
|
+
|
|
|
+ IPMIMsgHdr_T* pReqMsgHdr;
|
|
|
+ IPMIMsgHdr_T* pResMsgHdr;
|
|
|
+ uint8_t SeqNum = g_BMCInfo.SendMsgSeqNum;
|
|
|
+ int RetVal;
|
|
|
+ int fd_BridgeQue;
|
|
|
+ uint8_t PBTbl;
|
|
|
+
|
|
|
+ pthread_mutex_lock(&api_bridge_mutex);
|
|
|
+ //create BRIDGE_QUEUE
|
|
|
+ if(-1 != access(BRIDGE_QUEUE, F_OK))
|
|
|
+ {
|
|
|
+ remove(BRIDGE_QUEUE);
|
|
|
+ }
|
|
|
+ if(0 != mkfifo (BRIDGE_QUEUE, 0777))
|
|
|
+ {
|
|
|
+ printf("%s: Create %s fifo failed! \n", __FUNCTION__, BRIDGE_QUEUE);
|
|
|
+ pthread_mutex_unlock(&api_bridge_mutex);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ fd_BridgeQue = open (BRIDGE_QUEUE, O_RDWR);
|
|
|
+ if(-1 == fd_BridgeQue)
|
|
|
+ {
|
|
|
+ printf("%s: Open %s fifo failed! \n", __FUNCTION__, BRIDGE_QUEUE);
|
|
|
+ pthread_mutex_unlock(&api_bridge_mutex);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(NULL != pReqPkt)
|
|
|
+ {
|
|
|
+ memcpy(&(pReqPkt->Data[sizeof(IPMIMsgHdr_T)]), pReqPkt->Data, pReqPkt->Size);
|
|
|
+ pReqPkt->Size += sizeof(IPMIMsgHdr_T);
|
|
|
+ pReqMsgHdr = (IPMIMsgHdr_T*)pReqPkt->Data;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ printf("Warning: Message Packet to be bridged is NULL\r\n");
|
|
|
+ remove(BRIDGE_QUEUE);
|
|
|
+ pthread_mutex_unlock(&api_bridge_mutex);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if(NULL != pResPkt)
|
|
|
+ {
|
|
|
+ pResMsgHdr = (IPMIMsgHdr_T*)pResPkt->Data;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ printf("Warning: Message Packet to be bridged is NULL\r\n");
|
|
|
+ remove(BRIDGE_QUEUE);
|
|
|
+ pthread_mutex_unlock(&api_bridge_mutex);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ /* Format IPMI message header */
|
|
|
+ pReqMsgHdr->ResAddr = DestAddr;
|
|
|
+ pReqMsgHdr->NetFnLUN = pReqPkt->NetFnLUN;
|
|
|
+ pReqMsgHdr->ChkSum = ~(pReqMsgHdr->ResAddr + pReqMsgHdr->NetFnLUN) + 1;
|
|
|
+
|
|
|
+ if(Channel == PRIMARY_IPMB_CHANNEL)
|
|
|
+ {
|
|
|
+ pReqMsgHdr->ReqAddr = PRIMARY_IPMB_ADDR;
|
|
|
+ }
|
|
|
+ else if(Channel == SECONDARY_IPMB_CHANNEL)
|
|
|
+ {
|
|
|
+ pReqMsgHdr->ReqAddr = PRIMARY_IPMB_ADDR;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ printf ("Warning: Invalid IPMB Channel: %d\r\n", Channel);
|
|
|
+ remove(BRIDGE_QUEUE);
|
|
|
+ pthread_mutex_unlock(&api_bridge_mutex);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ pResPkt->NetFnLUN = pReqPkt->NetFnLUN + 0x40;
|
|
|
+ pResPkt->Cmd = pReqPkt->Cmd;
|
|
|
+
|
|
|
+ pReqMsgHdr->Cmd = pReqPkt->Cmd;
|
|
|
+
|
|
|
+ pResMsgHdr->ResAddr = pReqMsgHdr->ReqAddr;
|
|
|
+ pResMsgHdr->ChkSum = ~(pResMsgHdr->ResAddr + pResMsgHdr->NetFnLUN) + 1;
|
|
|
+ pResMsgHdr->ReqAddr = pReqMsgHdr->ResAddr;
|
|
|
+ pResMsgHdr->RqSeqLUN = pReqMsgHdr->RqSeqLUN;
|
|
|
+ pResMsgHdr->Cmd = pReqMsgHdr->Cmd;
|
|
|
+
|
|
|
+ PBTbl = (Channel == SECONDARY_IPMB_CHANNEL) ? SECONDARY_PB_TBL : PRIMARY_PB_TBL ;
|
|
|
+ /* Store in the table for response tracking */
|
|
|
+ while(TRUE)
|
|
|
+ {
|
|
|
+ if (FALSE == m_PendingBridgedResTbl[PBTbl][SeqNum].Used)
|
|
|
+ {
|
|
|
+ m_PendingBridgedResTbl[PBTbl][SeqNum].TimeOut = DEFAULT_TIMEOUT;
|
|
|
+
|
|
|
+ m_PendingBridgedResTbl[PBTbl][SeqNum].ChannelNum = pReqPkt->Channel;
|
|
|
+ m_PendingBridgedResTbl[PBTbl][SeqNum].OriginSrc = ORIGIN_INT_REQ;
|
|
|
+ g_BMCInfo.SendMsgSeqNum = SeqNum;
|
|
|
+
|
|
|
+ /* Format Sequence Number */
|
|
|
+ pReqMsgHdr->RqSeqLUN = ((g_BMCInfo.SendMsgSeqNum) << 2) & 0xFC;
|
|
|
+ pResMsgHdr->RqSeqLUN = pReqMsgHdr->RqSeqLUN + 0x40;
|
|
|
+
|
|
|
+ memcpy (&m_PendingBridgedResTbl[PBTbl][SeqNum].ReqMsgHdr, pReqMsgHdr, sizeof (IPMIMsgHdr_T));
|
|
|
+ memcpy (&m_PendingBridgedResTbl[PBTbl][SeqNum].ResMsgHdr, pResMsgHdr, sizeof (IPMIMsgHdr_T));
|
|
|
+ m_PendingBridgedResTbl[PBTbl][SeqNum].DestQ = fd_BridgeQue;
|
|
|
+
|
|
|
+ /* Store Session ID for final response to the origin for KCS*/
|
|
|
+ //m_PendingBridgedResTbl[SeqNum].SrcSessionID = pReqPkt->SessionID;
|
|
|
+
|
|
|
+ m_PendingBridgedResTbl[PBTbl][SeqNum].Used = TRUE;
|
|
|
+ //printf( "---> oemApi.c: Bridged message added index = %d.\n", SeqNum );
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ SeqNum = (SeqNum + 1) & 0x3F;
|
|
|
+ if(SeqNum == g_BMCInfo.SendMsgSeqNum)
|
|
|
+ {
|
|
|
+ printf ("Warning: Pending Bridge Response Table is full \n");
|
|
|
+ remove(BRIDGE_QUEUE);
|
|
|
+ pthread_mutex_unlock(&api_bridge_mutex);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Format message packet */
|
|
|
+ pReqPkt->Channel = Channel;
|
|
|
+ pReqPkt->Param = PARAM_BRIDGE;
|
|
|
+
|
|
|
+ /* Recalculate the checksum */
|
|
|
+ pReqPkt->Data [pReqPkt->Size] = CalculateCheckSum2 (pReqPkt->Data, pReqPkt->Size);
|
|
|
+ pReqPkt->Size++;
|
|
|
+
|
|
|
+ if(Channel == PRIMARY_IPMB_CHANNEL)
|
|
|
+ {
|
|
|
+ pReqPkt->SrcQ = gFd_PrimaryIpmbIfcQ;
|
|
|
+ }
|
|
|
+ else if(Channel == SECONDARY_IPMB_CHANNEL)
|
|
|
+ {
|
|
|
+ pReqPkt->SrcQ = gFd_SecondaryIpmbIfcQ;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ printf("Warning: Invalid Channel %d\n", Channel);
|
|
|
+ remove(BRIDGE_QUEUE);
|
|
|
+ pthread_mutex_unlock(&api_bridge_mutex);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Post Message to the bridge queue */
|
|
|
+ if(0 != PostMsg(pReqPkt->SrcQ, pReqPkt) )
|
|
|
+ {
|
|
|
+ printf ("Warning: oemApi.c : Error posting message to Queue %p \n", pReqPkt->SrcQ);
|
|
|
+ remove(BRIDGE_QUEUE);
|
|
|
+ pthread_mutex_unlock(&api_bridge_mutex);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ m_PendingBridgedResTbl[PBTbl][SeqNum].ResDataOk = 1;
|
|
|
+
|
|
|
+ RetVal = GetMsg (fd_BridgeQue, pResPkt, 5000); //3s
|
|
|
+ remove(BRIDGE_QUEUE);
|
|
|
+ pthread_mutex_unlock(&api_bridge_mutex);
|
|
|
+ if(RetVal != 0)
|
|
|
+ {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ memcpy(pResPkt->Data, &(pResPkt->Data[sizeof(IPMIMsgHdr_T)]), pResPkt->Size - sizeof(IPMIMsgHdr_T)-1);
|
|
|
+ pResPkt->Size = pResPkt->Size - sizeof(IPMIMsgHdr_T)-1; //remove header & checksum2
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|