← 전체 글
네트워킹/약 15분 읽기/— 조회

outstation을 탓하기 전에 DNP3 IIN 비트부터 읽어라

모든 DNP3 응답에 붙는 두 옥텟의 IIN은 재시작, 잃어버린 이벤트, 없는 시간, 로컬 제어를 알려준다. 이 비트를 읽는 법과 사라지지 않는 비트를 지우는 법을 정리한다.

네트워킹SCADA문제 해결시운전

"나 방금 재시작했어"를 계속 말하는 폴

한 outstation이 폴에 정상으로 답하고 있었다. 값도 갱신되고 품질도 좋았다. 그런데 마스터는 스캔마다 재시작 알람을 띄웠고, 한 엔지니어는 그걸 멈추려고 오후 내내 RTU 전원을 껐다 켰다. RTU는 멀쩡했다. 마스터가 outstation이 부팅 때 한 번 세운 비트를 읽고 있었고, 아무도 그 비트를 지우지 않았을 뿐이다.

그 비트는 DNP3가 모든 애플리케이션 계층 응답 앞에 붙이는 두 옥텟, 즉 Internal Indications(IIN) 필드에 산다. 실제 DNP3 문제의 거의 전부 — 잃어버린 이벤트, 마스터가 한 번도 맞추지 않은 시계, 로컬에 묶인 출력, 손상된 설정 — 는 다른 어디에 나타나기 전에 이 16비트에 먼저 신고된다. 대부분의 마스터는 이걸 진단 태그로 노출하지만, 대부분의 통합업체는 들여다보지 않는다. IIN을 읽을 줄 알면 DNP3 문제 해결의 절반이 "outstation이 이미 말해준 걸 읽는 일"로 바뀐다.

두 옥텟이 담는 것

IIN은 두 바이트 IIN1과 IIN2로, 모든 응답 헤더와 비요청 메시지에 실린다. IIN1은 대부분 상태 — outstation이 당신을 위해 쥐고 있는 것 — 이고, IIN2는 대부분 불만 — 방금 받은 요청에서 마음에 안 든 것 — 이다.

비트마스크이름의미
IIN1.00x01Broadcast마지막 메시지를 브로드캐스트(전 국)로 받음
IIN1.10x02Class 1 이벤트Class 1 이벤트가 읽히길 기다림
IIN1.20x04Class 2 이벤트Class 2 이벤트 대기 중
IIN1.30x08Class 3 이벤트Class 3 이벤트 대기 중
IIN1.40x10Need Timeoutstation이 시간 동기화를 원함
IIN1.50x20Local Control하나 이상의 출력이 원격이 아닌 로컬에 있음
IIN1.60x40Device Troubleoutstation 고유의 비정상 상태
IIN1.70x80Device Restart마스터가 마지막으로 지운 뒤 outstation이 재시작함
IIN2.00x01No Func Support요청한 기능 코드를 지원하지 않음
IIN2.10x02Object Unknown요청한 객체/변형을 여기서 모름
IIN2.20x04Parameter Error한정자/범위/파라미터가 범위 밖이거나 파싱 불가
IIN2.30x08Buffer Overflow이벤트 버퍼가 넘쳐 이벤트가 손실됨
IIN2.40x10Already Executing요청한 동작이 이미 실행 중
IIN2.50x20Config Corruptoutstation 설정이 손상됨

IIN2.6과 IIN2.7은 예약이며 0으로 읽혀야 한다. 여기 비트 배정과 지우기 규칙은 IEEE 1815(DNP3)를 따른다. 준수 outstation은 이를 지키지만, 일부 상태 비트가 언제 사라지는지는 벤더마다 다르니 장치 프로파일과 대조해 확인하라.

Class 이벤트 비트(IIN1.1–1.3)는 오류가 아니라 outstation이 "읽을 게 있다"고 말하는 것이다. 건강한 이벤트 기반 시스템에서는 마스터가 이벤트를 읽으면서 이 비트가 끊임없이 세워지고 지워진다. 세워져 있는데 해당 클래스를 한 번도 폴하지 않으면 이벤트는 버퍼가 넘칠 때까지 쌓인다. 그게 바로 다음 문제다.

