📄 udbldmsg.c
字号:
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 + -