⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udprotcl.c

📁 工业组态软件modbus驱动源代码, 包括帮助文件.共享.
💻 C
📖 第 1 页 / 共 5 页
字号:
        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 + -