@@ -124,23 +124,6 @@ bool Modbus::regOutOfBounds (word address, word value) {
124
124
return false ;
125
125
}
126
126
127
- // -------------------------------------------------------------------------------
128
- int Modbus::setAdditionalServerData (const char data[]) {
129
-
130
- free (_additional_data);
131
- if (data) {
132
- size_t l = strlen (data) + 1 ;
133
-
134
- _additional_data = (char *) malloc (l);
135
- if (_additional_data) {
136
-
137
- strcpy (_additional_data, data);
138
- return l;
139
- }
140
- }
141
- return 0 ;
142
- }
143
-
144
127
// -------------------------------------------------------------------------------
145
128
// protected
146
129
void Modbus::receivePDU (byte *frame) {
@@ -204,6 +187,7 @@ void Modbus::receivePDU (byte *frame) {
204
187
}
205
188
206
189
// -------------------------------------------------------------------------------
190
+ // private
207
191
void Modbus::exceptionResponse (byte fcode, byte excode) {
208
192
// Clean frame buffer
209
193
free (_frame);
@@ -215,6 +199,40 @@ void Modbus::exceptionResponse (byte fcode, byte excode) {
215
199
_reply = MB_REPLY_NORMAL;
216
200
}
217
201
202
+ /* Func 06: Write Single Register
203
+ Request
204
+ Function code 1 Byte 0x06
205
+ Register Address 2 Bytes 0x0000 to 0xFFFF
206
+ Register Value 2 Bytes 0x0000 to 0xFFFF
207
+ Response
208
+ Function code 1 Byte 0x06
209
+ Register Address 2 Bytes 0x0000 to 0xFFFF
210
+ Register Value 2 Bytes 0x0000 to 0xFFFF
211
+ */
212
+ // -------------------------------------------------------------------------------
213
+ // private
214
+ void Modbus::writeSingleRegister (word reg, word value) {
215
+
216
+ if (hregOutOfBounds (reg, value)) {
217
+ exceptionResponse (MB_FC_WRITE_REG, MB_EX_ILLEGAL_VALUE);
218
+ return ;
219
+ }
220
+
221
+ // Check Address and execute (reg exists?)
222
+ if (!setHreg (reg, value)) {
223
+ exceptionResponse (MB_FC_WRITE_REG, MB_EX_ILLEGAL_ADDRESS);
224
+ return ;
225
+ }
226
+
227
+ // Check for failure ? Why ???
228
+ /*
229
+ if (hreg (reg) != value) {
230
+ exceptionResponse (MB_FC_WRITE_REG, MB_EX_SLAVE_FAILURE);
231
+ return;
232
+ }
233
+ */
234
+ _reply = MB_REPLY_ECHO; // reply with received frame
235
+ }
218
236
219
237
/*
220
238
Func 03: Read Holding Registers
@@ -228,21 +246,23 @@ void Modbus::exceptionResponse (byte fcode, byte excode) {
228
246
Register value N* x 2 Bytes
229
247
N = Quantity of Registers
230
248
*/
249
+ // -------------------------------------------------------------------------------
250
+ // private
231
251
void Modbus::readRegisters (word startreg, word numregs) {
232
252
// Check value (numregs)
233
253
if (numregs < 1 || numregs > 125 ) {
234
254
exceptionResponse (MB_FC_READ_REGS, MB_EX_ILLEGAL_VALUE);
235
255
return ;
236
256
}
237
257
238
- // Check Address
239
- // *** See comments on readCoils method.
240
- if (!searchRegister (startreg + TRegister::HregOffset)) {
241
- exceptionResponse (MB_FC_READ_REGS, MB_EX_ILLEGAL_ADDRESS);
242
- return ;
258
+ // Check Address (startreg...startreg + numregs - 1)
259
+ for (word k = 0 ; k < numregs; k++) {
260
+ if (!searchRegister (startreg + TRegister::HregOffset + k)) {
261
+ exceptionResponse (MB_FC_WRITE_REGS, MB_EX_ILLEGAL_ADDRESS);
262
+ return ;
263
+ }
243
264
}
244
265
245
-
246
266
// Clean frame buffer
247
267
free (_frame);
248
268
_len = 0 ;
@@ -275,39 +295,6 @@ void Modbus::readRegisters (word startreg, word numregs) {
275
295
_reply = MB_REPLY_NORMAL;
276
296
}
277
297
278
- /* Func 06: Write Single Register
279
- Request
280
- Function code 1 Byte 0x06
281
- Register Address 2 Bytes 0x0000 to 0xFFFF
282
- Register Value 2 Bytes 0x0000 to 0xFFFF
283
- Response
284
- Function code 1 Byte 0x06
285
- Register Address 2 Bytes 0x0000 to 0xFFFF
286
- Register Value 2 Bytes 0x0000 to 0xFFFF
287
- */
288
- void Modbus::writeSingleRegister (word reg, word value) {
289
-
290
- if (hregOutOfBounds (reg, value)) {
291
- exceptionResponse (MB_FC_WRITE_REG, MB_EX_ILLEGAL_VALUE);
292
- return ;
293
- }
294
-
295
- // Check Address and execute (reg exists?)
296
- if (!setHreg (reg, value)) {
297
- exceptionResponse (MB_FC_WRITE_REG, MB_EX_ILLEGAL_ADDRESS);
298
- return ;
299
- }
300
-
301
- // Check for failure ?
302
- /*
303
- if (hreg (reg) != value) {
304
- exceptionResponse (MB_FC_WRITE_REG, MB_EX_SLAVE_FAILURE);
305
- return;
306
- }
307
- */
308
- _reply = MB_REPLY_ECHO; // reply with received frame
309
- }
310
-
311
298
/* Func 16: Write Multiple registers
312
299
Request
313
300
Function code 1 Byte 0x10
@@ -321,14 +308,16 @@ void Modbus::writeSingleRegister (word reg, word value) {
321
308
Starting Address 2 Bytes 0x0000 to 0xFFFF
322
309
Quantity of Registers 2 Bytes 1 to 123 (0x7B)
323
310
*/
311
+ // -------------------------------------------------------------------------------
312
+ // private
324
313
void Modbus::writeMultipleRegisters (byte *frame, word startreg, word numoutputs, byte bytecount) {
325
314
// Check value
326
315
if (numoutputs < 1 || numoutputs > 123 || bytecount != 2 * numoutputs) {
327
316
exceptionResponse (MB_FC_WRITE_REGS, MB_EX_ILLEGAL_VALUE);
328
317
return ;
329
318
}
330
319
331
- // Check Address (startreg...startreg + numregs)
320
+ // Check Address (startreg...startreg + numregs - 1 )
332
321
for (word k = 0 ; k < numoutputs; k++) {
333
322
if (!searchRegister (startreg + TRegister::HregOffset + k)) {
334
323
exceptionResponse (MB_FC_WRITE_REGS, MB_EX_ILLEGAL_ADDRESS);
@@ -380,21 +369,26 @@ void Modbus::writeMultipleRegisters (byte *frame, word startreg, word numoutputs
380
369
Coil Status n Byte n = N or N+1
381
370
N = Quantity of Outputs / 8, if the remainder is different of 0 -> N = N+1
382
371
*/
372
+ // -------------------------------------------------------------------------------
373
+ // private
383
374
void Modbus::readCoils (word startreg, word numregs) {
384
375
// Check value (numregs)
385
376
if (numregs < 1 || numregs > 2000 ) {
386
377
exceptionResponse (MB_FC_READ_COILS, MB_EX_ILLEGAL_VALUE);
387
378
return ;
388
379
}
389
380
390
- // Check Address
391
- // Check only startreg. Is this correct?
392
381
// When I check all registers in range I got errors in ScadaBR
393
382
// I think that ScadaBR request more than one in the single request
394
383
// when you have more then one datapoint configured from same type.
395
- if (!searchRegister (startreg + TRegister::CoilOffset)) {
396
- exceptionResponse (MB_FC_READ_COILS, MB_EX_ILLEGAL_ADDRESS);
397
- return ;
384
+ // epsilonrt -> We absolutely must not return values that do not exist !!
385
+
386
+ // Check Address (startreg...startreg + numregs - 1)
387
+ for (word k = 0 ; k < numregs; k++) {
388
+ if (!searchRegister (startreg + TRegister::CoilOffset + k)) {
389
+ exceptionResponse (MB_FC_WRITE_REGS, MB_EX_ILLEGAL_ADDRESS);
390
+ return ;
391
+ }
398
392
}
399
393
400
394
// Clean frame buffer
@@ -452,18 +446,21 @@ void Modbus::readCoils (word startreg, word numregs) {
452
446
N = Quantity of Inputs / 8 if the remainder is different of 0 N = N+1
453
447
Error
454
448
*/
449
+ // -------------------------------------------------------------------------------
450
+ // private
455
451
void Modbus::readInputStatus (word startreg, word numregs) {
456
452
// Check value (numregs)
457
453
if (numregs < 0x0001 || numregs > 0x07D0 ) {
458
454
exceptionResponse (MB_FC_READ_INPUT_STAT, MB_EX_ILLEGAL_VALUE);
459
455
return ;
460
456
}
461
457
462
- // Check Address
463
- // *** See comments on readCoils method.
464
- if (!searchRegister (startreg + TRegister::IstsOffset)) {
465
- exceptionResponse (MB_FC_READ_COILS, MB_EX_ILLEGAL_ADDRESS);
466
- return ;
458
+ // Check Address (startreg...startreg + numregs - 1)
459
+ for (word k = 0 ; k < numregs; k++) {
460
+ if (!searchRegister (startreg + TRegister::IstsOffset + k)) {
461
+ exceptionResponse (MB_FC_WRITE_REGS, MB_EX_ILLEGAL_ADDRESS);
462
+ return ;
463
+ }
467
464
}
468
465
469
466
// Clean frame buffer
@@ -520,18 +517,21 @@ void Modbus::readInputStatus (word startreg, word numregs) {
520
517
Input Registers N* x 2 Bytes
521
518
N = Quantity of Input Registers
522
519
*/
520
+ // -------------------------------------------------------------------------------
521
+ // private
523
522
void Modbus::readInputRegisters (word startreg, word numregs) {
524
523
// Check value (numregs)
525
524
if (numregs < 0x0001 || numregs > 0x007D ) {
526
525
exceptionResponse (MB_FC_READ_INPUT_REGS, MB_EX_ILLEGAL_VALUE);
527
526
return ;
528
527
}
529
528
530
- // Check Address
531
- // *** See comments on readCoils method.
532
- if (!searchRegister (startreg + TRegister::IregOffset)) {
533
- exceptionResponse (MB_FC_READ_COILS, MB_EX_ILLEGAL_ADDRESS);
534
- return ;
529
+ // Check Address (startreg...startreg + numregs - 1)
530
+ for (word k = 0 ; k < numregs; k++) {
531
+ if (!searchRegister (startreg + TRegister::IregOffset + k)) {
532
+ exceptionResponse (MB_FC_WRITE_REGS, MB_EX_ILLEGAL_ADDRESS);
533
+ return ;
534
+ }
535
535
}
536
536
537
537
// Clean frame buffer
@@ -576,6 +576,8 @@ void Modbus::readInputRegisters (word startreg, word numregs) {
576
576
Output Address 2 Bytes 0x0000 to 0xFFFF
577
577
Output Value 2 Bytes 0x0000 or 0xFF00
578
578
*/
579
+ // -------------------------------------------------------------------------------
580
+ // private
579
581
void Modbus::writeSingleCoil (word reg, word status) {
580
582
// Check value (status)
581
583
if (status != 0xFF00 && status != 0x0000 ) {
@@ -584,16 +586,18 @@ void Modbus::writeSingleCoil (word reg, word status) {
584
586
}
585
587
586
588
// Check Address and execute (reg exists?)
587
- if (!setCoil (reg, ( bool ) status)) {
589
+ if (!setCoil (reg, status != 0 )) {
588
590
exceptionResponse (MB_FC_WRITE_COIL, MB_EX_ILLEGAL_ADDRESS);
589
591
return ;
590
592
}
591
593
592
- // Check for failure
594
+ // Check for failure ?? Why ?
595
+ /*
593
596
if (coil (reg) != (bool) status) {
594
597
exceptionResponse (MB_FC_WRITE_COIL, MB_EX_SLAVE_FAILURE);
595
598
return;
596
599
}
600
+ */
597
601
598
602
_reply = MB_REPLY_ECHO; // reply with received frame
599
603
}
@@ -610,6 +614,8 @@ void Modbus::writeSingleCoil (word reg, word status) {
610
614
Starting Address 2 Bytes 0x0000 to 0xFFFF
611
615
Quantity of Outputs 2 Bytes 0x0001 to 0x07B0
612
616
*/
617
+ // -------------------------------------------------------------------------------
618
+ // private
613
619
void Modbus::writeMultipleCoils (byte *frame, word startreg, word numoutputs, byte bytecount) {
614
620
// Check value
615
621
word bytecount_calc = numoutputs / 8 ;
@@ -673,6 +679,8 @@ void Modbus::writeMultipleCoils (byte *frame, word startreg, word numoutputs, by
673
679
Run Indicator Status 1 Byte 0x00 = OFF, 0xFF = ON
674
680
Additional Data
675
681
*/
682
+ // -------------------------------------------------------------------------------
683
+ // private
676
684
void Modbus::reportServerId () {
677
685
// Clean frame buffer
678
686
free (_frame);
@@ -695,5 +703,22 @@ void Modbus::reportServerId() {
695
703
_reply = MB_REPLY_NORMAL;
696
704
}
697
705
706
+ // -------------------------------------------------------------------------------
707
+ int Modbus::setAdditionalServerData (const char data[]) {
708
+
709
+ free (_additional_data);
710
+ if (data) {
711
+ size_t l = strlen (data) + 1 ;
712
+
713
+ _additional_data = (char *) malloc (l);
714
+ if (_additional_data) {
715
+
716
+ strcpy (_additional_data, data);
717
+ return l;
718
+ }
719
+ }
720
+ return 0 ;
721
+ }
722
+
698
723
// -------------------------------------------------------------------------------
699
724
#endif // USE_HOLDING_REGISTERS_ONLY not defined
0 commit comments