在线文档教程

4.内部形式及其编码 | 4. Internal form and its encodings

4内部形式及其编码

此版本的堆栈符合:

  • Megaco / H.248版本1(RFC3525)根据实施者指南版本10-13更新。

  • 根据Draft-ietf-megaco-h248v2-04定义的Megaco / H.248版本2根据实施者指南版本10-13更新。

  • 由ITU H.248.1(09/2005)定义的Megaco / H.248第3版.4.1消息的内部形式对于二进制和文本编码,我们使用相同的内部形式。我们的Megaco / H.248消息的内部形式受ASN.1编码器/解码器使用的内部格式的严重影响:

  • “序列”表示为列表。

  • “CHOICE”表示为大小为2的标记元组。

  • “序列”表示为记录,定义为“megaco/include/meaco”。[医]讯息[医]v1.hrl“。

  • “可选”表示为默认为'asn1_NOVALUE'的记录中的普通字段,表示该字段没有值。

  • “八进制字符串”表示为无符号整数的列表。

  • “枚举”表示为单个原子。

  • “位字符串”表示为原子列表。

  • “BOOLEAN”表示为原子“真”或“假”。

  • “整数”表示为整数。

  • “IA5String”表示为整数列表,其中每个整数是相应字符的ASCII值。

  • “NULL”被表示为原子'NULL'。

为了充分理解内部形式,您必须掌握Megaco / H.248协议的ASN.1规范,并应用上述规则。请参阅Erlang / OTP中ASN.1编译器的文档,了解ASN.1和相应内部表单之间映射语义的更多细节。

注意到'TerminationId'记录没有用在内部表格中。它已被替换为megaco_term_id记录(在“megaco / include / megaco.hrl”中定义)。

4.2不同的编码

Megaco / H.248标准定义了纯文本编码和二进制编码(ASN.1 BER),并且我们实现了两者的编码器和解码器。实际上我们提供五种不同的编码/解码模块。

在文本编码中,实现者可以选择使用短和长关键字的组合。也可以添加空格以提高可读性。我们对短信使用术语“紧凑”(compact),用尽可能短的关键字和没有可选的空格,术语“漂亮”(pretty)表示使用长关键字和缩进样式,如Megaco / H.248规范中的文本示例)。

下面是一个文本消息的示例,它给出了文本消息的漂亮版本和紧凑版本之间的区别。第一,漂亮的缩进版本,有长的关键字:

MEGACO/1 [124.124.124.222] Transaction = 9998 { Context = - { ServiceChange = ROOT { Services { Method = Restart, ServiceChangeAddress = 55555, Profile = ResGW/1, Reason = "901 Cold Boot" } } } }

然后是紧凑的版本,没有缩进和简短的关键字:

!/1 [124.124.124.222] T=9998{C=-{SC=ROOT{SV{MT=RS,AD=55555,PF=ResGW/1,RE="901 Cold Boot"}}}}

以及程序员对同一条消息的看法。首先构造一个ActionRequest记录列表,然后使用API中的一个Send函数发送它:

Prof = #'ServiceChangeProfile'{profileName = "resgw", version = 1}, Parm = #'ServiceChangeParm'{serviceChangeMethod = restart, serviceChangeAddress = {portNumber, 55555}, serviceChangeReason = "901 Cold Boot", serviceChangeProfile = Prof}, Req = #'ServiceChangeRequest'{terminationID = [?megaco_root_termination_id], serviceChangeParms = Parm}, Actions = [#'ActionRequest'{contextId = ?megaco_null_context_id, commandRequests = {serviceChangeReq, Req}}], megaco:call(ConnHandle, Actions, Config).

最后打印出整个内部形式:

{'MegacoMessage', asn1_NOVALUE, {'Message', 1, {ip4Address,{'IP4Address', [124,124,124,222], asn1_NOVALUE}}, {transactions, [ {transactionRequest, {'TransactionRequest', 9998, [{'ActionRequest', 0, asn1_NOVALUE, asn1_NOVALUE, [ {'CommandRequest', {serviceChangeReq, {'ServiceChangeRequest', [ {megaco_term_id, false, ["root"]}], {'ServiceChangeParm', restart, {portNumber, 55555}, asn1_NOVALUE, {'ServiceChangeProfile', "resgw", version = 1}, "901 MG Cold Boot", asn1_NOVALUE, asn1_NOVALUE, asn1_NOVALUE } } }, asn1_NOVALUE, asn1_NOVALUE } ] } ] } } ] } } }

提供了下列编码模块:

  • megaco_pretty_text_encoder - 将消息编码为漂亮的文本格式,对漂亮和紧凑的文本进行解码。

  • megaco_compact_text_encoder - 将消息编码为紧凑文本格式,可以同时对紧凑文本进行解码。

  • megaco_binary_encoder - 编码/解码ASN.1 BER消息。该编码器实现了最快的BER编码器/解码器。推荐的二进制编码。

  • megaco_ber_encoder - 编码/解码ASN.1 BER消息。

  • megaco_per_encoder - 编码/解码ASN.1 PER消息。注意这种格式不包含在Megaco标准中。

  • megaco_erl_dist_encoder - 将消息编码为Erlangs分发格式。它比较冗长,但编码和解码速度很快。注意这种格式不包含在Megaco标准中。

