You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
3.6 KiB
156 lines
3.6 KiB
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// modbus.cc is part of TestModbus-Client.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include "modbus.h"
|
|
|
|
#define PACK_INT8(__dstptr, __srci8) \
|
|
memcpy(__dstptr, &__srci8, 1); \
|
|
__dstptr += 1
|
|
|
|
#define UNPACK_INT8(__dsti8, __srcptr) \
|
|
memcpy(&__dsti8, __srcptr, 1); \
|
|
__srcptr += 1
|
|
|
|
#define PACK_INT16(__tmpi16, __dstptr, __srci16) \
|
|
__tmpi16 = htons((uint16_t)__srci16); \
|
|
memcpy(__dstptr, &__tmpi16, 2); \
|
|
__dstptr += 2
|
|
|
|
#define UNPACK_INT16(__tmpi16, __dsti16, __srcptr) \
|
|
memcpy(&__tmpi16, __srcptr, 2); \
|
|
__srcptr += 2; \
|
|
__dsti16 = ntohs((uint16_t)__tmpi16)
|
|
|
|
/*
|
|
* packs the request header into the buffer data and returns the lenght of the header
|
|
* returns NULL on error or points to end of data
|
|
*/
|
|
char * modbustcp_pkt_headerrq (char *destbuffer, int bufsize, modbustcp_rq_header *srcmbh) {
|
|
uint16_t tmp;
|
|
|
|
// destination memory valid
|
|
if (destbuffer == NULL) {
|
|
errno = EFAULT;
|
|
return NULL;
|
|
}
|
|
if (bufsize < 12) {
|
|
errno = EOVERFLOW;
|
|
return NULL;
|
|
}
|
|
|
|
char *pos = destbuffer;
|
|
|
|
PACK_INT16(tmp, pos, srcmbh->transid);
|
|
PACK_INT16(tmp, pos, srcmbh->protid);
|
|
PACK_INT16(tmp, pos, srcmbh->length);
|
|
PACK_INT8(pos, srcmbh->uid);
|
|
PACK_INT8(pos, srcmbh->fc);
|
|
PACK_INT16(tmp, pos, srcmbh->offset);
|
|
PACK_INT16(tmp, pos, srcmbh->number);
|
|
|
|
return pos;
|
|
}
|
|
|
|
|
|
/*
|
|
* unpacks the buffer into the header request
|
|
* returns NULL on error or points to end of data
|
|
*/
|
|
char * modbustcp_unpkt_headerrq (modbustcp_rq_header *destmbh, char *srcbuffer, int bufsize) {
|
|
uint16_t tmp;
|
|
|
|
printf ("%s:%d %s bufsize:%d\n", __FILE__, __LINE__, __FUNCTION__, bufsize);
|
|
|
|
// source memory valid
|
|
if (srcbuffer == NULL) {
|
|
errno = EFAULT;
|
|
return NULL;
|
|
}
|
|
if (bufsize < 12) {
|
|
errno = EOVERFLOW;
|
|
return NULL;
|
|
}
|
|
|
|
char *src = srcbuffer;
|
|
|
|
UNPACK_INT16(tmp, destmbh->transid, src);
|
|
UNPACK_INT16(tmp, destmbh->protid, src);
|
|
UNPACK_INT16(tmp, destmbh->length, src);
|
|
UNPACK_INT8(destmbh->uid, src);
|
|
UNPACK_INT8(destmbh->fc, src);
|
|
UNPACK_INT16(tmp, destmbh->offset, src);
|
|
UNPACK_INT16(tmp, destmbh->number, src);
|
|
|
|
return src;
|
|
}
|
|
|
|
|
|
/*
|
|
* packs the resonse header into the buffer data and returns the lenght of the header
|
|
* returns NULL on error or points to end of data
|
|
*/
|
|
char * modbustcp_pkt_headerres (char *destbuffer, int bufsize, modbustcp_res_header *srcmbh) {
|
|
uint16_t tmp;
|
|
|
|
// destination memory valid
|
|
if (destbuffer == NULL) {
|
|
errno = EFAULT;
|
|
return NULL;
|
|
}
|
|
if (bufsize < 9) {
|
|
errno = EOVERFLOW;
|
|
return NULL;
|
|
}
|
|
|
|
char *pos = destbuffer;
|
|
|
|
PACK_INT16(tmp, pos, srcmbh->transid);
|
|
PACK_INT16(tmp, pos, srcmbh->protid);
|
|
PACK_INT16(tmp, pos, srcmbh->length);
|
|
PACK_INT8(pos, srcmbh->uid);
|
|
PACK_INT8(pos, srcmbh->fc);
|
|
PACK_INT8(pos, srcmbh->number);
|
|
|
|
return pos;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* unpacks the buffer into the header modbustcp response
|
|
* returns NULL on error or points to end of data
|
|
*/
|
|
char * modbustcp_unpkt_headerres (modbustcp_res_header *destmbh, char *srcbuffer, int bufsize) {
|
|
uint16_t tmp;
|
|
|
|
printf ("%s:%d %s bufsize:%d\n", __FILE__, __LINE__, __FUNCTION__, bufsize);
|
|
|
|
// source memory valid
|
|
if (srcbuffer == NULL) {
|
|
errno = EFAULT;
|
|
return NULL;
|
|
}
|
|
if (bufsize < 10) {
|
|
errno = EOVERFLOW;
|
|
return NULL;
|
|
}
|
|
|
|
char *src = srcbuffer;
|
|
|
|
UNPACK_INT16(tmp, destmbh->transid, src);
|
|
UNPACK_INT16(tmp, destmbh->protid, src);
|
|
UNPACK_INT16(tmp, destmbh->length, src);
|
|
UNPACK_INT8(destmbh->uid, src);
|
|
UNPACK_INT8(destmbh->fc, src);
|
|
UNPACK_INT8(destmbh->number, src);
|
|
|
|
return src;
|
|
}
|