📄 bus232.cpp
字号:
{
if (Rs232LogToFile)
{
// Heap full
fprintf(Rs232HdlcLogFile, "\n bus232_SendPacketToUnit -- HEAP FULL");
}
#ifdef RSX
PrintfInt("No more room - Heap full\n");
#endif
return;
}
sHdlcControl.bTxNoAckCnt++;
bControl.InfoControl = 0;
bControl.PollFinal = 1;
bControl.RxSeq = sHdlcControl.bExpectedRxSeq; // Acknowledge received frames
bControl.TxSeq = sHdlcControl.bNextTxSeq;
if (Rs232LogToFile)
{
if (NotAcknowledgeFramePtr[bControl.TxSeq]!=NULL)
{
fprintf(Rs232HdlcLogFile, "\n NotAcknowledgeFramePtr NOT NULL, bControl.TxSeq=%x",bControl.TxSeq);
}
}
NotAcknowledgeFramePtr[bControl.TxSeq] = pTempNoAckPtr;
sHdlcControl.bNextTxSeq = (sHdlcControl.bNextTxSeq + 1 ) & BUSM_HDLC_SEQ_MOD;
bDataPtr->Dle = 0x10; // DLE
bDataPtr->uLengthMSB = (uint8) ((wDataLength&0xff00)>>8); // Length MSB
bDataPtr->uLengthLSB = (uint8) (wDataLength&0x00ff); // Length LSB
bDataPtr->uControl = (BUSM_InfoFrameType)bControl; // Sequence number
bDataPtr->payloadHead.uProgId = 0; // Program ID
bDataPtr->payloadHead.uTaskId = (uint8) iTaskId; // Task ID
if (iLength)
{
memcpy(bDataPtr->payloadTail, bInputDataPtr, iLength); // Data
}
bCheckSum = (*(uint8*)&bDataPtr->uControl) + bDataPtr->payloadHead.uProgId + bDataPtr->payloadHead.uTaskId;
for(i=0; i<iLength; i++)
{
bCheckSum += bDataPtr->payloadTail[i];
}
bDataPtr->payloadTail[iLength] = bCheckSum; // Checksum
if (bControl.PollFinal) // if we have set final flag then start retransmit timer.
{
sHdlcControl.tNoAckNowledge = clock(); // time stamp
}
// Store unacknowledged frames
memcpy(pTempNoAckPtr,bDataPtr,iLength + sizeof(BUSM_FrameType));
if (Rs232LogToFile)
{
fprintf(Rs232HdlcLogFile, "\nTx Infoframe : Tx-Seq:%02x Rx-Seq:%02x PollFinal: %01x State %x ",bDataPtr->uControl.TxSeq,bDataPtr->uControl.RxSeq,bDataPtr->uControl.PollFinal&0x1,sHdlcControl.eHdlcState);
}
WaitForSingleObject(semTestbusFrameQueueSem, INFINITE);
EnQueue(&TestbusFrameQueue, bDataPtr);
ReleaseMutex(semTestbusFrameQueueSem);
}
else
{
sUnsentInfoframes *NextUnsendFrame;
NextUnsendFrame = (sUnsentInfoframes *)malloc(sizeof(sUnsentInfoframes)+iLength);
if (NextUnsendFrame == NULL)
{
if (Rs232LogToFile)
{
// Heap full
fprintf(Rs232HdlcLogFile, "\n bus232_SendPacketToUnit -- HEAP FULL");
}
#ifdef RSX
PrintfInt("No more room - Heap full\n");
#endif
}
else
{
// protected by the semaphore semBusmHdlcSem
memcpy(NextUnsendFrame->Data, bInputDataPtr,iLength);
NextUnsendFrame->iTaskId = iTaskId;
NextUnsendFrame->iLength = iLength;
NextUnsendFrame->Next = NULL;
if (FirstUnsent==NULL) // First in list
{
FirstUnsent = NextUnsendFrame;
LastUnsent = FirstUnsent;
}
else
{
LastUnsent->Next = NextUnsendFrame;
LastUnsent = NextUnsendFrame;
}
}
}
ReleaseMutex(semBusmHdlcSem);
}
void bus232_SendSupervisorFrame(int iTaskId, bool boolPollFinal)
{
BUSM_FrameType *bDataPtr;
uint16 wDataLength = (uint16) (1);
BUSM_SuperVisoryControlFrameType bControl;
uint8 bCheckSum;
WaitForSingleObject(semBusmHdlcSem, INFINITE);
if (sHdlcControl.eHdlcState == BUSM_LOCKED)
{
bDataPtr = (BUSM_FrameType*) malloc(sizeof(BUSM_FrameType));
if(bDataPtr==NULL)
{
if (Rs232LogToFile)
{
// Heap full
fprintf(Rs232HdlcLogFile, "\n bus232_SendSupervisorFrame -- HEAP FULL");
}
#ifdef RSX
PrintfInt("bus232_SendSupervisorFrame - Heap full\n");
#endif
return;
}
bControl.InfoControl = 1; // Supervisory frame
bControl.Supervisory = 0;
bControl.PollFinal = boolPollFinal;
bControl.RxSeq = sHdlcControl.bExpectedRxSeq; // Acknowledge received frames
bDataPtr->Dle = 0x10; // DLE
bDataPtr->uLengthMSB = (uint8) ((wDataLength&0xff00)>>8); // Length MSB
bDataPtr->uLengthLSB = (uint8) (wDataLength&0x00ff); // Length LSB
bDataPtr->uControl = *(BUSM_InfoFrameType*)&bControl; // Sequence number
bCheckSum = (*(uint8*)&bDataPtr->uControl);
bDataPtr->payloadHead.uProgId = bCheckSum; // Checksum
}
ReleaseMutex(semBusmHdlcSem);
if (Rs232LogToFile)
{
fprintf(Rs232HdlcLogFile, "\nTx Supervisoryframe: Rx-Seq:%02x PollFinal: %01x State %x ",bDataPtr->uControl.RxSeq,bDataPtr->uControl.PollFinal&0x1,sHdlcControl.eHdlcState);
}
WaitForSingleObject(semTestbusFrameQueueSem, INFINITE);
EnQueue(&TestbusFrameQueue, bDataPtr);
ReleaseMutex(semTestbusFrameQueueSem);
}
void bus232_SendUnnumberedFrame(int iTaskId, bool boolPollFinal)
{
BUSM_FrameType *bDataPtr;
uint16 wDataLength = (uint16) (1);
BUSM_UnnumberedControlFrameType bControl;
uint8 bCheckSum;
WaitForSingleObject(semBusmHdlcSem, INFINITE);
bDataPtr = (BUSM_FrameType*) malloc(sizeof(BUSM_FrameType));
if(bDataPtr==NULL)
{
if (Rs232LogToFile)
{
// Heap full
fprintf(Rs232HdlcLogFile, "\n bus232_SendUnnumberedFrame -- HEAP FULL");
}
#ifdef RSX
PrintfInt("bus232_SendUnnumberedFrame - Heap full\n");
#endif
return;
}
bControl.InfoControl = 1; //
bControl.Unnumbered = 1; // Unnumbered frame
bControl.PollFinal = boolPollFinal;
bControl.Modifier = 0;
bControl.UnNmbSpec = BUSM_FLOW_UNNMB_SABM; // SABM control frame
bDataPtr->Dle = 0x10; // DLE
bDataPtr->uLengthMSB = (uint8) ((wDataLength&0xff00)>>8); // Length MSB
bDataPtr->uLengthLSB = (uint8) (wDataLength&0x00ff); // Length LSB
bDataPtr->uControl = *(BUSM_InfoFrameType*)&bControl; // Sequence number
bCheckSum = (*(uint8*)&bDataPtr->uControl);
bDataPtr->payloadHead.uProgId = bCheckSum; // Checksum
ReleaseMutex(semBusmHdlcSem);
if (Rs232LogToFile)
{
fprintf(Rs232HdlcLogFile, "\nTx Unnumbered SABM : PollFinal: %01x State %x ",bDataPtr->uControl.PollFinal&0x1,sHdlcControl.eHdlcState);
}
WaitForSingleObject(semTestbusFrameQueueSem, INFINITE);
EnQueue(&TestbusFrameQueue, bDataPtr);
ReleaseMutex(semTestbusFrameQueueSem);
}
static void bus232_RetransmitFrame(BUSM_FrameType *bInputDataPtr, bool boolPollFinal)
{
BUSM_FrameType *bDataPtr;
uint16 iLength;
uint8 bCheckSum,i;
if (sHdlcControl.eHdlcState == BUSM_LOCKED)
{
iLength = (bInputDataPtr->uLengthMSB<<8) + bInputDataPtr->uLengthLSB-3;
bDataPtr = (BUSM_FrameType*)malloc(iLength+sizeof(BUSM_FrameType));
if(bDataPtr==NULL)
{
if (Rs232LogToFile)
{
// Heap full
fprintf(Rs232HdlcLogFile, "\n bus232_RetransmitFrame -- HEAP FULL");
}
#ifdef RSX
PrintfInt("bus232_RetransmitFrame - Heap full\n");
#endif
return;
}
memcpy(bDataPtr,bInputDataPtr,iLength+sizeof(BUSM_FrameType)); // Copy mail
bDataPtr->uControl.PollFinal = boolPollFinal;
bDataPtr->uControl.RxSeq = sHdlcControl.bExpectedRxSeq;
bCheckSum = (*(uint8*)&bDataPtr->uControl) + bDataPtr->payloadHead.uProgId + bDataPtr->payloadHead.uTaskId;
for(i=0; i<iLength; i++)
{
bCheckSum += bDataPtr->payloadTail[i];
}
bDataPtr->payloadTail[iLength] = bCheckSum; // Checksum
if (Rs232LogToFile)
{
fprintf(Rs232HdlcLogFile, "\nTx Infoframe Resend: Tx-Seq:%02x Rx-Seq:%02x PollFinal: %01x State %x ",bDataPtr->uControl.TxSeq,bDataPtr->uControl.RxSeq,bDataPtr->uControl.PollFinal&0x1,sHdlcControl.eHdlcState);
}
}
WaitForSingleObject(semTestbusFrameQueueSem, INFINITE);
EnQueue(&TestbusFrameQueue, bDataPtr);
ReleaseMutex(semTestbusFrameQueueSem);
}
bool bus232_Busy(void)
{
return (sHdlcControl.eHdlcState != BUSM_LOCKED);
}
#endif
#ifdef BUSM_HDLC // Sliding window protocol
static bool RsxSwpCheckReceivedFrame(uint8 *RxFrame)
{
BUSM_BufferHeaderType *FramePtr=(BUSM_BufferHeaderType *)RxFrame;
bool boolReturnValue=FALSE,boolTestAcknowledge=FALSE;
uint8 uControl;
eFrameTypeEnum eFrameType;
uControl = (uint8)FramePtr->uControl;
if (((BUSM_InfoFrameType*)&uControl)->InfoControl == 0)
{
eFrameType = INFORMATION_FRAME;
}
else if (((BUSM_SuperVisoryControlFrameType*)&uControl)->Supervisory == 0)
{
eFrameType = SUPERVISORY_FRAME;
}
else
{
eFrameType = UNNUMBERED_FRAME;
}
WaitForSingleObject(semBusmHdlcSem, INFINITE);
switch (eFrameType){
case INFORMATION_FRAME:
{
if (Rs232LogToFile)
{
fprintf(Rs232HdlcLogFile, "\nRx Infoframe : Tx-Seq:%02x(%02x)Rx-Seq:%02x(%02x) PollFinal: %01x State %x ",((BUSM_InfoFrameType*)&uControl)->TxSeq,sHdlcControl.bExpectedRxSeq,((BUSM_InfoFrameType*)&uControl)->RxSeq,sHdlcControl.bExpectedAck,((BUSM_InfoFrameType*)&uControl)->PollFinal&0x1,sHdlcControl.eHdlcState);
}
if (sHdlcControl.eHdlcState == BUSM_LOCKED)
{
if (((BUSM_InfoFrameType*)&uControl)->TxSeq == sHdlcControl.bExpectedRxSeq)
{
#ifdef RSX
if(clRsx.iPrintBytes)
clRsx.Printf("Right Seq RX: %x EXP: %x ",((BUSM_InfoFrameType*)&uControl)->TxSeq, sHdlcControl.bExpectedRxSeq);
#endif
sHdlcControl.bExpectedRxSeq = (sHdlcControl.bExpectedRxSeq + 1) & BUSM_HDLC_SEQ_MOD;
boolTestAcknowledge = TRUE;
boolReturnValue = TRUE;
}
else
{
#ifdef RSX
if(clRsx.iPrintBytes)
{
clRsx.Printf("Wrong RX: %x EXP: %x ",((BUSM_InfoFrameType*)&uControl)->TxSeq, sHdlcControl.bExpectedRxSeq);
}
#endif
if (Rs232LogToFile)
{
fprintf(Rs232HdlcLogFile, " -> WRONG SEQ");
}
}
if (((BUSM_InfoFrameType*)&uControl)->PollFinal) // if final send acknowledge frame
{
bus232_SendSupervisorFrame(0,0);
}
}
else
{
// Try sending reset frame again
bus232_SendUnnumberedFrame(0, 1); // Final flag set, wiat for Unnumbered frame response
sHdlcControl.eHdlcState = BUSM_LOCK_PENDING;
}
}
break;
case SUPERVISORY_FRAME:
if (Rs232LogToFile)
{
fprintf(Rs232HdlcLogFile, "\nRx Supervisoryframe: Rx-Seq:%02x(%02x) PollFinal: %01x State %x ",((BUSM_InfoFrameType*)&uControl)->RxSeq,sHdlcControl.bExpectedAck,(((BUSM_InfoFrameType*)&uControl)->PollFinal)&0x1,sHdlcControl.eHdlcState);
}
if (sHdlcControl.eHdlcState == BUSM_LOCKED)
{
boolTestAcknowledge = TRUE;
}
else
{
// Try sending reset frame again
bus232_SendUnnumberedFrame(0, 1); // Final flag set, wiat for Unnumbered frame response
sHdlcControl.eHdlcState = BUSM_LOCK_PENDING;
}
break;
case UNNUMBERED_FRAME:
if (Rs232LogToFile)
{
fprintf(Rs232HdlcLogFile, "\nRx Unnumberedframe : PollFinal: %01x State %x ",((BUSM_InfoFrameType*)&uControl)->RxSeq,((BUSM_InfoFrameType*)&uControl)->PollFinal&0x1,sHdlcControl.eHdlcState);
}
//
if (((BUSM_UnnumberedControlFrameType*)&uControl)->PollFinal)
{
// reset HDLC
memset((void*)&sHdlcControl,0x00,sizeof(sHdlcControl)); // Reset variables
sHdlcControl.eHdlcState = BUSM_LOCKED;
bus232_SendUnnumberedFrame(0,0); //Answer
// Check for unsent frames
if (FirstUnsent)
{
// protected by the semaphore semBusmHdlcSem
sUnsentInfoframes *TempUnsendFrame;
bus232_SendPacketToUnit(FirstUnsent->iTaskId,FirstUnsent->iLength,FirstUnsent->Data);
TempUnsendFrame = FirstUnsent;
FirstUnsent = (sUnsentInfoframes*)FirstUnsent->Next; // Remove from list
free(TempUnsendFrame);
}
}
else
{
if (sHdlcControl.eHdlcState == BUSM_LOCK_PENDING)
{
memset((void*)&sHdlcControl,0x00,sizeof(sHdlcControl)); // Reset variables
sHdlcControl.eHdlcState = BUSM_LOCKED;
// Check for unsent frames
if (FirstUnsent)
{
// protected by the semaphore semBusmHdlcSem
sUnsentInfoframes *TempUnsendFrame;
bus232_SendPacketToUnit(FirstUnsent->iTaskId,FirstUnsent->iLength,FirstUnsent->Data);
TempUnsendFrame = FirstUnsent;
FirstUnsent = (sUnsentInfoframes*)FirstUnsent->Next; // Remove from list
free(TempUnsendFrame);
}
}
else
{
// Ignore
}
}
break;
}
if (boolTestAcknowledge)
{
while(Between(sHdlcControl.bExpectedAck, (((BUSM_InfoFrameType*)&uControl)->RxSeq+BUSM_HDLC_SEQ_MOD)&BUSM_HDLC_SEQ_MOD, sHdlcControl.bNextTxSeq))
{
// Free acknowledged frames
sHdlcControl.bTxNoAckCnt--;
if (NotAcknowledgeFramePtr[sHdlcControl.bExpectedAck])
{
free(NotAcknowledgeFramePtr[sHdlcControl.bExpectedAck]);
NotAcknowledgeFramePtr[sHdlcControl.bExpectedAck] = NULL;
}
if (sHdlcControl.bTxNoAckCnt==0) // If we are below the no acknowledge limit clear acknowledge timer
{
sHdlcControl.tNoAckNowledge = 0;
}
sHdlcControl.bExpectedAck=(sHdlcControl.bExpectedAck+1) & BUSM_HDLC_SEQ_MOD;
// Check for unsent frames
if (FirstUnsent&& sHdlcControl.eHdlcState == BUSM_LOCKED)
{
// protected by the semaphore semBusmHdlcSem
sUnsentInfoframes *TempUnsendFrame;
bus232_SendPacketToUnit(FirstUnsent->iTaskId,FirstUnsent->iLength,FirstUnsent->Data);
TempUnsendFrame = FirstUnsent;
FirstUnsent = (sUnsentInfoframes*)FirstUnsent->Next; // Remove from list
free(TempUnsendFrame);
}
}
}
ReleaseMutex(semBusmHdlcSem);
return boolReturnValue;
}
void bus232_ResetHDLCprotocol(void)
{
WaitForSingleObject(semBusmHdlcSem, INFINITE);
memset((void*)&sHdlcControl,0x00,sizeof(sHdlcControl)); // Reset variables
sHdlcControl.eHdlcState = BUSM_LOCK_PENDING;
ReleaseMutex(semBusmHdlcSem);
bus232_SendUnnumberedFrame(0, 1); // Final flag set, wiat for Unnumbered frame response
}
/****************************************************************************
* FUNCTION: Between
*
* INPUTS : a,b,c
* OUTPUTS : none
* RETURNS : Return: TRUE if a <= b < c
*
* DESCRIPTION: This function is used to check that the received acknowledgment
* number is within the acceptable vindow, the check is circulary.
*
****************************************************************************/
static bool Between(unsigned char a, unsigned int b, unsigned int c)
{
return ( ((a<=b) && (b<c)) || ((c<a) && (a<=b)) || ((b<c) && (c<a)));
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -