← Articles
SECS/GEM/13 min read/ views

Why Your S6F11 Never Arrives: Getting S2F33, S2F35 and S2F37 in the Right Order

Your report is defined but S6F11 never arrives. Real S2F33, S2F35 and S2F37 captures from two equipments, and what a non-zero LRACK tells the host.

SECS/GEMMESSCADATroubleshootingChecklists

The MES side is written. You define a report, attach it to a CEID, send the enable. All three messages came back answered and all three answers ended in 00. And not one S6F11 has arrived. There is no equipment to plug into — only a simulator.

The mistake host developers make most often here is treating those three messages as independent. They are not. S2F35 refers to an RPTID that must already be defined, and S2F37 refers to a CEID that should already be linked. Reverse the order and you are sending a message whose referent does not exist — and what comes back then, which is the whole point, depends on the equipment implementation.

So I pushed the same frames in the same order at two equipments. One answers 00 to anything you send it. The other rejects with LRACK 5. Same host code, same bytes, different answers.

The host links undefined RPTID 700 with S2F35 and gets LRACK 5, then defines it with S2F33, links it again, enables it, and receives S6F11 HostEquipment S2F35 — CEID 10001, RPTID 700 S2F36 — LRACK 5 S2F33 — RPTID 700 = VID 1, 2 S2F34 — DRACK 0 S2F35 — CEID 10001, RPTID 700 S2F36 — LRACK 0 S2F37 — CEED TRUE, CEID 10001 S2F38 — ERACK 0 S6F11 — RPTID 700 S6F12 undefinedRPTID

The three messages are chained by reference

What define, link and enable each do, and why the whole setup evaporates after a tool restart, is already covered in the article on event report links. That one shows the bytes the host sends and stops there without answers — the listener it ran against had no SECS-II responder. This article is the answer side: what actually rides in DRACK, LRACK and ERACK.

The reference chain, restated:

  • S2F33 binds a VID list to one RPTID. The equipment has to own those VIDs.
  • S2F35 binds an RPTID list to one CEID. Those RPTIDs must already exist from S2F33.
  • S2F37 carries CEED (TRUE/FALSE) and a CEID list. No RPTID appears in it at all.

That third item is the trap. S2F37 knows nothing about reports. It switches CEIDs on and off. So there is no ground for the equipment to reject an enable on a CEID with no link, and it does not reject it. The host gets ERACK 0, believes the setup is complete, and the equipment has no report to attach and sends nothing. Half of "I got ERACK 0 and no S6F11" is exactly this.

The permissive equipment: wrong order, all zeros

First the SECS/GEM simulator's EQ1 passive listener (127.0.0.1:5501, SessionID 11, no fault modes). Select and S1F13 get the session to COMMUNICATING — SELECTED is not COMMUNICATING — and then I deliberately inverted the order: link RPTID 700, never defined, to CEID 1101.

TX S2F35 W   00 00 00 24 00 0B 82 23 00 00 00 00 04 03
             01 02 B1 04 00 00 00 01
                   01 01 01 02 B1 04 00 00 04 4D 01 01 B1 04 00 00 02 BC
RX S2F36     00 00 00 0D 00 0B 02 24 00 00 00 00 04 03  21 01 00

The body is <L [2] <U4 1> <L [1] <L [2] <U4 1101> <L [1] <U4 700>>>>>. 00 00 04 4D is CEID 1101, 00 00 02 BC is RPTID 700. RPTID 700 was never defined in this session.

The answer is 21 01 00 — a one-byte binary item, value 0. LRACK 0, accepted. The enable goes through too.

TX S2F37 W   00 00 00 17 00 0B 82 25 00 00 00 00 04 04  01 02 25 01 01 01 01 B1 04 00 00 04 4D
RX S2F38     00 00 00 0D 00 0B 02 26 00 00 00 00 04 04  21 01 00

25 01 01 is CEED TRUE. ERACK 0. And sending the identical S2F33 twice in a row gets DRACK 0 both times.

