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

📄 udbldmsg.c

📁 工业组态软件modbus驱动源代码, 包括帮助文件.共享.
💻 C
📖 第 1 页 / 共 3 页
字号:
    return ((BYTE) cks);
} /* BldCks */

/***********************************************************************/
/** build message to read data from a point in the PLC,
    return length of message **/

/************************************************************************\
  Note: The last four arguments to this routine are protocol-dependent.
  Modify them as required.
\************************************************************************/

WORD
WINAPI
BldRead(LPSTR   *plpMsg,       /* pointer to where the message is stored */
        BYTE     plcDataType,  /* type of data to read */
        BYTE     DDEType,      /* type of data to transfer */
        WORD     addr1,        /* address of point(s) to be accessed */
        WORD     numRd)        /* number of items to read */
{
    LPSTR  ptr;
    BYTE   msgCmd;
    WORD   len;
    BYTE   cks;
    int    errflg;

    len = 0;

    /**************************\
      Build the message here.
      Example:
    \**************************/

    /* determine message command */
    msgCmd = plcDataType;

    /* initialize message buffer pointer */
    ptr = (LPSTR) msg;

    /* message type */
    ptr = put_bin_byte (ptr, msgCmd);

    /* starting address, number of items to read */
    ptr = put_bin_word (ptr, addr1);
    ptr = put_bin_byte (ptr, (BYTE) numRd);

    /* get length, allowing for checksum */
    len = (WORD) ((unsigned long)(ptr - (LPSTR) msg) + 1);

    /* checksum */
    cks = BldCks ((LPSTR) &msg[0], len-1, &errflg);
    ptr = put_bin_byte (ptr, cks);

    /**************************\
      End of example
    \**************************/

    /* return the address and the length of the message built */
    *plpMsg = (LPSTR) msg;
    if (Verbose)
        ShowBldMsg ((LPSTR) &msg[0], len);
    return (len);
} /* BldRead */

/***********************************************************************/
/** build message to write data to a point in the PLC,
    return length of message **/

/************************************************************************\
  Note: The last four arguments to this routine are protocol-dependent.
  Modify them as required.
\************************************************************************/

WORD
WINAPI
BldWrite(LPSTR    *plpMsg,     /* pointer to where the message is stored */
         BYTE FAR *pData,      /* pointer to data values to be sent */
         BYTE      plcDataType,/* type of device data to generate */
         BYTE      DDEType,    /* type of data to transfer */
         WORD      addr1,      /* address of point(s) to be accessed */
         WORD      numWrt)     /* number of items to write */
{
    LPSTR  ptr;
    BYTE   msgCmd;
    WORD   len;
    BYTE   cks;
    WORD   i;
    int    errflg;

    len = 0;

    /**************************\
      Build the message here.
      Example:
    \**************************/

    /* determine message command */
    msgCmd = (BYTE) (plcDataType | 0x80);

    /* initialize message buffer pointer */
    ptr = (LPSTR) msg;

    /* message type */
    ptr = put_bin_byte (ptr, msgCmd);

    /* starting address, number of items to write */
    ptr = put_bin_word (ptr, addr1);
    ptr = put_bin_byte (ptr, (BYTE) numWrt);

    /* data for each item */
    for( i=0; i<numWrt; i++ ) {
        ptr = put_bin_word (ptr, (WORD) (*(INTG FAR *)pData));
        pData += 2;
    }

    /* get length, allowing for checksum */
    len = (WORD) ((unsigned long)(ptr - (LPSTR) msg) + 1);

    /* checksum */
    cks = BldCks ((LPSTR) &msg[0], len-1, &errflg);
    ptr = put_bin_byte (ptr, cks);

    /**************************\
      End of example
    \**************************/

    /* return the address and the length of the message built */
    *plpMsg = (LPSTR) msg;
    if (Verbose)
        ShowBldMsg ((LPSTR) &msg[0], len);
    return (len);
} /* BldWrite */

/***********************************************************************/
/* display built message for tracing purposes */

