From cd08819ea333e5aa86326d72bcfd169d1beb4c76 Mon Sep 17 00:00:00 2001 From: Steffen Pohle Date: Fri, 8 Nov 2024 22:04:57 +0100 Subject: [PATCH] fixed single word/coil write fc5/fc6 --- Changelog | 3 +++ Makefile | 2 +- modbussrv.cc | 59 +++++++++++----------------------------------------- 3 files changed, 16 insertions(+), 48 deletions(-) diff --git a/Changelog b/Changelog index 6bc44d9..30b454b 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,6 @@ +2024-11-08: +- fixed single coil / word write. Response was not correct. + 2024-08-07: - fixed compile on windows. stdint.h was not included diff --git a/Makefile b/Makefile index 92745c3..3e02600 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ .SILENT: help -VERSION = 1.0.3 +VERSION = 1.0.4 -include Makefile.rules diff --git a/modbussrv.cc b/modbussrv.cc index c0bc240..e4237ca 100644 --- a/modbussrv.cc +++ b/modbussrv.cc @@ -254,8 +254,6 @@ void ModbusSrv::ServerThread() { else if (mbindata->fc == 5 || mbindata->fc == 6) { if (WorkerAndEncodeWriteSingle(mbindata, mboutdata)) { clients[slot]->Write(mboutdata->buffer, mboutdata->bufferlen); - delete clients[slot]; - clients[slot] = NULL; } else { char *txt = (char*)malloc(255); @@ -456,33 +454,10 @@ int ModbusSrv::WorkerAndEncodeWriteSingle(struct modbus_data *mbin, struct modbu // transaction 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; - i16 = htons((uint16_t)mbin->protoolid); - 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->length = 0; mbout->unitid = mbin->unitid; - memcpy (mbout->buffer+pos, &mbout->unitid, sizeof(uint8_t)); - pos += sizeof (uint8_t); - - // fc mbout->fc = mbin->fc; - memcpy (mbout->buffer+pos, &mbout->fc, sizeof(uint8_t)); - pos += sizeof (uint8_t); - mbout->direction = 1; 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 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) { mbarray[FC3][mbin->regstart].requested |= 2; if (mbarray[FC3][mbin->regstart].enabled) mbarray[FC3][mbin->regstart].value = mbin->regcnt; 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 @@ -672,8 +631,8 @@ int ModbusSrv::Decode(struct modbus_data *mbdata) { int ret = 1; mbdata->fc = 0; - mbdata->regcnt = -1; - mbdata->regstart = -1; + mbdata->regcnt = 0; + mbdata->regstart =-1; mbdata->unitid = 0; mbdata->length = 0; mbdata->direction = 0; @@ -716,6 +675,12 @@ int ModbusSrv::Decode(struct modbus_data *mbdata) { pos += sizeof(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 if (mbdata->length < pos-6) ret = 0; memcpy (&i16, mbdata->buffer+pos, sizeof(i16));