TX S2F33 W   00 00 00 2A 00 0B 82 21 00 00 00 00 04 06
             01 02 B1 04 00 00 00 01
                   01 01 01 02 B1 04 00 00 02 BC 01 02 B1 04 00 00 00 64 B1 04 00 00 00 65
RX S2F34     00 00 00 0D 00 0B 02 22 00 00 00 00 04 06  21 01 00

This listener returns 21 01 00 to S2F33, S2F35 and S2F37 unconditionally. It is not imitating an equipment, it is satisfying the ack shape — which makes it the worst possible partner for a host developer. Run your integration tests only here and the whole class of ordering bugs stays invisible until the first real tool.

The strict equipment: LRACK 5, DRACK 3, LRACK 4

The second partner is the secs-gem-equipment 0.1.0 package from the same repository, running as a listener on 127.0.0.1:5599 with SessionID 0. It owns two CEIDs, 10001 (START) and 10002 (STOP), and three VIDs: 1 (CONTROL_STATE), 2 (PROCESS_STATE), 3 (PROCESS_EVENT). Same inverted order first.

TX S2F35 W   00 00 00 24 00 00 82 23 00 00 00 00 04 03
             01 02 B1 04 00 00 00 01
                   01 01 01 02 B1 04 00 00 27 11 01 01 B1 04 00 00 02 BC
RX S2F36     00 00 00 0D 00 00 02 24 00 00 00 00 04 03  21 01 05

00 00 27 11 is CEID 10001 and 00 00 02 BC is RPTID 700 again. The answer is 21 01 05LRACK 5, which in this implementation means at least one RPTID in the link is not defined. Same host frame as before, different answer.

Then the line that matters most here. Enable the CEID whose link just failed:

TX S2F37 W   00 00 00 17 00 00 82 25 00 00 00 00 04 04  01 02 25 01 01 01 01 B1 04 00 00 27 11
RX S2F38     00 00 00 0D 00 00 02 26 00 00 00 00 04 04  21 01 00

ERACK 0. Even the strict equipment does not object, because S2F37 carries no RPTID and has nothing to object with. The host log records "enable OK" and S6F11 never comes.

Now in order. Define RPTID 700 as VID 1 and VID 2.

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

DRACK 0. Send the same message once more:

RX S2F34     00 00 00 0D 00 00 02 22 00 00 00 00 04 06  21 01 03

DRACK 3 — that RPTID is already defined. Define a different report with a VID the equipment does not have, 99, and a different value comes back.

TX S2F33 W   00 00 00 24 00 00 82 21 00 00 00 00 04 07
             01 02 B1 04 00 00 00 01
                   01 01 01 02 B1 04 00 00 02 BD 01 01 B1 04 00 00 00 63
RX S2F34     00 00 00 0D 00 00 02 22 00 00 00 00 04 07  21 01 04

00 00 00 63 is VID 99. DRACK 4, and RPTID 701 (02 BD) is not created. Note what that implies: rejection is per message. Pack five reports into one S2F33, get one VID wrong, and none of the five exist afterwards.

With the definition in place the link goes through.

RX S2F36     00 00 00 0D 00 00 02 24 00 00 00 00 04 08  21 01 00

LRACK 0. Repeat the same link and you get 21 01 03LRACK 3, the CEID is already linked. Link CEID 9999 (00 00 27 0F), which does not exist, and you get 21 01 04LRACK 4.

One line per value. What follows is the meaning this equipment's code assigns; I have not checked these against the wording of the DRACK/LRACK/ERACK definitions in the SEMI E5 text.

ValueS2F34 DRACKS2F36 LRACK
0acceptedaccepted
2item structure not as expecteditem structure not as expected
3RPTID already definedCEID already linked
4no such VIDno such CEID
5RPTID not defined

S2F38 ERACK has only two values in this implementation: 0 (accepted) and 1 (no such CEID, or CEED was not a BOOLEAN).

What S6F11 looks like once the order is right

After define → link → enable, S1F17 puts the equipment in ON-LINE REMOTE and S2F41 START goes out. HCACK 0 comes back — HCACK 2 and control states are a separate story — and the event follows immediately.

