@@ -22,6 +22,9 @@ dotnet run --project src/ZB.MOM.WW.OtOpcUa.Driver.S7.Cli -- --help
|
||||
| `--rack` | `0` | Hardware rack (S7-400 distributed setups only) |
|
||||
| `--slot` | `0` | CPU slot (S7-300 = 2, S7-400 = 2 or 3, S7-1200/1500 = 0) |
|
||||
| `--timeout-ms` | `5000` | Per-operation timeout |
|
||||
| `--tsap-mode` | `Auto` | ISO-on-TCP connection class: `Auto` / `Pg` / `Op` / `S7Basic` / `Other`. Hardened S7-1500 / ET 200SP CPUs may require `Op` or `S7Basic`. See [s7.md TSAP / Connection Type](v2/s7.md#tsap--connection-type). |
|
||||
| `--local-tsap` | (unset) | Optional 16-bit local TSAP override (e.g. `0x0200`). Required when `--tsap-mode Other`; wins over class default under Pg/Op/S7Basic. |
|
||||
| `--remote-tsap` | (unset) | Optional 16-bit remote TSAP override. Required when `--tsap-mode Other`; wins over class default under Pg/Op/S7Basic. |
|
||||
| `--verbose` | off | Serilog debug output |
|
||||
|
||||
## PUT/GET must be enabled
|
||||
@@ -83,6 +86,26 @@ otopcua-s7-cli write -h 192.168.1.30 -a M0.0 -t Bool -v true
|
||||
**Writes to M / Q are real** — they drive the PLC program. Be careful what you
|
||||
flip on a running machine.
|
||||
|
||||
### Hardened CPU — forcing OP-class TSAP
|
||||
|
||||
```powershell
|
||||
# Probe a hardened S7-1500 that rejects PG class but accepts OP.
|
||||
otopcua-s7-cli probe -h 10.50.12.30 --tsap-mode Op
|
||||
|
||||
# Read against the same CPU.
|
||||
otopcua-s7-cli read -h 10.50.12.30 --tsap-mode Op -a DB1.DBW0 -t Int16
|
||||
|
||||
# Manual TSAP override (e.g. site with a fixed proprietary TSAP gateway).
|
||||
otopcua-s7-cli probe -h 10.50.12.30 --tsap-mode Other --local-tsap 0x4D57 --remote-tsap 0x4D58
|
||||
```
|
||||
|
||||
Without `--tsap-mode`, the CLI uses S7netplus's CpuType-derived default (PG
|
||||
class for almost everything). The same connection-refused failure shape that a
|
||||
wrong `--slot` produces also shows up when the CPU rejects PG class — try
|
||||
`--tsap-mode Op` first when the handshake is failing on otherwise-correct
|
||||
endpoint config. See [s7.md TSAP / Connection Type](v2/s7.md#tsap--connection-type)
|
||||
for the byte table and motivation.
|
||||
|
||||
### `subscribe`
|
||||
|
||||
```powershell
|
||||
|
||||
@@ -573,6 +573,86 @@ S7 driver health without reaching for a Wireshark capture:
|
||||
The values render alongside Modbus / OPC UA Client metrics in the Admin
|
||||
UI driver-diagnostics panel — same RPC, same dashboard row layout.
|
||||
|
||||
## TSAP / Connection Type
|
||||
|
||||
S7comm runs on top of ISO-on-TCP (RFC 1006), and the COTP connection-request
|
||||
PDU carries a 16-bit **TSAP pair** (local + remote) that the CPU validates
|
||||
before any S7comm payload flows. S7netplus's default `Plc(CpuType, host, port,
|
||||
rack, slot)` constructor picks a **PG-class** TSAP pair via
|
||||
`TsapPair.GetDefaultTsapPair`. That choice works against most lab S7-1200 /
|
||||
S7-1500 CPUs and against TIA Portal itself, but **hardened deployments**
|
||||
(security-config'd S7-1500, ET 200SP, locked-down PROFINET projects) reject
|
||||
PG class outright at COTP-handshake time, returning the same connection-refused
|
||||
shape as a wrong slot byte.
|
||||
|
||||
PR-S7-C2 surfaces a `TsapMode` enum on `S7DriverOptions` so an operator can
|
||||
force a specific class without re-flashing the PLC project. It applies equally
|
||||
to the Admin-UI-driven config DB row and to the `otopcua-s7-cli` test client.
|
||||
|
||||
### Raw-TSAP byte table
|
||||
|
||||
The high byte is the connection class. The local low byte is conventionally
|
||||
`0x00` (caller / unprivileged), and the remote low byte is
|
||||
`(rack << 5) | slot` per the S7 spec — the same convention S7netplus's
|
||||
`TsapPair.GetDefaultTsapPair(CpuType, rack, slot)` uses for the remote endpoint.
|
||||
|
||||
| Class | High byte | Local TSAP (rack=0/slot=0) | Remote TSAP (rack=0/slot=0) | Remote TSAP (rack=0/slot=2) | Typical use |
|
||||
|----------|-----------|----------------------------|------------------------------|------------------------------|----------------------------------------------|
|
||||
| PG | `0x01` | `0x0100` | `0x0100` | `0x0102` | TIA Portal, dev laptops, lab S7-1200/1500 |
|
||||
| OP | `0x02` | `0x0200` | `0x0200` | `0x0202` | Operator panels, hardened-CPU S7-1500 |
|
||||
| S7-Basic | `0x03` | `0x0300` | `0x0300` | `0x0302` | WinCC BasicPanel SDK, S7-Basic clients |
|
||||
| Other | caller | caller-supplied | caller-supplied | caller-supplied | escape hatch — unusual fixed-TSAP firmware |
|
||||
|
||||
### `TsapMode` enum
|
||||
|
||||
| Mode | Behaviour |
|
||||
|-----------|----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `Auto` | Existing behaviour — S7netplus picks the TSAP pair from `CpuType`. Explicit `LocalTsap` / `RemoteTsap` are ignored under `Auto`. |
|
||||
| `Pg` | Force PG class (high byte `0x01`). Local / remote computed from rack + slot. |
|
||||
| `Op` | Force OP class (high byte `0x02`). |
|
||||
| `S7Basic` | Force S7-Basic class (high byte `0x03`). |
|
||||
| `Other` | Caller-supplied `LocalTsap` + `RemoteTsap`. Both must be set or driver init throws `InvalidOperationException`. |
|
||||
|
||||
Explicit `LocalTsap` / `RemoteTsap` overrides win over the class-derived
|
||||
defaults under any non-`Auto` mode — a site that needs a fixed source-TSAP for
|
||||
firewall reasons can pin `LocalTsap` while keeping `TsapMode = Pg` for the
|
||||
remote computation.
|
||||
|
||||
### Worked example: hardened S7-1500 requiring OP class
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"Host": "10.50.12.30",
|
||||
"CpuType": "S71500",
|
||||
"Rack": 0,
|
||||
"Slot": 0,
|
||||
"TsapMode": "Op",
|
||||
"Tags": [ /* … */ ]
|
||||
}
|
||||
```
|
||||
|
||||
This produces local = `0x0200`, remote = `0x0200` (rack=0, slot=0). The same
|
||||
PLC under `TsapMode = "Auto"` (PG class) returns COTP rejection — same packet
|
||||
capture shape as a wrong-slot misconfig, which is the failure-mode footnote
|
||||
under §5 of `driver-specs.md`.
|
||||
|
||||
### Why not just expose `LocalTsap` / `RemoteTsap` directly?
|
||||
|
||||
Most operators don't know the byte format off-hand and reach for `Pg` /
|
||||
`Op` / `S7Basic` based on Siemens-doc terminology. Keeping the enum lets the
|
||||
Admin UI render a dropdown with sensible labels, while the `ushort?` fields
|
||||
stay available as the manual escape hatch when a site has truly unusual
|
||||
firmware (e.g. third-party S7-protocol gateways with fixed proprietary
|
||||
TSAPs). Both paths are exercised in the unit-test mapping table.
|
||||
|
||||
### Live-firmware verification
|
||||
|
||||
The PG/OP/S7-Basic byte table above is the documented Siemens convention; the
|
||||
actual handshake is verified against the dev-box S7-1500 lab rig (a hardened
|
||||
project that rejects PG and accepts OP). That test is documented in
|
||||
`tests/ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests` but only runs against
|
||||
real firmware — the pymodbus-style "TSAP simulator" doesn't exist for S7.
|
||||
|
||||
## References
|
||||
|
||||
1. Siemens Industry Online Support, *Modbus/TCP Communication between SIMATIC S7-1500 / S7-1200 and Modbus/TCP Controllers with Instructions `MB_CLIENT` and `MB_SERVER`*, Entry ID 102020340, V6 (Feb 2021). https://cache.industry.siemens.com/dl/files/340/102020340/att_118119/v6/net_modbus_tcp_s7-1500_s7-1200_en.pdf
|
||||
|
||||
Reference in New Issue
Block a user