ASN.1是“Abstract Syntax Notation One”的缩写。
ASN.1可以被看作一种高层协议描述语言,由于它可以用来清晰地描述复杂的数据结构,因而被广泛的作为应用层协议语法的标准。
ASN.1给协议设计者提供了一些简单的数据类型,如整型(Integer)、布尔型(Boolean)以及字节串(Octet string)等,以这些简单类型为基础,协议的设计者就可以构造出更复杂的数据类型。
通过唯一的“标识符(Tag)”可以很容易的标注出由一系列简单类型组成的复杂数据类型。
例如:一张话单可以由一系列数据域的集合组成,每个数据域是一个编码单元或者是多个编码单元的复合。
一个编码单元最多包括四部分:
标识符(identifier octets,或者称为Tag):参见“1.2.1 标识符的编码规则”。
长度(length octets):参见“1.2.2 长度的编码规则”。
内容(contents octets):参见“1.2.3 内容的编码规则”。
结束符(end-of-contents octets):不是必须的,在不定长编码方式下才使用,参见“1.2.4 结束符的编码规则”。
标识符表示该编码对应的协议数据类型,它的编码分两种情况:
情况一
标识符值在0-30之间时,用一个字节表示,其中各位含义如下,具体编码示意图如图1-1所示。
位8和位7代表数据的类型标记(Universal-00, Application-01, Context-specific-10, Private-11)。
位6代表该数据单元是原子式还是结构类型(Primitive-0, Construct-1)。
位5到位1代表具体分配的TAG值(Number of Tag)。
UNIVERSAL类型是ASN.1规范中定义的基本类型使用的,即是为基本类型进行分配TAG值用的,如BOOLEAN类型定义TAG值为1时使用。
Application类型很少用到,不详述。
Context-Specific主要是定义结构类型时使用。
Private私有的,可以根据具体协商而定。
Primitive原子式代表该域采用ASN最小编码单元编码。
Construct结构式代表该域由多个ASN最小编码单元组成。
图1-1 标识符值在0-30之间编码示意图
8 7 6 5 4 3 2 1
+-------+---+------------------+
1 ¦ CLASS ¦P/C¦ TAG NUMBER ¦
+------------------------------+
Bits 8-7: 数据的类型标记:
+------------------------------+
¦ Bit: 8 7 ¦
+-------------------------------¦
¦ Universal 0 0 ¦
¦ Application 0 1 ¦
¦ Context-specific 1 0 ¦
¦ Private 1 1 ¦
+------------------------------+
Bit 6 :原子式 (0) 或 结构类型 (1)
Bits 5-1: 5个比特的二进制数
情况二
标识符值大于等于31时,用一个前字节和若干后续字节表示。
前字节的位8、7、6与第一种情况一样,位5到位1为11111。
后续字节遵守以下规则:
− 除最后一个字节外,其他字节的第8位为1。
− 从第一个字节到最后一个字节的第7位到第1位加起来表示tags值。
− 第一个字节的第7位到第1位不能全为0。
如图1-2所示。
图1-2 标识符值大于等于31时编码示意图
8 7 6 5 4 3 2 1
+-------+---+---+---+---+---+---¦
1 ¦ CLASS ¦P/C¦ 1 ¦ 1 ¦ 1 ¦ 1 ¦ 1 ¦
+-------------------------------+
Bits 8-7: 数据的类型标记
Bit 6 : 原子式 (0) 或 结构类型 (1)
Bits 5-1: 全部设置为1
后续字节编码如下:
8 7 6 5 4 3 2 1
+---+---------------------------¦ first
2 ¦ 1 ¦ NUMBER of TAG (msb) ¦ subsequent
+-------------------------------¦
. .
. .
+-------------------------------¦ last
¦ 0 ¦ NUMBER of TAG (lsb) ¦ subsequent
+-------------------------------+
Bits 8 : 最后一个字节时,设置为0,其他均设置为1
Bits 7-1: 所有字节的比特7-1都加起来,就是实际的Tag值。
1.2.2 长度的编码规则
长度表示内容字段的净长度,不包括内容以外的其他字段的长度。
长度有三种表示形式:短编码方式,长编码方式和不定长编码方式。其中,不定长编码方式不应用于ASN.1话单文件中,因此不做更进一步的描述。
短编码方式
当长度<=127时,用一个字节表示,即为短编码方式:
第8位为0。
第7到第1位表示长度。
如L=26H,则编码为 0010,0110。
8 7 6 5 4 3 2 1
+----------------------------¦
1 ¦ 0 L L L L L L L ¦
+----------------------------+
LLLLLLL 表示实际长度的值
长编码方式
当长度>127时,用多个字节表示,即为长编码方式:
8 7 6 5 4 3 2 1
+---+-------------------------¦
1 ¦ 1 ¦ 0 < n < 127 ¦
+-----------------------------+
+-----------------------------¦
2 ¦ L L L L L L L L ¦
+-----------------------------+
...
+-----------------------------¦
n+1¦ L L L L L L L L ¦
+-----------------------------+
LLLLLLLL表示实际长度的值
第1个字节的位8固定填写为1,BIT1~BIT7表示长度所占的字节数。
第2到n+1字节代表长度的值。
1.2.3 内容的编码规则
内容包含零个、一个或更多的字节,它们的值依赖于所表示的数据类型。
如下图所示:
8 7 6 5 4 3 2 1
+------------------------------¦
¦ most significant byte ¦ octet 1
+------------------------------¦
¦ ¦ octet 2
+------------------------------¦
. .
. .
+------------------------------¦
¦ least significant byte ¦ octet n
+------------------------------+
下面对不同的数据类型分别进行介绍。
BOOLEAN
该类型只能以原子式进行编码。
FALSE编码为:
Tag Length Value
+------------------------------¦
¦ 01H ¦ 01H ¦ 0000, 0000 ¦
+------------------------------¦
TRUE的编码(任何不是全0都可以)为:
Tag Length Value
+------------------------------¦
¦ 01H ¦ 01H ¦ 1111, 1011 ¦
+------------------------------¦
NULL
该类型只能以原子式进行编码,且只有一个值,这样其Value中就无需填写,即Value处就不会占用空间。
Tag Length Value
+------------------------------¦
¦ 05H ¦ 00H ¦
+------------------------------¦
INTEGER
该类型只能以原子式进行编码。整型分正数和负数两种情况,由于负数不应用于ASN.1话单文件,不加以详述。
对于正数,如果最高比特位为0,则直接编码;如果为1,则在最高比特位之前增加一个全0的八位数组(采用的是补码的方式存储)。如下示例250的编码:
Tag Length Value
+-------------------------------------¦
¦ 02H ¦ 02H ¦ 0000,0000 1111,1010¦
+-------------------------------------¦
ENUMERATED
该类型编码与INTEGER类型编码方式相同。
BIT STRING
该类型可以采用原子式或者结构式,下面以比特串'1011011101011'B为例,分别介绍以这两种方式进行编码。
Primitive
Tag Length Value
+------------------------------------------¦
¦ 03H ¦ 03H ¦ 03H 10110111 01011xxx¦
+------------------------------------------¦
注意在比特串'1011011101011'B之前增加了一个八位数组,取值为0~7,表征这个值最后补位的个数,主要是解决比特串可能不是8的倍数。
Constructed
采用结构式发送时,主要是有部分编码还不能确定时采用,比特串'1011011101011'B的编码如下:
Tag Length Value
+----------------------------------------------¦
¦ 03H ¦ 80H ¦ T L V
¦ ¦ 03H ¦ 02H ¦ 00H 10110111¦
¦ ¦ 03H ¦ 02H ¦ 03H 01011xxx¦
00H 00H
+-----------------------------------------------¦
注意:此处整个比特串的Length采用不定长编码。
OCTET STRING
该类型编码原则和BIT STRING编码原理一样,但由于该类型直接以八位组为单位,就不存在补位的情况。
SET
该类型采用constructed格式编码,其每个成员都是采用TLV格式编码。
以MOC {recordType ENUMERATED, callDuration INTEGER }:={ recordType 0,callDuration 11}为例:
Tag Length Value
+--------------------------------------------¦
¦ 16H ¦ 80H ¦ T L V
¦ ¦ 02H ¦ 01H ¦ 0000 0000¦
¦ ¦ 02H ¦ 01H ¦ 0000 1011¦
+--------------------------------------------¦
SEQUENCE
该类型与SET类型编码方式基本一样,只是其成员顺序要与定义保持一致,而SET类型无需如此。
SET OF
该类型编码与SET相同。
SEQUENCE OF
该类型编码与SEQUENCE相同。
其他的不常见的类型,在此不一一介绍。
1.2.4 结束符的编码规则
在定长编码结构中不存在,只有在不定长编码结构中存在,此处不加以详述。
1.2.5 话单文件的结构
一个话单文件是Sequence类型,采用TLV格式,其Valve部分由以下四部分组成:
第一部分是文件头部headerRecord,TAG是A0。
第二部分是话单内容,SEQUENCE OF表示可以由多张话单组成,callEventRecords的TAG值是A1。
第三部分是文件尾部trailerRecord,TAG值是A2。
第四部分是扩展,TAG值是A3,该部分没有内容,长度为0。
各个部分的TAG值和长度在文件中的位置如图1-3所示。
图1-3 话单文件的结构
以一张ASN.1话单文件为例,其二进制码流,如图1-4所示。
图1-4 ASN.1话单文件二进制码流解析
上图所对应的ASN.1文件:
ASN.1 BER编码
解码后的文本
record no.: 0
recordType: moCallRecord
servedIMSI: 460007001002000
servedMSISDN: (91)8613720012000
callingNumber: (91)8613720012000
calledNumber: (A1)13720012010
roamingNumber: (A1)136755002201
recordingEntity: (91)86136755002
mscIncomingROUTE: TO_BSC1
mscOutgoingROUTE: TO_BSC2
location: LAC-3001. CellID-0001
basicService: teleService(11)
msClassmark: 021C00
answerTime: 070809141502
releaseTime: 070809141513
callDuration: 11
radioChanRequested: fullRateChannel
radioChanUsed: halfRate
causeForTerm: normalRelease
diagnostics: gsm0408Cause(90)
callReference: 16 00 00 00 ED
additionalChgInfo: chargeIndicator-charge
networkcallReference: 16 05 A2 30 1B
mSCAddress: (91)86136755002
speechVersionSupported: 1
speechVersionUsed: 1
systemType: gERAN
chargedParty: callingParty
mscOutgoingCircuit: 1
orgRNCorBSCId: 01 0B
orgMSCId: 00 0B
callerDefaultEmlppPriority: EMLPP_CallPriorityLevel4(1)
globalAreaID: 64 F0 00 30 01 00 01
subscriberCategory: Common(A)
firstmccmnc: 64F000
lastmccmnc: 64F000
calledIMSI: 460007001002010
typeOfSubscribers:visiting
audioDataType:audio
disconnectparty:unknown