static
VOID
WINAPI
ShowBldMsg (LPSTR lpStr, WORD len)
{
    BYTE FAR *rd;
    int i, n, L;
    int max_str, max_msg;

    /* get message length and pointer */
    n = (int) len;
    rd = (BYTE FAR *) lpStr;

    /* get number of characters that can be stored in display string */
    max_str = DBG_BUF_SIZE - 1;

    /* format message for display */
    sprintf (dbgBuf, "BldMsg (%d) -- ", n);

    /****************************************************************\
        Format the rest of the message and append it to dbgBuf.
        Depending on the protocol, it may be appropriate to
        convert bytes to hex ASCII, or simply copy an ASCII string.
    \****************************************************************/

    L = strlen (dbgBuf);
    if (n == 0) {
        sprintf (&dbgBuf[L], "<nothing>");
    } else {
        if (bBldSendMsgInBinary) {
            /* convert characters to hex ASCII */
            max_msg = (max_str - L) / 2;
            if (n > max_msg)
                /* make sure message doesn't overflow buffer */
                n = max_msg;
            if (n > 0) {
                for (i = 1; i <= n; i++) {
                    sprintf (&dbgBuf[L], "%02X", *(rd++));
                    L += strlen (&dbgBuf[L]);
                }
            }
        } else {
            /* take characters just as they are */
            max_msg = max_str - L;
            if (n > max_msg)
                /* make sure message doesn't overflow buffer */
                n = max_msg;
            f_lstrncpy (&dbgBuf[L], (LPSTR) rd, n);
            dbgBuf[L+n] = '\0';
        }
    }

    /* output display string to logger */
    debug (dbgBuf);
} /* ShowBldMsg */

/***********************************************************************/
/** verify that the command header format is valid,
    return the expected total length of the message **/

BOOL
WINAPI
IsHeaderValid (LPSTR lpStr, int len, int *total_len)
{
    /*******************************************************************\
        The contents of this routine are protocol dependent.

        This routine is called at the point when 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 return the new expected length.

        The example code below assumes a header of the form
            BBAAAANN
        where response to a write will be of the form
            BBAAAANNXX
        and the response to a read will be of the form
            BBAAAANN[CCCC]....[CCCC]XX
        where BB   is a 1-byte command
              AAAA is a 2-byte address
              NN   is a 1-byte number of words
              CCCC is a word value
              XX   is a 1-byte checksum
        Alternatively, an error message may be received, which will
        have one of the following forms:
            000000000000FF
        for a garbled message
            00BBAAAANN00XX
        for an invalid command BB
            00BBAAAANNDDXX
        for an invalid number of "cells" to read or write
        So by the fourth character, we know how many are coming.
    \*******************************************************************/

    BYTE FAR *lpBuf;
    int    num_words;
    BYTE   cmd;
    BOOL   valid;

    /* initialize return status, length */
    valid = TRUE;
    *total_len = len;

    /* check start of message */
    lpBuf = (BYTE FAR *) lpStr;

    /* get command */
    if (len < 1) {
        valid = FALSE;
    } else {
        cmd = *lpBuf;
    }

    /* check for error message */
    if (valid) {
        if (cmd == 0x00) {
            /* error message, set up for response length */
            *total_len = 7;
        } else {
            /* get number of words handled by message */
            if (len < 4) {
                valid = FALSE;
            } else {
                num_words = (int) *(lpBuf+3);
                /* check whether read or write */
                if ((cmd & 0x80) != 0) {
                    /* command is a write, response is fixed length */
                    *total_len = 5;
                } else {
                    /* command is a read, response is based on count */
                    *total_len = 5 + num_words * 2;
                }
            }
        }
    }

    /* indicate whether message header is valid */
    return (valid);
} /* IsHeaderValid */

/***********************************************************************/
/** verify that the command format is valid **/

BOOL
WINAPI
IsCommandValid (LPSTR lpStr, int len)
{
    /*******************************************************************\
       The contents of this routine are protocol dependent.

       The following example assumes that the received message is in
       the format
           AABBCCDDEE...ZZ
       where AA, BB, ..., ZZ are byte values,
       and ZZ is the checksum for the message.
    \*******************************************************************/

    int cks, byteval, err1;
    BOOL ok;

    /* initialize return value */
    ok = TRUE;

    /* check length of command */
    if (len < 2) {
        /* too short */
        ok = FALSE;
    } else {
        /* calculate checksum */
        cks = BldCks (lpStr, len-1, &err1);
        /* compare to checksum in message */
        byteval = *((BYTE FAR *) (lpStr+(len-1)));
        if (err1 || (cks != byteval))
            /* invalid characters or mismatched checksum */
            ok = FALSE;
    }
    /* indicate success or failure */
    return (ok);
} /* IsCommandValid */

