IEC 60870-5-104: Why the Link Connects but No Values Show Up
TCP to port 2404 is up, the RTU is reachable, every point still stale. It is almost always STARTDT and the general interrogation nobody sent.
The socket is open and the data is dead
A substation gateway had a clean TCP session to the RTU — port 2404, ESTABLISHED, no retransmits in the packet capture. The SCADA still showed every breaker, every analog, as stale. The commissioning engineer had spent an hour checking the firewall and the IP plan. Both were fine. The link was up in the sense that TCP was up, and up in no other sense.
IEC 60870-5-104 has a startup sequence that Modbus and DNP3 don't force on you the same way. A raw TCP connection carries nothing until the controlling station explicitly turns on data flow and then asks for a snapshot. Skip either step and you get exactly this: a socket that looks perfect and a database full of nothing.
STARTDT is the on switch
The 104 protocol wraps everything in an APDU that starts with 0x68, a length byte, and four control-field octets. Those four octets decide the frame type. There are three:
- I-format — information transfer. Carries an ASDU (the actual data). Numbered with a send and receive sequence count.
- S-format — supervisory. Pure acknowledgement, no payload. It's how the receiver says "I've got up to sequence N" without having data of its own to send.
- U-format — unnumbered control. This is STARTDT, STOPDT, and TESTFR.
After the TCP handshake, the controlled station (the RTU) sends nothing on its own. It waits. The controlling station has to send STARTDT act — a U-format frame — and the RTU answers STARTDT con. Only after that confirmation is the RTU allowed to push monitor-direction data. Before it, an I-format frame from the RTU is a protocol violation, so a correct RTU simply stays silent.
That silence is the trap. Nothing errors. The capture shows the SYN/SYN-ACK, then dead air. If you see a TCP session with no 0x68 ... 07 00 00 00 (STARTDT act) going out from the master, that's your bug: the master never armed the link. Some gateways send STARTDT only after a configuration flag is set, or only once and never again after a socket drop. If the RTU reset the socket and the master reconnected TCP but didn't re-send STARTDT, you're back to a live socket with no data.
Then you have to ask for a snapshot
STARTDT lets spontaneous changes through — a breaker trips, the RTU sends it with cause of transmission 3 (spontaneous). But nothing has changed yet at commissioning time, so nothing spontaneous arrives, and your database is still empty of current values.
You get the current state by sending a general interrogation: an ASDU of type 100, C_IC_NA_1, with cause of transmission 6 (activation) and a qualifier of interrogation (QOI) of 20 for a station-wide request. The RTU answers in a specific order that's worth memorizing, because you can read the whole exchange in a capture:
- COT 7 — activation confirmation. "I heard your GI and I'm starting."
- A burst of I-format ASDUs carrying every point, each with COT 20 (interrogated by station, sometimes written "inrogen"). This is the snapshot.
- COT 10 — activation termination. "That's all of them."
If you send the GI and get COT 7 but no COT 20 values, the RTU has an empty or misaddressed point list. If you get no COT 7 at all, the GI never landed — check the ASDU common address (below). Many masters fire the GI automatically right after STARTDT con; some don't, and some only re-fire it on a cold reconnect, not a warm one. When a link "comes back but the values don't," a missing GI after reconnect is the usual reason. Force one manually and watch for the COT 7 / COT 20 / COT 10 triplet.
The cause of transmission tells you what went wrong
The COT octet is the single most useful field for troubleshooting 104, and people ignore it. A few worth knowing by number:
- 1 cyclic, 3 spontaneous, 5 requested — normal traffic.
- 6 activation, 7 act-confirm, 10 act-termination — the command/interrogation lifecycle.
- 44 unknown type identification, 45 unknown cause of transmission, 46 unknown common address of ASDU, 47 unknown information object address.
Those last four are gold. If you send a command and the RTU bounces it back with COT 46, your ASDU common address is wrong — the master and RTU disagree on the station number. COT 47 means the common address matched but the information object address (IOA) didn't; your point map is off by an offset, or you swapped the IOA byte order. There's also a P/N bit (bit 7 of the COT octet): set means negative confirmation — the RTU understood you and refused. A negative COT 7 on a select or a GI is the RTU telling you the request was structurally valid but not accepted, which is a different problem than a mismatch and points you at authority, mode, or a busy resource rather than addressing.
Addressing is where most 104 commissioning time actually goes. The common address of ASDU is usually two octets, the IOA usually three, and both are configurable widths. A gateway defaulted to a two-octet IOA talking to an RTU using three will parse every object at the wrong offset, and you'll see plausible-looking but wrong values, or a flood of COT 47. Confirm the octet widths on both ends before you argue about the point list.
Don't let the keepalive timers surprise you
104 has four timeouts, and the defaults matter because a mistuned one drops links that are actually fine:
- t1 = 15 s — how long the sender waits for an acknowledgement of an I- or U-frame before it declares the link dead and closes the TCP socket.
- t2 = 10 s — how long the receiver waits before sending an S-frame ack when it has data to acknowledge but nothing of its own to send. t2 must be shorter than t1, or you'll time out waiting for an ack the peer hasn't decided to send yet.
- t3 = 20 s — idle time before the station sends a TESTFR act to prove the link is still alive. The peer answers TESTFR con.
- k = 12, w = 8 — the send/receive window. k is the maximum number of I-frames you can have outstanding (unacknowledged) before you must stop and wait; w is the count of received I-frames after which the receiver must send an ack. Keep w around two-thirds of k. Set w too high relative to k and the sender hits the k limit and stalls waiting for an ack the receiver isn't obligated to send yet — a self-inflicted deadlock that looks like a slow link.
The classic field mistake is setting t1 shorter than the round-trip over a slow radio or cellular backhaul. The link works, then under load an ack arrives at 16 s, t1 fires at 15 s, and the master tears down a perfectly good socket and reconnects — dropping data every time the path gets busy. On anything but a clean LAN, measure the actual RTT before you trust the default t1.
If you remember one thing: a 104 socket being open tells you almost nothing. STARTDT con, a COT 7 / 20 / 10 general interrogation, and matching common-address and IOA widths tell you the link is real. Check those four before you touch the firewall again.