마스터가 지워줘야 하는 두 비트

두 IIN 비트는 일부러 래치된다. outstation이 세우고 나서 마스터가 뭔가 하기를 기다린다. 마스터 설정이 잘못되면 이 비트는 영원히 세워진 채 스캔마다 성가신 알람을 만든다 — 위의 재시작 루프 이야기가 정확히 그것이다.

Device Restart (IIN1.7). 모든 콜드/웜 재시작 때 세워진다. outstation이 잘 돌아가도 저절로 사라지지 않는다. 마스터가 Internal Indications 포인트 — 객체 그룹 80, 변형 1, 인덱스 7 — 에 Write 기능(FC 2)으로 명시적으로 0을 써야만 지워진다. 이건 의도된 설계다. 비트가 내려가기 전에 마스터가 "재시작을 봤고, 너에 대한 내 관점을 다시 초기화했다"고 인정하도록 강제하는 것이다. 그 Write를 절대 내지 않는 마스터는 비트를 영구히 세워둔다. 해결책은 보통 시작 시 restart IIN 지우기 또는 restart 처리 활성화 같은 이름의 마스터 측 설정이다. 켜두면 마스터가 재-integrity 폴 후 g80v1 인덱스 7을 쓴다. outstation은 애초에 문제가 아니었다.

Need Time (IIN1.4). outstation 시계가 동기화되지 않았거나, 설정된 재동기 주기가 지났을 때 세워진다. 마스터가 시간 동기화 — 객체 그룹 50(Time and Date) Write — 를 수행하면 지워진다. 마스터의 시간 동기 작업이 꺼져 있거나 엉뚱한 outstation을 향해 있으면 이 비트는 세워진 채 남고, outstation이 만드는 모든 이벤트 타임스탬프는 의심스러워진다. 이건 사건 순서(SOE) 정확도와 직결된다. Need Time을 세운 outstation은 동기를 고치기 전까지 자기 이벤트 시각을 믿지 말라고 말하는 것이다.

두 비트가 주는 교훈은 같다. 지워지지 않는 IIN 상태 비트는 거의 언제나 outstation이 고장 난 게 아니라 마스터가 해야 할 단계를 건너뛰고 있다는 뜻이다.

Buffer Overflow는 이미 데이터를 잃었다는 뜻

IIN2.3은 알람을 걸고 절대 무시하면 안 되는 비트다. outstation의 이벤트 버퍼가 가득 차, 마스터가 읽기 전에 이벤트가 버려졌다는 뜻이다. 그 안에 있던 것 — 차단기 동작, 알람 전이, 아날로그 급변 — 은 사라졌다. 예외 보고에 구멍이 났고, 다시 폴해도 잃은 이벤트는 돌아오지 않는다. 덮어써졌기 때문이다.

이걸 보면 원인은 대개 몇 가지 중 하나다.

  • 마스터가 이벤트 클래스를 충분히 자주 폴하지 않아, 이벤트가 빠지는 속도보다 빠르게 쌓인다.
  • 회선이 outstation이 보고할 수 없을 만큼 오래 끊겨 그동안 버퍼가 찼다. 무선이나 다이얼업 경로에서 흔하다.
  • outstation의 이벤트 버퍼가 포인트 수와 변화율에 비해 그냥 너무 작게 설정됐다.

해결책은 비트를 지우는 게 아니라 버퍼 크기와 폴 주기다. 대부분의 outstation에서 오버플로 플래그는 버퍼가 더 이상 가득 차지 않으면 스스로 지워지지만, 그건 위안이 못 된다. 플래그가 지워졌다고 데이터가 돌아온 건 아니다. 모든 Buffer Overflow를 해당 outstation의 히스토리안에 기록된 구멍으로 취급하고, 재발하면 이벤트 클래스 폴 주기를 높이거나 버퍼를 키워라. 오래 끊기는 회선에서는 현실적으로 가장 긴 정전을 버틸 크기로 버퍼를 잡아라.

Local Control, Device Trouble, 그리고 정직한 상태 비트들

