This version of the stack is compliant with:
We use the same internal form for both the binary and text encoding. Our internal form of Megaco/H.248 messages is heavily influenced by the internal format used by ASN.1 encoders/decoders:
In order to fully understand the internal form you must get hold on a ASN.1 specification for the Megaco/H.248 protocol, and apply the rules above. Please, see the documentation of the ASN.1 compiler in Erlang/OTP for more details of the semantics in mapping between ASN.1 and the corresponding internal form.
Observe that the 'TerminationId' record is not used in the internal form. It has been replaced with a megaco_term_id record (defined in "megaco/include/megaco.hrl").
The Megaco/H.248 standard defines both a plain text encoding and a binary encoding (ASN.1 BER) and we have implemented encoders and decoders for both. We do in fact supply five different encoding/decoding modules.
In the text encoding, implementors have the choice of using a mix of short and long keywords. It is also possible to add white spaces to improve readability. We use the term compact for text messages with the shortest possible keywords and no optional white spaces, and the term pretty for a well indented text format using long keywords and an indentation style like the text examples in the Megaco/H.248 specification).
Here follows an example of a text message to give a feeling of the difference between the pretty and compact versions of text messages. First the pretty, well indented version with long keywords:
MEGACO/1 [124.124.124.222] Transaction = 9998 { Context = - { ServiceChange = ROOT { Services { Method = Restart, ServiceChangeAddress = 55555, Profile = ResGW/1, Reason = "901 Cold Boot" } } } }
Then the compact version without indentation and with short keywords:
!/1 [124.124.124.222] T=9998{C=-{SC=ROOT{SV{MT=RS,AD=55555,PF=ResGW/1,RE="901 Cold Boot"}}}}
And the programmers view of the same message. First a list of ActionRequest records are constructed and then it is sent with one of the send functions in the API:
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).
And finally a print-out of the entire internal form:
{'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 } ] } ] } } ] } } }
The following encoding modules are provided:
The encoding_config of the megaco_erl_dist_encoder module may be one of these:
[]
- Encodes the messages to the standard distribution
format. It is rather verbose but encoding and decoding is
blinding fast.[megaco_compressed]
- Encodes the messages to the
standard distribution format after an internal transformation.
It is less verbose, but the total time of the encoding and
decoding will on the other hand be somewhat slower (see the
performance
chapter for more info).[{megaco_compressed, Module}]
- Works in the same
way as the megaco_compressed config parameter, only here the
user provide their own compress module. This module must
implement the
megaco_edist_compress
behaviour.[compressed]
- Encodes the messages to a compressed
form of the standard distribution format. It is less
verbose, but the encoding and decoding will on the other
hand be slower.When using text encoding(s), there is actually two different configs controlling what software to use:
[]
- An empty list indicates that the erlang
scanner should be used.[{flex, port()}]
- Use the flex scanner when
decoding.The Flex scanner is a Megaco scanner written as a linked in driver (in C). There are two ways to get this working:
{scanner, flex}
directive to an
Erlang system config file for the megaco app. This will
make the Megaco stack initiate the default
megaco_receive_handle
with the encoding_config set
to the [{flex, port()}]
. megaco_receive_handle
,
retain the encoding_config.megaco_flex_scanner:start()
function.port()
and when initiating
the megaco_receive_handle
, set the encoding_config to
[{flex, port()}].receive_handle
to the transport module.When using binary encoding, the structure of the termination id's needs to be specified.
[driver|_]
- make use of the asn1 driver for decode
(ber_bin) and encode (per_bin). This option is only available for
encoding modules: megaco_binary_encoder
,
megaco_ber_bin_encoder
and megaco_per_bin_encoder
.[{version3,prev3b},driver]
.[native]
- skips the transformation phase, i.e.
the decoded message(s) will not be transformed into our internal
form.[integer()]
- A list containing the size (the number
of bits) of each level. Example: [3,8,5,8]
.integer()
- Number of one byte (8 bits) levels.
N.B. This is currently converted into the previous config.
Example: 3
([8,8,8]
).Since the version 3 implemented, in this version of the Megaco
application, is preliminary, it is necessary to have a way
to handle different version 3 implementations. For this reason
the encoding config option {version3, version3()}
has been
introduced. This option, if present, has to be first in the
encoding config list. Version 1 and 2 codec's ignore this option, if
found.
version3() -> prev3a | prev3b | prev3c
contextProperty
(which is backward compatible with v2).
There are two ways to handle the different megaco encoding versions. Either using dynamic version detection (only valid for for incoming messages) or by explicit version setting in the connection info.
For incomming messages:
dynamic
(this is the default).
megaco_binary_encoder
and megaco_ber_bin_encoder
).
udp
is used, the same transport process
could be used for several connections. This could make upgrading
impossible.
megaco_ber_encoder
, megaco_per_encoder
and megaco_per_bin_encoder
, dynamic
will revert to
version 1.
For outgoing messages:
{protocol_version, integer()}
to the Options.
See
call or
cast.
The encoder callback interface is defined by the megaco_encoder
behaviour, see megaco_encoder.