/***********************************************************************/
/** convert indicated message to binary,
    return TRUE if resulting string is valid binary data **/

BOOL
WINAPI
GetMsgAsBinary (LPSTR lpStr, int *len)
{
    /*******************************************************************\
       The contents of this routine are protocol dependent.

       The following example assumes that the received message is
       already in binary form.
    \*******************************************************************/

    /* indicate whether binary message is valid */
    return (TRUE);
} /* GetMsgAsBinary */

/***********************************************************************/
/** determine size of block needed for message to read data
    returns size for a new block of data
    and size for extending an existing block of data **/

/************************************************************************\
  Note: The last four arguments to this routine are protocol-dependent.
  Modify them as required.
\************************************************************************/

VOID
WINAPI
GetBldMsgReadBlockSizes (WORD *blockSize,
                         WORD *extSize,
                         BYTE msgType,
                         BYTE plcDataType,
                         WORD addr1,
                         WORD count)
{
    WORD len;
    WORD bytesToWrite;

    /* determine length of data */
    bytesToWrite = (WORD) (count * 2);

    /* length of characters needed to specify data */
    len = 0;

    /* return length of data extension */
    *extSize = len;

    /** allow for type, address prefix, length count:  TT AAAA NN **/
    len += 4;

    /** allow for checksum XX **/
    len += 1;

    /* return length of block */
    *blockSize = len;
} /* GetBldMsgReadBlockSizes */

/***********************************************************************/
/** determine size of block needed for message to write data
    returns size for a new block of data
    and size for extending an existing block of data **/

/************************************************************************\
  Note: The last four arguments to this routine are protocol-dependent.
  Modify them as required.
\************************************************************************/

VOID
WINAPI
GetBldMsgWriteBlockSizes (WORD *blockSize,
                          WORD *extSize,
                          BYTE msgType,
                          BYTE plcDataType,
                          WORD addr1,
                          WORD count)
{
    WORD len;
    WORD bytesToWrite;

    /* determine length of data */
    bytesToWrite = (WORD) (count * 2);

    /* length of characters needed to specify data */
    len = bytesToWrite;

    /* return length of data extension */
    *extSize = len;

    /** allow for type, address prefix, length count:  TT AAAA NN **/
    len += 4;

    /** allow for checksum XX **/
    len += 1;

    /* return length of block */
    *blockSize = len;
} /* GetBldMsgWriteBlockSizes */
#endif

/********************************************************************/
/** ensure string is of length that can be handled by a single message
    returns acceptable length */

WORD
WINAPI
LimitStringLength (WORD addr1,
                   WORD count,
                   WORD numBytes,
                   int  msgRead)
{
    WORD new_count;
    WORD count_limit;
    WORD length;

    /*******************************************************************\
       The contents of this routine are protocol dependent.
       The protocol may have addressing schemes that require
       additional bytes, further limiting the number of bytes
       available for data.
    \*******************************************************************/

    /* initialize return value */
    new_count = count;

    /* check expected length of message */
    if (msgRead)
    {
        /* set aside length for command, addressing */
        length = 0;
        /* ensure string is no longer than what we can receive in one message */
        count_limit = (WORD) ((UD_MAX_READ_LENGTH - length) / numBytes);
        if (new_count > count_limit)
        {
            /* too long, truncate string to manageable length */
            new_count = count_limit;
        }
    }
    else
    {
        /* set aside length for command, addressing */
        length = 0;
        /* ensure string is no longer than what we can transmit in one message */
        count_limit = (WORD) ((UD_MAX_MESSAGE_SIZE - length) / numBytes);
        if (new_count > count_limit)
        {
            /* too long, truncate string to manageable length */
            new_count = count_limit;
        }
    }

    /* return limited string count */
    return (new_count);
} /* LimitStringLength */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -