?? udprotcl.c
字號:
valid = GetMsgAsBinary ((LPSTR) &lpPort->mbRspBuffer[0], &len);
lpPort->mbRspIndex = len;
\*******************************************************************/
/* check whether received message was valid */
// 3/4/2000 modify by Chen jun
int len;
WORD cks;
BYTE cks1,cks2;
len = lpPort->mbRspIndex;
cks = CRC16((BYTE*)lpPort->mbRspBuffer,len-2);
cks1 = (BYTE)(cks%256);
cks2 = (BYTE)(cks/256);
// 3/5/2000 modify by Chen jun
if (lpPort->mbRspBuffer[1] & 0x80) {
UdprotHandleRspError(lpPort);
debug ("Error message received.");
lpPort->mbState = PROT_WAITQUIET;
}
else {
if (lpPort->mbRspBuffer[len-2] != cks1 ||lpPort->mbRspBuffer[len-1] != cks2){
UdprotHandleRspError(lpPort);
debug ("Error message received.");
lpPort->mbState = PROT_WAITQUIET;
}
else
ProcessValidResponse(lpPort);
}
/* check the port for errors and log them */
checkEvents(lpPort);
/* set up new poll of current station */
UdprotPoll(lpPort);
} /* UdprotProcessResponse */
/***********************************************************************/
/** Read port and check for complete message.
Check the communications port for a completed message ending in a return
character, too many characters received, or a timeout while waiting for
completion.
Called from DoProtocol( )
returns TRUE if complete message has been received. **/
BOOL
WINAPI
UdprotGetResponse(LPPORT lpPort)
{
int iWCRet;
int total_len;
LPSTAT lpTopic;
LPSTR topic_name;
/*******************************************************************\
For variable length messages, you should normally wait for the
number of bytes required to insure that the length field of the
message has been received. Then calculate the total length of
the message.
When the entire message has been received, this function should
return TRUE.
In ALL other cases, it should return FALSE.
\*******************************************************************/
/* attempt to read message from port, check result */
if (PortHasData (lpPort)) {
/* check for response data */
iWCRet = ReadPortMsg (lpPort);
if (iWCRet < 0) {
/* serious error encountered, wait for quiet recovery */
lpPort->mbState = PROT_WAITQUIET;
/* indicate message not complete */
return FALSE;
}
} else {
/* indicate no new response data */
iWCRet = 0;
}
/* check for receive timeout */
if (lpPort->mbRspIndex < lpPort->mbRspExpLen) {
/* number of characters less than number expected, check timing */
if ((lpPort->mbTimer -= tickChange) <= 0) {
/* timed out, clear timer */
lpPort->mbTimer = (WORD) GetDeltaTime ();
if (ShowingErrors) {
/* get name of topic for timeout message */
lpTopic = lpPort->mbCurTopic;
if (lpTopic != (LPSTAT) NULL) {
topic_name = lpTopic->statTopicName;
} else {
topic_name = (LPSTR) "<none>";
}
/* "Response Timeout (wait=%d, got=%d, topic=\"%Fs\", port=%Fs)" */
sprintf(dbgBuf, GetString(STRUSER + 105),
(int) lpPort->mbRspExpLen, (int) lpPort->mbRspIndex,
topic_name, lpPort->mbPortName);
debug(dbgBuf);
}
/* handle response error */
UdprotHandleRspError(lpPort);
}
/* indicate message not complete */
return FALSE;
}
/* not timed out, handle according to protocol state */
switch (lpPort->mbState) {
case PROT_WAITHDR:
/* waiting for header with length, check length of response */
if (lpPort->mbRspIndex < lpPort->mbRspExpLen) {
/* expected length not yet received, indicate message not complete */
return FALSE;
}
/*******************************************************************\
At this point, we have received enough bytes to pick the
length out of the message header. Validate the message
header and calculate the total length of the message.
Then set the new expected length with the following statement:
lpPort->mbRspExpLen = total message length;
\*******************************************************************/
/* check whether message format is valid so far, get total length */
// if (IsHeaderValid ((LPSTR) &lpPort->mbRspBuffer[0],
// lpPort->mbRspIndex, &total_len)) {
/* update expected length for total message */
// lpPort->mbRspExpLen = total_len;
// } else {
/** indicate problem with the message header,
wait for message to end */
// debug ("Bad header");
// lpPort->mbTimer = (WORD) GetDeltaTime () + ERRORDELAY;
// lpPort->mbState = PROT_PROTERRORDELAY;
// return (FALSE);
// }
/* advance to next state, waiting for remainder of message */
lpPort->mbState = PROT_WAITRESP;
/* fall through to next case */
case PROT_WAITRESP:
/* waiting for complete response, check length of response */
/***************************************************************\
Note: We may have recalculated the response length
based on information in the message header.
Check to see if the entire message has been received.
\***************************************************************/
if (lpPort->mbRspIndex < lpPort->mbRspExpLen) {
/* expected length not yet received, indicate message not complete */
return FALSE;
}
/* We have received the entire message. */
if (ShowingReceive)
/* have logger display received message */
showReceivedData(lpPort);
/* indicate complete message received */
return TRUE;
default:
/* this is not a valid state for the protocol, report error */
lpPort->mbTimer = (WORD) GetDeltaTime () + ERRORDELAY;
lpPort->mbState = PROT_PROTERRORDELAY;
checkEvents(lpPort);
sprintf(dbgBuf, "Illogical Protocol State: %d", lpPort->mbState);
debug(dbgBuf);
break;
}
/* indicate message not complete */
return FALSE;
} /* UdprotGetResponse */
/***********************************************************************/
/** advance message timers on indicated port **/
void
WINAPI
UdprotAdvanceMsgTimers(LPPORT lpPort)
{
LPSTAT lpTopic;
LPUDMSG lpMsg;
CHAINSCANNER station_scanner;
CHAINSCANNER message_scanner;
/* get pointer to first station on port */
lpTopic = (LPSTAT) FindFirstItem (&lpPort->mbTopicList, SCAN_FROM_HEAD,
NULL, NULL, &station_scanner);
/* examine each station on the port */
while (lpTopic != (LPSTAT) NULL) {
/* check for topic being delayed after errors */
if (lpTopic->statDelay != 0L) {
/* decrement delay timer */
if ((lpTopic->statDelay -= (LONG) tickChange) <= 0L) {
/* end of delay reached, clear delay count */
lpTopic->statDelay = 0L;
}
} else {
/* no topic delay, examine every message on the topic */
lpMsg = (LPUDMSG) FindFirstItem (&lpTopic->statReadMsgList,
SCAN_FROM_HEAD,
NULL, NULL, &message_scanner);
while (lpMsg != (LPUDMSG) NULL) {
/* check whether message is active and still waiting */
if (lpMsg->mmActiveCt && lpMsg->mmScanTimer) {
/* decrement scan timer */
if ((lpMsg->mmScanTimer -= tickChange) <= 0) {
/* end of scan interval reached, reload */
lpMsg->mmScanTimer = lpMsg->mmScanReload;
/* indicate message is due */
lpMsg->mmDue = TRUE;
}
}
/* advance to next message on this station */
lpMsg = (LPUDMSG) FindNextItem (&message_scanner);
}
}
/* advance to next station on this port */
lpTopic = (LPSTAT) FindNextItem (&station_scanner);
}
} /* UdprotAdvanceMsgTimers */
/***********************************************************************/
/** This function will be called periodically by ProtTimerEvent().
All continuing protocol activity will be controlled by this function.
A state-machine is used to control the events of the protocol
from call to call. This function is the heartbeat of the protocol. **/
LPPORT
WINAPI
UdprotDoProtocol(LPPORT lpPort)
{
/* check pointer to port structure */
if (lpPort == (LPPORT)NULL) {
/* nothing to do, just return */
return (LPPORT) NULL;
}
/* advance all message timers on this port */
UdprotAdvanceMsgTimers(lpPort);
/* handle port activity according to state */
switch (lpPort->mbState) {
case PROT_IDLE:
/* port is idle, check for something to do */
UdprotPoll(lpPort);
break;
case PROT_WAITHDR:
case PROT_WAITRESP:
/* port is waiting for a message to come in, check if complete */
if (UdprotGetResponse(lpPort)) {
/* complete message received, process it */
UdprotProcessResponse(lpPort);
}
break;
case PROT_WAITQUIET:
/* receive error occurred, wait for receive to stop. */
if (WaitForQuietPort (lpPort, (LPSTR) "Port has data during wait for quiet:")) {
/* quiet, handle response error, then continue */
UdprotHandleRspError(lpPort);
}
break;
case PROT_PROTERRORDELAY:
/* error delay on port, update delay timer */
if ((lpPort->mbTimer -= tickChange) <= 0) {
/* error delay complete, clear delay counter */
lpPort->mbTimer = (WORD) GetDeltaTime ();
if (bFlushOnError)
/* flush port buffers */
FlushPort (lpPort, (LPSTR) "");
/* set up new poll of current station */
UdprotPoll(lpPort);
}
break;
default:
/* this is not a valid state for the protocol, report error */
/* "Invalid Protocol State (%d) on %Fs" */
sprintf(dbgBuf, GetString(STRUSER + 106),
lpPort->mbState, lpPort->mbPortName);
lpPort->mbTimer = (WORD) GetDeltaTime () + ERRORDELAY;
lpPort->mbState = PROT_PROTERRORDELAY;
debug(dbgBuf);
break;
}
/* return pointer to next port in list */
return ((LPPORT) lpPort->mbChainLink.next_item.ptr);
} /* UdprotDoProtocol */
/********************************************************************/
/* convert binary value to BCD */
WORD
WINAPI
UdprotCvtBinToBCD ( WORD BinaryValue )
{
WORD BcdVal;
div_t temp;
ldiv_t tempL;
/* get ones digit */
tempL = ldiv ((long) BinaryValue, 10L);
BcdVal = (WORD) tempL.rem;
/* get tens digit */
temp = div ((int) tempL.quot, 10);
BcdVal |= ((WORD) temp.rem << 4);
/* get hundreds digit */
temp = div (temp.quot, 10);
BcdVal |= ((WORD) temp.rem << 8);
/* get thousands digit */
#ifdef ENSURE_BCD
temp = div (temp.quot, 10);
BcdVal |= ((WORD) temp.rem << 12);
#else
BcdVal |= ((WORD) temp.quot << 12);
#endif
/* return result */
return BcdVal;
} /*UdprotCvtBinToBCD*/
/********************************************************************/
/* convert BCD value to binary */
WORD
WINAPI
UdprotCvtBCDToBin ( WORD BcdVal
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -