← Articles
SECS/GEM/8 min read/— views

An S2F0 Doesn't Tell You Why: Unimplemented Function or Closed Communication Gate

Two captures from one HSMS session show S2F23 aborted twice for different reasons, and the reply bytes differ only in SystemBytes.

SECS/GEMMESSCADATroubleshootingChecklists

I was wiring trace collection into a host driver and sent S2F23 (Trace Initialize Send). What came back was not S2F24 but S2F0 — ten bytes, no body. The problem is that an earlier S2F23 on the same socket, fired by mistake before S1F13, came back identical except for SystemBytes. Did the tool never implement the function, or is E30 communication simply not open yet? Nothing in the reply tells you.

Sorting an S2F0 returned for S2F23 by one test — whether the COMMACK 0 in S1F14 already arrived on this session — which separates the E30 communication gate from an unimplemented function S2F23 → S2F0 no body, no status code COMMACK 0 in S1F14 received? no E30 communication gate S1F13 first yes Function not implemented no Trace Data Collection

Every frame below came out of one session against the passive listener of the SECS/GEM simulator at 127.0.0.1:5501, driven by a Python socket client. The raw export sits in content/demos/s2f23-trace-capability-probe-sxf0.json.

Select first, then a session with nothing open

TX Select.req   00 00 00 0A FF FF 00 00 00 01 00 00 00 01
RX Select.rsp   00 00 00 0A 00 0B 00 00 00 02 00 00 00 01

SType 1, then SType 2, with Select Status 00 in byte 3. Per E37 I used SessionID FF FF on the control message, and the Select.rsp came back with 00 0B — 11. That gap is its own problem, covered in an HSMS reply's session ID is not always the one you sent. All that matters here is that HSMS is SELECTED.

The same S2F23, twice

The E5 body for S2F23 is L[5]{ TRID, DSPER, TOTSMP, REPGSZ, L[n]{SVID} }. I sent TRID 1, DSPER as the ASCII string "000100", TOTSMP 60, REPGSZ 1, and two SVIDs.

TX S2F23 W   00 00 00 34 00 01 82 17 00 00 00 00 00 02
             01 05 B1 04 00 00 00 01 41 06 30 30 30 31 30 30
             B1 04 00 00 00 3C B1 04 00 00 00 01
             01 02 B1 04 00 00 00 65 B1 04 00 00 00 66
RX reply     00 00 00 0A 00 01 02 00 00 00 00 00 00 02
BytesFieldValue
00 00 00 0ALength10 — header only, no body
00 01SessionID1 — echoed from the request
02Header byte 2W-bit 0, Stream 2
00Header byte 3Function 0
00 00PType, SType0, 0 — a data message
00 00 00 02SystemBytes2 — echoed from the request

At that moment the equipment sat in NOT COMMUNICATING in E30's communication state model, so this S2F0 is the gate. The mechanism is traced byte by byte in your HSMS session is SELECTED and S1F3 still comes back as S1F0.

Now open the gate on the same socket.

TX S1F13 W   00 00 00 0C 00 01 81 0D 00 00 00 00 00 03  01 00
RX S1F14     00 00 00 37 00 01 01 0E 00 00 00 00 00 03
             01 02 21 01 00
             01 02 41 15 56 58 2D 39 30 30 30 20 50 6C 61 73 6D 61 20 45 74 63 68 65 72
             41 0D 53 45 43 53 47 45 4D 2D 31 2E 34 2E 31

The body is L[2]{ B 0, L[2]{A "VX-9000 Plasma Etcher", A "SECSGEM-1.4.1"} }. The leading 21 01 00 is COMMACK 0 — accepted. The session is COMMUNICATING.

Then I sent the exact same S2F23 bytes again, with SystemBytes stepped from 2 to 4.

TX S2F23 W   00 00 00 34 00 01 82 17 00 00 00 00 00 04
             01 05 B1 04 00 00 00 01 41 06 30 30 30 31 30 30
             B1 04 00 00 00 3C B1 04 00 00 00 01
             01 02 B1 04 00 00 00 65 B1 04 00 00 00 66
RX reply     00 00 00 0A 00 01 02 00 00 00 00 00 00 04

S2F0 again. Side by side:

00 00 00 0A 00 01 02 00 00 00 00 00 00 02   ← because the gate was shut
00 00 00 0A 00 01 02 00 00 00 00 00 00 04   ← because the function is absent

Thirteen of fourteen bytes match. The one that differs is SystemBytes, which is a value I chose. Of everything the equipment contributed, nothing separates the two causes.

Proving the link is open in the same session is what makes the second reading safe. S2F33, which this tool does implement, answers on the same socket:

TX S2F33 W   00 00 00 14 00 01 82 21 00 00 00 00 00 05  01 02 B1 04 00 00 00 00 01 00
RX S2F34     00 00 00 0D 00 01 02 22 00 00 00 00 00 05  21 01 00

Header byte 3 is 22, Function 34. The body 21 01 00 is Binary 0, DRACK 0 — accepted. Same session, same SessionID, same state: one function answers and one aborts. So the second S2F0 is not a session problem. That function does not exist on this tool.

S2F0 has no room for a reason

In SEMI E5, SxF0 is abort transaction. It reuses the stream the request used, sets the function to 0, clears the W-bit and leaves the body empty. With no fields there is no status code and no ERRCODE — none of the "why" that HCACK carries in S2F42 or DRACK in S2F34.

E5 also defines S9F5 (Unrecognized Function Type) as a way to answer a function the equipment does not have. Which one a tool sends is an implementation choice, and building a host that counts on getting S9 at all is a bad bet — see why your host can't count on an S9 error message. The equipment in the capture above sent S2F0, not S9F5. What any other tool does, I have not verified.

Trace Data Collection is optional in GEM

Picking S2F23 for this was not arbitrary. SEMI E30 does not place trace data collection among the capabilities every compliant tool must have; it is an additional capability. S2F23/S2F24 arm the trace and S6F1/S6F2 carry the samples. So "it's a GEM tool, therefore it has trace" can be wrong, and those ten bytes are how the tool tells you.

When the MES requirement arrives as "temperature trend at one-second resolution", trace is the tempting path. I would rather fire one S2F23 before that goes into a design. If it is missing, the fallback is S6F11 on a short period, and what that costs is in your GEM link is green and MES still can't rebuild the run. Either way the choice comes after you know what the tool implements.

What to put in the host driver

  • Probe optional capabilities once at startup and cache the answer. Right after S1F13/S1F14 closes with COMMACK 0, send one primary per optional capability you plan to use. An SxF0 means record "unsupported" and stop sending it. This is not a retry case.
  • Probe after the gate opens. Every probe sent before S1F14 comes back as SxF0, which reads as "nothing is supported". Get the order wrong and you will believe that result.
  • Keep a control in the same probe batch. Include one primary E30 requires of every tool — S1F3 or S2F13 — alongside the probes. If it answers while only the probes abort, the problem is capability. If it aborts too, the problem is the session.
  • Log the request's ten header bytes next to the abort. All an S2F0 carries is SystemBytes. Which request died is something only the host's own records can reconstruct.
  • Do not fold "SxF0" and "non-zero ACK code" into one error class. The first says the function is not on this tool. The second says it is, and was refused. The responses have nothing in common.

To reproduce this exchange without equipment, point a socket client at the passive listener in the SECS/GEM simulator. Sending the same primary once before S1F13 and once after is enough to get both S2F0 replies.