fixed single word/coil write fc5/fc6

master
Steffen Pohle 10 months ago
parent f0c160a9d6
commit cd08819ea3

@ -1,3 +1,6 @@
2024-11-08:
- fixed single coil / word write. Response was not correct.
2024-08-07: 2024-08-07:
- fixed compile on windows. stdint.h was not included - fixed compile on windows. stdint.h was not included

@ -1,5 +1,5 @@
.SILENT: help .SILENT: help
VERSION = 1.0.3 VERSION = 1.0.4
-include Makefile.rules -include Makefile.rules

@ -254,8 +254,6 @@ void ModbusSrv::ServerThread() {
else if (mbindata->fc == 5 || mbindata->fc == 6) { else if (mbindata->fc == 5 || mbindata->fc == 6) {
if (WorkerAndEncodeWriteSingle(mbindata, mboutdata)) { if (WorkerAndEncodeWriteSingle(mbindata, mboutdata)) {
clients[slot]->Write(mboutdata->buffer, mboutdata->bufferlen); clients[slot]->Write(mboutdata->buffer, mboutdata->bufferlen);
delete clients[slot];
clients[slot] = NULL;
} }
else { else {
char *txt = (char*)malloc(255); char *txt = (char*)malloc(255);
@ -456,33 +454,10 @@ int ModbusSrv::WorkerAndEncodeWriteSingle(struct modbus_data *mbin, struct modbu
// transaction // transaction
mbout->transactionid = mbin->transactionid; mbout->transactionid = mbin->transactionid;
i16 = htons((uint16_t)mbin->transactionid);
memcpy (mbout->buffer+pos, &i16, sizeof(i16));
pos += sizeof (i16);
// protocolid
mbout->protoolid = mbin->protoolid; mbout->protoolid = mbin->protoolid;
i16 = htons((uint16_t)mbin->protoolid); mbout->length = 0;
memcpy (mbout->buffer+pos, &i16, sizeof(i16));
pos += sizeof (i16);
// length 3 + number of registers
mbout->length = 3;
mbout->length += mbin->regcnt * 2; // 16bit = 2Bytes
i16 = htons((uint16_t)mbout->length);
memcpy (mbout->buffer+pos, &i16, sizeof(i16));
pos += sizeof (i16);
// device id
mbout->unitid = mbin->unitid; mbout->unitid = mbin->unitid;
memcpy (mbout->buffer+pos, &mbout->unitid, sizeof(uint8_t));
pos += sizeof (uint8_t);
// fc
mbout->fc = mbin->fc; mbout->fc = mbin->fc;
memcpy (mbout->buffer+pos, &mbout->fc, sizeof(uint8_t));
pos += sizeof (uint8_t);
mbout->direction = 1; mbout->direction = 1;
if (mbin->fc == 5) { if (mbin->fc == 5) {
@ -492,33 +467,17 @@ int ModbusSrv::WorkerAndEncodeWriteSingle(struct modbus_data *mbin, struct modbu
else mbarray[FC1][mbin->regstart].value = 0; else mbarray[FC1][mbin->regstart].value = 0;
} }
else error = 1; else error = 1;
// return register and value
i16 = htons((uint16_t)mbin->regstart);
memcpy (mbout->buffer+pos, &i16, sizeof(i16));
pos += sizeof (i16);
i16 = htons((uint16_t)mbin->regcnt);
memcpy (mbout->buffer+pos, &i16, sizeof(i16));
pos += sizeof (i16);
} }
if (mbin->fc == 6) { if (mbin->fc == 6) {
mbarray[FC3][mbin->regstart].requested |= 2; mbarray[FC3][mbin->regstart].requested |= 2;
if (mbarray[FC3][mbin->regstart].enabled) if (mbarray[FC3][mbin->regstart].enabled)
mbarray[FC3][mbin->regstart].value = mbin->regcnt; mbarray[FC3][mbin->regstart].value = mbin->regcnt;
else error = 1; else error = 1;
// return register and value
i16 = htons((uint16_t)mbin->regstart);
memcpy (mbout->buffer+pos, &i16, sizeof(i16));
pos += sizeof (i16);
i16 = htons((uint16_t)mbin->regcnt);
memcpy (mbout->buffer+pos, &i16, sizeof(i16));
pos += sizeof (i16);
} }
mbout->bufferlen = pos; // mirror the output
memcpy (mbout->buffer, mbin->buffer, mbin->bufferlen);
mbout->bufferlen = mbin->bufferlen;
// //
// inform the application about the modbus values change // inform the application about the modbus values change
@ -672,7 +631,7 @@ int ModbusSrv::Decode(struct modbus_data *mbdata) {
int ret = 1; int ret = 1;
mbdata->fc = 0; mbdata->fc = 0;
mbdata->regcnt = -1; mbdata->regcnt = 0;
mbdata->regstart =-1; mbdata->regstart =-1;
mbdata->unitid = 0; mbdata->unitid = 0;
mbdata->length = 0; mbdata->length = 0;
@ -716,6 +675,12 @@ int ModbusSrv::Decode(struct modbus_data *mbdata) {
pos += sizeof(i16); pos += sizeof(i16);
mbdata->regstart = ntohs(i16); mbdata->regstart = ntohs(i16);
// not needed for single write
if (mbdata->fc == 5 || mbdata->fc == 6) {
mbdata->regcnt = 0;
mbdata->bytecnt = 0;
}
// number of registers // number of registers
if (mbdata->length < pos-6) ret = 0; if (mbdata->length < pos-6) ret = 0;
memcpy (&i16, mbdata->buffer+pos, sizeof(i16)); memcpy (&i16, mbdata->buffer+pos, sizeof(i16));

Loading…
Cancel
Save