NGAP와 함께 보는 ASN.1 - 1st
NGAP
NGAP (Next Generation Application Protocol)은 5G 네트워크에서 gNB와 AMF 사이의 N2 인터페이스 프로토콜이며 asn.1의 PER에 따라 인코딩하여 주고 받는다. NGAP 표준에 정의된 asn.1 문서는 총 여섯 개이다.
- NGAP-CommonDataTypes.asn
- NGAP-Constants.asn
- NGAP-Containers.asn
- NGAP-IEs.asn
- NGAP-PDU-Contents.asn
- NGAP-PDU-Descriptions.asn
이제부터 수차례에 걸쳐 각 .asn 파일을 하나씩 열어 asn.1 표준을 분석해볼 것이다. NGAP 자체를 분석하는 것이 목적이 아니기 때문에 asn.1 문법 상 중복되는 내용은 생략하고 건너뛸 것이다. 표준문서는 3GPP Rel 16.3의 것을 기준으로 한다.
먼저 NGAP-CommonDataTypes.asn 파일부터 분석한다.
Object Identifier
파일은 아래 내용으로 시작한다.
NGAP-CommonDataTypes {
itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
ngran-Access (22) modules (3) ngap (1) version1 (1) ngap-CommonDataTypes (3) }
NGAP-CommonDataTypes
은 해당 파일에 ASN.1으로 정의된 모듈의 식별자다. 모듈 식별자는 파일명과 똑같게 정한다. asn.1로 작성한 파일이 여러 개 있고 서로 다른 파일을 참조할 경우에는 모듈 식별자를 갖고 참조할 파일을 결정하기 때문이다.
모듈명 다음의 {...}
는 해당 모듈의 OID(Object Identifier)를 정의한 부분이다. OID는 전 세계적으로 고유한 식별자로 계층적 구조를 가진다. 위의 내용을 분석하면 다음과 같다.
itu-t (0)
: ITU-T 기관identified-organization (4)
etsi (0)
: ETSI 유럽 표준화 기구mobileDomain (0)
ngran-Access (22)
: NG-RAN 무선 접속망modules (3)
ngap (1)
: Next Generation Application Protocol (NGAP)version1 (1)
: 버전 정보ngap-CommonDataTypes (3)
제일 처음의 itu-t (0)
은 ITU-T에서 결정한 값으로, X.660 표준에 정의되어 있다. 참고로 X.660은 바로 이 OID에 대한 표준으로, ITU-T에서 관리하고 있다. 그 뒤로는 ETSI, 3GPP 등 하위 단체 순으로 다음 OID 값을 결정한다. 이런 계층적 방식으로 해당 asn.1 모듈을 전 세계적으로 고유하게 식별될 수 있다.
asn.1 모듈의 몸통
그 다음 내용을 보면 나머지 내용은 대부분 BEGIN
과 END
사이에 있음을 알 수 있다.
DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
...
END
이 부분은 asn.1 모듈 정의의 시작과 끝을 나타낸다. 우선 첫 줄은 다음과 같다.
DEFINITIONS
: asn.1 모듈 정의의 시작AUTOMATIC TAGS
: 모듈에서 사용되는 모든 태그가 자동으로 할당됨을 나타낸다. 이 경우 모듈 내의 각 구성 요소에 대해 명시적으로 태그를 정의하는 대신 context specific 태그를 자동으로 붙여주기 때문에 모듈 내의 타입 정의가 훨씬 더 간결해진다.::=
: asn.1에서의 할당 연산자로, 왼쪽에 있는 식별자에 오른쪽에 있는 값을 할당한다.BEGIN
,END
: 모듈 정의의 시작과 끝을 나타낸다. 이 사이의 내용에 모듈에서의 타입과 값 정의가 포함된다.
타입의 정의
다음은 Criticality
라는 이름의 새로운 타입을 정의한다.
Criticality ::= ENUMERATED { reject, ignore, notify }
Criticality
: 정의하고자 하는 새로운 타입의 이름ENUMERATED
: enumerated(열거형) 타입. 명시된 여러 개의 가능한 값 중 하나를 가질 수 있다.{ reject, ignore, notify }
:Criticality
타입은 여기에 나열된 값 중 하나를 가질 수 있다.
ENUMERATED
에 열거된 값들은 나열된 순서대로 다음과 같이 0부터 시작하는 정수 값에 매핑된다.
reject
:0
ignore
:1
notify
:2
BER과 DER의 경우 정수 값은 1바이트씩 인코딩된다. 물론 태그와 길이까지 추가된 완전한 TLV 포맷으로는 더 늘어난다. PER의 경우 정수 값은 최소 길이의 비트로 표현된다. 여기서는 총 3개의 값을 가지므로 다음과 같이 2비트로 인코딩된다.
reject
:00
ignore
:01
notify
:10
다음은 PrivateIE-ID
라는 이름의 CHOICE
타입을 정의한다.
PrivateIE-ID ::= CHOICE {
local INTEGER (0..65535),
global OBJECT IDENTIFIER
}
CHOICE
타입은 여러 개의 타입 중 하나를 선택하여 사용할 수 있는 데이터 타입이다. 이 경우 PrivateIE-ID
는 local
이라는 이름의 INTEGER
타입 또는 global
이라는 이름의 OBJECT IDENTIFIER
타입 중 하나를 선택할 수 있다.
PrivateIE-ID
: 정의하고자 하는 새로운 타입의 이름CHOICE
: 여러 개의 타입 중 하나를 선택하여 사용할 수 있는 데이터 타입local INTEGER (0..65535)
: 0에서 65535까지의 범위를 갖는local
이라는 이름의INTEGER
타입global OBJECT IDENTIFIER
:global
이라는 이름의OBJECT IDENTIFIER
타입
OBJECT IDENTIFIER
는 앞서 설명한 전 세계적으로 고유한 OID를 의미한다. OID를 인코딩하는 방법에 대해서는 나중에 설명하기로 한다.
PER로 인코딩할 때, CHOICE
타입의 경우 안에 정의된 여러 타입 중 어떤 것을 쓰고 있는지 가리키는 선택 비트가 먼저 추가된다. 위의 경우 2개 중에서 선택하는 것이므로 1비트만 사용된다.
local
:0
global
:1
local
인 경우 65535까지의 값을 갖는 정수를 사용하므로 값은 16비트로 할당된다. 예를 들어 0xffff
정수를 사용한 경우 PrivateIE-ID
는 다음과 같이 인코딩된다.
- `local` select bit: `0`
- padding bits: ` 000 0000`
- integer (16bits): ` 1111 1111 1111 1111`
다음은 INTEGER
타입으로 정의되는 ProcedureCode
이다. 0에서 255 사이의 값을 가지기 때문에 8비트 정수로 인코딩될 것이다.
ProcedureCode ::= INTEGER (0..255)
PER의 경우, 정수 값은 그대로 이진수 형태로 인코딩되므로 값이 42인 경우 이진수로 0010 1010
(0x2a
)로 인코딩된다.
만약 DER이라면, tag와 길이까지 합쳐 다음과 같이 인코딩된다.
- tag:
INTEGER
타입은 범용 클래스 태그 2를 가진다. (0x02
) - length: 값이 8비트 이내에 표현되므로 길이 값은 1이다. (
0x01
) - value: 정수 값 42는 16진수로
0x2a
가 된다.
따라서 인코딩된 결과는 02 01 2a
가 된다.
여기까지 NGAP-CommonDataTypes.asn의 내용을 살펴봤다. 담고 있는 내용도 제일 적고 구조도 간단하기 때문에 처음에 asn.1에 대해 설명하기가 쉬웠다. 점점 크기도 커지고 구조가 복잡해지는 순으로 .asn 파일을 골라서 설명을 할 것이다.