An Accepted Select and a Refused One Differ by a Single Byte
Real Select.rsp captures — accepted, refused with SEMI E37 Select Status 1/2/3, and answered under a different SessionID — and where 'select failed' loses the detail.
"Select failed." That's usually the whole line your host stack leaves behind. Whether the equipment refused you, answered something strange, or never answered at all is not in it — even though the answer had already arrived. It's sitting in the reply frame.
A Select.rsp is fourteen bytes. The three below are all responses to the same request, and each differs from the others in exactly one field.
Accepted
TX Select.req 00 00 00 0A 00 0B 00 00 00 01 00 00 04 01
RX Select.rsp 00 00 00 0A 00 0B 00 00 00 02 00 00 04 01
Sent with SessionID 00 0B (11), came back 00 0B. SystemBytes 00 00 04 01 returned unchanged. The SType went from 01 (Select.req) to 02 (Select.rsp). And Byte 3 of the header — the fourth one, since E37 numbers them from zero — is 00.
Byte 3 is the Select Status. The slot a data message uses for its Function number is reused for this on control messages. Zero means accepted.
Refused
TX Select.req 00 00 00 0A 00 0B 00 00 00 01 00 00 04 04
RX Select.rsp 00 00 00 0A 00 0B 00 03 00 02 00 00 04 04
Same length. Same SessionID. SystemBytes echoed correctly. SType is 02 — a perfectly well-formed Select.rsp. One thing differs: Byte 3 is 03 instead of 00.
The equipment answered you properly. The content of the answer was "no". Not a timeout, not a network fault. But on a host stack that doesn't log the Select Status, this is indistinguishable from silence.
What the number means
SEMI E37 names the low Select Status values. The table is cited from the standard, not measured — the captures below prove only that the byte carries whatever the equipment puts there:
| Select Status | SEMI E37 meaning |
|---|---|
| 0 | Communication Established — accepted |
| 1 | Communication Already Active |
| 2 | Connection Not Ready |
| 3 | Connect Exhaust |
| 4 and above | Reserved by E37 and its subsidiary standards; in practice vendor territory — go to the manual |
Status 1 is the one that catches host developers. It doesn't mean the equipment is broken; it means somebody already holds the session and you are the second Select on the wire.
Three refusals from the same listener, one per code, over a real socket:
TX Select.req 00 00 00 0A 00 0B 00 00 00 01 00 00 04 02
RX Select.rsp 00 00 00 0A 00 0B 00 01 00 02 00 00 04 02 Select Status 1
TX Select.req 00 00 00 0A 00 0B 00 00 00 01 00 00 04 03
RX Select.rsp 00 00 00 0A 00 0B 00 02 00 02 00 00 04 03 Select Status 2
TX Select.req 00 00 00 0A 00 0B 00 00 00 01 00 00 04 04
RX Select.rsp 00 00 00 0A 00 0B 00 03 00 02 00 00 04 04 Select Status 3
Only Byte 3 moves. Length, SessionID, Header Byte 2, PType, SType and the echoed SystemBytes are byte-identical across all three. That is the whole problem with a log line that says "select failed" — it discards the only field that changed.
Which code a given tool sends in which circumstance is still a vendor-manual question. The simulator above doesn't choose; it echoes the status you set on it.
Something the equipment side records and the host cannot see: after each refusal the listener's HSMS state stayed NOT CONNECTED, while the accepted exchange moved it to SELECTED. The TCP socket was open in every one of those cases. An open socket is not a session.
In practice this single value ends meetings. "Select doesn't work" and "we're being refused with Select Status 3" are entirely different tickets from the vendor's side.
Answered under a different SessionID
TX Select.req 00 00 00 0A 00 0B 00 00 00 01 00 00 04 05
RX Select.rsp 00 00 00 0A 00 0C 00 00 00 02 00 00 04 05
Select Status is 00 — accepted. SystemBytes echoed exactly as 00 00 04 05. But the SessionID went out as 00 0B (11) and came back 00 0C (12).
What happens next depends on your host implementation. A stack that matches transactions on SystemBytes alone will accept this and consider the session open — then run data messages with a SessionID the equipment disagrees with. A stack that validates the SessionID will discard it and time out instead. Either way the symptom surfaces later, at the data stage rather than at Select.
If you don't know which kind of stack you have, connecting it to a simulator is the fast way to find out. Reproduction steps are below.
Three places to look
When you've captured a Select.rsp, check in this order:
- SType — is it
02? If not, it isn't a Select.rsp. - Byte 3, the Select Status —
00is accepted; anything else is a refusal and that number is the reason. E37 names 1, 2 and 3; see the table above. - SessionID and SystemBytes — do they match what you sent? If not, a reply arrived but it wasn't yours.
All three agree and the session is SELECTED. Any one of them off, and that field is the name of your symptom.
Reproducing it
All three captures came from the SECS/GEM simulator. Set the equipment's selectRefuse fault for the second and wrongSessionId for the third. Point your own host stack at each and read what lands in your log — you'll know immediately whether it's the kind of implementation that reports Select Status.
If nothing comes back at all, see three failures that look identical to the host; if the SystemBytes are what's off, that case has its own walkthrough.