← 전체 글
SECS/GEM/약 9분 읽기/— 조회

SELECTED는 통신 중이라는 뜻이 아니다: S1F13에 S1F14가 안 올 때

HSMS는 SELECTED인데 S1F13은 조용히 T3만 태운다. 같은 소켓에서 Linktest는 0ms에 답하는 실제 캡처와, 상태 기계가 두 개인 이유.

SECS/GEMMESSCADA문제 해결체크리스트

호스트 화면에는 SELECTED가 떠 있다. Select.rsp는 1ms 만에 돌아왔고, Linktest도 계속 답한다. 그런데 S1F13을 던지면 S1F14가 오지 않고 T3만 조용히 만료된다. 여기서 보통 네트워크를 의심하기 시작하는데, 방금 Linktest가 0ms에 왕복했다. 링크 문제가 아니라는 뜻이다. HSMS 연결 상태와 GEM 통신 상태는 서로 다른 상태 기계이고, 앞의 것이 끝났다고 뒤의 것이 시작된 건 아니다.

같은 소켓에서의 세 번의 요청 — Select.req는 Select.rsp로 1ms에 돌아오고, S1F13은 4004ms 동안 응답 없음, Linktest.req는 Linktest.rsp로 0ms에 돌아온다 Host장비 Select.req Select.rsp · 1ms Linktest.req Linktest.rsp · 0ms S1F13 · W-bit 응답 없음 · 4004ms

같은 소켓, 세 번의 요청

passive 리스너에 직접 소켓을 열고 호스트 역할을 했다. Select.req, S1F13, Linktest.req 순서로 던진 결과다.

TX Select.req     00 00 00 0A 00 0B 00 00 00 01 00 00 05 01
RX Select.rsp     00 00 00 0A 00 0B 00 00 00 02 00 00 05 01   (1ms)

TX S1F13          00 00 00 1A 00 0B 81 0D 00 00 00 00 05 02
                  01 02 41 07 48 4F 53 54 4D 45 53 41 03 32 2E 31
RX                (응답 없음, 4004ms 대기 후 포기)

TX Linktest.req   00 00 00 0A 00 0B 00 00 00 05 00 00 05 03
RX Linktest.rsp   00 00 00 0A 00 0B 00 00 00 06 00 00 05 03   (0ms)

Select는 끝났다. Select Status 바이트가 00이고 SystemBytes 00 00 05 01이 그대로 돌아왔으니 세션은 SELECTED다. 그 다음 줄에서 데이터 메시지가 침묵을 맞는다. 그리고 바로 뒤의 Linktest는 0ms에 답이 온다.

이 순서가 중요하다. Linktest를 S1F13 뒤에 보내야 "그 사이에 죽은 게 아니다"를 증명할 수 있다. 소켓도 프로세스도 멀쩡하고, 답할 여유도 있다. 침묵은 그 위 계층에서 나온 것이다.

S1F13 헤더를 바이트로 뜯으면

00 00 00 1A   Length      26바이트 (헤더 10 + 바디 16)
00 0B         SessionID   11
81            Byte 2      W-bit 1 + Stream 1
0D            Byte 3      Function 13
00            PType       0 = SECS-II
00            SType       0 = 데이터 메시지
00 00 05 02   SystemBytes 이 트랜잭션 ID
01 02 ...     바디        L,2 { A 'HOSTMES', A '2.1' }

볼 곳은 두 군데다. SType이 00이면 제어 메시지가 아니라 데이터 메시지고, 이건 세션이 SELECTED일 때만 보낼 수 있다. Byte 2의 최상위 비트가 W-bit인데 여기서는 81, 즉 답을 요구하고 있다. W-bit을 0으로 보내놓고 답을 기다리는 버그는 헤더 바이트 2에서 따로 다뤘다. 바디의 01 02는 원소 2개짜리 List, 41 07은 7바이트 ASCII다 — 이 계산은 아이템 헤더의 길이 바이트 쪽이다.

바디에 MDLN과 SOFTREV를 넣었다. 장비 쪽 RX 로그에 이 26바이트가 보낸 그대로 찍혀 있으니, 인코딩이 틀려서 무시당한 경우는 아니다.

상태 기계가 두 개다

SEMI E37이 관리하는 건 연결이다. NOT CONNECTED에서 시작해 TCP가 붙으면 CONNECTED, Select가 끝나야 SELECTED가 된다. 데이터 메시지는 이때부터 흐를 수 있다. 여기까지가 E37이 책임지는 전부다.

SEMI E30(GEM)의 통신 상태는 그 위에 따로 있다. 장비가 통신을 허용하는 상태인지(DISABLED / ENABLED), 그리고 호스트와 실제로 통신 중인지(NOT COMMUNICATING / COMMUNICATING)를 구분한다. NOT COMMUNICATING에서 COMMUNICATING으로 넘어가게 하는 게 S1F13 / S1F14 교환이다. S1F14 바디의 첫 아이템이 COMMACK이고, 0이 수락이다. 0이 아니면 거부인데, 어떤 값이 무슨 뜻인지는 E30의 표와 장비 매뉴얼에 있다 — 나는 실제 장비에서 0이 아닌 COMMACK을 받아본 캡처가 없다.

그래서 SELECTED는 "소켓과 세션이 열렸다"까지만 말해준다. 장비가 통신을 아직 켜지 않았거나, 켜는 중이거나, 호스트를 받아줄 상태가 아니면 S1F13은 그대로 버려진다. MES 화면에 SELECTED를 "온라인"으로 그려놓은 시스템이 여기서 틀린다.

이 캡처가 증명하지 않는 것

이 리스너는 제어 메시지에만 답한다. 데이터 메시지 바디를 파싱하지 않으니, 위 캡처의 침묵은 리스너 자신의 한계지 GEM 수준의 거부가 아니다. COMMACK이 붙은 S1F14를 실제로 받아본 캡처는 아니다.

캡처가 증명하는 건 두 가지다. 26바이트가 실제 소켓을 타고 장비 쪽 RX로 기록됐다는 것, 그리고 같은 소켓의 Linktest가 0ms에 답한다는 것. 호스트에서 보이는 증상의 모양은 실제 장비가 통신 확립을 안 해줄 때와 같다. 원인이 같다는 뜻은 아니다.

호스트에서 정리할 것

  • SELECTED를 통신 확립으로 취급하지 않는다. 온라인 판정은 S1F14의 COMMACK을 읽은 뒤다.
  • S1F13에 답이 없다고 T3 주기로 무한 재시도하지 않는다. GEM은 통신 확립 재시도에 별도 지연을 두는 쪽이고, 그 지연은 장비 상수로 노출되는 경우가 많다. 값과 이름은 장비 매뉴얼에서 확인해라.
  • Linktest 성공은 링크만 증명한다. 감시 화면에 이것만 걸어두면 Select도 안 끝난 세션까지 초록불로 보인다.
  • 장비 쪽 RX 로그부터 본다. 바이트가 도착조차 안 했으면 이건 GEM 문제가 아니라 프레이밍 문제다.

여기서 시간 제일 많이 버리는 지점은 따로 있다. 호스트 로그에 "T3 timeout"만 남기고 어떤 메시지가 죽었는지 안 적는 스택이다. S1F13이 죽은 것과 S6F11이 죽은 것은 완전히 다른 사건인데, 로그만 보면 구별이 안 된다.

재현

캡처는 SECS/GEM 시뮬레이터의 passive 리스너에 소켓을 직접 열어서 만들었다. 같은 순서로 던져보고, 장비 쪽 RX hex가 보낸 바이트와 일치하는지 먼저 확인해라.