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

S5F3에 ACKC5 0이 돌아왔다고 그 ALID가 있는 건 아니다

알람이 한 건도 안 올라올 때 호스트가 보내야 하는 S5F3의 바이트 구조와, 장비에 없는 ALID를 껐는데도 ACKC5 0이 돌아온 소켓 캡처.

SECS/GEM알람MESSCADA문제 해결체크리스트

장비 붙이고 이틀째다. S6F11은 잘 올라온다. 그런데 알람이 한 건도 안 온다. 장비 화면에는 빨간 줄이 떠 있고 호스트 로그에는 S5F1이 없다. 선 문제도 아니고 통신 게이트 문제도 아니다. 알람을 보내 달라고 말한 적이 없을 뿐이다. 그 말을 하는 메시지가 S5F3이고, 본문은 아이템 두 개다. ALED 하나, ALID 하나. 전체 알람을 한 번에 켜려면 ALID를 길이 0으로 비워서 보낸다.

S5F3 본문 7바이트: L,2 다음에 ALED 한 바이트 80, 그리고 길이 0인 ALID가 전체 알람을 뜻한다 S5F3 본문 — 전체 알람 enable, 7바이트 헤더 10바이트는 뺀 것 L,2 ALED ALID 0102 210180 B100 012 3456 21 = BB1 = U4 길이 0 — 전체 알람

캡처

시뮬레이터의 passive listener에 소켓을 직접 열었다. HTTP API가 아니라 소켓이다. 장비 쪽에 RX가 찍혀야 실제로 선을 탄 프레임이다.

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

바이트 3의 00이 Select Status다. 세션은 SELECTED다.

TX S1F13 W      00 00 00 17 00 0B 81 0D 00 00 00 00 02 02
                01 02 41 04 48 4F 53 54 41 03 31 2E 30
RX S1F14        00 00 00 37 00 0B 01 0E 00 00 00 00 02 02
                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

21 01 00은 B[1] 0, COMMACK 0이다. E30의 통신 게이트가 열렸다. 이걸 먼저 해 두지 않으면 뒤의 S5F3은 알람 얘기도 못 꺼내고 S5F0으로 끊긴다. 그쪽은 게이트 글에 따로 있다.

TX S5F3 W       00 00 00 11 00 0B 85 03 00 00 00 00 02 03 01 02 21 01 80 B1 00
RX S5F4         00 00 00 0D 00 0B 05 04 00 00 00 00 02 03 21 01 00

바이트 2가 85다. 상위 1비트가 W-bit, 나머지가 Stream 5. 바이트 3 03은 function 3이다.

본문 7바이트를 쪼개면 이렇다. 01 02는 L이고 원소 두 개다. 21은 상위 6비트가 8, 즉 포맷 B이고 하위 2비트가 1이라 길이 바이트 한 개, 그게 01이니 1바이트. 값은 80. 이게 ALED다. 그다음 B1은 상위 6비트가 44, U4다. 길이 바이트는 00 — 길이 0이다. 데이터가 한 바이트도 없는 아이템이다. E5에서 S5F3의 ALID 자리가 비어 있으면 "전체 알람"이라는 뜻이다.

답은 21 01 00, B[1] 0이다. ACKC5 0, 받았다는 뜻이다.

TX S5F3 W       00 00 00 15 00 0B 85 03 00 00 00 00 02 04 01 02 21 01 00 B1 04 00 00 03 EC
RX S5F4         00 00 00 0D 00 0B 05 04 00 00 00 00 02 04 21 01 00

두 번째는 ALED를 00으로 바꾸고 ALID를 하나 지정했다. B1 04 00 00 03 EC — U4, 4바이트, 값 1004다. "ALID 1004만 끄라"는 요청이다.

여기가 함정이다

이 장비에 ALID 1004는 없다. 이 listener가 가진 알람은 두 개뿐이고 5001과 5002다. 내가 1004를 지어냈다.

그런데 답은 21 01 00, 똑같은 ACKC5 0이다.

없는 ALID 1004 끄기  →  ACKC5 0
전체 알람 켜기       →  ACKC5 0

구분이 안 된다. 호스트 코드에서 "S5F4가 0으로 왔으니 알람 설정이 반영됐다"로 적으면, 오타 난 ALID 하나가 조용히 통과한다. 통합 테스트는 초록색이고, 현장에서 그 알람만 안 온다. 디버깅은 몇 달 뒤에 시작된다.

ACKC5 0이 보장하는 건 하나다. 장비가 그 프레임을 받아서 파싱했다. 그 ALID가 존재하는지, 지금 enable인지 disable인지는 아무것도 말해 주지 않는다.

그래서 호스트는 뭘 하나

  • ALID는 지어내지 말고 받아 온다. 장비가 가진 알람 목록은 S5F5로 물어 S5F6으로 받는 자리다. 그 목록에 없는 번호를 S5F3에 넣을 일이 없어진다. ALCD와 set/clear 쪽은 알람 매핑 글에 있다.
  • 전체를 한 번에 켠다. ALID를 길이 0으로 비우면 번호를 안 틀린다. 알람을 골라 끄는 건 그다음 문제다.
  • 재접속할 때마다 다시 보낸다. enable 상태가 세션을 넘어 남는다는 보장이 없다. S1F13 직후에 S5F3 한 방을 고정으로 넣어 두는 편이 싸다.
  • 알람이 안 오면 S5F3부터 본다. 선, 게이트, 리포트 링크를 다 뒤지기 전에 이것부터다. 호스트가 알람을 켠 적이 있는지 로그에서 찾는 데 1분이면 된다.

확인하지 못한 것

ALED 값의 의미는 이번 캡처로 확인하지 못했다. 이 listener는 ALED 바이트를 읽지도 않고 80이든 00이든 같은 ACKC5 0을 돌려준다. E5의 S5F3 정의에서 ALED는 0이 disable, 0이 아니면 enable이고 현장에서 80을 쓰는데, 그 조항 문구를 이번 런에 사본으로 다시 읽지는 않았다.

길이 0인 ALID가 전체 알람을 뜻한다는 것도 E5 쪽 규정이지 내가 바이트로 증명한 게 아니다. 이 listener에는 알람 필터링 자체가 없어서 켜고 끈 결과를 볼 수 없다.

GEM 장비가 출하 시점에 알람을 켜 두는지 꺼 두는지도 확인하지 못했다. 장비마다 다르다고 보고 호스트가 명시적으로 켜는 쪽이 안전하다.

위 프레임은 전부 공개된 SECS/GEM 시뮬레이터의 passive listener에 소켓을 열고 주고받은 것이다. 본인 호스트 스택으로 없는 ALID를 하나 S5F3에 넣어 보면, 그 스택이 ACKC5 0을 어떻게 기록하는지 바로 보인다. 거기서 위 함정에 걸리는지 안 걸리는지가 갈린다.