Local Control (IIN1.5) 는 outstation의 하나 이상 출력 포인트가 로컬 모드 — 패널의 핸드 스위치, 정비 잠금 — 에 있어 원격 명령에 응하지 않을 때 세워진다. "열기 명령을 보냈는데 오류도 없이 아무 일도 없었다"를 설명하는 비트다. 명령은 제대로 수신됐고 제대로 거부됐다. 그 포인트가 로컬 제어 아래 있기 때문이다. 이걸 운전원 화면에 노출하라. "outstation 로컬" 을 볼 수 있는 운전원은 애초에 움직일 리 없던 제어와 싸우기를 멈추고, 현장에 사람을 보내야 한다는 걸 안다.

Device Trouble (IIN1.6) 는 표준에서 일부러 모호하게 뒀다. 벤더가 신고할 가치가 있다고 판단한 outstation 고유의 비정상 상태 — 자체 진단 실패, 하드웨어 결함, 워치독 트립 — 다. 그 자체로는 뭔가 잘못됐다는 것만 알려주니, 무엇인지는 장치 자체 진단이나 매뉴얼로 가야 안다. 알람은 걸되, 벤더가 상세를 어디에 노출하는지 가리키는 메모와 함께 걸어라. 아니면 그냥 정체불명의 경고등이 된다.

Config Corrupt (IIN2.5) 는 outstation이 자기 설정이 손상됐다고 판단했다는 뜻이다. 지우고 넘어가지 마라. 자기가 못 믿는 설정으로 도는 outstation은 쓰레기 값을 낼 수 있다. 이건 현장 방문과 설정 재적재를 요한다.

IIN2의 불만 비트는 당신의 요청에 관한 것

IIN2의 아래쪽 — No Function Support, Object Unknown, Parameter Error, Already Executing — 은 outstation이 자기가 아프다는 게 아니라 당신의 요청이 틀렸다고 말하는 것이다. 시운전 때 이 비트는 금값이다. "폴이 안 된다"를 구체적 이유로 바꿔주기 때문이다.

  • No Function Support (IIN2.0): 이 outstation이 구현하지 않은 기능 코드를 요청했다. 마스터가 단순 RTU가 지원하는 것보다 풍부한 기능으로 설정됐을 때 흔하다.
  • Object Unknown (IIN2.1): outstation에 없는 객체 그룹이나 변형을 요청했다 — 매핑되지 않은 포인트 인덱스나, 장치가 만들지 않는 아날로그 변형인 경우가 많다.
  • Parameter Error (IIN2.2): 요청의 한정자나 범위가 파싱되지 않거나 범위를 벗어났다. 존재하는 것보다 많은 포인트를 요구하는 범위가 흔하다.

시운전 중 폴이 쓸모없는 응답을 내면 IIN2부터 읽어라. 대개 마스터와 outstation이 어긋난 정확한 객체나 기능을 짚어준다. 패킷 캡처를 노려보며 추측하는 것보다 빠르다.

IIN을 디버그 로그가 아니라 진단에 엮어라

좋은 DNP3 마스터는 IIN 비트를 outstation별 개별 진단 태그로 매핑한다. 당신 것이 그렇다면 활용하라.

  • Buffer Overflow 와 Config Corrupt 에 알람을 걸어라 — 실제 피해(잃은 데이터, 못 믿는 설정)를 뜻한다.
  • Local Control 과 Device Restart 를 운전원/정비 화면에 표시하라 — 운전원이 아니면 오해할 동작을 설명한다.
  • Device Trouble 과 Need Time 을 추세나 카운트로 잡아, 서서히 오는 문제(드리프트하는 시계, 불안정한 자체 진단)가 사고가 되기 전에 보이게 하라.
  • Class 이벤트 비트는 엔지니어링 진단용으로 남겨라. 설계상 깜빡이며 운전원이 신경 쓸 값이 아니다.

다음에 outstation이 "명령을 안 받는다", "재시작 알람을 계속 낸다", "이벤트를 몇 개 흘렸다" 할 때, 현장으로 차를 몰기 전에 IIN 비트부터 확인하라. 모든 응답 앞의 열여섯 비트에 대개 답이 이미 들어 있다 — outstation은 마지막으로 답했을 때 무엇이 잘못됐는지 이미 말해줬다.