RX S6F11 W   00 00 00 2A 00 00 86 0B 00 00 00 00 00 01
             01 03 B1 04 00 00 00 01
                   B1 04 00 00 27 11
                   01 01 01 02 B1 04 00 00 02 BC 01 02 A5 01 05 A5 01 03
TX S6F12     00 00 00 0D 00 00 06 0C 00 00 00 00 00 01  21 01 00

The body is <L [3] <U4 1> <U4 10001> <L [1] <L [2] <U4 700> <L [2] <U1 5> <U1 3>>>>>: DATAID 1, CEID 10001, and one report — RPTID 700 holding the values of VID 1 and VID 2 in the order the definition gave them. A5 is a U1 item; the values are 5 (CONTROL_STATE = ON-LINE REMOTE) and 3 (PROCESS_STATE = EXECUTING). The report body carries no VID numbers. Order is the contract.

One more thing in the header. 86 0B is W-bit plus Stream 6, Function 11, and the SystemBytes are 00 00 00 01 — not the 00 00 04 xx range the host was using. S6F11 is a primary message the equipment opens, so it uses the equipment's own SystemBytes, and S6F12 has to echo that value back. Look for it in the host's transaction table and it is not there.

On a fresh session I linked both CEID 10001 and 10002 to RPTID 700, enabled them, and received one S6F11 from START normally. Then, intending to add a report, I sent an S2F33 carrying only the new RPTID 701.

TX S2F33 W   00 00 00 24 00 00 82 21 00 00 00 00 05 08
             01 02 B1 04 00 00 00 01
                   01 01 01 02 B1 04 00 00 02 BD 01 01 B1 04 00 00 00 03
RX S2F34     00 00 00 0D 00 00 02 22 00 00 00 00 05 08  21 01 00

DRACK 0. Success. Then STOP:

TX S2F41 W   00 00 00 14 00 00 82 29 00 00 00 00 05 09  01 02 41 04 53 54 4F 50 01 00
RX S2F42     00 00 00 11 00 00 02 2A 00 00 00 00 05 09  01 02 21 01 00 01 00

HCACK 0. And then three seconds of nothing. No S6F11 for CEID 10002.

This equipment treats one S2F33 as a replacement of the entire report definition set. RPTID 700 is not in the new set, so it disappears, and the two links referring to it are quietly deleted with it. The ack is 0 and there is no warning. That is the classic shape of a report that arrived yesterday and does not today.

Whether E5 specifies S2F33 as a replacement or as an accumulation is something I did not confirm in the standard text. What is certain is that this equipment behaved as a replacement in the capture above, and the host-side conclusion is the same either way. Do not send partial S2F33 messages when adding a report. Resend the complete definition set for that session every time.

The host-side list

  1. Order is S2F33 → S2F35 → S2F37. If a step answers non-zero, do not send the next one.
  2. Do not just test the last byte for zero — log the value itself. LRACK 5 and LRACK 4 have nothing in common, and collapsing both into "link setup failed" fixes neither.
  3. ERACK 0 is not evidence that a link exists. The only evidence is an S6F11 actually arriving. Force one event right after setup and check.
  4. Pull the VID list with S1F11 before defining, and keep VIDs the equipment does not have out of S2F33. DRACK 4 kills the whole message.
  5. The SystemBytes on S6F11 belong to the equipment. Echo them in S6F12 and never match them against the host's outstanding transactions.
  6. Report bodies contain no VID numbers. Store the order you sent in S2F33 on the host side, and refuse to interpret values without that mapping.
  7. When changing reports, resend everything. Whether an equipment supports incremental additions is answered by a capture, not by the vendor document.

Every frame above went over a socket. The same bytes are in the equipment-side RX log and the host-side TX log, and the raw export sits in content/demos/s2f35-lrack-report-link-order.json. To run it yourself, point a socket at the SECS/GEM simulator.

A last caveat. The ack values in this article belong to two implementations, not to the standard. A real tool may hold a third answer — silence, an SxF0, or a code that appears nowhere here — so host code should default to treating any value it does not recognise as a failure. The moment an unknown ack is handled like a zero, every failure in this article goes quiet.