|
|
|
@ -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));
|
|
|
|
|