4.3配置Erlang分配编码模块

megaco_erl_dist_encoder模块的encoding_config可能是以下其中一个:

  • [] - 将消息编码为标准分发格式。它比较冗长,但编码和解码速度很快。

  • [megaco_compressed] - 在内部转换后将消息编码为标准分发格式。它不那么冗长,但是编码和解码的总时间会稍微慢一些(参见performance本章了解更多信息)。

  • [{megaco_compressed, Module}] - 以与megaco_compressed配置参数相同的方式工作,只有在这里用户提供他们自己的压缩模块。该模块必须执行该megaco_edist_compress行为。

  • [compressed] - 将消息编码为标准分发格式的压缩格式。它不那么冗长,但编码和解码将会更慢。

4.4文本编码模块的配置

当使用文本编码时,实际上有两种不同的配置控制使用什么软件:

  • [] - 空列表表示应使用erlang扫描器。

  • [{flex, port()}] - 解码时使用柔性扫描仪(不针对SMP进行优化)。查看initial configuration更多信息。

  • [{flex, ports()}] - 解码时使用柔性扫描器(针对SMP进行了优化)。参见initial configuration更多信息。Flex扫描仪是一种Megaco扫描仪,写成驱动程序链接(C语言)。有两种方法可以实现这一点:

  • 让Megaco堆栈启动Flex扫描器(加载驱动程序)。

为了实现这一点,必须配置Megaco堆栈:

- Add the `{scanner, flex}` (or similar) directive to an Erlang system config file for the megaco app (see [`initial configuration`](megaco_run#initial_config) chapter for details). - Retrieve the encoding-config using the [`system_info`](megaco#system_info) function (with `Item = text_config`).

- Update the receive handle with the encoding-config (the `encoding_config` field). 这样做的好处是,Megaco负责司机和港口的启动、持有和监督。Megaco客户端%28用户%29启动Flex扫描仪%28加载驱动程序%29。

启动柔性扫描仪时,会创建链接到驱动程序的端口。这个端口必须由一个进程拥有。这个过程不能死。如果有,端口也将终止。为此:

- Create a permanent process. Make sure this process is supervised (so that if it does die, this will be noticed). - Let this process start the flex scanner by calling the `megaco_flex_scanner:start/0,1` function.

- Retrieve the encoding-config and when initiating the `megaco_receive_handle`, set the field `encoding_config` accordingly. - Pass the `megaco_receive_handle` to the transport module.

4.5二进制编码模块的配置

使用二进制编码时,需要指定终结ID的结构。

  • [native]-跳过转换阶段,即解码后的消息%28s%29将不会转换为我们的内部形式。

  • [integer()] - 包含每个级别的大小(位数)的列表。例如:[3,8,5,8]

  • integer() - 一个字节(8位)级别的数量。NB这当前转换为以前的配置。例如:3([8,8,8]).4.6处理MEGACO versionsSince实现的版本3,在这个版本中的Megaco应用的,是初步的,有必要有一种方法来处理不同的版本3的实施方式。出于这个原因,编码配置选项{version3, version3()}已被引入。此选项,如果存在的话,必须先在编码配置列表。如果找到,版本1和2编解码器会忽略此选项。version3() - > prev3a | prev3b | prev3c | V3

  • prev3a

初稿第3版,基于TD-33

  • prev3b 初稿第3版,基于TD-33,但文本编码更新为最终解决方案contextProperty(与v2向后兼容)。

  • prev3c

初步版本3,基于v3标准的最终版本,但是不包括段数%21

  • v3 完整版3.包括分割。这是默认的版本3变体(即,如果版本3消息要被编码/解码并且没有找到版本3编码配置,则假定为v3)。有两种方式来处理不同的megaco编码版本。使用动态版本检测(仅适用于传入消息)或通过连接信息中的显式版本设置。对于传入消息:

  • 动态版本检测

将megaco_receive_handle中的协议版本设置为dynamic(这是默认值)。

这适用于那些支持版本,当前文本和ber_bin(megaco_binary_encodermegaco_ber_bin_encoder)的部分解码的编解码器。

这样解码器将检测使用哪个版本,然后使用正确的解码器。

  • 显式版本显式设置megaco_receive_handle中的实际协议版本。从版本1开始。执行初始服务更改并协商了版本2时,请将传输进程的megaco_receive_handle(control_pid)升级到版本2.请参阅megaco_tcpmegaco_udp。请注意,如果udp使用相同的传输过程,则可用于多个连接。这可能使升级变得不可能。对于不支持的版本部分解码的编解码器,目前megaco_ber_encodermegaco_per_encodermegaco_per_bin_encoderdynamic将恢复到版本1.对于传出消息:

  • 更新连接信息协议[医]版本。

  • 通过将项目添加{protocol_version, integer()}到选项来覆盖发送消息时的协议版本。参见callcast

请注意,这不会影响由堆栈自动发送的消息。他们使用连接信息的protocol_version。

4.7编码器回调函数

编码器回调接口由megaco_encoder行为定义,请参阅megaco_encoder