You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Implement FC01/FC02 across Protocol, transports, tests, and docs
- Add ReadCoilStatus (FC01) and ReadInputStatus (FC02) to Protocol NVI API and hooks\n- Implement FC01/FC02 for TCPIPProtocol and RTUProtocol; add DummyProtocol overrides\n- Extend tests with FC01/FC02 coverage for TCP/IP, Dummy, and RTU endpoints\n- Update README, TECHNICAL_DOCS, CLAUDE guidance, and regenerate Doxygen HTML output
└── DummyProtocol — No-op stub for tests (ModbusDummy.h)
74
74
```
75
75
76
-
**`Modbus::Master::Protocol`** is the abstract base. Subclasses implement protected `Do*()` virtual hooks for transport I/O and connection management. Public methods (FC03, FC04, FC06, FC16, FC22) are implemented in the base class on top of those hooks.
76
+
**`Modbus::Master::Protocol`** is the abstract base. Subclasses implement protected `Do*()` virtual hooks for transport I/O and connection management. Public methods (FC01, FC02, FC03, FC04, FC06, FC16, FC22) are implemented in the base class on top of those hooks.
77
77
78
78
**`Modbus::Master::SessionManager`** is an RAII guard: calls `Open()` on construction, `Close()` on destruction.
`Test/ModbusTest.cpp` uses **Boost.Test 1.89** (`boost/test/included/unit_test.hpp`). A `ServerFixture` global fixture starts an embedded Modbus slave on `127.0.0.1:5020` in a `std::thread` before tests run and stops it after. Tests cover FC03, FC04, FC06, FC16, FC22, and exception handling.
92
+
`Test/ModbusTest.cpp` uses **Boost.Test 1.89** (`boost/test/included/unit_test.hpp`). A `ServerFixture` global fixture starts an embedded Modbus slave on `127.0.0.1:5020` in a `std::thread` before tests run and stops it after. Tests cover FC01, FC02, FC03, FC04, FC06, FC16, FC22, and exception handling across TCP/IP, Dummy, and RTU endpoints.
93
93
94
94
CMake test build details and known pitfalls (SysInit.o linking, PCH2 force-include) are documented in [Test/README-cmake.md](Test/README-cmake.md) and [TECHNICAL_DOCS.md](TECHNICAL_DOCS.md).
95
95
@@ -100,23 +100,23 @@ CMake test build details and known pitfalls (SysInit.o linking, PCH2 force-inclu
This project implements the NVI pattern throughout the protocol hierarchy to enforce consistent API contracts across all transports:
106
-
107
-
-**Public methods** (Open, Close, ReadHoldingRegisters, PresetMultipleRegisters, etc.) are non-virtual concrete functions in the base class.
108
-
-**Virtual hooks** follow the "`Do`" prefix naming convention: DoOpen, DoClose, DoReadHoldingRegisters, DoPresetMultipleRegisters, etc.
109
-
-**Hook placement:** Virtual hooks are declared in the `protected` section of abstract base classes.
110
-
-**Subclass responsibility:** Concrete transport subclasses (RTUProtocol, TCPProtocolIndy, TCPProtocolWinSock, etc.) implement ONLY the Do…() virtual hooks; they do NOT override public methods.
111
-
-**Benefit:** This enforces contract validation, logging, and error handling at the base class level, ensuring consistency across RTU, TCP, UDP, and Dummy transports.
112
-
113
-
Example: To add a new transport (e.g., SerialProtocolCustom extending RTUProtocol), override only the Do…() methods—never override the public API.
114
-
115
-
**Namespaces:**
116
-
117
-
-`Modbus::` — types, exceptions, `Context`
118
-
-`Modbus::Master::` — `Protocol`, `SessionManager`, all transport classes
119
-
-`Modbus::Utils::` — serial enumeration (`SerEnum.h`)
103
+
**Non-Virtual Interface (NVI) Pattern:**
104
+
105
+
This project implements the NVI pattern throughout the protocol hierarchy to enforce consistent API contracts across all transports:
106
+
107
+
-**Public methods** (Open, Close, ReadHoldingRegisters, PresetMultipleRegisters, etc.) are non-virtual concrete functions in the base class.
108
+
-**Virtual hooks** follow the "`Do`" prefix naming convention: DoOpen, DoClose, DoReadHoldingRegisters, DoPresetMultipleRegisters, etc.
109
+
-**Hook placement:** Virtual hooks are declared in the `protected` section of abstract base classes.
110
+
-**Subclass responsibility:** Concrete transport subclasses (RTUProtocol, TCPProtocolIndy, TCPProtocolWinSock, etc.) implement ONLY the Do…() virtual hooks; they do NOT override public methods.
111
+
-**Benefit:** This enforces contract validation, logging, and error handling at the base class level, ensuring consistency across RTU, TCP, UDP, and Dummy transports.
112
+
113
+
Example: To add a new transport (e.g., SerialProtocolCustom extending RTUProtocol), override only the Do…() methods—never override the public API.
114
+
115
+
**Namespaces:**
116
+
117
+
-`Modbus::` — types, exceptions, `Context`
118
+
-`Modbus::Master::` — `Protocol`, `SessionManager`, all transport classes
119
+
-`Modbus::Utils::` — serial enumeration (`SerEnum.h`)
120
120
121
121
**Compiler compatibility:**`[[noreturn]]` attribute placement differs between BCC32 and BCC32C/BCC64 — see existing exception class declarations for the guarded pattern.
0 commit comments