aboutsummaryrefslogtreecommitdiffstats
path: root/lib/megaco/src/binary
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/megaco/src/binary
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/megaco/src/binary')
-rw-r--r--lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-prev3a.asn1001
-rw-r--r--lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-prev3b.asn1001
-rw-r--r--lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-prev3c.asn1073
-rw-r--r--lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-v1.asn982
-rw-r--r--lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-v2.asn966
-rw-r--r--lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-v3.asn1068
-rw-r--r--lib/megaco/src/binary/Makefile212
-rw-r--r--lib/megaco/src/binary/depend.mk557
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3a.asn1config43
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3a.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3b.asn1config43
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3b.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3c.asn1config43
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3c.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v1.asn1config44
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v1.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v2.asn1config43
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v2.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v3.asn1config43
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v3.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_encoder.erl716
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3a.asn1config43
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3a.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3b.asn1config43
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3b.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3c.asn1config43
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3c.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v1.asn1config44
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v1.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v2.asn1config43
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v2.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v3.asn1config43
-rw-r--r--lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v3.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_encoder.erl346
-rw-r--r--lib/megaco/src/binary/megaco_ber_media_gateway_control_prev3a.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_media_gateway_control_prev3b.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_media_gateway_control_prev3c.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_media_gateway_control_v1.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_media_gateway_control_v2.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_ber_media_gateway_control_v3.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_binary_encoder.erl588
-rw-r--r--lib/megaco/src/binary/megaco_binary_encoder_lib.erl317
-rw-r--r--lib/megaco/src/binary/megaco_binary_name_resolver_prev3a.erl2003
-rw-r--r--lib/megaco/src/binary/megaco_binary_name_resolver_prev3b.erl2003
-rw-r--r--lib/megaco/src/binary/megaco_binary_name_resolver_prev3c.erl2004
-rw-r--r--lib/megaco/src/binary/megaco_binary_name_resolver_v1.erl1613
-rw-r--r--lib/megaco/src/binary/megaco_binary_name_resolver_v2.erl1681
-rw-r--r--lib/megaco/src/binary/megaco_binary_name_resolver_v3.erl2016
-rw-r--r--lib/megaco/src/binary/megaco_binary_term_id.erl187
-rw-r--r--lib/megaco/src/binary/megaco_binary_term_id_gen.erl436
-rw-r--r--lib/megaco/src/binary/megaco_binary_transformer_prev3a.erl1629
-rw-r--r--lib/megaco/src/binary/megaco_binary_transformer_prev3b.erl1629
-rw-r--r--lib/megaco/src/binary/megaco_binary_transformer_prev3c.erl1756
-rw-r--r--lib/megaco/src/binary/megaco_binary_transformer_v1.erl1261
-rw-r--r--lib/megaco/src/binary/megaco_binary_transformer_v2.erl1544
-rw-r--r--lib/megaco/src/binary/megaco_binary_transformer_v3.erl1763
-rw-r--r--lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3a.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3b.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3c.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v1.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v2.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v3.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_bin_encoder.erl447
-rw-r--r--lib/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3a.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3b.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3c.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_bin_media_gateway_control_v1.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_bin_media_gateway_control_v2.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_bin_media_gateway_control_v3.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_encoder.erl291
-rw-r--r--lib/megaco/src/binary/megaco_per_media_gateway_control_prev3a.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_media_gateway_control_prev3b.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_media_gateway_control_prev3c.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_media_gateway_control_v1.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_media_gateway_control_v2.set.asn1
-rw-r--r--lib/megaco/src/binary/megaco_per_media_gateway_control_v3.set.asn1
-rw-r--r--lib/megaco/src/binary/modules.mk128
-rw-r--r--lib/megaco/src/binary/old/megaco_ber_bin_drv_encoder.erl319
-rw-r--r--lib/megaco/src/binary/old/megaco_per_bin_drv_encoder.erl255
79 files changed, 32346 insertions, 0 deletions
diff --git a/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-prev3a.asn b/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-prev3a.asn
new file mode 100644
index 0000000000..083f7e8271
--- /dev/null
+++ b/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-prev3a.asn
@@ -0,0 +1,1001 @@
+MEDIA-GATEWAY-CONTROL-prev3a
+{itu-t(0) recommendation(0) h(8) h248(248)
+ modules(0) media-gateway-control(0) version3(3)}
+DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+
+MegacoMessage ::= SEQUENCE
+ {
+ authHeader AuthenticationHeader OPTIONAL,
+ mess Message
+ }
+
+AuthenticationHeader ::= SEQUENCE
+ {
+ secParmIndex SecurityParmIndex,
+ seqNum SequenceNum,
+ ad AuthData
+ }
+
+SecurityParmIndex ::= OCTET STRING(SIZE(4))
+
+SequenceNum ::= OCTET STRING(SIZE(4))
+
+AuthData ::= OCTET STRING (SIZE (12..32))
+
+Message ::= SEQUENCE
+ {
+ version INTEGER(0..99),
+ -- The version of the protocol defined here is equal to 3.
+ mId MId, -- Name/address of message originator
+ messageBody CHOICE
+ {
+ messageError ErrorDescriptor,
+ transactions SEQUENCE OF Transaction
+ },
+ ...
+ }
+
+MId ::= CHOICE
+ {
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ -- Addressing structure of mtpAddress:
+ -- 25 - 15 0
+ -- | PC | NI |
+ -- 24 - 14 bits 2 bits
+ -- Note: 14 bits are defined for international use.
+ -- Two national options exist where the point code is 16 or 24
+ -- bits.
+ -- To octet align the mtpAddress, the MSBs shall be encoded as 0s.
+ ...
+ }
+
+DomainName ::= SEQUENCE
+ {
+ name IA5String,
+ -- The name starts with an alphanumeric digit followed by a
+ -- sequence of alphanumeric digits, hyphens and dots. No two
+ -- dots shall occur consecutively.
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+IP4Address ::= SEQUENCE
+ {
+ address OCTET STRING (SIZE(4)),
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+IP6Address ::= SEQUENCE
+ {
+ address OCTET STRING (SIZE(16)),
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+PathName ::= IA5String(SIZE (1..64))
+-- See A.3
+
+Transaction ::= CHOICE
+ {
+ transactionRequest TransactionRequest,
+ transactionPending TransactionPending,
+ transactionReply TransactionReply,
+ transactionResponseAck TransactionResponseAck,
+ -- use of response acks is dependent on underlying transport
+ ...
+ }
+
+TransactionId ::= INTEGER(0..4294967295) -- 32-bit unsigned integer
+
+TransactionRequest ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ actions SEQUENCE OF ActionRequest,
+ ...
+ }
+
+TransactionPending ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ ...
+ }
+
+TransactionReply ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ immAckRequired NULL OPTIONAL,
+ transactionResult CHOICE
+ {
+ transactionError ErrorDescriptor,
+ actionReplies SEQUENCE OF ActionReply
+ },
+ ...,
+ -- Erlang Note: NOT REALLY PART OF THIS IMPLEMENTATION
+ -- Erlang Note: The only reason why we need to include
+ -- Erlang Note: these definitions in this version is
+ -- Erlang Note: that we cannot distinguish between v3
+ -- Erlang Note: versions in the megaco_messenger module
+ segmentNumber SegmentNumber OPTIONAL,
+ segmentationComplete NULL OPTIONAL
+ }
+
+-- SegmentReply ::= SEQUENCE
+-- {
+-- transactionId TransactionId,
+-- segmentNumber SegmentNumber,
+-- segmentationComplete NULL OPTIONAL,
+-- ...
+-- }
+--
+SegmentNumber ::= INTEGER(0..65535)
+
+TransactionResponseAck ::= SEQUENCE OF TransactionAck
+TransactionAck ::= SEQUENCE
+ {
+ firstAck TransactionId,
+ lastAck TransactionId OPTIONAL
+ }
+
+ErrorDescriptor ::= SEQUENCE
+ {
+ errorCode ErrorCode,
+ errorText ErrorText OPTIONAL
+ }
+
+ErrorCode ::= INTEGER(0..65535)
+-- See clause 14 for IANA considerations with respect to error codes
+ErrorText ::= IA5String
+
+ContextID ::= INTEGER(0..4294967295)
+
+-- Context NULL Value: 0
+-- Context CHOOSE Value: 4294967294 (0xFFFFFFFE)
+-- Context ALL Value: 4294967295 (0xFFFFFFFF)
+
+
+ActionRequest ::= SEQUENCE
+ {
+ contextId ContextID,
+ contextRequest ContextRequest OPTIONAL,
+ contextAttrAuditReq ContextAttrAuditRequest OPTIONAL,
+ commandRequests SEQUENCE OF CommandRequest
+ }
+
+ActionReply ::= SEQUENCE
+ {
+ contextId ContextID,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ contextReply ContextRequest OPTIONAL,
+ commandReply SEQUENCE OF CommandReply
+ }
+
+ContextRequest ::= SEQUENCE
+ {
+ priority INTEGER(0..15) OPTIONAL,
+ emergency BOOLEAN OPTIONAL,
+ topologyReq SEQUENCE OF TopologyRequest OPTIONAL,
+ ...,
+ iepsCallind BOOLEAN OPTIONAL, -- Fixed
+ contextProp SEQUENCE OF PropertyParm OPTIONAL
+ }
+
+ContextAttrAuditRequest ::= SEQUENCE
+ {
+ topology NULL OPTIONAL,
+ emergency NULL OPTIONAL,
+ priority NULL OPTIONAL,
+ ...,
+ iepsCallind NULL OPTIONAL, -- Fixed
+ contextPropAud SEQUENCE OF IndAudPropertyParm OPTIONAL
+ }
+
+CommandRequest ::= SEQUENCE
+ {
+ command Command,
+ optional NULL OPTIONAL,
+ wildcardReturn NULL OPTIONAL,
+ ...
+ }
+
+Command ::= CHOICE
+ {
+ addReq AmmRequest,
+ moveReq AmmRequest,
+ modReq AmmRequest,
+ -- Add, Move, Modify requests have the same parameters
+ subtractReq SubtractRequest,
+ auditCapRequest AuditRequest,
+ auditValueRequest AuditRequest,
+ notifyReq NotifyRequest,
+ serviceChangeReq ServiceChangeRequest,
+ ...
+ }
+
+CommandReply ::= CHOICE
+ {
+ addReply AmmsReply,
+ moveReply AmmsReply,
+ modReply AmmsReply,
+ subtractReply AmmsReply,
+ -- Add, Move, Modify, Subtract replies have the same parameters
+ auditCapReply AuditReply,
+ auditValueReply AuditReply,
+ notifyReply NotifyReply,
+ serviceChangeReply ServiceChangeReply,
+ ...
+ }
+
+TopologyRequest ::= SEQUENCE
+ {
+ terminationFrom TerminationID,
+ terminationTo TerminationID,
+ topologyDirection ENUMERATED
+ {
+ bothway(0),
+ isolate(1),
+ oneway(2)
+ },
+ ...,
+ streamID StreamID OPTIONAL
+ }
+
+AmmRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ descriptors SEQUENCE OF AmmDescriptor,
+ -- At most one descriptor of each type (see AmmDescriptor)
+ -- allowed in the sequence.
+ ...
+ }
+
+AmmDescriptor ::= CHOICE
+ {
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ auditDescriptor AuditDescriptor,
+ ...,
+ statisticsDescriptor StatisticsDescriptor
+ }
+
+
+AmmsReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ terminationAudit TerminationAudit OPTIONAL,
+ ...
+ }
+
+SubtractRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ auditDescriptor AuditDescriptor OPTIONAL,
+ ...
+ }
+
+AuditRequest ::= SEQUENCE
+ {
+ terminationID TerminationID,
+ auditDescriptor AuditDescriptor,
+ ...
+ }
+
+AuditReply ::= CHOICE
+ {
+ contextAuditResult TerminationIDList,
+ error ErrorDescriptor,
+ auditResult AuditResult,
+ ...
+ }
+
+AuditResult ::= SEQUENCE
+ {
+
+ terminationID TerminationID,
+ terminationAuditResult TerminationAudit
+ }
+
+
+
+TerminationAudit ::= SEQUENCE OF AuditReturnParameter
+
+AuditReturnParameter ::= CHOICE
+ {
+ errorDescriptor ErrorDescriptor,
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ statisticsDescriptor StatisticsDescriptor,
+ packagesDescriptor PackagesDescriptor,
+ emptyDescriptors AuditDescriptor,
+ ...
+ }
+
+AuditDescriptor ::= SEQUENCE
+ {
+ auditToken BIT STRING
+ {
+ muxToken(0), modemToken(1), mediaToken(2),
+ eventsToken(3), signalsToken(4),
+ digitMapToken(5), statsToken(6),
+ observedEventsToken(7),
+ packagesToken(8), eventBufferToken(9)
+ } OPTIONAL,
+ ...,
+ auditPropertyToken SEQUENCE OF IndAuditParameter OPTIONAL
+ }
+
+
+IndAuditParameter ::= CHOICE
+ {
+ -- Note that the lower/upper case letters of the tags have
+ -- been changed. The same changes has been made in text...
+ indAudMediaDescriptor IndAudMediaDescriptor,
+ indAudEventsDescriptor IndAudEventsDescriptor,
+ indAudEventBufferDescriptor IndAudEventBufferDescriptor,
+ indAudSignalsDescriptor IndAudSignalsDescriptor,
+ indAudDigitMapDescriptor IndAudDigitMapDescriptor,
+ indAudStatisticsDescriptor IndAudStatisticsDescriptor,
+ indAudPackagesDescriptor IndAudPackagesDescriptor,
+ ...
+ }
+
+IndAudMediaDescriptor ::= SEQUENCE
+ {
+
+ termStateDescr IndAudTerminationStateDescriptor OPTIONAL,
+ streams CHOICE
+ {
+ oneStream IndAudStreamParms,
+ multiStream SEQUENCE OF IndAudStreamDescriptor
+ } OPTIONAL,
+ ...
+ }
+
+IndAudStreamDescriptor ::= SEQUENCE
+ {
+ streamID StreamID,
+ streamParms IndAudStreamParms
+ }
+
+IndAudStreamParms ::= SEQUENCE
+ {
+ localControlDescriptor IndAudLocalControlDescriptor OPTIONAL,
+ localDescriptor IndAudLocalRemoteDescriptor OPTIONAL,
+ remoteDescriptor IndAudLocalRemoteDescriptor OPTIONAL,
+ ...,
+ statisticsDescriptor IndAudStatisticsDescriptor OPTIONAL
+ }
+
+IndAudLocalControlDescriptor ::= SEQUENCE
+ {
+ streamMode NULL OPTIONAL,
+ reserveValue NULL OPTIONAL,
+ reserveGroup NULL OPTIONAL,
+ propertyParms SEQUENCE OF IndAudPropertyParm OPTIONAL,
+ ...
+ }
+
+IndAudPropertyParm ::= SEQUENCE
+ {
+ name PkgdName,
+ ...
+ }
+
+IndAudLocalRemoteDescriptor ::= SEQUENCE
+ {
+ propGroupID INTEGER(0..65535) OPTIONAL,
+ propGrps IndAudPropertyGroup,
+ ...
+ }
+
+IndAudPropertyGroup ::= SEQUENCE OF IndAudPropertyParm
+
+IndAudTerminationStateDescriptor ::= SEQUENCE
+ {
+ propertyParms SEQUENCE OF IndAudPropertyParm,
+ eventBufferControl NULL OPTIONAL,
+ serviceState NULL OPTIONAL,
+ ...
+ }
+
+IndAudEventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...
+ }
+
+IndAudEventBufferDescriptor ::= SEQUENCE
+ {
+ eventName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...
+ }
+
+IndAudSignalsDescriptor ::=CHOICE
+ {
+ signal IndAudSignal,
+ seqSigList IndAudSeqSigList,
+ ...
+ }
+
+IndAudSeqSigList ::= SEQUENCE
+ {
+ id INTEGER(0..65535),
+ signalList IndAudSignal OPTIONAL
+ }
+
+IndAudSignal ::= SEQUENCE
+ {
+ signalName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...
+ }
+
+IndAudDigitMapDescriptor ::= SEQUENCE
+ {
+ digitMapName DigitMapName OPTIONAL
+ }
+
+IndAudStatisticsDescriptor ::= SEQUENCE
+ {
+ statName PkgdName
+ }
+
+IndAudPackagesDescriptor ::= SEQUENCE
+ {
+ packageName Name,
+ packageVersion INTEGER(0..99),
+ ...
+ }
+
+NotifyRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+ }
+
+NotifyReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+ }
+
+ObservedEventsDescriptor ::= SEQUENCE
+ {
+ requestId RequestID,
+ observedEventLst SEQUENCE OF ObservedEvent
+ }
+
+ObservedEvent ::= SEQUENCE
+ {
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ timeNotation TimeNotation OPTIONAL,
+ ...
+ }
+
+EventName ::= PkgdName
+
+EventParameter ::= SEQUENCE
+ {
+ eventParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to PropertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+
+ }
+
+ServiceChangeRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ serviceChangeParms ServiceChangeParm,
+ ...
+ }
+
+ServiceChangeReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ serviceChangeResult ServiceChangeResult,
+ ...
+ }
+
+-- For ServiceChangeResult, no parameters are mandatory. Hence the
+-- distinction between ServiceChangeParm and ServiceChangeResParm.
+
+ServiceChangeResult ::= CHOICE
+ {
+ errorDescriptor ErrorDescriptor,
+ serviceChangeResParms ServiceChangeResParm
+ }
+
+WildcardField ::= OCTET STRING(SIZE(1))
+
+TerminationID ::= SEQUENCE
+ {
+ wildcard SEQUENCE OF WildcardField,
+ id OCTET STRING(SIZE(1..8)),
+ ...
+ }
+-- See A.1 for explanation of wildcarding mechanism.
+-- Termination ID 0xFFFFFFFFFFFFFFFF indicates the ROOT Termination.
+
+TerminationIDList ::= SEQUENCE OF TerminationID
+
+MediaDescriptor ::= SEQUENCE
+ {
+ termStateDescr TerminationStateDescriptor OPTIONAL,
+ streams CHOICE
+ {
+ oneStream StreamParms,
+ multiStream SEQUENCE OF StreamDescriptor
+ } OPTIONAL,
+ ...
+ }
+
+StreamDescriptor ::= SEQUENCE
+ {
+ streamID StreamID,
+ streamParms StreamParms
+ }
+
+StreamParms ::= SEQUENCE
+ {
+ localControlDescriptor LocalControlDescriptor OPTIONAL,
+ localDescriptor LocalRemoteDescriptor OPTIONAL,
+ remoteDescriptor LocalRemoteDescriptor OPTIONAL,
+ ...,
+ statisticsDescriptor StatisticsDescriptor OPTIONAL
+ }
+
+LocalControlDescriptor ::= SEQUENCE
+ {
+ streamMode StreamMode OPTIONAL,
+ reserveValue BOOLEAN OPTIONAL,
+ reserveGroup BOOLEAN OPTIONAL,
+ propertyParms SEQUENCE OF PropertyParm,
+ ...
+ }
+
+StreamMode ::= ENUMERATED
+ {
+ sendOnly(0),
+ recvOnly(1),
+ sendRecv(2),
+ inactive(3),
+ loopBack(4),
+ ...
+ }
+
+-- In PropertyParm, value is a SEQUENCE OF octet string. When sent
+-- by an MGC the interpretation is as follows:
+-- empty sequence means CHOOSE
+-- one element sequence specifies value
+-- If the sublist field is not selected, a longer sequence means
+-- "choose one of the values" (i.e. value1 OR value2 OR ...)
+-- If the sublist field is selected,
+-- a sequence with more than one element encodes the value of a
+-- list-valued property (i.e. value1 AND value2 AND ...).
+-- The relation field may only be selected if the value sequence
+-- has length 1. It indicates that the MG has to choose a value
+-- for the property. E.g. x > 3 (using the greaterThan
+-- value for relation) instructs the MG to choose any value larger
+-- than 3 for property x.
+-- The range field may only be selected if the value sequence
+-- has length 2. It indicates that the MG has to choose a value
+-- in the range between the first octet in the value sequence and
+-- the trailing octet in the value sequence, including the
+-- boundary values.
+-- When sent by the MG, only responses to an AuditCapability request
+-- may contain multiple values, a range, or a relation field.
+
+PropertyParm ::= SEQUENCE
+ {
+ name PkgdName,
+ value SEQUENCE OF OCTET STRING,
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+ }
+
+Name ::= OCTET STRING(SIZE(2))
+
+PkgdName ::= OCTET STRING(SIZE(4))
+-- represents Package Name (2 octets) plus Property, Event,
+-- Signal Names or Statistics ID. (2 octets)
+-- To wildcard a package use 0xFFFF for first two octets, choose
+-- is not allowed. To reference native property tag specified in
+-- Annex C, use 0x0000 as first two octets.
+-- To wildcard a Property, Event, Signal, or Statistics ID, use
+-- 0xFFFF for last two octets, choose is not allowed.
+-- Wildcarding of Package Name is permitted only if Property,
+-- Event, Signal, or Statistics ID are
+-- also wildcarded.
+
+Relation ::= ENUMERATED
+ {
+ greaterThan(0),
+ smallerThan(1),
+ unequalTo(2),
+ ...
+ }
+
+LocalRemoteDescriptor ::= SEQUENCE
+ {
+ propGrps SEQUENCE OF PropertyGroup,
+ ...
+ }
+
+PropertyGroup ::= SEQUENCE OF PropertyParm
+
+TerminationStateDescriptor ::= SEQUENCE
+ {
+ propertyParms SEQUENCE OF PropertyParm,
+ eventBufferControl EventBufferControl OPTIONAL,
+ serviceState ServiceState OPTIONAL,
+ ...
+ }
+
+EventBufferControl ::= ENUMERATED
+ {
+ off(0),
+ lockStep(1),
+ ...
+ }
+
+ServiceState ::= ENUMERATED
+ {
+ test(0),
+ outOfSvc(1),
+ inSvc(2),
+ ...
+ }
+
+MuxDescriptor ::= SEQUENCE
+ {
+ muxType MuxType,
+ termList SEQUENCE OF TerminationID,
+ nonStandardData NonStandardData OPTIONAL,
+ ...
+ }
+
+MuxType ::= ENUMERATED
+ {
+ h221(0),
+ h223(1),
+ h226(2),
+ v76(3),
+ ...,
+ nx64k(4)
+ }
+
+StreamID ::= INTEGER(0..65535) -- 16-bit unsigned integer
+
+EventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ -- RequestID must be present if eventList
+ -- is non empty
+ eventList SEQUENCE OF RequestedEvent,
+ ...
+ }
+
+RequestedEvent ::= SEQUENCE
+ {
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction RequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+RequestedActions ::= SEQUENCE
+ {
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ secondEvent SecondEventsDescriptor OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+ }
+
+EventDM ::= CHOICE
+ {
+ digitMapName DigitMapName,
+ digitMapValue DigitMapValue
+ }
+
+SecondEventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ eventList SEQUENCE OF SecondRequestedEvent,
+ ...
+ }
+
+SecondRequestedEvent ::= SEQUENCE
+ {
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction SecondRequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+SecondRequestedActions ::= SEQUENCE
+ {
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+ }
+
+EventBufferDescriptor ::= SEQUENCE OF EventSpec
+
+EventSpec ::= SEQUENCE
+ {
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+
+SignalsDescriptor ::= SEQUENCE OF SignalRequest
+
+SignalRequest ::= CHOICE
+ {
+ signal Signal,
+ seqSigList SeqSigList,
+ ...
+ }
+
+SeqSigList ::= SEQUENCE
+ {
+ id INTEGER(0..65535),
+ signalList SEQUENCE OF Signal
+ }
+
+Signal ::= SEQUENCE
+ {
+ signalName SignalName,
+ streamID StreamID OPTIONAL,
+ sigType SignalType OPTIONAL,
+ duration INTEGER (0..65535) OPTIONAL,
+ notifyCompletion NotifyCompletion OPTIONAL,
+ keepActive BOOLEAN OPTIONAL,
+ sigParList SEQUENCE OF SigParameter,
+ ...,
+ direction SignalDirection OPTIONAL,
+ requestID RequestID OPTIONAL
+ }
+
+SignalType ::= ENUMERATED
+ {
+ brief(0),
+ onOff(1),
+ timeOut(2),
+ ...
+ }
+
+SignalDirection ::= ENUMERATED
+ {
+ internal(0),
+ external(1),
+ both(3),
+ ...
+ }
+
+SignalName ::= PkgdName
+
+NotifyCompletion ::= BIT STRING
+ {
+ onTimeOut(0), onInterruptByEvent(1),
+ onInterruptByNewSignalDescr(2), otherReason(3)
+ }
+
+SigParameter ::= SEQUENCE
+ {
+ sigParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to PropertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+ }
+
+-- For an AuditCapReply with all events, the RequestID SHALL be ALL.
+-- ALL is represented by 0xffffffff.
+
+RequestID ::= INTEGER(0..4294967295) -- 32-bit unsigned integer
+
+ModemDescriptor ::= SEQUENCE
+ {
+ mtl SEQUENCE OF ModemType,
+ mpl SEQUENCE OF PropertyParm,
+ nonStandardData NonStandardData OPTIONAL
+ }
+
+ModemType ::= ENUMERATED
+ {
+ v18(0),
+ v22(1),
+ v22bis(2),
+ v32(3),
+ v32bis(4),
+ v34(5),
+ v90(6),
+ v91(7),
+ synchISDN(8),
+ ...
+ }
+
+DigitMapDescriptor ::= SEQUENCE
+ {
+ digitMapName DigitMapName OPTIONAL,
+ digitMapValue DigitMapValue OPTIONAL
+ }
+
+DigitMapName ::= Name
+
+DigitMapValue ::= SEQUENCE
+ {
+ startTimer INTEGER(0..99) OPTIONAL,
+ shortTimer INTEGER(0..99) OPTIONAL,
+ longTimer INTEGER(0..99) OPTIONAL,
+ digitMapBody IA5String,
+ -- Units are seconds for start, short and long timers, and
+ -- hundreds of milliseconds for duration timer. Thus start,
+ -- short, and long range from 1 to 99 seconds and duration
+ -- from 100 ms to 9.9 s
+ -- See A.3 for explanation of digit map syntax
+ ...,
+ durationTimer INTEGER (0..99) OPTIONAL
+ }
+
+ServiceChangeParm ::= SEQUENCE
+ {
+ serviceChangeMethod ServiceChangeMethod,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ serviceChangeReason Value,
+ -- A serviceChangeReason consists of a numeric reason code
+ -- and an optional text description.
+ -- The serviceChangeReason SHALL be a string consisting of
+ -- a decimal reason code, optionally followed by a single
+ -- space character and a textual description string.
+ -- This string is first BER-encoded as an IA5String.
+ -- The result of this BER-encoding is then encoded as
+ -- an ASN.1 OCTET STRING type, "double wrapping" the
+ -- value
+ -- as was done for package elements.
+ serviceChangeDelay INTEGER(0..4294967295) OPTIONAL,
+ -- 32-bit unsigned integer
+ serviceChangeMgcId MId OPTIONAL,
+ timeStamp TimeNotation OPTIONAL,
+ nonStandardData NonStandardData OPTIONAL,
+ ...,
+ serviceChangeInfo AuditDescriptor OPTIONAL,
+ serviceChangeIncompleteFlag NULL OPTIONAL
+ }
+
+ServiceChangeAddress ::= CHOICE
+ {
+ portNumber INTEGER(0..65535), -- TCP/UDP port number
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ ...
+ }
+
+ServiceChangeResParm ::= SEQUENCE
+ {
+ serviceChangeMgcId MId OPTIONAL,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ timestamp TimeNotation OPTIONAL,
+ ...
+ }
+
+ServiceChangeMethod ::= ENUMERATED
+ {
+ failover(0),
+ forced(1),
+ graceful(2),
+ restart(3),
+ disconnected(4),
+ handOff(5),
+ ...
+ }
+
+ServiceChangeProfile ::= SEQUENCE
+ {
+ profileName IA5String(SIZE (1..67))
+
+ -- 64 characters for name, 1 for "/", 2 for version to match ABNF
+ }
+
+PackagesDescriptor ::= SEQUENCE OF PackagesItem
+PackagesItem ::= SEQUENCE
+ {
+ packageName Name,
+ packageVersion INTEGER(0..99),
+ ...
+ }
+
+StatisticsDescriptor ::= SEQUENCE OF StatisticsParameter
+
+StatisticsParameter ::= SEQUENCE
+ {
+ statName PkgdName,
+ statValue Value OPTIONAL
+ }
+
+NonStandardData ::= SEQUENCE
+ {
+ nonStandardIdentifier NonStandardIdentifier,
+ data OCTET STRING
+ }
+
+NonStandardIdentifier ::= CHOICE
+ {
+ object OBJECT IDENTIFIER,
+ h221NonStandard H221NonStandard,
+ experimental IA5String(SIZE(8)),
+ -- first two characters SHOULD be "X-" or "X+"
+ ...
+ }
+
+H221NonStandard ::= SEQUENCE
+ { t35CountryCode1 INTEGER(0..255),
+ t35CountryCode2 INTEGER(0..255), -- country, as per T.35
+ t35Extension INTEGER(0..255), -- assigned nationally
+ manufacturerCode INTEGER(0..65535), -- assigned nationally
+ ...
+ }
+
+TimeNotation ::= SEQUENCE
+ {
+ date IA5String(SIZE(8)), -- yyyymmdd format
+ time IA5String(SIZE(8)) -- hhmmssss format
+ -- per ISO 8601:1988
+ }
+
+Value ::= SEQUENCE OF OCTET STRING
+
+END
diff --git a/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-prev3b.asn b/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-prev3b.asn
new file mode 100644
index 0000000000..1fb4d8fff2
--- /dev/null
+++ b/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-prev3b.asn
@@ -0,0 +1,1001 @@
+MEDIA-GATEWAY-CONTROL-prev3b
+{itu-t(0) recommendation(0) h(8) h248(248)
+ modules(0) media-gateway-control(0) version3(3)}
+DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+
+MegacoMessage ::= SEQUENCE
+ {
+ authHeader AuthenticationHeader OPTIONAL,
+ mess Message
+ }
+
+AuthenticationHeader ::= SEQUENCE
+ {
+ secParmIndex SecurityParmIndex,
+ seqNum SequenceNum,
+ ad AuthData
+ }
+
+SecurityParmIndex ::= OCTET STRING(SIZE(4))
+
+SequenceNum ::= OCTET STRING(SIZE(4))
+
+AuthData ::= OCTET STRING (SIZE (12..32))
+
+Message ::= SEQUENCE
+ {
+ version INTEGER(0..99),
+ -- The version of the protocol defined here is equal to 3.
+ mId MId, -- Name/address of message originator
+ messageBody CHOICE
+ {
+ messageError ErrorDescriptor,
+ transactions SEQUENCE OF Transaction
+ },
+ ...
+ }
+
+MId ::= CHOICE
+ {
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ -- Addressing structure of mtpAddress:
+ -- 25 - 15 0
+ -- | PC | NI |
+ -- 24 - 14 bits 2 bits
+ -- Note: 14 bits are defined for international use.
+ -- Two national options exist where the point code is 16 or 24
+ -- bits.
+ -- To octet align the mtpAddress, the MSBs shall be encoded as 0s.
+ ...
+ }
+
+DomainName ::= SEQUENCE
+ {
+ name IA5String,
+ -- The name starts with an alphanumeric digit followed by a
+ -- sequence of alphanumeric digits, hyphens and dots. No two
+ -- dots shall occur consecutively.
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+IP4Address ::= SEQUENCE
+ {
+ address OCTET STRING (SIZE(4)),
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+IP6Address ::= SEQUENCE
+ {
+ address OCTET STRING (SIZE(16)),
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+PathName ::= IA5String(SIZE (1..64))
+-- See A.3
+
+Transaction ::= CHOICE
+ {
+ transactionRequest TransactionRequest,
+ transactionPending TransactionPending,
+ transactionReply TransactionReply,
+ transactionResponseAck TransactionResponseAck,
+ -- use of response acks is dependent on underlying transport
+ ...
+ }
+
+TransactionId ::= INTEGER(0..4294967295) -- 32-bit unsigned integer
+
+TransactionRequest ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ actions SEQUENCE OF ActionRequest,
+ ...
+ }
+
+TransactionPending ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ ...
+ }
+
+TransactionReply ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ immAckRequired NULL OPTIONAL,
+ transactionResult CHOICE
+ {
+ transactionError ErrorDescriptor,
+ actionReplies SEQUENCE OF ActionReply
+ },
+ ...,
+ -- Erlang Note: NOT REALLY PART OF THIS IMPLEMENTATION
+ -- Erlang Note: The only reason why we need to include
+ -- Erlang Note: these definitions in this version is
+ -- Erlang Note: that we cannot distinguish between v3
+ -- Erlang Note: versions in the megaco_messenger module
+ segmentNumber SegmentNumber OPTIONAL,
+ segmentationComplete NULL OPTIONAL
+ }
+
+-- SegmentReply ::= SEQUENCE
+-- {
+-- transactionId TransactionId,
+-- segmentNumber SegmentNumber,
+-- segmentationComplete NULL OPTIONAL,
+-- ...
+-- }
+--
+SegmentNumber ::= INTEGER(0..65535)
+
+TransactionResponseAck ::= SEQUENCE OF TransactionAck
+TransactionAck ::= SEQUENCE
+ {
+ firstAck TransactionId,
+ lastAck TransactionId OPTIONAL
+ }
+
+ErrorDescriptor ::= SEQUENCE
+ {
+ errorCode ErrorCode,
+ errorText ErrorText OPTIONAL
+ }
+
+ErrorCode ::= INTEGER(0..65535)
+-- See clause 14 for IANA considerations with respect to error codes
+ErrorText ::= IA5String
+
+ContextID ::= INTEGER(0..4294967295)
+
+-- Context NULL Value: 0
+-- Context CHOOSE Value: 4294967294 (0xFFFFFFFE)
+-- Context ALL Value: 4294967295 (0xFFFFFFFF)
+
+
+ActionRequest ::= SEQUENCE
+ {
+ contextId ContextID,
+ contextRequest ContextRequest OPTIONAL,
+ contextAttrAuditReq ContextAttrAuditRequest OPTIONAL,
+ commandRequests SEQUENCE OF CommandRequest
+ }
+
+ActionReply ::= SEQUENCE
+ {
+ contextId ContextID,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ contextReply ContextRequest OPTIONAL,
+ commandReply SEQUENCE OF CommandReply
+ }
+
+ContextRequest ::= SEQUENCE
+ {
+ priority INTEGER(0..15) OPTIONAL,
+ emergency BOOLEAN OPTIONAL,
+ topologyReq SEQUENCE OF TopologyRequest OPTIONAL,
+ ...,
+ iepscallind BOOLEAN OPTIONAL,
+ contextProp SEQUENCE OF PropertyParm OPTIONAL
+ }
+
+ContextAttrAuditRequest ::= SEQUENCE
+ {
+ topology NULL OPTIONAL,
+ emergency NULL OPTIONAL,
+ priority NULL OPTIONAL,
+ ...,
+ iepscallind NULL OPTIONAL,
+ contextPropAud SEQUENCE OF IndAudPropertyParm OPTIONAL
+ }
+
+CommandRequest ::= SEQUENCE
+ {
+ command Command,
+ optional NULL OPTIONAL,
+ wildcardReturn NULL OPTIONAL,
+ ...
+ }
+
+Command ::= CHOICE
+ {
+ addReq AmmRequest,
+ moveReq AmmRequest,
+ modReq AmmRequest,
+ -- Add, Move, Modify requests have the same parameters
+ subtractReq SubtractRequest,
+ auditCapRequest AuditRequest,
+ auditValueRequest AuditRequest,
+ notifyReq NotifyRequest,
+ serviceChangeReq ServiceChangeRequest,
+ ...
+ }
+
+CommandReply ::= CHOICE
+ {
+ addReply AmmsReply,
+ moveReply AmmsReply,
+ modReply AmmsReply,
+ subtractReply AmmsReply,
+ -- Add, Move, Modify, Subtract replies have the same parameters
+ auditCapReply AuditReply,
+ auditValueReply AuditReply,
+ notifyReply NotifyReply,
+ serviceChangeReply ServiceChangeReply,
+ ...
+ }
+
+TopologyRequest ::= SEQUENCE
+ {
+ terminationFrom TerminationID,
+ terminationTo TerminationID,
+ topologyDirection ENUMERATED
+ {
+ bothway(0),
+ isolate(1),
+ oneway(2)
+ },
+ ...,
+ streamID StreamID OPTIONAL
+ }
+
+AmmRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ descriptors SEQUENCE OF AmmDescriptor,
+ -- At most one descriptor of each type (see AmmDescriptor)
+ -- allowed in the sequence.
+ ...
+ }
+
+AmmDescriptor ::= CHOICE
+ {
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ auditDescriptor AuditDescriptor,
+ ...,
+ statisticsDescriptor StatisticsDescriptor
+ }
+
+
+AmmsReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ terminationAudit TerminationAudit OPTIONAL,
+ ...
+ }
+
+SubtractRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ auditDescriptor AuditDescriptor OPTIONAL,
+ ...
+ }
+
+AuditRequest ::= SEQUENCE
+ {
+ terminationID TerminationID,
+ auditDescriptor AuditDescriptor,
+ ...
+ }
+
+AuditReply ::= CHOICE
+ {
+ contextAuditResult TerminationIDList,
+ error ErrorDescriptor,
+ auditResult AuditResult,
+ ...
+ }
+
+AuditResult ::= SEQUENCE
+ {
+
+ terminationID TerminationID,
+ terminationAuditResult TerminationAudit
+ }
+
+
+
+TerminationAudit ::= SEQUENCE OF AuditReturnParameter
+
+AuditReturnParameter ::= CHOICE
+ {
+ errorDescriptor ErrorDescriptor,
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ statisticsDescriptor StatisticsDescriptor,
+ packagesDescriptor PackagesDescriptor,
+ emptyDescriptors AuditDescriptor,
+ ...
+ }
+
+AuditDescriptor ::= SEQUENCE
+ {
+ auditToken BIT STRING
+ {
+ muxToken(0), modemToken(1), mediaToken(2),
+ eventsToken(3), signalsToken(4),
+ digitMapToken(5), statsToken(6),
+ observedEventsToken(7),
+ packagesToken(8), eventBufferToken(9)
+ } OPTIONAL,
+ ...,
+ auditPropertyToken SEQUENCE OF IndAuditParameter OPTIONAL
+ }
+
+
+IndAuditParameter ::= CHOICE
+ {
+ -- Note that the lower/upper case letters of the tags have
+ -- been changed. The same changes has been made in text...
+ indAudMediaDescriptor IndAudMediaDescriptor,
+ indAudEventsDescriptor IndAudEventsDescriptor,
+ indAudEventBufferDescriptor IndAudEventBufferDescriptor,
+ indAudSignalsDescriptor IndAudSignalsDescriptor,
+ indAudDigitMapDescriptor IndAudDigitMapDescriptor,
+ indAudStatisticsDescriptor IndAudStatisticsDescriptor,
+ indAudPackagesDescriptor IndAudPackagesDescriptor,
+ ...
+ }
+
+IndAudMediaDescriptor ::= SEQUENCE
+ {
+
+ termStateDescr IndAudTerminationStateDescriptor OPTIONAL,
+ streams CHOICE
+ {
+ oneStream IndAudStreamParms,
+ multiStream SEQUENCE OF IndAudStreamDescriptor
+ } OPTIONAL,
+ ...
+ }
+
+IndAudStreamDescriptor ::= SEQUENCE
+ {
+ streamID StreamID,
+ streamParms IndAudStreamParms
+ }
+
+IndAudStreamParms ::= SEQUENCE
+ {
+ localControlDescriptor IndAudLocalControlDescriptor OPTIONAL,
+ localDescriptor IndAudLocalRemoteDescriptor OPTIONAL,
+ remoteDescriptor IndAudLocalRemoteDescriptor OPTIONAL,
+ ...,
+ statisticsDescriptor IndAudStatisticsDescriptor OPTIONAL
+ }
+
+IndAudLocalControlDescriptor ::= SEQUENCE
+ {
+ streamMode NULL OPTIONAL,
+ reserveValue NULL OPTIONAL,
+ reserveGroup NULL OPTIONAL,
+ propertyParms SEQUENCE OF IndAudPropertyParm OPTIONAL,
+ ...
+ }
+
+IndAudPropertyParm ::= SEQUENCE
+ {
+ name PkgdName,
+ ...
+ }
+
+IndAudLocalRemoteDescriptor ::= SEQUENCE
+ {
+ propGroupID INTEGER(0..65535) OPTIONAL,
+ propGrps IndAudPropertyGroup,
+ ...
+ }
+
+IndAudPropertyGroup ::= SEQUENCE OF IndAudPropertyParm
+
+IndAudTerminationStateDescriptor ::= SEQUENCE
+ {
+ propertyParms SEQUENCE OF IndAudPropertyParm,
+ eventBufferControl NULL OPTIONAL,
+ serviceState NULL OPTIONAL,
+ ...
+ }
+
+IndAudEventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...
+ }
+
+IndAudEventBufferDescriptor ::= SEQUENCE
+ {
+ eventName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...
+ }
+
+IndAudSignalsDescriptor ::=CHOICE
+ {
+ signal IndAudSignal,
+ seqSigList IndAudSeqSigList,
+ ...
+ }
+
+IndAudSeqSigList ::= SEQUENCE
+ {
+ id INTEGER(0..65535),
+ signalList IndAudSignal OPTIONAL
+ }
+
+IndAudSignal ::= SEQUENCE
+ {
+ signalName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...
+ }
+
+IndAudDigitMapDescriptor ::= SEQUENCE
+ {
+ digitMapName DigitMapName OPTIONAL
+ }
+
+IndAudStatisticsDescriptor ::= SEQUENCE
+ {
+ statName PkgdName
+ }
+
+IndAudPackagesDescriptor ::= SEQUENCE
+ {
+ packageName Name,
+ packageVersion INTEGER(0..99),
+ ...
+ }
+
+NotifyRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+ }
+
+NotifyReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+ }
+
+ObservedEventsDescriptor ::= SEQUENCE
+ {
+ requestId RequestID,
+ observedEventLst SEQUENCE OF ObservedEvent
+ }
+
+ObservedEvent ::= SEQUENCE
+ {
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ timeNotation TimeNotation OPTIONAL,
+ ...
+ }
+
+EventName ::= PkgdName
+
+EventParameter ::= SEQUENCE
+ {
+ eventParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to PropertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+
+ }
+
+ServiceChangeRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ serviceChangeParms ServiceChangeParm,
+ ...
+ }
+
+ServiceChangeReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ serviceChangeResult ServiceChangeResult,
+ ...
+ }
+
+-- For ServiceChangeResult, no parameters are mandatory. Hence the
+-- distinction between ServiceChangeParm and ServiceChangeResParm.
+
+ServiceChangeResult ::= CHOICE
+ {
+ errorDescriptor ErrorDescriptor,
+ serviceChangeResParms ServiceChangeResParm
+ }
+
+WildcardField ::= OCTET STRING(SIZE(1))
+
+TerminationID ::= SEQUENCE
+ {
+ wildcard SEQUENCE OF WildcardField,
+ id OCTET STRING(SIZE(1..8)),
+ ...
+ }
+-- See A.1 for explanation of wildcarding mechanism.
+-- Termination ID 0xFFFFFFFFFFFFFFFF indicates the ROOT Termination.
+
+TerminationIDList ::= SEQUENCE OF TerminationID
+
+MediaDescriptor ::= SEQUENCE
+ {
+ termStateDescr TerminationStateDescriptor OPTIONAL,
+ streams CHOICE
+ {
+ oneStream StreamParms,
+ multiStream SEQUENCE OF StreamDescriptor
+ } OPTIONAL,
+ ...
+ }
+
+StreamDescriptor ::= SEQUENCE
+ {
+ streamID StreamID,
+ streamParms StreamParms
+ }
+
+StreamParms ::= SEQUENCE
+ {
+ localControlDescriptor LocalControlDescriptor OPTIONAL,
+ localDescriptor LocalRemoteDescriptor OPTIONAL,
+ remoteDescriptor LocalRemoteDescriptor OPTIONAL,
+ ...,
+ statisticsDescriptor StatisticsDescriptor OPTIONAL
+ }
+
+LocalControlDescriptor ::= SEQUENCE
+ {
+ streamMode StreamMode OPTIONAL,
+ reserveValue BOOLEAN OPTIONAL,
+ reserveGroup BOOLEAN OPTIONAL,
+ propertyParms SEQUENCE OF PropertyParm,
+ ...
+ }
+
+StreamMode ::= ENUMERATED
+ {
+ sendOnly(0),
+ recvOnly(1),
+ sendRecv(2),
+ inactive(3),
+ loopBack(4),
+ ...
+ }
+
+-- In PropertyParm, value is a SEQUENCE OF octet string. When sent
+-- by an MGC the interpretation is as follows:
+-- empty sequence means CHOOSE
+-- one element sequence specifies value
+-- If the sublist field is not selected, a longer sequence means
+-- "choose one of the values" (i.e. value1 OR value2 OR ...)
+-- If the sublist field is selected,
+-- a sequence with more than one element encodes the value of a
+-- list-valued property (i.e. value1 AND value2 AND ...).
+-- The relation field may only be selected if the value sequence
+-- has length 1. It indicates that the MG has to choose a value
+-- for the property. E.g. x > 3 (using the greaterThan
+-- value for relation) instructs the MG to choose any value larger
+-- than 3 for property x.
+-- The range field may only be selected if the value sequence
+-- has length 2. It indicates that the MG has to choose a value
+-- in the range between the first octet in the value sequence and
+-- the trailing octet in the value sequence, including the
+-- boundary values.
+-- When sent by the MG, only responses to an AuditCapability request
+-- may contain multiple values, a range, or a relation field.
+
+PropertyParm ::= SEQUENCE
+ {
+ name PkgdName,
+ value SEQUENCE OF OCTET STRING,
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+ }
+
+Name ::= OCTET STRING(SIZE(2))
+
+PkgdName ::= OCTET STRING(SIZE(4))
+-- represents Package Name (2 octets) plus Property, Event,
+-- Signal Names or Statistics ID. (2 octets)
+-- To wildcard a package use 0xFFFF for first two octets, choose
+-- is not allowed. To reference native property tag specified in
+-- Annex C, use 0x0000 as first two octets.
+-- To wildcard a Property, Event, Signal, or Statistics ID, use
+-- 0xFFFF for last two octets, choose is not allowed.
+-- Wildcarding of Package Name is permitted only if Property,
+-- Event, Signal, or Statistics ID are
+-- also wildcarded.
+
+Relation ::= ENUMERATED
+ {
+ greaterThan(0),
+ smallerThan(1),
+ unequalTo(2),
+ ...
+ }
+
+LocalRemoteDescriptor ::= SEQUENCE
+ {
+ propGrps SEQUENCE OF PropertyGroup,
+ ...
+ }
+
+PropertyGroup ::= SEQUENCE OF PropertyParm
+
+TerminationStateDescriptor ::= SEQUENCE
+ {
+ propertyParms SEQUENCE OF PropertyParm,
+ eventBufferControl EventBufferControl OPTIONAL,
+ serviceState ServiceState OPTIONAL,
+ ...
+ }
+
+EventBufferControl ::= ENUMERATED
+ {
+ off(0),
+ lockStep(1),
+ ...
+ }
+
+ServiceState ::= ENUMERATED
+ {
+ test(0),
+ outOfSvc(1),
+ inSvc(2),
+ ...
+ }
+
+MuxDescriptor ::= SEQUENCE
+ {
+ muxType MuxType,
+ termList SEQUENCE OF TerminationID,
+ nonStandardData NonStandardData OPTIONAL,
+ ...
+ }
+
+MuxType ::= ENUMERATED
+ {
+ h221(0),
+ h223(1),
+ h226(2),
+ v76(3),
+ ...,
+ nx64k(4)
+ }
+
+StreamID ::= INTEGER(0..65535) -- 16-bit unsigned integer
+
+EventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ -- RequestID must be present if eventList
+ -- is non empty
+ eventList SEQUENCE OF RequestedEvent,
+ ...
+ }
+
+RequestedEvent ::= SEQUENCE
+ {
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction RequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+RequestedActions ::= SEQUENCE
+ {
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ secondEvent SecondEventsDescriptor OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+ }
+
+EventDM ::= CHOICE
+ {
+ digitMapName DigitMapName,
+ digitMapValue DigitMapValue
+ }
+
+SecondEventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ eventList SEQUENCE OF SecondRequestedEvent,
+ ...
+ }
+
+SecondRequestedEvent ::= SEQUENCE
+ {
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction SecondRequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+SecondRequestedActions ::= SEQUENCE
+ {
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+ }
+
+EventBufferDescriptor ::= SEQUENCE OF EventSpec
+
+EventSpec ::= SEQUENCE
+ {
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+
+SignalsDescriptor ::= SEQUENCE OF SignalRequest
+
+SignalRequest ::= CHOICE
+ {
+ signal Signal,
+ seqSigList SeqSigList,
+ ...
+ }
+
+SeqSigList ::= SEQUENCE
+ {
+ id INTEGER(0..65535),
+ signalList SEQUENCE OF Signal
+ }
+
+Signal ::= SEQUENCE
+ {
+ signalName SignalName,
+ streamID StreamID OPTIONAL,
+ sigType SignalType OPTIONAL,
+ duration INTEGER (0..65535) OPTIONAL,
+ notifyCompletion NotifyCompletion OPTIONAL,
+ keepActive BOOLEAN OPTIONAL,
+ sigParList SEQUENCE OF SigParameter,
+ ...,
+ direction SignalDirection OPTIONAL,
+ requestID RequestID OPTIONAL
+ }
+
+SignalType ::= ENUMERATED
+ {
+ brief(0),
+ onOff(1),
+ timeOut(2),
+ ...
+ }
+
+SignalDirection ::= ENUMERATED
+ {
+ internal(0),
+ external(1),
+ both(3),
+ ...
+ }
+
+SignalName ::= PkgdName
+
+NotifyCompletion ::= BIT STRING
+ {
+ onTimeOut(0), onInterruptByEvent(1),
+ onInterruptByNewSignalDescr(2), otherReason(3)
+ }
+
+SigParameter ::= SEQUENCE
+ {
+ sigParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to PropertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+ }
+
+-- For an AuditCapReply with all events, the RequestID SHALL be ALL.
+-- ALL is represented by 0xffffffff.
+
+RequestID ::= INTEGER(0..4294967295) -- 32-bit unsigned integer
+
+ModemDescriptor ::= SEQUENCE
+ {
+ mtl SEQUENCE OF ModemType,
+ mpl SEQUENCE OF PropertyParm,
+ nonStandardData NonStandardData OPTIONAL
+ }
+
+ModemType ::= ENUMERATED
+ {
+ v18(0),
+ v22(1),
+ v22bis(2),
+ v32(3),
+ v32bis(4),
+ v34(5),
+ v90(6),
+ v91(7),
+ synchISDN(8),
+ ...
+ }
+
+DigitMapDescriptor ::= SEQUENCE
+ {
+ digitMapName DigitMapName OPTIONAL,
+ digitMapValue DigitMapValue OPTIONAL
+ }
+
+DigitMapName ::= Name
+
+DigitMapValue ::= SEQUENCE
+ {
+ startTimer INTEGER(0..99) OPTIONAL,
+ shortTimer INTEGER(0..99) OPTIONAL,
+ longTimer INTEGER(0..99) OPTIONAL,
+ digitMapBody IA5String,
+ -- Units are seconds for start, short and long timers, and
+ -- hundreds of milliseconds for duration timer. Thus start,
+ -- short, and long range from 1 to 99 seconds and duration
+ -- from 100 ms to 9.9 s
+ -- See A.3 for explanation of digit map syntax
+ ...,
+ durationTimer INTEGER (0..99) OPTIONAL
+ }
+
+ServiceChangeParm ::= SEQUENCE
+ {
+ serviceChangeMethod ServiceChangeMethod,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ serviceChangeReason Value,
+ -- A serviceChangeReason consists of a numeric reason code
+ -- and an optional text description.
+ -- The serviceChangeReason SHALL be a string consisting of
+ -- a decimal reason code, optionally followed by a single
+ -- space character and a textual description string.
+ -- This string is first BER-encoded as an IA5String.
+ -- The result of this BER-encoding is then encoded as
+ -- an ASN.1 OCTET STRING type, "double wrapping" the
+ -- value
+ -- as was done for package elements.
+ serviceChangeDelay INTEGER(0..4294967295) OPTIONAL,
+ -- 32-bit unsigned integer
+ serviceChangeMgcId MId OPTIONAL,
+ timeStamp TimeNotation OPTIONAL,
+ nonStandardData NonStandardData OPTIONAL,
+ ...,
+ serviceChangeInfo AuditDescriptor OPTIONAL,
+ serviceChangeIncompleteFlag NULL OPTIONAL
+ }
+
+ServiceChangeAddress ::= CHOICE
+ {
+ portNumber INTEGER(0..65535), -- TCP/UDP port number
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ ...
+ }
+
+ServiceChangeResParm ::= SEQUENCE
+ {
+ serviceChangeMgcId MId OPTIONAL,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ timestamp TimeNotation OPTIONAL,
+ ...
+ }
+
+ServiceChangeMethod ::= ENUMERATED
+ {
+ failover(0),
+ forced(1),
+ graceful(2),
+ restart(3),
+ disconnected(4),
+ handOff(5),
+ ...
+ }
+
+ServiceChangeProfile ::= SEQUENCE
+ {
+ profileName IA5String(SIZE (1..67))
+
+ -- 64 characters for name, 1 for "/", 2 for version to match ABNF
+ }
+
+PackagesDescriptor ::= SEQUENCE OF PackagesItem
+PackagesItem ::= SEQUENCE
+ {
+ packageName Name,
+ packageVersion INTEGER(0..99),
+ ...
+ }
+
+StatisticsDescriptor ::= SEQUENCE OF StatisticsParameter
+
+StatisticsParameter ::= SEQUENCE
+ {
+ statName PkgdName,
+ statValue Value OPTIONAL
+ }
+
+NonStandardData ::= SEQUENCE
+ {
+ nonStandardIdentifier NonStandardIdentifier,
+ data OCTET STRING
+ }
+
+NonStandardIdentifier ::= CHOICE
+ {
+ object OBJECT IDENTIFIER,
+ h221NonStandard H221NonStandard,
+ experimental IA5String(SIZE(8)),
+ -- first two characters SHOULD be "X-" or "X+"
+ ...
+ }
+
+H221NonStandard ::= SEQUENCE
+ { t35CountryCode1 INTEGER(0..255),
+ t35CountryCode2 INTEGER(0..255), -- country, as per T.35
+ t35Extension INTEGER(0..255), -- assigned nationally
+ manufacturerCode INTEGER(0..65535), -- assigned nationally
+ ...
+ }
+
+TimeNotation ::= SEQUENCE
+ {
+ date IA5String(SIZE(8)), -- yyyymmdd format
+ time IA5String(SIZE(8)) -- hhmmssss format
+ -- per ISO 8601:1988
+ }
+
+Value ::= SEQUENCE OF OCTET STRING
+
+END
diff --git a/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-prev3c.asn b/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-prev3c.asn
new file mode 100644
index 0000000000..cb6940e8b0
--- /dev/null
+++ b/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-prev3c.asn
@@ -0,0 +1,1073 @@
+MEDIA-GATEWAY-CONTROL-prev3c
+{itu-t(0) recommendation(0) h(8) h248(248)
+ modules(0) media-gateway-control(0) version3(3)}
+DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+
+MegacoMessage ::= SEQUENCE
+ {
+ authHeader AuthenticationHeader OPTIONAL,
+ mess Message
+ }
+
+AuthenticationHeader ::= SEQUENCE
+ {
+ secParmIndex SecurityParmIndex,
+ seqNum SequenceNum,
+ ad AuthData
+ }
+
+SecurityParmIndex ::= OCTET STRING(SIZE(4))
+
+SequenceNum ::= OCTET STRING(SIZE(4))
+
+AuthData ::= OCTET STRING (SIZE (12..32))
+
+Message ::= SEQUENCE
+ {
+ version INTEGER(0..99),
+ -- The version of the protocol defined here is equal to 3.
+ mId MId, -- Name/address of message originator
+ messageBody CHOICE
+ {
+ messageError ErrorDescriptor,
+ transactions SEQUENCE OF Transaction
+ },
+ ...
+ }
+
+MId ::= CHOICE
+ {
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ -- Addressing structure of mtpAddress:
+ -- 25 - 15 0
+ -- | PC | NI |
+ -- 24 - 14 bits 2 bits
+ -- Note: 14 bits are defined for international use.
+ -- Two national options exist where the point code is 16 or 24
+ -- bits.
+ -- To octet align the mtpAddress, the MSBs shall be encoded as 0s.
+ ...
+ }
+
+DomainName ::= SEQUENCE
+ {
+ name IA5String,
+ -- The name starts with an alphanumeric digit followed by a
+ -- sequence of alphanumeric digits, hyphens and dots. No two
+ -- dots shall occur consecutively.
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+IP4Address ::= SEQUENCE
+ {
+ address OCTET STRING (SIZE(4)),
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+IP6Address ::= SEQUENCE
+ {
+ address OCTET STRING (SIZE(16)),
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+PathName ::= IA5String(SIZE (1..64))
+-- See A.3
+
+Transaction ::= CHOICE
+ {
+ transactionRequest TransactionRequest,
+ transactionPending TransactionPending,
+ transactionReply TransactionReply,
+ transactionResponseAck TransactionResponseAck,
+ -- use of response acks is dependent on underlying transport
+ ...
+ -- segmentReply SegmentReply
+ }
+
+TransactionId ::= INTEGER(0..4294967295) -- 32-bit unsigned integer
+
+TransactionRequest ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ actions SEQUENCE OF ActionRequest,
+ ...
+ }
+
+TransactionPending ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ ...
+ }
+
+TransactionReply ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ immAckRequired NULL OPTIONAL,
+ transactionResult CHOICE
+ {
+ transactionError ErrorDescriptor,
+ actionReplies SEQUENCE OF ActionReply
+ },
+ ...,
+ -- Erlang Note: NOT REALLY PART OF THIS IMPLEMENTATION
+ -- Erlang Note: The only reason why we need to include
+ -- Erlang Note: these definitions in this version is
+ -- Erlang Note: that we cannot distinguish between v3
+ -- Erlang Note: versions in the megaco_messenger module
+ segmentNumber SegmentNumber OPTIONAL,
+ segmentationComplete NULL OPTIONAL
+ }
+
+-- SegmentReply ::= SEQUENCE
+-- {
+-- transactionId TransactionId,
+-- segmentNumber SegmentNumber,
+-- segmentationComplete NULL OPTIONAL,
+-- ...
+-- }
+--
+SegmentNumber ::= INTEGER(0..65535)
+
+TransactionResponseAck ::= SEQUENCE OF TransactionAck
+TransactionAck ::= SEQUENCE
+ {
+ firstAck TransactionId,
+ lastAck TransactionId OPTIONAL
+ }
+
+ErrorDescriptor ::= SEQUENCE
+ {
+ errorCode ErrorCode,
+ errorText ErrorText OPTIONAL
+ }
+
+ErrorCode ::= INTEGER(0..65535)
+-- See clause 14 for IANA considerations with respect to error codes
+ErrorText ::= IA5String
+
+ContextID ::= INTEGER(0..4294967295)
+-- Context NULL Value: 0
+-- Context CHOOSE Value: 4294967294 (0xFFFFFFFE)
+-- Context ALL Value: 4294967295 (0xFFFFFFFF)
+
+
+ActionRequest ::= SEQUENCE
+ {
+ contextId ContextID,
+ contextRequest ContextRequest OPTIONAL,
+ contextAttrAuditReq ContextAttrAuditRequest OPTIONAL,
+ commandRequests SEQUENCE OF CommandRequest
+ }
+
+ActionReply ::= SEQUENCE
+ {
+ contextId ContextID,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ contextReply ContextRequest OPTIONAL,
+ commandReply SEQUENCE OF CommandReply
+ }
+
+ContextRequest ::= SEQUENCE
+ {
+ priority INTEGER(0..15) OPTIONAL,
+ emergency BOOLEAN OPTIONAL,
+ topologyReq SEQUENCE OF TopologyRequest OPTIONAL,
+ ...,
+ iepscallind BOOLEAN OPTIONAL,
+ contextProp SEQUENCE OF PropertyParm OPTIONAL,
+ contextList SEQUENCE OF ContextID OPTIONAL
+ }
+-- When returning a contextList, the contextId in the ActionReply
+-- construct will return the contextId from the associated ActionRequest.
+
+ContextAttrAuditRequest ::= SEQUENCE
+ {
+ topology NULL OPTIONAL,
+ emergency NULL OPTIONAL,
+ priority NULL OPTIONAL,
+ ...,
+ iepscallind NULL OPTIONAL,
+ contextPropAud SEQUENCE OF IndAudPropertyParm OPTIONAL,
+
+ selectpriority INTEGER(0..15) OPTIONAL,
+ -- to select given priority
+
+ selectemergency BOOLEAN OPTIONAL,
+ -- to select if emergency set/not set (T/F)
+
+ selectiepscallind BOOLEAN OPTIONAL,
+ -- to select if IEPS set/not set (T/F)
+
+ selectLogic SelectLogic OPTIONAL -- default is AND
+ }
+
+SelectLogic ::= CHOICE
+ {
+ andAUDITSelect NULL, -- all selection conditions satisfied
+ orAUDITSelect NULL, -- at least one selection condition satisfied
+ ...
+ }
+
+
+CommandRequest ::= SEQUENCE
+ {
+ command Command,
+ optional NULL OPTIONAL,
+ wildcardReturn NULL OPTIONAL,
+ ...
+ }
+
+Command ::= CHOICE
+ {
+ addReq AmmRequest,
+ moveReq AmmRequest,
+ modReq AmmRequest,
+ -- Add, Move, Modify requests have the same parameters
+ subtractReq SubtractRequest,
+ auditCapRequest AuditRequest,
+ auditValueRequest AuditRequest,
+ notifyReq NotifyRequest,
+ serviceChangeReq ServiceChangeRequest,
+ ...
+ }
+
+CommandReply ::= CHOICE
+ {
+ addReply AmmsReply,
+ moveReply AmmsReply,
+ modReply AmmsReply,
+ subtractReply AmmsReply,
+ -- Add, Move, Modify, Subtract replies have the same parameters
+ auditCapReply AuditReply,
+ auditValueReply AuditReply,
+ notifyReply NotifyReply,
+ serviceChangeReply ServiceChangeReply,
+ ...
+ }
+
+TopologyRequest ::= SEQUENCE
+ {
+ terminationFrom TerminationID,
+ terminationTo TerminationID,
+ topologyDirection ENUMERATED
+ {
+ bothway(0),
+ isolate(1),
+ oneway(2)
+ },
+ ...,
+ streamID StreamID OPTIONAL,
+ topologyDirectionExtension ENUMERATED
+ {
+ onewayexternal(0),
+ onewayboth(1),
+ ...
+ } OPTIONAL
+ -- This is not according to the standard, but without it
+ -- the TopologyRequest will be useless since topologyDirection
+ -- and topologyDirectionExtension are contradictory.
+ }
+
+AmmRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ descriptors SEQUENCE OF AmmDescriptor,
+ -- At most one descriptor of each type (see AmmDescriptor)
+ -- allowed in the sequence.
+ ...
+ }
+
+AmmDescriptor ::= CHOICE
+ {
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ auditDescriptor AuditDescriptor,
+ ...,
+ statisticsDescriptor StatisticsDescriptor
+ }
+
+
+AmmsReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ terminationAudit TerminationAudit OPTIONAL,
+ ...
+ }
+
+SubtractRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ auditDescriptor AuditDescriptor OPTIONAL,
+ ...
+ }
+
+AuditRequest ::= SEQUENCE
+ {
+ terminationID TerminationID,
+ auditDescriptor AuditDescriptor,
+ ...,
+ terminationIDList TerminationIDList OPTIONAL
+ }
+-- terminationID shall contain the first termination in the
+-- list when using the terminationIDList construct in AuditRequest
+
+AuditReply ::= CHOICE
+ {
+ contextAuditResult TerminationIDList,
+ error ErrorDescriptor,
+ auditResult AuditResult,
+ ...,
+ auditResultTermList TermListAuditResult
+ }
+
+AuditResult ::= SEQUENCE
+ {
+
+ terminationID TerminationID,
+ terminationAuditResult TerminationAudit
+ }
+
+TermListAuditResult ::= SEQUENCE
+ {
+ terminationIDList TerminationIDList,
+ terminationAuditResult TerminationAudit,
+ ...
+ }
+
+TerminationAudit ::= SEQUENCE OF AuditReturnParameter
+
+AuditReturnParameter ::= CHOICE
+ {
+ errorDescriptor ErrorDescriptor,
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ statisticsDescriptor StatisticsDescriptor,
+ packagesDescriptor PackagesDescriptor,
+ emptyDescriptors AuditDescriptor,
+ ...
+ }
+
+AuditDescriptor ::= SEQUENCE
+ {
+ auditToken BIT STRING
+ {
+ muxToken(0), modemToken(1), mediaToken(2),
+ eventsToken(3), signalsToken(4),
+ digitMapToken(5), statsToken(6),
+ observedEventsToken(7),
+ packagesToken(8), eventBufferToken(9)
+ } OPTIONAL,
+ ...,
+ auditPropertyToken SEQUENCE OF IndAuditParameter OPTIONAL
+ }
+
+
+IndAuditParameter ::= CHOICE
+ {
+ -- Note that the lower/upper case letters of the tags have
+ -- been changed. The same changes has been made in text...
+ indAudMediaDescriptor IndAudMediaDescriptor,
+ indAudEventsDescriptor IndAudEventsDescriptor,
+ indAudEventBufferDescriptor IndAudEventBufferDescriptor,
+ indAudSignalsDescriptor IndAudSignalsDescriptor,
+ indAudDigitMapDescriptor IndAudDigitMapDescriptor,
+ indAudStatisticsDescriptor IndAudStatisticsDescriptor,
+ indAudPackagesDescriptor IndAudPackagesDescriptor,
+ ...
+ }
+
+IndAudMediaDescriptor ::= SEQUENCE
+ {
+
+ termStateDescr IndAudTerminationStateDescriptor OPTIONAL,
+ streams CHOICE
+ {
+ oneStream IndAudStreamParms,
+ multiStream SEQUENCE OF IndAudStreamDescriptor
+ } OPTIONAL,
+ ...
+ }
+
+IndAudStreamDescriptor ::= SEQUENCE
+ {
+ streamID StreamID,
+ streamParms IndAudStreamParms
+ }
+
+IndAudStreamParms ::= SEQUENCE
+ {
+ localControlDescriptor IndAudLocalControlDescriptor OPTIONAL,
+ localDescriptor IndAudLocalRemoteDescriptor OPTIONAL,
+ remoteDescriptor IndAudLocalRemoteDescriptor OPTIONAL,
+ ...,
+ statisticsDescriptor IndAudStatisticsDescriptor OPTIONAL
+ }
+
+IndAudLocalControlDescriptor ::= SEQUENCE
+ {
+ streamMode NULL OPTIONAL,
+ reserveValue NULL OPTIONAL,
+ reserveGroup NULL OPTIONAL,
+ propertyParms SEQUENCE OF IndAudPropertyParm OPTIONAL,
+ ...,
+ streamModeSel StreamMode OPTIONAL
+ -- must not have both streamMode and streamModeSel
+ -- if both are present only streamModeSel shall be honoured
+ }
+
+IndAudPropertyParm ::= SEQUENCE
+ {
+ name PkgdName,
+ ...,
+ propertyParms PropertyParm OPTIONAL
+ }
+-- to select based on property values
+-- AND/OR selection logic is specified at context level
+
+IndAudLocalRemoteDescriptor ::= SEQUENCE
+ {
+ propGroupID INTEGER(0..65535) OPTIONAL,
+ propGrps IndAudPropertyGroup,
+ ...
+ }
+
+IndAudPropertyGroup ::= SEQUENCE OF IndAudPropertyParm
+
+IndAudTerminationStateDescriptor ::= SEQUENCE
+ {
+ propertyParms SEQUENCE OF IndAudPropertyParm,
+ eventBufferControl NULL OPTIONAL,
+ serviceState NULL OPTIONAL,
+ ...,
+ serviceStateSel ServiceState OPTIONAL
+ -- must not have both serviceState and serviceStateSel
+ -- if both are present only serviceStateSel shall be honoured
+ }
+
+IndAudEventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...
+ }
+
+IndAudEventBufferDescriptor ::= SEQUENCE
+ {
+ eventName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...
+ }
+
+IndAudSignalsDescriptor ::=CHOICE
+ {
+ signal IndAudSignal,
+ seqSigList IndAudSeqSigList,
+ ...
+ }
+
+IndAudSeqSigList ::= SEQUENCE
+ {
+ id INTEGER(0..65535),
+ signalList IndAudSignal OPTIONAL
+ }
+
+IndAudSignal ::= SEQUENCE
+ {
+ signalName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...,
+ signalRequestID RequestID OPTIONAL
+ }
+
+IndAudDigitMapDescriptor ::= SEQUENCE
+ {
+ digitMapName DigitMapName OPTIONAL
+ }
+
+IndAudStatisticsDescriptor ::= SEQUENCE
+ {
+ statName PkgdName
+ }
+
+IndAudPackagesDescriptor ::= SEQUENCE
+ {
+ packageName Name,
+ packageVersion INTEGER(0..99),
+ ...
+ }
+
+NotifyRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+ }
+
+NotifyReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+ }
+
+ObservedEventsDescriptor ::= SEQUENCE
+ {
+ requestId RequestID,
+ observedEventLst SEQUENCE OF ObservedEvent
+ }
+
+ObservedEvent ::= SEQUENCE
+ {
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ timeNotation TimeNotation OPTIONAL,
+ ...
+ }
+
+EventName ::= PkgdName
+
+EventParameter ::= SEQUENCE
+ {
+ eventParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to PropertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+
+ }
+
+ServiceChangeRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ serviceChangeParms ServiceChangeParm,
+ ...
+ }
+
+ServiceChangeReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ serviceChangeResult ServiceChangeResult,
+ ...
+ }
+
+-- For ServiceChangeResult, no parameters are mandatory. Hence the
+-- distinction between ServiceChangeParm and ServiceChangeResParm.
+ServiceChangeResult ::= CHOICE
+ {
+ errorDescriptor ErrorDescriptor,
+ serviceChangeResParms ServiceChangeResParm
+ }
+
+WildcardField ::= OCTET STRING(SIZE(1))
+
+TerminationID ::= SEQUENCE
+ {
+ wildcard SEQUENCE OF WildcardField,
+ id OCTET STRING(SIZE(1..8)),
+ ...
+ }
+-- See A.1 for explanation of wildcarding mechanism.
+-- Termination ID 0xFFFFFFFFFFFFFFFF indicates the ROOT Termination.
+
+TerminationIDList ::= SEQUENCE OF TerminationID
+
+MediaDescriptor ::= SEQUENCE
+ {
+ termStateDescr TerminationStateDescriptor OPTIONAL,
+ streams CHOICE
+ {
+ oneStream StreamParms,
+ multiStream SEQUENCE OF StreamDescriptor
+ } OPTIONAL,
+ ...
+ }
+
+StreamDescriptor ::= SEQUENCE
+ {
+ streamID StreamID,
+ streamParms StreamParms
+ }
+
+StreamParms ::= SEQUENCE
+ {
+ localControlDescriptor LocalControlDescriptor OPTIONAL,
+ localDescriptor LocalRemoteDescriptor OPTIONAL,
+ remoteDescriptor LocalRemoteDescriptor OPTIONAL,
+ ...,
+ statisticsDescriptor StatisticsDescriptor OPTIONAL
+ }
+
+LocalControlDescriptor ::= SEQUENCE
+ {
+ streamMode StreamMode OPTIONAL,
+ reserveValue BOOLEAN OPTIONAL,
+ reserveGroup BOOLEAN OPTIONAL,
+ propertyParms SEQUENCE OF PropertyParm,
+ ...
+ }
+
+StreamMode ::= ENUMERATED
+ {
+ sendOnly(0),
+ recvOnly(1),
+ sendRecv(2),
+ inactive(3),
+ loopBack(4),
+ ...
+ }
+
+-- In PropertyParm, value is a SEQUENCE OF octet string. When sent
+-- by an MGC the interpretation is as follows:
+-- empty sequence means CHOOSE
+-- one element sequence specifies value
+-- If the sublist field is not selected, a longer sequence means
+-- "choose one of the values" (i.e. value1 OR value2 OR ...)
+-- If the sublist field is selected,
+-- a sequence with more than one element encodes the value of a
+-- list-valued property (i.e. value1 AND value2 AND ...).
+-- The relation field may only be selected if the value sequence
+-- has length 1. It indicates that the MG has to choose a value
+-- for the property. E.g. x > 3 (using the greaterThan
+-- value for relation) instructs the MG to choose any value larger
+-- than 3 for property x.
+-- The range field may only be selected if the value sequence
+-- has length 2. It indicates that the MG has to choose a value
+-- in the range between the first octet in the value sequence and
+-- the trailing octet in the value sequence, including the
+-- boundary values.
+-- When sent by the MG, only responses to an AuditCapability request
+-- may contain multiple values, a range, or a relation field.
+
+PropertyParm ::= SEQUENCE
+ {
+ name PkgdName,
+ value SEQUENCE OF OCTET STRING,
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+ }
+
+Name ::= OCTET STRING(SIZE(2))
+
+PkgdName ::= OCTET STRING(SIZE(4))
+-- represents Package Name (2 octets) plus Property, Event,
+-- Signal Names or Statistics ID. (2 octets)
+-- To wildcard a package use 0xFFFF for first two octets, choose
+-- is not allowed. To reference native property tag specified in
+-- Annex C, use 0x0000 as first two octets.
+-- To wildcard a Property, Event, Signal, or Statistics ID, use
+-- 0xFFFF for last two octets, choose is not allowed.
+-- Wildcarding of Package Name is permitted only if Property,
+-- Event, Signal, or Statistics ID are
+-- also wildcarded.
+
+Relation ::= ENUMERATED
+ {
+ greaterThan(0),
+ smallerThan(1),
+ unequalTo(2),
+ ...
+ }
+
+LocalRemoteDescriptor ::= SEQUENCE
+ {
+ propGrps SEQUENCE OF PropertyGroup,
+ ...
+ }
+
+PropertyGroup ::= SEQUENCE OF PropertyParm
+
+TerminationStateDescriptor ::= SEQUENCE
+ {
+ propertyParms SEQUENCE OF PropertyParm,
+ eventBufferControl EventBufferControl OPTIONAL,
+ serviceState ServiceState OPTIONAL,
+ ...
+ }
+
+EventBufferControl ::= ENUMERATED
+ {
+ off(0),
+ lockStep(1),
+ ...
+ }
+
+ServiceState ::= ENUMERATED
+ {
+ test(0),
+ outOfSvc(1),
+ inSvc(2),
+ ...
+ }
+
+MuxDescriptor ::= SEQUENCE
+ {
+ muxType MuxType,
+ termList SEQUENCE OF TerminationID,
+ nonStandardData NonStandardData OPTIONAL,
+ ...
+ }
+
+MuxType ::= ENUMERATED
+ {
+ h221(0),
+ h223(1),
+ h226(2),
+ v76(3),
+ ...,
+ nx64k(4)
+ }
+
+StreamID ::= INTEGER(0..65535) -- 16-bit unsigned integer
+
+EventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ -- RequestID must be present if eventList
+ -- is non empty
+ eventList SEQUENCE OF RequestedEvent,
+ ...
+ }
+
+RequestedEvent ::= SEQUENCE
+ {
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction RequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+RegulatedEmbeddedDescriptor ::= SEQUENCE
+ {
+ secondEvent SecondEventsDescriptor OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+ }
+
+NotifyBehaviour ::= CHOICE
+ {
+ notifyImmediate NULL,
+ notifyRegulated RegulatedEmbeddedDescriptor,
+ neverNotify NULL,
+ ...
+ }
+
+RequestedActions ::= SEQUENCE
+ {
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ secondEvent SecondEventsDescriptor OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...,
+ notifyBehaviour NotifyBehaviour OPTIONAL,
+ resetEventsDescriptor NULL OPTIONAL
+ }
+
+EventDM ::= CHOICE
+ {
+ digitMapName DigitMapName,
+ digitMapValue DigitMapValue
+ }
+
+SecondEventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ eventList SEQUENCE OF SecondRequestedEvent,
+ ...
+ }
+
+SecondRequestedEvent ::= SEQUENCE
+ {
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction SecondRequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+SecondRequestedActions ::= SEQUENCE
+ {
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...,
+ notifyBehaviour NotifyBehaviour OPTIONAL,
+ resetEventsDescriptor NULL OPTIONAL
+ }
+
+EventBufferDescriptor ::= SEQUENCE OF EventSpec
+
+EventSpec ::= SEQUENCE
+ {
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+
+SignalsDescriptor ::= SEQUENCE OF SignalRequest
+
+SignalRequest ::= CHOICE
+ {
+ signal Signal,
+ seqSigList SeqSigList,
+ ...
+ }
+
+SeqSigList ::= SEQUENCE
+ {
+ id INTEGER(0..65535),
+ signalList SEQUENCE OF Signal
+ }
+
+Signal ::= SEQUENCE
+ {
+ signalName SignalName,
+ streamID StreamID OPTIONAL,
+ sigType SignalType OPTIONAL,
+ duration INTEGER (0..65535) OPTIONAL,
+ notifyCompletion NotifyCompletion OPTIONAL,
+ keepActive BOOLEAN OPTIONAL,
+ sigParList SEQUENCE OF SigParameter,
+ ...,
+ direction SignalDirection OPTIONAL,
+ requestID RequestID OPTIONAL,
+ intersigDelay INTEGER (0..65535) OPTIONAL
+ }
+
+SignalType ::= ENUMERATED
+ {
+ brief(0),
+ onOff(1),
+ timeOut(2),
+ ...
+ }
+
+SignalDirection ::= ENUMERATED
+ {
+ internal(0),
+ external(1),
+ both(3),
+ ...
+ }
+
+SignalName ::= PkgdName
+
+NotifyCompletion ::= BIT STRING
+ {
+ onTimeOut(0), onInterruptByEvent(1),
+ onInterruptByNewSignalDescr(2), otherReason(3), onIteration(4)
+ }
+
+SigParameter ::= SEQUENCE
+ {
+ sigParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to PropertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+ }
+
+-- For an AuditCapReply with all events, the RequestID SHALL be ALL.
+-- ALL is represented by 0xffffffff.
+RequestID ::= INTEGER(0..4294967295) -- 32-bit unsigned integer
+
+ModemDescriptor ::= SEQUENCE
+ {
+ mtl SEQUENCE OF ModemType,
+ mpl SEQUENCE OF PropertyParm,
+ nonStandardData NonStandardData OPTIONAL
+ }
+
+ModemType ::= ENUMERATED
+ {
+ v18(0),
+ v22(1),
+ v22bis(2),
+ v32(3),
+ v32bis(4),
+ v34(5),
+ v90(6),
+ v91(7),
+ synchISDN(8),
+ ...
+ }
+
+DigitMapDescriptor ::= SEQUENCE
+ {
+ digitMapName DigitMapName OPTIONAL,
+ digitMapValue DigitMapValue OPTIONAL
+ }
+
+DigitMapName ::= Name
+
+DigitMapValue ::= SEQUENCE
+ {
+ startTimer INTEGER(0..99) OPTIONAL,
+ shortTimer INTEGER(0..99) OPTIONAL,
+ longTimer INTEGER(0..99) OPTIONAL,
+ digitMapBody IA5String,
+ -- Units are seconds for start, short and long timers, and
+ -- hundreds of milliseconds for duration timer. Thus start,
+ -- short, and long range from 1 to 99 seconds and duration
+ -- from 100 ms to 9.9 s
+ -- See A.3 for explanation of digit map syntax
+ ...,
+ durationTimer INTEGER (0..99) OPTIONAL
+ }
+
+ServiceChangeParm ::= SEQUENCE
+ {
+ serviceChangeMethod ServiceChangeMethod,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ serviceChangeReason Value,
+ -- A serviceChangeReason consists of a numeric reason code
+ -- and an optional text description.
+ -- The serviceChangeReason SHALL be a string consisting of
+ -- a decimal reason code, optionally followed by a single
+ -- space character and a textual description string.
+ -- This string is first BER-encoded as an IA5String.
+ -- The result of this BER-encoding is then encoded as
+ -- an ASN.1 OCTET STRING type, "double wrapping" the
+ -- value
+ -- as was done for package elements.
+ serviceChangeDelay INTEGER(0..4294967295) OPTIONAL,
+ -- 32-bit unsigned integer
+ serviceChangeMgcId MId OPTIONAL,
+ timeStamp TimeNotation OPTIONAL,
+ nonStandardData NonStandardData OPTIONAL,
+ ...,
+ serviceChangeInfo AuditDescriptor OPTIONAL,
+ serviceChangeIncompleteFlag NULL OPTIONAL
+ }
+
+ServiceChangeAddress ::= CHOICE
+ {
+ portNumber INTEGER(0..65535), -- TCP/UDP port number
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ ...
+ }
+
+ServiceChangeResParm ::= SEQUENCE
+ {
+ serviceChangeMgcId MId OPTIONAL,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ timestamp TimeNotation OPTIONAL,
+ ...
+ }
+
+ServiceChangeMethod ::= ENUMERATED
+ {
+ failover(0),
+ forced(1),
+ graceful(2),
+ restart(3),
+ disconnected(4),
+ handOff(5),
+ ...
+ }
+
+ServiceChangeProfile ::= SEQUENCE
+ {
+ profileName IA5String(SIZE (1..67))
+
+ -- 64 characters for name, 1 for "/", 2 for version to match ABNF
+ }
+
+PackagesDescriptor ::= SEQUENCE OF PackagesItem
+
+PackagesItem ::= SEQUENCE
+ {
+ packageName Name,
+ packageVersion INTEGER(0..99),
+ ...
+ }
+
+StatisticsDescriptor ::= SEQUENCE OF StatisticsParameter
+
+StatisticsParameter ::= SEQUENCE
+ {
+ statName PkgdName,
+ statValue Value OPTIONAL
+ }
+
+-- If statistic consists of a sub-list there will be more than one
+-- octetstring in statValue.
+
+NonStandardData ::= SEQUENCE
+ {
+ nonStandardIdentifier NonStandardIdentifier,
+ data OCTET STRING
+ }
+
+NonStandardIdentifier ::= CHOICE
+ {
+ object OBJECT IDENTIFIER,
+ h221NonStandard H221NonStandard,
+ experimental IA5String(SIZE(8)),
+ -- first two characters SHOULD be "X-" or "X+"
+ ...
+ }
+
+H221NonStandard ::= SEQUENCE
+ { t35CountryCode1 INTEGER(0..255),
+ t35CountryCode2 INTEGER(0..255), -- country, as per T.35
+ t35Extension INTEGER(0..255), -- assigned nationally
+ manufacturerCode INTEGER(0..65535), -- assigned nationally
+ ...
+ }
+
+TimeNotation ::= SEQUENCE
+ {
+ date IA5String(SIZE(8)), -- yyyymmdd format
+ time IA5String(SIZE(8)) -- hhmmssss format
+ -- per ISO 8601:1988
+ }
+
+Value ::= SEQUENCE OF OCTET STRING
+
+END
diff --git a/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-v1.asn b/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-v1.asn
new file mode 100644
index 0000000000..717517938f
--- /dev/null
+++ b/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-v1.asn
@@ -0,0 +1,982 @@
+-- This ASN.1 spec has been extracted from the Megaco/H.248 spec
+-- http://www.ietf.org/internet-drafts/draft-ietf-megaco-merged-01.txt
+--
+-- o Removed stuff named nonStandard
+-- o Major enhancements of the indentation has been performed.
+--
+-- Hakan Mattsson <[email protected]>
+--
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+-- ANNEX A: BINARY ENCODING OF THE PROTOCOL (NORMATIVE)
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+--
+-- This Annex specifies the syntax of messages using the notation
+-- defined in ASN.1 [ITU-T Recommendation X.680 (1997): Information
+-- Technology - Abstract Syntax Notation One (ASN.1) - Specification of
+-- basic notation.]. Messages shall be encoded for transmission by
+-- applying the basic encoding rules specified in [ITU-T Recommendation
+-- X.690(1994) Information Technology - ASN.1 Encoding Rules:
+-- Specification of Basic Encoding Rules (BER)].
+--
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+-- A.1 Coding of wildcards
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+--
+-- The use of wildcards ALL and CHOOSE is allowed in the protocol.
+-- This allows a MGC to partially specify Termination IDs and let the
+-- MG choose from the values that conform to the partial specification.
+-- Termination IDs may encode a hierarchy of names. This hierarchy is
+-- provisioned. For instance, a TerminationID may consist of a trunk
+-- group, a trunk within the group and a circuit. Wildcarding must be
+-- possible at all levels. The following paragraphs explain how this
+-- is achieved.
+--
+-- The ASN.1 description uses octet strings of up to 8 octets in length
+-- for Termination IDs. This means that Termination IDs consist of at
+-- most 64 bits. A fully specified Termination ID may be preceded by a
+-- sequence of wildcarding fields. A wildcarding field is one octet in
+-- length. Bit 7 (the most significant bit) of this octet specifies
+-- what type of wildcarding is invoked: if the bit value equals 1,
+-- then the ALL wildcard is used; if the bit value if 0, then the
+-- CHOOSE wildcard is used. Bit 6 of the wildcarding field specifies
+-- whether the wildcarding pertains to one level in the hierarchical
+-- naming scheme (bit value 0) or to the level of the hierarchy
+-- specified in the wildcarding field plus all lower levels (bit value
+-- 1). Bits 0 through 5 of the wildcarding field specify the bit
+-- position in the Termination ID at which the starts.
+--
+-- We illustrate this scheme with some examples. In these examples,
+-- the most significant bit in a string of bits appears on the left
+-- hand side.
+--
+-- Assume that Termination IDs are three octets long and that each
+-- octet represents a level in a hierarchical naming scheme. A valid
+-- Termination ID is
+-- 00000001 00011110 01010101.
+--
+-- Addressing ALL names with prefix 00000001 00011110 is done as
+-- follows:
+-- wildcarding field: 10000111
+-- Termination ID: 00000001 00011110 xxxxxxxx.
+--
+-- The values of the bits labeled "x" is irrelevant and shall be
+-- ignored by the receiver.
+--
+-- Indicating to the receiver that is must choose a name with 00011110
+-- as the second octet is done as follows:
+-- wildcarding fields: 00010111 followed by 00000111
+-- Termination ID: xxxxxxxx 00011110 xxxxxxxx.
+--
+-- The first wildcard field indicates a CHOOSE wildcard for the level
+-- in the naming hierarchy starting at bit 23, the highest level in our
+-- assumed naming scheme. The second wildcard field indicates a CHOOSE
+-- wildcard for the level in the naming hierarchy starting at bit 7,
+-- the lowest level in our assumed naming scheme.
+--
+-- Finally, a CHOOSE-wildcarded name with the highest level of the name
+-- equal to 00000001 is specified as follows:
+-- wildcard field: 01001111
+-- Termination ID: 0000001 xxxxxxxx xxxxxxxx .
+--
+-- Bit value 1 at bit position 6 of the first octet of the wildcard
+-- field indicates that the wildcarding pertains to the specified level
+-- in the naming hierarchy and all lower levels.
+--
+-- Context IDs may also be wildcarded. In the case of Context IDs,
+-- however, specifying partial names is not allowed. Context ID 0x0
+-- SHALL be used to indicate the NULL Context, Context ID 0xFFFFFFFE
+-- SHALL be used to indicate a CHOOSE wildcard, and Context ID
+-- 0xFFFFFFFF SHALL be used to indicate an ALL wildcard.
+--
+-- TerminationID 0xFFFFFFFFFFFFFFFF SHALL be used to indicate the ROOT
+-- Termination.
+--
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+-- Digit maps and path names
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+--
+-- From a syntactic viewpoint, digit maps are strings with syntactic
+-- restrictions imposed upon them. The syntax of valid digit maps is
+-- specified in ABNF [RFC 2234]. The syntax for digit maps presented
+-- in this section is for illustrative purposes only. The definition of
+-- digitMap in Annex B takes precedence in the case of differences
+-- between the two.
+--
+-- digitMap = (digitString / LWSP "(" LWSP digitStringList LWSP ")"
+-- LWSP)
+-- digitStringList = digitString *( LWSP "/" LWSP digitString )
+-- digitString = 1*(digitStringElement)
+-- digitStringElement = digitPosition [DOT]
+-- digitPosition = digitMapLetter / digitMapRange
+-- digitMapRange = ("x" / LWSP "[" LWSP digitLetter LWSP "]" LWSP)
+-- digitLetter = *((DIGIT "-" DIGIT) /digitMapLetter)
+-- digitMapLetter = DIGIT ;digits 0-9
+-- / %x41-4B / %x61-6B ;a-k and A-K
+-- / "L" / "S" ;Inter-event timers
+-- ;(long, short)
+-- / "Z" ;Long duration event
+-- DOT = %x2E ; "."
+-- LWSP = *(WSP / COMMENT / EOL)
+-- WSP = SP / HTAB
+-- COMMENT = ";" *(SafeChar / RestChar / WSP) EOL
+-- EOL = (CR [LF]) / LF
+-- SP = %x20
+-- HTAB = %x09
+-- CR = %x0D
+-- LF = %x0A
+-- SafeChar = DIGIT / ALPHA / "+" / "-" / "&" / "!" / "_" / "/" /
+-- "'" / "?" / "@" / "^" / "`" / "~" / "*" / "$" / "\" /
+-- "(" / ")" / "%" / "."
+-- RestChar = ";" / "[" / "]" / "{" / "}" / ":" / "," / "#" /
+-- "<" / ">" / "=" / %x22
+-- DIGIT = %x30-39 ; digits 0 through 9
+-- ALPHA = %x41-5A / %x61-7A ; A-Z, a-z
+-- A path name is also a string with syntactic restrictions imposed
+-- upon it. The ABNF production defining it is copied from Annex B.
+--
+-- PathName = NAME *(["/"] ["*"] ["@"] (ALPHA / DIGIT)) ["*"]
+-- NAME = ALPHA *63(ALPHA / DIGIT / "_" )
+--
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+-- A.2 ASN.1 syntax specification
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+--
+-- This section contains the ASN.1 specification of the H.248 protocol
+-- syntax.
+--
+-- NOTE - In case a transport mechanism is used that employs
+-- application level framing, the definition of Transaction below
+-- changes. Refer to the annex defining the transport mechanism for
+-- the definition that applies in that case.
+--
+-- NOTE - The ASN.1 specification below contains a clause defining
+-- TerminationIDList as a sequence of TerminationIDs. The length of
+-- this sequence SHALL be one, except possibly when used in
+-- contextAuditResult.
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+
+MEDIA-GATEWAY-CONTROL-v1
+DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+MegacoMessage ::= SEQUENCE
+{
+ authHeader AuthenticationHeader OPTIONAL,
+ mess Message
+}
+
+AuthenticationHeader ::= SEQUENCE
+{
+ secParmIndex SecurityParmIndex,
+ seqNum SequenceNum,
+ ad AuthData
+}
+
+SecurityParmIndex ::= OCTET STRING(SIZE(4))
+
+SequenceNum ::= OCTET STRING(SIZE(4))
+
+AuthData ::= OCTET STRING (SIZE (12..32))
+
+Message ::= SEQUENCE
+{
+ version INTEGER(0..99),
+ -- The version of the protocol defined here is equal to 1.
+ mId MId, -- Name/address of message originator
+ messageBody CHOICE
+ {
+ messageError ErrorDescriptor,
+ transactions SEQUENCE OF Transaction
+ },
+ ...
+}
+
+MId ::= CHOICE
+{
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ -- Addressing structure of mtpAddress:
+ -- 15 0
+ -- | PC | NI |
+ -- 14 bits 2 bits
+ ...
+}
+
+DomainName ::= SEQUENCE
+{
+ name IA5String,
+ -- The name starts with an alphanumeric digit followed by a
+ -- sequence of alphanumeric digits, hyphens and dots. No two
+ -- dots shall occur consecutively.
+ portNumber INTEGER(0..65535) OPTIONAL
+}
+
+IP4Address ::= SEQUENCE
+{
+ address OCTET STRING (SIZE(4)),
+ portNumber INTEGER(0..65535) OPTIONAL
+}
+
+IP6Address ::= SEQUENCE
+{
+ address OCTET STRING (SIZE(16)),
+ portNumber INTEGER(0..65535) OPTIONAL
+}
+
+PathName ::= IA5String(SIZE (1..64))
+-- See section A.3
+
+Transaction ::= CHOICE
+{
+ transactionRequest TransactionRequest,
+ transactionPending TransactionPending,
+ transactionReply TransactionReply,
+ transactionResponseAck TransactionResponseAck,
+ -- use of response acks is dependent on underlying transport
+ ...
+}
+
+TransactionId ::= INTEGER(0..4294967295) -- 32 bit unsigned integer
+
+TransactionRequest ::= SEQUENCE
+{
+ transactionId TransactionId,
+ actions SEQUENCE OF ActionRequest,
+ ...
+}
+
+TransactionPending ::= SEQUENCE
+{
+ transactionId TransactionId,
+ ...
+}
+
+TransactionReply ::= SEQUENCE
+{
+ transactionId TransactionId,
+ immAckRequired NULL OPTIONAL,
+ transactionResult CHOICE
+ {
+ transactionError ErrorDescriptor,
+ actionReplies SEQUENCE OF ActionReply
+ },
+ ...
+}
+
+TransactionResponseAck ::= SEQUENCE OF TransactionAck
+
+TransactionAck ::= SEQUENCE
+{
+ firstAck TransactionId,
+ lastAck TransactionId OPTIONAL
+}
+
+ErrorDescriptor ::= SEQUENCE
+{
+ errorCode ErrorCode,
+ errorText ErrorText OPTIONAL
+}
+
+ErrorCode ::= INTEGER(0..65535)
+-- See section 13 for IANA considerations w.r.t. error codes
+
+ErrorText ::= IA5String
+
+ContextID ::= INTEGER(0..4294967295)
+
+-- Context NULL Value: 0
+-- Context CHOOSE Value: 4294967294 (0xFFFFFFFE)
+-- Context ALL Value: 4294967295 (0xFFFFFFFF)
+
+
+ActionRequest ::= SEQUENCE
+{
+ contextId ContextID,
+ contextRequest ContextRequest OPTIONAL,
+ contextAttrAuditReq ContextAttrAuditRequest OPTIONAL,
+ commandRequests SEQUENCE OF CommandRequest
+}
+
+ActionReply ::= SEQUENCE
+{
+ contextId ContextID,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ contextReply ContextRequest OPTIONAL,
+ commandReply SEQUENCE OF CommandReply
+}
+
+ContextRequest ::= SEQUENCE
+{
+ priority INTEGER(0..15) OPTIONAL,
+ emergency BOOLEAN OPTIONAL,
+ topologyReq SEQUENCE OF TopologyRequest OPTIONAL,
+ ...
+}
+
+ContextAttrAuditRequest ::= SEQUENCE
+{
+ topology NULL OPTIONAL,
+ emergency NULL OPTIONAL,
+ priority NULL OPTIONAL,
+ ...
+}
+
+CommandRequest ::= SEQUENCE
+{
+ command Command,
+ optional NULL OPTIONAL,
+ wildcardReturn NULL OPTIONAL,
+ ...
+}
+
+Command ::= CHOICE
+{
+ addReq AmmRequest,
+ moveReq AmmRequest,
+ modReq AmmRequest,
+ -- Add, Move, Modify requests have the same parameters
+ subtractReq SubtractRequest,
+ auditCapRequest AuditRequest,
+ auditValueRequest AuditRequest,
+ notifyReq NotifyRequest,
+ serviceChangeReq ServiceChangeRequest,
+ ...
+}
+
+CommandReply ::= CHOICE
+{
+ addReply AmmsReply,
+ moveReply AmmsReply,
+ modReply AmmsReply,
+ subtractReply AmmsReply,
+ -- Add, Move, Modify, Subtract replies have the same parameters
+ auditCapReply AuditReply,
+ auditValueReply AuditReply,
+ notifyReply NotifyReply,
+ serviceChangeReply ServiceChangeReply,
+ ...
+}
+
+TopologyRequest ::= SEQUENCE
+{
+ terminationFrom TerminationID,
+ terminationTo TerminationID,
+ topologyDirection ENUMERATED
+ {
+ bothway(0),
+ isolate(1),
+ oneway(2)
+ }
+}
+
+AmmRequest ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ descriptors SEQUENCE OF AmmDescriptor,
+ -- At most one descriptor of each type (see AmmDescriptor)
+ -- allowed in the sequence.
+ ...
+}
+
+AmmDescriptor ::= CHOICE
+{
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ auditDescriptor AuditDescriptor,
+...
+}
+
+AmmsReply ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ terminationAudit TerminationAudit OPTIONAL,
+ ...
+}
+
+SubtractRequest ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ auditDescriptor AuditDescriptor OPTIONAL,
+ ...
+}
+
+AuditRequest ::= SEQUENCE
+{
+ terminationID TerminationID,
+ auditDescriptor AuditDescriptor,
+ ...
+}
+
+AuditReply ::= CHOICE
+{
+ contextAuditResult TerminationIDList,
+ error ErrorDescriptor,
+ auditResult AuditResult,
+ ...
+}
+
+AuditResult ::= SEQUENCE
+{
+ terminationID TerminationID,
+ terminationAuditResult TerminationAudit
+}
+
+TerminationAudit ::= SEQUENCE OF AuditReturnParameter
+
+AuditReturnParameter ::= CHOICE
+{
+ errorDescriptor ErrorDescriptor,
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ statisticsDescriptor StatisticsDescriptor,
+ packagesDescriptor PackagesDescriptor,
+ emptyDescriptors AuditDescriptor,
+ ...
+}
+
+AuditDescriptor ::= SEQUENCE
+{
+ auditToken BIT STRING
+ {
+ muxToken(0),
+ modemToken(1),
+ mediaToken(2),
+ eventsToken(3),
+ signalsToken(4),
+ digitMapToken(5),
+ statsToken(6),
+ observedEventsToken(7),
+ packagesToken(8),
+ eventBufferToken(9)
+ } OPTIONAL,
+ ...
+}
+
+NotifyRequest ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+}
+
+NotifyReply ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+}
+
+ObservedEventsDescriptor ::= SEQUENCE
+{
+ requestId RequestID,
+ observedEventLst SEQUENCE OF ObservedEvent
+}
+
+ObservedEvent ::= SEQUENCE
+{
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ timeNotation TimeNotation OPTIONAL,
+ ...
+}
+
+EventName ::= PkgdName
+
+EventParameter ::= SEQUENCE
+{
+ eventParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to propertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+}
+
+ServiceChangeRequest ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ serviceChangeParms ServiceChangeParm,
+ ...
+}
+
+ServiceChangeReply ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ serviceChangeResult ServiceChangeResult,
+ ...
+}
+
+-- For ServiceChangeResult, no parameters are mandatory. Hence the
+-- distinction between ServiceChangeParm and ServiceChangeResParm.
+
+ServiceChangeResult ::= CHOICE
+{
+ errorDescriptor ErrorDescriptor,
+ serviceChangeResParms ServiceChangeResParm
+}
+
+WildcardField ::= OCTET STRING(SIZE(1))
+
+TerminationID ::= SEQUENCE
+{
+ wildcard SEQUENCE OF WildcardField,
+ id OCTET STRING(SIZE(1..8)),
+ ...
+}
+-- See Section A.1 for explanation of wildcarding mechanism.
+-- Termination ID 0xFFFFFFFFFFFFFFFF indicates the ROOT Termination.
+
+TerminationIDList ::= SEQUENCE OF TerminationID
+
+MediaDescriptor ::= SEQUENCE
+{
+
+ termStateDescr TerminationStateDescriptor OPTIONAL,
+ streams CHOICE
+ {
+ oneStream StreamParms,
+ multiStream SEQUENCE OF StreamDescriptor
+ } OPTIONAL,
+ ...
+}
+
+StreamDescriptor ::= SEQUENCE
+{
+ streamID StreamID,
+ streamParms StreamParms
+}
+
+StreamParms ::= SEQUENCE
+{
+ localControlDescriptor LocalControlDescriptor OPTIONAL,
+ localDescriptor LocalRemoteDescriptor OPTIONAL,
+ remoteDescriptor LocalRemoteDescriptor OPTIONAL,
+ ...
+}
+
+LocalControlDescriptor ::= SEQUENCE
+{
+ streamMode StreamMode OPTIONAL,
+ reserveValue BOOLEAN OPTIONAL,
+ reserveGroup BOOLEAN OPTIONAL,
+ propertyParms SEQUENCE OF PropertyParm,
+ ...
+}
+
+StreamMode ::= ENUMERATED
+{
+ sendOnly(0),
+ recvOnly(1),
+ sendRecv(2),
+ inactive(3),
+ loopBack(4),
+ ...
+}
+
+-- In PropertyParm, value is a SEQUENCE OF octet string. When sent
+-- by an MGC the interpretation is as follows:
+-- empty sequence means CHOOSE
+-- one element sequence specifies value
+-- If the sublist field is not selected, a longer sequence means
+-- "choose one of the values" (i.e. value1 OR value2 OR ...)
+-- If the sublist field is selected,
+-- a sequence with more than one element encodes the value of a
+-- list-valued property (i.e. value1 AND value2 AND ...).
+-- The relation field may only be selected if the value sequence
+-- has length 1. It indicates that the MG has to choose a value
+-- for the property. E.g., x > 3 (using the greaterThan
+-- value for relation) instructs the MG to choose any value larger
+-- than 3 for property x.
+-- The range field may only be selected if the value sequence
+-- has length 2. It indicates that the MG has to choose a value
+-- in the range between the first octet in the value sequence and
+-- the trailing octet in the value sequence, including the
+-- boundary values.
+-- When sent by the MG, only responses to an AuditCapability request
+-- may contain multiple values, a range, or a relation field.
+
+PropertyParm ::= SEQUENCE
+{
+ name PkgdName,
+ value SEQUENCE OF OCTET STRING,
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+}
+
+Name ::= OCTET STRING(SIZE(2))
+
+PkgdName ::= OCTET STRING(SIZE(4))
+-- represents Package Name (2 octets) plus Property Name (2 octets)
+-- To wildcard a package use 0xFFFF for first two octets, choose
+-- is not allowed. To reference native property tag specified in
+-- Annex C, use 0x0000 as first two octets.
+-- Wildcarding of Package Name is permitted only if Property Name is
+-- also wildcarded.
+
+Relation ::= ENUMERATED
+{
+ greaterThan(0),
+ smallerThan(1),
+ unequalTo(2),
+ ...
+}
+
+LocalRemoteDescriptor ::= SEQUENCE
+{
+ propGrps SEQUENCE OF PropertyGroup,
+ ...
+}
+
+PropertyGroup ::= SEQUENCE OF PropertyParm
+
+TerminationStateDescriptor ::= SEQUENCE
+{
+ propertyParms SEQUENCE OF PropertyParm,
+ eventBufferControl EventBufferControl OPTIONAL,
+ serviceState ServiceState OPTIONAL,
+ ...
+}
+
+EventBufferControl ::= ENUMERATED
+{
+ off(0),
+ lockStep(1),
+ ...
+}
+
+ServiceState ::= ENUMERATED
+{
+ test(0),
+ outOfSvc(1),
+ inSvc(2),
+ ...
+}
+
+MuxDescriptor ::= SEQUENCE
+{
+ muxType MuxType,
+ termList SEQUENCE OF TerminationID,
+ nonStandardData NonStandardData OPTIONAL,
+ ...
+}
+
+MuxType ::= ENUMERATED
+{
+ h221(0),
+ h223(1),
+ h226(2),
+ v76(3),
+ ...
+}
+
+StreamID ::= INTEGER(0..65535) -- 16 bit unsigned integer
+
+EventsDescriptor ::= SEQUENCE
+{
+ requestID RequestID,
+ -- IG 6.82 was withdrawn
+ -- requestID RequestID OPTIONAL,
+ -- RequestID must be present if eventList is non empty
+ eventList SEQUENCE OF RequestedEvent,
+ ...
+}
+
+RequestedEvent ::= SEQUENCE
+{
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction RequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+}
+
+RequestedActions ::= SEQUENCE
+{
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ secondEvent SecondEventsDescriptor OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+}
+
+
+EventDM ::= CHOICE
+{
+ digitMapName DigitMapName,
+ digitMapValue DigitMapValue
+}
+
+SecondEventsDescriptor ::= SEQUENCE
+{
+ requestID RequestID,
+ -- IG 6.82 was withdrawn
+ -- requestID RequestID OPTIONAL,
+ -- RequestID must be present if eventList is non empty
+ eventList SEQUENCE OF SecondRequestedEvent,
+ ...
+}
+
+SecondRequestedEvent ::= SEQUENCE
+{
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction SecondRequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+}
+
+SecondRequestedActions ::= SEQUENCE
+{
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+}
+
+EventBufferDescriptor ::= SEQUENCE OF EventSpec
+
+EventSpec ::= SEQUENCE
+{
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ ...
+}
+
+SignalsDescriptor ::= SEQUENCE OF SignalRequest
+
+SignalRequest ::= CHOICE
+{
+ signal Signal,
+ seqSigList SeqSigList,
+ ...
+}
+
+SeqSigList ::= SEQUENCE
+{
+ id INTEGER(0..65535),
+ signalList SEQUENCE OF Signal
+}
+
+Signal ::= SEQUENCE
+{
+ signalName SignalName,
+ streamID StreamID OPTIONAL,
+ sigType SignalType OPTIONAL,
+ duration INTEGER (0..65535) OPTIONAL,
+ notifyCompletion NotifyCompletion OPTIONAL,
+ keepActive BOOLEAN OPTIONAL,
+ sigParList SEQUENCE OF SigParameter,
+ ...
+}
+
+SignalType ::= ENUMERATED
+{
+ brief(0),
+ onOff(1),
+ timeOut(2),
+ ...
+}
+
+SignalName ::= PkgdName
+
+NotifyCompletion ::= BIT STRING
+{
+ onTimeOut(0),
+ onInterruptByEvent(1),
+ onInterruptByNewSignalDescr(2),
+ otherReason(3)
+}
+
+SigParameter ::= SEQUENCE
+{
+ sigParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to propertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+}
+
+RequestID ::= INTEGER(0..4294967295) -- 32 bit unsigned integer
+-- Request ALL Value: 4294967295 (0xFFFFFFFF)
+
+ModemDescriptor ::= SEQUENCE
+{
+ mtl SEQUENCE OF ModemType,
+ mpl SEQUENCE OF PropertyParm,
+ nonStandardData NonStandardData OPTIONAL
+}
+
+ModemType ::= ENUMERATED
+{
+ v18(0),
+ v22(1),
+ v22bis(2),
+ v32(3),
+ v32bis(4),
+ v34(5),
+ v90(6),
+ v91(7),
+ synchISDN(8),
+ ...
+}
+
+DigitMapDescriptor ::= SEQUENCE
+{
+ digitMapName DigitMapName OPTIONAL,
+ digitMapValue DigitMapValue OPTIONAL
+}
+
+DigitMapName ::= Name
+
+DigitMapValue ::= SEQUENCE
+{
+ startTimer INTEGER(0..99) OPTIONAL,
+ shortTimer INTEGER(0..99) OPTIONAL,
+ longTimer INTEGER(0..99) OPTIONAL,
+ digitMapBody IA5String,
+ -- See Section A.3 for explanation of digit map syntax
+ ...
+}
+
+ServiceChangeParm ::= SEQUENCE
+{
+ serviceChangeMethod ServiceChangeMethod,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ serviceChangeReason Value,
+ serviceChangeDelay INTEGER(0..4294967295) OPTIONAL,
+ -- 32 bit unsigned integer
+ serviceChangeMgcId MId OPTIONAL,
+ timeStamp TimeNotation OPTIONAL,
+ nonStandardData NonStandardData OPTIONAL,
+ ...
+}
+
+ServiceChangeAddress ::= CHOICE
+{
+ portNumber INTEGER(0..65535), -- TCP/UDP port number
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ ...
+}
+
+ServiceChangeResParm ::= SEQUENCE
+{
+ serviceChangeMgcId MId OPTIONAL,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ timeStamp TimeNotation OPTIONAL,
+ ...
+}
+
+ServiceChangeMethod ::= ENUMERATED
+{
+ failover(0),
+ forced(1),
+ graceful(2),
+ restart(3),
+ disconnected(4),
+ handOff(5),
+ ...
+}
+
+ServiceChangeProfile ::= SEQUENCE
+{
+ profileName IA5String(SIZE (1..67))
+ -- 64 characters for name, 1 for "/", 2 for version to match ABNF
+}
+
+-- ServiceChangeProfile ::= SEQUENCE
+-- {
+-- profileName Name,
+-- version INTEGER(0..99)
+-- }
+
+PackagesDescriptor ::= SEQUENCE OF PackagesItem
+
+PackagesItem ::= SEQUENCE
+{
+ packageName Name,
+ packageVersion INTEGER(0..99),
+ ...
+}
+
+StatisticsDescriptor ::= SEQUENCE OF StatisticsParameter
+
+StatisticsParameter ::= SEQUENCE
+{
+ statName PkgdName,
+ statValue Value OPTIONAL
+}
+
+NonStandardData ::= SEQUENCE
+{
+ nonStandardIdentifier NonStandardIdentifier,
+ data OCTET STRING
+}
+
+NonStandardIdentifier ::= CHOICE
+{
+ object OBJECT IDENTIFIER,
+ h221NonStandard H221NonStandard,
+ experimental IA5String(SIZE(8)),
+ -- first two characters should be "X-" or "X+"
+ ...
+}
+
+H221NonStandard ::= SEQUENCE
+{
+ t35CountryCode1 INTEGER(0..255),
+ t35CountryCode2 INTEGER(0..255), -- country, as per T.35
+ t35Extension INTEGER(0..255), -- assigned nationally
+ manufacturerCode INTEGER(0..65535), -- assigned nationally
+ ...
+}
+
+TimeNotation ::= SEQUENCE
+{
+ date IA5String(SIZE(8)), -- yyyymmdd format
+ time IA5String(SIZE(8)) -- hhmmssss format
+}
+
+Value ::= SEQUENCE OF OCTET STRING
+
+
+END
+
diff --git a/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-v2.asn b/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-v2.asn
new file mode 100644
index 0000000000..b75925b30e
--- /dev/null
+++ b/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-v2.asn
@@ -0,0 +1,966 @@
+MEDIA-GATEWAY-CONTROL-v2
+{itu-t(0) recommendation(0) h(8) h248(248)
+ modules(0) media-gateway-control(0) version2(2)}
+DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+
+MegacoMessage ::= SEQUENCE
+ {
+ authHeader AuthenticationHeader OPTIONAL,
+ mess Message
+ }
+
+AuthenticationHeader ::= SEQUENCE
+ {
+ secParmIndex SecurityParmIndex,
+ seqNum SequenceNum,
+ ad AuthData
+ }
+
+SecurityParmIndex ::= OCTET STRING(SIZE(4))
+
+SequenceNum ::= OCTET STRING(SIZE(4))
+
+AuthData ::= OCTET STRING (SIZE (12..32))
+
+Message ::= SEQUENCE
+ {
+ version INTEGER(0..99),
+ -- The version of the protocol defined here is equal to 2.
+ mId MId, -- Name/address of message originator
+ messageBody CHOICE
+ {
+ messageError ErrorDescriptor,
+ transactions SEQUENCE OF Transaction
+ },
+ ...
+ }
+
+MId ::= CHOICE
+ {
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ -- Addressing structure of mtpAddress:
+ -- 25 - 15 0
+ -- | PC | NI |
+ -- 24 - 14 bits 2 bits
+ -- Note: 14 bits are defined for international use.
+ -- Two national options exist where the point code is 16 or 24
+ -- bits.
+ -- To octet align the mtpAddress, the MSBs shall be encoded as 0s.
+ ...
+ }
+
+DomainName ::= SEQUENCE
+ {
+ name IA5String,
+ -- The name starts with an alphanumeric digit followed by a
+ -- sequence of alphanumeric digits, hyphens and dots. No two
+ -- dots shall occur consecutively.
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+IP4Address ::= SEQUENCE
+ {
+ address OCTET STRING (SIZE(4)),
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+IP6Address ::= SEQUENCE
+ {
+ address OCTET STRING (SIZE(16)),
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+PathName ::= IA5String(SIZE (1..64))
+-- See A.3
+
+Transaction ::= CHOICE
+ {
+ transactionRequest TransactionRequest,
+ transactionPending TransactionPending,
+ transactionReply TransactionReply,
+ transactionResponseAck TransactionResponseAck,
+ -- use of response acks is dependent on underlying transport
+ ...
+ }
+
+TransactionId ::= INTEGER(0..4294967295) -- 32-bit unsigned integer
+
+TransactionRequest ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ actions SEQUENCE OF ActionRequest,
+ ...
+ }
+
+TransactionPending ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ ...
+ }
+
+TransactionReply ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ immAckRequired NULL OPTIONAL,
+ transactionResult CHOICE
+ {
+ transactionError ErrorDescriptor,
+ actionReplies SEQUENCE OF ActionReply
+ },
+ ...
+ }
+
+TransactionResponseAck ::= SEQUENCE OF TransactionAck
+TransactionAck ::= SEQUENCE
+ {
+ firstAck TransactionId,
+ lastAck TransactionId OPTIONAL
+ }
+
+ErrorDescriptor ::= SEQUENCE
+ {
+ errorCode ErrorCode,
+ errorText ErrorText OPTIONAL
+ }
+
+ErrorCode ::= INTEGER(0..65535)
+-- See clause 14 for IANA considerations with respect to error codes
+ErrorText ::= IA5String
+
+ContextID ::= INTEGER(0..4294967295)
+
+-- Context NULL Value: 0
+-- Context CHOOSE Value: 4294967294 (0xFFFFFFFE)
+-- Context ALL Value: 4294967295 (0xFFFFFFFF)
+
+
+ActionRequest ::= SEQUENCE
+ {
+ contextId ContextID,
+ contextRequest ContextRequest OPTIONAL,
+ contextAttrAuditReq ContextAttrAuditRequest OPTIONAL,
+ commandRequests SEQUENCE OF CommandRequest
+ }
+
+ActionReply ::= SEQUENCE
+ {
+ contextId ContextID,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ contextReply ContextRequest OPTIONAL,
+ commandReply SEQUENCE OF CommandReply
+ }
+
+ContextRequest ::= SEQUENCE
+ {
+ priority INTEGER(0..15) OPTIONAL,
+ emergency BOOLEAN OPTIONAL,
+ topologyReq SEQUENCE OF TopologyRequest OPTIONAL,
+ ...
+ }
+
+ContextAttrAuditRequest ::= SEQUENCE
+ {
+ topology NULL OPTIONAL,
+ emergency NULL OPTIONAL,
+ priority NULL OPTIONAL,
+ ...
+ }
+
+CommandRequest ::= SEQUENCE
+ {
+ command Command,
+ optional NULL OPTIONAL,
+ wildcardReturn NULL OPTIONAL,
+ ...
+ }
+
+Command ::= CHOICE
+ {
+ addReq AmmRequest,
+ moveReq AmmRequest,
+ modReq AmmRequest,
+ -- Add, Move, Modify requests have the same parameters
+ subtractReq SubtractRequest,
+ auditCapRequest AuditRequest,
+ auditValueRequest AuditRequest,
+ notifyReq NotifyRequest,
+ serviceChangeReq ServiceChangeRequest,
+ ...
+ }
+
+CommandReply ::= CHOICE
+ {
+ addReply AmmsReply,
+ moveReply AmmsReply,
+ modReply AmmsReply,
+ subtractReply AmmsReply,
+ -- Add, Move, Modify, Subtract replies have the same parameters
+ auditCapReply AuditReply,
+ auditValueReply AuditReply,
+ notifyReply NotifyReply,
+ serviceChangeReply ServiceChangeReply,
+ ...
+ }
+
+TopologyRequest ::= SEQUENCE
+ {
+ terminationFrom TerminationID,
+ terminationTo TerminationID,
+ topologyDirection ENUMERATED
+ {
+ bothway(0),
+ isolate(1),
+ oneway(2)
+ },
+ ...,
+ streamID StreamID OPTIONAL
+ }
+
+AmmRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ descriptors SEQUENCE OF AmmDescriptor,
+ -- At most one descriptor of each type (see AmmDescriptor)
+ -- allowed in the sequence.
+ ...
+ }
+
+AmmDescriptor ::= CHOICE
+ {
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ auditDescriptor AuditDescriptor,
+ ...
+ }
+
+
+AmmsReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ terminationAudit TerminationAudit OPTIONAL,
+ ...
+ }
+
+SubtractRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ auditDescriptor AuditDescriptor OPTIONAL,
+ ...
+ }
+
+AuditRequest ::= SEQUENCE
+ {
+ terminationID TerminationID,
+ auditDescriptor AuditDescriptor,
+ ...
+ }
+
+AuditReply ::= CHOICE
+ {
+ contextAuditResult TerminationIDList,
+ error ErrorDescriptor,
+ auditResult AuditResult,
+ ...
+ }
+
+AuditResult ::= SEQUENCE
+ {
+
+ terminationID TerminationID,
+ terminationAuditResult TerminationAudit
+ }
+
+
+
+TerminationAudit ::= SEQUENCE OF AuditReturnParameter
+
+AuditReturnParameter ::= CHOICE
+ {
+ errorDescriptor ErrorDescriptor,
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ statisticsDescriptor StatisticsDescriptor,
+ packagesDescriptor PackagesDescriptor,
+ emptyDescriptors AuditDescriptor,
+ ...
+ }
+
+AuditDescriptor ::= SEQUENCE
+ {
+ auditToken BIT STRING
+ {
+ muxToken(0), modemToken(1), mediaToken(2),
+ eventsToken(3), signalsToken(4),
+ digitMapToken(5), statsToken(6),
+ observedEventsToken(7),
+ packagesToken(8), eventBufferToken(9)
+ } OPTIONAL,
+ ...,
+ auditPropertyToken SEQUENCE OF IndAuditParameter OPTIONAL
+ }
+
+
+IndAuditParameter ::= CHOICE
+ {
+ -- Note that the lower/upper case letters of the tags have
+ -- been changed. The same changes has been made in text...
+ indAudMediaDescriptor IndAudMediaDescriptor,
+ indAudEventsDescriptor IndAudEventsDescriptor,
+ indAudEventBufferDescriptor IndAudEventBufferDescriptor,
+ indAudSignalsDescriptor IndAudSignalsDescriptor,
+ indAudDigitMapDescriptor IndAudDigitMapDescriptor,
+ indAudStatisticsDescriptor IndAudStatisticsDescriptor,
+ indAudPackagesDescriptor IndAudPackagesDescriptor,
+ ...
+ }
+
+IndAudMediaDescriptor ::= SEQUENCE
+ {
+
+ termStateDescr IndAudTerminationStateDescriptor OPTIONAL,
+ streams CHOICE
+ {
+ oneStream IndAudStreamParms,
+ multiStream SEQUENCE OF IndAudStreamDescriptor
+ } OPTIONAL,
+ ...
+ }
+
+IndAudStreamDescriptor ::= SEQUENCE
+ {
+ streamID StreamID,
+ streamParms IndAudStreamParms
+ }
+
+IndAudStreamParms ::= SEQUENCE
+ {
+ localControlDescriptor IndAudLocalControlDescriptor OPTIONAL,
+ localDescriptor IndAudLocalRemoteDescriptor OPTIONAL,
+ remoteDescriptor IndAudLocalRemoteDescriptor OPTIONAL,
+ ...
+ }
+
+IndAudLocalControlDescriptor ::= SEQUENCE
+ {
+ streamMode NULL OPTIONAL,
+ reserveValue NULL OPTIONAL,
+ reserveGroup NULL OPTIONAL,
+ propertyParms SEQUENCE OF IndAudPropertyParm OPTIONAL,
+ ...
+ }
+
+IndAudPropertyParm ::= SEQUENCE
+ {
+ name PkgdName,
+ ...
+ }
+
+IndAudLocalRemoteDescriptor ::= SEQUENCE
+ {
+ propGroupID INTEGER(0..65535) OPTIONAL,
+ propGrps IndAudPropertyGroup,
+ ...
+ }
+
+IndAudPropertyGroup ::= SEQUENCE OF IndAudPropertyParm
+
+IndAudTerminationStateDescriptor ::= SEQUENCE
+ {
+ propertyParms SEQUENCE OF IndAudPropertyParm,
+ eventBufferControl NULL OPTIONAL,
+ serviceState NULL OPTIONAL,
+ ...
+ }
+
+IndAudEventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...
+ }
+
+IndAudEventBufferDescriptor ::= SEQUENCE
+ {
+ eventName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...
+ }
+
+IndAudSignalsDescriptor ::=CHOICE
+ {
+ signal IndAudSignal,
+ seqSigList IndAudSeqSigList,
+ ...
+ }
+
+IndAudSeqSigList ::= SEQUENCE
+ {
+ id INTEGER(0..65535),
+ signalList IndAudSignal OPTIONAL
+ }
+
+IndAudSignal ::= SEQUENCE
+ {
+ signalName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...
+ }
+
+IndAudDigitMapDescriptor ::= SEQUENCE
+ {
+ digitMapName DigitMapName OPTIONAL
+ }
+
+IndAudStatisticsDescriptor ::= SEQUENCE
+ {
+ statName PkgdName
+ }
+
+IndAudPackagesDescriptor ::= SEQUENCE
+ {
+ packageName Name,
+ packageVersion INTEGER(0..99),
+ ...
+ }
+
+NotifyRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+ }
+
+NotifyReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+ }
+
+ObservedEventsDescriptor ::= SEQUENCE
+ {
+ requestId RequestID,
+ observedEventLst SEQUENCE OF ObservedEvent
+ }
+
+ObservedEvent ::= SEQUENCE
+ {
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ timeNotation TimeNotation OPTIONAL,
+ ...
+ }
+
+EventName ::= PkgdName
+
+EventParameter ::= SEQUENCE
+ {
+ eventParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to PropertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+
+ }
+
+ServiceChangeRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ serviceChangeParms ServiceChangeParm,
+ ...
+ }
+
+ServiceChangeReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ serviceChangeResult ServiceChangeResult,
+ ...
+ }
+
+-- For ServiceChangeResult, no parameters are mandatory. Hence the
+-- distinction between ServiceChangeParm and ServiceChangeResParm.
+
+ServiceChangeResult ::= CHOICE
+ {
+ errorDescriptor ErrorDescriptor,
+ serviceChangeResParms ServiceChangeResParm
+ }
+
+WildcardField ::= OCTET STRING(SIZE(1))
+
+TerminationID ::= SEQUENCE
+ {
+ wildcard SEQUENCE OF WildcardField,
+ id OCTET STRING(SIZE(1..8)),
+ ...
+ }
+-- See A.1 for explanation of wildcarding mechanism.
+-- Termination ID 0xFFFFFFFFFFFFFFFF indicates the ROOT Termination.
+
+TerminationIDList ::= SEQUENCE OF TerminationID
+
+MediaDescriptor ::= SEQUENCE
+ {
+ termStateDescr TerminationStateDescriptor OPTIONAL,
+ streams CHOICE
+ {
+ oneStream StreamParms,
+ multiStream SEQUENCE OF StreamDescriptor
+ } OPTIONAL,
+ ...
+ }
+
+StreamDescriptor ::= SEQUENCE
+ {
+ streamID StreamID,
+ streamParms StreamParms
+ }
+
+StreamParms ::= SEQUENCE
+ {
+ localControlDescriptor LocalControlDescriptor OPTIONAL,
+ localDescriptor LocalRemoteDescriptor OPTIONAL,
+ remoteDescriptor LocalRemoteDescriptor OPTIONAL,
+ ...
+ }
+
+LocalControlDescriptor ::= SEQUENCE
+ {
+ streamMode StreamMode OPTIONAL,
+ reserveValue BOOLEAN OPTIONAL,
+ reserveGroup BOOLEAN OPTIONAL,
+ propertyParms SEQUENCE OF PropertyParm,
+ ...
+ }
+
+StreamMode ::= ENUMERATED
+ {
+ sendOnly(0),
+ recvOnly(1),
+ sendRecv(2),
+ inactive(3),
+ loopBack(4),
+ ...
+ }
+
+-- In PropertyParm, value is a SEQUENCE OF octet string. When sent
+-- by an MGC the interpretation is as follows:
+-- empty sequence means CHOOSE
+-- one element sequence specifies value
+-- If the sublist field is not selected, a longer sequence means
+-- "choose one of the values" (i.e. value1 OR value2 OR ...)
+-- If the sublist field is selected,
+-- a sequence with more than one element encodes the value of a
+-- list-valued property (i.e. value1 AND value2 AND ...).
+-- The relation field may only be selected if the value sequence
+-- has length 1. It indicates that the MG has to choose a value
+-- for the property. E.g. x > 3 (using the greaterThan
+-- value for relation) instructs the MG to choose any value larger
+-- than 3 for property x.
+-- The range field may only be selected if the value sequence
+-- has length 2. It indicates that the MG has to choose a value
+-- in the range between the first octet in the value sequence and
+-- the trailing octet in the value sequence, including the
+-- boundary values.
+-- When sent by the MG, only responses to an AuditCapability request
+-- may contain multiple values, a range, or a relation field.
+
+PropertyParm ::= SEQUENCE
+ {
+ name PkgdName,
+ value SEQUENCE OF OCTET STRING,
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+ }
+
+Name ::= OCTET STRING(SIZE(2))
+
+PkgdName ::= OCTET STRING(SIZE(4))
+-- represents Package Name (2 octets) plus Property, Event,
+-- Signal Names or Statistics ID. (2 octets)
+-- To wildcard a package use 0xFFFF for first two octets, choose
+-- is not allowed. To reference native property tag specified in
+-- Annex C, use 0x0000 as first two octets.
+-- To wildcard a Property, Event, Signal, or Statistics ID, use
+-- 0xFFFF for last two octets, choose is not allowed.
+-- Wildcarding of Package Name is permitted only if Property,
+-- Event, Signal, or Statistics ID are
+-- also wildcarded.
+
+Relation ::= ENUMERATED
+ {
+ greaterThan(0),
+ smallerThan(1),
+ unequalTo(2),
+ ...
+ }
+
+LocalRemoteDescriptor ::= SEQUENCE
+ {
+ propGrps SEQUENCE OF PropertyGroup,
+ ...
+ }
+
+PropertyGroup ::= SEQUENCE OF PropertyParm
+
+TerminationStateDescriptor ::= SEQUENCE
+ {
+ propertyParms SEQUENCE OF PropertyParm,
+ eventBufferControl EventBufferControl OPTIONAL,
+ serviceState ServiceState OPTIONAL,
+ ...
+ }
+
+EventBufferControl ::= ENUMERATED
+ {
+ off(0),
+ lockStep(1),
+ ...
+ }
+
+ServiceState ::= ENUMERATED
+ {
+ test(0),
+ outOfSvc(1),
+ inSvc(2),
+ ...
+ }
+
+MuxDescriptor ::= SEQUENCE
+ {
+ muxType MuxType,
+ termList SEQUENCE OF TerminationID,
+ nonStandardData NonStandardData OPTIONAL,
+ ...
+ }
+
+MuxType ::= ENUMERATED
+ {
+ h221(0),
+ h223(1),
+ h226(2),
+ v76(3),
+ ...,
+ nx64k(4)
+ }
+
+StreamID ::= INTEGER(0..65535) -- 16-bit unsigned integer
+
+EventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ -- RequestID must be present if eventList
+ -- is non empty
+ eventList SEQUENCE OF RequestedEvent,
+ ...
+ }
+
+RequestedEvent ::= SEQUENCE
+ {
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction RequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+RequestedActions ::= SEQUENCE
+ {
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ secondEvent SecondEventsDescriptor OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+ }
+
+EventDM ::= CHOICE
+ {
+ digitMapName DigitMapName,
+ digitMapValue DigitMapValue
+ }
+
+SecondEventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ eventList SEQUENCE OF SecondRequestedEvent,
+ ...
+ }
+
+SecondRequestedEvent ::= SEQUENCE
+ {
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction SecondRequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+SecondRequestedActions ::= SEQUENCE
+ {
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+ }
+
+EventBufferDescriptor ::= SEQUENCE OF EventSpec
+
+EventSpec ::= SEQUENCE
+ {
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+
+SignalsDescriptor ::= SEQUENCE OF SignalRequest
+
+SignalRequest ::= CHOICE
+ {
+ signal Signal,
+ seqSigList SeqSigList,
+ ...
+ }
+
+SeqSigList ::= SEQUENCE
+ {
+ id INTEGER(0..65535),
+ signalList SEQUENCE OF Signal
+ }
+
+Signal ::= SEQUENCE
+ {
+ signalName SignalName,
+ streamID StreamID OPTIONAL,
+ sigType SignalType OPTIONAL,
+ duration INTEGER (0..65535) OPTIONAL,
+ notifyCompletion NotifyCompletion OPTIONAL,
+ keepActive BOOLEAN OPTIONAL,
+ sigParList SEQUENCE OF SigParameter,
+ ...
+ }
+
+SignalType ::= ENUMERATED
+ {
+ brief(0),
+ onOff(1),
+ timeOut(2),
+ ...
+ }
+
+SignalName ::= PkgdName
+
+NotifyCompletion ::= BIT STRING
+ {
+ onTimeOut(0), onInterruptByEvent(1),
+ onInterruptByNewSignalDescr(2), otherReason(3)
+ }
+
+SigParameter ::= SEQUENCE
+ {
+ sigParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to PropertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+ }
+
+-- For an AuditCapReply with all events, the RequestID SHALL be ALL.
+-- ALL is represented by 0xffffffff.
+
+RequestID ::= INTEGER(0..4294967295) -- 32-bit unsigned integer
+
+ModemDescriptor ::= SEQUENCE
+ {
+ mtl SEQUENCE OF ModemType,
+ mpl SEQUENCE OF PropertyParm,
+ nonStandardData NonStandardData OPTIONAL
+ }
+
+ModemType ::= ENUMERATED
+ {
+ v18(0),
+ v22(1),
+ v22bis(2),
+ v32(3),
+ v32bis(4),
+ v34(5),
+ v90(6),
+ v91(7),
+ synchISDN(8),
+ ...
+ }
+
+DigitMapDescriptor ::= SEQUENCE
+ {
+ digitMapName DigitMapName OPTIONAL,
+ digitMapValue DigitMapValue OPTIONAL
+ }
+
+DigitMapName ::= Name
+
+DigitMapValue ::= SEQUENCE
+ {
+ startTimer INTEGER(0..99) OPTIONAL,
+ shortTimer INTEGER(0..99) OPTIONAL,
+ longTimer INTEGER(0..99) OPTIONAL,
+ digitMapBody IA5String,
+ -- Units are seconds for start, short and long timers, and
+ -- hundreds of milliseconds for duration timer. Thus start,
+ -- short, and long range from 1 to 99 seconds and duration
+ -- from 100 ms to 9.9 s
+ -- See A.3 for explanation of digit map syntax
+ ...,
+ durationTimer INTEGER (0..99) OPTIONAL
+ }
+
+ServiceChangeParm ::= SEQUENCE
+ {
+ serviceChangeMethod ServiceChangeMethod,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ serviceChangeReason Value,
+ -- A serviceChangeReason consists of a numeric reason code
+ -- and an optional text description.
+ -- The serviceChangeReason SHALL be a string consisting of
+ -- a decimal reason code, optionally followed by a single
+ -- space character and a textual description string.
+ -- This string is first BER-encoded as an IA5String.
+ -- The result of this BER-encoding is then encoded as
+ -- an ASN.1 OCTET STRING type, "double wrapping" the
+ -- value
+ -- as was done for package elements.
+ serviceChangeDelay INTEGER(0..4294967295) OPTIONAL,
+ -- 32-bit unsigned integer
+ serviceChangeMgcId MId OPTIONAL,
+ timeStamp TimeNotation OPTIONAL,
+ nonStandardData NonStandardData OPTIONAL,
+ ...,
+ serviceChangeInfo AuditDescriptor OPTIONAL
+ }
+
+ServiceChangeAddress ::= CHOICE
+ {
+ portNumber INTEGER(0..65535), -- TCP/UDP port number
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ ...
+ }
+
+ServiceChangeResParm ::= SEQUENCE
+ {
+ serviceChangeMgcId MId OPTIONAL,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ timestamp TimeNotation OPTIONAL,
+ ...
+ }
+
+ServiceChangeMethod ::= ENUMERATED
+ {
+ failover(0),
+ forced(1),
+ graceful(2),
+ restart(3),
+ disconnected(4),
+ handOff(5),
+ ...
+ }
+
+ServiceChangeProfile ::= SEQUENCE
+ {
+ profileName IA5String(SIZE (1..67))
+
+ -- 64 characters for name, 1 for "/", 2 for version to match ABNF
+ }
+
+PackagesDescriptor ::= SEQUENCE OF PackagesItem
+PackagesItem ::= SEQUENCE
+ {
+ packageName Name,
+ packageVersion INTEGER(0..99),
+ ...
+ }
+
+StatisticsDescriptor ::= SEQUENCE OF StatisticsParameter
+
+StatisticsParameter ::= SEQUENCE
+ {
+ statName PkgdName,
+ statValue Value OPTIONAL
+ }
+
+NonStandardData ::= SEQUENCE
+ {
+ nonStandardIdentifier NonStandardIdentifier,
+ data OCTET STRING
+ }
+
+NonStandardIdentifier ::= CHOICE
+ {
+ object OBJECT IDENTIFIER,
+ h221NonStandard H221NonStandard,
+ experimental IA5String(SIZE(8)),
+ -- first two characters SHOULD be "X-" or "X+"
+ ...
+ }
+
+H221NonStandard ::= SEQUENCE
+ { t35CountryCode1 INTEGER(0..255),
+ t35CountryCode2 INTEGER(0..255), -- country, as per T.35
+ t35Extension INTEGER(0..255), -- assigned nationally
+ manufacturerCode INTEGER(0..65535), -- assigned nationally
+ ...
+ }
+
+TimeNotation ::= SEQUENCE
+ {
+ date IA5String(SIZE(8)), -- yyyymmdd format
+ time IA5String(SIZE(8)) -- hhmmssss format
+ -- per ISO 8601:1988
+ }
+
+Value ::= SEQUENCE OF OCTET STRING
+
+END
diff --git a/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-v3.asn b/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-v3.asn
new file mode 100644
index 0000000000..644a35ffee
--- /dev/null
+++ b/lib/megaco/src/binary/MEDIA-GATEWAY-CONTROL-v3.asn
@@ -0,0 +1,1068 @@
+MEDIA-GATEWAY-CONTROL-v3
+{itu-t(0) recommendation(0) h(8) h248(248)
+ modules(0) media-gateway-control(0) version3(3)}
+DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+
+MegacoMessage ::= SEQUENCE
+ {
+ authHeader AuthenticationHeader OPTIONAL,
+ mess Message
+ }
+
+AuthenticationHeader ::= SEQUENCE
+ {
+ secParmIndex SecurityParmIndex,
+ seqNum SequenceNum,
+ ad AuthData
+ }
+
+SecurityParmIndex ::= OCTET STRING(SIZE(4))
+
+SequenceNum ::= OCTET STRING(SIZE(4))
+
+AuthData ::= OCTET STRING (SIZE (12..32))
+
+Message ::= SEQUENCE
+ {
+ version INTEGER(0..99),
+ -- The version of the protocol defined here is equal to 3.
+ mId MId, -- Name/address of message originator
+ messageBody CHOICE
+ {
+ messageError ErrorDescriptor,
+ transactions SEQUENCE OF Transaction
+ },
+ ...
+ }
+
+MId ::= CHOICE
+ {
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ -- Addressing structure of mtpAddress:
+ -- 25 - 15 0
+ -- | PC | NI |
+ -- 24 - 14 bits 2 bits
+ -- Note: 14 bits are defined for international use.
+ -- Two national options exist where the point code is 16 or 24
+ -- bits.
+ -- To octet align the mtpAddress, the MSBs shall be encoded as 0s.
+ ...
+ }
+
+DomainName ::= SEQUENCE
+ {
+ name IA5String,
+ -- The name starts with an alphanumeric digit followed by a
+ -- sequence of alphanumeric digits, hyphens and dots. No two
+ -- dots shall occur consecutively.
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+IP4Address ::= SEQUENCE
+ {
+ address OCTET STRING (SIZE(4)),
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+IP6Address ::= SEQUENCE
+ {
+ address OCTET STRING (SIZE(16)),
+ portNumber INTEGER(0..65535) OPTIONAL
+ }
+
+PathName ::= IA5String(SIZE (1..64))
+-- See A.3
+
+Transaction ::= CHOICE
+ {
+ transactionRequest TransactionRequest,
+ transactionPending TransactionPending,
+ transactionReply TransactionReply,
+ transactionResponseAck TransactionResponseAck,
+ -- use of response acks is dependent on underlying transport
+ ...,
+ segmentReply SegmentReply
+ }
+
+TransactionId ::= INTEGER(0..4294967295) -- 32-bit unsigned integer
+
+TransactionRequest ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ actions SEQUENCE OF ActionRequest,
+ ...
+ }
+
+TransactionPending ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ ...
+ }
+
+TransactionReply ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ immAckRequired NULL OPTIONAL,
+ transactionResult CHOICE
+ {
+ transactionError ErrorDescriptor,
+ actionReplies SEQUENCE OF ActionReply
+ },
+ ...,
+ segmentNumber SegmentNumber OPTIONAL,
+ segmentationComplete NULL OPTIONAL
+ }
+
+SegmentReply ::= SEQUENCE
+ {
+ transactionId TransactionId,
+ segmentNumber SegmentNumber,
+ segmentationComplete NULL OPTIONAL,
+ ...
+ }
+
+SegmentNumber ::= INTEGER(0..65535)
+
+TransactionResponseAck ::= SEQUENCE OF TransactionAck
+TransactionAck ::= SEQUENCE
+ {
+ firstAck TransactionId,
+ lastAck TransactionId OPTIONAL
+ }
+
+ErrorDescriptor ::= SEQUENCE
+ {
+ errorCode ErrorCode,
+ errorText ErrorText OPTIONAL
+ }
+
+ErrorCode ::= INTEGER(0..65535)
+-- See clause 14 for IANA considerations with respect to error codes
+ErrorText ::= IA5String
+
+ContextID ::= INTEGER(0..4294967295)
+-- Context NULL Value: 0
+-- Context CHOOSE Value: 4294967294 (0xFFFFFFFE)
+-- Context ALL Value: 4294967295 (0xFFFFFFFF)
+
+
+ActionRequest ::= SEQUENCE
+ {
+ contextId ContextID,
+ contextRequest ContextRequest OPTIONAL,
+ contextAttrAuditReq ContextAttrAuditRequest OPTIONAL,
+ commandRequests SEQUENCE OF CommandRequest
+ }
+
+ActionReply ::= SEQUENCE
+ {
+ contextId ContextID,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ contextReply ContextRequest OPTIONAL,
+ commandReply SEQUENCE OF CommandReply
+ }
+
+ContextRequest ::= SEQUENCE
+ {
+ priority INTEGER(0..15) OPTIONAL,
+ emergency BOOLEAN OPTIONAL,
+ topologyReq SEQUENCE OF TopologyRequest OPTIONAL,
+ ...,
+ iepscallind BOOLEAN OPTIONAL,
+ contextProp SEQUENCE OF PropertyParm OPTIONAL,
+ contextList SEQUENCE OF ContextID OPTIONAL
+ }
+-- When returning a contextList, the contextId in the ActionReply
+-- construct will return the contextId from the associated ActionRequest.
+
+ContextAttrAuditRequest ::= SEQUENCE
+ {
+ topology NULL OPTIONAL,
+ emergency NULL OPTIONAL,
+ priority NULL OPTIONAL,
+ ...,
+ iepscallind NULL OPTIONAL,
+ contextPropAud SEQUENCE OF IndAudPropertyParm OPTIONAL,
+
+ selectpriority INTEGER(0..15) OPTIONAL,
+ -- to select given priority
+
+ selectemergency BOOLEAN OPTIONAL,
+ -- to select if emergency set/not set (T/F)
+
+ selectiepscallind BOOLEAN OPTIONAL,
+ -- to select if IEPS set/not set (T/F)
+
+ selectLogic SelectLogic OPTIONAL -- default is AND
+ }
+
+SelectLogic ::= CHOICE
+ {
+ andAUDITSelect NULL, -- all selection conditions satisfied
+ orAUDITSelect NULL, -- at least one selection condition satisfied
+ ...
+ }
+
+
+CommandRequest ::= SEQUENCE
+ {
+ command Command,
+ optional NULL OPTIONAL,
+ wildcardReturn NULL OPTIONAL,
+ ...
+ }
+
+Command ::= CHOICE
+ {
+ addReq AmmRequest,
+ moveReq AmmRequest,
+ modReq AmmRequest,
+ -- Add, Move, Modify requests have the same parameters
+ subtractReq SubtractRequest,
+ auditCapRequest AuditRequest,
+ auditValueRequest AuditRequest,
+ notifyReq NotifyRequest,
+ serviceChangeReq ServiceChangeRequest,
+ ...
+ }
+
+CommandReply ::= CHOICE
+ {
+ addReply AmmsReply,
+ moveReply AmmsReply,
+ modReply AmmsReply,
+ subtractReply AmmsReply,
+ -- Add, Move, Modify, Subtract replies have the same parameters
+ auditCapReply AuditReply,
+ auditValueReply AuditReply,
+ notifyReply NotifyReply,
+ serviceChangeReply ServiceChangeReply,
+ ...
+ }
+
+TopologyRequest ::= SEQUENCE
+ {
+ terminationFrom TerminationID,
+ terminationTo TerminationID,
+ topologyDirection ENUMERATED
+ {
+ bothway(0),
+ isolate(1),
+ oneway(2)
+ },
+ ...,
+ streamID StreamID OPTIONAL,
+ topologyDirectionExtension ENUMERATED
+ {
+ onewayexternal(0),
+ onewayboth(1),
+ ...
+ } OPTIONAL
+ -- This is not according to the standard, but without it
+ -- the TopologyRequest will be useless since topologyDirection
+ -- and topologyDirectionExtension are contradictory.
+ }
+
+AmmRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ descriptors SEQUENCE OF AmmDescriptor,
+ -- At most one descriptor of each type (see AmmDescriptor)
+ -- allowed in the sequence.
+ ...
+ }
+
+AmmDescriptor ::= CHOICE
+ {
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ auditDescriptor AuditDescriptor,
+ ...,
+ statisticsDescriptor StatisticsDescriptor
+ }
+
+
+AmmsReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ terminationAudit TerminationAudit OPTIONAL,
+ ...
+ }
+
+SubtractRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ auditDescriptor AuditDescriptor OPTIONAL,
+ ...
+ }
+
+AuditRequest ::= SEQUENCE
+ {
+ terminationID TerminationID,
+ auditDescriptor AuditDescriptor,
+ ...,
+ terminationIDList TerminationIDList OPTIONAL
+ }
+-- terminationID shall contain the first termination in the
+-- list when using the terminationIDList construct in AuditRequest
+
+AuditReply ::= CHOICE
+ {
+ contextAuditResult TerminationIDList,
+ error ErrorDescriptor,
+ auditResult AuditResult,
+ ...,
+ auditResultTermList TermListAuditResult
+ }
+
+AuditResult ::= SEQUENCE
+ {
+
+ terminationID TerminationID,
+ terminationAuditResult TerminationAudit
+ }
+
+TermListAuditResult ::= SEQUENCE
+ {
+ terminationIDList TerminationIDList,
+ terminationAuditResult TerminationAudit,
+ ...
+ }
+
+TerminationAudit ::= SEQUENCE OF AuditReturnParameter
+
+AuditReturnParameter ::= CHOICE
+ {
+ errorDescriptor ErrorDescriptor,
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ statisticsDescriptor StatisticsDescriptor,
+ packagesDescriptor PackagesDescriptor,
+ emptyDescriptors AuditDescriptor,
+ ...
+ }
+
+AuditDescriptor ::= SEQUENCE
+ {
+ auditToken BIT STRING
+ {
+ muxToken(0), modemToken(1), mediaToken(2),
+ eventsToken(3), signalsToken(4),
+ digitMapToken(5), statsToken(6),
+ observedEventsToken(7),
+ packagesToken(8), eventBufferToken(9)
+ } OPTIONAL,
+ ...,
+ auditPropertyToken SEQUENCE OF IndAuditParameter OPTIONAL
+ }
+
+
+IndAuditParameter ::= CHOICE
+ {
+ -- Note that the lower/upper case letters of the tags have
+ -- been changed. The same changes has been made in text...
+ indAudMediaDescriptor IndAudMediaDescriptor,
+ indAudEventsDescriptor IndAudEventsDescriptor,
+ indAudEventBufferDescriptor IndAudEventBufferDescriptor,
+ indAudSignalsDescriptor IndAudSignalsDescriptor,
+ indAudDigitMapDescriptor IndAudDigitMapDescriptor,
+ indAudStatisticsDescriptor IndAudStatisticsDescriptor,
+ indAudPackagesDescriptor IndAudPackagesDescriptor,
+ ...
+ }
+
+IndAudMediaDescriptor ::= SEQUENCE
+ {
+
+ termStateDescr IndAudTerminationStateDescriptor OPTIONAL,
+ streams CHOICE
+ {
+ oneStream IndAudStreamParms,
+ multiStream SEQUENCE OF IndAudStreamDescriptor
+ } OPTIONAL,
+ ...
+ }
+
+IndAudStreamDescriptor ::= SEQUENCE
+ {
+ streamID StreamID,
+ streamParms IndAudStreamParms
+ }
+
+IndAudStreamParms ::= SEQUENCE
+ {
+ localControlDescriptor IndAudLocalControlDescriptor OPTIONAL,
+ localDescriptor IndAudLocalRemoteDescriptor OPTIONAL,
+ remoteDescriptor IndAudLocalRemoteDescriptor OPTIONAL,
+ ...,
+ statisticsDescriptor IndAudStatisticsDescriptor OPTIONAL
+ }
+
+IndAudLocalControlDescriptor ::= SEQUENCE
+ {
+ streamMode NULL OPTIONAL,
+ reserveValue NULL OPTIONAL,
+ reserveGroup NULL OPTIONAL,
+ propertyParms SEQUENCE OF IndAudPropertyParm OPTIONAL,
+ ...,
+ streamModeSel StreamMode OPTIONAL
+ -- must not have both streamMode and streamModeSel
+ -- if both are present only streamModeSel shall be honoured
+ }
+
+IndAudPropertyParm ::= SEQUENCE
+ {
+ name PkgdName,
+ ...,
+ propertyParms PropertyParm OPTIONAL
+ }
+-- to select based on property values
+-- AND/OR selection logic is specified at context level
+
+IndAudLocalRemoteDescriptor ::= SEQUENCE
+ {
+ propGroupID INTEGER(0..65535) OPTIONAL,
+ propGrps IndAudPropertyGroup,
+ ...
+ }
+
+IndAudPropertyGroup ::= SEQUENCE OF IndAudPropertyParm
+
+IndAudTerminationStateDescriptor ::= SEQUENCE
+ {
+ propertyParms SEQUENCE OF IndAudPropertyParm,
+ eventBufferControl NULL OPTIONAL,
+ serviceState NULL OPTIONAL,
+ ...,
+ serviceStateSel ServiceState OPTIONAL
+ -- must not have both serviceState and serviceStateSel
+ -- if both are present only serviceStateSel shall be honoured
+ }
+
+IndAudEventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...
+ }
+
+IndAudEventBufferDescriptor ::= SEQUENCE
+ {
+ eventName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...
+ }
+
+IndAudSignalsDescriptor ::=CHOICE
+ {
+ signal IndAudSignal,
+ seqSigList IndAudSeqSigList,
+ ...
+ }
+
+IndAudSeqSigList ::= SEQUENCE
+ {
+ id INTEGER(0..65535),
+ signalList IndAudSignal OPTIONAL
+ }
+
+IndAudSignal ::= SEQUENCE
+ {
+ signalName PkgdName,
+ streamID StreamID OPTIONAL,
+ ...,
+ signalRequestID RequestID OPTIONAL
+ }
+
+IndAudDigitMapDescriptor ::= SEQUENCE
+ {
+ digitMapName DigitMapName OPTIONAL
+ }
+
+IndAudStatisticsDescriptor ::= SEQUENCE
+ {
+ statName PkgdName
+ }
+
+IndAudPackagesDescriptor ::= SEQUENCE
+ {
+ packageName Name,
+ packageVersion INTEGER(0..99),
+ ...
+ }
+
+NotifyRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+ }
+
+NotifyReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+ }
+
+ObservedEventsDescriptor ::= SEQUENCE
+ {
+ requestId RequestID,
+ observedEventLst SEQUENCE OF ObservedEvent
+ }
+
+ObservedEvent ::= SEQUENCE
+ {
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ timeNotation TimeNotation OPTIONAL,
+ ...
+ }
+
+EventName ::= PkgdName
+
+EventParameter ::= SEQUENCE
+ {
+ eventParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to PropertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+
+ }
+
+ServiceChangeRequest ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ serviceChangeParms ServiceChangeParm,
+ ...
+ }
+
+ServiceChangeReply ::= SEQUENCE
+ {
+ terminationID TerminationIDList,
+ serviceChangeResult ServiceChangeResult,
+ ...
+ }
+
+-- For ServiceChangeResult, no parameters are mandatory. Hence the
+-- distinction between ServiceChangeParm and ServiceChangeResParm.
+ServiceChangeResult ::= CHOICE
+ {
+ errorDescriptor ErrorDescriptor,
+ serviceChangeResParms ServiceChangeResParm
+ }
+
+WildcardField ::= OCTET STRING(SIZE(1))
+
+TerminationID ::= SEQUENCE
+ {
+ wildcard SEQUENCE OF WildcardField,
+ id OCTET STRING(SIZE(1..8)),
+ ...
+ }
+-- See A.1 for explanation of wildcarding mechanism.
+-- Termination ID 0xFFFFFFFFFFFFFFFF indicates the ROOT Termination.
+
+TerminationIDList ::= SEQUENCE OF TerminationID
+
+MediaDescriptor ::= SEQUENCE
+ {
+ termStateDescr TerminationStateDescriptor OPTIONAL,
+ streams CHOICE
+ {
+ oneStream StreamParms,
+ multiStream SEQUENCE OF StreamDescriptor
+ } OPTIONAL,
+ ...
+ }
+
+StreamDescriptor ::= SEQUENCE
+ {
+ streamID StreamID,
+ streamParms StreamParms
+ }
+
+StreamParms ::= SEQUENCE
+ {
+ localControlDescriptor LocalControlDescriptor OPTIONAL,
+ localDescriptor LocalRemoteDescriptor OPTIONAL,
+ remoteDescriptor LocalRemoteDescriptor OPTIONAL,
+ ...,
+ statisticsDescriptor StatisticsDescriptor OPTIONAL
+ }
+
+LocalControlDescriptor ::= SEQUENCE
+ {
+ streamMode StreamMode OPTIONAL,
+ reserveValue BOOLEAN OPTIONAL,
+ reserveGroup BOOLEAN OPTIONAL,
+ propertyParms SEQUENCE OF PropertyParm,
+ ...
+ }
+
+StreamMode ::= ENUMERATED
+ {
+ sendOnly(0),
+ recvOnly(1),
+ sendRecv(2),
+ inactive(3),
+ loopBack(4),
+ ...
+ }
+
+-- In PropertyParm, value is a SEQUENCE OF octet string. When sent
+-- by an MGC the interpretation is as follows:
+-- empty sequence means CHOOSE
+-- one element sequence specifies value
+-- If the sublist field is not selected, a longer sequence means
+-- "choose one of the values" (i.e. value1 OR value2 OR ...)
+-- If the sublist field is selected,
+-- a sequence with more than one element encodes the value of a
+-- list-valued property (i.e. value1 AND value2 AND ...).
+-- The relation field may only be selected if the value sequence
+-- has length 1. It indicates that the MG has to choose a value
+-- for the property. E.g. x > 3 (using the greaterThan
+-- value for relation) instructs the MG to choose any value larger
+-- than 3 for property x.
+-- The range field may only be selected if the value sequence
+-- has length 2. It indicates that the MG has to choose a value
+-- in the range between the first octet in the value sequence and
+-- the trailing octet in the value sequence, including the
+-- boundary values.
+-- When sent by the MG, only responses to an AuditCapability request
+-- may contain multiple values, a range, or a relation field.
+
+PropertyParm ::= SEQUENCE
+ {
+ name PkgdName,
+ value SEQUENCE OF OCTET STRING,
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+ }
+
+Name ::= OCTET STRING(SIZE(2))
+
+PkgdName ::= OCTET STRING(SIZE(4))
+-- represents Package Name (2 octets) plus Property, Event,
+-- Signal Names or Statistics ID. (2 octets)
+-- To wildcard a package use 0xFFFF for first two octets, choose
+-- is not allowed. To reference native property tag specified in
+-- Annex C, use 0x0000 as first two octets.
+-- To wildcard a Property, Event, Signal, or Statistics ID, use
+-- 0xFFFF for last two octets, choose is not allowed.
+-- Wildcarding of Package Name is permitted only if Property,
+-- Event, Signal, or Statistics ID are
+-- also wildcarded.
+
+Relation ::= ENUMERATED
+ {
+ greaterThan(0),
+ smallerThan(1),
+ unequalTo(2),
+ ...
+ }
+
+LocalRemoteDescriptor ::= SEQUENCE
+ {
+ propGrps SEQUENCE OF PropertyGroup,
+ ...
+ }
+
+PropertyGroup ::= SEQUENCE OF PropertyParm
+
+TerminationStateDescriptor ::= SEQUENCE
+ {
+ propertyParms SEQUENCE OF PropertyParm,
+ eventBufferControl EventBufferControl OPTIONAL,
+ serviceState ServiceState OPTIONAL,
+ ...
+ }
+
+EventBufferControl ::= ENUMERATED
+ {
+ off(0),
+ lockStep(1),
+ ...
+ }
+
+ServiceState ::= ENUMERATED
+ {
+ test(0),
+ outOfSvc(1),
+ inSvc(2),
+ ...
+ }
+
+MuxDescriptor ::= SEQUENCE
+ {
+ muxType MuxType,
+ termList SEQUENCE OF TerminationID,
+ nonStandardData NonStandardData OPTIONAL,
+ ...
+ }
+
+MuxType ::= ENUMERATED
+ {
+ h221(0),
+ h223(1),
+ h226(2),
+ v76(3),
+ ...,
+ nx64k(4)
+ }
+
+StreamID ::= INTEGER(0..65535) -- 16-bit unsigned integer
+
+EventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ -- RequestID must be present if eventList
+ -- is non empty
+ eventList SEQUENCE OF RequestedEvent,
+ ...
+ }
+
+RequestedEvent ::= SEQUENCE
+ {
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction RequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+RegulatedEmbeddedDescriptor ::= SEQUENCE
+ {
+ secondEvent SecondEventsDescriptor OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+ }
+
+NotifyBehaviour ::= CHOICE
+ {
+ notifyImmediate NULL,
+ notifyRegulated RegulatedEmbeddedDescriptor,
+ neverNotify NULL,
+ ...
+ }
+
+RequestedActions ::= SEQUENCE
+ {
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ secondEvent SecondEventsDescriptor OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...,
+ notifyBehaviour NotifyBehaviour OPTIONAL,
+ resetEventsDescriptor NULL OPTIONAL
+ }
+
+EventDM ::= CHOICE
+ {
+ digitMapName DigitMapName,
+ digitMapValue DigitMapValue
+ }
+
+SecondEventsDescriptor ::= SEQUENCE
+ {
+ requestID RequestID OPTIONAL,
+ eventList SEQUENCE OF SecondRequestedEvent,
+ ...
+ }
+
+SecondRequestedEvent ::= SEQUENCE
+ {
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction SecondRequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+SecondRequestedActions ::= SEQUENCE
+ {
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...,
+ notifyBehaviour NotifyBehaviour OPTIONAL,
+ resetEventsDescriptor NULL OPTIONAL
+ }
+
+EventBufferDescriptor ::= SEQUENCE OF EventSpec
+
+EventSpec ::= SEQUENCE
+ {
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ ...
+ }
+
+
+SignalsDescriptor ::= SEQUENCE OF SignalRequest
+
+SignalRequest ::= CHOICE
+ {
+ signal Signal,
+ seqSigList SeqSigList,
+ ...
+ }
+
+SeqSigList ::= SEQUENCE
+ {
+ id INTEGER(0..65535),
+ signalList SEQUENCE OF Signal
+ }
+
+Signal ::= SEQUENCE
+ {
+ signalName SignalName,
+ streamID StreamID OPTIONAL,
+ sigType SignalType OPTIONAL,
+ duration INTEGER (0..65535) OPTIONAL,
+ notifyCompletion NotifyCompletion OPTIONAL,
+ keepActive BOOLEAN OPTIONAL,
+ sigParList SEQUENCE OF SigParameter,
+ ...,
+ direction SignalDirection OPTIONAL,
+ requestID RequestID OPTIONAL,
+ intersigDelay INTEGER (0..65535) OPTIONAL
+ }
+
+SignalType ::= ENUMERATED
+ {
+ brief(0),
+ onOff(1),
+ timeOut(2),
+ ...
+ }
+
+SignalDirection ::= ENUMERATED
+ {
+ internal(0),
+ external(1),
+ both(3),
+ ...
+ }
+
+SignalName ::= PkgdName
+
+NotifyCompletion ::= BIT STRING
+ {
+ onTimeOut(0), onInterruptByEvent(1),
+ onInterruptByNewSignalDescr(2), otherReason(3), onIteration(4)
+ }
+
+SigParameter ::= SEQUENCE
+ {
+ sigParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to PropertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+ }
+
+-- For an AuditCapReply with all events, the RequestID SHALL be ALL.
+-- ALL is represented by 0xffffffff.
+RequestID ::= INTEGER(0..4294967295) -- 32-bit unsigned integer
+
+ModemDescriptor ::= SEQUENCE
+ {
+ mtl SEQUENCE OF ModemType,
+ mpl SEQUENCE OF PropertyParm,
+ nonStandardData NonStandardData OPTIONAL
+ }
+
+ModemType ::= ENUMERATED
+ {
+ v18(0),
+ v22(1),
+ v22bis(2),
+ v32(3),
+ v32bis(4),
+ v34(5),
+ v90(6),
+ v91(7),
+ synchISDN(8),
+ ...
+ }
+
+DigitMapDescriptor ::= SEQUENCE
+ {
+ digitMapName DigitMapName OPTIONAL,
+ digitMapValue DigitMapValue OPTIONAL
+ }
+
+DigitMapName ::= Name
+
+DigitMapValue ::= SEQUENCE
+ {
+ startTimer INTEGER(0..99) OPTIONAL,
+ shortTimer INTEGER(0..99) OPTIONAL,
+ longTimer INTEGER(0..99) OPTIONAL,
+ digitMapBody IA5String,
+ -- Units are seconds for start, short and long timers, and
+ -- hundreds of milliseconds for duration timer. Thus start,
+ -- short, and long range from 1 to 99 seconds and duration
+ -- from 100 ms to 9.9 s
+ -- See A.3 for explanation of digit map syntax
+ ...,
+ durationTimer INTEGER (0..99) OPTIONAL
+ }
+
+ServiceChangeParm ::= SEQUENCE
+ {
+ serviceChangeMethod ServiceChangeMethod,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ serviceChangeReason Value,
+ -- A serviceChangeReason consists of a numeric reason code
+ -- and an optional text description.
+ -- The serviceChangeReason SHALL be a string consisting of
+ -- a decimal reason code, optionally followed by a single
+ -- space character and a textual description string.
+ -- This string is first BER-encoded as an IA5String.
+ -- The result of this BER-encoding is then encoded as
+ -- an ASN.1 OCTET STRING type, "double wrapping" the
+ -- value
+ -- as was done for package elements.
+ serviceChangeDelay INTEGER(0..4294967295) OPTIONAL,
+ -- 32-bit unsigned integer
+ serviceChangeMgcId MId OPTIONAL,
+ timeStamp TimeNotation OPTIONAL,
+ nonStandardData NonStandardData OPTIONAL,
+ ...,
+ serviceChangeInfo AuditDescriptor OPTIONAL,
+ serviceChangeIncompleteFlag NULL OPTIONAL
+ }
+
+ServiceChangeAddress ::= CHOICE
+ {
+ portNumber INTEGER(0..65535), -- TCP/UDP port number
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ ...
+ }
+
+ServiceChangeResParm ::= SEQUENCE
+ {
+ serviceChangeMgcId MId OPTIONAL,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ timestamp TimeNotation OPTIONAL,
+ ...
+ }
+
+ServiceChangeMethod ::= ENUMERATED
+ {
+ failover(0),
+ forced(1),
+ graceful(2),
+ restart(3),
+ disconnected(4),
+ handOff(5),
+ ...
+ }
+
+ServiceChangeProfile ::= SEQUENCE
+ {
+ profileName IA5String(SIZE (1..67))
+
+ -- 64 characters for name, 1 for "/", 2 for version to match ABNF
+ }
+
+PackagesDescriptor ::= SEQUENCE OF PackagesItem
+
+PackagesItem ::= SEQUENCE
+ {
+ packageName Name,
+ packageVersion INTEGER(0..99),
+ ...
+ }
+
+StatisticsDescriptor ::= SEQUENCE OF StatisticsParameter
+
+StatisticsParameter ::= SEQUENCE
+ {
+ statName PkgdName,
+ statValue Value OPTIONAL
+ }
+
+-- If statistic consists of a sub-list there will be more than one
+-- octetstring in statValue.
+
+NonStandardData ::= SEQUENCE
+ {
+ nonStandardIdentifier NonStandardIdentifier,
+ data OCTET STRING
+ }
+
+NonStandardIdentifier ::= CHOICE
+ {
+ object OBJECT IDENTIFIER,
+ h221NonStandard H221NonStandard,
+ experimental IA5String(SIZE(8)),
+ -- first two characters SHOULD be "X-" or "X+"
+ ...
+ }
+
+H221NonStandard ::= SEQUENCE
+ { t35CountryCode1 INTEGER(0..255),
+ t35CountryCode2 INTEGER(0..255), -- country, as per T.35
+ t35Extension INTEGER(0..255), -- assigned nationally
+ manufacturerCode INTEGER(0..65535), -- assigned nationally
+ ...
+ }
+
+TimeNotation ::= SEQUENCE
+ {
+ date IA5String(SIZE(8)), -- yyyymmdd format
+ time IA5String(SIZE(8)) -- hhmmssss format
+ -- per ISO 8601:1988
+ }
+
+Value ::= SEQUENCE OF OCTET STRING
+
+END
diff --git a/lib/megaco/src/binary/Makefile b/lib/megaco/src/binary/Makefile
new file mode 100644
index 0000000000..d594f34f43
--- /dev/null
+++ b/lib/megaco/src/binary/Makefile
@@ -0,0 +1,212 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+include $(ERL_TOP)/make/target.mk
+
+EBIN = ../../ebin
+MEGACO_INCLUDEDIR = ../../include
+MEGACO_ENGINEDIR = ../engine
+
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../../vsn.mk
+VSN=$(MEGACO_VSN)
+
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/megaco-$(VSN)
+
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+include modules.mk
+
+ASN1_SPECS = $(ASN1_V1_SPEC) \
+ $(ASN1_V2_SPEC) \
+ $(ASN1_PREV3A_SPEC)
+ASN1_FILES = $(ASN1_SPECS:%=%.asn)
+
+V1_SPECS = $(BER_ASN1_V1_SPEC) \
+ $(BER_BIN_ASN1_V1_SPEC) \
+ $(BER_BIN_DRV_ASN1_V1_SPEC) \
+ $(PER_ASN1_V1_SPEC) \
+ $(PER_BIN_ASN1_V1_SPEC) \
+ $(PER_BIN_DRV_ASN1_V1_SPEC)
+
+V2_SPECS = $(BER_ASN1_V2_SPEC) \
+ $(BER_BIN_ASN1_V2_SPEC) \
+ $(BER_BIN_DRV_ASN1_V2_SPEC) \
+ $(PER_ASN1_V2_SPEC) \
+ $(PER_BIN_ASN1_V2_SPEC) \
+ $(PER_BIN_DRV_ASN1_V2_SPEC)
+
+PREV3A_SPECS = $(BER_ASN1_PREV3A_SPEC) \
+ $(BER_BIN_ASN1_PREV3A_SPEC) \
+ $(BER_BIN_DRV_ASN1_PREV3A_SPEC) \
+ $(PER_ASN1_PREV3A_SPEC) \
+ $(PER_BIN_ASN1_PREV3A_SPEC) \
+ $(PER_BIN_DRV_ASN1_PREV3A_SPEC)
+
+PREV3B_SPECS = $(BER_ASN1_PREV3B_SPEC) \
+ $(BER_BIN_ASN1_PREV3B_SPEC) \
+ $(BER_BIN_DRV_ASN1_PREV3B_SPEC) \
+ $(PER_ASN1_PREV3B_SPEC) \
+ $(PER_BIN_ASN1_PREV3B_SPEC) \
+ $(PER_BIN_DRV_ASN1_PREV3B_SPEC)
+
+PREV3C_SPECS = $(BER_ASN1_PREV3C_SPEC) \
+ $(BER_BIN_ASN1_PREV3C_SPEC) \
+ $(BER_BIN_DRV_ASN1_PREV3C_SPEC) \
+ $(PER_ASN1_PREV3C_SPEC) \
+ $(PER_BIN_ASN1_PREV3C_SPEC) \
+ $(PER_BIN_DRV_ASN1_PREV3C_SPEC)
+
+V3_SPECS = $(BER_ASN1_V3_SPEC) \
+ $(BER_BIN_ASN1_V3_SPEC) \
+ $(BER_BIN_DRV_ASN1_V3_SPEC) \
+ $(PER_ASN1_V3_SPEC) \
+ $(PER_BIN_ASN1_V3_SPEC) \
+ $(PER_BIN_DRV_ASN1_V3_SPEC) \
+ $(PREV3A_SPECS) $(PREV3B_SPECS) $(PREV3C_SPECS)
+
+SPECS = $(V1_SPECS) $(V2_SPECS) $(V3_SPECS)
+
+V1_SPEC_ASN1DB = $(V1_SPECS:%=%.asn1db)
+V2_SPEC_ASN1DB = $(V2_SPECS:%=%.asn1db)
+PREV3A_SPEC_ASN1DB = $(PREV3A_SPECS:%=%.asn1db)
+PREV3B_SPEC_ASN1DB = $(PREV3B_SPECS:%=%.asn1db)
+PREV3C_SPEC_ASN1DB = $(PREV3C_SPECS:%=%.asn1db)
+V3_SPEC_ASN1DB = $(V3_SPECS:%=%.asn1db) \
+ $(PREV3A_SPEC_ASN1DB) \
+ $(PREV3B_SPEC_ASN1DB) \
+ $(PREV3C_SPEC_ASN1DB)
+SPEC_ASN1DB = $(V1_SPEC_ASN1DB) \
+ $(V2_SPEC_ASN1DB)\
+ $(V3_SPEC_ASN1DB)
+
+V1_SPEC_BINS = $(V1_SPECS:%=%.erl) $(V1_SPECS:%=%.hrl)
+V2_SPEC_BINS = $(V2_SPECS:%=%.erl) $(V2_SPECS:%=%.hrl)
+PREV3A_SPEC_BINS = $(PREV3A_SPECS:%=%.erl) $(PREV3A_SPECS:%=%.hrl)
+PREV3B_SPEC_BINS = $(PREV3B_SPECS:%=%.erl) $(PREV3B_SPECS:%=%.hrl)
+PREV3C_SPEC_BINS = $(PREV3C_SPECS:%=%.erl) $(PREV3C_SPECS:%=%.hrl)
+V3_SPEC_BINS = $(V3_SPECS:%=%.erl) $(V3_SPECS:%=%.hrl) \
+ $(PREV3A_SPEC_BINS) \
+ $(PREV3B_SPEC_BINS) \
+ $(PREV3C_SPEC_BINS)
+SPEC_BINS = $(V1_SPEC_BINS) $(V2_SPEC_BINS) $(V3_SPEC_BINS)
+
+ERL_FILES = $(MODULES:%=%.erl)
+HRL_FILES = $(INTERNAL_HRL_FILES) \
+ $(V1_SPECS:%=%.hrl) \
+ $(V2_SPECS:%=%.hrl) \
+ $(V3_SPECS:%=%.hrl)
+
+TARGET_FILES = \
+ $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ifeq ($(TYPE),debug)
+ERL_COMPILE_FLAGS += -Ddebug
+endif
+
+include ../app/megaco.mk
+
+ERL_COMPILE_FLAGS += \
+ $(MEGACO_ERL_COMPILE_FLAGS) \
+ -I../../include
+
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+debug:
+ @${MAKE} TYPE=debug opt
+
+opt: prebuild $(TARGET_FILES)
+
+prebuild: prebuild.skip
+
+prebuild.skip:
+ @echo "Building prebuild.skip\c"
+ @touch prebuild.skip
+ @for a in $(SPEC_ASN1DB); do \
+ echo $$a >> prebuild.skip; \
+ done
+ @echo ""
+
+v1: $(V2_SPEC_BINS)
+
+v2: $(V2_SPEC_BINS)
+
+v3: $(V3_SPEC_BINS)
+
+specs: v1 v2 v3
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f $(SPEC_BINS)
+ rm -f $(SPEC_ASN1DB)
+ rm -f prebuild.skip
+ rm -f core *~
+
+docs:
+
+info:
+ @echo "MODULES: $(MODULES)"
+ @echo "ERL_FILES: $(ERL_FILES)"
+ @echo "HRL_FILES: $(HRL_FILES)"
+ @echo "TARGET_FILES: $(TARGET_FILES)"
+ @echo "ASN1_SPECS: $(ASN1_SPECS)"
+ @echo "SPECS: $(SPECS)"
+ @echo "SPEC_BINS: $(SPEC_BINS)"
+
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+
+release_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)/ebin
+ $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin
+ $(INSTALL_DIR) $(RELSYSDIR)/src
+ $(INSTALL_DIR) $(RELSYSDIR)/src/binary
+ $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(ASN1_FILES) $(RELSYSDIR)/src/binary
+
+
+release_docs_spec:
+
+
+# ----------------------------------------------------
+# Include dependencies
+# ----------------------------------------------------
+
+include depend.mk
+
diff --git a/lib/megaco/src/binary/depend.mk b/lib/megaco/src/binary/depend.mk
new file mode 100644
index 0000000000..5ec4977175
--- /dev/null
+++ b/lib/megaco/src/binary/depend.mk
@@ -0,0 +1,557 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+# Flag description:
+#
+# +optimize
+# For ber_bin this means "optimize" (whatever that is),
+# but for per_bin it means that a stage in the encode
+# is done in the asn1 driver.
+#
+# +driver
+# For ber_bin this means that part of the decode is done
+# in the asn1 driver.
+#
+# +asn1config
+# This is only used by the ber_bin, and means that
+# some partial decode functions will be created
+# (as described by the asn1config file).
+#
+# +inline
+# This means that the ASN.1 runtime library will be inlined.
+#
+
+ASN1_CT_OPTS += +noobj
+ifeq ($(MEGACO_INLINE_ASN1_RT),true)
+# We need atleast version 1.4.6 of the ANS.1 application
+ASN1_CT_OPTS += +inline
+endif
+
+BER_V1_FLAGS = $(ASN1_CT_OPTS)
+BER_BIN_V1_FLAGS = $(ASN1_CT_OPTS) +asn1config +optimize
+BER_BIN_DRV_V1_FLAGS = $(ASN1_CT_OPTS) +asn1config +optimize +driver
+BER_V2_FLAGS = $(ASN1_CT_OPTS)
+BER_BIN_V2_FLAGS = $(ASN1_CT_OPTS) +asn1config +optimize
+BER_BIN_DRV_V2_FLAGS = $(ASN1_CT_OPTS) +asn1config +optimize +driver
+BER_PREV3A_FLAGS = $(ASN1_CT_OPTS)
+BER_BIN_PREV3A_FLAGS = $(ASN1_CT_OPTS) +asn1config +optimize
+BER_BIN_DRV_PREV3A_FLAGS = $(ASN1_CT_OPTS) +asn1config +optimize +driver
+BER_PREV3B_FLAGS = $(ASN1_CT_OPTS)
+BER_BIN_PREV3B_FLAGS = $(ASN1_CT_OPTS) +asn1config +optimize
+BER_BIN_DRV_PREV3B_FLAGS = $(ASN1_CT_OPTS) +asn1config +optimize +driver
+BER_PREV3C_FLAGS = $(ASN1_CT_OPTS)
+BER_BIN_PREV3C_FLAGS = $(ASN1_CT_OPTS) +asn1config +optimize
+BER_BIN_DRV_PREV3C_FLAGS = $(ASN1_CT_OPTS) +asn1config +optimize +driver
+BER_V3_FLAGS = $(ASN1_CT_OPTS)
+BER_BIN_V3_FLAGS = $(ASN1_CT_OPTS) +asn1config +optimize
+BER_BIN_DRV_V3_FLAGS = $(ASN1_CT_OPTS) +asn1config +optimize +driver
+PER_V1_FLAGS = $(ASN1_CT_OPTS)
+PER_BIN_V1_FLAGS = $(ASN1_CT_OPTS)
+PER_BIN_DRV_V1_FLAGS = $(ASN1_CT_OPTS) +optimize
+PER_V2_FLAGS = $(ASN1_CT_OPTS)
+PER_BIN_V2_FLAGS = $(ASN1_CT_OPTS)
+PER_BIN_DRV_V2_FLAGS = $(ASN1_CT_OPTS) +optimize
+PER_PREV3A_FLAGS = $(ASN1_CT_OPTS)
+PER_BIN_PREV3A_FLAGS = $(ASN1_CT_OPTS)
+PER_BIN_DRV_PREV3A_FLAGS = $(ASN1_CT_OPTS) +optimize
+PER_PREV3B_FLAGS = $(ASN1_CT_OPTS)
+PER_BIN_PREV3B_FLAGS = $(ASN1_CT_OPTS)
+PER_BIN_DRV_PREV3B_FLAGS = $(ASN1_CT_OPTS) +optimize
+PER_PREV3C_FLAGS = $(ASN1_CT_OPTS)
+PER_BIN_PREV3C_FLAGS = $(ASN1_CT_OPTS)
+PER_BIN_DRV_PREV3C_FLAGS = $(ASN1_CT_OPTS) +optimize
+PER_V3_FLAGS = $(ASN1_CT_OPTS)
+PER_BIN_V3_FLAGS = $(ASN1_CT_OPTS)
+PER_BIN_DRV_V3_FLAGS = $(ASN1_CT_OPTS) +optimize
+
+
+# --- Version 1 ---
+
+$(BER_ASN1_V1_SPEC).erl $(BER_ASN1_V1_SPEC).hrl: \
+ $(BER_ASN1_V1_SPEC).set.asn \
+ $(ASN1_V1_SPEC).asn
+ @echo "$(BER_ASN1_V1_SPEC):"
+ $(ERLC) -bber $(BER_V1_FLAGS) $(BER_ASN1_V1_SPEC).set.asn
+
+$(EBIN)/$(BER_ASN1_V1_SPEC).$(EMULATOR): \
+ $(BER_ASN1_V1_SPEC).erl \
+ $(BER_ASN1_V1_SPEC).hrl
+
+$(BER_BIN_ASN1_V1_SPEC).erl $(BER_BIN_ASN1_V1_SPEC).hrl: \
+ $(BER_BIN_ASN1_V1_SPEC).set.asn \
+ $(BER_BIN_ASN1_V1_SPEC).asn1config \
+ $(ASN1_V1_SPEC).asn
+ @echo "$(BER_BIN_ASN1_V1_SPEC):"
+ $(ERLC) -bber_bin $(BER_BIN_V1_FLAGS) $(BER_BIN_ASN1_V1_SPEC).set.asn
+
+$(EBIN)/$(BER_BIN_ASN1_V1_SPEC).$(EMULATOR): \
+ $(BER_BIN_ASN1_V1_SPEC).erl \
+ $(BER_BIN_ASN1_V1_SPEC).hrl
+
+$(BER_BIN_DRV_ASN1_V1_SPEC).erl $(BER_BIN_DRV_ASN1_V1_SPEC).hrl: \
+ $(BER_BIN_DRV_ASN1_V1_SPEC).set.asn \
+ $(BER_BIN_DRV_ASN1_V1_SPEC).asn1config \
+ $(ASN1_V1_SPEC).asn
+ @echo "$(BER_BIN_DRV_ASN1_V1_SPEC):"
+ $(ERLC) -bber_bin $(BER_BIN_DRV_V1_FLAGS) $(BER_BIN_DRV_ASN1_V1_SPEC).set.asn
+
+$(EBIN)/$(BER_BIN_DRV_ASN1_V1_SPEC).$(EMULATOR): \
+ $(BER_BIN_DRV_ASN1_V1_SPEC).erl \
+ $(BER_BIN_DRV_ASN1_V1_SPEC).hrl
+
+$(PER_ASN1_V1_SPEC).erl $(PER_ASN1_V1_SPEC).hrl: \
+ $(PER_ASN1_V1_SPEC).set.asn \
+ $(ASN1_V1_SPEC).asn
+ @echo "$(PER_ASN1_V1_SPEC):"
+ $(ERLC) -bper $(PER_V1_FLAGS) $(PER_ASN1_V1_SPEC).set.asn
+
+$(EBIN)/$(PER_ASN1_V1_SPEC).$(EMULATOR): \
+ $(PER_ASN1_V1_SPEC).erl \
+ $(PER_ASN1_V1_SPEC).hrl
+
+$(PER_BIN_ASN1_V1_SPEC).erl $(PER_BIN_ASN1_V1_SPEC).hrl: \
+ $(PER_BIN_ASN1_V1_SPEC).set.asn \
+ $(ASN1_V1_SPEC).asn
+ @echo "$(PER_BIN_ASN1_V1_SPEC):"
+ $(ERLC) -bper_bin $(PER_BIN_V1_FLAGS) $(PER_BIN_ASN1_V1_SPEC).set.asn
+
+$(EBIN)/$(PER_BIN_ASN1_V1_SPEC).$(EMULATOR): \
+ $(PER_BIN_ASN1_V1_SPEC).erl \
+ $(PER_BIN_ASN1_V1_SPEC).hrl
+
+$(PER_BIN_DRV_ASN1_V1_SPEC).erl $(PER_BIN_DRV_ASN1_V1_SPEC).hrl: \
+ $(PER_BIN_DRV_ASN1_V1_SPEC).set.asn \
+ $(ASN1_V1_SPEC).asn
+ @echo "$(PER_BIN_DRV_ASN1_V1_SPEC):"
+ $(ERLC) -bper_bin $(PER_BIN_DRV_V1_FLAGS) $(PER_BIN_DRV_ASN1_V1_SPEC).set.asn
+
+$(EBIN)/$(PER_BIN_DRV_ASN1_V1_SPEC).$(EMULATOR): \
+ $(PER_BIN_DRV_ASN1_V1_SPEC).erl \
+ $(PER_BIN_DRV_ASN1_V1_SPEC).hrl
+
+
+# --- Version 2 ---
+
+$(BER_ASN1_V2_SPEC).erl $(BER_ASN1_V2_SPEC).hrl: \
+ $(BER_ASN1_V2_SPEC).set.asn \
+ $(ASN1_V2_SPEC).asn
+ @echo "$(BER_ASN1_V2_SPEC):"
+ $(ERLC) -bber $(BER_V2_FLAGS) $(BER_ASN1_V2_SPEC).set.asn
+
+$(EBIN)/$(BER_ASN1_V2_SPEC).$(EMULATOR): \
+ $(BER_ASN1_V2_SPEC).erl \
+ $(BER_ASN1_V2_SPEC).hrl
+
+$(BER_BIN_ASN1_V2_SPEC).erl $(BER_BIN_ASN1_V2_SPEC).hrl: \
+ $(BER_BIN_ASN1_V2_SPEC).set.asn \
+ $(BER_BIN_ASN1_V2_SPEC).asn1config \
+ $(ASN1_V2_SPEC).asn
+ @echo "$(BER_BIN_ASN1_V2_SPEC):"
+ $(ERLC) -bber_bin $(BER_BIN_V2_FLAGS) $(BER_BIN_ASN1_V2_SPEC).set.asn
+
+$(EBIN)/$(BER_BIN_ASN1_V2_SPEC).$(EMULATOR): \
+ $(BER_BIN_ASN1_V2_SPEC).erl \
+ $(BER_BIN_ASN1_V2_SPEC).hrl
+
+$(BER_BIN_DRV_ASN1_V2_SPEC).erl $(BER_BIN_DRV_ASN1_V2_SPEC).hrl: \
+ $(BER_BIN_DRV_ASN1_V2_SPEC).set.asn \
+ $(BER_BIN_DRV_ASN1_V2_SPEC).asn1config \
+ $(ASN1_V2_SPEC).asn
+ @echo "$(BER_BIN_DRV_ASN1_V2_SPEC):"
+ $(ERLC) -bber_bin $(BER_BIN_DRV_V2_FLAGS) $(BER_BIN_DRV_ASN1_V2_SPEC).set.asn
+
+$(EBIN)/$(BER_BIN_DRV_ASN1_V2_SPEC).$(EMULATOR): \
+ $(BER_BIN_DRV_ASN1_V2_SPEC).erl \
+ $(BER_BIN_DRV_ASN1_V2_SPEC).hrl
+
+$(PER_ASN1_V2_SPEC).erl $(PER_ASN1_V2_SPEC).hrl: \
+ $(PER_ASN1_V2_SPEC).set.asn \
+ $(ASN1_V2_SPEC).asn
+ @echo "$(PER_ASN1_V2_SPEC):"
+ $(ERLC) -bper $(PER_V2_FLAGS) $(PER_ASN1_V2_SPEC).set.asn
+
+$(EBIN)/$(PER_ASN1_V2_SPEC).$(EMULATOR): \
+ $(PER_ASN1_V2_SPEC).erl \
+ $(PER_ASN1_V2_SPEC).hrl
+
+$(PER_BIN_ASN1_V2_SPEC).erl $(PER_BIN_ASN1_V2_SPEC).hrl: \
+ $(PER_BIN_ASN1_V2_SPEC).set.asn \
+ $(ASN1_V2_SPEC).asn
+ @echo "$(PER_BIN_ASN1_V2_SPEC):"
+ $(ERLC) -bper_bin $(PER_BIN_V2_FLAGS) $(PER_BIN_ASN1_V2_SPEC).set.asn
+
+$(EBIN)/$(PER_BIN_ASN1_V2_SPEC).$(EMULATOR): \
+ $(PER_BIN_ASN1_V2_SPEC).erl \
+ $(PER_BIN_ASN1_V2_SPEC).hrl
+
+$(PER_BIN_DRV_ASN1_V2_SPEC).erl $(PER_BIN_DRV_ASN1_V2_SPEC).hrl: \
+ $(PER_BIN_DRV_ASN1_V2_SPEC).set.asn \
+ $(ASN1_V2_SPEC).asn
+ @echo "$(PER_BIN_DRV_ASN1_V2_SPEC):"
+ $(ERLC) -bper_bin $(PER_BIN_DRV_V2_FLAGS) $(PER_BIN_DRV_ASN1_V2_SPEC).set.asn
+
+$(EBIN)/$(PER_BIN_DRV_ASN1_V2_SPEC).$(EMULATOR): \
+ $(PER_BIN_DRV_ASN1_V2_SPEC).erl \
+ $(PER_BIN_DRV_ASN1_V2_SPEC).hrl
+
+
+# --- Version 3 ---
+
+# -- (prev3a) --
+
+$(BER_ASN1_PREV3A_SPEC).erl $(BER_ASN1_PREV3A_SPEC).hrl: \
+ $(BER_ASN1_PREV3A_SPEC).set.asn \
+ $(ASN1_PREV3A_SPEC).asn
+ @echo "$(BER_ASN1_PREV3A_SPEC):"
+ $(ERLC) -bber $(BER_PREV3A_FLAGS) $(BER_ASN1_PREV3A_SPEC).set.asn
+
+$(EBIN)/$(BER_ASN1_PREV3A_SPEC).$(EMULATOR): \
+ $(BER_ASN1_PREV3A_SPEC).erl \
+ $(BER_ASN1_PREV3A_SPEC).hrl
+
+$(BER_BIN_ASN1_PREV3A_SPEC).erl $(BER_BIN_ASN1_PREV3A_SPEC).hrl: \
+ $(BER_BIN_ASN1_PREV3A_SPEC).set.asn \
+ $(BER_BIN_ASN1_PREV3A_SPEC).asn1config \
+ $(ASN1_PREV3A_SPEC).asn
+ @echo "$(BER_BIN_ASN1_PREV3A_SPEC):"
+ $(ERLC) -bber_bin $(BER_BIN_PREV3A_FLAGS) $(BER_BIN_ASN1_PREV3A_SPEC).set.asn
+
+$(EBIN)/$(BER_BIN_ASN1_PREV3A_SPEC).$(EMULATOR): \
+ $(BER_BIN_ASN1_PREV3A_SPEC).erl \
+ $(BER_BIN_ASN1_PREV3A_SPEC).hrl
+
+$(BER_BIN_DRV_ASN1_PREV3A_SPEC).erl $(BER_BIN_DRV_ASN1_PREV3A_SPEC).hrl: \
+ $(BER_BIN_DRV_ASN1_PREV3A_SPEC).set.asn \
+ $(BER_BIN_DRV_ASN1_PREV3A_SPEC).asn1config \
+ $(ASN1_PREV3A_SPEC).asn
+ @echo "$(BER_BIN_DRV_ASN1_PREV3A_SPEC):"
+ $(ERLC) -bber_bin $(BER_BIN_DRV_PREV3A_FLAGS) $(BER_BIN_DRV_ASN1_PREV3A_SPEC).set.asn
+
+$(EBIN)/$(BER_BIN_DRV_ASN1_PREV3A_SPEC).$(EMULATOR): \
+ $(BER_BIN_DRV_ASN1_PREV3A_SPEC).erl \
+ $(BER_BIN_DRV_ASN1_PREV3A_SPEC).hrl
+
+$(PER_ASN1_PREV3A_SPEC).erl $(PER_ASN1_PREV3A_SPEC).hrl: \
+ $(PER_ASN1_PREV3A_SPEC).set.asn \
+ $(ASN1_PREV3A_SPEC).asn
+ @echo "$(PER_ASN1_PREV3A_SPEC):"
+ $(ERLC) -bper $(PER_PREV3A_FLAGS) $(PER_ASN1_PREV3A_SPEC).set.asn
+
+$(EBIN)/$(PER_ASN1_PREV3A_SPEC).$(EMULATOR): \
+ $(PER_ASN1_PREV3A_SPEC).erl \
+ $(PER_ASN1_PREV3A_SPEC).hrl
+
+$(PER_BIN_ASN1_PREV3A_SPEC).erl $(PER_BIN_ASN1_PREV3A_SPEC).hrl: \
+ $(PER_BIN_ASN1_PREV3A_SPEC).set.asn \
+ $(ASN1_PREV3A_SPEC).asn
+ @echo "$(PER_BIN_ASN1_PREV3A_SPEC):"
+ $(ERLC) -bper_bin $(PER_BIN_PREV3A_FLAGS) $(PER_BIN_ASN1_PREV3A_SPEC).set.asn
+
+$(EBIN)/$(PER_BIN_ASN1_PREV3A_SPEC).$(EMULATOR): \
+ $(PER_BIN_ASN1_PREV3A_SPEC).erl \
+ $(PER_BIN_ASN1_PREV3A_SPEC).hrl
+
+$(PER_BIN_DRV_ASN1_PREV3A_SPEC).erl $(PER_BIN_DRV_ASN1_PREV3A_SPEC).hrl: \
+ $(PER_BIN_DRV_ASN1_PREV3A_SPEC).set.asn \
+ $(ASN1_PREV3A_SPEC).asn
+ @echo "$(PER_BIN_DRV_ASN1_PREV3A_SPEC):"
+ $(ERLC) -bper_bin $(PER_BIN_DRV_PREV3A_FLAGS) $(PER_BIN_DRV_ASN1_PREV3A_SPEC).set.asn
+
+$(EBIN)/$(PER_BIN_DRV_ASN1_PREV3A_SPEC).$(EMULATOR): \
+ $(PER_BIN_DRV_ASN1_PREV3A_SPEC).erl \
+ $(PER_BIN_DRV_ASN1_PREV3A_SPEC).hrl
+
+# -- (prev3b) --
+
+$(BER_ASN1_PREV3B_SPEC).erl $(BER_ASN1_PREV3B_SPEC).hrl: \
+ $(BER_ASN1_PREV3B_SPEC).set.asn \
+ $(ASN1_PREV3B_SPEC).asn
+ @echo "$(BER_ASN1_PREV3B_SPEC):"
+ $(ERLC) -bber $(BER_PREV3B_FLAGS) $(BER_ASN1_PREV3B_SPEC).set.asn
+
+$(EBIN)/$(BER_ASN1_PREV3B_SPEC).$(EMULATOR): \
+ $(BER_ASN1_PREV3B_SPEC).erl \
+ $(BER_ASN1_PREV3B_SPEC).hrl
+
+$(BER_BIN_ASN1_PREV3B_SPEC).erl $(BER_BIN_ASN1_PREV3B_SPEC).hrl: \
+ $(BER_BIN_ASN1_PREV3B_SPEC).set.asn \
+ $(BER_BIN_ASN1_PREV3B_SPEC).asn1config \
+ $(ASN1_PREV3B_SPEC).asn
+ @echo "$(BER_BIN_ASN1_PREV3B_SPEC):"
+ $(ERLC) -bber_bin $(BER_BIN_PREV3B_FLAGS) $(BER_BIN_ASN1_PREV3B_SPEC).set.asn
+
+$(EBIN)/$(BER_BIN_ASN1_PREV3B_SPEC).$(EMULATOR): \
+ $(BER_BIN_ASN1_PREV3B_SPEC).erl \
+ $(BER_BIN_ASN1_PREV3B_SPEC).hrl
+
+$(BER_BIN_DRV_ASN1_PREV3B_SPEC).erl $(BER_BIN_DRV_ASN1_PREV3B_SPEC).hrl: \
+ $(BER_BIN_DRV_ASN1_PREV3B_SPEC).set.asn \
+ $(BER_BIN_DRV_ASN1_PREV3B_SPEC).asn1config \
+ $(ASN1_PREV3B_SPEC).asn
+ @echo "$(BER_BIN_DRV_ASN1_PREV3B_SPEC):"
+ $(ERLC) -bber_bin $(BER_BIN_DRV_PREV3B_FLAGS) $(BER_BIN_DRV_ASN1_PREV3B_SPEC).set.asn
+
+$(EBIN)/$(BER_BIN_DRV_ASN1_PREV3B_SPEC).$(EMULATOR): \
+ $(BER_BIN_DRV_ASN1_PREV3B_SPEC).erl \
+ $(BER_BIN_DRV_ASN1_PREV3B_SPEC).hrl
+
+$(PER_ASN1_PREV3B_SPEC).erl $(PER_ASN1_PREV3B_SPEC).hrl: \
+ $(PER_ASN1_PREV3B_SPEC).set.asn \
+ $(ASN1_PREV3B_SPEC).asn
+ @echo "$(PER_ASN1_PREV3B_SPEC):"
+ $(ERLC) -bper $(PER_PREV3B_FLAGS) $(PER_ASN1_PREV3B_SPEC).set.asn
+
+$(EBIN)/$(PER_ASN1_PREV3B_SPEC).$(EMULATOR): \
+ $(PER_ASN1_PREV3B_SPEC).erl \
+ $(PER_ASN1_PREV3B_SPEC).hrl
+
+$(PER_BIN_ASN1_PREV3B_SPEC).erl $(PER_BIN_ASN1_PREV3B_SPEC).hrl: \
+ $(PER_BIN_ASN1_PREV3B_SPEC).set.asn \
+ $(ASN1_PREV3B_SPEC).asn
+ @echo "$(PER_BIN_ASN1_PREV3B_SPEC):"
+ $(ERLC) -bper_bin $(PER_BIN_PREV3B_FLAGS) $(PER_BIN_ASN1_PREV3B_SPEC).set.asn
+
+$(EBIN)/$(PER_BIN_ASN1_PREV3B_SPEC).$(EMULATOR): \
+ $(PER_BIN_ASN1_PREV3B_SPEC).erl \
+ $(PER_BIN_ASN1_PREV3B_SPEC).hrl
+
+$(PER_BIN_DRV_ASN1_PREV3B_SPEC).erl $(PER_BIN_DRV_ASN1_PREV3B_SPEC).hrl: \
+ $(PER_BIN_DRV_ASN1_PREV3B_SPEC).set.asn \
+ $(ASN1_PREV3B_SPEC).asn
+ @echo "$(PER_BIN_DRV_ASN1_PREV3B_SPEC):"
+ $(ERLC) -bper_bin $(PER_BIN_DRV_PREV3B_FLAGS) $(PER_BIN_DRV_ASN1_PREV3B_SPEC).set.asn
+
+$(EBIN)/$(PER_BIN_DRV_ASN1_PREV3B_SPEC).$(EMULATOR): \
+ $(PER_BIN_DRV_ASN1_PREV3B_SPEC).erl \
+ $(PER_BIN_DRV_ASN1_PREV3B_SPEC).hrl
+
+
+# -- (prev3c) --
+
+$(BER_ASN1_PREV3C_SPEC).erl $(BER_ASN1_PREV3C_SPEC).hrl: \
+ $(BER_ASN1_PREV3C_SPEC).set.asn \
+ $(ASN1_PREV3C_SPEC).asn
+ @echo "$(BER_ASN1_PREV3C_SPEC):"
+ $(ERLC) -bber $(BER_PREV3C_FLAGS) $(BER_ASN1_PREV3C_SPEC).set.asn
+
+$(EBIN)/$(BER_ASN1_PREV3C_SPEC).$(EMULATOR): \
+ $(BER_ASN1_PREV3C_SPEC).erl \
+ $(BER_ASN1_PREV3C_SPEC).hrl
+
+$(BER_BIN_ASN1_PREV3C_SPEC).erl $(BER_BIN_ASN1_PREV3C_SPEC).hrl: \
+ $(BER_BIN_ASN1_PREV3C_SPEC).set.asn \
+ $(BER_BIN_ASN1_PREV3C_SPEC).asn1config \
+ $(ASN1_PREV3C_SPEC).asn
+ @echo "$(BER_BIN_ASN1_PREV3C_SPEC):"
+ $(ERLC) -bber_bin $(BER_BIN_PREV3C_FLAGS) $(BER_BIN_ASN1_PREV3C_SPEC).set.asn
+
+$(EBIN)/$(BER_BIN_ASN1_PREV3C_SPEC).$(EMULATOR): \
+ $(BER_BIN_ASN1_PREV3C_SPEC).erl \
+ $(BER_BIN_ASN1_PREV3C_SPEC).hrl
+
+$(BER_BIN_DRV_ASN1_PREV3C_SPEC).erl $(BER_BIN_DRV_ASN1_PREV3C_SPEC).hrl: \
+ $(BER_BIN_DRV_ASN1_PREV3C_SPEC).set.asn \
+ $(BER_BIN_DRV_ASN1_PREV3C_SPEC).asn1config \
+ $(ASN1_PREV3C_SPEC).asn
+ @echo "$(BER_BIN_DRV_ASN1_PREV3C_SPEC):"
+ $(ERLC) -bber_bin $(BER_BIN_DRV_PREV3C_FLAGS) $(BER_BIN_DRV_ASN1_PREV3C_SPEC).set.asn
+
+$(EBIN)/$(BER_BIN_DRV_ASN1_PREV3C_SPEC).$(EMULATOR): \
+ $(BER_BIN_DRV_ASN1_PREV3C_SPEC).erl \
+ $(BER_BIN_DRV_ASN1_PREV3C_SPEC).hrl
+
+$(PER_ASN1_PREV3C_SPEC).erl $(PER_ASN1_PREV3C_SPEC).hrl: \
+ $(PER_ASN1_PREV3C_SPEC).set.asn \
+ $(ASN1_PREV3C_SPEC).asn
+ @echo "$(PER_ASN1_PREV3C_SPEC):"
+ $(ERLC) -bper $(PER_PREV3C_FLAGS) $(PER_ASN1_PREV3C_SPEC).set.asn
+
+$(EBIN)/$(PER_ASN1_PREV3C_SPEC).$(EMULATOR): \
+ $(PER_ASN1_PREV3C_SPEC).erl \
+ $(PER_ASN1_PREV3C_SPEC).hrl
+
+$(PER_BIN_ASN1_PREV3C_SPEC).erl $(PER_BIN_ASN1_PREV3C_SPEC).hrl: \
+ $(PER_BIN_ASN1_PREV3C_SPEC).set.asn \
+ $(ASN1_PREV3C_SPEC).asn
+ @echo "$(PER_BIN_ASN1_PREV3C_SPEC):"
+ $(ERLC) -bper_bin $(PER_BIN_PREV3C_FLAGS) $(PER_BIN_ASN1_PREV3C_SPEC).set.asn
+
+$(EBIN)/$(PER_BIN_ASN1_PREV3C_SPEC).$(EMULATOR): \
+ $(PER_BIN_ASN1_PREV3C_SPEC).erl \
+ $(PER_BIN_ASN1_PREV3C_SPEC).hrl
+
+$(PER_BIN_DRV_ASN1_PREV3C_SPEC).erl $(PER_BIN_DRV_ASN1_PREV3C_SPEC).hrl: \
+ $(PER_BIN_DRV_ASN1_PREV3C_SPEC).set.asn \
+ $(ASN1_PREV3C_SPEC).asn
+ @echo "$(PER_BIN_DRV_ASN1_PREV3C_SPEC):"
+ $(ERLC) -bper_bin $(PER_BIN_DRV_PREV3C_FLAGS) $(PER_BIN_DRV_ASN1_PREV3C_SPEC).set.asn
+
+$(EBIN)/$(PER_BIN_DRV_ASN1_PREV3C_SPEC).$(EMULATOR): \
+ $(PER_BIN_DRV_ASN1_PREV3C_SPEC).erl \
+ $(PER_BIN_DRV_ASN1_PREV3C_SPEC).hrl
+
+
+# -- (v3) --
+
+$(BER_ASN1_V3_SPEC).erl $(BER_ASN1_V3_SPEC).hrl: \
+ $(BER_ASN1_V3_SPEC).set.asn \
+ $(ASN1_V3_SPEC).asn
+ @echo "$(BER_ASN1_V3_SPEC):"
+ $(ERLC) -bber $(BER_V3_FLAGS) $(BER_ASN1_V3_SPEC).set.asn
+
+$(EBIN)/$(BER_ASN1_V3_SPEC).$(EMULATOR): \
+ $(BER_ASN1_V3_SPEC).erl \
+ $(BER_ASN1_V3_SPEC).hrl
+
+$(BER_BIN_ASN1_V3_SPEC).erl $(BER_BIN_ASN1_V3_SPEC).hrl: \
+ $(BER_BIN_ASN1_V3_SPEC).set.asn \
+ $(BER_BIN_ASN1_V3_SPEC).asn1config \
+ $(ASN1_V3_SPEC).asn
+ @echo "$(BER_BIN_ASN1_V3_SPEC):"
+ $(ERLC) -bber_bin $(BER_BIN_V3_FLAGS) $(BER_BIN_ASN1_V3_SPEC).set.asn
+
+$(EBIN)/$(BER_BIN_ASN1_V3_SPEC).$(EMULATOR): \
+ $(BER_BIN_ASN1_V3_SPEC).erl \
+ $(BER_BIN_ASN1_V3_SPEC).hrl
+
+$(BER_BIN_DRV_ASN1_V3_SPEC).erl $(BER_BIN_DRV_ASN1_V3_SPEC).hrl: \
+ $(BER_BIN_DRV_ASN1_V3_SPEC).set.asn \
+ $(BER_BIN_DRV_ASN1_V3_SPEC).asn1config \
+ $(ASN1_V3_SPEC).asn
+ @echo "$(BER_BIN_DRV_ASN1_V3_SPEC):"
+ $(ERLC) -bber_bin $(BER_BIN_DRV_V3_FLAGS) $(BER_BIN_DRV_ASN1_V3_SPEC).set.asn
+
+$(EBIN)/$(BER_BIN_DRV_ASN1_V3_SPEC).$(EMULATOR): \
+ $(BER_BIN_DRV_ASN1_V3_SPEC).erl \
+ $(BER_BIN_DRV_ASN1_V3_SPEC).hrl
+
+$(PER_ASN1_V3_SPEC).erl $(PER_ASN1_V3_SPEC).hrl: \
+ $(PER_ASN1_V3_SPEC).set.asn \
+ $(ASN1_V3_SPEC).asn
+ @echo "$(PER_ASN1_V3_SPEC):"
+ $(ERLC) -bper $(PER_V3_FLAGS) $(PER_ASN1_V3_SPEC).set.asn
+
+$(EBIN)/$(PER_ASN1_V3_SPEC).$(EMULATOR): \
+ $(PER_ASN1_V3_SPEC).erl \
+ $(PER_ASN1_V3_SPEC).hrl
+
+$(PER_BIN_ASN1_V3_SPEC).erl $(PER_BIN_ASN1_V3_SPEC).hrl: \
+ $(PER_BIN_ASN1_V3_SPEC).set.asn \
+ $(ASN1_V3_SPEC).asn
+ @echo "$(PER_BIN_ASN1_V3_SPEC):"
+ $(ERLC) -bper_bin $(PER_BIN_V3_FLAGS) $(PER_BIN_ASN1_V3_SPEC).set.asn
+
+$(EBIN)/$(PER_BIN_ASN1_V3_SPEC).$(EMULATOR): \
+ $(PER_BIN_ASN1_V3_SPEC).erl \
+ $(PER_BIN_ASN1_V3_SPEC).hrl
+
+$(PER_BIN_DRV_ASN1_V3_SPEC).erl $(PER_BIN_DRV_ASN1_V3_SPEC).hrl: \
+ $(PER_BIN_DRV_ASN1_V3_SPEC).set.asn \
+ $(ASN1_V3_SPEC).asn
+ @echo "$(PER_BIN_DRV_ASN1_V3_SPEC):"
+ $(ERLC) -bper_bin $(PER_BIN_DRV_V3_FLAGS) $(PER_BIN_DRV_ASN1_V3_SPEC).set.asn
+
+$(EBIN)/$(PER_BIN_DRV_ASN1_V3_SPEC).$(EMULATOR): \
+ $(PER_BIN_DRV_ASN1_V3_SPEC).erl \
+ $(PER_BIN_DRV_ASN1_V3_SPEC).hrl
+
+
+# -------------
+
+$(EBIN)/megaco_ber_encoder.$(EMULATOR): megaco_ber_encoder.erl \
+ $(MEGACO_ENGINEDIR)/megaco_message_internal.hrl
+
+$(EBIN)/megaco_ber_bin_encoder.$(EMULATOR): megaco_ber_bin_encoder.erl \
+ $(MEGACO_ENGINEDIR)/megaco_message_internal.hrl
+
+$(EBIN)/megaco_per_encoder.$(EMULATOR): megaco_per_encoder.erl \
+ $(MEGACO_ENGINEDIR)/megaco_message_internal.hrl
+
+$(EBIN)/megaco_per_bin_encoder.$(EMULATOR): megaco_per_bin_encoder.erl \
+ $(MEGACO_ENGINEDIR)/megaco_message_internal.hrl
+
+$(EBIN)/megaco_binary_encoder_lib.$(EMULATOR): megaco_binary_encoder_lib.erl \
+ $(MEGACO_ENGINEDIR)/megaco_message_internal.hrl
+
+$(EBIN)/megaco_binary_encoder.$(EMULATOR): megaco_binary_encoder.erl \
+ $(MEGACO_ENGINEDIR)/megaco_message_internal.hrl
+
+$(EBIN)/megaco_binary_name_resolver_v1.$(EMULATOR): \
+ megaco_binary_name_resolver_v1.erl \
+ ../app/megaco_internal.hrl
+
+$(EBIN)/megaco_binary_name_resolver_v2.$(EMULATOR): \
+ megaco_binary_name_resolver_v2.erl \
+ ../app/megaco_internal.hrl
+
+$(EBIN)/megaco_binary_name_resolver_prev3a.$(EMULATOR): \
+ megaco_binary_name_resolver_prev3a.erl \
+ ../app/megaco_internal.hrl
+
+$(EBIN)/megaco_binary_name_resolver_prev3b.$(EMULATOR): \
+ megaco_binary_name_resolver_prev3b.erl \
+ ../app/megaco_internal.hrl
+
+$(EBIN)/megaco_binary_name_resolver_prev3c.$(EMULATOR): \
+ megaco_binary_name_resolver_prev3c.erl \
+ ../app/megaco_internal.hrl
+
+$(EBIN)/megaco_binary_name_resolver_v3.$(EMULATOR): \
+ megaco_binary_name_resolver_v3.erl
+
+$(EBIN)/megaco_binary_term_id.$(EMULATOR): megaco_binary_term_id.erl
+
+$(EBIN)/megaco_binary_term_id_gen.$(EMULATOR): megaco_binary_term_id_gen.erl
+
+$(EBIN)/megaco_binary_transformer_v1.$(EMULATOR): \
+ megaco_binary_transformer_v1.erl \
+ ../app/megaco_internal.hrl \
+ $(MEGACO_INCLUDEDIR)/megaco.hrl \
+ $(MEGACO_INCLUDEDIR)/megaco_message_v1.hrl
+
+$(EBIN)/megaco_binary_transformer_v2.$(EMULATOR): \
+ megaco_binary_transformer_v2.erl \
+ ../app/megaco_internal.hrl \
+ $(MEGACO_INCLUDEDIR)/megaco.hrl \
+ $(MEGACO_INCLUDEDIR)/megaco_message_v2.hrl
+
+$(EBIN)/megaco_binary_transformer_prev3a.$(EMULATOR): \
+ megaco_binary_transformer_prev3a.erl \
+ ../app/megaco_internal.hrl \
+ $(MEGACO_INCLUDEDIR)/megaco.hrl \
+ $(MEGACO_INCLUDEDIR)/megaco_message_prev3a.hrl
+
+$(EBIN)/megaco_binary_transformer_prev3b.$(EMULATOR): \
+ megaco_binary_transformer_prev3b.erl \
+ ../app/megaco_internal.hrl \
+ $(MEGACO_INCLUDEDIR)/megaco.hrl \
+ $(MEGACO_INCLUDEDIR)/megaco_message_prev3b.hrl
+
+$(EBIN)/megaco_binary_transformer_prev3c.$(EMULATOR): \
+ megaco_binary_transformer_prev3c.erl \
+ ../app/megaco_internal.hrl \
+ $(MEGACO_INCLUDEDIR)/megaco.hrl \
+ $(MEGACO_INCLUDEDIR)/megaco_message_prev3c.hrl
+
+$(EBIN)/megaco_binary_transformer_v3.$(EMULATOR): \
+ megaco_binary_transformer_v3.erl \
+ ../app/megaco_internal.hrl \
+ $(MEGACO_INCLUDEDIR)/megaco.hrl \
+ $(MEGACO_INCLUDEDIR)/megaco_message_v3.hrl
+
diff --git a/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3a.asn1config b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3a.asn1config
new file mode 100644
index 0000000000..179473717d
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3a.asn1config
@@ -0,0 +1,43 @@
+{exclusive_decode,
+ {'megaco_ber_bin_drv_media_gateway_control_prev3a',
+ [
+ {decode_message_trans_partial,
+ [
+ 'MegacoMessage',[{mess,[{messageBody,[{transactions,parts}]}]}]
+ ]
+ },
+ {decode_message_acts_partial,
+ ['Transaction',
+ [
+ {transactionRequest,
+ [
+ {actions,parts}
+ ]
+ },
+ {transactionReply,
+ [
+ {transactionResult, [{actionReplies,parts}]}
+ ]
+ }
+ ]
+ ]
+ },
+ {decode_message_version,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{mId,undecoded},{messageBody,undecoded}]}
+ ]
+ ]
+ },
+ {decode_message_mId,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{messageBody,undecoded}]}
+ ]
+ ]
+ }
+ ]
+ }
+}.
diff --git a/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3a.set.asn b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3a.set.asn
new file mode 100644
index 0000000000..b9ba7ffdb4
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3a.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3a.asn
diff --git a/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3b.asn1config b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3b.asn1config
new file mode 100644
index 0000000000..ceda97fbd1
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3b.asn1config
@@ -0,0 +1,43 @@
+{exclusive_decode,
+ {'megaco_ber_bin_drv_media_gateway_control_prev3b',
+ [
+ {decode_message_trans_partial,
+ [
+ 'MegacoMessage',[{mess,[{messageBody,[{transactions,parts}]}]}]
+ ]
+ },
+ {decode_message_acts_partial,
+ ['Transaction',
+ [
+ {transactionRequest,
+ [
+ {actions,parts}
+ ]
+ },
+ {transactionReply,
+ [
+ {transactionResult, [{actionReplies,parts}]}
+ ]
+ }
+ ]
+ ]
+ },
+ {decode_message_version,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{mId,undecoded},{messageBody,undecoded}]}
+ ]
+ ]
+ },
+ {decode_message_mId,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{messageBody,undecoded}]}
+ ]
+ ]
+ }
+ ]
+ }
+}.
diff --git a/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3b.set.asn b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3b.set.asn
new file mode 100644
index 0000000000..0437bde310
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3b.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3b.asn
diff --git a/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3c.asn1config b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3c.asn1config
new file mode 100644
index 0000000000..d181ef44bd
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3c.asn1config
@@ -0,0 +1,43 @@
+{exclusive_decode,
+ {'megaco_ber_bin_drv_media_gateway_control_prev3c',
+ [
+ {decode_message_trans_partial,
+ [
+ 'MegacoMessage',[{mess,[{messageBody,[{transactions,parts}]}]}]
+ ]
+ },
+ {decode_message_acts_partial,
+ ['Transaction',
+ [
+ {transactionRequest,
+ [
+ {actions,parts}
+ ]
+ },
+ {transactionReply,
+ [
+ {transactionResult, [{actionReplies,parts}]}
+ ]
+ }
+ ]
+ ]
+ },
+ {decode_message_version,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{mId,undecoded},{messageBody,undecoded}]}
+ ]
+ ]
+ },
+ {decode_message_mId,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{messageBody,undecoded}]}
+ ]
+ ]
+ }
+ ]
+ }
+}.
diff --git a/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3c.set.asn b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3c.set.asn
new file mode 100644
index 0000000000..e78055fbad
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3c.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3c.asn
diff --git a/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v1.asn1config b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v1.asn1config
new file mode 100644
index 0000000000..ea10a7d527
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v1.asn1config
@@ -0,0 +1,44 @@
+{exclusive_decode,
+ {'megaco_ber_bin_drv_media_gateway_control_v1',
+ [
+ {decode_message_trans_partial,
+ [
+ 'MegacoMessage',[{mess,[{messageBody,[{transactions,parts}]}]}]
+ ]
+ },
+ {decode_message_acts_partial,
+ ['Transaction',
+ [
+ {transactionRequest,
+ [
+ {actions,parts}
+ ]
+ },
+ {transactionReply,
+ [
+ {transactionResult, [{actionReplies,parts}]}
+ ]
+ }
+ ]
+ ]
+ },
+ {decode_message_version,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{mId,undecoded},{messageBody,undecoded}]}
+ ]
+ ]
+ },
+ {decode_message_mId,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{messageBody,undecoded}]}
+ ]
+ ]
+ }
+ ]
+ }
+}.
+
diff --git a/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v1.set.asn b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v1.set.asn
new file mode 100644
index 0000000000..0f5a92dba1
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v1.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v1.asn
diff --git a/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v2.asn1config b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v2.asn1config
new file mode 100644
index 0000000000..3d0cb9a019
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v2.asn1config
@@ -0,0 +1,43 @@
+{exclusive_decode,
+ {'megaco_ber_bin_drv_media_gateway_control_v2',
+ [
+ {decode_message_trans_partial,
+ [
+ 'MegacoMessage',[{mess,[{messageBody,[{transactions,parts}]}]}]
+ ]
+ },
+ {decode_message_acts_partial,
+ ['Transaction',
+ [
+ {transactionRequest,
+ [
+ {actions,parts}
+ ]
+ },
+ {transactionReply,
+ [
+ {transactionResult, [{actionReplies,parts}]}
+ ]
+ }
+ ]
+ ]
+ },
+ {decode_message_version,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{mId,undecoded},{messageBody,undecoded}]}
+ ]
+ ]
+ },
+ {decode_message_mId,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{messageBody,undecoded}]}
+ ]
+ ]
+ }
+ ]
+ }
+}.
diff --git a/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v2.set.asn b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v2.set.asn
new file mode 100644
index 0000000000..7fc82b127f
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v2.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v2.asn
diff --git a/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v3.asn1config b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v3.asn1config
new file mode 100644
index 0000000000..cc662c0145
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v3.asn1config
@@ -0,0 +1,43 @@
+{exclusive_decode,
+ {'megaco_ber_bin_drv_media_gateway_control_v3',
+ [
+ {decode_message_trans_partial,
+ [
+ 'MegacoMessage',[{mess,[{messageBody,[{transactions,parts}]}]}]
+ ]
+ },
+ {decode_message_acts_partial,
+ ['Transaction',
+ [
+ {transactionRequest,
+ [
+ {actions,parts}
+ ]
+ },
+ {transactionReply,
+ [
+ {transactionResult, [{actionReplies,parts}]}
+ ]
+ }
+ ]
+ ]
+ },
+ {decode_message_version,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{mId,undecoded},{messageBody,undecoded}]}
+ ]
+ ]
+ },
+ {decode_message_mId,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{messageBody,undecoded}]}
+ ]
+ ]
+ }
+ ]
+ }
+}.
diff --git a/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v3.set.asn b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v3.set.asn
new file mode 100644
index 0000000000..1d7950a283
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v3.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v3.asn
diff --git a/lib/megaco/src/binary/megaco_ber_bin_encoder.erl b/lib/megaco/src/binary/megaco_ber_bin_encoder.erl
new file mode 100644
index 0000000000..bf9926c7e5
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_encoder.erl
@@ -0,0 +1,716 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose : Handle ASN.1 BER encoding of Megaco/H.248
+%%----------------------------------------------------------------------
+
+-module(megaco_ber_bin_encoder).
+
+-behaviour(megaco_encoder).
+
+-export([encode_message/3, decode_message/3,
+ decode_mini_message/3,
+
+ encode_transaction/3,
+ encode_action_requests/3,
+ encode_action_request/3,
+ encode_action_reply/3,
+
+ version_of/2]).
+
+%% Backward compatible functions:
+-export([encode_message/2, decode_message/2]).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+
+-define(V1_ASN1_MOD, megaco_ber_bin_media_gateway_control_v1).
+-define(V2_ASN1_MOD, megaco_ber_bin_media_gateway_control_v2).
+-define(V3_ASN1_MOD, megaco_ber_bin_media_gateway_control_v3).
+-define(PREV3A_ASN1_MOD, megaco_ber_bin_media_gateway_control_prev3a).
+-define(PREV3B_ASN1_MOD, megaco_ber_bin_media_gateway_control_prev3b).
+-define(PREV3C_ASN1_MOD, megaco_ber_bin_media_gateway_control_prev3c).
+-define(V1_ASN1_MOD_DRV, megaco_ber_bin_drv_media_gateway_control_v1).
+-define(V2_ASN1_MOD_DRV, megaco_ber_bin_drv_media_gateway_control_v2).
+-define(V3_ASN1_MOD_DRV, megaco_ber_bin_drv_media_gateway_control_v3).
+-define(PREV3A_ASN1_MOD_DRV, megaco_ber_bin_drv_media_gateway_control_prev3a).
+-define(PREV3B_ASN1_MOD_DRV, megaco_ber_bin_drv_media_gateway_control_prev3b).
+-define(PREV3C_ASN1_MOD_DRV, megaco_ber_bin_drv_media_gateway_control_prev3c).
+
+-define(V1_TRANS_MOD, megaco_binary_transformer_v1).
+-define(V2_TRANS_MOD, megaco_binary_transformer_v2).
+-define(V3_TRANS_MOD, megaco_binary_transformer_v3).
+-define(PREV3A_TRANS_MOD, megaco_binary_transformer_prev3a).
+-define(PREV3B_TRANS_MOD, megaco_binary_transformer_prev3b).
+-define(PREV3C_TRANS_MOD, megaco_binary_transformer_prev3c).
+
+-define(BIN_LIB, megaco_binary_encoder_lib).
+
+
+%%----------------------------------------------------------------------
+%% Detect (check/get) message version
+%% Return {ok, Version} | {error, Reason}
+%%----------------------------------------------------------------------
+
+version_of([{version3,v3},driver|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD_DRV, ?V2_ASN1_MOD_DRV, ?V3_ASN1_MOD_DRV],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3c},driver|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD_DRV, ?V2_ASN1_MOD_DRV, ?PREV3C_ASN1_MOD_DRV],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3b},driver|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD_DRV, ?V2_ASN1_MOD_DRV, ?PREV3B_ASN1_MOD_DRV],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3a},driver|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD_DRV, ?V2_ASN1_MOD_DRV, ?PREV3A_ASN1_MOD_DRV],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,v3}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3c}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3C_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3b}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3B_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3a}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3A_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([driver|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD_DRV, ?V2_ASN1_MOD_DRV, ?V3_ASN1_MOD_DRV],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+version_of(EC, Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders).
+
+
+%%----------------------------------------------------------------------
+%% Convert a 'MegacoMessage' record into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+
+encode_message(EC,
+ #'MegacoMessage'{mess = #'Message'{version = V}} = MegaMsg) ->
+ encode_message(EC, V, MegaMsg).
+
+
+%% -- Version 1 --
+
+encode_message([{version3, _},driver|EC], 1, MegaMsg) ->
+ AsnMod = ?V1_ASN1_MOD_DRV,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([driver|EC], 1, MegaMsg) ->
+ AsnMod = ?V1_ASN1_MOD_DRV,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,_}|EC], 1, MegaMsg) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+encode_message(EC, 1, MegaMsg) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+
+%% -- Version 2 --
+
+encode_message([{version3,_},driver|EC], 2, MegaMsg) ->
+ AsnMod = ?V2_ASN1_MOD_DRV,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([driver|EC], 2, MegaMsg) ->
+ AsnMod = ?V2_ASN1_MOD_DRV,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,_}|EC], 2, MegaMsg) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+encode_message(EC, 2, MegaMsg) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+
+%% -- Version 3 --
+
+encode_message([{version3,v3},driver|EC], 3, MegaMsg) ->
+ AsnMod = ?V3_ASN1_MOD_DRV,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3c},driver|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3C_ASN1_MOD_DRV,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3b},driver|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3B_ASN1_MOD_DRV,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3a},driver|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3A_ASN1_MOD_DRV,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,v3}|EC], 3, MegaMsg) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3c}|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3C_ASN1_MOD,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3b}|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3B_ASN1_MOD,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3a}|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3A_ASN1_MOD,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([driver|EC], 3, MegaMsg) ->
+ AsnMod = ?V3_ASN1_MOD_DRV,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+encode_message(EC, 3, MegaMsg) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list).
+
+
+%%----------------------------------------------------------------------
+%% Convert a transaction (or transactions in the case of ack) record(s)
+%% into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+%% encode_transaction([] = EC, 1, Trans) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction([native] = EC, 1, Trans) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction([driver|EC], 1, Trans) ->
+%% AsnMod = ?V1_ASN1_MOD_DRV,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction(_EC, 1, _Trans) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction([] = EC, 2, Trans) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction([native] = EC, 2, Trans) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction([driver|EC], 2, Trans) ->
+%% AsnMod = ?V2_ASN1_MOD_DRV,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%%encode_transaction(_EC, 2, _Trans) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list).
+%% encode_transaction([] = EC, 3, Trans) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction([native] = EC, 3, Trans) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction([driver|EC], 3, Trans) ->
+%% AsnMod = ?V3_ASN1_MOD_DRV,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%%encode_transaction(_EC, 3, _Trans) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list).
+encode_transaction(_EC, _V, _Trans) ->
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a list of ActionRequest record's into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+%% encode_action_requests([] = EC, 1, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_requests([native] = EC, 1, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_requests([driver|EC], 1, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V1_ASN1_MOD_DRV,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_requests(_EC, 1, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_requests([] = EC, 2, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_requests([native] = EC, 2, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_requests([driver|EC], 2, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V2_ASN1_MOD_DRV,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_requests(_EC, 2, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_requests([] = EC, 3, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_requests([native] = EC, 3, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_requests([driver|EC], 3, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V3_ASN1_MOD_DRV,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+%%encode_action_requests(_EC, 3, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_requests(_EC, V, _ActReqs) ->
+%% {error, {bad_version, V}}.
+encode_action_requests(_EC, _V, _ActReqs) ->
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a ActionRequest record into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+%% encode_action_request([] = EC, 1, ActReq) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_request([native] = EC, 1, ActReq) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_request([driver|EC], 1, ActReq) ->
+%% AsnMod = ?V1_ASN1_MOD_DRV,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_request(_EC, 1, ActReq) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_request([] = EC, 2, ActReq) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_request([native] = EC, 2, ActReq) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_request([driver|EC], 2, ActReq) ->
+%% AsnMod = ?V2_ASN1_MOD_DRV,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_request(_EC, 2, ActReq) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_request([] = EC, 3, ActReq) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_request([native] = EC, 3, ActReq) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_request([driver|EC], 3, ActReq) ->
+%% AsnMod = ?V3_ASN1_MOD_DRV,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+%% encode_action_request(_EC, 3, ActReq) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+encode_action_request(_EC, _V, _ActReq) ->
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a action reply into a deep io list
+%% Not yest supported by this binary codec!
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_action_reply(_EC, _V, _AcionReply) ->
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a binary into a 'MegacoMessage' record
+%% Return {ok, MegacoMessageRecord} | {error, Reason}
+%%----------------------------------------------------------------------
+
+%% Old decode function
+decode_message(EC, Binary) ->
+ decode_message(EC, 1, Binary).
+
+%% -- Dynamic version detection --
+
+%% Select from message
+decode_message([{version3,v3},driver|EC], dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD_DRV, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD_DRV, ?V2_TRANS_MOD},
+ {?V3_ASN1_MOD_DRV, ?V3_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+decode_message([{version3,prev3c},driver|EC], dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD_DRV, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD_DRV, ?V2_TRANS_MOD},
+ {?PREV3C_ASN1_MOD_DRV, ?PREV3C_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+decode_message([{version3,prev3b},driver|EC], dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD_DRV, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD_DRV, ?V2_TRANS_MOD},
+ {?PREV3B_ASN1_MOD_DRV, ?PREV3B_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+decode_message([{version3,prev3a},driver|EC], dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD_DRV, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD_DRV, ?V2_TRANS_MOD},
+ {?PREV3A_ASN1_MOD_DRV, ?PREV3A_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+decode_message([{version3,v3}|EC], dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD, ?V2_TRANS_MOD},
+ {?V3_ASN1_MOD, ?V3_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+decode_message([{version3,prev3c}|EC], dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD, ?V2_TRANS_MOD},
+ {?PREV3C_ASN1_MOD, ?PREV3C_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+decode_message([{version3,prev3b}|EC], dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD, ?V2_TRANS_MOD},
+ {?PREV3B_ASN1_MOD, ?PREV3B_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+decode_message([{version3,prev3a}|EC], dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD, ?V2_TRANS_MOD},
+ {?PREV3A_ASN1_MOD, ?PREV3A_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+decode_message([driver|EC], dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD_DRV, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD_DRV, ?V2_TRANS_MOD},
+ {?V3_ASN1_MOD_DRV, ?V3_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+decode_message(EC, dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD, ?V2_TRANS_MOD},
+ {?V3_ASN1_MOD, ?V3_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+
+
+%% -- Version 1 --
+
+decode_message([{version3,_},driver|EC], 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD_DRV,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([driver|EC], 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD_DRV,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,_}|EC], 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+decode_message(EC, 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+
+%% -- Version 2 --
+
+decode_message([{version3,_},driver|EC], 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD_DRV,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([driver|EC], 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD_DRV,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,_}|EC], 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+decode_message(EC, 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+
+%% -- Version 3 --
+
+decode_message([{version3,v3},driver|EC], 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD_DRV,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3c},driver|EC], 3, Binary) ->
+ AsnMod = ?PREV3C_ASN1_MOD_DRV,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3b},driver|EC], 3, Binary) ->
+ AsnMod = ?PREV3B_ASN1_MOD_DRV,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3a},driver|EC], 3, Binary) ->
+ AsnMod = ?PREV3A_ASN1_MOD_DRV,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,v3}|EC], 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3c}|EC], 3, Binary) ->
+ AsnMod = ?PREV3C_ASN1_MOD,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3b}|EC], 3, Binary) ->
+ AsnMod = ?PREV3B_ASN1_MOD,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3a}|EC], 3, Binary) ->
+ AsnMod = ?PREV3A_ASN1_MOD,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([driver|EC], 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD_DRV,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+decode_message(EC, 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary).
+
+
+decode_mini_message([{version3,v3},driver|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD_DRV,
+ ?V2_ASN1_MOD_DRV,
+ ?V3_ASN1_MOD_DRV],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3c},driver|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD_DRV,
+ ?V2_ASN1_MOD_DRV,
+ ?PREV3C_ASN1_MOD_DRV],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3b},driver|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD_DRV,
+ ?V2_ASN1_MOD_DRV,
+ ?PREV3B_ASN1_MOD_DRV],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3a},driver|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD_DRV,
+ ?V2_ASN1_MOD_DRV,
+ ?PREV3A_ASN1_MOD_DRV],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,v3}|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD,
+ ?V2_ASN1_MOD,
+ ?V3_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3c}|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD,
+ ?V2_ASN1_MOD,
+ ?PREV3C_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3b}|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD,
+ ?V2_ASN1_MOD,
+ ?PREV3B_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3a}|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD,
+ ?V2_ASN1_MOD,
+ ?PREV3A_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([driver|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD_DRV,
+ ?V2_ASN1_MOD_DRV,
+ ?V3_ASN1_MOD_DRV],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message(EC, dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD,
+ ?V2_ASN1_MOD,
+ ?V3_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,_},driver|EC], 1, Bin) ->
+ AsnMod = ?V1_ASN1_MOD_DRV,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,_}|EC], 1, Bin) ->
+ AsnMod = ?V1_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([driver|EC], 1, Bin) ->
+ AsnMod = ?V1_ASN1_MOD_DRV,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message(EC, 1, Bin) ->
+ AsnMod = ?V1_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,_},driver|EC], 2, Bin) ->
+ AsnMod = ?V2_ASN1_MOD_DRV,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,_}|EC], 2, Bin) ->
+ AsnMod = ?V2_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([driver|EC], 2, Bin) ->
+ AsnMod = ?V2_ASN1_MOD_DRV,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message(EC, 2, Bin) ->
+ AsnMod = ?V2_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,v3},driver|EC], 3, Bin) ->
+ AsnMod = ?V3_ASN1_MOD_DRV,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3c},driver|EC], 3, Bin) ->
+ AsnMod = ?PREV3C_ASN1_MOD_DRV,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3b},driver|EC], 3, Bin) ->
+ AsnMod = ?PREV3B_ASN1_MOD_DRV,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3a},driver|EC], 3, Bin) ->
+ AsnMod = ?PREV3A_ASN1_MOD_DRV,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,v3}|EC], 3, Bin) ->
+ AsnMod = ?V3_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3c}|EC], 3, Bin) ->
+ AsnMod = ?PREV3C_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3b}|EC], 3, Bin) ->
+ AsnMod = ?PREV3B_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3a}|EC], 3, Bin) ->
+ AsnMod = ?PREV3A_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([driver|EC], 3, Bin) ->
+ AsnMod = ?V3_ASN1_MOD_DRV,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message(EC, 3, Bin) ->
+ AsnMod = ?V3_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary).
diff --git a/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3a.asn1config b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3a.asn1config
new file mode 100644
index 0000000000..456ce750ad
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3a.asn1config
@@ -0,0 +1,43 @@
+{exclusive_decode,
+ {'megaco_ber_bin_media_gateway_control_prev3a',
+ [
+ {decode_message_trans_partial,
+ [
+ 'MegacoMessage',[{mess,[{messageBody,[{transactions,parts}]}]}]
+ ]
+ },
+ {decode_message_acts_partial,
+ ['Transaction',
+ [
+ {transactionRequest,
+ [
+ {actions,parts}
+ ]
+ },
+ {transactionReply,
+ [
+ {transactionResult, [{actionReplies,parts}]}
+ ]
+ }
+ ]
+ ]
+ },
+ {decode_message_version,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{mId,undecoded},{messageBody,undecoded}]}
+ ]
+ ]
+ },
+ {decode_message_mId,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{messageBody,undecoded}]}
+ ]
+ ]
+ }
+ ]
+ }
+}.
diff --git a/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3a.set.asn b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3a.set.asn
new file mode 100644
index 0000000000..b9ba7ffdb4
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3a.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3a.asn
diff --git a/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3b.asn1config b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3b.asn1config
new file mode 100644
index 0000000000..fa5cd80baf
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3b.asn1config
@@ -0,0 +1,43 @@
+{exclusive_decode,
+ {'megaco_ber_bin_media_gateway_control_prev3b',
+ [
+ {decode_message_trans_partial,
+ [
+ 'MegacoMessage',[{mess,[{messageBody,[{transactions,parts}]}]}]
+ ]
+ },
+ {decode_message_acts_partial,
+ ['Transaction',
+ [
+ {transactionRequest,
+ [
+ {actions,parts}
+ ]
+ },
+ {transactionReply,
+ [
+ {transactionResult, [{actionReplies,parts}]}
+ ]
+ }
+ ]
+ ]
+ },
+ {decode_message_version,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{mId,undecoded},{messageBody,undecoded}]}
+ ]
+ ]
+ },
+ {decode_message_mId,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{messageBody,undecoded}]}
+ ]
+ ]
+ }
+ ]
+ }
+}.
diff --git a/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3b.set.asn b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3b.set.asn
new file mode 100644
index 0000000000..0437bde310
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3b.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3b.asn
diff --git a/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3c.asn1config b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3c.asn1config
new file mode 100644
index 0000000000..c74422b9a2
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3c.asn1config
@@ -0,0 +1,43 @@
+{exclusive_decode,
+ {'megaco_ber_bin_media_gateway_control_prev3c',
+ [
+ {decode_message_trans_partial,
+ [
+ 'MegacoMessage',[{mess,[{messageBody,[{transactions,parts}]}]}]
+ ]
+ },
+ {decode_message_acts_partial,
+ ['Transaction',
+ [
+ {transactionRequest,
+ [
+ {actions,parts}
+ ]
+ },
+ {transactionReply,
+ [
+ {transactionResult, [{actionReplies,parts}]}
+ ]
+ }
+ ]
+ ]
+ },
+ {decode_message_version,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{mId,undecoded},{messageBody,undecoded}]}
+ ]
+ ]
+ },
+ {decode_message_mId,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{messageBody,undecoded}]}
+ ]
+ ]
+ }
+ ]
+ }
+}.
diff --git a/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3c.set.asn b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3c.set.asn
new file mode 100644
index 0000000000..e78055fbad
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3c.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3c.asn
diff --git a/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v1.asn1config b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v1.asn1config
new file mode 100644
index 0000000000..e815e90948
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v1.asn1config
@@ -0,0 +1,44 @@
+{exclusive_decode,
+ {'megaco_ber_bin_media_gateway_control_v1',
+ [
+ {decode_message_trans_partial,
+ [
+ 'MegacoMessage',[{mess,[{messageBody,[{transactions,parts}]}]}]
+ ]
+ },
+ {decode_message_acts_partial,
+ ['Transaction',
+ [
+ {transactionRequest,
+ [
+ {actions,parts}
+ ]
+ },
+ {transactionReply,
+ [
+ {transactionResult, [{actionReplies,parts}]}
+ ]
+ }
+ ]
+ ]
+ },
+ {decode_message_version,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{mId,undecoded},{messageBody,undecoded}]}
+ ]
+ ]
+ },
+ {decode_message_mId,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{messageBody,undecoded}]}
+ ]
+ ]
+ }
+
+ ]
+ }
+}.
diff --git a/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v1.set.asn b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v1.set.asn
new file mode 100644
index 0000000000..0f5a92dba1
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v1.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v1.asn
diff --git a/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v2.asn1config b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v2.asn1config
new file mode 100644
index 0000000000..cc072b30ee
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v2.asn1config
@@ -0,0 +1,43 @@
+{exclusive_decode,
+ {'megaco_ber_bin_media_gateway_control_v2',
+ [
+ {decode_message_trans_partial,
+ [
+ 'MegacoMessage',[{mess,[{messageBody,[{transactions,parts}]}]}]
+ ]
+ },
+ {decode_message_acts_partial,
+ ['Transaction',
+ [
+ {transactionRequest,
+ [
+ {actions,parts}
+ ]
+ },
+ {transactionReply,
+ [
+ {transactionResult, [{actionReplies,parts}]}
+ ]
+ }
+ ]
+ ]
+ },
+ {decode_message_version,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{mId,undecoded},{messageBody,undecoded}]}
+ ]
+ ]
+ },
+ {decode_message_mId,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{messageBody,undecoded}]}
+ ]
+ ]
+ }
+ ]
+ }
+}.
diff --git a/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v2.set.asn b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v2.set.asn
new file mode 100644
index 0000000000..7fc82b127f
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v2.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v2.asn
diff --git a/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v3.asn1config b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v3.asn1config
new file mode 100644
index 0000000000..deeb2b2da9
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v3.asn1config
@@ -0,0 +1,43 @@
+{exclusive_decode,
+ {'megaco_ber_bin_media_gateway_control_v3',
+ [
+ {decode_message_trans_partial,
+ [
+ 'MegacoMessage',[{mess,[{messageBody,[{transactions,parts}]}]}]
+ ]
+ },
+ {decode_message_acts_partial,
+ ['Transaction',
+ [
+ {transactionRequest,
+ [
+ {actions,parts}
+ ]
+ },
+ {transactionReply,
+ [
+ {transactionResult, [{actionReplies,parts}]}
+ ]
+ }
+ ]
+ ]
+ },
+ {decode_message_version,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{mId,undecoded},{messageBody,undecoded}]}
+ ]
+ ]
+ },
+ {decode_message_mId,
+ ['MegacoMessage',
+ [
+ {authHeader,undecoded},
+ {mess,[{messageBody,undecoded}]}
+ ]
+ ]
+ }
+ ]
+ }
+}.
diff --git a/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v3.set.asn b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v3.set.asn
new file mode 100644
index 0000000000..1d7950a283
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_bin_media_gateway_control_v3.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v3.asn
diff --git a/lib/megaco/src/binary/megaco_ber_encoder.erl b/lib/megaco/src/binary/megaco_ber_encoder.erl
new file mode 100644
index 0000000000..ff65b5bf81
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_encoder.erl
@@ -0,0 +1,346 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose : Handle ASN.1 BER encoding of Megaco/H.248
+%%----------------------------------------------------------------------
+
+-module(megaco_ber_encoder).
+
+-behaviour(megaco_encoder).
+
+-export([encode_message/3, decode_message/3,
+ decode_mini_message/3,
+
+ encode_transaction/3,
+ encode_action_requests/3,
+ encode_action_request/3,
+ encode_action_reply/3,
+
+ version_of/2]).
+
+%% Backward compatible functions:
+-export([encode_message/2, decode_message/2]).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+
+-define(V1_ASN1_MOD, megaco_ber_media_gateway_control_v1).
+-define(V2_ASN1_MOD, megaco_ber_media_gateway_control_v2).
+-define(V3_ASN1_MOD, megaco_ber_media_gateway_control_v3).
+-define(PREV3A_ASN1_MOD, megaco_ber_media_gateway_control_prev3a).
+-define(PREV3B_ASN1_MOD, megaco_ber_media_gateway_control_prev3b).
+-define(PREV3C_ASN1_MOD, megaco_ber_media_gateway_control_prev3c).
+
+-define(V1_TRANS_MOD, megaco_binary_transformer_v1).
+-define(V2_TRANS_MOD, megaco_binary_transformer_v2).
+-define(V3_TRANS_MOD, megaco_binary_transformer_v3).
+-define(PREV3A_TRANS_MOD, megaco_binary_transformer_prev3a).
+-define(PREV3B_TRANS_MOD, megaco_binary_transformer_prev3b).
+-define(PREV3C_TRANS_MOD, megaco_binary_transformer_prev3c).
+
+-define(BIN_LIB, megaco_binary_encoder_lib).
+
+
+%%----------------------------------------------------------------------
+%% Detect (check/get) message version
+%% Return {ok, Version} | {error, Reason}
+%%----------------------------------------------------------------------
+
+version_of([{version3,v3}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3c}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3C_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3b}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3B_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3a}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3A_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of(EC, Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders).
+
+
+%%----------------------------------------------------------------------
+%% Convert a 'MegacoMessage' record into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_message(EC,
+ #'MegacoMessage'{mess = #'Message'{version = V}} = MegaMsg) ->
+ encode_message(EC, V, MegaMsg).
+
+
+%% -- Version 1 --
+
+encode_message([{version3,_}|EC], 1, MegaMsg) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message(EC, 1, MegaMsg) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+
+%% -- Version 2 --
+
+encode_message([{version3,_}|EC], 2, MegaMsg) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message(EC, 2, MegaMsg) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+
+%% -- Version 3 --
+
+encode_message([{version3,v3}|EC], 3, MegaMsg) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3c}|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3C_ASN1_MOD,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3b}|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3B_ASN1_MOD,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3a}|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3A_ASN1_MOD,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message(EC, 3, MegaMsg) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list).
+
+
+%%----------------------------------------------------------------------
+%% Convert a transaction (or transactions in the case of ack) record(s)
+%% into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_transaction(_EC, 1, _Trans) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented};
+encode_transaction(_EC, 2, _Trans) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented};
+encode_transaction(_EC, 3, _Trans) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a list of ActionRequest record's into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_requests(_EC, 1, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented};
+encode_action_requests(_EC, 2, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented};
+encode_action_requests(_EC, 3, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a ActionRequest record into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_request(_EC, 1, _ActReq) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented};
+encode_action_request(_EC, 2, _ActReq) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented};
+encode_action_request(_EC, 3, _ActReq) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a action reply into a deep io list
+%% Not yest supported by this binary codec!
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_action_reply(_EC, _V, _AcionReply) ->
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a binary into a 'MegacoMessage' record
+%% Return {ok, MegacoMessageRecord} | {error, Reason}
+%%----------------------------------------------------------------------
+
+decode_message(EC, Binary) ->
+ decode_message(EC, 1, Binary).
+
+%% Not supported for this codec, revert to version 1
+decode_message(EC, dynamic, Binary) ->
+ decode_message(EC, 1, Binary);
+
+
+%% -- Version 1 --
+
+decode_message([{version3,_}|EC], 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message(EC, 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+
+%% -- Version 2 --
+
+decode_message([{version3,_}|EC], 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message(EC, 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+
+%% -- Version 3 --
+
+decode_message([{version3,v3}|EC], 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3c}|EC], 3, Binary) ->
+ AsnMod = ?PREV3C_ASN1_MOD,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3b}|EC], 3, Binary) ->
+ AsnMod = ?PREV3B_ASN1_MOD,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3a}|EC], 3, Binary) ->
+ AsnMod = ?PREV3A_ASN1_MOD,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message(EC, 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary).
+
+
+decode_mini_message([{version3,v3}|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD,
+ ?V2_ASN1_MOD,
+ ?V3_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3c}|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD,
+ ?V2_ASN1_MOD,
+ ?PREV3C_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3b}|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD,
+ ?V2_ASN1_MOD,
+ ?PREV3B_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3a}|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD,
+ ?V2_ASN1_MOD,
+ ?PREV3A_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message(EC, dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD,
+ ?V2_ASN1_MOD,
+ ?V3_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+
+decode_mini_message([{version3,_}|EC], 1, Bin) ->
+ AsnMod = ?V1_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message(EC, 1, Bin) ->
+ AsnMod = ?V1_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,_}|EC], 2, Bin) ->
+ AsnMod = ?V2_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message(EC, 2, Bin) ->
+ AsnMod = ?V2_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,v3}|EC], 3, Bin) ->
+ AsnMod = ?V3_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3c}|EC], 3, Bin) ->
+ AsnMod = ?PREV3C_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3b}|EC], 3, Bin) ->
+ AsnMod = ?PREV3B_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3a}|EC], 3, Bin) ->
+ AsnMod = ?PREV3A_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message(EC, 3, Bin) ->
+ AsnMod = ?V3_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary).
+
+
diff --git a/lib/megaco/src/binary/megaco_ber_media_gateway_control_prev3a.set.asn b/lib/megaco/src/binary/megaco_ber_media_gateway_control_prev3a.set.asn
new file mode 100644
index 0000000000..b9ba7ffdb4
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_media_gateway_control_prev3a.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3a.asn
diff --git a/lib/megaco/src/binary/megaco_ber_media_gateway_control_prev3b.set.asn b/lib/megaco/src/binary/megaco_ber_media_gateway_control_prev3b.set.asn
new file mode 100644
index 0000000000..0437bde310
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_media_gateway_control_prev3b.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3b.asn
diff --git a/lib/megaco/src/binary/megaco_ber_media_gateway_control_prev3c.set.asn b/lib/megaco/src/binary/megaco_ber_media_gateway_control_prev3c.set.asn
new file mode 100644
index 0000000000..e78055fbad
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_media_gateway_control_prev3c.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3c.asn
diff --git a/lib/megaco/src/binary/megaco_ber_media_gateway_control_v1.set.asn b/lib/megaco/src/binary/megaco_ber_media_gateway_control_v1.set.asn
new file mode 100644
index 0000000000..0f5a92dba1
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_media_gateway_control_v1.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v1.asn
diff --git a/lib/megaco/src/binary/megaco_ber_media_gateway_control_v2.set.asn b/lib/megaco/src/binary/megaco_ber_media_gateway_control_v2.set.asn
new file mode 100644
index 0000000000..7fc82b127f
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_media_gateway_control_v2.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v2.asn
diff --git a/lib/megaco/src/binary/megaco_ber_media_gateway_control_v3.set.asn b/lib/megaco/src/binary/megaco_ber_media_gateway_control_v3.set.asn
new file mode 100644
index 0000000000..1d7950a283
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_ber_media_gateway_control_v3.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v3.asn
diff --git a/lib/megaco/src/binary/megaco_binary_encoder.erl b/lib/megaco/src/binary/megaco_binary_encoder.erl
new file mode 100644
index 0000000000..f825f91a45
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_encoder.erl
@@ -0,0 +1,588 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose : Handle ASN.1 BER encoding of Megaco/H.248
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_encoder).
+
+-behaviour(megaco_encoder).
+
+%% API
+-export([encode_message/3, decode_message/3,
+ decode_mini_message/3,
+
+ encode_transaction/3,
+ encode_action_requests/3,
+ encode_action_request/3,
+ encode_action_reply/3,
+
+ version_of/2]).
+
+%% Backward compatible functions:
+-export([encode_message/2, decode_message/2]).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+
+-define(BIN_LIB, megaco_binary_encoder_lib).
+
+
+%%----------------------------------------------------------------------
+%% Convert a 'MegacoMessage' record into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_message(EC,
+ #'MegacoMessage'{mess = #'Message'{version = V}} = MegaMsg) ->
+ encode_message(EC, V, MegaMsg).
+
+encode_message([{version3,_}|EC], 1, MegaMsg) ->
+ AsnMod = megaco_ber_media_gateway_control_v1,
+ TransMod = megaco_binary_transformer_v1,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message(EC, 1, MegaMsg) ->
+ AsnMod = megaco_ber_media_gateway_control_v1,
+ TransMod = megaco_binary_transformer_v1,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,_}|EC], 2, MegaMsg) ->
+ AsnMod = megaco_ber_media_gateway_control_v2,
+ TransMod = megaco_binary_transformer_v2,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message(EC, 2, MegaMsg) ->
+ AsnMod = megaco_ber_media_gateway_control_v2,
+ TransMod = megaco_binary_transformer_v2,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,v3}|EC], 3, MegaMsg) ->
+ AsnMod = megaco_ber_media_gateway_control_v3,
+ TransMod = megaco_binary_transformer_v3,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3c}|EC], 3, MegaMsg) ->
+ AsnMod = megaco_ber_media_gateway_control_prev3c,
+ TransMod = megaco_binary_transformer_prev3c,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3b}|EC], 3, MegaMsg) ->
+ AsnMod = megaco_ber_media_gateway_control_prev3b,
+ TransMod = megaco_binary_transformer_prev3b,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3a}|EC], 3, MegaMsg) ->
+ AsnMod = megaco_ber_media_gateway_control_prev3a,
+ TransMod = megaco_binary_transformer_prev3a,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message(EC, 3, MegaMsg) ->
+ AsnMod = megaco_ber_media_gateway_control_v3,
+ TransMod = megaco_binary_transformer_v3,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list).
+
+
+%%----------------------------------------------------------------------
+%% Convert a transaction (or transactions in the case of ack) record(s)
+%% into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_transaction([{version3,_}|EC], 1, Trans) ->
+ AsnMod = megaco_ber_media_gateway_control_v1,
+ TransMod = megaco_binary_transformer_v1,
+ ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod, io_list);
+encode_transaction(EC, 1, Trans) ->
+ AsnMod = megaco_ber_media_gateway_control_v1,
+ TransMod = megaco_binary_transformer_v1,
+ ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod, io_list);
+encode_transaction([{version3,_}|EC], 2, Trans) ->
+ AsnMod = megaco_ber_media_gateway_control_v2,
+ TransMod = megaco_binary_transformer_v2,
+ ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod, io_list);
+encode_transaction(EC, 2, Trans) ->
+ AsnMod = megaco_ber_media_gateway_control_v2,
+ TransMod = megaco_binary_transformer_v2,
+ ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod, io_list);
+encode_transaction([{version3,v3}|EC], 3, Trans) ->
+ AsnMod = megaco_ber_media_gateway_control_v3,
+ TransMod = megaco_binary_transformer_v3,
+ ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod, io_list);
+encode_transaction([{version3,prev3c}|EC], 3, Trans) ->
+ AsnMod = megaco_ber_media_gateway_control_prev3c,
+ TransMod = megaco_binary_transformer_prev3c,
+ ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod, io_list);
+encode_transaction([{version3,prev3b}|EC], 3, Trans) ->
+ AsnMod = megaco_ber_media_gateway_control_prev3b,
+ TransMod = megaco_binary_transformer_prev3b,
+ ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod, io_list);
+encode_transaction([{version3,prev3a}|EC], 3, Trans) ->
+ AsnMod = megaco_ber_media_gateway_control_prev3a,
+ TransMod = megaco_binary_transformer_prev3a,
+ ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod, io_list);
+encode_transaction(EC, 3, Trans) ->
+ AsnMod = megaco_ber_media_gateway_control_v3,
+ TransMod = megaco_binary_transformer_v3,
+ ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod, io_list).
+
+
+%%----------------------------------------------------------------------
+%% Convert a list of ActionRequest record's into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_requests([{version3,_}|EC], 1, ActReqs)
+ when is_list(ActReqs) ->
+ AsnMod = megaco_ber_media_gateway_control_v1,
+ TransMod = megaco_binary_transformer_v1,
+ ?BIN_LIB:encode_action_requests(EC, ActReqs, AsnMod, TransMod, io_list);
+encode_action_requests(EC, 1, ActReqs) when is_list(ActReqs) ->
+ AsnMod = megaco_ber_media_gateway_control_v1,
+ TransMod = megaco_binary_transformer_v1,
+ ?BIN_LIB:encode_action_requests(EC, ActReqs, AsnMod, TransMod, io_list);
+encode_action_requests([{version3,_}|EC], 2, ActReqs)
+ when is_list(ActReqs) ->
+ AsnMod = megaco_ber_media_gateway_control_v2,
+ TransMod = megaco_binary_transformer_v2,
+ ?BIN_LIB:encode_action_requests(EC, ActReqs, AsnMod, TransMod, io_list);
+encode_action_requests(EC, 2, ActReqs) when is_list(ActReqs) ->
+ AsnMod = megaco_ber_media_gateway_control_v2,
+ TransMod = megaco_binary_transformer_v2,
+ ?BIN_LIB:encode_action_requests(EC, ActReqs, AsnMod, TransMod, io_list);
+encode_action_requests([{version3,v3}|EC], 3, ActReqs)
+ when is_list(ActReqs) ->
+ AsnMod = megaco_ber_media_gateway_control_v3,
+ TransMod = megaco_binary_transformer_v3,
+ ?BIN_LIB:encode_action_requests(EC, ActReqs, AsnMod, TransMod, io_list);
+encode_action_requests([{version3,prev3c}|EC], 3, ActReqs)
+ when is_list(ActReqs) ->
+ AsnMod = megaco_ber_media_gateway_control_prev3c,
+ TransMod = megaco_binary_transformer_prev3c,
+ ?BIN_LIB:encode_action_requests(EC, ActReqs, AsnMod, TransMod, io_list);
+encode_action_requests([{version3,prev3b}|EC], 3, ActReqs)
+ when is_list(ActReqs) ->
+ AsnMod = megaco_ber_media_gateway_control_prev3b,
+ TransMod = megaco_binary_transformer_prev3b,
+ ?BIN_LIB:encode_action_requests(EC, ActReqs, AsnMod, TransMod, io_list);
+encode_action_requests([{version3,prev3a}|EC], 3, ActReqs)
+ when is_list(ActReqs) ->
+ AsnMod = megaco_ber_media_gateway_control_prev3a,
+ TransMod = megaco_binary_transformer_prev3a,
+ ?BIN_LIB:encode_action_requests(EC, ActReqs, AsnMod, TransMod, io_list);
+encode_action_requests(EC, 3, ActReqs) when is_list(ActReqs) ->
+ AsnMod = megaco_ber_media_gateway_control_v3,
+ TransMod = megaco_binary_transformer_v3,
+ ?BIN_LIB:encode_action_requests(EC, ActReqs, AsnMod, TransMod, io_list).
+
+
+%%----------------------------------------------------------------------
+%% Convert a ActionRequest record into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_request([{version3,_}|EC], 1, ActReq) ->
+ AsnMod = megaco_ber_media_gateway_control_v1,
+ TransMod = megaco_binary_transformer_v1,
+ ?BIN_LIB:encode_action_request(EC, ActReq, AsnMod, TransMod, io_list);
+encode_action_request(EC, 1, ActReq) ->
+ AsnMod = megaco_ber_media_gateway_control_v1,
+ TransMod = megaco_binary_transformer_v1,
+ ?BIN_LIB:encode_action_request(EC, ActReq, AsnMod, TransMod, io_list);
+encode_action_request([{version3,_}|EC], 2, ActReq) ->
+ AsnMod = megaco_ber_media_gateway_control_v2,
+ TransMod = megaco_binary_transformer_v2,
+ ?BIN_LIB:encode_action_request(EC, ActReq, AsnMod, TransMod, io_list);
+encode_action_request(EC, 2, ActReq) ->
+ AsnMod = megaco_ber_media_gateway_control_v2,
+ TransMod = megaco_binary_transformer_v2,
+ ?BIN_LIB:encode_action_request(EC, ActReq, AsnMod, TransMod, io_list);
+encode_action_request([{version3,v3}|EC], 3, ActReq) ->
+ AsnMod = megaco_ber_media_gateway_control_v3,
+ TransMod = megaco_binary_transformer_v3,
+ ?BIN_LIB:encode_action_request(EC, ActReq, AsnMod, TransMod, io_list);
+encode_action_request([{version3,prev3c}|EC], 3, ActReq) ->
+ AsnMod = megaco_ber_media_gateway_control_prev3c,
+ TransMod = megaco_binary_transformer_prev3c,
+ ?BIN_LIB:encode_action_request(EC, ActReq, AsnMod, TransMod, io_list);
+encode_action_request([{version3,prev3b}|EC], 3, ActReq) ->
+ AsnMod = megaco_ber_media_gateway_control_prev3b,
+ TransMod = megaco_binary_transformer_prev3b,
+ ?BIN_LIB:encode_action_request(EC, ActReq, AsnMod, TransMod, io_list);
+encode_action_request([{version3,prev3a}|EC], 3, ActReq) ->
+ AsnMod = megaco_ber_media_gateway_control_prev3a,
+ TransMod = megaco_binary_transformer_prev3a,
+ ?BIN_LIB:encode_action_request(EC, ActReq, AsnMod, TransMod, io_list);
+encode_action_request(EC, 3, ActReq) ->
+ AsnMod = megaco_ber_media_gateway_control_v3,
+ TransMod = megaco_binary_transformer_v3,
+ ?BIN_LIB:encode_action_request(EC, ActReq, AsnMod, TransMod, io_list).
+
+
+%%----------------------------------------------------------------------
+%% Convert a action reply into a deep io list
+%% Not yest supported by this binary codec!
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_action_reply(_EC, _V, _AcionReply) ->
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Detect (check) which version a message is
+%% Return {ok, Version} | {error, Reason}
+%%----------------------------------------------------------------------
+
+version_of([{version3,v3},driver|EC], Binary) ->
+ Decoders = [megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_ber_bin_drv_media_gateway_control_v3],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3c},driver|EC], Binary) ->
+ Decoders = [megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_ber_bin_drv_media_gateway_control_prev3c],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3b},driver|EC], Binary) ->
+ Decoders = [megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_ber_bin_drv_media_gateway_control_prev3b],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3a},driver|EC], Binary) ->
+ Decoders = [megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_ber_bin_drv_media_gateway_control_prev3a],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([driver|EC], Binary) ->
+ Decoders = [megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_ber_bin_drv_media_gateway_control_v3],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,v3}|EC], Binary) ->
+ Decoders = [megaco_ber_bin_media_gateway_control_v1,
+ megaco_ber_bin_media_gateway_control_v2,
+ megaco_ber_bin_media_gateway_control_v3],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3c}|EC], Binary) ->
+ Decoders = [megaco_ber_bin_media_gateway_control_v1,
+ megaco_ber_bin_media_gateway_control_v2,
+ megaco_ber_bin_media_gateway_control_prev3c],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3b}|EC], Binary) ->
+ Decoders = [megaco_ber_bin_media_gateway_control_v1,
+ megaco_ber_bin_media_gateway_control_v2,
+ megaco_ber_bin_media_gateway_control_prev3b],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3a}|EC], Binary) ->
+ Decoders = [megaco_ber_bin_media_gateway_control_v1,
+ megaco_ber_bin_media_gateway_control_v2,
+ megaco_ber_bin_media_gateway_control_prev3a],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of(EC, Binary) ->
+ Decoders = [megaco_ber_bin_media_gateway_control_v1,
+ megaco_ber_bin_media_gateway_control_v2,
+ megaco_ber_bin_media_gateway_control_v3],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders).
+
+
+%%----------------------------------------------------------------------
+%% Convert a binary into a 'MegacoMessage' record
+%% Return {ok, MegacoMessageRecord} | {error, Reason}
+%%----------------------------------------------------------------------
+
+decode_message(EC, Binary) ->
+ decode_message(EC, 1, Binary).
+
+decode_message([{version3,v3},driver|EC], dynamic, Binary) ->
+ Decoders = [{megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_binary_transformer_v1},
+ {megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_binary_transformer_v2},
+ {megaco_ber_bin_drv_media_gateway_control_v3,
+ megaco_binary_transformer_v3}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Decoders, binary);
+decode_message([{version3,prev3c},driver|EC], dynamic, Binary) ->
+ Decoders = [{megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_binary_transformer_v1},
+ {megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_binary_transformer_v2},
+ {megaco_ber_bin_drv_media_gateway_control_prev3c,
+ megaco_binary_transformer_prev3c}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Decoders, binary);
+decode_message([{version3,prev3b},driver|EC], dynamic, Binary) ->
+ Decoders = [{megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_binary_transformer_v1},
+ {megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_binary_transformer_v2},
+ {megaco_ber_bin_drv_media_gateway_control_prev3b,
+ megaco_binary_transformer_prev3b}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Decoders, binary);
+decode_message([{version3,prev3a},driver|EC], dynamic, Binary) ->
+ Decoders = [{megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_binary_transformer_v1},
+ {megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_binary_transformer_v2},
+ {megaco_ber_bin_drv_media_gateway_control_prev3a,
+ megaco_binary_transformer_prev3a}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Decoders, binary);
+decode_message([driver|EC], dynamic, Binary) ->
+ Decoders = [{megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_binary_transformer_v1},
+ {megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_binary_transformer_v2},
+ {megaco_ber_bin_drv_media_gateway_control_v3,
+ megaco_binary_transformer_v3}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Decoders, binary);
+decode_message([{version3,v3}|EC], dynamic, Binary) ->
+ Decoders = [{megaco_ber_bin_media_gateway_control_v1,
+ megaco_binary_transformer_v1},
+ {megaco_ber_bin_media_gateway_control_v2,
+ megaco_binary_transformer_v2},
+ {megaco_ber_bin_media_gateway_control_v3,
+ megaco_binary_transformer_v3}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Decoders, binary);
+decode_message([{version3,prev3c}|EC], dynamic, Binary) ->
+ Decoders = [{megaco_ber_bin_media_gateway_control_v1,
+ megaco_binary_transformer_v1},
+ {megaco_ber_bin_media_gateway_control_v2,
+ megaco_binary_transformer_v2},
+ {megaco_ber_bin_media_gateway_control_prev3c,
+ megaco_binary_transformer_prev3c}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Decoders, binary);
+decode_message([{version3,prev3b}|EC], dynamic, Binary) ->
+ Decoders = [{megaco_ber_bin_media_gateway_control_v1,
+ megaco_binary_transformer_v1},
+ {megaco_ber_bin_media_gateway_control_v2,
+ megaco_binary_transformer_v2},
+ {megaco_ber_bin_media_gateway_control_prev3b,
+ megaco_binary_transformer_prev3b}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Decoders, binary);
+decode_message([{version3,prev3a}|EC], dynamic, Binary) ->
+ Decoders = [{megaco_ber_bin_media_gateway_control_v1,
+ megaco_binary_transformer_v1},
+ {megaco_ber_bin_media_gateway_control_v2,
+ megaco_binary_transformer_v2},
+ {megaco_ber_bin_media_gateway_control_prev3a,
+ megaco_binary_transformer_prev3a}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Decoders, binary);
+decode_message(EC, dynamic, Binary) ->
+ Decoders = [{megaco_ber_bin_media_gateway_control_v1,
+ megaco_binary_transformer_v1},
+ {megaco_ber_bin_media_gateway_control_v2,
+ megaco_binary_transformer_v2},
+ {megaco_ber_bin_media_gateway_control_v3,
+ megaco_binary_transformer_v3}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Decoders, binary);
+
+
+%% -- Version 1 --
+
+decode_message([{version3,_},driver|EC], 1, Binary) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_v1,
+ TransMod = megaco_binary_transformer_v1,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+decode_message([driver|EC], 1, Binary) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_v1,
+ TransMod = megaco_binary_transformer_v1,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+decode_message([{version3,_}|EC], 1, Binary) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_v1,
+ TransMod = megaco_binary_transformer_v1,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+decode_message(EC, 1, Binary) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_v1,
+ TransMod = megaco_binary_transformer_v1,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+
+%% -- Version 2 --
+
+decode_message([{version3,_},driver|EC], 2, Binary) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_v2,
+ TransMod = megaco_binary_transformer_v2,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+decode_message([driver|EC], 2, Binary) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_v2,
+ TransMod = megaco_binary_transformer_v2,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+decode_message([{version3,_}|EC], 2, Binary) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_v2,
+ TransMod = megaco_binary_transformer_v2,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+decode_message(EC, 2, Binary) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_v2,
+ TransMod = megaco_binary_transformer_v2,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+
+%% -- Version 3 --
+
+decode_message([{version3,v3},driver|EC], 3, Binary) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_v3,
+ TransMod = megaco_binary_transformer_v3,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3c},driver|EC], 3, Binary) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_prev3c,
+ TransMod = megaco_binary_transformer_prev3c,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3b},driver|EC], 3, Binary) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_prev3b,
+ TransMod = megaco_binary_transformer_prev3b,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3a},driver|EC], 3, Binary) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_prev3a,
+ TransMod = megaco_binary_transformer_prev3a,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+decode_message([driver|EC], 3, Binary) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_v3,
+ TransMod = megaco_binary_transformer_v3,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+decode_message([{version3,v3}|EC], 3, Binary) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_v3,
+ TransMod = megaco_binary_transformer_v3,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3c}|EC], 3, Binary) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_prev3c,
+ TransMod = megaco_binary_transformer_prev3c,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3b}|EC], 3, Binary) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_prev3b,
+ TransMod = megaco_binary_transformer_prev3b,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3a}|EC], 3, Binary) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_prev3a,
+ TransMod = megaco_binary_transformer_prev3a,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+decode_message(EC, 3, Binary) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_v3,
+ TransMod = megaco_binary_transformer_v3,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary).
+
+
+decode_mini_message([{version3,v3},driver|EC], dynamic, Bin) ->
+ Mods = [megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_ber_bin_drv_media_gateway_control_v3],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3c},driver|EC], dynamic, Bin) ->
+ Mods = [megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_ber_bin_drv_media_gateway_control_prev3c],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3b},driver|EC], dynamic, Bin) ->
+ Mods = [megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_ber_bin_drv_media_gateway_control_prev3b],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3a},driver|EC], dynamic, Bin) ->
+ Mods = [megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_ber_bin_drv_media_gateway_control_prev3a],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([driver|EC], dynamic, Bin) ->
+ Mods = [megaco_ber_bin_drv_media_gateway_control_v1,
+ megaco_ber_bin_drv_media_gateway_control_v2,
+ megaco_ber_bin_drv_media_gateway_control_v3],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,v3}|EC], dynamic, Bin) ->
+ Mods = [megaco_ber_bin_media_gateway_control_v1,
+ megaco_ber_bin_media_gateway_control_v2,
+ megaco_ber_bin_media_gateway_control_v3],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3c}|EC], dynamic, Bin) ->
+ Mods = [megaco_ber_bin_media_gateway_control_v1,
+ megaco_ber_bin_media_gateway_control_v2,
+ megaco_ber_bin_media_gateway_control_prev3c],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3b}|EC], dynamic, Bin) ->
+ Mods = [megaco_ber_bin_media_gateway_control_v1,
+ megaco_ber_bin_media_gateway_control_v2,
+ megaco_ber_bin_media_gateway_control_prev3b],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3a}|EC], dynamic, Bin) ->
+ Mods = [megaco_ber_bin_media_gateway_control_v1,
+ megaco_ber_bin_media_gateway_control_v2,
+ megaco_ber_bin_media_gateway_control_prev3a],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message(EC, dynamic, Bin) ->
+ Mods = [megaco_ber_bin_media_gateway_control_v1,
+ megaco_ber_bin_media_gateway_control_v2,
+ megaco_ber_bin_media_gateway_control_v3],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+
+decode_mini_message([{version3,_},driver|EC], 1, Bin) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_v1,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([driver|EC], 1, Bin) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_v1,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,_}|EC], 1, Bin) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_v1,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message(EC, 1, Bin) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_v1,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+
+decode_mini_message([{version3,_},driver|EC], 2, Bin) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_v2,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([driver|EC], 2, Bin) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_v2,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,_}|EC], 2, Bin) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_v2,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message(EC, 2, Bin) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_v2,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+
+decode_mini_message([{version3,v3},driver|EC], 3, Bin) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_v3,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3c},driver|EC], 3, Bin) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_prev3c,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3b},driver|EC], 3, Bin) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_prev3b,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3a},driver|EC], 3, Bin) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_prev3a,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([driver|EC], 3, Bin) ->
+ AsnMod = megaco_ber_bin_drv_media_gateway_control_v3,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,v3}|EC], 3, Bin) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_v3,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3c}|EC], 3, Bin) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_prev3c,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3b}|EC], 3, Bin) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_prev3b,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3a}|EC], 3, Bin) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_prev3a,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message(EC, 3, Bin) ->
+ AsnMod = megaco_ber_bin_media_gateway_control_v3,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary).
+
+
+
diff --git a/lib/megaco/src/binary/megaco_binary_encoder_lib.erl b/lib/megaco/src/binary/megaco_binary_encoder_lib.erl
new file mode 100644
index 0000000000..842d6b70d1
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_encoder_lib.erl
@@ -0,0 +1,317 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose : Handle ASN.1 BER encoding of Megaco/H.248
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_encoder_lib).
+
+%% API
+-export([
+ version_of/4,
+ decode_message/5, decode_message_dynamic/4,
+ decode_mini_message/4, decode_mini_message_dynamic/4,
+ encode_message/5,
+ encode_transaction/5,
+ encode_action_requests/5,
+ encode_action_request/5,
+ encode_action_reply/5
+ ]).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+
+
+%%----------------------------------------------------------------------
+%% Detect (check) which version a message is
+%% Return {ok, Version} | {error, Reason}
+%%----------------------------------------------------------------------
+
+version_of(_EC, Binary, dynamic, [AsnModV1|_AsnMods])
+ when is_binary(Binary) andalso is_atom(AsnModV1) ->
+ case (catch AsnModV1:decode_message_version(Binary)) of
+ {ok, PartialMsg} ->
+ V = (PartialMsg#'MegacoMessage'.mess)#'Message'.version,
+ {ok, V};
+ Error ->
+ Error
+ end;
+version_of(_EC, Binary, 1, AsnMods)
+ when is_binary(Binary) andalso is_list(AsnMods) ->
+ version_of(AsnMods, Binary, []);
+version_of(_EC, Binary, 2, [AsnModV1, AsnModV2, AsnModV3])
+ when is_binary(Binary) ->
+ version_of([AsnModV2, AsnModV1, AsnModV3], Binary, []);
+version_of(_EC, Binary, 3, [AsnModV1, AsnModV2, AsnModV3])
+ when is_binary(Binary) ->
+ version_of([AsnModV3, AsnModV1, AsnModV2], Binary, []).
+
+version_of([], _Binary, Err) ->
+ {error, {decode_failed, lists:reverse(Err)}};
+version_of([AsnMod|AsnMods], Binary, Errs) when is_atom(AsnMod) ->
+ case (catch asn1rt:decode(AsnMod, 'MegacoMessage', Binary)) of
+ {ok, M} ->
+ V = (M#'MegacoMessage'.mess)#'Message'.version,
+ {ok, V};
+ Err ->
+ version_of(AsnMods, Binary, [Err|Errs])
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Convert a 'MegacoMessage' record into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_message([native], MegaMsg, AsnMod, _TransMod, binary)
+ when is_record(MegaMsg, 'MegacoMessage') ->
+ asn1rt:encode(AsnMod, 'MegacoMessage', MegaMsg);
+encode_message(EC, MegaMsg, AsnMod, TransMod, binary)
+ when is_list(EC) andalso is_record(MegaMsg, 'MegacoMessage') ->
+ case (catch TransMod:tr_message(MegaMsg, encode, EC)) of
+ {'EXIT', Reason} ->
+ {error, Reason};
+ MegaMsg2 ->
+ asn1rt:encode(AsnMod, 'MegacoMessage', MegaMsg2)
+ end;
+encode_message(EC, MegaMsg, AsnMod, TransMod, io_list) ->
+ case encode_message(EC, MegaMsg, AsnMod, TransMod, binary) of
+ {ok, Bin} when is_binary(Bin) ->
+ {ok, Bin};
+ {ok, DeepIoList} ->
+ Bin = erlang:list_to_binary(DeepIoList),
+ {ok, Bin};
+ {error, Reason} ->
+ {error, Reason}
+ end;
+encode_message(EC, MegaMsg, _AsnMod, _TransMod, _Type)
+ when is_record(MegaMsg, 'MegacoMessage') ->
+ {error, {bad_encoding_config, EC}};
+encode_message(_EC, MegaMsg, _AsnMod, _TransMod, _Type) ->
+ {error, {no_megaco_message, MegaMsg}}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a transaction (or transactions in the case of ack) record(s)
+%% into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+%% Should handle encoding of all types of transactions:
+%% TransactionAck, TransactionPending, TransactionRequest
+%% and TransactionReply
+encode_transaction(EC, {Tag, _} = Trans, AsnMod, TransMod, Type)
+ when (Tag == transactionResponseAck) ->
+ do_encode_transaction(EC, Trans, AsnMod, TransMod, Type);
+encode_transaction(EC, {Tag, _} = Trans, AsnMod, TransMod, Type)
+ when (Tag == transactionPending) ->
+ do_encode_transaction(EC, Trans, AsnMod, TransMod, Type);
+encode_transaction(EC, {Tag, _} = Trans, AsnMod, TransMod, Type)
+ when (Tag == transactionRequest) ->
+ do_encode_transaction(EC, Trans, AsnMod, TransMod, Type);
+%% TransactionReply has been changed as of v3 so we cannot use
+%% the record definition in this common module.
+encode_transaction(EC, {Tag, _} = Trans, AsnMod, TransMod, Type)
+ when (Tag == transactionReply) ->
+ do_encode_transaction(EC, Trans, AsnMod, TransMod, Type);
+encode_transaction(_EC, T, _AsnMod, _TransMod, _Type) ->
+ {error, {no_megaco_transaction, T}}.
+
+do_encode_transaction([native], _Trans, _AsnMod, _TransMod, binary) ->
+ %% asn1rt:encode(AsnMod, element(1, T), T);
+ {error, not_implemented};
+do_encode_transaction(EC, _Trans, _AsnMod, _TransMod, binary)
+ when is_list(EC) ->
+ %% T2 = TransMod:tr_transaction(Trans, encode, EC),
+ %% asn1rt:encode(AsnMod, element(1, T), T2);
+ {error, not_implemented};
+do_encode_transaction(EC, Trans, AsnMod, TransMod, io_list) ->
+ case do_encode_transaction(EC, Trans, AsnMod, TransMod, binary) of
+ {ok, Bin} when is_binary(Bin) ->
+ {ok, Bin};
+ {ok, DeepIoList} ->
+ Bin = erlang:list_to_binary(DeepIoList),
+ {ok, Bin};
+ {error, Reason} ->
+ {error, Reason}
+ end;
+do_encode_transaction(EC, _Trans, _AsnMod, _TransMod, _Type) ->
+ {error, {bad_encoding_config, EC}}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a list of ActionRequest record's into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_requests([native], _ARs, _AsnMod, _TransMod, binary) ->
+ %% asn1rt:encode(AsnMod, element(1, T), T);
+ {error, not_implemented};
+encode_action_requests(_EC, _ARs0, _AsnMod, _TransMod, binary) ->
+ {error, not_implemented};
+encode_action_requests(EC, ARs, AsnMod, TransMod, io_list) ->
+ case encode_action_requests(EC, ARs, AsnMod, TransMod, binary) of
+ {ok, Bin} when is_binary(Bin) ->
+ {ok, Bin};
+ {ok, DeepIoList} ->
+ Bin = erlang:list_to_binary(DeepIoList),
+ {ok, Bin};
+ {error, Reason} ->
+ {error, Reason}
+ end;
+encode_action_requests(EC, _ARs, _AsnMod, _TransMod, _Type) ->
+ {error, {bad_encoding_config, EC}}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a ActionRequest record into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_request([native], _ARs, _AsnMod, _TransMod, binary) ->
+ %% asn1rt:encode(AsnMod, element(1, T), T);
+ {error, not_implemented};
+encode_action_request(_EC, _ARs0, _AsnMod, _TransMod, binary) ->
+ {error, not_implemented};
+encode_action_request(EC, ARs, AsnMod, TransMod, io_list) ->
+ case encode_action_request(EC, ARs, AsnMod, TransMod, binary) of
+ {ok, Bin} when is_binary(Bin) ->
+ {ok, Bin};
+ {ok, DeepIoList} ->
+ Bin = erlang:list_to_binary(DeepIoList),
+ {ok, Bin};
+ {error, Reason} ->
+ {error, Reason}
+ end;
+encode_action_request(EC, _ARs, _AsnMod, _TransMod, _Type) ->
+ {error, {bad_encoding_config, EC}}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a ActionReply record into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_reply([native], _ARs, _AsnMod, _TransMod, binary) ->
+ %% asn1rt:encode(AsnMod, element(1, T), T);
+ {error, not_implemented};
+encode_action_reply(_EC, _ARs0, _AsnMod, _TransMod, binary) ->
+ {error, not_implemented};
+encode_action_reply(EC, ARs, AsnMod, TransMod, io_list) ->
+ case encode_action_reply(EC, ARs, AsnMod, TransMod, binary) of
+ {ok, Bin} when is_binary(Bin) ->
+ {ok, Bin};
+ {ok, DeepIoList} ->
+ Bin = erlang:list_to_binary(DeepIoList),
+ {ok, Bin};
+ {error, Reason} ->
+ {error, Reason}
+ end;
+encode_action_reply(EC, _ARs, _AsnMod, _TransMod, _Type) ->
+ {error, {bad_encoding_config, EC}}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a binary into a 'MegacoMessage' record
+%% Return {ok, MegacoMessageRecord} | {error, Reason}
+%%----------------------------------------------------------------------
+
+decode_message_dynamic(EC, Bin,
+ [{AsnModV1, TransModV1},
+ {AsnModV2, TransModV2},
+ {AsnModV3, TransModV3}], Form)
+ when is_list(EC) andalso is_binary(Bin) ->
+ case AsnModV1:decode_message_version(Bin) of
+ {ok, PartialMsg} ->
+ V = (PartialMsg#'MegacoMessage'.mess)#'Message'.version,
+ case V of
+ 1 ->
+ decode_message(EC, Bin, AsnModV1, TransModV1, Form);
+ 2 ->
+ decode_message(EC, Bin, AsnModV2, TransModV2, Form);
+ 3 ->
+ decode_message(EC, Bin, AsnModV3, TransModV3, Form)
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end;
+decode_message_dynamic(EC, Bin, _Mods, _Type)
+ when is_binary(Bin) ->
+ {error, {bad_encoding_config, EC}};
+decode_message_dynamic(_EC, _BadBin, _Mods, _Type) ->
+ {error, no_binary}.
+
+
+decode_message(EC, Bin, AsnMod, TransMod, binary) ->
+ case asn1rt:decode(AsnMod, 'MegacoMessage', Bin) of
+ {ok, MegaMsg} ->
+ case EC of
+ [native] ->
+ {ok, MegaMsg};
+ _ ->
+ {ok, TransMod:tr_message(MegaMsg, decode, EC)}
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end;
+decode_message(EC, Bin, AsnMod, TransMod, io_list) ->
+ ShallowIoList = erlang:binary_to_list(Bin),
+ case asn1rt:decode(AsnMod, 'MegacoMessage', ShallowIoList) of
+ {ok, MegaMsg} ->
+ case EC of
+ [native] ->
+ {ok, MegaMsg};
+ _ ->
+ {ok, TransMod:tr_message(MegaMsg, decode, EC)}
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Convert a binary into a partial 'MegacoMessage' record
+%% I.e. only version and Mid is fully decoded.
+%% Return {ok, MegacoMessageRecord} | {error, Reason}
+%%----------------------------------------------------------------------
+
+decode_mini_message(_, Bin, Mod, _) ->
+ case (catch Mod:decode_message_mId(Bin)) of
+ {ok, #'MegacoMessage'{mess = Mess} = MegaMsg} ->
+ Mess2 = Mess#'Message'{messageBody = undefined},
+ {ok, MegaMsg#'MegacoMessage'{mess = Mess2}};
+ Error ->
+ Error
+ end.
+
+
+decode_mini_message_dynamic(EC, Bin, [Mod1, Mod2, Mod3], Form) ->
+ case Mod1:decode_message_version(Bin) of
+ {ok, PartialMsg} ->
+ V = (PartialMsg#'MegacoMessage'.mess)#'Message'.version,
+ case V of
+ 1 ->
+ decode_mini_message(EC, Bin, Mod1, Form);
+ 2 ->
+ decode_mini_message(EC, Bin, Mod2, Form);
+ 3 ->
+ decode_mini_message(EC, Bin, Mod3, Form)
+ end;
+ Error ->
+ Error
+ end.
+
diff --git a/lib/megaco/src/binary/megaco_binary_name_resolver_prev3a.erl b/lib/megaco/src/binary/megaco_binary_name_resolver_prev3a.erl
new file mode 100644
index 0000000000..72b3112053
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_name_resolver_prev3a.erl
@@ -0,0 +1,2003 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Handle meta data about packages
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_name_resolver_prev3a).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+-include_lib("megaco/src/app/megaco_internal.hrl").
+
+
+-define(LOWER(Char),
+ if
+ Char >= $A, Char =< $Z ->
+ Char - ($A - $a);
+ true ->
+ Char
+ end).
+
+-export([packages/0,
+ capabilities/0,
+ capabilities/1,
+ decode_name/3,
+ encode_name/3
+ ]).
+
+encode_name(Config, term_id, TermId) ->
+ case megaco:encode_binary_term_id(Config, TermId) of
+ {ok, TermId2} ->
+ TermId2;
+ {error, _Reason} ->
+ exit({bad_term_id, TermId})
+ end;
+encode_name(_Config, Scope, Item) ->
+ ?d("encode_name(~p) -> entry with"
+ "~n Item: ~p", [Scope, Item]),
+ encode(Scope, Item).
+
+decode_name(Config, term_id, TermId) ->
+ case megaco:decode_binary_term_id(Config, TermId) of
+ {ok, TermId2} ->
+ TermId2;
+ {error, _Reason} ->
+ exit({bad_term_id, TermId})
+ end;
+decode_name(_Config, Scope, Item) ->
+ ?d("decode_name(~p) -> entry with"
+ "~n Item: ~p", [Scope, Item]),
+ decode(Scope, Item).
+
+
+
+%%----------------------------------------------------------------------
+%% 12.1.1 Package
+%%
+%% Overall description of the package, specifying:
+%%
+%% Package Name: only descriptive
+%%
+%% PackageID: is an identifier
+%%
+%% Description: is a description of the package
+%%
+%% Version:
+%%
+%% A new version of a package can only add additional Properties,
+%% Events, Signals, Statistics and new possible values for an
+%% existing parameter described in the original package. No
+%% deletions or modifications shall be allowed. A version is an
+%% integer in the range from 1 to 99.
+%%
+%% Designed to be extended only (Optional): Yes
+%%
+%% This indicates that the package has been expressly designed to
+%% be extended by others, not to be directly referenced. For
+%% example, the package may not have any function on its own or be
+%% nonsensical on its own. The MG SHOULD NOT publish this PackageID
+%% when reporting packages.
+%%
+%% Extends: existing package Descriptor
+%%
+%% A package may extend an existing package. The version of the
+%% original package must be specified. When a package extends
+%% another package it shall only add additional Properties, Events,
+%% Signals, Statistics and new possible values for an existing
+%% parameter described in the original package. An extended package
+%% shall not redefine or overload an identifier defined in the
+%% original package and packages it may have extended (multiple
+%% levels of extension). Hence, if package B version 1 extends
+%% package A version 1, version 2 of B will not be able to extend
+%% the A version 2 if A version 2 defines a name already in B
+%% version 1. If the package does not extend another package, it
+%% shall specify "none".
+%%
+%%
+%% 12.1.2 Properties
+%%
+%% Properties defined by the package, specifying:
+%%
+%% Property Name: only descriptive
+%%
+%% PropertyID: is an identifier
+%%
+%% Description: is a description of the function of the property
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 string
+%%
+%% Octet String: A number of octets. See Annex A and B.3 for
+%% encoding
+%%
+%% Integer: 4 byte signed integer
+%%
+%% Double: 8 byte signed integer
+%%
+%% Character: unicode UTF-8 encoding of a single letter.
+%% Could be more than one octet.
+%%
+%% Enumeration: one of a list of possible unique values (see 12.3)
+%%
+%% Sub-list: a list of several values from a list.
+%% The type of sub-list SHALL also be specified.
+%% The type shall be chosen from the types specified in
+%% this section (with the exception of sub-list). For
+%% example, Type: sub-list of enumeration. The encoding
+%% of sub-lists is specified in Annexes A and B.3.
+%%
+%% Possible values:
+%%
+%% A package MUST specify either a specific set of values or a
+%% description of how values are determined. A package MUST also
+%% specify a default value or the default behaviour when the value
+%% is omitted from its descriptor. For example, a package may
+%% specify that procedures related to the property are suspended
+%% when its value is omitted.
+%%
+%% Default:
+%%
+%% A default value (but not procedures) may be specified as
+%% provisionable.
+%%
+%% Defined in:
+%%
+%% Which H.248.1 descriptor the property is defined in.
+%% LocalControl is for stream-dependent properties.
+%% TerminationState is for stream-independent properties.
+%% ContextAttribute is for properties that affect the context as
+%% a whole, i.e., mixing properties. These are expected to be the
+%% most common cases, but it is possible for properties to be
+%% defined in other descriptors. Context properties MUST be defined
+%% in the ContextAttribute descriptor.
+%%
+%% Characteristics: Read/Write or both, and (optionally), global:
+%%
+%% Indicates whether a property is read-only, or read-write, and
+%% if it is global. If Global is omitted, the property is not
+%% global. If a property is declared as global, the value of the
+%% property is shared by all Terminations realizing the package.
+%% If a context property is declared as global, the property is
+%% shared by all contexts realizing the package.
+%%
+%%
+%% 12.1.3 Events
+%%
+%% Events defined by the package, specifying:
+%%
+%% Event name: only descriptive
+%%
+%% EventID: is an identifier
+%%
+%% Description: a description of the function of the event
+%%
+%% EventsDescriptor Parameters:
+%%
+%% Parameters used by the MGC to configure the event, and found in
+%% the EventsDescriptor. See 12.2. If there are no parameters for
+%% the Events Descriptor, then "none" shall be specified.
+%%
+%% ObservedEventsDescriptor Parameters:
+%%
+%% Parameters returned to the MGC in Notify requests and in replies
+%% to command requests from the MGC that audit
+%% ObservedEventsDescriptor, and found in the
+%% ObservedEventsDescriptor. See 12.2. If there are no parameters
+%% for the ObservedEvents Descriptor, then �none� shall be specified.
+%%
+%%
+%% 12.1.4 Signals
+%%
+%% Signals defined by the package, specifying:
+%%
+%% Signal Name: only descriptive
+%%
+%% SignalID: is an identifier. SignalID is used in a SignalsDescriptor
+%%
+%% Description: a description of the function of the signal
+%%
+%% SignalType: one of:
+%%
+%% OO (On/Off)
+%%
+%% TO (TimeOut)
+%%
+%% BR (Brief)
+%%
+%% NOTE -�SignalType may be defined such that it is dependent on
+%% the value of one or more parameters. The package MUST specify a
+%% default signal type. If the default type is TO, the package MUST
+%% specify a default duration which may be provisioned. A default
+%% duration is meaningless for BR.
+%%
+%% Duration: in hundredths of seconds
+%%
+%% Additional Parameters: see 12.2
+%%
+%%
+%% 12.1.5 Statistics
+%%
+%% Statistics defined by the package, specifying:
+%%
+%% Statistic name: only descriptive
+%%
+%% StatisticID: is an identifier
+%%
+%% StatisticID is used in a StatisticsDescriptor
+%%
+%% Description: a description of the statistic
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 string
+%%
+%% Octet String: A number of octets.
+%% See Annex A and Annex B.3 for encoding
+%%
+%% Integer: 4 byte signed integer
+%%
+%% Double: 8 byte signed integer
+%%
+%% Character: Unicode UTF-8 encoding of a single letter.
+%% Could be more than one octet.
+%%
+%% Enumeration: One of a list of possible unique values (See 12.3)
+%%
+%% Sub-list: A list of several values from a list.
+%% The type of sub-list SHALL also be specified.
+%% The type shall be chosen from the types specified in
+%% this section (with the exception of sub-list).
+%% For example, Type: sub-list of enumeration.
+%% The encoding of sub-lists is specified in Annexes A
+%% and B.3.
+%%
+%% Possible Values:
+%%
+%% A package must indicate the unit of measure, e.g. milliseconds,
+%% packets, either here or along with the type above, as well as
+%% indicating any restriction on the range.
+%%
+%% Level: Specify if the statistic can be kept at the Termination
+%% level, Stream level or Either.
+%%
+%%
+%% 12.1.6 Error Codes
+%%
+%% If the package does not define any error codes, this section may be omitted.
+%% Otherwise, it describes error codes defined by the package, specifying:
+%%
+%% Error Code #: The error code number.
+%%
+%% Name: Name of the error
+%%
+%% Definition: A description of the error code.
+%%
+%% Error Text in the Error Descriptor:
+%%
+%% A description of what text to return in the Error Descriptor.
+%%
+%% Comment: Any further comments on the use of the error code.
+%%
+%%
+%% 12.1.7 Procedures
+%%
+%% Additional guidance on the use of the package.
+%%
+%%
+%% 12.2 Guidelines to defining parameters to events and signals
+%%
+%% Parameter Name: only descriptive
+%%
+%% ParameterID: is an identifier. The textual ParameterID of
+%% parameters to Events and Signals shall not start with "EPA" and
+%% "SPA", respectively. The textual ParameterID shall also not be
+%% "ST", "Stream", "SY", "SignalType", "DR", "Duration", "NC",
+%% "NotifyCompletion", "KA", "KeepActive", "EB", "Embed", "DM",
+%% "DigitMap", "DI", "Direction", "RQ" or "RequestID".
+%%
+%% Description: a description of the function of the parameter.
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 octet string
+%%
+%% Octet String: A number of octets. See Annex A and B.3 for
+%% encoding
+%%
+%% Integer: 4-octet signed integer
+%%
+%% Double: 8-octet signed integer
+%%
+%% Character: Unicode UTF-8 encoding of a single letter. Could be
+%% more than one octet.
+%%
+%% Enumeration: one of a list of possible unique values (see 12.3)
+%%
+%% Sub-list: a list of several values from a list (not supported
+%% for statistics). The type of sub-list SHALL also be
+%% specified The type shall be chosen from the types
+%% specified in this section (with the exception of
+%% sub-list). For example, Type: sub-list of enumeration.
+%% The encoding of sub-lists is specified in Annex A
+%% and B.3.
+%%
+%% Optional: Yes/No
+%%
+%% Describes if the parameter may be omitted from the signal or
+%% event.
+%%
+%% Possible values:
+%%
+%% A package MUST specify either a specific set of values or a
+%% description of how values are determined. A package MUST
+%% also specify a default value or the default behavior when the
+%% value is omitted from its descriptor. For example, a package
+%% may specify that procedures related to the parameter are
+%% suspended when its value is omitted.
+%%
+%% Default:
+%%
+%% A default value (but not procedures) may be specified as
+%% provisionable.
+%%
+%%
+%% 12.3 Lists
+%%
+%% Possible values for parameters include enumerations. Enumerations may be
+%% defined in a list. It is recommended that the list be IANA registered so
+%% that packages that extend the list can be defined without concern for
+%% conflicting names.
+%%
+%%
+%% 12.4 Identifiers
+%%
+%% Identifiers in text encoding shall be strings of up to 64 characters,
+%% containing no spaces, starting with an alphabetic character and consisting
+%% of alphanumeric characters and/or digits, and possibly including the
+%% special character underscore ("_").
+%%
+%% Identifiers in binary encoding are 2 octets long.
+%%
+%% Both text and binary values shall be specified for each identifier,
+%% including identifiers used as values in enumerated types.
+%%
+%%
+%% 12.5 Package registration
+%%
+%% A package can be registered with IANA for interoperability reasons. See
+%% clause 14 for IANA considerations.
+%%
+%%----------------------------------------------------------------------
+
+capabilities() ->
+ [{P, capabilities(P)} || P <- packages()].
+
+%% -record(property, {name, type, values, defined_in, characteristics}).
+
+%%----------------------------------------------------------------------
+%% List all known packages
+%% 'native' and 'all' are not real packages
+%%----------------------------------------------------------------------
+
+packages() ->
+ [
+ "g", % Generic
+ "root", % Base Root Package
+ "tonegen", % Tone Generator Package
+ "tonedet", % Tone Detection Package
+ "dg", % Basic DTMF Generator Package
+ "dd", % DTMF detection Package
+ "cg", % Call Progress Tones Generator Package
+ "cd", % Call Progress Tones Detection Package
+ "al", % Analog Line Supervision Package
+ "ct", % Basic Continuity Package
+ "nt", % Network Package
+ "rtp", % RTP Package
+ "swb", % SwitchBoard Package
+ "tdmc", % TDM Circuit Package
+ "" % Native pseudo package
+ ].
+
+%%----------------------------------------------------------------------
+%% List all matching capabilities
+%%----------------------------------------------------------------------
+
+capabilities(Package) ->
+ case Package of
+ "g" -> capabilities_g();
+ "root" -> capabilities_root();
+ "tonegen" -> capabilities_tonegen();
+ "tonedet" -> capabilities_tonedet();
+ "dg" -> capabilities_dg();
+ "dd" -> capabilities_dd();
+ "cg" -> capabilities_cg();
+ "cd" -> capabilities_cd();
+ "al" -> capabilities_al();
+ "ct" -> capabilities_ct();
+ "nt" -> capabilities_nt();
+ "rtp" -> capabilities_rtp();
+ "swb" -> capabilities_swb();
+ "tdmc" -> capabilities_tdmc();
+ "" -> capabilities_native()
+ end.
+
+%%----------------------------------------------------------------------
+%% Decode package name to internal form
+%% Scope ::= property | event | signal | statistics
+%%----------------------------------------------------------------------
+
+decode(mid, Package) ->
+ decode_mid(Package);
+decode(package, Package) ->
+ decode_package(Package);
+decode(profile, Package) ->
+ decode_profile(Package);
+decode(dialplan, Dialplan) ->
+ decode_dialplan(Dialplan);
+decode(Scope, [A, B | Item]) when is_atom(Scope) ->
+ ?d("decode(~p) -> entry with"
+ "~n A: ~p"
+ "~n B: ~p"
+ "~n Item: ~p", [Scope, A, B, Item]),
+ case decode_package([A, B]) of
+ "" ->
+ ?d("decode -> \"no\" package",[]),
+ decode_item(Scope, [A, B], Item);
+ Package ->
+ ?d("decode -> Package: ~p", [Package]),
+ Package ++ "/" ++ decode_item(Scope, [A, B], Item)
+ end;
+decode({Scope, [A, B | Item]}, SubItem) when is_atom(Scope) ->
+ ?d("decode(~p) -> entry with"
+ "~n A: ~p"
+ "~n B: ~p"
+ "~n Item: ~p"
+ "~n SubItem: ~p", [Scope, A, B, Item, SubItem]),
+ decode_item({Scope, Item}, [A, B], SubItem).
+
+decode_item(Scope, [A, B], Item) ->
+ ?d("decode_item -> entry",[]),
+ case A of
+ 16#00 ->
+ case B of
+ 16#01 -> decode_g(Scope, Item);
+ 16#02 -> decode_root(Scope, Item);
+ 16#03 -> decode_tonegen(Scope, Item);
+ 16#04 -> decode_tonedet(Scope, Item);
+ 16#05 -> decode_dg(Scope, Item);
+ 16#06 -> decode_dd(Scope, Item);
+ 16#07 -> decode_cg(Scope, Item);
+ 16#08 -> decode_cd(Scope, Item);
+ 16#09 -> decode_al(Scope, Item);
+ 16#0a -> decode_ct(Scope, Item);
+ 16#0b -> decode_nt(Scope, Item);
+ 16#0c -> decode_rtp(Scope, Item);
+ 16#0d -> decode_tdmc(Scope, Item);
+ 16#00 -> decode_native(Scope, Item)
+ end;
+ 16#fe ->
+ case B of
+ %% Proprietary extension
+ 16#fe -> decode_swb(Scope, Item)
+ end;
+ 16#ff ->
+ case B of
+ 16#ff when Item =:= [16#ff, 16#ff] -> "*"
+ end
+ end.
+
+decode_package(Package) ->
+ ?d("decode_package -> entry with"
+ "~n Package: ~p", [Package]),
+ [A, B] = Package,
+ case A of
+ 16#00 ->
+ case B of
+ 16#01 -> "g";
+ 16#02 -> "root";
+ 16#03 -> "tonegen";
+ 16#04 -> "tonedet";
+ 16#05 -> "dg";
+ 16#06 -> "dd";
+ 16#07 -> "cg";
+ 16#08 -> "cd";
+ 16#09 -> "al";
+ 16#0a -> "ct";
+ 16#0b -> "nt";
+ 16#0c -> "rtp";
+ 16#0d -> "tdmc";
+ 16#00 -> ""
+ end;
+ 16#fe ->
+ case B of
+ 16#fe -> "swb"
+ end;
+ 16#ff ->
+ case B of
+ 16#ff -> "*"
+ end
+ end.
+
+decode_profile([A, B]) ->
+ case A of
+ 16#00 ->
+ case B of
+ 16#fe -> "resgw";
+ _ -> "profile" ++ [A + $0, B + $0]
+ end;
+ _ ->
+ "profile" ++ [A + $0, B + $0]
+ end.
+
+decode_dialplan([A, B]) ->
+ "dialplan" ++ [A + $0, B + $0].
+
+decode_mid(Mid) ->
+ case Mid of
+ {domainName, DN} ->
+ Lower = to_lower(DN#'DomainName'.name),
+ {domainName, DN#'DomainName'{name = Lower}};
+ {deviceName, PathName} ->
+ Lower = to_lower(PathName),
+ {deviceName, Lower};
+ Other ->
+ Other
+ end.
+
+to_lower(Chars) ->
+ [?LOWER(Char) || Char <- Chars].
+
+%%----------------------------------------------------------------------
+%% Encode package name from internal form
+%% Scope ::= property | event | signal | statistics
+%%----------------------------------------------------------------------
+
+encode(mid, Package) ->
+ encode_mid(Package);
+encode(package, Package) ->
+ encode_package(Package);
+encode(profile, Profile) ->
+ encode_profile(Profile);
+encode(dialplan, Dialplan) ->
+ encode_dialplan(Dialplan);
+encode(Scope, PackageItem) when is_atom(Scope) ->
+ ?d("encode(~p) -> entry with"
+ "~n PackageItem: ~p", [Scope, PackageItem]),
+ case string:tokens(PackageItem, [$/]) of
+ [Package, Item] ->
+ ?d("encode -> "
+ "~n Package: ~p"
+ "~n Item: ~p", [Package, Item]),
+ encode_package(Package) ++ encode_item(Scope, Package, Item);
+ [Item] ->
+ ?d("encode -> Item: ~p", [Item]),
+ [16#00, 16#00 | encode_native(Scope, Item)]
+ end;
+encode({Scope, PackageItem}, SubItem) when is_atom(Scope) ->
+ ?d("encode(~p) -> entry with"
+ "~n PackageItem: ~p"
+ "~n SubItem: ~p", [Scope, PackageItem, SubItem]),
+ case string:tokens(PackageItem, [$/]) of
+ [Package, Item] ->
+ ?d("encode -> "
+ "~n Package: ~p"
+ "~n Item: ~p", [Package, Item]),
+ encode_item({Scope, Item}, Package, SubItem);
+ [_Item] ->
+ ?d("encode -> _Item: ~p", [_Item]),
+ encode_native(Scope, SubItem)
+ end.
+
+encode_item(_Scope, _Package, "*") ->
+ [16#ff, 16#ff];
+encode_item(Scope, Package, Item) ->
+ ?d("encode_item(~s) -> entry", [Package]),
+ case Package of
+ "g" -> encode_g(Scope, Item);
+ "root" -> encode_root(Scope, Item);
+ "tonegen" -> encode_tonegen(Scope, Item);
+ "tonedet" -> encode_tonedet(Scope, Item);
+ "dg" -> encode_dg(Scope, Item);
+ "dd" -> encode_dd(Scope, Item);
+ "cg" -> encode_cg(Scope, Item);
+ "cd" -> encode_cd(Scope, Item);
+ "al" -> encode_al(Scope, Item);
+ "ct" -> encode_ct(Scope, Item);
+ "nt" -> encode_nt(Scope, Item);
+ "rtp" -> encode_rtp(Scope, Item);
+ "tdmc" -> encode_tdmc(Scope, Item);
+ "swb" -> encode_swb(Scope, Item)
+ end.
+
+encode_package(Package) ->
+ case Package of
+ "g" -> [16#00, 16#01];
+ "root" -> [16#00, 16#02];
+ "tonegen" -> [16#00, 16#03];
+ "tonedet" -> [16#00, 16#04];
+ "dg" -> [16#00, 16#05];
+ "dd" -> [16#00, 16#06];
+ "cg" -> [16#00, 16#07];
+ "cd" -> [16#00, 16#08];
+ "al" -> [16#00, 16#09];
+ "ct" -> [16#00, 16#0a];
+ "nt" -> [16#00, 16#0b];
+ "rtp" -> [16#00, 16#0c];
+ "tdmc" -> [16#00, 16#0d];
+ "" -> [16#00, 16#00];
+ "*" -> [16#ff, 16#ff];
+ "swb" -> [16#fe, 16#fe]
+ end.
+
+encode_profile(Profile) ->
+ case Profile of
+ "resgw" ->
+ [16#00, 16#fe];
+ [$p, $r, $o, $f, $i, $l, $e | Name] ->
+ case Name of
+ [A, B] -> [A - $0, B - $0];
+ [B] -> [0, B - $0];
+ [] -> [0, 0]
+ end
+ end.
+
+encode_dialplan(Dialplan) ->
+ case Dialplan of
+ [$d, $i, $a, $l, $p, $l, $a, $n | Name] ->
+ case Name of
+ [A, B] -> [A - $0, B - $0];
+ [B] -> [0, B - $0];
+ [] -> [0, 0]
+ end
+ end.
+
+encode_mid(Mid) ->
+ Mid.
+
+
+%%----------------------------------------------------------------------
+%% Name: g - Generic
+%% Version: 1
+%% Extends: None
+%% Purpose: Generic package for commonly encountered items
+%%----------------------------------------------------------------------
+
+capabilities_g() ->
+ [
+ {event, "cause"},
+ {event, "sc"}
+ ].
+
+encode_g(event, Item) ->
+ case Item of
+ "cause" -> [16#00, 16#01];
+ "sc" -> [16#00, 16#02]
+ end;
+
+encode_g({event_parameter, Item}, SubItem) ->
+ case Item of
+ "cause" ->
+ case SubItem of
+ "Generalcause" -> [16#00, 16#01];
+ "Failurecause" -> [16#00, 16#02]
+ end;
+ "sc" ->
+ case SubItem of
+ "SigID" -> [16#00, 16#01];
+ "Meth" -> [16#00, 16#02];
+ "SLID" -> [16#00, 16#03];
+ "RID" -> [16#00, 16#04]
+ end
+ end.
+
+decode_g(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "cause";
+ [16#00, 16#02] -> "sc"
+ end;
+
+decode_g({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event: cause
+ case SubItem of
+ [16#00, 16#01] -> "Generalcause";
+ [16#00, 16#02] -> "Failurecause"
+ end;
+
+ [16#00, 16#02] -> % Event: sc
+ case SubItem of
+ [16#00, 16#01] -> "SigID";
+ [16#00, 16#02] -> "Meth";
+ [16#00, 16#03] -> "SLID";
+ [16#00, 16#04] -> "RID"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: root - Base Root Package
+%% Version: 2
+%% Extends: None
+%% Purpose: This package defines Gateway wide properties.
+%%----------------------------------------------------------------------
+
+capabilities_root() ->
+ [
+ {property, "maxNumberOfContexts"},
+ {property, "maxTerminationsPerContext"},
+ {property, "normalMGExecutionTime"},
+ {property, "normalMGCExecutionTime"},
+ {property, "MGProvisionalResponseTimerValue"},
+ {property, "MGCProvisionalResponseTimerValue"},
+ {property, "MGCOriginatedPendingLimit"},
+ {property, "MGOriginatedPendingLimit"}
+ ].
+
+encode_root(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ "maxNumberOfContexts" -> [16#00, 16#01];
+ "maxTerminationsPerContext" -> [16#00, 16#02];
+ "normalMGExecutionTime" -> [16#00, 16#03];
+ "normalMGCExecutionTime" -> [16#00, 16#04];
+ "MGProvisionalResponseTimerValue" -> [16#00, 16#05];
+ "MGCProvisionalResponseTimerValue" -> [16#00, 16#06];
+ "MGCOriginatedPendingLimit" -> [16#00, 16#07];
+ "MGOriginatedPendingLimit" -> [16#00, 16#08]
+ end
+ end.
+
+decode_root(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ [16#00, 16#01] -> "maxNumberOfContexts";
+ [16#00, 16#02] -> "maxTerminationsPerContext";
+ [16#00, 16#03] -> "normalMGExecutionTime";
+ [16#00, 16#04] -> "normalMGCExecutionTime";
+ [16#00, 16#05] -> "MGProvisionalResponseTimerValue";
+ [16#00, 16#06] -> "MGCProvisionalResponseTimerValue";
+ [16#00, 16#07] -> "MGCOriginatedPendingLimit";
+ [16#00, 16#08] -> "MGOriginatedPendingLimit"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tonegen - Tone Generator Package
+%% Version: 2
+%% Extends: None
+%% Purpose: This package defines signals to generate audio tones.
+%% This package does not specify parameter values. It is
+%% intended to be extendable. Generally, tones are defined
+%% as an individual signal with a parameter, ind,
+%% representing "interdigit" time delay, and a tone id to
+%% be used with playtones. A tone id should be kept
+%% consistent with any tone generation for the same tone.
+%% MGs are expected to be provisioned with the characteristics
+%% of appropriate tones for the country in which the MG is located.
+%%----------------------------------------------------------------------
+
+capabilities_tonegen() ->
+ [
+ {signal, "pt"}
+ ].
+
+encode_tonegen(signal, Item) ->
+ case Item of
+ "pt" -> [16#00, 16#01]
+ end;
+
+encode_tonegen({signal_parameter, Item}, SubItem) ->
+ case Item of
+ "pt" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "ind" -> [16#00, 16#02];
+ "btd" -> [16#00, 16#03]
+ end
+ end.
+
+decode_tonegen(signal, Item) ->
+ case Item of
+ [16#00, 16#01] -> "pt"
+ end;
+
+decode_tonegen({signal_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event: pt
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#02] -> "ind";
+ [16#00, 16#03] -> "btd"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tonedet - Tone Detection Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This Package defines events for audio tone detection.
+%% Tones are selected by name (tone id). MGs are expected
+%% to be provisioned with the characteristics of appropriate
+%% tones for the country in which the MG is located.
+%%
+%% This package does not specify parameter values.
+%% It is intended to be extendable.
+%%----------------------------------------------------------------------
+
+capabilities_tonedet() ->
+ [
+ {event, "std"},
+ {event, "etd"},
+ {event, "ltd"}
+ ].
+
+encode_tonedet(event, Item) ->
+ case Item of
+ "std" -> [16#00, 16#01];
+ "etd" -> [16#00, 16#02];
+ "ltd" -> [16#00, 16#03]
+ end;
+
+encode_tonedet({event_parameter, Item}, SubItem) ->
+ case Item of
+ "std" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "tid" -> [16#00, 16#03]
+ end;
+ "etd" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "tid" -> [16#00, 16#03];
+ "dur" -> [16#00, 16#02]
+ end;
+ "ltd" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "dur" -> [16#00, 16#02];
+ "tid" -> [16#00, 16#03]
+ end
+ end.
+
+decode_tonedet(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "std";
+ [16#00, 16#02] -> "etd";
+ [16#00, 16#03] -> "ltd"
+ end;
+
+decode_tonedet({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event std
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#03] -> "tid"
+ end;
+ [16#00, 16#02] -> % Event etd
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#03] -> "tid";
+ [16#00, 16#02] -> "dur"
+ end;
+ [16#00, 16#03] -> % Event ltd
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#02] -> "dur";
+ [16#00, 16#03] -> "tid"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: dg - Basic DTMF Generator Package
+%% Version: 1
+%% Extends: tonegen version 1
+%% Purpose: This package defines the basic DTMF tones as signals and
+%% extends the allowed values of parameter tl of playtone
+%% in tonegen.
+%%----------------------------------------------------------------------
+
+capabilities_dg() ->
+ [
+ {signal, "d0"},
+ {signal, "d1"},
+ {signal, "d2"},
+ {signal, "d3"},
+ {signal, "d4"},
+ {signal, "d5"},
+ {signal, "d6"},
+ {signal, "d7"},
+ {signal, "d8"},
+ {signal, "d9"},
+ {signal, "ds"},
+ {signal, "do"},
+ {signal, "da"},
+ {signal, "db"},
+ {signal, "dc"},
+ {signal, "dd"}
+ ].
+
+encode_dg(signal, Item) ->
+ case Item of
+ "d0" -> [16#00, 16#10];
+ "d1" -> [16#00, 16#11];
+ "d2" -> [16#00, 16#12];
+ "d3" -> [16#00, 16#13];
+ "d4" -> [16#00, 16#14];
+ "d5" -> [16#00, 16#15];
+ "d6" -> [16#00, 16#16];
+ "d7" -> [16#00, 16#17];
+ "d8" -> [16#00, 16#18];
+ "d9" -> [16#00, 16#19];
+ "ds" -> [16#00, 16#20];
+ "do" -> [16#00, 16#21];
+ "da" -> [16#00, 16#1a];
+ "db" -> [16#00, 16#1b];
+ "dc" -> [16#00, 16#1c];
+ "dd" -> [16#00, 16#1d]
+ end;
+
+encode_dg({signal_parameter, Item}, SubItem) ->
+ case Item of
+ "d0" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d1" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d2" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d3" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d4" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d5" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d6" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d7" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d8" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d9" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "ds" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "do" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "da" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "db" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dc" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dd" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end
+ end.
+
+decode_dg(signal, Item) ->
+ case Item of
+ [16#00, 16#10] -> "d0";
+ [16#00, 16#11] -> "d1";
+ [16#00, 16#12] -> "d2";
+ [16#00, 16#13] -> "d3";
+ [16#00, 16#14] -> "d4";
+ [16#00, 16#15] -> "d5";
+ [16#00, 16#16] -> "d6";
+ [16#00, 16#17] -> "d7";
+ [16#00, 16#18] -> "d8";
+ [16#00, 16#19] -> "d9";
+ [16#00, 16#20] -> "ds";
+ [16#00, 16#21] -> "do";
+ [16#00, 16#1a] -> "da";
+ [16#00, 16#1b] -> "db";
+ [16#00, 16#1c] -> "dc";
+ [16#00, 16#1d] -> "dd"
+ end;
+
+decode_dg({signal_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#10] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#11] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#12] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#13] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#14] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#15] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#16] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#17] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#18] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#19] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#20] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#21] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1a] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1b] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1c] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1d] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: dd - DTMF detection Package
+%% Version: 1
+%% Extends: tonedet version 1
+%% Purpose: This package defines the basic DTMF tones detection.
+%% Tones are selected by name (tone id). MGs are expected
+%% to be provisioned with the characteristics of appropriate
+%% tones for the country in which the MG is located.
+%%
+%% This package does not specify parameter values.
+%% It is intended to be extendable.
+%%
+%% Additional tone id values are all tone ids described in package dg
+%% (basic DTMF generator package).
+%%
+%% The following table maps DTMF events to digit map symbols as described
+%% in section 7.1.14.
+%%
+%% _________________________________
+%% | DTMF Event | Symbol |
+%% | d0 | "0" |
+%% | d1 | "1" |
+%% | d2 | "2" |
+%% | d3 | "3" |
+%% | d4 | "4" |
+%% | d5 | "5" |
+%% | d6 | "6" |
+%% | d7 | "7" |
+%% | d8 | "8" |
+%% | d9 | "9" |
+%% | da | "A" or "a"|
+%% | db | "B" or "b"|
+%% | dc | "C" or "c"|
+%% | dd | "D" or "d"|
+%% | ds | "E" or "e"|
+%% | do | "F" or "f"|
+%% |___________________|____________|
+%%
+%%----------------------------------------------------------------------
+
+capabilities_dd() ->
+ [
+ {event, "ce"},
+ {event, "d0"},
+ {event, "d1"},
+ {event, "d2"},
+ {event, "d3"},
+ {event, "d4"},
+ {event, "d5"},
+ {event, "d6"},
+ {event, "d7"},
+ {event, "d8"},
+ {event, "d9"},
+ {event, "ds"},
+ {event, "do"},
+ {event, "da"},
+ {event, "db"},
+ {event, "dc"},
+ {event, "dd"}
+ ].
+
+encode_dd(event, Item) ->
+ case Item of
+ "ce" -> [16#00, 16#04];
+ "d0" -> [16#00, 16#10];
+ "d1" -> [16#00, 16#11];
+ "d2" -> [16#00, 16#12];
+ "d3" -> [16#00, 16#13];
+ "d4" -> [16#00, 16#14];
+ "d5" -> [16#00, 16#15];
+ "d6" -> [16#00, 16#16];
+ "d7" -> [16#00, 16#17];
+ "d8" -> [16#00, 16#18];
+ "d9" -> [16#00, 16#19];
+ "ds" -> [16#00, 16#20];
+ "do" -> [16#00, 16#21];
+ "da" -> [16#00, 16#1a];
+ "db" -> [16#00, 16#1b];
+ "dc" -> [16#00, 16#1c];
+ "dd" -> [16#00, 16#1d]
+ end;
+
+encode_dd({event_parameter, Item}, SubItem) ->
+ case Item of
+ "ce" ->
+ case SubItem of
+ "ds" -> [16#00, 16#01];
+ "Meth" -> [16#00, 16#03]
+ end;
+ "d0" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d1" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d2" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d3" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d4" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d5" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d6" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d7" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d8" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d9" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "ds" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "do" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "da" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "db" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dc" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dd" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end
+ end.
+
+decode_dd(event, Item) ->
+ case Item of
+ [16#00, 16#04] -> "ce";
+ [16#00, 16#10] -> "d0";
+ [16#00, 16#11] -> "d1";
+ [16#00, 16#12] -> "d2";
+ [16#00, 16#13] -> "d3";
+ [16#00, 16#14] -> "d4";
+ [16#00, 16#15] -> "d5";
+ [16#00, 16#16] -> "d6";
+ [16#00, 16#17] -> "d7";
+ [16#00, 16#18] -> "d8";
+ [16#00, 16#19] -> "d9";
+ [16#00, 16#20] -> "ds";
+ [16#00, 16#21] -> "do";
+ [16#00, 16#1a] -> "da";
+ [16#00, 16#1b] -> "db";
+ [16#00, 16#1c] -> "dc";
+ [16#00, 16#1d] -> "dd"
+ end;
+
+decode_dd({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#04] -> % Event ce
+ case SubItem of
+ [16#00, 16#01] -> "ds";
+ [16#00, 16#03] -> "Meth"
+ end;
+ [16#00, 16#10] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#11] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#12] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#13] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#14] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#15] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#16] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#17] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#18] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#19] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#20] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#21] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1a] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1b] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1c] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1d] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: cg - Call Progress Tones Generator Package
+%% Version: 1
+%% Extends: tonegen version 1
+%% Purpose: This package defines the basic call progress tones as signals
+%% and extends the allowed values of the tl parameter of
+%% playtone in tonegen.
+%%----------------------------------------------------------------------
+
+capabilities_cg() ->
+ [
+ {signal, "dt"},
+ {signal, "rt"},
+ {signal, "bt"},
+ {signal, "ct"},
+ {signal, "sit"},
+ {signal, "wt"},
+ {signal, "prt"},
+ {signal, "cw"},
+ {signal, "cr"}
+ ].
+
+
+encode_cg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ "dt" -> [16#00, 16#30];
+ "rt" -> [16#00, 16#31];
+ "bt" -> [16#00, 16#32];
+ "ct" -> [16#00, 16#33];
+ "sit" -> [16#00, 16#34];
+ "wt" -> [16#00, 16#35];
+ "prt" -> [16#00, 16#36];
+ "cw" -> [16#00, 16#37];
+ "cr" -> [16#00, 16#38]
+ end
+ end.
+
+decode_cg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ [16#00, 16#30] -> "dt";
+ [16#00, 16#31] -> "rt";
+ [16#00, 16#32] -> "bt";
+ [16#00, 16#33] -> "ct";
+ [16#00, 16#34] -> "sit";
+ [16#00, 16#35] -> "wt";
+ [16#00, 16#36] -> "prt";
+ [16#00, 16#37] -> "cw";
+ [16#00, 16#38] -> "cr"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: cd - Call Progress Tones Detection Package
+%% Version: 1
+%% Extends: tonedet version 1
+%% Purpose: This package defines the basic call progress detection tones.
+%% This Package extends the possible values of tone id
+%% in the "start tone detected", "end tone detected" and
+%% "long tone detected" events.
+%% Additional values
+%% tone id values are defined for start tone detected,
+%% end tone detected and long tone detected with
+%% the same values as those in package cg (call
+%% progress tones generation package).
+%%
+%% The required set of tone ids corresponds to Recommendation E.180/Q.35
+%% [ITU-T Recommendation E.180/Q.35 (1998)]. See Recommendation E.180/Q.35
+%% for definition of the meanings of these tones.
+%%----------------------------------------------------------------------
+
+capabilities_cd() ->
+ [
+ {event, "dt"},
+ {event, "rt"},
+ {event, "bt"},
+ {event, "ct"},
+ {event, "sit"},
+ {event, "wt"},
+ {event, "prt"},
+ {event, "cw"},
+ {event, "cr"}
+ ].
+
+
+encode_cd(Scope, Item) ->
+ case Scope of
+ event ->
+ case Item of
+ "dt" -> [16#00, 16#30];
+ "rt" -> [16#00, 16#31];
+ "bt" -> [16#00, 16#32];
+ "ct" -> [16#00, 16#33];
+ "sit"-> [16#00, 16#34];
+ "wt" -> [16#00, 16#35];
+ "prt"-> [16#00, 16#36];
+ "cw" -> [16#00, 16#37];
+ "cr" -> [16#00, 16#38]
+ end
+ end.
+
+decode_cd(Scope, Item) ->
+ case Scope of
+ event ->
+ case Item of
+ [16#00, 16#30] -> "dt";
+ [16#00, 16#31] -> "rt";
+ [16#00, 16#32] -> "bt";
+ [16#00, 16#33] -> "ct";
+ [16#00, 16#34] -> "sit";
+ [16#00, 16#35] -> "wt";
+ [16#00, 16#36] -> "prt";
+ [16#00, 16#37] -> "cw";
+ [16#00, 16#38] -> "cr"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: al - Analog Line Supervision Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines events and signals for an analog line.
+%%----------------------------------------------------------------------
+
+capabilities_al() ->
+ [
+ {event, "on"},
+ {event, "of"},
+ {event, "fl"},
+ {signal, "ri"}
+ ].
+
+encode_al(event, Item) ->
+ ?d("encode_al(event) -> entry with"
+ "~n Item: ~p", [Item]),
+ case Item of
+ "on" -> [16#00, 16#04];
+ "of" -> [16#00, 16#05];
+ "fl" -> [16#00, 16#06]
+ end;
+
+encode_al({event_parameter, Item}, SubItem) ->
+ ?d("encode_al({event_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ "on" ->
+ case SubItem of
+ "strict" -> [16#00, 16#01];
+ "init" -> [16#00, 16#02]
+ end;
+ "of" ->
+ case SubItem of
+ "strict" -> [16#00, 16#01];
+ "init" -> [16#00, 16#02]
+ end;
+ "fl" ->
+ case SubItem of
+ "mindur" -> [16#00, 16#04];
+ "maxdur" -> [16#00, 16#05]
+ end
+ end;
+
+encode_al(signal, Item) ->
+ ?d("encode_al(signal) -> entry with"
+ "~n Item: ~p", [Item]),
+ case Item of
+ "ri" -> [16#00, 16#02]
+ end;
+
+encode_al({signal_parameter, Item}, SubItem) ->
+ ?d("encode_al({signal_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ "ri" ->
+ case SubItem of
+ "cad" -> [16#00, 16#06];
+ "freq" -> [16#00, 16#07]
+ end
+ end.
+
+decode_al(event, SubItem) ->
+ ?d("decode_al(event) -> entry with"
+ "~n SubItem: ~p", [SubItem]),
+ case SubItem of
+ [16#00, 16#04] -> "on";
+ [16#00, 16#05] -> "of";
+ [16#00, 16#06] -> "fl"
+ end;
+
+decode_al({event_parameter, Item}, SubItem) ->
+ ?d("decode_al({event_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ [16#00,16#04] -> %% Event: on
+ case SubItem of
+ [16#00, 16#01] -> "strict";
+ [16#00, 16#02] -> "init"
+ end;
+ [16#00,16#05] -> %% Event: of
+ case SubItem of
+ [16#00, 16#01] -> "strict";
+ [16#00, 16#02] -> "init"
+ end;
+ [16#00,16#06] -> %% Event: fl
+ case SubItem of
+ [16#00, 16#04] -> "mindur";
+ [16#00, 16#05] -> "maxdur"
+ end
+ end;
+
+decode_al(signal, SubItem) ->
+ ?d("decode_al(signal) -> entry with"
+ "~n SubItem: ~p", [SubItem]),
+ case SubItem of
+ [16#00, 16#02] -> "ri"
+ end;
+
+decode_al({signal_parameter, Item}, SubItem) ->
+ ?d("decode_al({signal_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ [16#00,16#02] -> %% Event: ri
+ case SubItem of
+ [16#00, 16#06] -> "cad";
+ [16#00, 16#07] -> "freq"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: ct - Basic Continuity Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines events and signals for continuity test.
+%% The continuity test includes provision of either a loopback
+%% or transceiver functionality.
+%%----------------------------------------------------------------------
+
+capabilities_ct() ->
+ [
+ {event, "cmp"},
+ {signal, "ct"},
+ {signal, "rsp"}
+ ].
+
+encode_ct(event, Item) ->
+ case Item of
+ "cmp" -> [16#00, 16#05]
+ end;
+encode_ct({event_parameter, Item}, SubItem) ->
+ case Item of
+ "cmp" ->
+ case SubItem of
+ "res" -> [16#00, 16#08]
+ end
+ end;
+encode_ct(signal, Item) ->
+ case Item of
+ "ct" -> [16#00, 16#03];
+ "rsp" -> [16#00, 16#04]
+ end.
+
+decode_ct(event, Item) ->
+ case Item of
+ [16#00, 16#05] -> "cmp"
+ end;
+decode_ct({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#05] -> % Event cmp
+ case SubItem of
+ [16#00, 16#08] -> "res"
+ end
+ end;
+decode_ct(signal, Item) ->
+ case Item of
+ [16#00, 16#03] -> "ct";
+ [16#00, 16#04] -> "rsp"
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: nt - Network Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines properties of network terminations
+%% independent of network type.
+%%----------------------------------------------------------------------
+
+capabilities_nt() ->
+ [
+ {property, "jit"},
+ {event, "netfail"},
+ {event, "qualert"},
+ {statistics, "dur"},
+ {statistics, "os"},
+ {statistics, "or"}
+ ].
+
+encode_nt(property, Item) ->
+ case Item of
+ "jit" -> [16#00, 16#07]
+ end;
+encode_nt(event, Item) ->
+ case Item of
+ "netfail" -> [16#00, 16#05];
+ "qualert" -> [16#00, 16#06]
+ end;
+encode_nt({event_parameter, Item}, SubItem) ->
+ case Item of
+ "netfail" ->
+ case SubItem of
+ "cs" -> [16#00, 16#01]
+ end;
+ "qualert" ->
+ case SubItem of
+ "th" -> [16#00, 16#01]
+ end
+ end;
+encode_nt(statistics, Item) ->
+ case Item of
+ "dur" -> [16#00, 16#01];
+ "os" -> [16#00, 16#02];
+ "or" -> [16#00, 16#03]
+ end.
+
+decode_nt(property, Item) ->
+ case Item of
+ [16#00, 16#07] -> "jit"
+ end;
+decode_nt(event, Item) ->
+ case Item of
+ [16#00, 16#05] -> "netfail";
+ [16#00, 16#06] -> "qualert"
+ end;
+decode_nt({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#05] -> % Event netfail
+ case SubItem of
+ [16#00, 16#01] -> "cs"
+ end;
+ [16#00, 16#06] -> % Event qualert
+ case Item of
+ [16#00, 16#01] -> "th"
+ end
+ end;
+decode_nt(statistics, Item) ->
+ case Item of
+ [16#00, 16#01] -> "dur";
+ [16#00, 16#02] -> "os";
+ [16#00, 16#03] -> "or"
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: rtp - RTP Package
+%% Version: 1
+%% Extends: nt version 1
+%% Purpose: This package is used to support packet based multimedia
+%% data transfer by means of the Real-time Transport Protocol
+%% (RTP) [RFC 1889].
+%%----------------------------------------------------------------------
+
+capabilities_rtp() ->
+ [
+ {event, "pltrans"},
+ {statistics, "ps"},
+ {statistics, "pr"},
+ {statistics, "pl"},
+ {statistics, "jit"},
+ {statistics, "delay"}
+ ].
+
+encode_rtp(event, Item) ->
+ case Item of
+ "pltrans" -> [16#00, 16#01]
+ end;
+encode_rtp({event_parameter, Item}, SubItem) ->
+ case Item of
+ "pltrans" ->
+ case SubItem of
+ "rtppltype" -> [16#00, 16#01]
+ end
+ end;
+encode_rtp(statistics, Item) ->
+ case Item of
+ "ps" -> [16#00, 16#04];
+ "pr" -> [16#00, 16#05];
+ "pl" -> [16#00, 16#06];
+ "jit" -> [16#00, 16#07];
+ "delay" -> [16#00, 16#08]
+ end.
+
+decode_rtp(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "pltrans"
+ end;
+decode_rtp({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event pltrans
+ case SubItem of
+ [16#00, 16#01] -> "rtppltype"
+ end
+ end;
+decode_rtp(statistics, Item) ->
+ case Item of
+ [16#00, 16#04] -> "ps";
+ [16#00, 16#05] -> "pr";
+ [16#00, 16#06] -> "pl";
+ [16#00, 16#07] -> "jit";
+ [16#00, 16#08] -> "delay"
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tdmc - TDM Circuit Package
+%% Version: 1
+%% Extends: nt version 1
+%% Purpose: This package is used to support TDM circuit terminations.
+%%----------------------------------------------------------------------
+
+capabilities_tdmc() ->
+ [
+ {property, "ec"},
+ {property, "gain"}
+ ].
+
+encode_tdmc(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ "ec" -> [16#00, 16#08];
+ "gain" -> [16#00, 16#0a]
+ end
+ end.
+
+decode_tdmc(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ [16#00, 16#08] -> "ec";
+ [16#00, 16#0a] -> "gain"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: swb - SwitchBoard Package
+%% Version: 1
+%% Extends: none
+%% Purpose: This package is used to support SwitchBoard specials
+%%----------------------------------------------------------------------
+
+capabilities_swb() ->
+ [
+ {statistics, "fs"}, % Free slots
+ {statistics, "as"} % Allocated slots
+ ].
+
+encode_swb(Scope, Item) ->
+ case Scope of
+ statistics ->
+ case Item of
+ "fs" -> [16#00, 16#00];
+ "as" -> [16#00, 16#01]
+ end
+ end.
+
+decode_swb(Scope, Item) ->
+ case Scope of
+ statistics ->
+ case Item of
+ [16#00, 16#00] -> "fs";
+ [16#00, 16#01] -> "as"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: native - Pseudo package
+%% Version: 1
+%% Extends: None
+%% Purpose: Native tags for media stream properties
+%%
+%% Parameters for Local descriptors and Remote descriptors are
+%% specified as tag-value pairs if binary encoding is used for the
+%% protocol. This annex contains the property names (PropertyID), the
+%% tags (Property Tag), type of the property (Type) and the values
+%% (Value).Values presented in the Value field when the field contains
+%% references shall be regarded as "information". The reference
+%% contains the normative values. If a value field does not contain a
+%% reference then the values in that field can be considered as
+%% "normative".
+%%
+%% Tags are given as hexadecimal numbers in this annex. When setting
+%% the value of a property, a MGC may underspecify the value according
+%% to one of the mechanisms specified in section 7.1.1.
+%%
+%% For type "enumeration" the value is represented by the value in brack-
+%% ets, e.g., Send(0), Receive(1).
+%%----------------------------------------------------------------------
+%%
+%% C.6. IP
+%%
+%% ________________________________________________________________
+%% | PropertyID| Tag | Type | Value |
+%% | IPv4 | 6001 | 32 BITS | Ipv4Address |
+%% | IPv6 | 6002 | 128 BITS | IPv6 Address |
+%% | Port | 6003 | Unsigned Int| Port |
+%% | Porttype | 6004 | Enumerated | TCP(0),UDP(1),SCTP(2)|
+%% |___________|____________|______________|_______________________|
+%%
+%%
+%% C.11. SDP Equivalents
+%%
+%% ______________________________________________________________
+%% | PropertyID| Tag | Type | Value |
+%% | SDP_V | B001| STRING| Protocol Version |
+%% | SDP_O | B002| STRING| Owner-creator and session ID |
+%% | SDP_S | B003| STRING| Sesson name |
+%% | SDP_I | B004| STRING| Session identifier |
+%% | SDP_U | B005| STRING| URI of descriptor |
+%% | SDC_E | B006| STRING| email address |
+%% | SDP_P | B007| STRING| phone number |
+%% | SDP_C | B008| STRING| Connection information |
+%% | SDP_B | B009| STRING| Bandwidth Information |
+%% | SDP_Z | B00A| STRING| time zone adjustment |
+%% | SDP_K | B00B| STRING| Encryption Key |
+%% | SDP_A | B00C| STRING| Zero or more session attributes|
+%% | SDP_T | B00D| STRING| Active Session Time |
+%% | SDP_R | B00E| STRING| Zero or more repeat times |
+%% | SDP_M | B00F| STRING| Media name and transport addr |
+%% | | | | Reference: IETF RFC 2327 |
+%% |___________|______|________|_________________________________|
+%%
+%%----------------------------------------------------------------------
+
+capabilities_native() ->
+ [
+ %% C.6. IP
+ {property, "IPv4"},
+ {property, "IPv6"},
+ {property, "Port"},
+ {property, "Porttype"},
+
+ %% C.11. SDP Equivalents
+ {property, "v"},
+ {property, "o"},
+ {property, "s"},
+ {property, "i"},
+ {property, "u"},
+ {property, "e"},
+ {property, "p"},
+ {property, "c"},
+ {property, "b"},
+ {property, "z"},
+ {property, "k"},
+ {property, "a"},
+ {property, "t"},
+ {property, "r"},
+ {property, "m"}
+ ].
+
+encode_native(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ %% IP
+ "IPv4" -> [16#60, 16#01];
+ "IPv6" -> [16#60, 16#02];
+ "Port" -> [16#60, 16#03];
+ "Porttype" -> [16#60, 16#04];
+
+ %% SDP
+ "v" -> [16#b0, 16#01];
+ "o" -> [16#b0, 16#02];
+ "s" -> [16#b0, 16#03];
+ "i" -> [16#b0, 16#04];
+ "u" -> [16#b0, 16#05];
+ "e" -> [16#b0, 16#06];
+ "p" -> [16#b0, 16#07];
+ "c" -> [16#b0, 16#08];
+ "b" -> [16#b0, 16#09];
+ "z" -> [16#b0, 16#0a];
+ "k" -> [16#b0, 16#0b];
+ "a" -> [16#b0, 16#0c];
+ "t" -> [16#b0, 16#0d];
+ "r" -> [16#b0, 16#0e];
+ "m" -> [16#b0, 16#0f]
+ end
+ end.
+
+decode_native(Scope, [Type, Item]) ->
+ case Scope of
+ property ->
+ case Type of
+ 16#60 ->
+ case Item of
+ 16#01 -> "IPv4";
+ 16#02 -> "IPv6";
+ 16#03 -> "Port";
+ 16#04 -> "Porttype"
+ end;
+
+ 16#b0 ->
+ case Item of
+ 16#01 -> "v";
+ 16#02 -> "o";
+ 16#03 -> "s";
+ 16#04 -> "i";
+ 16#05 -> "u";
+ 16#06 -> "e";
+ 16#07 -> "p";
+ 16#08 -> "c";
+ 16#09 -> "b";
+ 16#0a -> "z";
+ 16#0b -> "k";
+ 16#0c -> "a";
+ 16#0d -> "t";
+ 16#0e -> "r";
+ 16#0f -> "m"
+ end
+ end
+ end.
+
+%% -------------------------------------------------------------------
+
+% error(Reason) ->
+% erlang:error(Reason).
+
diff --git a/lib/megaco/src/binary/megaco_binary_name_resolver_prev3b.erl b/lib/megaco/src/binary/megaco_binary_name_resolver_prev3b.erl
new file mode 100644
index 0000000000..12e673ac81
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_name_resolver_prev3b.erl
@@ -0,0 +1,2003 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Handle meta data about packages
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_name_resolver_prev3b).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+-include_lib("megaco/src/app/megaco_internal.hrl").
+
+
+-define(LOWER(Char),
+ if
+ Char >= $A, Char =< $Z ->
+ Char - ($A - $a);
+ true ->
+ Char
+ end).
+
+-export([packages/0,
+ capabilities/0,
+ capabilities/1,
+ decode_name/3,
+ encode_name/3
+ ]).
+
+encode_name(Config, term_id, TermId) ->
+ case megaco:encode_binary_term_id(Config, TermId) of
+ {ok, TermId2} ->
+ TermId2;
+ {error, _Reason} ->
+ exit({bad_term_id, TermId})
+ end;
+encode_name(_Config, Scope, Item) ->
+ ?d("encode_name(~p) -> entry with"
+ "~n Item: ~p", [Scope, Item]),
+ encode(Scope, Item).
+
+decode_name(Config, term_id, TermId) ->
+ case megaco:decode_binary_term_id(Config, TermId) of
+ {ok, TermId2} ->
+ TermId2;
+ {error, _Reason} ->
+ exit({bad_term_id, TermId})
+ end;
+decode_name(_Config, Scope, Item) ->
+ ?d("decode_name(~p) -> entry with"
+ "~n Item: ~p", [Scope, Item]),
+ decode(Scope, Item).
+
+
+
+%%----------------------------------------------------------------------
+%% 12.1.1 Package
+%%
+%% Overall description of the package, specifying:
+%%
+%% Package Name: only descriptive
+%%
+%% PackageID: is an identifier
+%%
+%% Description: is a description of the package
+%%
+%% Version:
+%%
+%% A new version of a package can only add additional Properties,
+%% Events, Signals, Statistics and new possible values for an
+%% existing parameter described in the original package. No
+%% deletions or modifications shall be allowed. A version is an
+%% integer in the range from 1 to 99.
+%%
+%% Designed to be extended only (Optional): Yes
+%%
+%% This indicates that the package has been expressly designed to
+%% be extended by others, not to be directly referenced. For
+%% example, the package may not have any function on its own or be
+%% nonsensical on its own. The MG SHOULD NOT publish this PackageID
+%% when reporting packages.
+%%
+%% Extends: existing package Descriptor
+%%
+%% A package may extend an existing package. The version of the
+%% original package must be specified. When a package extends
+%% another package it shall only add additional Properties, Events,
+%% Signals, Statistics and new possible values for an existing
+%% parameter described in the original package. An extended package
+%% shall not redefine or overload an identifier defined in the
+%% original package and packages it may have extended (multiple
+%% levels of extension). Hence, if package B version 1 extends
+%% package A version 1, version 2 of B will not be able to extend
+%% the A version 2 if A version 2 defines a name already in B
+%% version 1. If the package does not extend another package, it
+%% shall specify "none".
+%%
+%%
+%% 12.1.2 Properties
+%%
+%% Properties defined by the package, specifying:
+%%
+%% Property Name: only descriptive
+%%
+%% PropertyID: is an identifier
+%%
+%% Description: is a description of the function of the property
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 string
+%%
+%% Octet String: A number of octets. See Annex A and B.3 for
+%% encoding
+%%
+%% Integer: 4 byte signed integer
+%%
+%% Double: 8 byte signed integer
+%%
+%% Character: unicode UTF-8 encoding of a single letter.
+%% Could be more than one octet.
+%%
+%% Enumeration: one of a list of possible unique values (see 12.3)
+%%
+%% Sub-list: a list of several values from a list.
+%% The type of sub-list SHALL also be specified.
+%% The type shall be chosen from the types specified in
+%% this section (with the exception of sub-list). For
+%% example, Type: sub-list of enumeration. The encoding
+%% of sub-lists is specified in Annexes A and B.3.
+%%
+%% Possible values:
+%%
+%% A package MUST specify either a specific set of values or a
+%% description of how values are determined. A package MUST also
+%% specify a default value or the default behaviour when the value
+%% is omitted from its descriptor. For example, a package may
+%% specify that procedures related to the property are suspended
+%% when its value is omitted.
+%%
+%% Default:
+%%
+%% A default value (but not procedures) may be specified as
+%% provisionable.
+%%
+%% Defined in:
+%%
+%% Which H.248.1 descriptor the property is defined in.
+%% LocalControl is for stream-dependent properties.
+%% TerminationState is for stream-independent properties.
+%% ContextAttribute is for properties that affect the context as
+%% a whole, i.e., mixing properties. These are expected to be the
+%% most common cases, but it is possible for properties to be
+%% defined in other descriptors. Context properties MUST be defined
+%% in the ContextAttribute descriptor.
+%%
+%% Characteristics: Read/Write or both, and (optionally), global:
+%%
+%% Indicates whether a property is read-only, or read-write, and
+%% if it is global. If Global is omitted, the property is not
+%% global. If a property is declared as global, the value of the
+%% property is shared by all Terminations realizing the package.
+%% If a context property is declared as global, the property is
+%% shared by all contexts realizing the package.
+%%
+%%
+%% 12.1.3 Events
+%%
+%% Events defined by the package, specifying:
+%%
+%% Event name: only descriptive
+%%
+%% EventID: is an identifier
+%%
+%% Description: a description of the function of the event
+%%
+%% EventsDescriptor Parameters:
+%%
+%% Parameters used by the MGC to configure the event, and found in
+%% the EventsDescriptor. See 12.2. If there are no parameters for
+%% the Events Descriptor, then "none" shall be specified.
+%%
+%% ObservedEventsDescriptor Parameters:
+%%
+%% Parameters returned to the MGC in Notify requests and in replies
+%% to command requests from the MGC that audit
+%% ObservedEventsDescriptor, and found in the
+%% ObservedEventsDescriptor. See 12.2. If there are no parameters
+%% for the ObservedEvents Descriptor, then �none� shall be specified.
+%%
+%%
+%% 12.1.4 Signals
+%%
+%% Signals defined by the package, specifying:
+%%
+%% Signal Name: only descriptive
+%%
+%% SignalID: is an identifier. SignalID is used in a SignalsDescriptor
+%%
+%% Description: a description of the function of the signal
+%%
+%% SignalType: one of:
+%%
+%% OO (On/Off)
+%%
+%% TO (TimeOut)
+%%
+%% BR (Brief)
+%%
+%% NOTE -�SignalType may be defined such that it is dependent on
+%% the value of one or more parameters. The package MUST specify a
+%% default signal type. If the default type is TO, the package MUST
+%% specify a default duration which may be provisioned. A default
+%% duration is meaningless for BR.
+%%
+%% Duration: in hundredths of seconds
+%%
+%% Additional Parameters: see 12.2
+%%
+%%
+%% 12.1.5 Statistics
+%%
+%% Statistics defined by the package, specifying:
+%%
+%% Statistic name: only descriptive
+%%
+%% StatisticID: is an identifier
+%%
+%% StatisticID is used in a StatisticsDescriptor
+%%
+%% Description: a description of the statistic
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 string
+%%
+%% Octet String: A number of octets.
+%% See Annex A and Annex B.3 for encoding
+%%
+%% Integer: 4 byte signed integer
+%%
+%% Double: 8 byte signed integer
+%%
+%% Character: Unicode UTF-8 encoding of a single letter.
+%% Could be more than one octet.
+%%
+%% Enumeration: One of a list of possible unique values (See 12.3)
+%%
+%% Sub-list: A list of several values from a list.
+%% The type of sub-list SHALL also be specified.
+%% The type shall be chosen from the types specified in
+%% this section (with the exception of sub-list).
+%% For example, Type: sub-list of enumeration.
+%% The encoding of sub-lists is specified in Annexes A
+%% and B.3.
+%%
+%% Possible Values:
+%%
+%% A package must indicate the unit of measure, e.g. milliseconds,
+%% packets, either here or along with the type above, as well as
+%% indicating any restriction on the range.
+%%
+%% Level: Specify if the statistic can be kept at the Termination
+%% level, Stream level or Either.
+%%
+%%
+%% 12.1.6 Error Codes
+%%
+%% If the package does not define any error codes, this section may be omitted.
+%% Otherwise, it describes error codes defined by the package, specifying:
+%%
+%% Error Code #: The error code number.
+%%
+%% Name: Name of the error
+%%
+%% Definition: A description of the error code.
+%%
+%% Error Text in the Error Descriptor:
+%%
+%% A description of what text to return in the Error Descriptor.
+%%
+%% Comment: Any further comments on the use of the error code.
+%%
+%%
+%% 12.1.7 Procedures
+%%
+%% Additional guidance on the use of the package.
+%%
+%%
+%% 12.2 Guidelines to defining parameters to events and signals
+%%
+%% Parameter Name: only descriptive
+%%
+%% ParameterID: is an identifier. The textual ParameterID of
+%% parameters to Events and Signals shall not start with "EPA" and
+%% "SPA", respectively. The textual ParameterID shall also not be
+%% "ST", "Stream", "SY", "SignalType", "DR", "Duration", "NC",
+%% "NotifyCompletion", "KA", "KeepActive", "EB", "Embed", "DM",
+%% "DigitMap", "DI", "Direction", "RQ" or "RequestID".
+%%
+%% Description: a description of the function of the parameter.
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 octet string
+%%
+%% Octet String: A number of octets. See Annex A and B.3 for
+%% encoding
+%%
+%% Integer: 4-octet signed integer
+%%
+%% Double: 8-octet signed integer
+%%
+%% Character: Unicode UTF-8 encoding of a single letter. Could be
+%% more than one octet.
+%%
+%% Enumeration: one of a list of possible unique values (see 12.3)
+%%
+%% Sub-list: a list of several values from a list (not supported
+%% for statistics). The type of sub-list SHALL also be
+%% specified The type shall be chosen from the types
+%% specified in this section (with the exception of
+%% sub-list). For example, Type: sub-list of enumeration.
+%% The encoding of sub-lists is specified in Annex A
+%% and B.3.
+%%
+%% Optional: Yes/No
+%%
+%% Describes if the parameter may be omitted from the signal or
+%% event.
+%%
+%% Possible values:
+%%
+%% A package MUST specify either a specific set of values or a
+%% description of how values are determined. A package MUST
+%% also specify a default value or the default behavior when the
+%% value is omitted from its descriptor. For example, a package
+%% may specify that procedures related to the parameter are
+%% suspended when its value is omitted.
+%%
+%% Default:
+%%
+%% A default value (but not procedures) may be specified as
+%% provisionable.
+%%
+%%
+%% 12.3 Lists
+%%
+%% Possible values for parameters include enumerations. Enumerations may be
+%% defined in a list. It is recommended that the list be IANA registered so
+%% that packages that extend the list can be defined without concern for
+%% conflicting names.
+%%
+%%
+%% 12.4 Identifiers
+%%
+%% Identifiers in text encoding shall be strings of up to 64 characters,
+%% containing no spaces, starting with an alphabetic character and consisting
+%% of alphanumeric characters and/or digits, and possibly including the
+%% special character underscore ("_").
+%%
+%% Identifiers in binary encoding are 2 octets long.
+%%
+%% Both text and binary values shall be specified for each identifier,
+%% including identifiers used as values in enumerated types.
+%%
+%%
+%% 12.5 Package registration
+%%
+%% A package can be registered with IANA for interoperability reasons. See
+%% clause 14 for IANA considerations.
+%%
+%%----------------------------------------------------------------------
+
+capabilities() ->
+ [{P, capabilities(P)} || P <- packages()].
+
+%% -record(property, {name, type, values, defined_in, characteristics}).
+
+%%----------------------------------------------------------------------
+%% List all known packages
+%% 'native' and 'all' are not real packages
+%%----------------------------------------------------------------------
+
+packages() ->
+ [
+ "g", % Generic
+ "root", % Base Root Package
+ "tonegen", % Tone Generator Package
+ "tonedet", % Tone Detection Package
+ "dg", % Basic DTMF Generator Package
+ "dd", % DTMF detection Package
+ "cg", % Call Progress Tones Generator Package
+ "cd", % Call Progress Tones Detection Package
+ "al", % Analog Line Supervision Package
+ "ct", % Basic Continuity Package
+ "nt", % Network Package
+ "rtp", % RTP Package
+ "swb", % SwitchBoard Package
+ "tdmc", % TDM Circuit Package
+ "" % Native pseudo package
+ ].
+
+%%----------------------------------------------------------------------
+%% List all matching capabilities
+%%----------------------------------------------------------------------
+
+capabilities(Package) ->
+ case Package of
+ "g" -> capabilities_g();
+ "root" -> capabilities_root();
+ "tonegen" -> capabilities_tonegen();
+ "tonedet" -> capabilities_tonedet();
+ "dg" -> capabilities_dg();
+ "dd" -> capabilities_dd();
+ "cg" -> capabilities_cg();
+ "cd" -> capabilities_cd();
+ "al" -> capabilities_al();
+ "ct" -> capabilities_ct();
+ "nt" -> capabilities_nt();
+ "rtp" -> capabilities_rtp();
+ "swb" -> capabilities_swb();
+ "tdmc" -> capabilities_tdmc();
+ "" -> capabilities_native()
+ end.
+
+%%----------------------------------------------------------------------
+%% Decode package name to internal form
+%% Scope ::= property | event | signal | statistics
+%%----------------------------------------------------------------------
+
+decode(mid, Package) ->
+ decode_mid(Package);
+decode(package, Package) ->
+ decode_package(Package);
+decode(profile, Package) ->
+ decode_profile(Package);
+decode(dialplan, Dialplan) ->
+ decode_dialplan(Dialplan);
+decode(Scope, [A, B | Item]) when is_atom(Scope) ->
+ ?d("decode(~p) -> entry with"
+ "~n A: ~p"
+ "~n B: ~p"
+ "~n Item: ~p", [Scope, A, B, Item]),
+ case decode_package([A, B]) of
+ "" ->
+ ?d("decode -> \"no\" package",[]),
+ decode_item(Scope, [A, B], Item);
+ Package ->
+ ?d("decode -> Package: ~p", [Package]),
+ Package ++ "/" ++ decode_item(Scope, [A, B], Item)
+ end;
+decode({Scope, [A, B | Item]}, SubItem) when is_atom(Scope) ->
+ ?d("decode(~p) -> entry with"
+ "~n A: ~p"
+ "~n B: ~p"
+ "~n Item: ~p"
+ "~n SubItem: ~p", [Scope, A, B, Item, SubItem]),
+ decode_item({Scope, Item}, [A, B], SubItem).
+
+decode_item(Scope, [A, B], Item) ->
+ ?d("decode_item -> entry",[]),
+ case A of
+ 16#00 ->
+ case B of
+ 16#01 -> decode_g(Scope, Item);
+ 16#02 -> decode_root(Scope, Item);
+ 16#03 -> decode_tonegen(Scope, Item);
+ 16#04 -> decode_tonedet(Scope, Item);
+ 16#05 -> decode_dg(Scope, Item);
+ 16#06 -> decode_dd(Scope, Item);
+ 16#07 -> decode_cg(Scope, Item);
+ 16#08 -> decode_cd(Scope, Item);
+ 16#09 -> decode_al(Scope, Item);
+ 16#0a -> decode_ct(Scope, Item);
+ 16#0b -> decode_nt(Scope, Item);
+ 16#0c -> decode_rtp(Scope, Item);
+ 16#0d -> decode_tdmc(Scope, Item);
+ 16#00 -> decode_native(Scope, Item)
+ end;
+ 16#fe ->
+ case B of
+ %% Proprietary extension
+ 16#fe -> decode_swb(Scope, Item)
+ end;
+ 16#ff ->
+ case B of
+ 16#ff when Item =:= [16#ff, 16#ff] -> "*"
+ end
+ end.
+
+decode_package(Package) ->
+ ?d("decode_package -> entry with"
+ "~n Package: ~p", [Package]),
+ [A, B] = Package,
+ case A of
+ 16#00 ->
+ case B of
+ 16#01 -> "g";
+ 16#02 -> "root";
+ 16#03 -> "tonegen";
+ 16#04 -> "tonedet";
+ 16#05 -> "dg";
+ 16#06 -> "dd";
+ 16#07 -> "cg";
+ 16#08 -> "cd";
+ 16#09 -> "al";
+ 16#0a -> "ct";
+ 16#0b -> "nt";
+ 16#0c -> "rtp";
+ 16#0d -> "tdmc";
+ 16#00 -> ""
+ end;
+ 16#fe ->
+ case B of
+ 16#fe -> "swb"
+ end;
+ 16#ff ->
+ case B of
+ 16#ff -> "*"
+ end
+ end.
+
+decode_profile([A, B]) ->
+ case A of
+ 16#00 ->
+ case B of
+ 16#fe -> "resgw";
+ _ -> "profile" ++ [A + $0, B + $0]
+ end;
+ _ ->
+ "profile" ++ [A + $0, B + $0]
+ end.
+
+decode_dialplan([A, B]) ->
+ "dialplan" ++ [A + $0, B + $0].
+
+decode_mid(Mid) ->
+ case Mid of
+ {domainName, DN} ->
+ Lower = to_lower(DN#'DomainName'.name),
+ {domainName, DN#'DomainName'{name = Lower}};
+ {deviceName, PathName} ->
+ Lower = to_lower(PathName),
+ {deviceName, Lower};
+ Other ->
+ Other
+ end.
+
+to_lower(Chars) ->
+ [?LOWER(Char) || Char <- Chars].
+
+%%----------------------------------------------------------------------
+%% Encode package name from internal form
+%% Scope ::= property | event | signal | statistics
+%%----------------------------------------------------------------------
+
+encode(mid, Package) ->
+ encode_mid(Package);
+encode(package, Package) ->
+ encode_package(Package);
+encode(profile, Profile) ->
+ encode_profile(Profile);
+encode(dialplan, Dialplan) ->
+ encode_dialplan(Dialplan);
+encode(Scope, PackageItem) when is_atom(Scope) ->
+ ?d("encode(~p) -> entry with"
+ "~n PackageItem: ~p", [Scope, PackageItem]),
+ case string:tokens(PackageItem, [$/]) of
+ [Package, Item] ->
+ ?d("encode -> "
+ "~n Package: ~p"
+ "~n Item: ~p", [Package, Item]),
+ encode_package(Package) ++ encode_item(Scope, Package, Item);
+ [Item] ->
+ ?d("encode -> Item: ~p", [Item]),
+ [16#00, 16#00 | encode_native(Scope, Item)]
+ end;
+encode({Scope, PackageItem}, SubItem) when is_atom(Scope) ->
+ ?d("encode(~p) -> entry with"
+ "~n PackageItem: ~p"
+ "~n SubItem: ~p", [Scope, PackageItem, SubItem]),
+ case string:tokens(PackageItem, [$/]) of
+ [Package, Item] ->
+ ?d("encode -> "
+ "~n Package: ~p"
+ "~n Item: ~p", [Package, Item]),
+ encode_item({Scope, Item}, Package, SubItem);
+ [_Item] ->
+ ?d("encode -> _Item: ~p", [_Item]),
+ encode_native(Scope, SubItem)
+ end.
+
+encode_item(_Scope, _Package, "*") ->
+ [16#ff, 16#ff];
+encode_item(Scope, Package, Item) ->
+ ?d("encode_item(~s) -> entry", [Package]),
+ case Package of
+ "g" -> encode_g(Scope, Item);
+ "root" -> encode_root(Scope, Item);
+ "tonegen" -> encode_tonegen(Scope, Item);
+ "tonedet" -> encode_tonedet(Scope, Item);
+ "dg" -> encode_dg(Scope, Item);
+ "dd" -> encode_dd(Scope, Item);
+ "cg" -> encode_cg(Scope, Item);
+ "cd" -> encode_cd(Scope, Item);
+ "al" -> encode_al(Scope, Item);
+ "ct" -> encode_ct(Scope, Item);
+ "nt" -> encode_nt(Scope, Item);
+ "rtp" -> encode_rtp(Scope, Item);
+ "tdmc" -> encode_tdmc(Scope, Item);
+ "swb" -> encode_swb(Scope, Item)
+ end.
+
+encode_package(Package) ->
+ case Package of
+ "g" -> [16#00, 16#01];
+ "root" -> [16#00, 16#02];
+ "tonegen" -> [16#00, 16#03];
+ "tonedet" -> [16#00, 16#04];
+ "dg" -> [16#00, 16#05];
+ "dd" -> [16#00, 16#06];
+ "cg" -> [16#00, 16#07];
+ "cd" -> [16#00, 16#08];
+ "al" -> [16#00, 16#09];
+ "ct" -> [16#00, 16#0a];
+ "nt" -> [16#00, 16#0b];
+ "rtp" -> [16#00, 16#0c];
+ "tdmc" -> [16#00, 16#0d];
+ "" -> [16#00, 16#00];
+ "*" -> [16#ff, 16#ff];
+ "swb" -> [16#fe, 16#fe]
+ end.
+
+encode_profile(Profile) ->
+ case Profile of
+ "resgw" ->
+ [16#00, 16#fe];
+ [$p, $r, $o, $f, $i, $l, $e | Name] ->
+ case Name of
+ [A, B] -> [A - $0, B - $0];
+ [B] -> [0, B - $0];
+ [] -> [0, 0]
+ end
+ end.
+
+encode_dialplan(Dialplan) ->
+ case Dialplan of
+ [$d, $i, $a, $l, $p, $l, $a, $n | Name] ->
+ case Name of
+ [A, B] -> [A - $0, B - $0];
+ [B] -> [0, B - $0];
+ [] -> [0, 0]
+ end
+ end.
+
+encode_mid(Mid) ->
+ Mid.
+
+
+%%----------------------------------------------------------------------
+%% Name: g - Generic
+%% Version: 1
+%% Extends: None
+%% Purpose: Generic package for commonly encountered items
+%%----------------------------------------------------------------------
+
+capabilities_g() ->
+ [
+ {event, "cause"},
+ {event, "sc"}
+ ].
+
+encode_g(event, Item) ->
+ case Item of
+ "cause" -> [16#00, 16#01];
+ "sc" -> [16#00, 16#02]
+ end;
+
+encode_g({event_parameter, Item}, SubItem) ->
+ case Item of
+ "cause" ->
+ case SubItem of
+ "Generalcause" -> [16#00, 16#01];
+ "Failurecause" -> [16#00, 16#02]
+ end;
+ "sc" ->
+ case SubItem of
+ "SigID" -> [16#00, 16#01];
+ "Meth" -> [16#00, 16#02];
+ "SLID" -> [16#00, 16#03];
+ "RID" -> [16#00, 16#04]
+ end
+ end.
+
+decode_g(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "cause";
+ [16#00, 16#02] -> "sc"
+ end;
+
+decode_g({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event: cause
+ case SubItem of
+ [16#00, 16#01] -> "Generalcause";
+ [16#00, 16#02] -> "Failurecause"
+ end;
+
+ [16#00, 16#02] -> % Event: sc
+ case SubItem of
+ [16#00, 16#01] -> "SigID";
+ [16#00, 16#02] -> "Meth";
+ [16#00, 16#03] -> "SLID";
+ [16#00, 16#04] -> "RID"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: root - Base Root Package
+%% Version: 2
+%% Extends: None
+%% Purpose: This package defines Gateway wide properties.
+%%----------------------------------------------------------------------
+
+capabilities_root() ->
+ [
+ {property, "maxNumberOfContexts"},
+ {property, "maxTerminationsPerContext"},
+ {property, "normalMGExecutionTime"},
+ {property, "normalMGCExecutionTime"},
+ {property, "MGProvisionalResponseTimerValue"},
+ {property, "MGCProvisionalResponseTimerValue"},
+ {property, "MGCOriginatedPendingLimit"},
+ {property, "MGOriginatedPendingLimit"}
+ ].
+
+encode_root(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ "maxNumberOfContexts" -> [16#00, 16#01];
+ "maxTerminationsPerContext" -> [16#00, 16#02];
+ "normalMGExecutionTime" -> [16#00, 16#03];
+ "normalMGCExecutionTime" -> [16#00, 16#04];
+ "MGProvisionalResponseTimerValue" -> [16#00, 16#05];
+ "MGCProvisionalResponseTimerValue" -> [16#00, 16#06];
+ "MGCOriginatedPendingLimit" -> [16#00, 16#07];
+ "MGOriginatedPendingLimit" -> [16#00, 16#08]
+ end
+ end.
+
+decode_root(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ [16#00, 16#01] -> "maxNumberOfContexts";
+ [16#00, 16#02] -> "maxTerminationsPerContext";
+ [16#00, 16#03] -> "normalMGExecutionTime";
+ [16#00, 16#04] -> "normalMGCExecutionTime";
+ [16#00, 16#05] -> "MGProvisionalResponseTimerValue";
+ [16#00, 16#06] -> "MGCProvisionalResponseTimerValue";
+ [16#00, 16#07] -> "MGCOriginatedPendingLimit";
+ [16#00, 16#08] -> "MGOriginatedPendingLimit"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tonegen - Tone Generator Package
+%% Version: 2
+%% Extends: None
+%% Purpose: This package defines signals to generate audio tones.
+%% This package does not specify parameter values. It is
+%% intended to be extendable. Generally, tones are defined
+%% as an individual signal with a parameter, ind,
+%% representing "interdigit" time delay, and a tone id to
+%% be used with playtones. A tone id should be kept
+%% consistent with any tone generation for the same tone.
+%% MGs are expected to be provisioned with the characteristics
+%% of appropriate tones for the country in which the MG is located.
+%%----------------------------------------------------------------------
+
+capabilities_tonegen() ->
+ [
+ {signal, "pt"}
+ ].
+
+encode_tonegen(signal, Item) ->
+ case Item of
+ "pt" -> [16#00, 16#01]
+ end;
+
+encode_tonegen({signal_parameter, Item}, SubItem) ->
+ case Item of
+ "pt" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "ind" -> [16#00, 16#02];
+ "btd" -> [16#00, 16#03]
+ end
+ end.
+
+decode_tonegen(signal, Item) ->
+ case Item of
+ [16#00, 16#01] -> "pt"
+ end;
+
+decode_tonegen({signal_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event: pt
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#02] -> "ind";
+ [16#00, 16#03] -> "btd"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tonedet - Tone Detection Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This Package defines events for audio tone detection.
+%% Tones are selected by name (tone id). MGs are expected
+%% to be provisioned with the characteristics of appropriate
+%% tones for the country in which the MG is located.
+%%
+%% This package does not specify parameter values.
+%% It is intended to be extendable.
+%%----------------------------------------------------------------------
+
+capabilities_tonedet() ->
+ [
+ {event, "std"},
+ {event, "etd"},
+ {event, "ltd"}
+ ].
+
+encode_tonedet(event, Item) ->
+ case Item of
+ "std" -> [16#00, 16#01];
+ "etd" -> [16#00, 16#02];
+ "ltd" -> [16#00, 16#03]
+ end;
+
+encode_tonedet({event_parameter, Item}, SubItem) ->
+ case Item of
+ "std" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "tid" -> [16#00, 16#03]
+ end;
+ "etd" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "tid" -> [16#00, 16#03];
+ "dur" -> [16#00, 16#02]
+ end;
+ "ltd" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "dur" -> [16#00, 16#02];
+ "tid" -> [16#00, 16#03]
+ end
+ end.
+
+decode_tonedet(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "std";
+ [16#00, 16#02] -> "etd";
+ [16#00, 16#03] -> "ltd"
+ end;
+
+decode_tonedet({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event std
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#03] -> "tid"
+ end;
+ [16#00, 16#02] -> % Event etd
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#03] -> "tid";
+ [16#00, 16#02] -> "dur"
+ end;
+ [16#00, 16#03] -> % Event ltd
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#02] -> "dur";
+ [16#00, 16#03] -> "tid"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: dg - Basic DTMF Generator Package
+%% Version: 1
+%% Extends: tonegen version 1
+%% Purpose: This package defines the basic DTMF tones as signals and
+%% extends the allowed values of parameter tl of playtone
+%% in tonegen.
+%%----------------------------------------------------------------------
+
+capabilities_dg() ->
+ [
+ {signal, "d0"},
+ {signal, "d1"},
+ {signal, "d2"},
+ {signal, "d3"},
+ {signal, "d4"},
+ {signal, "d5"},
+ {signal, "d6"},
+ {signal, "d7"},
+ {signal, "d8"},
+ {signal, "d9"},
+ {signal, "ds"},
+ {signal, "do"},
+ {signal, "da"},
+ {signal, "db"},
+ {signal, "dc"},
+ {signal, "dd"}
+ ].
+
+encode_dg(signal, Item) ->
+ case Item of
+ "d0" -> [16#00, 16#10];
+ "d1" -> [16#00, 16#11];
+ "d2" -> [16#00, 16#12];
+ "d3" -> [16#00, 16#13];
+ "d4" -> [16#00, 16#14];
+ "d5" -> [16#00, 16#15];
+ "d6" -> [16#00, 16#16];
+ "d7" -> [16#00, 16#17];
+ "d8" -> [16#00, 16#18];
+ "d9" -> [16#00, 16#19];
+ "ds" -> [16#00, 16#20];
+ "do" -> [16#00, 16#21];
+ "da" -> [16#00, 16#1a];
+ "db" -> [16#00, 16#1b];
+ "dc" -> [16#00, 16#1c];
+ "dd" -> [16#00, 16#1d]
+ end;
+
+encode_dg({signal_parameter, Item}, SubItem) ->
+ case Item of
+ "d0" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d1" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d2" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d3" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d4" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d5" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d6" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d7" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d8" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d9" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "ds" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "do" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "da" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "db" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dc" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dd" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end
+ end.
+
+decode_dg(signal, Item) ->
+ case Item of
+ [16#00, 16#10] -> "d0";
+ [16#00, 16#11] -> "d1";
+ [16#00, 16#12] -> "d2";
+ [16#00, 16#13] -> "d3";
+ [16#00, 16#14] -> "d4";
+ [16#00, 16#15] -> "d5";
+ [16#00, 16#16] -> "d6";
+ [16#00, 16#17] -> "d7";
+ [16#00, 16#18] -> "d8";
+ [16#00, 16#19] -> "d9";
+ [16#00, 16#20] -> "ds";
+ [16#00, 16#21] -> "do";
+ [16#00, 16#1a] -> "da";
+ [16#00, 16#1b] -> "db";
+ [16#00, 16#1c] -> "dc";
+ [16#00, 16#1d] -> "dd"
+ end;
+
+decode_dg({signal_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#10] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#11] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#12] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#13] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#14] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#15] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#16] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#17] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#18] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#19] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#20] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#21] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1a] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1b] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1c] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1d] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: dd - DTMF detection Package
+%% Version: 1
+%% Extends: tonedet version 1
+%% Purpose: This package defines the basic DTMF tones detection.
+%% Tones are selected by name (tone id). MGs are expected
+%% to be provisioned with the characteristics of appropriate
+%% tones for the country in which the MG is located.
+%%
+%% This package does not specify parameter values.
+%% It is intended to be extendable.
+%%
+%% Additional tone id values are all tone ids described in package dg
+%% (basic DTMF generator package).
+%%
+%% The following table maps DTMF events to digit map symbols as described
+%% in section 7.1.14.
+%%
+%% _________________________________
+%% | DTMF Event | Symbol |
+%% | d0 | "0" |
+%% | d1 | "1" |
+%% | d2 | "2" |
+%% | d3 | "3" |
+%% | d4 | "4" |
+%% | d5 | "5" |
+%% | d6 | "6" |
+%% | d7 | "7" |
+%% | d8 | "8" |
+%% | d9 | "9" |
+%% | da | "A" or "a"|
+%% | db | "B" or "b"|
+%% | dc | "C" or "c"|
+%% | dd | "D" or "d"|
+%% | ds | "E" or "e"|
+%% | do | "F" or "f"|
+%% |___________________|____________|
+%%
+%%----------------------------------------------------------------------
+
+capabilities_dd() ->
+ [
+ {event, "ce"},
+ {event, "d0"},
+ {event, "d1"},
+ {event, "d2"},
+ {event, "d3"},
+ {event, "d4"},
+ {event, "d5"},
+ {event, "d6"},
+ {event, "d7"},
+ {event, "d8"},
+ {event, "d9"},
+ {event, "ds"},
+ {event, "do"},
+ {event, "da"},
+ {event, "db"},
+ {event, "dc"},
+ {event, "dd"}
+ ].
+
+encode_dd(event, Item) ->
+ case Item of
+ "ce" -> [16#00, 16#04];
+ "d0" -> [16#00, 16#10];
+ "d1" -> [16#00, 16#11];
+ "d2" -> [16#00, 16#12];
+ "d3" -> [16#00, 16#13];
+ "d4" -> [16#00, 16#14];
+ "d5" -> [16#00, 16#15];
+ "d6" -> [16#00, 16#16];
+ "d7" -> [16#00, 16#17];
+ "d8" -> [16#00, 16#18];
+ "d9" -> [16#00, 16#19];
+ "ds" -> [16#00, 16#20];
+ "do" -> [16#00, 16#21];
+ "da" -> [16#00, 16#1a];
+ "db" -> [16#00, 16#1b];
+ "dc" -> [16#00, 16#1c];
+ "dd" -> [16#00, 16#1d]
+ end;
+
+encode_dd({event_parameter, Item}, SubItem) ->
+ case Item of
+ "ce" ->
+ case SubItem of
+ "ds" -> [16#00, 16#01];
+ "Meth" -> [16#00, 16#03]
+ end;
+ "d0" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d1" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d2" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d3" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d4" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d5" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d6" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d7" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d8" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d9" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "ds" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "do" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "da" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "db" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dc" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dd" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end
+ end.
+
+decode_dd(event, Item) ->
+ case Item of
+ [16#00, 16#04] -> "ce";
+ [16#00, 16#10] -> "d0";
+ [16#00, 16#11] -> "d1";
+ [16#00, 16#12] -> "d2";
+ [16#00, 16#13] -> "d3";
+ [16#00, 16#14] -> "d4";
+ [16#00, 16#15] -> "d5";
+ [16#00, 16#16] -> "d6";
+ [16#00, 16#17] -> "d7";
+ [16#00, 16#18] -> "d8";
+ [16#00, 16#19] -> "d9";
+ [16#00, 16#20] -> "ds";
+ [16#00, 16#21] -> "do";
+ [16#00, 16#1a] -> "da";
+ [16#00, 16#1b] -> "db";
+ [16#00, 16#1c] -> "dc";
+ [16#00, 16#1d] -> "dd"
+ end;
+
+decode_dd({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#04] -> % Event ce
+ case SubItem of
+ [16#00, 16#01] -> "ds";
+ [16#00, 16#03] -> "Meth"
+ end;
+ [16#00, 16#10] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#11] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#12] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#13] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#14] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#15] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#16] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#17] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#18] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#19] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#20] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#21] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1a] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1b] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1c] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1d] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: cg - Call Progress Tones Generator Package
+%% Version: 1
+%% Extends: tonegen version 1
+%% Purpose: This package defines the basic call progress tones as signals
+%% and extends the allowed values of the tl parameter of
+%% playtone in tonegen.
+%%----------------------------------------------------------------------
+
+capabilities_cg() ->
+ [
+ {signal, "dt"},
+ {signal, "rt"},
+ {signal, "bt"},
+ {signal, "ct"},
+ {signal, "sit"},
+ {signal, "wt"},
+ {signal, "prt"},
+ {signal, "cw"},
+ {signal, "cr"}
+ ].
+
+
+encode_cg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ "dt" -> [16#00, 16#30];
+ "rt" -> [16#00, 16#31];
+ "bt" -> [16#00, 16#32];
+ "ct" -> [16#00, 16#33];
+ "sit" -> [16#00, 16#34];
+ "wt" -> [16#00, 16#35];
+ "prt" -> [16#00, 16#36];
+ "cw" -> [16#00, 16#37];
+ "cr" -> [16#00, 16#38]
+ end
+ end.
+
+decode_cg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ [16#00, 16#30] -> "dt";
+ [16#00, 16#31] -> "rt";
+ [16#00, 16#32] -> "bt";
+ [16#00, 16#33] -> "ct";
+ [16#00, 16#34] -> "sit";
+ [16#00, 16#35] -> "wt";
+ [16#00, 16#36] -> "prt";
+ [16#00, 16#37] -> "cw";
+ [16#00, 16#38] -> "cr"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: cd - Call Progress Tones Detection Package
+%% Version: 1
+%% Extends: tonedet version 1
+%% Purpose: This package defines the basic call progress detection tones.
+%% This Package extends the possible values of tone id
+%% in the "start tone detected", "end tone detected" and
+%% "long tone detected" events.
+%% Additional values
+%% tone id values are defined for start tone detected,
+%% end tone detected and long tone detected with
+%% the same values as those in package cg (call
+%% progress tones generation package).
+%%
+%% The required set of tone ids corresponds to Recommendation E.180/Q.35
+%% [ITU-T Recommendation E.180/Q.35 (1998)]. See Recommendation E.180/Q.35
+%% for definition of the meanings of these tones.
+%%----------------------------------------------------------------------
+
+capabilities_cd() ->
+ [
+ {event, "dt"},
+ {event, "rt"},
+ {event, "bt"},
+ {event, "ct"},
+ {event, "sit"},
+ {event, "wt"},
+ {event, "prt"},
+ {event, "cw"},
+ {event, "cr"}
+ ].
+
+
+encode_cd(Scope, Item) ->
+ case Scope of
+ event ->
+ case Item of
+ "dt" -> [16#00, 16#30];
+ "rt" -> [16#00, 16#31];
+ "bt" -> [16#00, 16#32];
+ "ct" -> [16#00, 16#33];
+ "sit"-> [16#00, 16#34];
+ "wt" -> [16#00, 16#35];
+ "prt"-> [16#00, 16#36];
+ "cw" -> [16#00, 16#37];
+ "cr" -> [16#00, 16#38]
+ end
+ end.
+
+decode_cd(Scope, Item) ->
+ case Scope of
+ event ->
+ case Item of
+ [16#00, 16#30] -> "dt";
+ [16#00, 16#31] -> "rt";
+ [16#00, 16#32] -> "bt";
+ [16#00, 16#33] -> "ct";
+ [16#00, 16#34] -> "sit";
+ [16#00, 16#35] -> "wt";
+ [16#00, 16#36] -> "prt";
+ [16#00, 16#37] -> "cw";
+ [16#00, 16#38] -> "cr"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: al - Analog Line Supervision Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines events and signals for an analog line.
+%%----------------------------------------------------------------------
+
+capabilities_al() ->
+ [
+ {event, "on"},
+ {event, "of"},
+ {event, "fl"},
+ {signal, "ri"}
+ ].
+
+encode_al(event, Item) ->
+ ?d("encode_al(event) -> entry with"
+ "~n Item: ~p", [Item]),
+ case Item of
+ "on" -> [16#00, 16#04];
+ "of" -> [16#00, 16#05];
+ "fl" -> [16#00, 16#06]
+ end;
+
+encode_al({event_parameter, Item}, SubItem) ->
+ ?d("encode_al({event_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ "on" ->
+ case SubItem of
+ "strict" -> [16#00, 16#01];
+ "init" -> [16#00, 16#02]
+ end;
+ "of" ->
+ case SubItem of
+ "strict" -> [16#00, 16#01];
+ "init" -> [16#00, 16#02]
+ end;
+ "fl" ->
+ case SubItem of
+ "mindur" -> [16#00, 16#04];
+ "maxdur" -> [16#00, 16#05]
+ end
+ end;
+
+encode_al(signal, Item) ->
+ ?d("encode_al(signal) -> entry with"
+ "~n Item: ~p", [Item]),
+ case Item of
+ "ri" -> [16#00, 16#02]
+ end;
+
+encode_al({signal_parameter, Item}, SubItem) ->
+ ?d("encode_al({signal_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ "ri" ->
+ case SubItem of
+ "cad" -> [16#00, 16#06];
+ "freq" -> [16#00, 16#07]
+ end
+ end.
+
+decode_al(event, SubItem) ->
+ ?d("decode_al(event) -> entry with"
+ "~n SubItem: ~p", [SubItem]),
+ case SubItem of
+ [16#00, 16#04] -> "on";
+ [16#00, 16#05] -> "of";
+ [16#00, 16#06] -> "fl"
+ end;
+
+decode_al({event_parameter, Item}, SubItem) ->
+ ?d("decode_al({event_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ [16#00,16#04] -> %% Event: on
+ case SubItem of
+ [16#00, 16#01] -> "strict";
+ [16#00, 16#02] -> "init"
+ end;
+ [16#00,16#05] -> %% Event: of
+ case SubItem of
+ [16#00, 16#01] -> "strict";
+ [16#00, 16#02] -> "init"
+ end;
+ [16#00,16#06] -> %% Event: fl
+ case SubItem of
+ [16#00, 16#04] -> "mindur";
+ [16#00, 16#05] -> "maxdur"
+ end
+ end;
+
+decode_al(signal, SubItem) ->
+ ?d("decode_al(signal) -> entry with"
+ "~n SubItem: ~p", [SubItem]),
+ case SubItem of
+ [16#00, 16#02] -> "ri"
+ end;
+
+decode_al({signal_parameter, Item}, SubItem) ->
+ ?d("decode_al({signal_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ [16#00,16#02] -> %% Event: ri
+ case SubItem of
+ [16#00, 16#06] -> "cad";
+ [16#00, 16#07] -> "freq"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: ct - Basic Continuity Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines events and signals for continuity test.
+%% The continuity test includes provision of either a loopback
+%% or transceiver functionality.
+%%----------------------------------------------------------------------
+
+capabilities_ct() ->
+ [
+ {event, "cmp"},
+ {signal, "ct"},
+ {signal, "rsp"}
+ ].
+
+encode_ct(event, Item) ->
+ case Item of
+ "cmp" -> [16#00, 16#05]
+ end;
+encode_ct({event_parameter, Item}, SubItem) ->
+ case Item of
+ "cmp" ->
+ case SubItem of
+ "res" -> [16#00, 16#08]
+ end
+ end;
+encode_ct(signal, Item) ->
+ case Item of
+ "ct" -> [16#00, 16#03];
+ "rsp" -> [16#00, 16#04]
+ end.
+
+decode_ct(event, Item) ->
+ case Item of
+ [16#00, 16#05] -> "cmp"
+ end;
+decode_ct({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#05] -> % Event cmp
+ case SubItem of
+ [16#00, 16#08] -> "res"
+ end
+ end;
+decode_ct(signal, Item) ->
+ case Item of
+ [16#00, 16#03] -> "ct";
+ [16#00, 16#04] -> "rsp"
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: nt - Network Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines properties of network terminations
+%% independent of network type.
+%%----------------------------------------------------------------------
+
+capabilities_nt() ->
+ [
+ {property, "jit"},
+ {event, "netfail"},
+ {event, "qualert"},
+ {statistics, "dur"},
+ {statistics, "os"},
+ {statistics, "or"}
+ ].
+
+encode_nt(property, Item) ->
+ case Item of
+ "jit" -> [16#00, 16#07]
+ end;
+encode_nt(event, Item) ->
+ case Item of
+ "netfail" -> [16#00, 16#05];
+ "qualert" -> [16#00, 16#06]
+ end;
+encode_nt({event_parameter, Item}, SubItem) ->
+ case Item of
+ "netfail" ->
+ case SubItem of
+ "cs" -> [16#00, 16#01]
+ end;
+ "qualert" ->
+ case SubItem of
+ "th" -> [16#00, 16#01]
+ end
+ end;
+encode_nt(statistics, Item) ->
+ case Item of
+ "dur" -> [16#00, 16#01];
+ "os" -> [16#00, 16#02];
+ "or" -> [16#00, 16#03]
+ end.
+
+decode_nt(property, Item) ->
+ case Item of
+ [16#00, 16#07] -> "jit"
+ end;
+decode_nt(event, Item) ->
+ case Item of
+ [16#00, 16#05] -> "netfail";
+ [16#00, 16#06] -> "qualert"
+ end;
+decode_nt({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#05] -> % Event netfail
+ case SubItem of
+ [16#00, 16#01] -> "cs"
+ end;
+ [16#00, 16#06] -> % Event qualert
+ case Item of
+ [16#00, 16#01] -> "th"
+ end
+ end;
+decode_nt(statistics, Item) ->
+ case Item of
+ [16#00, 16#01] -> "dur";
+ [16#00, 16#02] -> "os";
+ [16#00, 16#03] -> "or"
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: rtp - RTP Package
+%% Version: 1
+%% Extends: nt version 1
+%% Purpose: This package is used to support packet based multimedia
+%% data transfer by means of the Real-time Transport Protocol
+%% (RTP) [RFC 1889].
+%%----------------------------------------------------------------------
+
+capabilities_rtp() ->
+ [
+ {event, "pltrans"},
+ {statistics, "ps"},
+ {statistics, "pr"},
+ {statistics, "pl"},
+ {statistics, "jit"},
+ {statistics, "delay"}
+ ].
+
+encode_rtp(event, Item) ->
+ case Item of
+ "pltrans" -> [16#00, 16#01]
+ end;
+encode_rtp({event_parameter, Item}, SubItem) ->
+ case Item of
+ "pltrans" ->
+ case SubItem of
+ "rtppltype" -> [16#00, 16#01]
+ end
+ end;
+encode_rtp(statistics, Item) ->
+ case Item of
+ "ps" -> [16#00, 16#04];
+ "pr" -> [16#00, 16#05];
+ "pl" -> [16#00, 16#06];
+ "jit" -> [16#00, 16#07];
+ "delay" -> [16#00, 16#08]
+ end.
+
+decode_rtp(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "pltrans"
+ end;
+decode_rtp({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event pltrans
+ case SubItem of
+ [16#00, 16#01] -> "rtppltype"
+ end
+ end;
+decode_rtp(statistics, Item) ->
+ case Item of
+ [16#00, 16#04] -> "ps";
+ [16#00, 16#05] -> "pr";
+ [16#00, 16#06] -> "pl";
+ [16#00, 16#07] -> "jit";
+ [16#00, 16#08] -> "delay"
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tdmc - TDM Circuit Package
+%% Version: 1
+%% Extends: nt version 1
+%% Purpose: This package is used to support TDM circuit terminations.
+%%----------------------------------------------------------------------
+
+capabilities_tdmc() ->
+ [
+ {property, "ec"},
+ {property, "gain"}
+ ].
+
+encode_tdmc(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ "ec" -> [16#00, 16#08];
+ "gain" -> [16#00, 16#0a]
+ end
+ end.
+
+decode_tdmc(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ [16#00, 16#08] -> "ec";
+ [16#00, 16#0a] -> "gain"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: swb - SwitchBoard Package
+%% Version: 1
+%% Extends: none
+%% Purpose: This package is used to support SwitchBoard specials
+%%----------------------------------------------------------------------
+
+capabilities_swb() ->
+ [
+ {statistics, "fs"}, % Free slots
+ {statistics, "as"} % Allocated slots
+ ].
+
+encode_swb(Scope, Item) ->
+ case Scope of
+ statistics ->
+ case Item of
+ "fs" -> [16#00, 16#00];
+ "as" -> [16#00, 16#01]
+ end
+ end.
+
+decode_swb(Scope, Item) ->
+ case Scope of
+ statistics ->
+ case Item of
+ [16#00, 16#00] -> "fs";
+ [16#00, 16#01] -> "as"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: native - Pseudo package
+%% Version: 1
+%% Extends: None
+%% Purpose: Native tags for media stream properties
+%%
+%% Parameters for Local descriptors and Remote descriptors are
+%% specified as tag-value pairs if binary encoding is used for the
+%% protocol. This annex contains the property names (PropertyID), the
+%% tags (Property Tag), type of the property (Type) and the values
+%% (Value).Values presented in the Value field when the field contains
+%% references shall be regarded as "information". The reference
+%% contains the normative values. If a value field does not contain a
+%% reference then the values in that field can be considered as
+%% "normative".
+%%
+%% Tags are given as hexadecimal numbers in this annex. When setting
+%% the value of a property, a MGC may underspecify the value according
+%% to one of the mechanisms specified in section 7.1.1.
+%%
+%% For type "enumeration" the value is represented by the value in brack-
+%% ets, e.g., Send(0), Receive(1).
+%%----------------------------------------------------------------------
+%%
+%% C.6. IP
+%%
+%% ________________________________________________________________
+%% | PropertyID| Tag | Type | Value |
+%% | IPv4 | 6001 | 32 BITS | Ipv4Address |
+%% | IPv6 | 6002 | 128 BITS | IPv6 Address |
+%% | Port | 6003 | Unsigned Int| Port |
+%% | Porttype | 6004 | Enumerated | TCP(0),UDP(1),SCTP(2)|
+%% |___________|____________|______________|_______________________|
+%%
+%%
+%% C.11. SDP Equivalents
+%%
+%% ______________________________________________________________
+%% | PropertyID| Tag | Type | Value |
+%% | SDP_V | B001| STRING| Protocol Version |
+%% | SDP_O | B002| STRING| Owner-creator and session ID |
+%% | SDP_S | B003| STRING| Sesson name |
+%% | SDP_I | B004| STRING| Session identifier |
+%% | SDP_U | B005| STRING| URI of descriptor |
+%% | SDC_E | B006| STRING| email address |
+%% | SDP_P | B007| STRING| phone number |
+%% | SDP_C | B008| STRING| Connection information |
+%% | SDP_B | B009| STRING| Bandwidth Information |
+%% | SDP_Z | B00A| STRING| time zone adjustment |
+%% | SDP_K | B00B| STRING| Encryption Key |
+%% | SDP_A | B00C| STRING| Zero or more session attributes|
+%% | SDP_T | B00D| STRING| Active Session Time |
+%% | SDP_R | B00E| STRING| Zero or more repeat times |
+%% | SDP_M | B00F| STRING| Media name and transport addr |
+%% | | | | Reference: IETF RFC 2327 |
+%% |___________|______|________|_________________________________|
+%%
+%%----------------------------------------------------------------------
+
+capabilities_native() ->
+ [
+ %% C.6. IP
+ {property, "IPv4"},
+ {property, "IPv6"},
+ {property, "Port"},
+ {property, "Porttype"},
+
+ %% C.11. SDP Equivalents
+ {property, "v"},
+ {property, "o"},
+ {property, "s"},
+ {property, "i"},
+ {property, "u"},
+ {property, "e"},
+ {property, "p"},
+ {property, "c"},
+ {property, "b"},
+ {property, "z"},
+ {property, "k"},
+ {property, "a"},
+ {property, "t"},
+ {property, "r"},
+ {property, "m"}
+ ].
+
+encode_native(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ %% IP
+ "IPv4" -> [16#60, 16#01];
+ "IPv6" -> [16#60, 16#02];
+ "Port" -> [16#60, 16#03];
+ "Porttype" -> [16#60, 16#04];
+
+ %% SDP
+ "v" -> [16#b0, 16#01];
+ "o" -> [16#b0, 16#02];
+ "s" -> [16#b0, 16#03];
+ "i" -> [16#b0, 16#04];
+ "u" -> [16#b0, 16#05];
+ "e" -> [16#b0, 16#06];
+ "p" -> [16#b0, 16#07];
+ "c" -> [16#b0, 16#08];
+ "b" -> [16#b0, 16#09];
+ "z" -> [16#b0, 16#0a];
+ "k" -> [16#b0, 16#0b];
+ "a" -> [16#b0, 16#0c];
+ "t" -> [16#b0, 16#0d];
+ "r" -> [16#b0, 16#0e];
+ "m" -> [16#b0, 16#0f]
+ end
+ end.
+
+decode_native(Scope, [Type, Item]) ->
+ case Scope of
+ property ->
+ case Type of
+ 16#60 ->
+ case Item of
+ 16#01 -> "IPv4";
+ 16#02 -> "IPv6";
+ 16#03 -> "Port";
+ 16#04 -> "Porttype"
+ end;
+
+ 16#b0 ->
+ case Item of
+ 16#01 -> "v";
+ 16#02 -> "o";
+ 16#03 -> "s";
+ 16#04 -> "i";
+ 16#05 -> "u";
+ 16#06 -> "e";
+ 16#07 -> "p";
+ 16#08 -> "c";
+ 16#09 -> "b";
+ 16#0a -> "z";
+ 16#0b -> "k";
+ 16#0c -> "a";
+ 16#0d -> "t";
+ 16#0e -> "r";
+ 16#0f -> "m"
+ end
+ end
+ end.
+
+%% -------------------------------------------------------------------
+
+% error(Reason) ->
+% erlang:error(Reason).
+
diff --git a/lib/megaco/src/binary/megaco_binary_name_resolver_prev3c.erl b/lib/megaco/src/binary/megaco_binary_name_resolver_prev3c.erl
new file mode 100644
index 0000000000..d08231caac
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_name_resolver_prev3c.erl
@@ -0,0 +1,2004 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Handle meta data about packages
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_name_resolver_prev3c).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+-include_lib("megaco/src/app/megaco_internal.hrl").
+
+
+-define(LOWER(Char),
+ if
+ Char >= $A, Char =< $Z ->
+ Char - ($A - $a);
+ true ->
+ Char
+ end).
+
+-export([packages/0,
+ capabilities/0,
+ capabilities/1,
+ decode_name/3,
+ encode_name/3
+ ]).
+
+encode_name(Config, term_id, TermId) ->
+ case megaco:encode_binary_term_id(Config, TermId) of
+ {ok, TermId2} ->
+ TermId2;
+ {error, Reason} ->
+ exit({bad_term_id, TermId, Reason})
+ end;
+encode_name(_Config, Scope, Item) ->
+ ?d("encode_name(~p) -> entry with"
+ "~n Item: ~p", [Scope, Item]),
+ encode(Scope, Item).
+
+decode_name(Config, term_id, TermId) ->
+ case megaco:decode_binary_term_id(Config, TermId) of
+ {ok, TermId2} ->
+ TermId2;
+ {error, Reason} ->
+ exit({bad_term_id, TermId, Reason})
+ end;
+decode_name(_Config, Scope, Item) ->
+ ?d("decode_name(~p) -> entry with"
+ "~n Item: ~p", [Scope, Item]),
+ decode(Scope, Item).
+
+
+
+%%----------------------------------------------------------------------
+%% 12.1.1 Package
+%%
+%% Overall description of the package, specifying:
+%%
+%% Package Name: only descriptive
+%%
+%% PackageID: is an identifier
+%%
+%% Description: is a description of the package
+%%
+%% Version:
+%%
+%% A new version of a package can only add additional Properties,
+%% Events, Signals, Statistics and new possible values for an
+%% existing parameter described in the original package. No
+%% deletions or modifications shall be allowed. A version is an
+%% integer in the range from 1 to 99.
+%%
+%% Designed to be extended only (Optional): Yes
+%%
+%% This indicates that the package has been expressly designed to
+%% be extended by others, not to be directly referenced. For
+%% example, the package may not have any function on its own or be
+%% nonsensical on its own. The MG SHOULD NOT publish this PackageID
+%% when reporting packages.
+%%
+%% Extends: existing package Descriptor
+%%
+%% A package may extend an existing package. The version of the
+%% original package must be specified. When a package extends
+%% another package it shall only add additional Properties, Events,
+%% Signals, Statistics and new possible values for an existing
+%% parameter described in the original package. An extended package
+%% shall not redefine or overload an identifier defined in the
+%% original package and packages it may have extended (multiple
+%% levels of extension). Hence, if package B version 1 extends
+%% package A version 1, version 2 of B will not be able to extend
+%% the A version 2 if A version 2 defines a name already in B
+%% version 1. If the package does not extend another package, it
+%% shall specify "none".
+%%
+%%
+%% 12.1.2 Properties
+%%
+%% Properties defined by the package, specifying:
+%%
+%% Property Name: only descriptive
+%%
+%% PropertyID: is an identifier
+%%
+%% Description: is a description of the function of the property
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 string
+%%
+%% Octet String: A number of octets. See Annex A and B.3 for
+%% encoding
+%%
+%% Integer: 4 byte signed integer
+%%
+%% Double: 8 byte signed integer
+%%
+%% Character: unicode UTF-8 encoding of a single letter.
+%% Could be more than one octet.
+%%
+%% Enumeration: one of a list of possible unique values (see 12.3)
+%%
+%% Sub-list: a list of several values from a list.
+%% The type of sub-list SHALL also be specified.
+%% The type shall be chosen from the types specified in
+%% this section (with the exception of sub-list). For
+%% example, Type: sub-list of enumeration. The encoding
+%% of sub-lists is specified in Annexes A and B.3.
+%%
+%% Possible values:
+%%
+%% A package MUST specify either a specific set of values or a
+%% description of how values are determined. A package MUST also
+%% specify a default value or the default behaviour when the value
+%% is omitted from its descriptor. For example, a package may
+%% specify that procedures related to the property are suspended
+%% when its value is omitted.
+%%
+%% Default:
+%%
+%% A default value (but not procedures) may be specified as
+%% provisionable.
+%%
+%% Defined in:
+%%
+%% Which H.248.1 descriptor the property is defined in.
+%% LocalControl is for stream-dependent properties.
+%% TerminationState is for stream-independent properties.
+%% ContextAttribute is for properties that affect the context as
+%% a whole, i.e., mixing properties. These are expected to be the
+%% most common cases, but it is possible for properties to be
+%% defined in other descriptors. Context properties MUST be defined
+%% in the ContextAttribute descriptor.
+%%
+%% Characteristics: Read/Write or both, and (optionally), global:
+%%
+%% Indicates whether a property is read-only, or read-write, and
+%% if it is global. If Global is omitted, the property is not
+%% global. If a property is declared as global, the value of the
+%% property is shared by all Terminations realizing the package.
+%% If a context property is declared as global, the property is
+%% shared by all contexts realizing the package.
+%%
+%%
+%% 12.1.3 Events
+%%
+%% Events defined by the package, specifying:
+%%
+%% Event name: only descriptive
+%%
+%% EventID: is an identifier
+%%
+%% Description: a description of the function of the event
+%%
+%% EventsDescriptor Parameters:
+%%
+%% Parameters used by the MGC to configure the event, and found in
+%% the EventsDescriptor. See 12.2. If there are no parameters for
+%% the Events Descriptor, then "none" shall be specified.
+%%
+%% ObservedEventsDescriptor Parameters:
+%%
+%% Parameters returned to the MGC in Notify requests and in replies
+%% to command requests from the MGC that audit
+%% ObservedEventsDescriptor, and found in the
+%% ObservedEventsDescriptor. See 12.2. If there are no parameters
+%% for the ObservedEvents Descriptor, then �none� shall be specified.
+%%
+%%
+%% 12.1.4 Signals
+%%
+%% Signals defined by the package, specifying:
+%%
+%% Signal Name: only descriptive
+%%
+%% SignalID: is an identifier. SignalID is used in a SignalsDescriptor
+%%
+%% Description: a description of the function of the signal
+%%
+%% SignalType: one of:
+%%
+%% OO (On/Off)
+%%
+%% TO (TimeOut)
+%%
+%% BR (Brief)
+%%
+%% NOTE -�SignalType may be defined such that it is dependent on
+%% the value of one or more parameters. The package MUST specify a
+%% default signal type. If the default type is TO, the package MUST
+%% specify a default duration which may be provisioned. A default
+%% duration is meaningless for BR.
+%%
+%% Duration: in hundredths of seconds
+%%
+%% Additional Parameters: see 12.2
+%%
+%%
+%% 12.1.5 Statistics
+%%
+%% Statistics defined by the package, specifying:
+%%
+%% Statistic name: only descriptive
+%%
+%% StatisticID: is an identifier
+%%
+%% StatisticID is used in a StatisticsDescriptor
+%%
+%% Description: a description of the statistic
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 string
+%%
+%% Octet String: A number of octets.
+%% See Annex A and Annex B.3 for encoding
+%%
+%% Integer: 4 byte signed integer
+%%
+%% Double: 8 byte signed integer
+%%
+%% Character: Unicode UTF-8 encoding of a single letter.
+%% Could be more than one octet.
+%%
+%% Enumeration: One of a list of possible unique values (See 12.3)
+%%
+%% Sub-list: A list of several values from a list.
+%% The type of sub-list SHALL also be specified.
+%% The type shall be chosen from the types specified in
+%% this section (with the exception of sub-list).
+%% For example, Type: sub-list of enumeration.
+%% The encoding of sub-lists is specified in Annexes A
+%% and B.3.
+%%
+%% Possible Values:
+%%
+%% A package must indicate the unit of measure, e.g. milliseconds,
+%% packets, either here or along with the type above, as well as
+%% indicating any restriction on the range.
+%%
+%% Level: Specify if the statistic can be kept at the Termination
+%% level, Stream level or Either.
+%%
+%%
+%% 12.1.6 Error Codes
+%%
+%% If the package does not define any error codes, this section may be omitted.
+%% Otherwise, it describes error codes defined by the package, specifying:
+%%
+%% Error Code #: The error code number.
+%%
+%% Name: Name of the error
+%%
+%% Definition: A description of the error code.
+%%
+%% Error Text in the Error Descriptor:
+%%
+%% A description of what text to return in the Error Descriptor.
+%%
+%% Comment: Any further comments on the use of the error code.
+%%
+%%
+%% 12.1.7 Procedures
+%%
+%% Additional guidance on the use of the package.
+%%
+%%
+%% 12.2 Guidelines to defining parameters to events and signals
+%%
+%% Parameter Name: only descriptive
+%%
+%% ParameterID: is an identifier. The textual ParameterID of
+%% parameters to Events and Signals shall not start with "EPA" and
+%% "SPA", respectively. The textual ParameterID shall also not be
+%% "ST", "Stream", "SY", "SignalType", "DR", "Duration", "NC",
+%% "NotifyCompletion", "KA", "KeepActive", "EB", "Embed", "DM",
+%% "DigitMap", "DI", "Direction", "RQ" or "RequestID".
+%%
+%% Description: a description of the function of the parameter.
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 octet string
+%%
+%% Octet String: A number of octets. See Annex A and B.3 for
+%% encoding
+%%
+%% Integer: 4-octet signed integer
+%%
+%% Double: 8-octet signed integer
+%%
+%% Character: Unicode UTF-8 encoding of a single letter. Could be
+%% more than one octet.
+%%
+%% Enumeration: one of a list of possible unique values (see 12.3)
+%%
+%% Sub-list: a list of several values from a list (not supported
+%% for statistics). The type of sub-list SHALL also be
+%% specified The type shall be chosen from the types
+%% specified in this section (with the exception of
+%% sub-list). For example, Type: sub-list of enumeration.
+%% The encoding of sub-lists is specified in Annex A
+%% and B.3.
+%%
+%% Optional: Yes/No
+%%
+%% Describes if the parameter may be omitted from the signal or
+%% event.
+%%
+%% Possible values:
+%%
+%% A package MUST specify either a specific set of values or a
+%% description of how values are determined. A package MUST
+%% also specify a default value or the default behavior when the
+%% value is omitted from its descriptor. For example, a package
+%% may specify that procedures related to the parameter are
+%% suspended when its value is omitted.
+%%
+%% Default:
+%%
+%% A default value (but not procedures) may be specified as
+%% provisionable.
+%%
+%%
+%% 12.3 Lists
+%%
+%% Possible values for parameters include enumerations. Enumerations may be
+%% defined in a list. It is recommended that the list be IANA registered so
+%% that packages that extend the list can be defined without concern for
+%% conflicting names.
+%%
+%%
+%% 12.4 Identifiers
+%%
+%% Identifiers in text encoding shall be strings of up to 64 characters,
+%% containing no spaces, starting with an alphabetic character and consisting
+%% of alphanumeric characters and/or digits, and possibly including the
+%% special character underscore ("_").
+%%
+%% Identifiers in binary encoding are 2 octets long.
+%%
+%% Both text and binary values shall be specified for each identifier,
+%% including identifiers used as values in enumerated types.
+%%
+%%
+%% 12.5 Package registration
+%%
+%% A package can be registered with IANA for interoperability reasons. See
+%% clause 14 for IANA considerations.
+%%
+%%----------------------------------------------------------------------
+
+capabilities() ->
+ [{P, capabilities(P)} || P <- packages()].
+
+%% -record(property, {name, type, values, defined_in, characteristics}).
+
+%%----------------------------------------------------------------------
+%% List all known packages
+%% 'native' and 'all' are not real packages
+%%----------------------------------------------------------------------
+
+packages() ->
+ [
+ "g", % Generic
+ "root", % Base Root Package
+ "tonegen", % Tone Generator Package
+ "tonedet", % Tone Detection Package
+ "dg", % Basic DTMF Generator Package
+ "dd", % DTMF detection Package
+ "cg", % Call Progress Tones Generator Package
+ "cd", % Call Progress Tones Detection Package
+ "al", % Analog Line Supervision Package
+ "ct", % Basic Continuity Package
+ "nt", % Network Package
+ "rtp", % RTP Package
+ "swb", % SwitchBoard Package
+ "tdmc", % TDM Circuit Package
+ "" % Native pseudo package
+ ].
+
+%%----------------------------------------------------------------------
+%% List all matching capabilities
+%%----------------------------------------------------------------------
+
+capabilities(Package) ->
+ case Package of
+ "g" -> capabilities_g();
+ "root" -> capabilities_root();
+ "tonegen" -> capabilities_tonegen();
+ "tonedet" -> capabilities_tonedet();
+ "dg" -> capabilities_dg();
+ "dd" -> capabilities_dd();
+ "cg" -> capabilities_cg();
+ "cd" -> capabilities_cd();
+ "al" -> capabilities_al();
+ "ct" -> capabilities_ct();
+ "nt" -> capabilities_nt();
+ "rtp" -> capabilities_rtp();
+ "swb" -> capabilities_swb();
+ "tdmc" -> capabilities_tdmc();
+ "" -> capabilities_native()
+ end.
+
+%%----------------------------------------------------------------------
+%% Decode package name to internal form
+%% Scope ::= property | event | signal | statistics
+%%----------------------------------------------------------------------
+
+decode(mid, Package) ->
+ decode_mid(Package);
+decode(package, Package) ->
+ decode_package(Package);
+decode(profile, Package) ->
+ decode_profile(Package);
+decode(dialplan, Dialplan) ->
+ decode_dialplan(Dialplan);
+decode(Scope, [A, B | Item]) when is_atom(Scope) ->
+ ?d("decode(~p) -> entry with"
+ "~n A: ~p"
+ "~n B: ~p"
+ "~n Item: ~p", [Scope, A, B, Item]),
+ case decode_package([A, B]) of
+ "" ->
+ ?d("decode -> \"no\" package",[]),
+ decode_item(Scope, [A, B], Item);
+ Package ->
+ ?d("decode -> Package: ~p", [Package]),
+ Package ++ "/" ++ decode_item(Scope, [A, B], Item)
+ end;
+decode({Scope, [A, B | Item]}, SubItem) when is_atom(Scope) ->
+ ?d("decode(~p) -> entry with"
+ "~n A: ~p"
+ "~n B: ~p"
+ "~n Item: ~p"
+ "~n SubItem: ~p", [Scope, A, B, Item, SubItem]),
+ decode_item({Scope, Item}, [A, B], SubItem).
+
+decode_item(Scope, [A, B], Item) ->
+ ?d("decode_item -> entry",[]),
+ case A of
+ 16#00 ->
+ case B of
+ 16#01 -> decode_g(Scope, Item);
+ 16#02 -> decode_root(Scope, Item);
+ 16#03 -> decode_tonegen(Scope, Item);
+ 16#04 -> decode_tonedet(Scope, Item);
+ 16#05 -> decode_dg(Scope, Item);
+ 16#06 -> decode_dd(Scope, Item);
+ 16#07 -> decode_cg(Scope, Item);
+ 16#08 -> decode_cd(Scope, Item);
+ 16#09 -> decode_al(Scope, Item);
+ 16#0a -> decode_ct(Scope, Item);
+ 16#0b -> decode_nt(Scope, Item);
+ 16#0c -> decode_rtp(Scope, Item);
+ 16#0d -> decode_tdmc(Scope, Item);
+ 16#00 -> decode_native(Scope, Item)
+ end;
+ 16#fe ->
+ case B of
+ %% Proprietary extension
+ 16#fe -> decode_swb(Scope, Item)
+ end;
+ 16#ff ->
+ case B of
+ 16#ff when Item =:= [16#ff, 16#ff] -> "*"
+ end
+ end.
+
+decode_package(Package) ->
+ ?d("decode_package -> entry with"
+ "~n Package: ~p", [Package]),
+ [A, B] = Package,
+ case A of
+ 16#00 ->
+ case B of
+ 16#01 -> "g";
+ 16#02 -> "root";
+ 16#03 -> "tonegen";
+ 16#04 -> "tonedet";
+ 16#05 -> "dg";
+ 16#06 -> "dd";
+ 16#07 -> "cg";
+ 16#08 -> "cd";
+ 16#09 -> "al";
+ 16#0a -> "ct";
+ 16#0b -> "nt";
+ 16#0c -> "rtp";
+ 16#0d -> "tdmc";
+ 16#00 -> ""
+ end;
+ 16#fe ->
+ case B of
+ 16#fe -> "swb"
+ end;
+ 16#ff ->
+ case B of
+ 16#ff -> "*"
+ end
+ end.
+
+decode_profile([A, B]) ->
+ case A of
+ 16#00 ->
+ case B of
+ 16#fe -> "resgw";
+ _ -> "profile" ++ [A + $0, B + $0]
+ end;
+ _ ->
+ "profile" ++ [A + $0, B + $0]
+ end.
+
+decode_dialplan([A, B]) ->
+ "dialplan" ++ [A + $0, B + $0].
+
+decode_mid(Mid) ->
+ case Mid of
+ {domainName, DN} ->
+ Lower = to_lower(DN#'DomainName'.name),
+ {domainName, DN#'DomainName'{name = Lower}};
+ {deviceName, PathName} ->
+ Lower = to_lower(PathName),
+ {deviceName, Lower};
+ Other ->
+ Other
+ end.
+
+to_lower(Chars) ->
+ [?LOWER(Char) || Char <- Chars].
+
+%%----------------------------------------------------------------------
+%% Encode package name from internal form
+%% Scope ::= property | event | signal | statistics
+%%----------------------------------------------------------------------
+
+encode(mid, Package) ->
+ encode_mid(Package);
+encode(package, Package) ->
+ encode_package(Package);
+encode(profile, Profile) ->
+ encode_profile(Profile);
+encode(dialplan, Dialplan) ->
+ encode_dialplan(Dialplan);
+encode(Scope, PackageItem) when is_atom(Scope) ->
+ ?d("encode(~p) -> entry with"
+ "~n PackageItem: ~p", [Scope, PackageItem]),
+ case string:tokens(PackageItem, [$/]) of
+ [Package, Item] ->
+ ?d("encode -> "
+ "~n Package: ~p"
+ "~n Item: ~p", [Package, Item]),
+ encode_package(Package) ++ encode_item(Scope, Package, Item);
+ [Item] ->
+ ?d("encode -> Item: ~p", [Item]),
+ [16#00, 16#00 | encode_native(Scope, Item)]
+ end;
+encode({Scope, PackageItem}, SubItem) when is_atom(Scope) ->
+ ?d("encode(~p) -> entry with"
+ "~n PackageItem: ~p"
+ "~n SubItem: ~p", [Scope, PackageItem, SubItem]),
+ case string:tokens(PackageItem, [$/]) of
+ [Package, Item] ->
+ ?d("encode -> "
+ "~n Package: ~p"
+ "~n Item: ~p", [Package, Item]),
+ encode_item({Scope, Item}, Package, SubItem);
+ [_Item] ->
+ ?d("encode -> _Item: ~p", [_Item]),
+ encode_native(Scope, SubItem)
+ end.
+
+encode_item(_Scope, _Package, "*") ->
+ [16#ff, 16#ff];
+encode_item(Scope, Package, Item) ->
+ ?d("encode_item(~s) -> entry", [Package]),
+ case Package of
+ "g" -> encode_g(Scope, Item);
+ "root" -> encode_root(Scope, Item);
+ "tonegen" -> encode_tonegen(Scope, Item);
+ "tonedet" -> encode_tonedet(Scope, Item);
+ "dg" -> encode_dg(Scope, Item);
+ "dd" -> encode_dd(Scope, Item);
+ "cg" -> encode_cg(Scope, Item);
+ "cd" -> encode_cd(Scope, Item);
+ "al" -> encode_al(Scope, Item);
+ "ct" -> encode_ct(Scope, Item);
+ "nt" -> encode_nt(Scope, Item);
+ "rtp" -> encode_rtp(Scope, Item);
+ "tdmc" -> encode_tdmc(Scope, Item);
+ "swb" -> encode_swb(Scope, Item)
+ end.
+
+encode_package(Package) ->
+ case Package of
+ "g" -> [16#00, 16#01];
+ "root" -> [16#00, 16#02];
+ "tonegen" -> [16#00, 16#03];
+ "tonedet" -> [16#00, 16#04];
+ "dg" -> [16#00, 16#05];
+ "dd" -> [16#00, 16#06];
+ "cg" -> [16#00, 16#07];
+ "cd" -> [16#00, 16#08];
+ "al" -> [16#00, 16#09];
+ "ct" -> [16#00, 16#0a];
+ "nt" -> [16#00, 16#0b];
+ "rtp" -> [16#00, 16#0c];
+ "tdmc" -> [16#00, 16#0d];
+ "" -> [16#00, 16#00];
+ "*" -> [16#ff, 16#ff];
+ "swb" -> [16#fe, 16#fe]
+ end.
+
+encode_profile(Profile) ->
+ case Profile of
+ "resgw" ->
+ [16#00, 16#fe];
+ [$p, $r, $o, $f, $i, $l, $e | Name] ->
+ case Name of
+ [A, B] -> [A - $0, B - $0];
+ [B] -> [0, B - $0];
+ [] -> [0, 0]
+ end
+ end.
+
+encode_dialplan(Dialplan) ->
+ case Dialplan of
+ [$d, $i, $a, $l, $p, $l, $a, $n | Name] ->
+ case Name of
+ [A, B] -> [A - $0, B - $0];
+ [B] -> [0, B - $0];
+ [] -> [0, 0]
+ end
+ end.
+
+encode_mid(Mid) ->
+ Mid.
+
+
+%%----------------------------------------------------------------------
+%% Name: g - Generic
+%% Version: 1
+%% Extends: None
+%% Purpose: Generic package for commonly encountered items
+%%----------------------------------------------------------------------
+
+capabilities_g() ->
+ [
+ {event, "cause"},
+ {event, "sc"}
+ ].
+
+encode_g(event, Item) ->
+ case Item of
+ "cause" -> [16#00, 16#01];
+ "sc" -> [16#00, 16#02]
+ end;
+
+encode_g({event_parameter, Item}, SubItem) ->
+ case Item of
+ "cause" ->
+ case SubItem of
+ "Generalcause" -> [16#00, 16#01];
+ "Failurecause" -> [16#00, 16#02]
+ end;
+ "sc" ->
+ case SubItem of
+ "SigID" -> [16#00, 16#01];
+ "Meth" -> [16#00, 16#02];
+ "SLID" -> [16#00, 16#03];
+ "RID" -> [16#00, 16#04]
+ end
+ end.
+
+decode_g(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "cause";
+ [16#00, 16#02] -> "sc"
+ end;
+
+decode_g({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event: cause
+ case SubItem of
+ [16#00, 16#01] -> "Generalcause";
+ [16#00, 16#02] -> "Failurecause"
+ end;
+
+ [16#00, 16#02] -> % Event: sc
+ case SubItem of
+ [16#00, 16#01] -> "SigID";
+ [16#00, 16#02] -> "Meth";
+ [16#00, 16#03] -> "SLID";
+ [16#00, 16#04] -> "RID"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: root - Base Root Package
+%% Version: 2
+%% Extends: None
+%% Purpose: This package defines Gateway wide properties.
+%%----------------------------------------------------------------------
+
+capabilities_root() ->
+ [
+ {property, "maxNumberOfContexts"},
+ {property, "maxTerminationsPerContext"},
+ {property, "normalMGExecutionTime"},
+ {property, "normalMGCExecutionTime"},
+ {property, "MGProvisionalResponseTimerValue"},
+ {property, "MGCProvisionalResponseTimerValue"},
+ {property, "MGCOriginatedPendingLimit"},
+ {property, "MGOriginatedPendingLimit"}
+ ].
+
+encode_root(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ "maxNumberOfContexts" -> [16#00, 16#01];
+ "maxTerminationsPerContext" -> [16#00, 16#02];
+ "normalMGExecutionTime" -> [16#00, 16#03];
+ "normalMGCExecutionTime" -> [16#00, 16#04];
+ "MGProvisionalResponseTimerValue" -> [16#00, 16#05];
+ "MGCProvisionalResponseTimerValue" -> [16#00, 16#06];
+ "MGCOriginatedPendingLimit" -> [16#00, 16#07];
+ "MGOriginatedPendingLimit" -> [16#00, 16#08]
+ end
+ end.
+
+decode_root(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ [16#00, 16#01] -> "maxNumberOfContexts";
+ [16#00, 16#02] -> "maxTerminationsPerContext";
+ [16#00, 16#03] -> "normalMGExecutionTime";
+ [16#00, 16#04] -> "normalMGCExecutionTime";
+ [16#00, 16#05] -> "MGProvisionalResponseTimerValue";
+ [16#00, 16#06] -> "MGCProvisionalResponseTimerValue";
+ [16#00, 16#07] -> "MGCOriginatedPendingLimit";
+ [16#00, 16#08] -> "MGOriginatedPendingLimit"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tonegen - Tone Generator Package
+%% Version: 2
+%% Extends: None
+%% Purpose: This package defines signals to generate audio tones.
+%% This package does not specify parameter values. It is
+%% intended to be extendable. Generally, tones are defined
+%% as an individual signal with a parameter, ind,
+%% representing "interdigit" time delay, and a tone id to
+%% be used with playtones. A tone id should be kept
+%% consistent with any tone generation for the same tone.
+%% MGs are expected to be provisioned with the characteristics
+%% of appropriate tones for the country in which the MG is located.
+%%----------------------------------------------------------------------
+
+capabilities_tonegen() ->
+ [
+ {signal, "pt"}
+ ].
+
+encode_tonegen(signal, Item) ->
+ case Item of
+ "pt" -> [16#00, 16#01]
+ end;
+
+encode_tonegen({signal_parameter, Item}, SubItem) ->
+ case Item of
+ "pt" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "ind" -> [16#00, 16#02];
+ "btd" -> [16#00, 16#03]
+ end
+ end.
+
+decode_tonegen(signal, Item) ->
+ case Item of
+ [16#00, 16#01] -> "pt"
+ end;
+
+decode_tonegen({signal_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event: pt
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#02] -> "ind";
+ [16#00, 16#03] -> "btd"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tonedet - Tone Detection Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This Package defines events for audio tone detection.
+%% Tones are selected by name (tone id). MGs are expected
+%% to be provisioned with the characteristics of appropriate
+%% tones for the country in which the MG is located.
+%%
+%% This package does not specify parameter values.
+%% It is intended to be extendable.
+%%----------------------------------------------------------------------
+
+capabilities_tonedet() ->
+ [
+ {event, "std"},
+ {event, "etd"},
+ {event, "ltd"}
+ ].
+
+encode_tonedet(event, Item) ->
+ case Item of
+ "std" -> [16#00, 16#01];
+ "etd" -> [16#00, 16#02];
+ "ltd" -> [16#00, 16#03]
+ end;
+
+encode_tonedet({event_parameter, Item}, SubItem) ->
+ case Item of
+ "std" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "tid" -> [16#00, 16#03]
+ end;
+ "etd" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "tid" -> [16#00, 16#03];
+ "dur" -> [16#00, 16#02]
+ end;
+ "ltd" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "dur" -> [16#00, 16#02];
+ "tid" -> [16#00, 16#03]
+ end
+ end.
+
+decode_tonedet(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "std";
+ [16#00, 16#02] -> "etd";
+ [16#00, 16#03] -> "ltd"
+ end;
+
+decode_tonedet({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event std
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#03] -> "tid"
+ end;
+ [16#00, 16#02] -> % Event etd
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#03] -> "tid";
+ [16#00, 16#02] -> "dur"
+ end;
+ [16#00, 16#03] -> % Event ltd
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#02] -> "dur";
+ [16#00, 16#03] -> "tid"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: dg - Basic DTMF Generator Package
+%% Version: 1
+%% Extends: tonegen version 1
+%% Purpose: This package defines the basic DTMF tones as signals and
+%% extends the allowed values of parameter tl of playtone
+%% in tonegen.
+%%----------------------------------------------------------------------
+
+capabilities_dg() ->
+ [
+ {signal, "d0"},
+ {signal, "d1"},
+ {signal, "d2"},
+ {signal, "d3"},
+ {signal, "d4"},
+ {signal, "d5"},
+ {signal, "d6"},
+ {signal, "d7"},
+ {signal, "d8"},
+ {signal, "d9"},
+ {signal, "ds"},
+ {signal, "do"},
+ {signal, "da"},
+ {signal, "db"},
+ {signal, "dc"},
+ {signal, "dd"}
+ ].
+
+encode_dg(signal, Item) ->
+ case Item of
+ "d0" -> [16#00, 16#10];
+ "d1" -> [16#00, 16#11];
+ "d2" -> [16#00, 16#12];
+ "d3" -> [16#00, 16#13];
+ "d4" -> [16#00, 16#14];
+ "d5" -> [16#00, 16#15];
+ "d6" -> [16#00, 16#16];
+ "d7" -> [16#00, 16#17];
+ "d8" -> [16#00, 16#18];
+ "d9" -> [16#00, 16#19];
+ "ds" -> [16#00, 16#20];
+ "do" -> [16#00, 16#21];
+ "da" -> [16#00, 16#1a];
+ "db" -> [16#00, 16#1b];
+ "dc" -> [16#00, 16#1c];
+ "dd" -> [16#00, 16#1d]
+ end;
+
+encode_dg({signal_parameter, Item}, SubItem) ->
+ case Item of
+ "d0" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d1" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d2" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d3" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d4" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d5" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d6" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d7" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d8" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d9" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "ds" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "do" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "da" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "db" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dc" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dd" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end
+ end.
+
+decode_dg(signal, Item) ->
+ case Item of
+ [16#00, 16#10] -> "d0";
+ [16#00, 16#11] -> "d1";
+ [16#00, 16#12] -> "d2";
+ [16#00, 16#13] -> "d3";
+ [16#00, 16#14] -> "d4";
+ [16#00, 16#15] -> "d5";
+ [16#00, 16#16] -> "d6";
+ [16#00, 16#17] -> "d7";
+ [16#00, 16#18] -> "d8";
+ [16#00, 16#19] -> "d9";
+ [16#00, 16#20] -> "ds";
+ [16#00, 16#21] -> "do";
+ [16#00, 16#1a] -> "da";
+ [16#00, 16#1b] -> "db";
+ [16#00, 16#1c] -> "dc";
+ [16#00, 16#1d] -> "dd"
+ end;
+
+decode_dg({signal_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#10] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#11] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#12] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#13] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#14] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#15] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#16] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#17] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#18] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#19] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#20] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#21] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1a] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1b] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1c] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1d] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: dd - DTMF detection Package
+%% Version: 1
+%% Extends: tonedet version 1
+%% Purpose: This package defines the basic DTMF tones detection.
+%% Tones are selected by name (tone id). MGs are expected
+%% to be provisioned with the characteristics of appropriate
+%% tones for the country in which the MG is located.
+%%
+%% This package does not specify parameter values.
+%% It is intended to be extendable.
+%%
+%% Additional tone id values are all tone ids described in package dg
+%% (basic DTMF generator package).
+%%
+%% The following table maps DTMF events to digit map symbols as described
+%% in section 7.1.14.
+%%
+%% _________________________________
+%% | DTMF Event | Symbol |
+%% | d0 | "0" |
+%% | d1 | "1" |
+%% | d2 | "2" |
+%% | d3 | "3" |
+%% | d4 | "4" |
+%% | d5 | "5" |
+%% | d6 | "6" |
+%% | d7 | "7" |
+%% | d8 | "8" |
+%% | d9 | "9" |
+%% | da | "A" or "a"|
+%% | db | "B" or "b"|
+%% | dc | "C" or "c"|
+%% | dd | "D" or "d"|
+%% | ds | "E" or "e"|
+%% | do | "F" or "f"|
+%% |___________________|____________|
+%%
+%%----------------------------------------------------------------------
+
+capabilities_dd() ->
+ [
+ {event, "ce"},
+ {event, "d0"},
+ {event, "d1"},
+ {event, "d2"},
+ {event, "d3"},
+ {event, "d4"},
+ {event, "d5"},
+ {event, "d6"},
+ {event, "d7"},
+ {event, "d8"},
+ {event, "d9"},
+ {event, "ds"},
+ {event, "do"},
+ {event, "da"},
+ {event, "db"},
+ {event, "dc"},
+ {event, "dd"}
+ ].
+
+encode_dd(event, Item) ->
+ case Item of
+ "ce" -> [16#00, 16#04];
+ "d0" -> [16#00, 16#10];
+ "d1" -> [16#00, 16#11];
+ "d2" -> [16#00, 16#12];
+ "d3" -> [16#00, 16#13];
+ "d4" -> [16#00, 16#14];
+ "d5" -> [16#00, 16#15];
+ "d6" -> [16#00, 16#16];
+ "d7" -> [16#00, 16#17];
+ "d8" -> [16#00, 16#18];
+ "d9" -> [16#00, 16#19];
+ "ds" -> [16#00, 16#20];
+ "do" -> [16#00, 16#21];
+ "da" -> [16#00, 16#1a];
+ "db" -> [16#00, 16#1b];
+ "dc" -> [16#00, 16#1c];
+ "dd" -> [16#00, 16#1d]
+ end;
+
+encode_dd({event_parameter, Item}, SubItem) ->
+ case Item of
+ "ce" ->
+ case SubItem of
+ "ds" -> [16#00, 16#01];
+ "Meth" -> [16#00, 16#03]
+ end;
+ "d0" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d1" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d2" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d3" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d4" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d5" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d6" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d7" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d8" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d9" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "ds" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "do" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "da" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "db" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dc" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dd" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end
+ end.
+
+decode_dd(event, Item) ->
+ case Item of
+ [16#00, 16#04] -> "ce";
+ [16#00, 16#10] -> "d0";
+ [16#00, 16#11] -> "d1";
+ [16#00, 16#12] -> "d2";
+ [16#00, 16#13] -> "d3";
+ [16#00, 16#14] -> "d4";
+ [16#00, 16#15] -> "d5";
+ [16#00, 16#16] -> "d6";
+ [16#00, 16#17] -> "d7";
+ [16#00, 16#18] -> "d8";
+ [16#00, 16#19] -> "d9";
+ [16#00, 16#20] -> "ds";
+ [16#00, 16#21] -> "do";
+ [16#00, 16#1a] -> "da";
+ [16#00, 16#1b] -> "db";
+ [16#00, 16#1c] -> "dc";
+ [16#00, 16#1d] -> "dd"
+ end;
+
+decode_dd({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#04] -> % Event ce
+ case SubItem of
+ [16#00, 16#01] -> "ds";
+ [16#00, 16#03] -> "Meth"
+ end;
+ [16#00, 16#10] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#11] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#12] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#13] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#14] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#15] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#16] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#17] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#18] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#19] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#20] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#21] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1a] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1b] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1c] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1d] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: cg - Call Progress Tones Generator Package
+%% Version: 1
+%% Extends: tonegen version 1
+%% Purpose: This package defines the basic call progress tones as signals
+%% and extends the allowed values of the tl parameter of
+%% playtone in tonegen.
+%%----------------------------------------------------------------------
+
+capabilities_cg() ->
+ [
+ {signal, "dt"},
+ {signal, "rt"},
+ {signal, "bt"},
+ {signal, "ct"},
+ {signal, "sit"},
+ {signal, "wt"},
+ {signal, "prt"},
+ {signal, "cw"},
+ {signal, "cr"}
+ ].
+
+
+encode_cg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ "dt" -> [16#00, 16#30];
+ "rt" -> [16#00, 16#31];
+ "bt" -> [16#00, 16#32];
+ "ct" -> [16#00, 16#33];
+ "sit" -> [16#00, 16#34];
+ "wt" -> [16#00, 16#35];
+ "prt" -> [16#00, 16#36];
+ "cw" -> [16#00, 16#37];
+ "cr" -> [16#00, 16#38]
+ end
+ end.
+
+decode_cg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ [16#00, 16#30] -> "dt";
+ [16#00, 16#31] -> "rt";
+ [16#00, 16#32] -> "bt";
+ [16#00, 16#33] -> "ct";
+ [16#00, 16#34] -> "sit";
+ [16#00, 16#35] -> "wt";
+ [16#00, 16#36] -> "prt";
+ [16#00, 16#37] -> "cw";
+ [16#00, 16#38] -> "cr"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: cd - Call Progress Tones Detection Package
+%% Version: 1
+%% Extends: tonedet version 1
+%% Purpose: This package defines the basic call progress detection tones.
+%% This Package extends the possible values of tone id
+%% in the "start tone detected", "end tone detected" and
+%% "long tone detected" events.
+%% Additional values
+%% tone id values are defined for start tone detected,
+%% end tone detected and long tone detected with
+%% the same values as those in package cg (call
+%% progress tones generation package).
+%%
+%% The required set of tone ids corresponds to Recommendation E.180/Q.35
+%% [ITU-T Recommendation E.180/Q.35 (1998)]. See Recommendation E.180/Q.35
+%% for definition of the meanings of these tones.
+%%----------------------------------------------------------------------
+
+capabilities_cd() ->
+ [
+ {event, "dt"},
+ {event, "rt"},
+ {event, "bt"},
+ {event, "ct"},
+ {event, "sit"},
+ {event, "wt"},
+ {event, "prt"},
+ {event, "cw"},
+ {event, "cr"}
+ ].
+
+
+encode_cd(Scope, Item) ->
+ case Scope of
+ event ->
+ case Item of
+ "dt" -> [16#00, 16#30];
+ "rt" -> [16#00, 16#31];
+ "bt" -> [16#00, 16#32];
+ "ct" -> [16#00, 16#33];
+ "sit"-> [16#00, 16#34];
+ "wt" -> [16#00, 16#35];
+ "prt"-> [16#00, 16#36];
+ "cw" -> [16#00, 16#37];
+ "cr" -> [16#00, 16#38]
+ end
+ end.
+
+decode_cd(Scope, Item) ->
+ case Scope of
+ event ->
+ case Item of
+ [16#00, 16#30] -> "dt";
+ [16#00, 16#31] -> "rt";
+ [16#00, 16#32] -> "bt";
+ [16#00, 16#33] -> "ct";
+ [16#00, 16#34] -> "sit";
+ [16#00, 16#35] -> "wt";
+ [16#00, 16#36] -> "prt";
+ [16#00, 16#37] -> "cw";
+ [16#00, 16#38] -> "cr"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: al - Analog Line Supervision Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines events and signals for an analog line.
+%%----------------------------------------------------------------------
+
+capabilities_al() ->
+ [
+ {event, "on"},
+ {event, "of"},
+ {event, "fl"},
+ {signal, "ri"}
+ ].
+
+encode_al(event, Item) ->
+ ?d("encode_al(event) -> entry with"
+ "~n Item: ~p", [Item]),
+ case Item of
+ "on" -> [16#00, 16#04];
+ "of" -> [16#00, 16#05];
+ "fl" -> [16#00, 16#06]
+ end;
+
+encode_al({event_parameter, Item}, SubItem) ->
+ ?d("encode_al({event_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ "on" ->
+ case SubItem of
+ "strict" -> [16#00, 16#01];
+ "init" -> [16#00, 16#02]
+ end;
+ "of" ->
+ case SubItem of
+ "strict" -> [16#00, 16#01];
+ "init" -> [16#00, 16#02]
+ end;
+ "fl" ->
+ case SubItem of
+ "mindur" -> [16#00, 16#04];
+ "maxdur" -> [16#00, 16#05]
+ end
+ end;
+
+encode_al(signal, Item) ->
+ ?d("encode_al(signal) -> entry with"
+ "~n Item: ~p", [Item]),
+ case Item of
+ "ri" -> [16#00, 16#02]
+ end;
+
+encode_al({signal_parameter, Item}, SubItem) ->
+ ?d("encode_al({signal_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ "ri" ->
+ case SubItem of
+ "cad" -> [16#00, 16#06];
+ "freq" -> [16#00, 16#07]
+ end
+ end.
+
+decode_al(event, SubItem) ->
+ ?d("decode_al(event) -> entry with"
+ "~n SubItem: ~p", [SubItem]),
+ case SubItem of
+ [16#00, 16#04] -> "on";
+ [16#00, 16#05] -> "of";
+ [16#00, 16#06] -> "fl"
+ end;
+
+decode_al({event_parameter, Item}, SubItem) ->
+ ?d("decode_al({event_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ [16#00,16#04] -> %% Event: on
+ case SubItem of
+ [16#00, 16#01] -> "strict";
+ [16#00, 16#02] -> "init"
+ end;
+ [16#00,16#05] -> %% Event: of
+ case SubItem of
+ [16#00, 16#01] -> "strict";
+ [16#00, 16#02] -> "init"
+ end;
+ [16#00,16#06] -> %% Event: fl
+ case SubItem of
+ [16#00, 16#04] -> "mindur";
+ [16#00, 16#05] -> "maxdur"
+ end
+ end;
+
+decode_al(signal, SubItem) ->
+ ?d("decode_al(signal) -> entry with"
+ "~n SubItem: ~p", [SubItem]),
+ case SubItem of
+ [16#00, 16#02] -> "ri"
+ end;
+
+decode_al({signal_parameter, Item}, SubItem) ->
+ ?d("decode_al({signal_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ [16#00,16#02] -> %% Event: ri
+ case SubItem of
+ [16#00, 16#06] -> "cad";
+ [16#00, 16#07] -> "freq"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: ct - Basic Continuity Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines events and signals for continuity test.
+%% The continuity test includes provision of either a loopback
+%% or transceiver functionality.
+%%----------------------------------------------------------------------
+
+capabilities_ct() ->
+ [
+ {event, "cmp"},
+ {signal, "ct"},
+ {signal, "rsp"}
+ ].
+
+encode_ct(event, Item) ->
+ case Item of
+ "cmp" -> [16#00, 16#05]
+ end;
+encode_ct({event_parameter, Item}, SubItem) ->
+ case Item of
+ "cmp" ->
+ case SubItem of
+ "res" -> [16#00, 16#08]
+ end
+ end;
+encode_ct(signal, Item) ->
+ case Item of
+ "ct" -> [16#00, 16#03];
+ "rsp" -> [16#00, 16#04]
+ end.
+
+decode_ct(event, Item) ->
+ case Item of
+ [16#00, 16#05] -> "cmp"
+ end;
+decode_ct({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#05] -> % Event cmp
+ case SubItem of
+ [16#00, 16#08] -> "res"
+ end
+ end;
+decode_ct(signal, Item) ->
+ case Item of
+ [16#00, 16#03] -> "ct";
+ [16#00, 16#04] -> "rsp"
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: nt - Network Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines properties of network terminations
+%% independent of network type.
+%%----------------------------------------------------------------------
+
+capabilities_nt() ->
+ [
+ {property, "jit"},
+ {event, "netfail"},
+ {event, "qualert"},
+ {statistics, "dur"},
+ {statistics, "os"},
+ {statistics, "or"}
+ ].
+
+encode_nt(property, Item) ->
+ case Item of
+ "jit" -> [16#00, 16#07]
+ end;
+encode_nt(event, Item) ->
+ case Item of
+ "netfail" -> [16#00, 16#05];
+ "qualert" -> [16#00, 16#06]
+ end;
+encode_nt({event_parameter, Item}, SubItem) ->
+ case Item of
+ "netfail" ->
+ case SubItem of
+ "cs" -> [16#00, 16#01]
+ end;
+ "qualert" ->
+ case SubItem of
+ "th" -> [16#00, 16#01]
+ end
+ end;
+encode_nt(statistics, Item) ->
+ case Item of
+ "dur" -> [16#00, 16#01];
+ "os" -> [16#00, 16#02];
+ "or" -> [16#00, 16#03]
+ end.
+
+decode_nt(property, Item) ->
+ case Item of
+ [16#00, 16#07] -> "jit"
+ end;
+decode_nt(event, Item) ->
+ case Item of
+ [16#00, 16#05] -> "netfail";
+ [16#00, 16#06] -> "qualert"
+ end;
+decode_nt({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#05] -> % Event netfail
+ case SubItem of
+ [16#00, 16#01] -> "cs"
+ end;
+ [16#00, 16#06] -> % Event qualert
+ case Item of
+ [16#00, 16#01] -> "th"
+ end
+ end;
+decode_nt(statistics, Item) ->
+ case Item of
+ [16#00, 16#01] -> "dur";
+ [16#00, 16#02] -> "os";
+ [16#00, 16#03] -> "or"
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: rtp - RTP Package
+%% Version: 1
+%% Extends: nt version 1
+%% Purpose: This package is used to support packet based multimedia
+%% data transfer by means of the Real-time Transport Protocol
+%% (RTP) [RFC 1889].
+%%----------------------------------------------------------------------
+
+capabilities_rtp() ->
+ [
+ {event, "pltrans"},
+ {statistics, "ps"},
+ {statistics, "pr"},
+ {statistics, "pl"},
+ {statistics, "jit"},
+ {statistics, "delay"}
+ ].
+
+encode_rtp(event, Item) ->
+ case Item of
+ "pltrans" -> [16#00, 16#01]
+ end;
+encode_rtp({event_parameter, Item}, SubItem) ->
+ case Item of
+ "pltrans" ->
+ case SubItem of
+ "rtppltype" -> [16#00, 16#01]
+ end
+ end;
+encode_rtp(statistics, Item) ->
+ case Item of
+ "ps" -> [16#00, 16#04];
+ "pr" -> [16#00, 16#05];
+ "pl" -> [16#00, 16#06];
+ "jit" -> [16#00, 16#07];
+ "delay" -> [16#00, 16#08]
+ end.
+
+decode_rtp(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "pltrans"
+ end;
+decode_rtp({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event pltrans
+ case SubItem of
+ [16#00, 16#01] -> "rtppltype"
+ end
+ end;
+decode_rtp(statistics, Item) ->
+ case Item of
+ [16#00, 16#04] -> "ps";
+ [16#00, 16#05] -> "pr";
+ [16#00, 16#06] -> "pl";
+ [16#00, 16#07] -> "jit";
+ [16#00, 16#08] -> "delay"
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tdmc - TDM Circuit Package
+%% Version: 1
+%% Extends: nt version 1
+%% Purpose: This package is used to support TDM circuit terminations.
+%%----------------------------------------------------------------------
+
+capabilities_tdmc() ->
+ [
+ {property, "ec"},
+ {property, "gain"}
+ ].
+
+encode_tdmc(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ "ec" -> [16#00, 16#08];
+ "gain" -> [16#00, 16#0a]
+ end
+ end.
+
+decode_tdmc(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ [16#00, 16#08] -> "ec";
+ [16#00, 16#0a] -> "gain"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: swb - SwitchBoard Package
+%% Version: 1
+%% Extends: none
+%% Purpose: This package is used to support SwitchBoard specials
+%%----------------------------------------------------------------------
+
+capabilities_swb() ->
+ [
+ {statistics, "fs"}, % Free slots
+ {statistics, "as"} % Allocated slots
+ ].
+
+encode_swb(Scope, Item) ->
+ case Scope of
+ statistics ->
+ case Item of
+ "fs" -> [16#00, 16#00];
+ "as" -> [16#00, 16#01]
+ end
+ end.
+
+decode_swb(Scope, Item) ->
+ case Scope of
+ statistics ->
+ case Item of
+ [16#00, 16#00] -> "fs";
+ [16#00, 16#01] -> "as"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: native - Pseudo package
+%% Version: 1
+%% Extends: None
+%% Purpose: Native tags for media stream properties
+%%
+%% Parameters for Local descriptors and Remote descriptors are
+%% specified as tag-value pairs if binary encoding is used for the
+%% protocol. This annex contains the property names (PropertyID), the
+%% tags (Property Tag), type of the property (Type) and the values
+%% (Value).Values presented in the Value field when the field contains
+%% references shall be regarded as "information". The reference
+%% contains the normative values. If a value field does not contain a
+%% reference then the values in that field can be considered as
+%% "normative".
+%%
+%% Tags are given as hexadecimal numbers in this annex. When setting
+%% the value of a property, a MGC may underspecify the value according
+%% to one of the mechanisms specified in section 7.1.1.
+%%
+%% For type "enumeration" the value is represented by the value in brack-
+%% ets, e.g., Send(0), Receive(1).
+%%----------------------------------------------------------------------
+%%
+%% C.6. IP
+%%
+%% ________________________________________________________________
+%% | PropertyID| Tag | Type | Value |
+%% | IPv4 | 6001 | 32 BITS | Ipv4Address |
+%% | IPv6 | 6002 | 128 BITS | IPv6 Address |
+%% | Port | 6003 | Unsigned Int| Port |
+%% | Porttype | 6004 | Enumerated | TCP(0),UDP(1),SCTP(2)|
+%% |___________|____________|______________|_______________________|
+%%
+%%
+%% C.11. SDP Equivalents
+%%
+%% ______________________________________________________________
+%% | PropertyID| Tag | Type | Value |
+%% | SDP_V | B001| STRING| Protocol Version |
+%% | SDP_O | B002| STRING| Owner-creator and session ID |
+%% | SDP_S | B003| STRING| Sesson name |
+%% | SDP_I | B004| STRING| Session identifier |
+%% | SDP_U | B005| STRING| URI of descriptor |
+%% | SDC_E | B006| STRING| email address |
+%% | SDP_P | B007| STRING| phone number |
+%% | SDP_C | B008| STRING| Connection information |
+%% | SDP_B | B009| STRING| Bandwidth Information |
+%% | SDP_Z | B00A| STRING| time zone adjustment |
+%% | SDP_K | B00B| STRING| Encryption Key |
+%% | SDP_A | B00C| STRING| Zero or more session attributes|
+%% | SDP_T | B00D| STRING| Active Session Time |
+%% | SDP_R | B00E| STRING| Zero or more repeat times |
+%% | SDP_M | B00F| STRING| Media name and transport addr |
+%% | | | | Reference: IETF RFC 2327 |
+%% |___________|______|________|_________________________________|
+%%
+%%----------------------------------------------------------------------
+
+capabilities_native() ->
+ [
+ %% C.6. IP
+ {property, "IPv4"},
+ {property, "IPv6"},
+ {property, "Port"},
+ {property, "Porttype"},
+
+ %% C.11. SDP Equivalents
+ {property, "v"},
+ {property, "o"},
+ {property, "s"},
+ {property, "i"},
+ {property, "u"},
+ {property, "e"},
+ {property, "p"},
+ {property, "c"},
+ {property, "b"},
+ {property, "z"},
+ {property, "k"},
+ {property, "a"},
+ {property, "t"},
+ {property, "r"},
+ {property, "m"}
+ ].
+
+encode_native(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ %% IP
+ "IPv4" -> [16#60, 16#01];
+ "IPv6" -> [16#60, 16#02];
+ "Port" -> [16#60, 16#03];
+ "Porttype" -> [16#60, 16#04];
+
+ %% SDP
+ "v" -> [16#b0, 16#01];
+ "o" -> [16#b0, 16#02];
+ "s" -> [16#b0, 16#03];
+ "i" -> [16#b0, 16#04];
+ "u" -> [16#b0, 16#05];
+ "e" -> [16#b0, 16#06];
+ "p" -> [16#b0, 16#07];
+ "c" -> [16#b0, 16#08];
+ "b" -> [16#b0, 16#09];
+ "z" -> [16#b0, 16#0a];
+ "k" -> [16#b0, 16#0b];
+ "a" -> [16#b0, 16#0c];
+ "t" -> [16#b0, 16#0d];
+ "r" -> [16#b0, 16#0e];
+ "m" -> [16#b0, 16#0f]
+ end
+ end.
+
+decode_native(Scope, [Type, Item]) ->
+ case Scope of
+ property ->
+ case Type of
+ 16#60 ->
+ case Item of
+ 16#01 -> "IPv4";
+ 16#02 -> "IPv6";
+ 16#03 -> "Port";
+ 16#04 -> "Porttype"
+ end;
+
+ 16#b0 ->
+ case Item of
+ 16#01 -> "v";
+ 16#02 -> "o";
+ 16#03 -> "s";
+ 16#04 -> "i";
+ 16#05 -> "u";
+ 16#06 -> "e";
+ 16#07 -> "p";
+ 16#08 -> "c";
+ 16#09 -> "b";
+ 16#0a -> "z";
+ 16#0b -> "k";
+ 16#0c -> "a";
+ 16#0d -> "t";
+ 16#0e -> "r";
+ 16#0f -> "m"
+ end
+ end
+ end.
+
+%% -------------------------------------------------------------------
+
+% error(Reason) ->
+% erlang:error(Reason).
+
diff --git a/lib/megaco/src/binary/megaco_binary_name_resolver_v1.erl b/lib/megaco/src/binary/megaco_binary_name_resolver_v1.erl
new file mode 100644
index 0000000000..a748a1d0cc
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_name_resolver_v1.erl
@@ -0,0 +1,1613 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Handle meta data about packages
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_name_resolver_v1).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+-include_lib("megaco/src/app/megaco_internal.hrl").
+
+-define(LOWER(Char),
+ if
+ Char >= $A, Char =< $Z ->
+ Char - ($A - $a);
+ true ->
+ Char
+ end).
+
+-export([packages/0,
+ capabilities/0,
+ capabilities/1,
+ decode_name/3,
+ encode_name/3
+ ]).
+
+encode_name(Config, term_id, TermId) ->
+ case megaco:encode_binary_term_id(Config, TermId) of
+ {ok, TermId2} ->
+ TermId2;
+ {error, _Reason} ->
+ exit({bad_term_id, TermId})
+ end;
+encode_name(_Config, Scope, Item) ->
+ ?d("encode_name(~p) -> entry with"
+ "~n Item: ~p", [Scope, Item]),
+ encode(Scope, Item).
+
+decode_name(Config, term_id, TermId) ->
+ case megaco:decode_binary_term_id(Config, TermId) of
+ {ok, TermId2} ->
+ TermId2;
+ {error, _Reason} ->
+ exit({bad_term_id, TermId})
+ end;
+decode_name(_Config, Scope, Item) ->
+ ?d("decode_name(~p) -> entry with"
+ "~n Item: ~p", [Scope, Item]),
+ decode(Scope, Item).
+
+
+
+
+%%----------------------------------------------------------------------
+%% 12.1.1 Package
+%%
+%% Overall description of the package, specifying:
+%%
+%% Package Name: only descriptive
+%%
+%% PackageID: is an identifier
+%%
+%% Description:
+%%
+%% Version:
+%%
+%% A new version of a package can only add additional Properties,
+%% Events, Signals, Statistics and new possible values for an
+%% existing parameter described in the original package. No
+%% deletions or modifications shall be allowed. A version is an
+%% integer in the range from 1 to 99.
+%%
+%% Designed to be extended only (Optional):
+%%
+%% This indicates that the package has been expressly designed to
+%% be extended by others, not to be directly referenced. For
+%% example, the package may not have any function on its own or be
+%% nonsensical on its own. The MG SHOULD NOT publish this
+%% PackageID when reporting packages.
+%%
+%% Extends (Optional): existing package Descriptor
+%%
+%% A package may extend an existing package. The version of the
+%% original package must be specified. When a package extends
+%% another package it shall only add additional Properties,
+%% Events, Signals, Statistics and new possible values for an
+%% existing parameter described in the original package. An
+%% extended package shall not redefine or overload an identifier
+%% defined in the original package and packages it may have
+%% extended (multiple levels of extension). Hence, if package B
+%% version 1 extends package A version 1, version 2 of B will not
+%% be able to extend the A version 2 if A version 2 defines a name
+%% already in B version 1.
+%%
+%%
+%% 12.1.2 Properties
+%%
+%% Properties defined by the package, specifying:
+%%
+%% Property Name: only descriptive
+%%
+%% PropertyID: is an identifier
+%%
+%% Description:
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 string
+%%
+%% Octet String: A number of octets. See Annex A and Annex B.3
+%% for encoding
+%%
+%% Integer: 4 byte signed integer
+%%
+%% Double: 8 byte signed integer
+%%
+%% Character: unicode UTF-8 encoding of a single letter. Could be
+%% more than one octet.
+%%
+%% Enumeration: one of a list of possible unique values (see 12.3)
+%%
+%% Sub-list: a list of several values from a list. The type of
+%% sub-list SHALL also be specified. The type shall be chosen
+%% from the types specified in this section (with the exception of
+%% sub-list). For example, Type: sub-list of enumeration. The
+%% encoding of sub-lists is specified in Annexes A and B.3.
+%%
+%% Possible values:
+%%
+%% A package MUST specify either a specific set of values or a
+%% description of how values are determined. A package MUST also
+%% specify a default value or the default behaviour when the value
+%% is omitted from its descriptor. For example, a package may
+%% specify that procedures related to the property are suspended
+%% when its value is omitted. A default value (but not
+%% procedures) may be specified as provisionable.
+%%
+%% Defined in:
+%%
+%% Which H.248.1 descriptor the property is defined in.
+%% LocalControl is for stream dependent properties.
+%% TerminationState is for stream independent properties. These
+%% are expected to be the most common cases, but it is possible
+%% for properties to be defined in other descriptors.
+%%
+%% Characteristics: Read/Write or both, and (optionally), global:
+%%
+%% Indicates whether a property is read-only, or read-write, and
+%% if it is global. If Global is omitted, the property is not
+%% global. If a property is declared as global, the value of the
+%% property is shared by all Terminations realizing the package.
+%%
+%%
+%% 12.1.3 Events
+%%
+%% Events defined by the package, specifying:
+%%
+%% Event name: only descriptive
+%%
+%% EventID: is an identifier
+%%
+%% Description:
+%%
+%% EventsDescriptor Parameters:
+%%
+%% Parameters used by the MGC to configure the event, and found in
+%% the EventsDescriptor. See 12.2.
+%%
+%% ObservedEventsDescriptor Parameters:
+%%
+%% Parameters returned to the MGC in Notify requests and in
+%% replies to command requests from the MGC that audit
+%% ObservedEventsDescriptor, and found in the
+%% ObservedEventsDescriptor. See 12.2.
+%%
+%%
+%% 12.1.4 Signals
+%%
+%% Signals defined by the package, specifying:
+%%
+%% Signal Name: only descriptive
+%%
+%% SignalID: is an identifier. SignalID is used in a
+%% SignalsDescriptor
+%%
+%% Description
+%%
+%% SignalType: one of:
+%%
+%% OO (On/Off)
+%%
+%% TO (TimeOut)
+%%
+%% BR (Brief)
+%%
+%% NOTE - SignalType may be defined such that it is dependent on the
+%% value of one or more parameters. The package MUST specify a
+%% default signal type. If the default type is TO, the package MUST
+%% specify a default duration which may be provisioned. A default
+%% duration is meaningless for BR.
+%%
+%% Duration: in hundredths of seconds
+%%
+%% Additional Parameters: see 12.2
+%%
+%%
+%% 12.1.5 Statistics
+%%
+%% Statistics defined by the package, specifying:
+%%
+%% Statistic name: only descriptive
+%%
+%% StatisticID: is an identifier
+%%
+%% StatisticID is used in a StatisticsDescriptor
+%%
+%% Description:
+%%
+%% Units: unit of measure, e.g., milliseconds, packets
+%%
+%%
+%% 12.1.6 Procedures
+%%
+%% Additional guidance on the use of the package.
+%%
+%%
+%% 12.2 Guidelines to defining Parameters to Events and Signals
+%%
+%% Parameter Name: only descriptive
+%%
+%% ParameterID: is an identifier. The textual ParameterID of parameters
+%% to Events and Signals shall not start with "EPA" and "SPA",
+%% respectively. The textual ParameterID shall also not be "ST",
+%% "Stream", "SY", "SignalType", "DR", "Duration", "NC",
+%% "NotifyCompletion", "KA", "Keepactive", "EB", "Embed", "DM" or
+%% "DigitMap".
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 octet string
+%% Octet String: A number of octets. See Annex A and Annex B.3 for
+%% encoding
+%%
+%% Integer: 4-octet signed integer
+%%
+%% Double: 8-octet signed integer
+%%
+%% Character: unicode UTF-8 encoding of a single letter. Could be
+%% more than one octet.
+%%
+%% Enumeration: one of a list of possible unique values (see 12.3)
+%%
+%% Sub-list: a list of several values from a list (not supported for
+%% statistics). The type of sub-list SHALL also be specified. The
+%% type shall be chosen from the types specified in this section
+%% (with the exception of sub-list). For example, Type: sub-list of
+%% enumeration. The encoding of sub-lists is specified in Annexes A
+%% and B.3.
+%%
+%% Possible values:
+%%
+%% A package MUST specify either a specific set of values or a
+%% description of how values are determined. A package MUST also
+%% specify a default value or the default behavior when the value is
+%% omitted from its descriptor. For example, a package may specify
+%% that procedures related to the parameter are suspended when it
+%% value is omitted. A default value (but not procedures) may be
+%% specified as provisionable.
+%%
+%% Description:
+%%
+%%
+%% 12.3 Lists
+%%
+%% Possible values for parameters include enumerations. Enumerations
+%% may be defined in a list. It is recommended that the list be IANA
+%% registered so that packages that extend the list can be defined
+%% without concern for conflicting names.
+%%
+%%
+%% 12.4 Identifiers
+%%
+%% Identifiers in text encoding shall be strings of up to 64 characters,
+%% containing no spaces, starting with an alphabetic character and
+%% consisting of alphanumeric characters and/or digits, and possibly
+%% including the special character underscore ("_").
+%%
+%% Identifiers in binary encoding are 2 octets long.
+%%
+%% Both text and binary values shall be specified for each identifier,
+%% including identifiers used as values in enumerated types.
+%%
+%%
+%% 12.5 Package registration
+%%
+%% A package can be registered with IANA for interoperability reasons.
+%% See clause 13 for IANA Considerations.
+%%
+%%----------------------------------------------------------------------
+
+capabilities() ->
+ [{P, capabilities(P)} || P <- packages()].
+
+%% -record(property, {name, type, values, defined_in, characteristics}).
+
+%%----------------------------------------------------------------------
+%% List all known packages
+%% 'native' and 'all' are not real packages
+%%----------------------------------------------------------------------
+
+packages() ->
+ [
+ "g", % Generic
+ "root", % Base Root Package
+ "tonegen", % Tone Generator Package
+ "tonedet", % Tone Detection Package
+ "dg", % Basic DTMF Generator Package
+ "dd", % DTMF detection Package
+ "cg", % Call Progress Tones Generator Package
+ "cd", % Call Progress Tones Detection Package
+ "al", % Analog Line Supervision Package
+ "ct", % Basic Continuity Package
+ "nt", % Network Package
+ "rtp", % RTP Package
+ "swb", % SwitchBoard Package
+ "tdmc", % TDM Circuit Package
+ "" % Native pseudo package
+ ].
+
+%%----------------------------------------------------------------------
+%% List all matching capabilities
+%%----------------------------------------------------------------------
+
+capabilities(Package) ->
+ case Package of
+ "g" -> capabilities_g();
+ "root" -> capabilities_root();
+ "tonegen" -> capabilities_tonegen();
+ "tonedet" -> capabilities_tonedet();
+ "dg" -> capabilities_dg();
+ "dd" -> capabilities_dd();
+ "cg" -> capabilities_cg();
+ "cd" -> capabilities_cd();
+ "al" -> capabilities_al();
+ "ct" -> capabilities_ct();
+ "nt" -> capabilities_nt();
+ "rtp" -> capabilities_rtp();
+ "swb" -> capabilities_swb();
+ "tdmc" -> capabilities_tdmc();
+ "" -> capabilities_native()
+ end.
+
+%%----------------------------------------------------------------------
+%% Decode package name to internal form
+%% Scope ::= property | event | signal | statistics
+%%----------------------------------------------------------------------
+
+decode(mid, Package) ->
+ decode_mid(Package);
+decode(package, Package) ->
+ decode_package(Package);
+decode(profile, Package) ->
+ decode_profile(Package);
+decode(dialplan, Dialplan) ->
+ decode_dialplan(Dialplan);
+decode(Scope, [A, B | Item]) when is_atom(Scope) ->
+ ?d("decode(~p) -> entry with"
+ "~n A: ~p"
+ "~n B: ~p"
+ "~n Item: ~p", [Scope, A, B, Item]),
+ case decode_package([A, B]) of
+ "" ->
+ ?d("decode -> \"no\" package",[]),
+ decode_item(Scope, [A, B], Item);
+ Package ->
+ ?d("decode -> Package: ~p", [Package]),
+ Package ++ "/" ++ decode_item(Scope, [A, B], Item)
+ end;
+decode({Scope, [A, B | Item]}, SubItem) when is_atom(Scope) ->
+ ?d("decode(~p) -> entry with"
+ "~n A: ~p"
+ "~n B: ~p"
+ "~n Item: ~p"
+ "~n SubItem: ~p", [Scope, A, B, Item, SubItem]),
+ decode_item({Scope, Item}, [A, B], SubItem).
+
+decode_item(Scope, [A, B], Item) ->
+ ?d("decode_item -> entry",[]),
+ case A of
+ 16#00 ->
+ case B of
+ 16#01 -> decode_g(Scope, Item);
+ 16#02 -> decode_root(Scope, Item);
+ 16#03 -> decode_tonegen(Scope, Item);
+ 16#04 -> decode_tonedet(Scope, Item);
+ 16#05 -> decode_dg(Scope, Item);
+ 16#06 -> decode_dd(Scope, Item);
+ 16#07 -> decode_cg(Scope, Item);
+ 16#08 -> decode_cd(Scope, Item);
+ 16#09 -> decode_al(Scope, Item);
+ 16#0a -> decode_ct(Scope, Item);
+ 16#0b -> decode_nt(Scope, Item);
+ 16#0c -> decode_rtp(Scope, Item);
+ 16#0d -> decode_tdmc(Scope, Item);
+ 16#00 -> decode_native(Scope, Item)
+ end;
+ 16#fe ->
+ case B of
+ %% Proprietary extension
+ 16#fe -> decode_swb(Scope, Item)
+ end;
+ 16#ff ->
+ case B of
+ 16#ff when Item =:= [16#ff, 16#ff] -> "*"
+ end
+ end.
+
+decode_package(Package) ->
+ ?d("decode_package -> entry with"
+ "~n Package: ~p", [Package]),
+ [A, B] = Package,
+ case A of
+ 16#00 ->
+ case B of
+ 16#01 -> "g";
+ 16#02 -> "root";
+ 16#03 -> "tonegen";
+ 16#04 -> "tonedet";
+ 16#05 -> "dg";
+ 16#06 -> "dd";
+ 16#07 -> "cg";
+ 16#08 -> "cd";
+ 16#09 -> "al";
+ 16#0a -> "ct";
+ 16#0b -> "nt";
+ 16#0c -> "rtp";
+ 16#0d -> "tdmc";
+ 16#00 -> ""
+ end;
+ 16#fe ->
+ case B of
+ 16#fe -> "swb"
+ end;
+ 16#ff ->
+ case B of
+ 16#ff -> "*"
+ end
+ end.
+
+decode_profile([A, B]) ->
+ case A of
+ 16#00 ->
+ case B of
+ 16#fe -> "resgw";
+ _ -> "profile" ++ [A + $0, B + $0]
+ end;
+ _ ->
+ "profile" ++ [A + $0, B + $0]
+ end.
+
+decode_dialplan([A, B]) ->
+ "dialplan" ++ [A + $0, B + $0].
+
+decode_mid(Mid) ->
+ case Mid of
+ {domainName, DN} ->
+ Lower = to_lower(DN#'DomainName'.name),
+ {domainName, DN#'DomainName'{name = Lower}};
+ {deviceName, PathName} ->
+ Lower = to_lower(PathName),
+ {deviceName, Lower};
+ Other ->
+ Other
+ end.
+
+to_lower(Chars) ->
+ [?LOWER(Char) || Char <- Chars].
+
+%%----------------------------------------------------------------------
+%% Encode package name from internal form
+%% Scope ::= property | event | signal | statistics
+%%----------------------------------------------------------------------
+
+encode(mid, Package) ->
+ encode_mid(Package);
+encode(package, Package) ->
+ encode_package(Package);
+encode(profile, Profile) ->
+ encode_profile(Profile);
+encode(dialplan, Dialplan) ->
+ encode_dialplan(Dialplan);
+encode(Scope, PackageItem) when is_atom(Scope) ->
+ ?d("encode(~p) -> entry with"
+ "~n PackageItem: ~p", [Scope, PackageItem]),
+ case string:tokens(PackageItem, [$/]) of
+ [Package, Item] ->
+ ?d("encode -> "
+ "~n Package: ~p"
+ "~n Item: ~p", [Package, Item]),
+ encode_package(Package) ++ encode_item(Scope, Package, Item);
+ [Item] ->
+ ?d("encode -> Item: ~p", [Item]),
+ [16#00, 16#00 | encode_native(Scope, Item)]
+ end;
+encode({Scope, PackageItem}, SubItem) when is_atom(Scope) ->
+ ?d("encode(~p) -> entry with"
+ "~n PackageItem: ~p"
+ "~n SubItem: ~p", [Scope, PackageItem, SubItem]),
+ case string:tokens(PackageItem, [$/]) of
+ [Package, Item] ->
+ ?d("encode -> "
+ "~n Package: ~p"
+ "~n Item: ~p", [Package, Item]),
+ encode_item({Scope, Item}, Package, SubItem);
+ [_Item] ->
+ ?d("encode -> _Item: ~p", [_Item]),
+ encode_native(Scope, SubItem)
+ end.
+
+encode_item(_Scope, _Package, "*") ->
+ [16#ff, 16#ff];
+encode_item(Scope, Package, Item) ->
+ ?d("encode_item(~s) -> entry", [Package]),
+ case Package of
+ "g" -> encode_g(Scope, Item);
+ "root" -> encode_root(Scope, Item);
+ "tonegen" -> encode_tonegen(Scope, Item);
+ "tonedet" -> encode_tonedet(Scope, Item);
+ "dg" -> encode_dg(Scope, Item);
+ "dd" -> encode_dd(Scope, Item);
+ "cg" -> encode_cg(Scope, Item);
+ "cd" -> encode_cd(Scope, Item);
+ "al" -> encode_al(Scope, Item);
+ "ct" -> encode_ct(Scope, Item);
+ "nt" -> encode_nt(Scope, Item);
+ "rtp" -> encode_rtp(Scope, Item);
+ "tdmc" -> encode_tdmc(Scope, Item);
+ "swb" -> encode_swb(Scope, Item)
+ end.
+
+encode_package(Package) ->
+ case Package of
+ "g" -> [16#00, 16#01];
+ "root" -> [16#00, 16#02];
+ "tonegen" -> [16#00, 16#03];
+ "tonedet" -> [16#00, 16#04];
+ "dg" -> [16#00, 16#05];
+ "dd" -> [16#00, 16#06];
+ "cg" -> [16#00, 16#07];
+ "cd" -> [16#00, 16#08];
+ "al" -> [16#00, 16#09];
+ "ct" -> [16#00, 16#0a];
+ "nt" -> [16#00, 16#0b];
+ "rtp" -> [16#00, 16#0c];
+ "tdmc" -> [16#00, 16#0d];
+ "" -> [16#00, 16#00];
+ "*" -> [16#ff, 16#ff];
+ "swb" -> [16#fe, 16#fe]
+ end.
+
+encode_profile(Profile) ->
+ case Profile of
+ "resgw" ->
+ [16#00, 16#fe];
+ [$p, $r, $o, $f, $i, $l, $e | Name] ->
+ case Name of
+ [A, B] -> [A - $0, B - $0];
+ [B] -> [0, B - $0];
+ [] -> [0, 0]
+ end
+ end.
+
+encode_dialplan(Dialplan) ->
+ case Dialplan of
+ [$d, $i, $a, $l, $p, $l, $a, $n | Name] ->
+ case Name of
+ [A, B] -> [A - $0, B - $0];
+ [B] -> [0, B - $0];
+ [] -> [0, 0]
+ end
+ end.
+
+encode_mid(Mid) ->
+ Mid.
+
+
+%%----------------------------------------------------------------------
+%% Name: g - Generic
+%% Version: 1
+%% Extends: None
+%% Purpose: Generic package for commonly encountered items
+%%----------------------------------------------------------------------
+
+capabilities_g() ->
+ [
+ {event, "cause"},
+ {event, "sc"}
+ ].
+
+encode_g(event, Item) ->
+ case Item of
+ "cause" -> [16#00, 16#01];
+ "sc" -> [16#00, 16#02]
+ end;
+
+encode_g({event_parameter, Item}, SubItem) ->
+ case Item of
+ "cause" ->
+ case SubItem of
+ "Generalcause" -> [16#00, 16#01];
+ "Failurecause" -> [16#00, 16#02]
+ end;
+ "sc" ->
+ case SubItem of
+ "SigID" -> [16#00, 16#01];
+ "Meth" -> [16#00, 16#02];
+ "SLID" -> [16#00, 16#03]
+ end
+ end.
+
+decode_g(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "cause";
+ [16#00, 16#02] -> "sc"
+ end;
+
+decode_g({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event: cause
+ case SubItem of
+ [16#00, 16#01] -> "Generalcause";
+ [16#00, 16#02] -> "Failurecause"
+ end;
+
+ [16#00, 16#02] -> % Event: sc
+ case SubItem of
+ [16#00, 16#01] -> "SigID";
+ [16#00, 16#02] -> "Meth";
+ [16#00, 16#03] -> "SLID"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: root - Base Root Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines Gateway wide properties.
+%%----------------------------------------------------------------------
+
+capabilities_root() ->
+ [
+ {property, "maxNumberOfContexts"},
+ {property, "maxTerminationsPerContext"},
+ {property, "normalMGExecutionTime"},
+ {property, "normalMGCExecutionTime"},
+ {property, "MGProvisionalResponseTimerValue"},
+ {property, "MGCProvisionalResponseTimerValue"}
+ ].
+
+encode_root(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ "maxNumberOfContexts" -> [16#00, 16#01];
+ "maxTerminationsPerContext" -> [16#00, 16#02];
+ "normalMGExecutionTime" -> [16#00, 16#03];
+ "normalMGCExecutionTime" -> [16#00, 16#04];
+ "MGProvisionalResponseTimerValue" -> [16#00, 16#05];
+ "MGCProvisionalResponseTimerValue" -> [16#00, 16#06]
+ end
+ end.
+
+decode_root(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ [16#00, 16#01] -> "maxNumberOfContexts";
+ [16#00, 16#02] -> "maxTerminationsPerContext";
+ [16#00, 16#03] -> "normalMGExecutionTime";
+ [16#00, 16#04] -> "normalMGCExecutionTime";
+ [16#00, 16#05] -> "MGProvisionalResponseTimerValue";
+ [16#00, 16#06] -> "MGCProvisionalResponseTimerValue"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tonegen - Tone Generator Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines signals to generate audio tones.
+%% This package does not specify parameter values. It is
+%% intended to be extendable. Generally, tones are defined
+%% as an individual signal with a parameter, ind,
+%% representing "interdigit" time delay, and a tone id to
+%% be used with playtones. A tone id should be kept
+%% consistent with any tone generation for the same tone.
+%% MGs are expected to be provisioned with the characteristics
+%% of appropriate tones for the country in which the MG is located.
+%%----------------------------------------------------------------------
+
+capabilities_tonegen() ->
+ [
+ {signal, "pt"}
+ ].
+
+encode_tonegen(signal, Item) ->
+ case Item of
+ "pt" -> [16#00, 16#01]
+ end;
+
+encode_tonegen({signal_parameter, Item}, SubItem) ->
+ case Item of
+ "pt" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "ind" -> [16#00, 16#02]
+ end
+ end.
+
+decode_tonegen(signal, Item) ->
+ case Item of
+ [16#00, 16#01] -> "pt"
+ end;
+
+decode_tonegen({signal_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event: pt
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#02] -> "ind"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tonedet - Tone Detection Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This Package defines events for audio tone detection.
+%% Tones are selected by name (tone id). MGs are expected
+%% to be provisioned with the characteristics of appropriate
+%% tones for the country in which the MG is located.
+%%
+%% This package does not specify parameter values.
+%% It is intended to be extendable.
+%%----------------------------------------------------------------------
+
+capabilities_tonedet() ->
+ [
+ {event, "std"},
+ {event, "etd"},
+ {event, "ltd"}
+ ].
+
+encode_tonedet(event, Item) ->
+ case Item of
+ "std" -> [16#00, 16#01];
+ "etd" -> [16#00, 16#02];
+ "ltd" -> [16#00, 16#03]
+ end;
+
+encode_tonedet({event_parameter, Item}, SubItem) ->
+ case Item of
+ "std" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "tid" -> [16#00, 16#03]
+ end;
+ "etd" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "tid" -> [16#00, 16#03];
+ "dur" -> [16#00, 16#02]
+ end;
+ "ltd" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "dur" -> [16#00, 16#02];
+ "tid" -> [16#00, 16#03]
+ end
+ end.
+
+decode_tonedet(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "std";
+ [16#00, 16#02] -> "etd";
+ [16#00, 16#03] -> "ltd"
+ end;
+
+decode_tonedet({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event std
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#03] -> "tid"
+ end;
+ [16#00, 16#02] -> % Event etd
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#03] -> "tid";
+ [16#00, 16#02] -> "dur"
+ end;
+ [16#00, 16#03] -> % Event ltd
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#02] -> "dur";
+ [16#00, 16#03] -> "tid"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: dg - Basic DTMF Generator Package
+%% Version: 1
+%% Extends: tonegen version 1
+%% Purpose: This package defines the basic DTMF tones as signals and
+%% extends the allowed values of parameter tl of playtone
+%% in tonegen.
+%%----------------------------------------------------------------------
+
+capabilities_dg() ->
+ [
+ {signal, "d0"},
+ {signal, "d1"},
+ {signal, "d2"},
+ {signal, "d3"},
+ {signal, "d4"},
+ {signal, "d5"},
+ {signal, "d6"},
+ {signal, "d7"},
+ {signal, "d8"},
+ {signal, "d9"},
+ {signal, "ds"},
+ {signal, "do"},
+ {signal, "da"},
+ {signal, "db"},
+ {signal, "dc"},
+ {signal, "dd"}
+ ].
+
+encode_dg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ "d0" -> [16#00, 16#10];
+ "d1" -> [16#00, 16#11];
+ "d2" -> [16#00, 16#12];
+ "d3" -> [16#00, 16#13];
+ "d4" -> [16#00, 16#14];
+ "d5" -> [16#00, 16#15];
+ "d6" -> [16#00, 16#16];
+ "d7" -> [16#00, 16#17];
+ "d8" -> [16#00, 16#18];
+ "d9" -> [16#00, 16#19];
+ "ds" -> [16#00, 16#20];
+ "do" -> [16#00, 16#21];
+ "da" -> [16#00, 16#1a];
+ "db" -> [16#00, 16#1b];
+ "dc" -> [16#00, 16#1c];
+ "dd" -> [16#00, 16#1d]
+ end
+ end.
+
+decode_dg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ [16#00, 16#10] -> "d0";
+ [16#00, 16#11] -> "d1";
+ [16#00, 16#12] -> "d2";
+ [16#00, 16#13] -> "d3";
+ [16#00, 16#14] -> "d4";
+ [16#00, 16#15] -> "d5";
+ [16#00, 16#16] -> "d6";
+ [16#00, 16#17] -> "d7";
+ [16#00, 16#18] -> "d8";
+ [16#00, 16#19] -> "d9";
+ [16#00, 16#20] -> "ds";
+ [16#00, 16#21] -> "do";
+ [16#00, 16#1a] -> "da";
+ [16#00, 16#1b] -> "db";
+ [16#00, 16#1c] -> "dc";
+ [16#00, 16#1d] -> "dd"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: dd - DTMF detection Package
+%% Version: 1
+%% Extends: tonedet version 1
+%% Purpose: This package defines the basic DTMF tones detection.
+%% Tones are selected by name (tone id). MGs are expected
+%% to be provisioned with the characteristics of appropriate
+%% tones for the country in which the MG is located.
+%%
+%% This package does not specify parameter values.
+%% It is intended to be extendable.
+%%
+%% Additional tone id values are all tone ids described in package dg
+%% (basic DTMF generator package).
+%%
+%% The following table maps DTMF events to digit map symbols as described
+%% in section 7.1.14.
+%%
+%% _________________________________
+%% | DTMF Event | Symbol |
+%% | d0 | "0" |
+%% | d1 | "1" |
+%% | d2 | "2" |
+%% | d3 | "3" |
+%% | d4 | "4" |
+%% | d5 | "5" |
+%% | d6 | "6" |
+%% | d7 | "7" |
+%% | d8 | "8" |
+%% | d9 | "9" |
+%% | da | "A" or "a"|
+%% | db | "B" or "b"|
+%% | dc | "C" or "c"|
+%% | dd | "D" or "d"|
+%% | ds | "E" or "e"|
+%% | do | "F" or "f"|
+%% |___________________|____________|
+%%
+%%----------------------------------------------------------------------
+
+capabilities_dd() ->
+ [
+ {event, "ce"}
+ ].
+
+encode_dd(event, Item) ->
+ case Item of
+ "ce" -> [16#00, 16#04]
+ end;
+
+encode_dd({event_parameter, Item}, SubItem) ->
+ case Item of
+ "ce" ->
+ case SubItem of
+ "ds" -> [16#00, 16#01];
+ "Meth" -> [16#00, 16#03]
+ end
+ end.
+
+decode_dd(event, Item) ->
+ case Item of
+ [16#00, 16#04] -> "ce"
+ end;
+
+decode_dd({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#04] -> % Event ce
+ case SubItem of
+ [16#00, 16#01] -> "ds";
+ [16#00, 16#03] -> "Meth"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: cg - Call Progress Tones Generator Package
+%% Version: 1
+%% Extends: tonegen version 1
+%% Purpose: This package defines the basic call progress tones as signals
+%% and extends the allowed values of the tl parameter of
+%% playtone in tonegen.
+%%----------------------------------------------------------------------
+
+capabilities_cg() ->
+ [
+ {signal, "dt"},
+ {signal, "rt"},
+ {signal, "bt"},
+ {signal, "ct"},
+ {signal, "sit"},
+ {signal, "wt"},
+ {signal, "prt"},
+ {signal, "cw"},
+ {signal, "cr"}
+ ].
+
+
+encode_cg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ "dt" -> [16#00, 16#30];
+ "rt" -> [16#00, 16#31];
+ "bt" -> [16#00, 16#32];
+ "ct" -> [16#00, 16#33];
+ "sit" -> [16#00, 16#34];
+ "wt" -> [16#00, 16#35];
+ "prt" -> [16#00, 16#36];
+ "cw" -> [16#00, 16#37];
+ "cr" -> [16#00, 16#38]
+ end
+ end.
+
+decode_cg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ [16#00, 16#30] -> "dt";
+ [16#00, 16#31] -> "rt";
+ [16#00, 16#32] -> "bt";
+ [16#00, 16#33] -> "ct";
+ [16#00, 16#34] -> "sit";
+ [16#00, 16#35] -> "wt";
+ [16#00, 16#36] -> "prt";
+ [16#00, 16#37] -> "cw";
+ [16#00, 16#38] -> "cr"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: cd - Call Progress Tones Detection Package
+%% Version: 1
+%% Extends: tonedet version 1
+%% Purpose: This package defines the basic call progress detection tones.
+%% This Package extends the possible values of tone id
+%% in the "start tone detected", "end tone detected" and
+%% "long tone detected" events.
+%% Additional values
+%% tone id values are defined for start tone detected,
+%% end tone detected and long tone detected with
+%% the same values as those in package cg (call
+%% progress tones generation package).
+%%
+%% The required set of tone ids corresponds to Recommendation E.180/Q.35
+%% [ITU-T Recommendation E.180/Q.35 (1998)]. See Recommendation E.180/Q.35
+%% for definition of the meanings of these tones.
+%%----------------------------------------------------------------------
+
+capabilities_cd() ->
+ [
+ {event, "dt"},
+ {event, "rt"},
+ {event, "bt"},
+ {event, "ct"},
+ {event, "sit"},
+ {event, "wt"},
+ {event, "prt"},
+ {event, "cw"},
+ {event, "cr"}
+ ].
+
+
+encode_cd(Scope, Item) ->
+ case Scope of
+ event ->
+ case Item of
+ "dt" -> [16#00, 16#30];
+ "rt" -> [16#00, 16#31];
+ "bt" -> [16#00, 16#32];
+ "ct" -> [16#00, 16#33];
+ "sit"-> [16#00, 16#34];
+ "wt" -> [16#00, 16#35];
+ "prt"-> [16#00, 16#36];
+ "cw" -> [16#00, 16#37];
+ "cr" -> [16#00, 16#38]
+ end
+ end.
+
+decode_cd(Scope, Item) ->
+ case Scope of
+ event ->
+ case Item of
+ [16#00, 16#30] -> "dt";
+ [16#00, 16#31] -> "rt";
+ [16#00, 16#32] -> "bt";
+ [16#00, 16#33] -> "ct";
+ [16#00, 16#34] -> "sit";
+ [16#00, 16#35] -> "wt";
+ [16#00, 16#36] -> "prt";
+ [16#00, 16#37] -> "cw";
+ [16#00, 16#38] -> "cr"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: al - Analog Line Supervision Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines events and signals for an analog line.
+%%----------------------------------------------------------------------
+
+capabilities_al() ->
+ [
+ {event, "on"},
+ {event, "of"},
+ {event, "fl"},
+ {signal, "ri"}
+ ].
+
+encode_al(event, Item) ->
+ ?d("encode_al(event) -> entry with"
+ "~n Item: ~p", [Item]),
+ case Item of
+ "on" -> [16#00, 16#04];
+ "of" -> [16#00, 16#05];
+ "fl" -> [16#00, 16#06]
+ end;
+
+encode_al({event_parameter, Item}, SubItem) ->
+ ?d("encode_al({event_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ "on" ->
+ case SubItem of
+ "strict" -> [16#00, 16#01];
+ "init" -> [16#00, 16#02]
+ end;
+ "of" ->
+ case SubItem of
+ "strict" -> [16#00, 16#01];
+ "init" -> [16#00, 16#02]
+ end;
+ "fl" ->
+ case SubItem of
+ "mindur" -> [16#00, 16#04];
+ "maxdur" -> [16#00, 16#05]
+ end
+ end;
+
+encode_al(signal, Item) ->
+ ?d("encode_al(signal) -> entry with"
+ "~n Item: ~p", [Item]),
+ case Item of
+ "ri" -> [16#00, 16#02]
+ end;
+
+encode_al({signal_parameter, Item}, SubItem) ->
+ ?d("encode_al({signal_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ "ri" ->
+ case SubItem of
+ "cad" -> [16#00, 16#06];
+ "freq" -> [16#00, 16#07]
+ end
+ end.
+
+decode_al(event, SubItem) ->
+ ?d("decode_al(event) -> entry with"
+ "~n SubItem: ~p", [SubItem]),
+ case SubItem of
+ [16#00, 16#04] -> "on";
+ [16#00, 16#05] -> "of";
+ [16#00, 16#06] -> "fl"
+ end;
+
+decode_al({event_parameter, Item}, SubItem) ->
+ ?d("decode_al({event_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ [16#00,16#04] -> %% Event: on
+ case SubItem of
+ [16#00, 16#01] -> "strict";
+ [16#00, 16#02] -> "init"
+ end;
+ [16#00,16#05] -> %% Event: of
+ case SubItem of
+ [16#00, 16#01] -> "strict";
+ [16#00, 16#02] -> "init"
+ end;
+ [16#00,16#06] -> %% Event: fl
+ case SubItem of
+ [16#00, 16#04] -> "mindur";
+ [16#00, 16#05] -> "maxdur"
+ end
+ end;
+
+decode_al(signal, SubItem) ->
+ ?d("decode_al(signal) -> entry with"
+ "~n SubItem: ~p", [SubItem]),
+ case SubItem of
+ [16#00, 16#02] -> "ri"
+ end;
+
+decode_al({signal_parameter, Item}, SubItem) ->
+ ?d("decode_al({signal_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ [16#00,16#02] -> %% Event: ri
+ case SubItem of
+ [16#00, 16#06] -> "cad";
+ [16#00, 16#07] -> "freq"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: ct - Basic Continuity Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines events and signals for continuity test.
+%% The continuity test includes provision of either a loopback
+%% or transceiver functionality.
+%%----------------------------------------------------------------------
+
+capabilities_ct() ->
+ [
+ {event, "cmp"},
+ {signal, "ct"},
+ {signal, "rsp"}
+ ].
+
+encode_ct(event, Item) ->
+ case Item of
+ "cmp" -> [16#00, 16#05]
+ end;
+encode_ct({event_parameter, Item}, SubItem) ->
+ case Item of
+ "cmp" ->
+ case SubItem of
+ "res" -> [16#00, 16#08]
+ end
+ end;
+encode_ct(signal, Item) ->
+ case Item of
+ "ct" -> [16#00, 16#03];
+ "rsp" -> [16#00, 16#04]
+ end.
+
+decode_ct(event, Item) ->
+ case Item of
+ [16#00, 16#05] -> "cmp"
+ end;
+decode_ct({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#05] -> % Event cmp
+ case SubItem of
+ [16#00, 16#08] -> "res"
+ end
+ end;
+decode_ct(signal, Item) ->
+ case Item of
+ [16#00, 16#03] -> "ct";
+ [16#00, 16#04] -> "rsp"
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: nt - Network Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines properties of network terminations
+%% independent of network type.
+%%----------------------------------------------------------------------
+
+capabilities_nt() ->
+ [
+ {property, "jit"},
+ {event, "netfail"},
+ {event, "qualert"},
+ {statistics, "dur"},
+ {statistics, "os"},
+ {statistics, "or"}
+ ].
+
+encode_nt(property, Item) ->
+ case Item of
+ "jit" -> [16#00, 16#07]
+ end;
+encode_nt(event, Item) ->
+ case Item of
+ "netfail" -> [16#00, 16#05];
+ "qualert" -> [16#00, 16#06]
+ end;
+encode_nt({event_parameter, Item}, SubItem) ->
+ case Item of
+ "netfail" ->
+ case SubItem of
+ "cs" -> [16#00, 16#01]
+ end;
+ "qualert" ->
+ case SubItem of
+ "th" -> [16#00, 16#01]
+ end
+ end;
+encode_nt(statistics, Item) ->
+ case Item of
+ "dur" -> [16#00, 16#01];
+ "os" -> [16#00, 16#02];
+ "or" -> [16#00, 16#03]
+ end.
+
+decode_nt(property, Item) ->
+ case Item of
+ [16#00, 16#07] -> "jit"
+ end;
+decode_nt(event, Item) ->
+ case Item of
+ [16#00, 16#05] -> "netfail";
+ [16#00, 16#06] -> "qualert"
+ end;
+decode_nt({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#05] -> % Event netfail
+ case SubItem of
+ [16#00, 16#01] -> "cs"
+ end;
+ [16#00, 16#06] -> % Event qualert
+ case Item of
+ [16#00, 16#01] -> "th"
+ end
+ end;
+decode_nt(statistics, Item) ->
+ case Item of
+ [16#00, 16#01] -> "dur";
+ [16#00, 16#02] -> "os";
+ [16#00, 16#03] -> "or"
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: rtp - RTP Package
+%% Version: 1
+%% Extends: nt version 1
+%% Purpose: This package is used to support packet based multimedia
+%% data transfer by means of the Real-time Transport Protocol
+%% (RTP) [RFC 1889].
+%%----------------------------------------------------------------------
+
+capabilities_rtp() ->
+ [
+ {event, "pltrans"},
+ {statistics, "ps"},
+ {statistics, "pr"},
+ {statistics, "pl"},
+ {statistics, "jit"},
+ {statistics, "delay"}
+ ].
+
+encode_rtp(event, Item) ->
+ case Item of
+ "pltrans" -> [16#00, 16#01]
+ end;
+encode_rtp({event_parameter, Item}, SubItem) ->
+ case Item of
+ "pltrans" ->
+ case SubItem of
+ "rtppltype" -> [16#00, 16#01]
+ end
+ end;
+encode_rtp(statistics, Item) ->
+ case Item of
+ "ps" -> [16#00, 16#04];
+ "pr" -> [16#00, 16#05];
+ "pl" -> [16#00, 16#06];
+ "jit" -> [16#00, 16#07];
+ "delay" -> [16#00, 16#08]
+ end.
+
+decode_rtp(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "pltrans"
+ end;
+decode_rtp({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event pltrans
+ case SubItem of
+ [16#00, 16#01] -> "rtppltype"
+ end
+ end;
+decode_rtp(statistics, Item) ->
+ case Item of
+ [16#00, 16#04] -> "ps";
+ [16#00, 16#05] -> "pr";
+ [16#00, 16#06] -> "pl";
+ [16#00, 16#07] -> "jit";
+ [16#00, 16#08] -> "delay"
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tdmc - TDM Circuit Package
+%% Version: 1
+%% Extends: nt version 1
+%% Purpose: This package is used to support TDM circuit terminations.
+%%----------------------------------------------------------------------
+
+capabilities_tdmc() ->
+ [
+ {property, "ec"},
+ {property, "gain"}
+ ].
+
+encode_tdmc(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ "ec" -> [16#00, 16#08];
+ "gain" -> [16#00, 16#0a]
+ end
+ end.
+
+decode_tdmc(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ [16#00, 16#08] -> "ec";
+ [16#00, 16#0a] -> "gain"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: swb - SwitchBoard Package
+%% Version: 1
+%% Extends: none
+%% Purpose: This package is used to support SwitchBoard specials
+%%----------------------------------------------------------------------
+
+capabilities_swb() ->
+ [
+ {statistics, "fs"}, % Free slots
+ {statistics, "as"} % Allocated slots
+ ].
+
+encode_swb(Scope, Item) ->
+ case Scope of
+ statistics ->
+ case Item of
+ "fs" -> [16#00, 16#00];
+ "as" -> [16#00, 16#01]
+ end
+ end.
+
+decode_swb(Scope, Item) ->
+ case Scope of
+ statistics ->
+ case Item of
+ [16#00, 16#00] -> "fs";
+ [16#00, 16#01] -> "as"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: native - Pseudo package
+%% Version: 1
+%% Extends: None
+%% Purpose: Native tags for media stream properties
+%%
+%% Parameters for Local descriptors and Remote descriptors are
+%% specified as tag-value pairs if binary encoding is used for the
+%% protocol. This annex contains the property names (PropertyID), the
+%% tags (Property Tag), type of the property (Type) and the values
+%% (Value).Values presented in the Value field when the field contains
+%% references shall be regarded as "information". The reference
+%% contains the normative values. If a value field does not contain a
+%% reference then the values in that field can be considered as
+%% "normative".
+%%
+%% Tags are given as hexadecimal numbers in this annex. When setting
+%% the value of a property, a MGC may underspecify the value according
+%% to one of the mechanisms specified in section 7.1.1.
+%%
+%% For type "enumeration" the value is represented by the value in brack-
+%% ets, e.g., Send(0), Receive(1).
+%%----------------------------------------------------------------------
+%%
+%% C.6. IP
+%%
+%% ________________________________________________________________
+%% | PropertyID| Tag | Type | Value |
+%% | IPv4 | 6001 | 32 BITS | Ipv4Address |
+%% | IPv6 | 6002 | 128 BITS | IPv6 Address |
+%% | Port | 6003 | Unsigned Int| Port |
+%% | Porttype | 6004 | Enumerated | TCP(0),UDP(1),SCTP(2)|
+%% |___________|____________|______________|_______________________|
+%%
+%%
+%% C.11. SDP Equivalents
+%%
+%% ______________________________________________________________
+%% | PropertyID| Tag | Type | Value |
+%% | SDP_V | B001| STRING| Protocol Version |
+%% | SDP_O | B002| STRING| Owner-creator and session ID |
+%% | SDP_S | B003| STRING| Sesson name |
+%% | SDP_I | B004| STRING| Session identifier |
+%% | SDP_U | B005| STRING| URI of descriptor |
+%% | SDC_E | B006| STRING| email address |
+%% | SDP_P | B007| STRING| phone number |
+%% | SDP_C | B008| STRING| Connection information |
+%% | SDP_B | B009| STRING| Bandwidth Information |
+%% | SDP_Z | B00A| STRING| time zone adjustment |
+%% | SDP_K | B00B| STRING| Encryption Key |
+%% | SDP_A | B00C| STRING| Zero or more session attributes|
+%% | SDP_T | B00D| STRING| Active Session Time |
+%% | SDP_R | B00E| STRING| Zero or more repeat times |
+%% | SDP_M | B00F| STRING| Media name and transport addr |
+%% | | | | Reference: IETF RFC 2327 |
+%% |___________|______|________|_________________________________|
+%%
+%%----------------------------------------------------------------------
+
+capabilities_native() ->
+ [
+ %% C.6. IP
+ {property, "IPv4"},
+ {property, "IPv6"},
+ {property, "Port"},
+ {property, "Porttype"},
+
+ %% C.11. SDP Equivalents
+ {property, "v"},
+ {property, "o"},
+ {property, "s"},
+ {property, "i"},
+ {property, "u"},
+ {property, "e"},
+ {property, "p"},
+ {property, "c"},
+ {property, "b"},
+ {property, "z"},
+ {property, "k"},
+ {property, "a"},
+ {property, "t"},
+ {property, "r"},
+ {property, "m"}
+ ].
+
+encode_native(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ %% IP
+ "IPv4" -> [16#60, 16#01];
+ "IPv6" -> [16#60, 16#02];
+ "Port" -> [16#60, 16#03];
+ "Porttype" -> [16#60, 16#04];
+
+ %% SDP
+ "v" -> [16#b0, 16#01];
+ "o" -> [16#b0, 16#02];
+ "s" -> [16#b0, 16#03];
+ "i" -> [16#b0, 16#04];
+ "u" -> [16#b0, 16#05];
+ "e" -> [16#b0, 16#06];
+ "p" -> [16#b0, 16#07];
+ "c" -> [16#b0, 16#08];
+ "b" -> [16#b0, 16#09];
+ "z" -> [16#b0, 16#0a];
+ "k" -> [16#b0, 16#0b];
+ "a" -> [16#b0, 16#0c];
+ "t" -> [16#b0, 16#0d];
+ "r" -> [16#b0, 16#0e];
+ "m" -> [16#b0, 16#0f]
+ end
+ end.
+
+decode_native(Scope, [Type, Item]) ->
+ case Scope of
+ property ->
+ case Type of
+ 16#60 ->
+ case Item of
+ 16#01 -> "IPv4";
+ 16#02 -> "IPv6";
+ 16#03 -> "Port";
+ 16#04 -> "Porttype"
+ end;
+
+ 16#b0 ->
+ case Item of
+ 16#01 -> "v";
+ 16#02 -> "o";
+ 16#03 -> "s";
+ 16#04 -> "i";
+ 16#05 -> "u";
+ 16#06 -> "e";
+ 16#07 -> "p";
+ 16#08 -> "c";
+ 16#09 -> "b";
+ 16#0a -> "z";
+ 16#0b -> "k";
+ 16#0c -> "a";
+ 16#0d -> "t";
+ 16#0e -> "r";
+ 16#0f -> "m"
+ end
+ end
+ end.
+
+%% -------------------------------------------------------------------
+
+% error(Reason) ->
+% erlang:error(Reason).
+
diff --git a/lib/megaco/src/binary/megaco_binary_name_resolver_v2.erl b/lib/megaco/src/binary/megaco_binary_name_resolver_v2.erl
new file mode 100644
index 0000000000..53891a26f2
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_name_resolver_v2.erl
@@ -0,0 +1,1681 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Handle meta data about packages
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_name_resolver_v2).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+-include_lib("megaco/src/app/megaco_internal.hrl").
+
+-define(LOWER(Char),
+ if
+ Char >= $A, Char =< $Z ->
+ Char - ($A - $a);
+ true ->
+ Char
+ end).
+
+-export([packages/0,
+ capabilities/0,
+ capabilities/1,
+ decode_name/3,
+ encode_name/3
+ ]).
+
+encode_name(Config, term_id, TermId) ->
+ case megaco:encode_binary_term_id(Config, TermId) of
+ {ok, TermId2} ->
+ TermId2;
+ {error, _Reason} ->
+ exit({bad_term_id, TermId})
+ end;
+encode_name(_Config, Scope, Item) ->
+ ?d("encode_name(~p) -> entry with"
+ "~n Item: ~p", [Scope, Item]),
+ encode(Scope, Item).
+
+decode_name(Config, term_id, TermId) ->
+ case megaco:decode_binary_term_id(Config, TermId) of
+ {ok, TermId2} ->
+ TermId2;
+ {error, _Reason} ->
+ exit({bad_term_id, TermId})
+ end;
+decode_name(_Config, Scope, Item) ->
+ ?d("decode_name(~p) -> entry with"
+ "~n Item: ~p", [Scope, Item]),
+ decode(Scope, Item).
+
+%%----------------------------------------------------------------------
+%% 12.1.1 Package
+%%
+%% Overall description of the package, specifying:
+%%
+%% Package Name: only descriptive
+%%
+%% PackageID: is an identifier
+%%
+%% Description:
+%%
+%% Version:
+%%
+%% A new version of a package can only add additional Properties,
+%% Events, Signals, Statistics and new possible values for an existing
+%% parameter described in the original package. No deletions or
+%% modifications shall be allowed. A version is an integer in the range
+%% from 1 to 99.
+%%
+%% Designed to be extended only (Optional): Yes
+%%
+%% This indicates that the package has been expressly designed to be
+%% extended by others, not to be directly referenced. For example, the
+%% package may not have any function on its own or be nonsensical on its
+%% own. The MG SHOULD NOT publish this PackageID when reporting
+%% packages.
+%%
+%% Extends (Optional): existing package Descriptor
+%%
+%% A package may extend an existing package. The version of the original
+%% package must be specified. When a package extends another package it
+%% shall only add additional Properties, Events, Signals, Statistics and
+%% new possible values for an existing parameter described in the
+%% original package. An extended package shall not redefine or overload
+%% an identifier defined in the original package and packages it may
+%% have extended (multiple levels of extension). Hence, if package B
+%% version 1 extends package A version 1, version 2 of B will not be
+%% able to extend the A version 2 if A version 2 defines a name already
+%% in B version 1.
+%%
+%%
+%% 12.1.2 Properties
+%%
+%% Properties defined by the package, specifying:
+%%
+%% Property Name: only descriptive
+%%
+%% PropertyID: is an identifier
+%%
+%% Description:
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 string
+%%
+%% Octet String: A number of octets. See Annex A and Annex B.3
+%% for encoding
+%%
+%% Integer: 4 byte signed integer
+%%
+%% Double: 8 byte signed integer
+%%
+%% Character: unicode UTF-8 encoding of a single letter. Could be
+%% more than one octet.
+%%
+%% Enumeration: one of a list of possible unique values (see 12.3)
+%%
+%% Sub-list: a list of several values from a list. The type of
+%% sub-list SHALL also be specified. The type shall be chosen
+%% from the types specified in this section (with the exception of
+%% sub-list). For example, Type: sub-list of enumeration. The
+%% encoding of sub-lists is specified in Annexes A and B.3.
+%%
+%% Possible values:
+%%
+%% A package MUST specify either a specific set of values or a
+%% description of how values are determined. A package MUST also
+%% specify a default value or the default behaviour when the value is
+%% omitted from its descriptor. For example, a package may specify that
+%% procedures related to the property are suspended when it value is
+%% omitted. A default value (but not procedures) may be specified as
+%% provisionable.
+%%
+%% Defined in:
+%%
+%% Which H.248.1 descriptor the property is defined in. LocalControl is
+%% for stream dependent properties. TerminationState is for stream
+%% independent properties. These are expected to be the most common
+%% cases, but it is possible for properties to be defined in other
+%% descriptors.
+%%
+%% Characteristics: Read/Write or both, and (optionally), global:
+%%
+%% Indicates whether a property is read-only, or read-write, and if it
+%% is global. If Global is omitted, the property is not global. If a
+%% property is declared as global, the value of the property is shared
+%% by all Terminations realizing the package.
+%%
+%%
+%% 12.1.3 Events
+%%
+%% Events defined by the package, specifying:
+%%
+%% Event name: only descriptive
+%%
+%% EventID: is an identifier
+%%
+%% Description:
+%%
+%% EventsDescriptor Parameters:
+%%
+%% Parameters used by the MGC to configure the event, and found in the
+%% EventsDescriptor. See 12.2.
+%%
+%% ObservedEventsDescriptor Parameters:
+%%
+%% Parameters returned to the MGC in Notify requests and in replies to
+%% command requests from the MGC that audit ObservedEventsDescriptor,
+%% and found in the ObservedEventsDescriptor. See 12.2.
+%%
+%%
+%% 12.1.4 Signals
+%%
+%% Signals defined by the package, specifying:
+%%
+%% Signal Name: only descriptive
+%%
+%% SignalID: is an identifier. SignalID is used in a
+%% SignalsDescriptor
+%%
+%% Description
+%%
+%% SignalType: one of:
+%%
+%% OO (On/Off)
+%%
+%% TO (TimeOut)
+%%
+%% BR (Brief)
+%%
+%% NOTE - SignalType may be defined such that it is dependent on the
+%% value of one or more parameters. The package MUST specify a default
+%% signal type. If the default type is TO, the package MUST specify a
+%% default duration which may be provisioned. A default duration is
+%% meaningless for BR.
+%%
+%% Duration: in hundredths of seconds
+%%
+%% Additional Parameters: see 12.2
+%%
+%%
+%% 12.1.5 Statistics
+%%
+%% Statistics defined by the package, specifying:
+%%
+%% Statistic name: only descriptive
+%%
+%% StatisticID: is an identifier
+%%
+%% StatisticID is used in a StatisticsDescriptor
+%%
+%% Description:
+%%
+%% Type: One of:
+%% Boolean
+%% String: UTF-8 string
+%% Octet String: A number of octets. See Annex A and B.3 for encoding
+%% Integer: 4 byte signed integer
+%% Double: 8 byte signed integer
+%% Character: Unicode UTF-8 encoding of a single letter.
+%% Could be more than one octet.
+%% Enumeration: One of a list of possible unique values (see 12.3)
+%% Sub-list: A list of several values from a list.
+%% The type of sub-list SHALL also be specified.
+%% The type shall be chosen from the types specified
+%% in this clause (with the exception of sub-list).
+%% For example, Type: sub-list of enumeration.
+%% The encoding of sub-lists is specified in
+%% Annex A and B.3.
+%% Possible Values:
+%% A package must indicate the unit of measure, e.g.,
+%% milliseconds, packets, either here or along with the type
+%% above, as well as indicating any restriction on the range.
+%%
+%%
+%% 12.1.6 Procedures
+%%
+%% Additional guidance on the use of the package.
+%%
+%%
+%% 12.2 Guidelines to defining Parameters to Events and Signals
+%%
+%% Parameter Name: only descriptive
+%%
+%% ParameterID: is an identifier. The textual ParameterID of
+%% parameters to Events and Signals shall not start with "EPA" and
+%% "SPA", respectively. The textual ParameterID shall also not be
+%% "ST", "Stream", "SY", "SignalType", "DR", "Duration", "NC",
+%% "NotifyCompletion", "KA", "Keepactive", "EB", "Embed", "DM" or
+%% "DigitMap".
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 octet string
+%%
+%% Octet String: A number of octets. See Annex A and Annex B.3
+%% for encoding
+%%
+%% Integer: 4-octet signed integer
+%%
+%% Double: 8-octet signed integer
+%%
+%% Character: unicode UTF-8 encoding of a single letter. Could be
+%% more than one octet.
+%%
+%% Enumeration: one of a list of possible unique values (see 12.3)
+%%
+%% Sub-list: a list of several values from a list (not supported
+%% for statistics). The type of sub-list SHALL also be specified.
+%% The type shall be chosen from the types specified in this
+%% section (with the exception of sub-list). For example, Type:
+%% sub-list of enumeration. The encoding of sub-lists is
+%% specified in Annexes A and B.3.
+%%
+%% Possible values:
+%%
+%% A package MUST specify either a specific set of values or a
+%% description of how values are determined. A package MUST also
+%% specify a default value or the default behavior when the value is
+%% omitted from its descriptor. For example, a package may specify that
+%% procedures related to the parameter are suspended when it value is
+%% omitted. A default value (but not procedures) may be specified as
+%% provisionable.
+%%
+%% Description:
+%%
+%%
+%% 12.3 Lists
+%%
+%% Possible values for parameters include enumerations. Enumerations may
+%% be defined in a list. It is recommended that the list be IANA
+%% registered so that packages that extend the list can be defined
+%% without concern for conflicting names.
+%%
+%%
+%% 12.4 Identifiers
+%%
+%% Identifiers in text encoding shall be strings of up to 64 characters,
+%% containing no spaces, starting with an alphabetic character and
+%% consisting of alphanumeric characters and/or digits, and possibly
+%% including the special character underscore ("_").
+%%
+%% Identifiers in binary encoding are 2 octets long.
+%%
+%% Both text and binary values shall be specified for each identifier,
+%% including identifiers used as values in enumerated types.
+%%
+%%
+%% 12.5 Package registration
+%%
+%% A package can be registered with IANA for interoperability reasons.
+%% See clause 14 for IANA considerations.
+%%
+%%----------------------------------------------------------------------
+
+capabilities() ->
+ [{P, capabilities(P)} || P <- packages()].
+
+%% -record(property, {name, type, values, defined_in, characteristics}).
+
+%%----------------------------------------------------------------------
+%% List all known packages
+%% 'native' and 'all' are not real packages
+%%----------------------------------------------------------------------
+
+packages() ->
+ [
+ "g", % Generic
+ "root", % Base Root Package
+ "tonegen", % Tone Generator Package
+ "tonedet", % Tone Detection Package
+ "dg", % Basic DTMF Generator Package
+ "dd", % DTMF detection Package
+ "cg", % Call Progress Tones Generator Package
+ "cd", % Call Progress Tones Detection Package
+ "al", % Analog Line Supervision Package
+ "ct", % Basic Continuity Package
+ "nt", % Network Package
+ "rtp", % RTP Package
+ "swb", % SwitchBoard Package
+ "tdmc", % TDM Circuit Package
+ "" % Native pseudo package
+ ].
+
+%%----------------------------------------------------------------------
+%% List all matching capabilities
+%%----------------------------------------------------------------------
+
+capabilities(Package) ->
+ case Package of
+ "g" -> capabilities_g();
+ "root" -> capabilities_root();
+ "tonegen" -> capabilities_tonegen();
+ "tonedet" -> capabilities_tonedet();
+ "dg" -> capabilities_dg();
+ "dd" -> capabilities_dd();
+ "cg" -> capabilities_cg();
+ "cd" -> capabilities_cd();
+ "al" -> capabilities_al();
+ "ct" -> capabilities_ct();
+ "nt" -> capabilities_nt();
+ "rtp" -> capabilities_rtp();
+ "swb" -> capabilities_swb();
+ "tdmc" -> capabilities_tdmc();
+ "" -> capabilities_native()
+ end.
+
+%%----------------------------------------------------------------------
+%% Decode package name to internal form
+%% Scope ::= property | event | signal | statistics
+%%----------------------------------------------------------------------
+
+decode(mid, Package) ->
+ decode_mid(Package);
+decode(package, Package) ->
+ decode_package(Package);
+decode(profile, Package) ->
+ decode_profile(Package);
+decode(dialplan, Dialplan) ->
+ decode_dialplan(Dialplan);
+decode(Scope, [A, B | Item]) when is_atom(Scope) ->
+ ?d("decode(~p) -> entry with"
+ "~n A: ~p"
+ "~n B: ~p"
+ "~n Item: ~p", [Scope, A, B, Item]),
+ case decode_package([A, B]) of
+ "" ->
+ ?d("decode -> \"no\" package",[]),
+ decode_item(Scope, [A, B], Item);
+ Package ->
+ ?d("decode -> Package: ~p", [Package]),
+ Package ++ "/" ++ decode_item(Scope, [A, B], Item)
+ end;
+decode({Scope, [A, B | Item]}, SubItem) when is_atom(Scope) ->
+ ?d("decode(~p) -> entry with"
+ "~n A: ~p"
+ "~n B: ~p"
+ "~n Item: ~p"
+ "~n SubItem: ~p", [Scope, A, B, Item, SubItem]),
+ decode_item({Scope, Item}, [A, B], SubItem).
+
+decode_item(Scope, [A, B], Item) ->
+ ?d("decode_item -> entry",[]),
+ case A of
+ 16#00 ->
+ case B of
+ 16#01 -> decode_g(Scope, Item);
+ 16#02 -> decode_root(Scope, Item);
+ 16#03 -> decode_tonegen(Scope, Item);
+ 16#04 -> decode_tonedet(Scope, Item);
+ 16#05 -> decode_dg(Scope, Item);
+ 16#06 -> decode_dd(Scope, Item);
+ 16#07 -> decode_cg(Scope, Item);
+ 16#08 -> decode_cd(Scope, Item);
+ 16#09 -> decode_al(Scope, Item);
+ 16#0a -> decode_ct(Scope, Item);
+ 16#0b -> decode_nt(Scope, Item);
+ 16#0c -> decode_rtp(Scope, Item);
+ 16#0d -> decode_tdmc(Scope, Item);
+ 16#00 -> decode_native(Scope, Item)
+ end;
+ 16#fe ->
+ case B of
+ %% Proprietary extension
+ 16#fe -> decode_swb(Scope, Item)
+ end;
+ 16#ff ->
+ case B of
+ 16#ff when Item =:= [16#ff, 16#ff] -> "*"
+ end
+ end.
+
+decode_package(Package) ->
+ ?d("decode_package -> entry with"
+ "~n Package: ~p", [Package]),
+ [A, B] = Package,
+ case A of
+ 16#00 ->
+ case B of
+ 16#01 -> "g";
+ 16#02 -> "root";
+ 16#03 -> "tonegen";
+ 16#04 -> "tonedet";
+ 16#05 -> "dg";
+ 16#06 -> "dd";
+ 16#07 -> "cg";
+ 16#08 -> "cd";
+ 16#09 -> "al";
+ 16#0a -> "ct";
+ 16#0b -> "nt";
+ 16#0c -> "rtp";
+ 16#0d -> "tdmc";
+ 16#00 -> ""
+ end;
+ 16#fe ->
+ case B of
+ 16#fe -> "swb"
+ end;
+ 16#ff ->
+ case B of
+ 16#ff -> "*"
+ end
+ end.
+
+decode_profile([A, B]) ->
+ case A of
+ 16#00 ->
+ case B of
+ 16#fe -> "resgw";
+ _ -> "profile" ++ [A + $0, B + $0]
+ end;
+ _ ->
+ "profile" ++ [A + $0, B + $0]
+ end.
+
+decode_dialplan([A, B]) ->
+ "dialplan" ++ [A + $0, B + $0].
+
+decode_mid(Mid) ->
+ case Mid of
+ {domainName, DN} ->
+ Lower = to_lower(DN#'DomainName'.name),
+ {domainName, DN#'DomainName'{name = Lower}};
+ {deviceName, PathName} ->
+ Lower = to_lower(PathName),
+ {deviceName, Lower};
+ Other ->
+ Other
+ end.
+
+to_lower(Chars) ->
+ [?LOWER(Char) || Char <- Chars].
+
+%%----------------------------------------------------------------------
+%% Encode package name from internal form
+%% Scope ::= property | event | signal | statistics
+%%----------------------------------------------------------------------
+
+encode(mid, Package) ->
+ encode_mid(Package);
+encode(package, Package) ->
+ encode_package(Package);
+encode(profile, Profile) ->
+ encode_profile(Profile);
+encode(dialplan, Dialplan) ->
+ encode_dialplan(Dialplan);
+encode(Scope, PackageItem) when is_atom(Scope) ->
+ ?d("encode(~p) -> entry with"
+ "~n PackageItem: ~p", [Scope, PackageItem]),
+ case string:tokens(PackageItem, [$/]) of
+ [Package, Item] ->
+ ?d("encode -> "
+ "~n Package: ~p"
+ "~n Item: ~p", [Package, Item]),
+ encode_package(Package) ++ encode_item(Scope, Package, Item);
+ [Item] ->
+ ?d("encode -> Item: ~p", [Item]),
+ [16#00, 16#00 | encode_native(Scope, Item)]
+ end;
+encode({Scope, PackageItem}, SubItem) when is_atom(Scope) ->
+ ?d("encode(~p) -> entry with"
+ "~n PackageItem: ~p"
+ "~n SubItem: ~p", [Scope, PackageItem, SubItem]),
+ case string:tokens(PackageItem, [$/]) of
+ [Package, Item] ->
+ ?d("encode -> "
+ "~n Package: ~p"
+ "~n Item: ~p", [Package, Item]),
+ encode_item({Scope, Item}, Package, SubItem);
+ [_Item] ->
+ ?d("encode -> _Item: ~p", [_Item]),
+ encode_native(Scope, SubItem)
+ end.
+
+encode_item(_Scope, _Package, "*") ->
+ [16#ff, 16#ff];
+encode_item(Scope, Package, Item) ->
+ ?d("encode_item(~s) -> entry", [Package]),
+ case Package of
+ "g" -> encode_g(Scope, Item);
+ "root" -> encode_root(Scope, Item);
+ "tonegen" -> encode_tonegen(Scope, Item);
+ "tonedet" -> encode_tonedet(Scope, Item);
+ "dg" -> encode_dg(Scope, Item);
+ "dd" -> encode_dd(Scope, Item);
+ "cg" -> encode_cg(Scope, Item);
+ "cd" -> encode_cd(Scope, Item);
+ "al" -> encode_al(Scope, Item);
+ "ct" -> encode_ct(Scope, Item);
+ "nt" -> encode_nt(Scope, Item);
+ "rtp" -> encode_rtp(Scope, Item);
+ "tdmc" -> encode_tdmc(Scope, Item);
+ "swb" -> encode_swb(Scope, Item)
+ end.
+
+encode_package(Package) ->
+ case Package of
+ "g" -> [16#00, 16#01];
+ "root" -> [16#00, 16#02];
+ "tonegen" -> [16#00, 16#03];
+ "tonedet" -> [16#00, 16#04];
+ "dg" -> [16#00, 16#05];
+ "dd" -> [16#00, 16#06];
+ "cg" -> [16#00, 16#07];
+ "cd" -> [16#00, 16#08];
+ "al" -> [16#00, 16#09];
+ "ct" -> [16#00, 16#0a];
+ "nt" -> [16#00, 16#0b];
+ "rtp" -> [16#00, 16#0c];
+ "tdmc" -> [16#00, 16#0d];
+ "" -> [16#00, 16#00];
+ "*" -> [16#ff, 16#ff];
+ "swb" -> [16#fe, 16#fe]
+ end.
+
+encode_profile(Profile) ->
+ case Profile of
+ "resgw" ->
+ [16#00, 16#fe];
+ [$p, $r, $o, $f, $i, $l, $e | Name] ->
+ case Name of
+ [A, B] -> [A - $0, B - $0];
+ [B] -> [0, B - $0];
+ [] -> [0, 0]
+ end
+ end.
+
+encode_dialplan(Dialplan) ->
+ case Dialplan of
+ [$d, $i, $a, $l, $p, $l, $a, $n | Name] ->
+ case Name of
+ [A, B] -> [A - $0, B - $0];
+ [B] -> [0, B - $0];
+ [] -> [0, 0]
+ end
+ end.
+
+encode_mid(Mid) ->
+ Mid.
+
+
+%%----------------------------------------------------------------------
+%% Name: g - Generic
+%% Version: 1
+%% Extends: None
+%% Purpose: Generic package for commonly encountered items
+%%----------------------------------------------------------------------
+
+capabilities_g() ->
+ [
+ {event, "cause"},
+ {event, "sc"}
+ ].
+
+encode_g(event, Item) ->
+ case Item of
+ "cause" -> [16#00, 16#01];
+ "sc" -> [16#00, 16#02]
+ end;
+
+encode_g({event_parameter, Item}, SubItem) ->
+ case Item of
+ "cause" ->
+ case SubItem of
+ "Generalcause" -> [16#00, 16#01];
+ "Failurecause" -> [16#00, 16#02]
+ end;
+ "sc" ->
+ case SubItem of
+ "SigID" -> [16#00, 16#01];
+ "Meth" -> [16#00, 16#02];
+ "SLID" -> [16#00, 16#03]
+ end
+ end.
+
+decode_g(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "cause";
+ [16#00, 16#02] -> "sc"
+ end;
+
+decode_g({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event: cause
+ case SubItem of
+ [16#00, 16#01] -> "Generalcause";
+ [16#00, 16#02] -> "Failurecause"
+ end;
+
+ [16#00, 16#02] -> % Event: sc
+ case SubItem of
+ [16#00, 16#01] -> "SigID";
+ [16#00, 16#02] -> "Meth";
+ [16#00, 16#03] -> "SLID"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: root - Base Root Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines Gateway wide properties.
+%%----------------------------------------------------------------------
+
+capabilities_root() ->
+ [
+ {property, "maxNumberOfContexts"},
+ {property, "maxTerminationsPerContext"},
+ {property, "normalMGExecutionTime"},
+ {property, "normalMGCExecutionTime"},
+ {property, "MGProvisionalResponseTimerValue"},
+ {property, "MGCProvisionalResponseTimerValue"},
+ {property, "MGCOriginatedPendingLimit"},
+ {property, "MGOriginatedPendingLimit"}
+ ].
+
+encode_root(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ "maxNumberOfContexts" -> [16#00, 16#01];
+ "maxTerminationsPerContext" -> [16#00, 16#02];
+ "normalMGExecutionTime" -> [16#00, 16#03];
+ "normalMGCExecutionTime" -> [16#00, 16#04];
+ "MGProvisionalResponseTimerValue" -> [16#00, 16#05];
+ "MGCProvisionalResponseTimerValue" -> [16#00, 16#06];
+ "MGCOriginatedPendingLimit" -> [16#00, 16#07];
+ "MGOriginatedPendingLimit" -> [16#00, 16#08]
+ end
+ end.
+
+decode_root(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ [16#00, 16#01] -> "maxNumberOfContexts";
+ [16#00, 16#02] -> "maxTerminationsPerContext";
+ [16#00, 16#03] -> "normalMGExecutionTime";
+ [16#00, 16#04] -> "normalMGCExecutionTime";
+ [16#00, 16#05] -> "MGProvisionalResponseTimerValue";
+ [16#00, 16#06] -> "MGCProvisionalResponseTimerValue";
+ [16#00, 16#07] -> "MGCOriginatedPendingLimit";
+ [16#00, 16#08] -> "MGOriginatedPendingLimit"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tonegen - Tone Generator Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines signals to generate audio tones.
+%% This package does not specify parameter values. It is
+%% intended to be extendable. Generally, tones are defined
+%% as an individual signal with a parameter, ind,
+%% representing "interdigit" time delay, and a tone id to
+%% be used with playtones. A tone id should be kept
+%% consistent with any tone generation for the same tone.
+%% MGs are expected to be provisioned with the characteristics
+%% of appropriate tones for the country in which the MG is located.
+%%----------------------------------------------------------------------
+
+capabilities_tonegen() ->
+ [
+ {signal, "pt"}
+ ].
+
+encode_tonegen(signal, Item) ->
+ case Item of
+ "pt" -> [16#00, 16#01]
+ end;
+
+encode_tonegen({signal_parameter, Item}, SubItem) ->
+ case Item of
+ "pt" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "ind" -> [16#00, 16#02]
+ end
+ end.
+
+decode_tonegen(signal, Item) ->
+ case Item of
+ [16#00, 16#01] -> "pt"
+ end;
+
+decode_tonegen({signal_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event: pt
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#02] -> "ind"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tonedet - Tone Detection Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This Package defines events for audio tone detection.
+%% Tones are selected by name (tone id). MGs are expected
+%% to be provisioned with the characteristics of appropriate
+%% tones for the country in which the MG is located.
+%%
+%% This package does not specify parameter values.
+%% It is intended to be extendable.
+%%----------------------------------------------------------------------
+
+capabilities_tonedet() ->
+ [
+ {event, "std"},
+ {event, "etd"},
+ {event, "ltd"}
+ ].
+
+encode_tonedet(event, Item) ->
+ case Item of
+ "std" -> [16#00, 16#01];
+ "etd" -> [16#00, 16#02];
+ "ltd" -> [16#00, 16#03]
+ end;
+
+encode_tonedet({event_parameter, Item}, SubItem) ->
+ case Item of
+ "std" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "tid" -> [16#00, 16#03]
+ end;
+ "etd" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "tid" -> [16#00, 16#03];
+ "dur" -> [16#00, 16#02]
+ end;
+ "ltd" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "dur" -> [16#00, 16#02];
+ "tid" -> [16#00, 16#03]
+ end
+ end.
+
+decode_tonedet(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "std";
+ [16#00, 16#02] -> "etd";
+ [16#00, 16#03] -> "ltd"
+ end;
+
+decode_tonedet({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event std
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#03] -> "tid"
+ end;
+ [16#00, 16#02] -> % Event etd
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#03] -> "tid";
+ [16#00, 16#02] -> "dur"
+ end;
+ [16#00, 16#03] -> % Event ltd
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#02] -> "dur";
+ [16#00, 16#03] -> "tid"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: dg - Basic DTMF Generator Package
+%% Version: 1
+%% Extends: tonegen version 1
+%% Purpose: This package defines the basic DTMF tones as signals and
+%% extends the allowed values of parameter tl of playtone
+%% in tonegen.
+%%----------------------------------------------------------------------
+
+capabilities_dg() ->
+ [
+ {signal, "d0"},
+ {signal, "d1"},
+ {signal, "d2"},
+ {signal, "d3"},
+ {signal, "d4"},
+ {signal, "d5"},
+ {signal, "d6"},
+ {signal, "d7"},
+ {signal, "d8"},
+ {signal, "d9"},
+ {signal, "ds"},
+ {signal, "do"},
+ {signal, "da"},
+ {signal, "db"},
+ {signal, "dc"},
+ {signal, "dd"}
+ ].
+
+encode_dg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ "d0" -> [16#00, 16#10];
+ "d1" -> [16#00, 16#11];
+ "d2" -> [16#00, 16#12];
+ "d3" -> [16#00, 16#13];
+ "d4" -> [16#00, 16#14];
+ "d5" -> [16#00, 16#15];
+ "d6" -> [16#00, 16#16];
+ "d7" -> [16#00, 16#17];
+ "d8" -> [16#00, 16#18];
+ "d9" -> [16#00, 16#19];
+ "ds" -> [16#00, 16#20];
+ "do" -> [16#00, 16#21];
+ "da" -> [16#00, 16#1a];
+ "db" -> [16#00, 16#1b];
+ "dc" -> [16#00, 16#1c];
+ "dd" -> [16#00, 16#1d]
+ end
+ end.
+
+decode_dg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ [16#00, 16#10] -> "d0";
+ [16#00, 16#11] -> "d1";
+ [16#00, 16#12] -> "d2";
+ [16#00, 16#13] -> "d3";
+ [16#00, 16#14] -> "d4";
+ [16#00, 16#15] -> "d5";
+ [16#00, 16#16] -> "d6";
+ [16#00, 16#17] -> "d7";
+ [16#00, 16#18] -> "d8";
+ [16#00, 16#19] -> "d9";
+ [16#00, 16#20] -> "ds";
+ [16#00, 16#21] -> "do";
+ [16#00, 16#1a] -> "da";
+ [16#00, 16#1b] -> "db";
+ [16#00, 16#1c] -> "dc";
+ [16#00, 16#1d] -> "dd"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: dd - DTMF detection Package
+%% Version: 1
+%% Extends: tonedet version 1
+%% Purpose: This package defines the basic DTMF tones detection.
+%% Tones are selected by name (tone id). MGs are expected
+%% to be provisioned with the characteristics of appropriate
+%% tones for the country in which the MG is located.
+%%
+%% This package does not specify parameter values.
+%% It is intended to be extendable.
+%%
+%% Additional tone id values are all tone ids described in package dg
+%% (basic DTMF generator package).
+%%
+%% The following table maps DTMF events to digit map symbols as described
+%% in section 7.1.14.
+%%
+%% _________________________________
+%% | DTMF Event | Symbol |
+%% | d0 | "0" |
+%% | d1 | "1" |
+%% | d2 | "2" |
+%% | d3 | "3" |
+%% | d4 | "4" |
+%% | d5 | "5" |
+%% | d6 | "6" |
+%% | d7 | "7" |
+%% | d8 | "8" |
+%% | d9 | "9" |
+%% | da | "A" or "a"|
+%% | db | "B" or "b"|
+%% | dc | "C" or "c"|
+%% | dd | "D" or "d"|
+%% | ds | "E" or "e"|
+%% | do | "F" or "f"|
+%% |___________________|____________|
+%%
+%%----------------------------------------------------------------------
+
+capabilities_dd() ->
+ [
+ {event, "ce"},
+ {event, "d0"},
+ {event, "d1"},
+ {event, "d2"},
+ {event, "d3"},
+ {event, "d4"},
+ {event, "d5"},
+ {event, "d6"},
+ {event, "d7"},
+ {event, "d8"},
+ {event, "d9"},
+ {event, "ds"},
+ {event, "do"},
+ {event, "da"},
+ {event, "db"},
+ {event, "dc"},
+ {event, "dd"}
+ ].
+
+encode_dd(event, Item) ->
+ case Item of
+ "ce" -> [16#00, 16#04];
+ "d0" -> [16#00, 16#10];
+ "d1" -> [16#00, 16#11];
+ "d2" -> [16#00, 16#12];
+ "d3" -> [16#00, 16#13];
+ "d4" -> [16#00, 16#14];
+ "d5" -> [16#00, 16#15];
+ "d6" -> [16#00, 16#16];
+ "d7" -> [16#00, 16#17];
+ "d8" -> [16#00, 16#18];
+ "d9" -> [16#00, 16#19];
+ "ds" -> [16#00, 16#20];
+ "do" -> [16#00, 16#21];
+ "da" -> [16#00, 16#1a];
+ "db" -> [16#00, 16#1b];
+ "dc" -> [16#00, 16#1c];
+ "dd" -> [16#00, 16#1d]
+ end;
+
+encode_dd({event_parameter, Item}, SubItem) ->
+ case Item of
+ "ce" ->
+ case SubItem of
+ "ds" -> [16#00, 16#01];
+ "Meth" -> [16#00, 16#03]
+ end
+ end.
+
+decode_dd(event, Item) ->
+ case Item of
+ [16#00, 16#04] -> "ce";
+ [16#00, 16#10] -> "d0";
+ [16#00, 16#11] -> "d1";
+ [16#00, 16#12] -> "d2";
+ [16#00, 16#13] -> "d3";
+ [16#00, 16#14] -> "d4";
+ [16#00, 16#15] -> "d5";
+ [16#00, 16#16] -> "d6";
+ [16#00, 16#17] -> "d7";
+ [16#00, 16#18] -> "d8";
+ [16#00, 16#19] -> "d9";
+ [16#00, 16#20] -> "ds";
+ [16#00, 16#21] -> "do";
+ [16#00, 16#1a] -> "da";
+ [16#00, 16#1b] -> "db";
+ [16#00, 16#1c] -> "dc";
+ [16#00, 16#1d] -> "dd"
+ end;
+
+decode_dd({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#04] -> % Event ce
+ case SubItem of
+ [16#00, 16#01] -> "ds";
+ [16#00, 16#03] -> "Meth"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: cg - Call Progress Tones Generator Package
+%% Version: 1
+%% Extends: tonegen version 1
+%% Purpose: This package defines the basic call progress tones as signals
+%% and extends the allowed values of the tl parameter of
+%% playtone in tonegen.
+%%----------------------------------------------------------------------
+
+capabilities_cg() ->
+ [
+ {signal, "dt"},
+ {signal, "rt"},
+ {signal, "bt"},
+ {signal, "ct"},
+ {signal, "sit"},
+ {signal, "wt"},
+ {signal, "prt"},
+ {signal, "cw"},
+ {signal, "cr"}
+ ].
+
+
+encode_cg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ "dt" -> [16#00, 16#30];
+ "rt" -> [16#00, 16#31];
+ "bt" -> [16#00, 16#32];
+ "ct" -> [16#00, 16#33];
+ "sit" -> [16#00, 16#34];
+ "wt" -> [16#00, 16#35];
+ "prt" -> [16#00, 16#36];
+ "cw" -> [16#00, 16#37];
+ "cr" -> [16#00, 16#38]
+ end
+ end.
+
+decode_cg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ [16#00, 16#30] -> "dt";
+ [16#00, 16#31] -> "rt";
+ [16#00, 16#32] -> "bt";
+ [16#00, 16#33] -> "ct";
+ [16#00, 16#34] -> "sit";
+ [16#00, 16#35] -> "wt";
+ [16#00, 16#36] -> "prt";
+ [16#00, 16#37] -> "cw";
+ [16#00, 16#38] -> "cr"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: cd - Call Progress Tones Detection Package
+%% Version: 1
+%% Extends: tonedet version 1
+%% Purpose: This package defines the basic call progress detection tones.
+%% This Package extends the possible values of tone id
+%% in the "start tone detected", "end tone detected" and
+%% "long tone detected" events.
+%% Additional values
+%% tone id values are defined for start tone detected,
+%% end tone detected and long tone detected with
+%% the same values as those in package cg (call
+%% progress tones generation package).
+%%
+%% The required set of tone ids corresponds to Recommendation E.180/Q.35
+%% [ITU-T Recommendation E.180/Q.35 (1998)]. See Recommendation E.180/Q.35
+%% for definition of the meanings of these tones.
+%%----------------------------------------------------------------------
+
+capabilities_cd() ->
+ [
+ {event, "dt"},
+ {event, "rt"},
+ {event, "bt"},
+ {event, "ct"},
+ {event, "sit"},
+ {event, "wt"},
+ {event, "prt"},
+ {event, "cw"},
+ {event, "cr"}
+ ].
+
+
+encode_cd(Scope, Item) ->
+ case Scope of
+ event ->
+ case Item of
+ "dt" -> [16#00, 16#30];
+ "rt" -> [16#00, 16#31];
+ "bt" -> [16#00, 16#32];
+ "ct" -> [16#00, 16#33];
+ "sit"-> [16#00, 16#34];
+ "wt" -> [16#00, 16#35];
+ "prt"-> [16#00, 16#36];
+ "cw" -> [16#00, 16#37];
+ "cr" -> [16#00, 16#38]
+ end
+ end.
+
+decode_cd(Scope, Item) ->
+ case Scope of
+ event ->
+ case Item of
+ [16#00, 16#30] -> "dt";
+ [16#00, 16#31] -> "rt";
+ [16#00, 16#32] -> "bt";
+ [16#00, 16#33] -> "ct";
+ [16#00, 16#34] -> "sit";
+ [16#00, 16#35] -> "wt";
+ [16#00, 16#36] -> "prt";
+ [16#00, 16#37] -> "cw";
+ [16#00, 16#38] -> "cr"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: al - Analog Line Supervision Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines events and signals for an analog line.
+%%----------------------------------------------------------------------
+
+capabilities_al() ->
+ [
+ {event, "on"},
+ {event, "of"},
+ {event, "fl"},
+ {signal, "ri"}
+ ].
+
+encode_al(event, Item) ->
+ ?d("encode_al(event) -> entry with"
+ "~n Item: ~p", [Item]),
+ case Item of
+ "on" -> [16#00, 16#04];
+ "of" -> [16#00, 16#05];
+ "fl" -> [16#00, 16#06]
+ end;
+
+encode_al({event_parameter, Item}, SubItem) ->
+ ?d("encode_al({event_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ "on" ->
+ case SubItem of
+ "strict" -> [16#00, 16#01];
+ "init" -> [16#00, 16#02]
+ end;
+ "of" ->
+ case SubItem of
+ "strict" -> [16#00, 16#01];
+ "init" -> [16#00, 16#02]
+ end;
+ "fl" ->
+ case SubItem of
+ "mindur" -> [16#00, 16#04];
+ "maxdur" -> [16#00, 16#05]
+ end
+ end;
+
+encode_al(signal, Item) ->
+ ?d("encode_al(signal) -> entry with"
+ "~n Item: ~p", [Item]),
+ case Item of
+ "ri" -> [16#00, 16#02]
+ end;
+
+encode_al({signal_parameter, Item}, SubItem) ->
+ ?d("encode_al({signal_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ "ri" ->
+ case SubItem of
+ "cad" -> [16#00, 16#06];
+ "freq" -> [16#00, 16#07]
+ end
+ end.
+
+decode_al(event, SubItem) ->
+ ?d("decode_al(event) -> entry with"
+ "~n SubItem: ~p", [SubItem]),
+ case SubItem of
+ [16#00, 16#04] -> "on";
+ [16#00, 16#05] -> "of";
+ [16#00, 16#06] -> "fl"
+ end;
+
+decode_al({event_parameter, Item}, SubItem) ->
+ ?d("decode_al({event_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ [16#00,16#04] -> %% Event: on
+ case SubItem of
+ [16#00, 16#01] -> "strict";
+ [16#00, 16#02] -> "init"
+ end;
+ [16#00,16#05] -> %% Event: of
+ case SubItem of
+ [16#00, 16#01] -> "strict";
+ [16#00, 16#02] -> "init"
+ end;
+ [16#00,16#06] -> %% Event: fl
+ case SubItem of
+ [16#00, 16#04] -> "mindur";
+ [16#00, 16#05] -> "maxdur"
+ end
+ end;
+
+decode_al(signal, SubItem) ->
+ ?d("decode_al(signal) -> entry with"
+ "~n SubItem: ~p", [SubItem]),
+ case SubItem of
+ [16#00, 16#02] -> "ri"
+ end;
+
+decode_al({signal_parameter, Item}, SubItem) ->
+ ?d("decode_al({signal_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ [16#00,16#02] -> %% Event: ri
+ case SubItem of
+ [16#00, 16#06] -> "cad";
+ [16#00, 16#07] -> "freq"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: ct - Basic Continuity Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines events and signals for continuity test.
+%% The continuity test includes provision of either a loopback
+%% or transceiver functionality.
+%%----------------------------------------------------------------------
+
+capabilities_ct() ->
+ [
+ {event, "cmp"},
+ {signal, "ct"},
+ {signal, "rsp"}
+ ].
+
+encode_ct(event, Item) ->
+ case Item of
+ "cmp" -> [16#00, 16#05]
+ end;
+encode_ct({event_parameter, Item}, SubItem) ->
+ case Item of
+ "cmp" ->
+ case SubItem of
+ "res" -> [16#00, 16#08]
+ end
+ end;
+encode_ct(signal, Item) ->
+ case Item of
+ "ct" -> [16#00, 16#03];
+ "rsp" -> [16#00, 16#04]
+ end.
+
+decode_ct(event, Item) ->
+ case Item of
+ [16#00, 16#05] -> "cmp"
+ end;
+decode_ct({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#05] -> % Event cmp
+ case SubItem of
+ [16#00, 16#08] -> "res"
+ end
+ end;
+decode_ct(signal, Item) ->
+ case Item of
+ [16#00, 16#03] -> "ct";
+ [16#00, 16#04] -> "rsp"
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: nt - Network Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines properties of network terminations
+%% independent of network type.
+%%----------------------------------------------------------------------
+
+capabilities_nt() ->
+ [
+ {property, "jit"},
+ {event, "netfail"},
+ {event, "qualert"},
+ {statistics, "dur"},
+ {statistics, "os"},
+ {statistics, "or"}
+ ].
+
+encode_nt(property, Item) ->
+ case Item of
+ "jit" -> [16#00, 16#07]
+ end;
+encode_nt(event, Item) ->
+ case Item of
+ "netfail" -> [16#00, 16#05];
+ "qualert" -> [16#00, 16#06]
+ end;
+encode_nt({event_parameter, Item}, SubItem) ->
+ case Item of
+ "netfail" ->
+ case SubItem of
+ "cs" -> [16#00, 16#01]
+ end;
+ "qualert" ->
+ case SubItem of
+ "th" -> [16#00, 16#01]
+ end
+ end;
+encode_nt(statistics, Item) ->
+ case Item of
+ "dur" -> [16#00, 16#01];
+ "os" -> [16#00, 16#02];
+ "or" -> [16#00, 16#03]
+ end.
+
+decode_nt(property, Item) ->
+ case Item of
+ [16#00, 16#07] -> "jit"
+ end;
+decode_nt(event, Item) ->
+ case Item of
+ [16#00, 16#05] -> "netfail";
+ [16#00, 16#06] -> "qualert"
+ end;
+decode_nt({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#05] -> % Event netfail
+ case SubItem of
+ [16#00, 16#01] -> "cs"
+ end;
+ [16#00, 16#06] -> % Event qualert
+ case Item of
+ [16#00, 16#01] -> "th"
+ end
+ end;
+decode_nt(statistics, Item) ->
+ case Item of
+ [16#00, 16#01] -> "dur";
+ [16#00, 16#02] -> "os";
+ [16#00, 16#03] -> "or"
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: rtp - RTP Package
+%% Version: 1
+%% Extends: nt version 1
+%% Purpose: This package is used to support packet based multimedia
+%% data transfer by means of the Real-time Transport Protocol
+%% (RTP) [RFC 1889].
+%%----------------------------------------------------------------------
+
+capabilities_rtp() ->
+ [
+ {event, "pltrans"},
+ {statistics, "ps"},
+ {statistics, "pr"},
+ {statistics, "pl"},
+ {statistics, "jit"},
+ {statistics, "delay"}
+ ].
+
+encode_rtp(event, Item) ->
+ case Item of
+ "pltrans" -> [16#00, 16#01]
+ end;
+encode_rtp({event_parameter, Item}, SubItem) ->
+ case Item of
+ "pltrans" ->
+ case SubItem of
+ "rtppltype" -> [16#00, 16#01]
+ end
+ end;
+encode_rtp(statistics, Item) ->
+ case Item of
+ "ps" -> [16#00, 16#04];
+ "pr" -> [16#00, 16#05];
+ "pl" -> [16#00, 16#06];
+ "jit" -> [16#00, 16#07];
+ "delay" -> [16#00, 16#08]
+ end.
+
+decode_rtp(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "pltrans"
+ end;
+decode_rtp({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event pltrans
+ case SubItem of
+ [16#00, 16#01] -> "rtppltype"
+ end
+ end;
+decode_rtp(statistics, Item) ->
+ case Item of
+ [16#00, 16#04] -> "ps";
+ [16#00, 16#05] -> "pr";
+ [16#00, 16#06] -> "pl";
+ [16#00, 16#07] -> "jit";
+ [16#00, 16#08] -> "delay"
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tdmc - TDM Circuit Package
+%% Version: 1
+%% Extends: nt version 1
+%% Purpose: This package is used to support TDM circuit terminations.
+%%----------------------------------------------------------------------
+
+capabilities_tdmc() ->
+ [
+ {property, "ec"},
+ {property, "gain"}
+ ].
+
+encode_tdmc(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ "ec" -> [16#00, 16#08];
+ "gain" -> [16#00, 16#0a]
+ end
+ end.
+
+decode_tdmc(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ [16#00, 16#08] -> "ec";
+ [16#00, 16#0a] -> "gain"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: swb - SwitchBoard Package
+%% Version: 1
+%% Extends: none
+%% Purpose: This package is used to support SwitchBoard specials
+%%----------------------------------------------------------------------
+
+capabilities_swb() ->
+ [
+ {statistics, "fs"}, % Free slots
+ {statistics, "as"} % Allocated slots
+ ].
+
+encode_swb(Scope, Item) ->
+ case Scope of
+ statistics ->
+ case Item of
+ "fs" -> [16#00, 16#00];
+ "as" -> [16#00, 16#01]
+ end
+ end.
+
+decode_swb(Scope, Item) ->
+ case Scope of
+ statistics ->
+ case Item of
+ [16#00, 16#00] -> "fs";
+ [16#00, 16#01] -> "as"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: native - Pseudo package
+%% Version: 1
+%% Extends: None
+%% Purpose: Native tags for media stream properties
+%%
+%% Parameters for Local descriptors and Remote descriptors are
+%% specified as tag-value pairs if binary encoding is used for the
+%% protocol. This annex contains the property names (PropertyID), the
+%% tags (Property Tag), type of the property (Type) and the values
+%% (Value).Values presented in the Value field when the field contains
+%% references shall be regarded as "information". The reference
+%% contains the normative values. If a value field does not contain a
+%% reference then the values in that field can be considered as
+%% "normative".
+%%
+%% Tags are given as hexadecimal numbers in this annex. When setting
+%% the value of a property, a MGC may underspecify the value according
+%% to one of the mechanisms specified in section 7.1.1.
+%%
+%% For type "enumeration" the value is represented by the value in brack-
+%% ets, e.g., Send(0), Receive(1).
+%%----------------------------------------------------------------------
+%%
+%% C.6. IP
+%%
+%% ________________________________________________________________
+%% | PropertyID| Tag | Type | Value |
+%% | IPv4 | 6001 | 32 BITS | Ipv4Address |
+%% | IPv6 | 6002 | 128 BITS | IPv6 Address |
+%% | Port | 6003 | Unsigned Int| Port |
+%% | Porttype | 6004 | Enumerated | TCP(0),UDP(1),SCTP(2)|
+%% |___________|____________|______________|_______________________|
+%%
+%%
+%% C.11. SDP Equivalents
+%%
+%% ______________________________________________________________
+%% | PropertyID| Tag | Type | Value |
+%% | SDP_V | B001| STRING| Protocol Version |
+%% | SDP_O | B002| STRING| Owner-creator and session ID |
+%% | SDP_S | B003| STRING| Sesson name |
+%% | SDP_I | B004| STRING| Session identifier |
+%% | SDP_U | B005| STRING| URI of descriptor |
+%% | SDC_E | B006| STRING| email address |
+%% | SDP_P | B007| STRING| phone number |
+%% | SDP_C | B008| STRING| Connection information |
+%% | SDP_B | B009| STRING| Bandwidth Information |
+%% | SDP_Z | B00A| STRING| time zone adjustment |
+%% | SDP_K | B00B| STRING| Encryption Key |
+%% | SDP_A | B00C| STRING| Zero or more session attributes|
+%% | SDP_T | B00D| STRING| Active Session Time |
+%% | SDP_R | B00E| STRING| Zero or more repeat times |
+%% | SDP_M | B00F| STRING| Media name and transport addr |
+%% | | | | Reference: IETF RFC 2327 |
+%% |___________|______|________|_________________________________|
+%%
+%%----------------------------------------------------------------------
+
+capabilities_native() ->
+ [
+ %% C.6. IP
+ {property, "IPv4"},
+ {property, "IPv6"},
+ {property, "Port"},
+ {property, "Porttype"},
+
+ %% C.11. SDP Equivalents
+ {property, "v"},
+ {property, "o"},
+ {property, "s"},
+ {property, "i"},
+ {property, "u"},
+ {property, "e"},
+ {property, "p"},
+ {property, "c"},
+ {property, "b"},
+ {property, "z"},
+ {property, "k"},
+ {property, "a"},
+ {property, "t"},
+ {property, "r"},
+ {property, "m"}
+ ].
+
+encode_native(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ %% IP
+ "IPv4" -> [16#60, 16#01];
+ "IPv6" -> [16#60, 16#02];
+ "Port" -> [16#60, 16#03];
+ "Porttype" -> [16#60, 16#04];
+
+ %% SDP
+ "v" -> [16#b0, 16#01];
+ "o" -> [16#b0, 16#02];
+ "s" -> [16#b0, 16#03];
+ "i" -> [16#b0, 16#04];
+ "u" -> [16#b0, 16#05];
+ "e" -> [16#b0, 16#06];
+ "p" -> [16#b0, 16#07];
+ "c" -> [16#b0, 16#08];
+ "b" -> [16#b0, 16#09];
+ "z" -> [16#b0, 16#0a];
+ "k" -> [16#b0, 16#0b];
+ "a" -> [16#b0, 16#0c];
+ "t" -> [16#b0, 16#0d];
+ "r" -> [16#b0, 16#0e];
+ "m" -> [16#b0, 16#0f]
+ end
+ end.
+
+decode_native(Scope, [Type, Item]) ->
+ case Scope of
+ property ->
+ case Type of
+ 16#60 ->
+ case Item of
+ 16#01 -> "IPv4";
+ 16#02 -> "IPv6";
+ 16#03 -> "Port";
+ 16#04 -> "Porttype"
+ end;
+
+ 16#b0 ->
+ case Item of
+ 16#01 -> "v";
+ 16#02 -> "o";
+ 16#03 -> "s";
+ 16#04 -> "i";
+ 16#05 -> "u";
+ 16#06 -> "e";
+ 16#07 -> "p";
+ 16#08 -> "c";
+ 16#09 -> "b";
+ 16#0a -> "z";
+ 16#0b -> "k";
+ 16#0c -> "a";
+ 16#0d -> "t";
+ 16#0e -> "r";
+ 16#0f -> "m"
+ end
+ end
+ end.
+
+%% -------------------------------------------------------------------
+
+% error(Reason) ->
+% erlang:error(Reason).
+
diff --git a/lib/megaco/src/binary/megaco_binary_name_resolver_v3.erl b/lib/megaco/src/binary/megaco_binary_name_resolver_v3.erl
new file mode 100644
index 0000000000..c101aa15bc
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_name_resolver_v3.erl
@@ -0,0 +1,2016 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Handle meta data about packages
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_name_resolver_v3).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+-include_lib("megaco/src/app/megaco_internal.hrl").
+
+
+-define(LOWER(Char),
+ if
+ Char >= $A, Char =< $Z ->
+ Char - ($A - $a);
+ true ->
+ Char
+ end).
+
+-export([packages/0,
+ capabilities/0,
+ capabilities/1,
+ decode_name/3,
+ encode_name/3
+ ]).
+
+encode_name(Config, term_id, TermId) ->
+ case megaco:encode_binary_term_id(Config, TermId) of
+ {ok, TermId2} ->
+ TermId2;
+ {error, Reason} ->
+ exit({bad_term_id, TermId, Reason})
+ end;
+encode_name(_Config, Scope, Item) ->
+ ?d("encode_name(~p) -> entry with"
+ "~n Item: ~p", [Scope, Item]),
+ encode(Scope, Item).
+
+decode_name(Config, term_id, TermId) ->
+ case megaco:decode_binary_term_id(Config, TermId) of
+ {ok, TermId2} ->
+ TermId2;
+ {error, Reason} ->
+ exit({bad_term_id, TermId, Reason})
+ end;
+decode_name(_Config, Scope, Item) ->
+ ?d("decode_name(~p) -> entry with"
+ "~n Item: ~p", [Scope, Item]),
+ decode(Scope, Item).
+
+
+
+%%----------------------------------------------------------------------
+%% 12.1.1 Package
+%%
+%% Overall description of the package, specifying:
+%%
+%% Package Name: only descriptive
+%%
+%% PackageID: is an identifier
+%%
+%% Description: is a description of the package
+%%
+%% Version:
+%%
+%% A new version of a package can only add additional Properties,
+%% Events, Signals, Statistics and new possible values for an
+%% existing parameter described in the original package. No
+%% deletions or modifications shall be allowed. A version is an
+%% integer in the range from 1 to 99.
+%%
+%% Designed to be extended only (Optional): Yes
+%%
+%% This indicates that the package has been expressly designed to
+%% be extended by others, not to be directly referenced. For
+%% example, the package may not have any function on its own or be
+%% nonsensical on its own. The MG SHOULD NOT publish this PackageID
+%% when reporting packages.
+%%
+%% Extends: existing package Descriptor
+%%
+%% A package may extend an existing package. The version of the
+%% original package must be specified. When a package extends
+%% another package it shall only add additional Properties, Events,
+%% Signals, Statistics and new possible values for an existing
+%% parameter described in the original package. An extended package
+%% shall not redefine or overload an identifier defined in the
+%% original package and packages it may have extended (multiple
+%% levels of extension). Hence, if package B version 1 extends
+%% package A version 1, version 2 of B will not be able to extend
+%% the A version 2 if A version 2 defines a name already in B
+%% version 1. If the package does not extend another package, it
+%% shall specify "none".
+%%
+%%
+%% 12.1.2 Properties
+%%
+%% Properties defined by the package, specifying:
+%%
+%% Property Name: only descriptive
+%%
+%% PropertyID: is an identifier
+%%
+%% Description: is a description of the function of the property
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 string
+%%
+%% Octet String: A number of octets. See Annex A and B.3 for
+%% encoding
+%%
+%% Integer: 4 byte signed integer
+%%
+%% Double: 8 byte signed integer
+%%
+%% Character: unicode UTF-8 encoding of a single letter.
+%% Could be more than one octet.
+%%
+%% Enumeration: one of a list of possible unique values (see 12.3)
+%%
+%% Sub-list: a list of several values from a list.
+%% The type of sub-list SHALL also be specified.
+%% The type shall be chosen from the types specified in
+%% this section (with the exception of sub-list). For
+%% example, Type: sub-list of enumeration. The encoding
+%% of sub-lists is specified in Annexes A and B.3.
+%%
+%% Possible values:
+%%
+%% A package MUST specify either a specific set of values or a
+%% description of how values are determined. A package MUST also
+%% specify a default value or the default behaviour when the value
+%% is omitted from its descriptor. For example, a package may
+%% specify that procedures related to the property are suspended
+%% when its value is omitted.
+%%
+%% Default:
+%%
+%% A default value (but not procedures) may be specified as
+%% provisionable.
+%%
+%% Defined in:
+%%
+%% Which H.248.1 descriptor the property is defined in.
+%% LocalControl is for stream-dependent properties.
+%% TerminationState is for stream-independent properties.
+%% ContextAttribute is for properties that affect the context as
+%% a whole, i.e., mixing properties. These are expected to be the
+%% most common cases, but it is possible for properties to be
+%% defined in other descriptors. Context properties MUST be defined
+%% in the ContextAttribute descriptor.
+%%
+%% Characteristics: Read/Write or both, and (optionally), global:
+%%
+%% Indicates whether a property is read-only, or read-write, and
+%% if it is global. If Global is omitted, the property is not
+%% global. If a property is declared as global, the value of the
+%% property is shared by all Terminations realizing the package.
+%% If a context property is declared as global, the property is
+%% shared by all contexts realizing the package.
+%%
+%%
+%% 12.1.3 Events
+%%
+%% Events defined by the package, specifying:
+%%
+%% Event name: only descriptive
+%%
+%% EventID: is an identifier
+%%
+%% Description: a description of the function of the event
+%%
+%% EventsDescriptor Parameters:
+%%
+%% Parameters used by the MGC to configure the event, and found in
+%% the EventsDescriptor. See 12.2. If there are no parameters for
+%% the Events Descriptor, then "none" shall be specified.
+%%
+%% ObservedEventsDescriptor Parameters:
+%%
+%% Parameters returned to the MGC in Notify requests and in replies
+%% to command requests from the MGC that audit
+%% ObservedEventsDescriptor, and found in the
+%% ObservedEventsDescriptor. See 12.2. If there are no parameters
+%% for the ObservedEvents Descriptor, then �none� shall be specified.
+%%
+%%
+%% 12.1.4 Signals
+%%
+%% Signals defined by the package, specifying:
+%%
+%% Signal Name: only descriptive
+%%
+%% SignalID: is an identifier. SignalID is used in a SignalsDescriptor
+%%
+%% Description: a description of the function of the signal
+%%
+%% SignalType: one of:
+%%
+%% OO (On/Off)
+%%
+%% TO (TimeOut)
+%%
+%% BR (Brief)
+%%
+%% NOTE -�SignalType may be defined such that it is dependent on
+%% the value of one or more parameters. The package MUST specify a
+%% default signal type. If the default type is TO, the package MUST
+%% specify a default duration which may be provisioned. A default
+%% duration is meaningless for BR.
+%%
+%% Duration: in hundredths of seconds
+%%
+%% Additional Parameters: see 12.2
+%%
+%%
+%% 12.1.5 Statistics
+%%
+%% Statistics defined by the package, specifying:
+%%
+%% Statistic name: only descriptive
+%%
+%% StatisticID: is an identifier
+%%
+%% StatisticID is used in a StatisticsDescriptor
+%%
+%% Description: a description of the statistic
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 string
+%%
+%% Octet String: A number of octets.
+%% See Annex A and Annex B.3 for encoding
+%%
+%% Integer: 4 byte signed integer
+%%
+%% Double: 8 byte signed integer
+%%
+%% Character: Unicode UTF-8 encoding of a single letter.
+%% Could be more than one octet.
+%%
+%% Enumeration: One of a list of possible unique values (See 12.3)
+%%
+%% Sub-list: A list of several values from a list.
+%% The type of sub-list SHALL also be specified.
+%% The type shall be chosen from the types specified in
+%% this section (with the exception of sub-list).
+%% For example, Type: sub-list of enumeration.
+%% The encoding of sub-lists is specified in Annexes A
+%% and B.3.
+%%
+%% Possible Values:
+%%
+%% A package must indicate the unit of measure, e.g. milliseconds,
+%% packets, either here or along with the type above, as well as
+%% indicating any restriction on the range.
+%%
+%% Level: Specify if the statistic can be kept at the Termination
+%% level, Stream level or Either.
+%%
+%%
+%% 12.1.6 Error Codes
+%%
+%% If the package does not define any error codes, this section may be omitted.
+%% Otherwise, it describes error codes defined by the package, specifying:
+%%
+%% Error Code #: The error code number.
+%%
+%% Name: Name of the error
+%%
+%% Definition: A description of the error code.
+%%
+%% Error Text in the Error Descriptor:
+%%
+%% A description of what text to return in the Error Descriptor.
+%%
+%% Comment: Any further comments on the use of the error code.
+%%
+%%
+%% 12.1.7 Procedures
+%%
+%% Additional guidance on the use of the package.
+%%
+%%
+%% 12.2 Guidelines to defining parameters to events and signals
+%%
+%% Parameter Name: only descriptive
+%%
+%% ParameterID: is an identifier. The textual ParameterID of
+%% parameters to Events and Signals shall not start with "EPA" and
+%% "SPA", respectively. The textual ParameterID shall also not be
+%% "ST", "Stream", "SY", "SignalType", "DR", "Duration", "NC",
+%% "NotifyCompletion", "KA", "KeepActive", "EB", "Embed", "DM",
+%% "DigitMap", "DI", "Direction", "RQ" or "RequestID".
+%%
+%% Description: a description of the function of the parameter.
+%%
+%% Type: One of:
+%%
+%% Boolean
+%%
+%% String: UTF-8 octet string
+%%
+%% Octet String: A number of octets. See Annex A and B.3 for
+%% encoding
+%%
+%% Integer: 4-octet signed integer
+%%
+%% Double: 8-octet signed integer
+%%
+%% Character: Unicode UTF-8 encoding of a single letter. Could be
+%% more than one octet.
+%%
+%% Enumeration: one of a list of possible unique values (see 12.3)
+%%
+%% Sub-list: a list of several values from a list (not supported
+%% for statistics). The type of sub-list SHALL also be
+%% specified The type shall be chosen from the types
+%% specified in this section (with the exception of
+%% sub-list). For example, Type: sub-list of enumeration.
+%% The encoding of sub-lists is specified in Annex A
+%% and B.3.
+%%
+%% Optional: Yes/No
+%%
+%% Describes if the parameter may be omitted from the signal or
+%% event.
+%%
+%% Possible values:
+%%
+%% A package MUST specify either a specific set of values or a
+%% description of how values are determined. A package MUST
+%% also specify a default value or the default behavior when the
+%% value is omitted from its descriptor. For example, a package
+%% may specify that procedures related to the parameter are
+%% suspended when its value is omitted.
+%%
+%% Default:
+%%
+%% A default value (but not procedures) may be specified as
+%% provisionable.
+%%
+%%
+%% 12.3 Lists
+%%
+%% Possible values for parameters include enumerations. Enumerations may be
+%% defined in a list. It is recommended that the list be IANA registered so
+%% that packages that extend the list can be defined without concern for
+%% conflicting names.
+%%
+%%
+%% 12.4 Identifiers
+%%
+%% Identifiers in text encoding shall be strings of up to 64 characters,
+%% containing no spaces, starting with an alphabetic character and consisting
+%% of alphanumeric characters and/or digits, and possibly including the
+%% special character underscore ("_").
+%%
+%% Identifiers in binary encoding are 2 octets long.
+%%
+%% Both text and binary values shall be specified for each identifier,
+%% including identifiers used as values in enumerated types.
+%%
+%%
+%% 12.5 Package registration
+%%
+%% A package can be registered with IANA for interoperability reasons. See
+%% clause 14 for IANA considerations.
+%%
+%%----------------------------------------------------------------------
+
+capabilities() ->
+ [{P, capabilities(P)} || P <- packages()].
+
+%% -record(property, {name, type, values, defined_in, characteristics}).
+
+%%----------------------------------------------------------------------
+%% List all known packages
+%% 'native' and 'all' are not real packages
+%%----------------------------------------------------------------------
+
+packages() ->
+ [
+ "g", % Generic
+ "root", % Base Root Package
+ "tonegen", % Tone Generator Package
+ "tonedet", % Tone Detection Package
+ "dg", % Basic DTMF Generator Package
+ "dd", % DTMF detection Package
+ "cg", % Call Progress Tones Generator Package
+ "cd", % Call Progress Tones Detection Package
+ "al", % Analog Line Supervision Package
+ "ct", % Basic Continuity Package
+ "nt", % Network Package
+ "rtp", % RTP Package
+ "swb", % SwitchBoard Package
+ "tdmc", % TDM Circuit Package
+ "" % Native pseudo package
+ ].
+
+%%----------------------------------------------------------------------
+%% List all matching capabilities
+%%----------------------------------------------------------------------
+
+capabilities(Package) ->
+ case Package of
+ "g" -> capabilities_g();
+ "root" -> capabilities_root();
+ "tonegen" -> capabilities_tonegen();
+ "tonedet" -> capabilities_tonedet();
+ "dg" -> capabilities_dg();
+ "dd" -> capabilities_dd();
+ "cg" -> capabilities_cg();
+ "cd" -> capabilities_cd();
+ "al" -> capabilities_al();
+ "ct" -> capabilities_ct();
+ "nt" -> capabilities_nt();
+ "rtp" -> capabilities_rtp();
+ "swb" -> capabilities_swb();
+ "tdmc" -> capabilities_tdmc();
+ "" -> capabilities_native()
+ end.
+
+%%----------------------------------------------------------------------
+%% Decode package name to internal form
+%% Scope ::= property | event | signal | statistics
+%%----------------------------------------------------------------------
+
+decode(mid, Package) ->
+ decode_mid(Package);
+decode(package, Package) ->
+ decode_package(Package);
+decode(profile, Package) ->
+ decode_profile(Package);
+decode(dialplan, Dialplan) ->
+ decode_dialplan(Dialplan);
+decode(Scope, [A, B | Item]) when is_atom(Scope) ->
+ ?d("decode(~p) -> entry with"
+ "~n A: ~p"
+ "~n B: ~p"
+ "~n Item: ~p", [Scope, A, B, Item]),
+ case decode_package([A, B]) of
+ "" ->
+ ?d("decode -> \"no\" package",[]),
+ decode_item(Scope, [A, B], Item);
+ Package ->
+ ?d("decode -> Package: ~p", [Package]),
+ Package ++ "/" ++ decode_item(Scope, [A, B], Item)
+ end;
+decode({Scope, [A, B | Item]}, SubItem) when is_atom(Scope) ->
+ ?d("decode(~p) -> entry with"
+ "~n A: ~p"
+ "~n B: ~p"
+ "~n Item: ~p"
+ "~n SubItem: ~p", [Scope, A, B, Item, SubItem]),
+ decode_item({Scope, Item}, [A, B], SubItem).
+
+decode_item(Scope, [A, B], Item) ->
+ ?d("decode_item -> entry",[]),
+ case A of
+ 16#00 ->
+ case B of
+ 16#01 -> decode_g(Scope, Item);
+ 16#02 -> decode_root(Scope, Item);
+ 16#03 -> decode_tonegen(Scope, Item);
+ 16#04 -> decode_tonedet(Scope, Item);
+ 16#05 -> decode_dg(Scope, Item);
+ 16#06 -> decode_dd(Scope, Item);
+ 16#07 -> decode_cg(Scope, Item);
+ 16#08 -> decode_cd(Scope, Item);
+ 16#09 -> decode_al(Scope, Item);
+ 16#0a -> decode_ct(Scope, Item);
+ 16#0b -> decode_nt(Scope, Item);
+ 16#0c -> decode_rtp(Scope, Item);
+ 16#0d -> decode_tdmc(Scope, Item);
+ 16#00 -> decode_native(Scope, Item)
+ end;
+ 16#fe ->
+ case B of
+ %% Proprietary extension
+ 16#fe -> decode_swb(Scope, Item)
+ end;
+ 16#ff ->
+ case B of
+ 16#ff when Item =:= [16#ff, 16#ff] -> "*"
+ end
+ end.
+
+decode_package(Package) ->
+ ?d("decode_package -> entry with"
+ "~n Package: ~p", [Package]),
+ [A, B] = Package,
+ case A of
+ 16#00 ->
+ case B of
+ 16#01 -> "g";
+ 16#02 -> "root";
+ 16#03 -> "tonegen";
+ 16#04 -> "tonedet";
+ 16#05 -> "dg";
+ 16#06 -> "dd";
+ 16#07 -> "cg";
+ 16#08 -> "cd";
+ 16#09 -> "al";
+ 16#0a -> "ct";
+ 16#0b -> "nt";
+ 16#0c -> "rtp";
+ 16#0d -> "tdmc";
+ 16#00 -> ""
+ end;
+ 16#fe ->
+ case B of
+ 16#fe -> "swb"
+ end;
+ 16#ff ->
+ case B of
+ 16#ff -> "*"
+ end
+ end.
+
+decode_profile([A, B]) ->
+ case A of
+ 16#00 ->
+ case B of
+ 16#fe -> "resgw";
+ _ -> "profile" ++ [A + $0, B + $0]
+ end;
+ _ ->
+ "profile" ++ [A + $0, B + $0]
+ end.
+
+decode_dialplan([A, B]) ->
+ "dialplan" ++ [A + $0, B + $0].
+
+decode_mid(Mid) ->
+ case Mid of
+ {domainName, DN} ->
+ Lower = to_lower(DN#'DomainName'.name),
+ {domainName, DN#'DomainName'{name = Lower}};
+ {deviceName, PathName} ->
+ Lower = to_lower(PathName),
+ {deviceName, Lower};
+ Other ->
+ Other
+ end.
+
+to_lower(Chars) ->
+ [?LOWER(Char) || Char <- Chars].
+
+%%----------------------------------------------------------------------
+%% Encode package name from internal form
+%% Scope ::= property | event | signal | statistics
+%%----------------------------------------------------------------------
+
+encode(mid, Package) ->
+ encode_mid(Package);
+encode(package, Package) ->
+ encode_package(Package);
+encode(profile, Profile) ->
+ encode_profile(Profile);
+encode(dialplan, Dialplan) ->
+ encode_dialplan(Dialplan);
+encode(Scope, PackageItem) when is_atom(Scope) ->
+ ?d("encode(~p) -> entry with"
+ "~n PackageItem: ~p", [Scope, PackageItem]),
+ case string:tokens(PackageItem, [$/]) of
+ [Package, Item] ->
+ ?d("encode -> "
+ "~n Package: ~p"
+ "~n Item: ~p", [Package, Item]),
+ encode_package(Package) ++ encode_item(Scope, Package, Item);
+ [Item] ->
+ ?d("encode -> Item: ~p", [Item]),
+ [16#00, 16#00 | encode_native(Scope, Item)]
+ end;
+encode({Scope, PackageItem}, SubItem) when is_atom(Scope) ->
+ ?d("encode(~p) -> entry with"
+ "~n PackageItem: ~p"
+ "~n SubItem: ~p", [Scope, PackageItem, SubItem]),
+ case string:tokens(PackageItem, [$/]) of
+ [Package, Item] ->
+ ?d("encode -> "
+ "~n Package: ~p"
+ "~n Item: ~p", [Package, Item]),
+ encode_item({Scope, Item}, Package, SubItem);
+ [_Item] ->
+ ?d("encode -> _Item: ~p", [_Item]),
+ encode_native(Scope, SubItem)
+ end.
+
+encode_item(_Scope, _Package, "*") ->
+ [16#ff, 16#ff];
+encode_item(Scope, Package, Item) ->
+ ?d("encode_item(~s) -> entry", [Package]),
+ case Package of
+ "g" -> encode_g(Scope, Item);
+ "root" -> encode_root(Scope, Item);
+ "tonegen" -> encode_tonegen(Scope, Item);
+ "tonedet" -> encode_tonedet(Scope, Item);
+ "dg" -> encode_dg(Scope, Item);
+ "dd" -> encode_dd(Scope, Item);
+ "cg" -> encode_cg(Scope, Item);
+ "cd" -> encode_cd(Scope, Item);
+ "al" -> encode_al(Scope, Item);
+ "ct" -> encode_ct(Scope, Item);
+ "nt" -> encode_nt(Scope, Item);
+ "rtp" -> encode_rtp(Scope, Item);
+ "tdmc" -> encode_tdmc(Scope, Item);
+ "swb" -> encode_swb(Scope, Item)
+ end.
+
+encode_package(Package) ->
+ case Package of
+ "g" -> [16#00, 16#01];
+ "root" -> [16#00, 16#02];
+ "tonegen" -> [16#00, 16#03];
+ "tonedet" -> [16#00, 16#04];
+ "dg" -> [16#00, 16#05];
+ "dd" -> [16#00, 16#06];
+ "cg" -> [16#00, 16#07];
+ "cd" -> [16#00, 16#08];
+ "al" -> [16#00, 16#09];
+ "ct" -> [16#00, 16#0a];
+ "nt" -> [16#00, 16#0b];
+ "rtp" -> [16#00, 16#0c];
+ "tdmc" -> [16#00, 16#0d];
+ "" -> [16#00, 16#00];
+ "*" -> [16#ff, 16#ff];
+ "swb" -> [16#fe, 16#fe]
+ end.
+
+encode_profile(Profile) ->
+ case Profile of
+ "resgw" ->
+ [16#00, 16#fe];
+ [$p, $r, $o, $f, $i, $l, $e | Name] ->
+ case Name of
+ [A, B] -> [A - $0, B - $0];
+ [B] -> [0, B - $0];
+ [] -> [0, 0]
+ end
+ end.
+
+encode_dialplan(Dialplan) ->
+ case Dialplan of
+ [$d, $i, $a, $l, $p, $l, $a, $n | Name] ->
+ case Name of
+ [A, B] -> [A - $0, B - $0];
+ [B] -> [0, B - $0];
+ [] -> [0, 0]
+ end
+ end.
+
+encode_mid(Mid) ->
+ Mid.
+
+
+%%----------------------------------------------------------------------
+%% Name: g - Generic
+%% Version: 1
+%% Extends: None
+%% Purpose: Generic package for commonly encountered items
+%%----------------------------------------------------------------------
+
+capabilities_g() ->
+ [
+ {event, "cause"},
+ {event, "sc"}
+ ].
+
+encode_g(event, Item) ->
+ case Item of
+ "cause" -> [16#00, 16#01];
+ "sc" -> [16#00, 16#02]
+ end;
+
+encode_g({event_parameter, Item}, SubItem) ->
+ case Item of
+ "cause" ->
+ case SubItem of
+ "Generalcause" -> [16#00, 16#01];
+ "Failurecause" -> [16#00, 16#02]
+ end;
+ "sc" ->
+ case SubItem of
+ "SigID" -> [16#00, 16#01];
+ "Meth" -> [16#00, 16#02];
+ "SLID" -> [16#00, 16#03];
+ "RID" -> [16#00, 16#04]
+ end
+ end.
+
+decode_g(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "cause";
+ [16#00, 16#02] -> "sc"
+ end;
+
+decode_g({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event: cause
+ case SubItem of
+ [16#00, 16#01] -> "Generalcause";
+ [16#00, 16#02] -> "Failurecause"
+ end;
+
+ [16#00, 16#02] -> % Event: sc
+ case SubItem of
+ [16#00, 16#01] -> "SigID";
+ [16#00, 16#02] -> "Meth";
+ [16#00, 16#03] -> "SLID";
+ [16#00, 16#04] -> "RID"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: root - Base Root Package
+%% Version: 2
+%% Extends: None
+%% Purpose: This package defines Gateway wide properties.
+%%----------------------------------------------------------------------
+
+capabilities_root() ->
+ [
+ {property, "maxNumberOfContexts"},
+ {property, "maxTerminationsPerContext"},
+ {property, "normalMGExecutionTime"},
+ {property, "normalMGCExecutionTime"},
+ {property, "MGProvisionalResponseTimerValue"},
+ {property, "MGCProvisionalResponseTimerValue"},
+ {property, "MGCOriginatedPendingLimit"},
+ {property, "MGOriginatedPendingLimit"},
+ {property, "MGSegmentationTimerValue"},
+ {property, "MGCSegmentationTimerValue"},
+ {property, "MGMaxPDUSize"},
+ {property, "MGCMaxPDUSize"}
+ ].
+
+encode_root(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ "maxNumberOfContexts" -> [16#00, 16#01];
+ "maxTerminationsPerContext" -> [16#00, 16#02];
+ "normalMGExecutionTime" -> [16#00, 16#03];
+ "normalMGCExecutionTime" -> [16#00, 16#04];
+ "MGProvisionalResponseTimerValue" -> [16#00, 16#05];
+ "MGCProvisionalResponseTimerValue" -> [16#00, 16#06];
+ "MGCOriginatedPendingLimit" -> [16#00, 16#07];
+ "MGOriginatedPendingLimit" -> [16#00, 16#08];
+ "MGSegmentationTimerValue" -> [16#00, 16#09];
+ "MGCSegmentationTimerValue" -> [16#00, 16#0a];
+ "MGMaxPDUSize" -> [16#00, 16#0b];
+ "MGCMaxPDUSize" -> [16#00, 16#0c]
+ end
+ end.
+
+decode_root(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ [16#00, 16#01] -> "maxNumberOfContexts";
+ [16#00, 16#02] -> "maxTerminationsPerContext";
+ [16#00, 16#03] -> "normalMGExecutionTime";
+ [16#00, 16#04] -> "normalMGCExecutionTime";
+ [16#00, 16#05] -> "MGProvisionalResponseTimerValue";
+ [16#00, 16#06] -> "MGCProvisionalResponseTimerValue";
+ [16#00, 16#07] -> "MGCOriginatedPendingLimit";
+ [16#00, 16#08] -> "MGOriginatedPendingLimit";
+ [16#00, 16#09] -> "MGSegmentationTimerValue";
+ [16#00, 16#0a] -> "MGCSegmentationTimerValue";
+ [16#00, 16#0b] -> "MGMaxPDUSize";
+ [16#00, 16#0c] -> "MGCMaxPDUSize"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tonegen - Tone Generator Package
+%% Version: 2
+%% Extends: None
+%% Purpose: This package defines signals to generate audio tones.
+%% This package does not specify parameter values. It is
+%% intended to be extendable. Generally, tones are defined
+%% as an individual signal with a parameter, ind,
+%% representing "interdigit" time delay, and a tone id to
+%% be used with playtones. A tone id should be kept
+%% consistent with any tone generation for the same tone.
+%% MGs are expected to be provisioned with the characteristics
+%% of appropriate tones for the country in which the MG is located.
+%%----------------------------------------------------------------------
+
+capabilities_tonegen() ->
+ [
+ {signal, "pt"}
+ ].
+
+encode_tonegen(signal, Item) ->
+ case Item of
+ "pt" -> [16#00, 16#01]
+ end;
+
+encode_tonegen({signal_parameter, Item}, SubItem) ->
+ case Item of
+ "pt" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "ind" -> [16#00, 16#02];
+ "btd" -> [16#00, 16#03]
+ end
+ end.
+
+decode_tonegen(signal, Item) ->
+ case Item of
+ [16#00, 16#01] -> "pt"
+ end;
+
+decode_tonegen({signal_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event: pt
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#02] -> "ind";
+ [16#00, 16#03] -> "btd"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tonedet - Tone Detection Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This Package defines events for audio tone detection.
+%% Tones are selected by name (tone id). MGs are expected
+%% to be provisioned with the characteristics of appropriate
+%% tones for the country in which the MG is located.
+%%
+%% This package does not specify parameter values.
+%% It is intended to be extendable.
+%%----------------------------------------------------------------------
+
+capabilities_tonedet() ->
+ [
+ {event, "std"},
+ {event, "etd"},
+ {event, "ltd"}
+ ].
+
+encode_tonedet(event, Item) ->
+ case Item of
+ "std" -> [16#00, 16#01];
+ "etd" -> [16#00, 16#02];
+ "ltd" -> [16#00, 16#03]
+ end;
+
+encode_tonedet({event_parameter, Item}, SubItem) ->
+ case Item of
+ "std" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "tid" -> [16#00, 16#03]
+ end;
+ "etd" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "tid" -> [16#00, 16#03];
+ "dur" -> [16#00, 16#02]
+ end;
+ "ltd" ->
+ case SubItem of
+ "tl" -> [16#00, 16#01];
+ "dur" -> [16#00, 16#02];
+ "tid" -> [16#00, 16#03]
+ end
+ end.
+
+decode_tonedet(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "std";
+ [16#00, 16#02] -> "etd";
+ [16#00, 16#03] -> "ltd"
+ end;
+
+decode_tonedet({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event std
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#03] -> "tid"
+ end;
+ [16#00, 16#02] -> % Event etd
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#03] -> "tid";
+ [16#00, 16#02] -> "dur"
+ end;
+ [16#00, 16#03] -> % Event ltd
+ case SubItem of
+ [16#00, 16#01] -> "tl";
+ [16#00, 16#02] -> "dur";
+ [16#00, 16#03] -> "tid"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: dg - Basic DTMF Generator Package
+%% Version: 1
+%% Extends: tonegen version 1
+%% Purpose: This package defines the basic DTMF tones as signals and
+%% extends the allowed values of parameter tl of playtone
+%% in tonegen.
+%%----------------------------------------------------------------------
+
+capabilities_dg() ->
+ [
+ {signal, "d0"},
+ {signal, "d1"},
+ {signal, "d2"},
+ {signal, "d3"},
+ {signal, "d4"},
+ {signal, "d5"},
+ {signal, "d6"},
+ {signal, "d7"},
+ {signal, "d8"},
+ {signal, "d9"},
+ {signal, "ds"},
+ {signal, "do"},
+ {signal, "da"},
+ {signal, "db"},
+ {signal, "dc"},
+ {signal, "dd"}
+ ].
+
+encode_dg(signal, Item) ->
+ case Item of
+ "d0" -> [16#00, 16#10];
+ "d1" -> [16#00, 16#11];
+ "d2" -> [16#00, 16#12];
+ "d3" -> [16#00, 16#13];
+ "d4" -> [16#00, 16#14];
+ "d5" -> [16#00, 16#15];
+ "d6" -> [16#00, 16#16];
+ "d7" -> [16#00, 16#17];
+ "d8" -> [16#00, 16#18];
+ "d9" -> [16#00, 16#19];
+ "ds" -> [16#00, 16#20];
+ "do" -> [16#00, 16#21];
+ "da" -> [16#00, 16#1a];
+ "db" -> [16#00, 16#1b];
+ "dc" -> [16#00, 16#1c];
+ "dd" -> [16#00, 16#1d]
+ end;
+
+encode_dg({signal_parameter, Item}, SubItem) ->
+ case Item of
+ "d0" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d1" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d2" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d3" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d4" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d5" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d6" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d7" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d8" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d9" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "ds" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "do" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "da" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "db" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dc" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dd" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end
+ end.
+
+decode_dg(signal, Item) ->
+ case Item of
+ [16#00, 16#10] -> "d0";
+ [16#00, 16#11] -> "d1";
+ [16#00, 16#12] -> "d2";
+ [16#00, 16#13] -> "d3";
+ [16#00, 16#14] -> "d4";
+ [16#00, 16#15] -> "d5";
+ [16#00, 16#16] -> "d6";
+ [16#00, 16#17] -> "d7";
+ [16#00, 16#18] -> "d8";
+ [16#00, 16#19] -> "d9";
+ [16#00, 16#20] -> "ds";
+ [16#00, 16#21] -> "do";
+ [16#00, 16#1a] -> "da";
+ [16#00, 16#1b] -> "db";
+ [16#00, 16#1c] -> "dc";
+ [16#00, 16#1d] -> "dd"
+ end;
+
+decode_dg({signal_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#10] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#11] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#12] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#13] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#14] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#15] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#16] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#17] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#18] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#19] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#20] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#21] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1a] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1b] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1c] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1d] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: dd - DTMF detection Package
+%% Version: 1
+%% Extends: tonedet version 1
+%% Purpose: This package defines the basic DTMF tones detection.
+%% Tones are selected by name (tone id). MGs are expected
+%% to be provisioned with the characteristics of appropriate
+%% tones for the country in which the MG is located.
+%%
+%% This package does not specify parameter values.
+%% It is intended to be extendable.
+%%
+%% Additional tone id values are all tone ids described in package dg
+%% (basic DTMF generator package).
+%%
+%% The following table maps DTMF events to digit map symbols as described
+%% in section 7.1.14.
+%%
+%% _________________________________
+%% | DTMF Event | Symbol |
+%% | d0 | "0" |
+%% | d1 | "1" |
+%% | d2 | "2" |
+%% | d3 | "3" |
+%% | d4 | "4" |
+%% | d5 | "5" |
+%% | d6 | "6" |
+%% | d7 | "7" |
+%% | d8 | "8" |
+%% | d9 | "9" |
+%% | da | "A" or "a"|
+%% | db | "B" or "b"|
+%% | dc | "C" or "c"|
+%% | dd | "D" or "d"|
+%% | ds | "E" or "e"|
+%% | do | "F" or "f"|
+%% |___________________|____________|
+%%
+%%----------------------------------------------------------------------
+
+capabilities_dd() ->
+ [
+ {event, "ce"},
+ {event, "d0"},
+ {event, "d1"},
+ {event, "d2"},
+ {event, "d3"},
+ {event, "d4"},
+ {event, "d5"},
+ {event, "d6"},
+ {event, "d7"},
+ {event, "d8"},
+ {event, "d9"},
+ {event, "ds"},
+ {event, "do"},
+ {event, "da"},
+ {event, "db"},
+ {event, "dc"},
+ {event, "dd"}
+ ].
+
+encode_dd(event, Item) ->
+ case Item of
+ "ce" -> [16#00, 16#04];
+ "d0" -> [16#00, 16#10];
+ "d1" -> [16#00, 16#11];
+ "d2" -> [16#00, 16#12];
+ "d3" -> [16#00, 16#13];
+ "d4" -> [16#00, 16#14];
+ "d5" -> [16#00, 16#15];
+ "d6" -> [16#00, 16#16];
+ "d7" -> [16#00, 16#17];
+ "d8" -> [16#00, 16#18];
+ "d9" -> [16#00, 16#19];
+ "ds" -> [16#00, 16#20];
+ "do" -> [16#00, 16#21];
+ "da" -> [16#00, 16#1a];
+ "db" -> [16#00, 16#1b];
+ "dc" -> [16#00, 16#1c];
+ "dd" -> [16#00, 16#1d]
+ end;
+
+encode_dd({event_parameter, Item}, SubItem) ->
+ case Item of
+ "ce" ->
+ case SubItem of
+ "ds" -> [16#00, 16#01];
+ "Meth" -> [16#00, 16#03]
+ end;
+ "d0" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d1" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d2" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d3" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d4" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d5" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d6" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d7" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d8" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "d9" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "ds" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "do" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "da" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "db" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dc" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end;
+ "dd" ->
+ case SubItem of
+ "btd" -> [16#00, 16#01]
+ end
+ end.
+
+decode_dd(event, Item) ->
+ case Item of
+ [16#00, 16#04] -> "ce";
+ [16#00, 16#10] -> "d0";
+ [16#00, 16#11] -> "d1";
+ [16#00, 16#12] -> "d2";
+ [16#00, 16#13] -> "d3";
+ [16#00, 16#14] -> "d4";
+ [16#00, 16#15] -> "d5";
+ [16#00, 16#16] -> "d6";
+ [16#00, 16#17] -> "d7";
+ [16#00, 16#18] -> "d8";
+ [16#00, 16#19] -> "d9";
+ [16#00, 16#20] -> "ds";
+ [16#00, 16#21] -> "do";
+ [16#00, 16#1a] -> "da";
+ [16#00, 16#1b] -> "db";
+ [16#00, 16#1c] -> "dc";
+ [16#00, 16#1d] -> "dd"
+ end;
+
+decode_dd({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#04] -> % Event ce
+ case SubItem of
+ [16#00, 16#01] -> "ds";
+ [16#00, 16#03] -> "Meth"
+ end;
+ [16#00, 16#10] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#11] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#12] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#13] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#14] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#15] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#16] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#17] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#18] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#19] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#20] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#21] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1a] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1b] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1c] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end;
+ [16#00, 16#1d] ->
+ case SubItem of
+ [16#00, 16#01] -> "btd"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: cg - Call Progress Tones Generator Package
+%% Version: 1
+%% Extends: tonegen version 1
+%% Purpose: This package defines the basic call progress tones as signals
+%% and extends the allowed values of the tl parameter of
+%% playtone in tonegen.
+%%----------------------------------------------------------------------
+
+capabilities_cg() ->
+ [
+ {signal, "dt"},
+ {signal, "rt"},
+ {signal, "bt"},
+ {signal, "ct"},
+ {signal, "sit"},
+ {signal, "wt"},
+ {signal, "prt"},
+ {signal, "cw"},
+ {signal, "cr"}
+ ].
+
+
+encode_cg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ "dt" -> [16#00, 16#30];
+ "rt" -> [16#00, 16#31];
+ "bt" -> [16#00, 16#32];
+ "ct" -> [16#00, 16#33];
+ "sit" -> [16#00, 16#34];
+ "wt" -> [16#00, 16#35];
+ "prt" -> [16#00, 16#36];
+ "cw" -> [16#00, 16#37];
+ "cr" -> [16#00, 16#38]
+ end
+ end.
+
+decode_cg(Scope, Item) ->
+ case Scope of
+ signal ->
+ case Item of
+ [16#00, 16#30] -> "dt";
+ [16#00, 16#31] -> "rt";
+ [16#00, 16#32] -> "bt";
+ [16#00, 16#33] -> "ct";
+ [16#00, 16#34] -> "sit";
+ [16#00, 16#35] -> "wt";
+ [16#00, 16#36] -> "prt";
+ [16#00, 16#37] -> "cw";
+ [16#00, 16#38] -> "cr"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: cd - Call Progress Tones Detection Package
+%% Version: 1
+%% Extends: tonedet version 1
+%% Purpose: This package defines the basic call progress detection tones.
+%% This Package extends the possible values of tone id
+%% in the "start tone detected", "end tone detected" and
+%% "long tone detected" events.
+%% Additional values
+%% tone id values are defined for start tone detected,
+%% end tone detected and long tone detected with
+%% the same values as those in package cg (call
+%% progress tones generation package).
+%%
+%% The required set of tone ids corresponds to Recommendation E.180/Q.35
+%% [ITU-T Recommendation E.180/Q.35 (1998)]. See Recommendation E.180/Q.35
+%% for definition of the meanings of these tones.
+%%----------------------------------------------------------------------
+
+capabilities_cd() ->
+ [
+ {event, "dt"},
+ {event, "rt"},
+ {event, "bt"},
+ {event, "ct"},
+ {event, "sit"},
+ {event, "wt"},
+ {event, "prt"},
+ {event, "cw"},
+ {event, "cr"}
+ ].
+
+
+encode_cd(Scope, Item) ->
+ case Scope of
+ event ->
+ case Item of
+ "dt" -> [16#00, 16#30];
+ "rt" -> [16#00, 16#31];
+ "bt" -> [16#00, 16#32];
+ "ct" -> [16#00, 16#33];
+ "sit"-> [16#00, 16#34];
+ "wt" -> [16#00, 16#35];
+ "prt"-> [16#00, 16#36];
+ "cw" -> [16#00, 16#37];
+ "cr" -> [16#00, 16#38]
+ end
+ end.
+
+decode_cd(Scope, Item) ->
+ case Scope of
+ event ->
+ case Item of
+ [16#00, 16#30] -> "dt";
+ [16#00, 16#31] -> "rt";
+ [16#00, 16#32] -> "bt";
+ [16#00, 16#33] -> "ct";
+ [16#00, 16#34] -> "sit";
+ [16#00, 16#35] -> "wt";
+ [16#00, 16#36] -> "prt";
+ [16#00, 16#37] -> "cw";
+ [16#00, 16#38] -> "cr"
+ end
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: al - Analog Line Supervision Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines events and signals for an analog line.
+%%----------------------------------------------------------------------
+
+capabilities_al() ->
+ [
+ {event, "on"},
+ {event, "of"},
+ {event, "fl"},
+ {signal, "ri"}
+ ].
+
+encode_al(event, Item) ->
+ ?d("encode_al(event) -> entry with"
+ "~n Item: ~p", [Item]),
+ case Item of
+ "on" -> [16#00, 16#04];
+ "of" -> [16#00, 16#05];
+ "fl" -> [16#00, 16#06]
+ end;
+
+encode_al({event_parameter, Item}, SubItem) ->
+ ?d("encode_al({event_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ "on" ->
+ case SubItem of
+ "strict" -> [16#00, 16#01];
+ "init" -> [16#00, 16#02]
+ end;
+ "of" ->
+ case SubItem of
+ "strict" -> [16#00, 16#01];
+ "init" -> [16#00, 16#02]
+ end;
+ "fl" ->
+ case SubItem of
+ "mindur" -> [16#00, 16#04];
+ "maxdur" -> [16#00, 16#05]
+ end
+ end;
+
+encode_al(signal, Item) ->
+ ?d("encode_al(signal) -> entry with"
+ "~n Item: ~p", [Item]),
+ case Item of
+ "ri" -> [16#00, 16#02]
+ end;
+
+encode_al({signal_parameter, Item}, SubItem) ->
+ ?d("encode_al({signal_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ "ri" ->
+ case SubItem of
+ "cad" -> [16#00, 16#06];
+ "freq" -> [16#00, 16#07]
+ end
+ end.
+
+decode_al(event, SubItem) ->
+ ?d("decode_al(event) -> entry with"
+ "~n SubItem: ~p", [SubItem]),
+ case SubItem of
+ [16#00, 16#04] -> "on";
+ [16#00, 16#05] -> "of";
+ [16#00, 16#06] -> "fl"
+ end;
+
+decode_al({event_parameter, Item}, SubItem) ->
+ ?d("decode_al({event_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ [16#00,16#04] -> %% Event: on
+ case SubItem of
+ [16#00, 16#01] -> "strict";
+ [16#00, 16#02] -> "init"
+ end;
+ [16#00,16#05] -> %% Event: of
+ case SubItem of
+ [16#00, 16#01] -> "strict";
+ [16#00, 16#02] -> "init"
+ end;
+ [16#00,16#06] -> %% Event: fl
+ case SubItem of
+ [16#00, 16#04] -> "mindur";
+ [16#00, 16#05] -> "maxdur"
+ end
+ end;
+
+decode_al(signal, SubItem) ->
+ ?d("decode_al(signal) -> entry with"
+ "~n SubItem: ~p", [SubItem]),
+ case SubItem of
+ [16#00, 16#02] -> "ri"
+ end;
+
+decode_al({signal_parameter, Item}, SubItem) ->
+ ?d("decode_al({signal_parameter,~p}) -> entry with"
+ "~n SubItem: ~p", [Item, SubItem]),
+ case Item of
+ [16#00,16#02] -> %% Event: ri
+ case SubItem of
+ [16#00, 16#06] -> "cad";
+ [16#00, 16#07] -> "freq"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: ct - Basic Continuity Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines events and signals for continuity test.
+%% The continuity test includes provision of either a loopback
+%% or transceiver functionality.
+%%----------------------------------------------------------------------
+
+capabilities_ct() ->
+ [
+ {event, "cmp"},
+ {signal, "ct"},
+ {signal, "rsp"}
+ ].
+
+encode_ct(event, Item) ->
+ case Item of
+ "cmp" -> [16#00, 16#05]
+ end;
+encode_ct({event_parameter, Item}, SubItem) ->
+ case Item of
+ "cmp" ->
+ case SubItem of
+ "res" -> [16#00, 16#08]
+ end
+ end;
+encode_ct(signal, Item) ->
+ case Item of
+ "ct" -> [16#00, 16#03];
+ "rsp" -> [16#00, 16#04]
+ end.
+
+decode_ct(event, Item) ->
+ case Item of
+ [16#00, 16#05] -> "cmp"
+ end;
+decode_ct({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#05] -> % Event cmp
+ case SubItem of
+ [16#00, 16#08] -> "res"
+ end
+ end;
+decode_ct(signal, Item) ->
+ case Item of
+ [16#00, 16#03] -> "ct";
+ [16#00, 16#04] -> "rsp"
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: nt - Network Package
+%% Version: 1
+%% Extends: None
+%% Purpose: This package defines properties of network terminations
+%% independent of network type.
+%%----------------------------------------------------------------------
+
+capabilities_nt() ->
+ [
+ {property, "jit"},
+ {event, "netfail"},
+ {event, "qualert"},
+ {statistics, "dur"},
+ {statistics, "os"},
+ {statistics, "or"}
+ ].
+
+encode_nt(property, Item) ->
+ case Item of
+ "jit" -> [16#00, 16#07]
+ end;
+encode_nt(event, Item) ->
+ case Item of
+ "netfail" -> [16#00, 16#05];
+ "qualert" -> [16#00, 16#06]
+ end;
+encode_nt({event_parameter, Item}, SubItem) ->
+ case Item of
+ "netfail" ->
+ case SubItem of
+ "cs" -> [16#00, 16#01]
+ end;
+ "qualert" ->
+ case SubItem of
+ "th" -> [16#00, 16#01]
+ end
+ end;
+encode_nt(statistics, Item) ->
+ case Item of
+ "dur" -> [16#00, 16#01];
+ "os" -> [16#00, 16#02];
+ "or" -> [16#00, 16#03]
+ end.
+
+decode_nt(property, Item) ->
+ case Item of
+ [16#00, 16#07] -> "jit"
+ end;
+decode_nt(event, Item) ->
+ case Item of
+ [16#00, 16#05] -> "netfail";
+ [16#00, 16#06] -> "qualert"
+ end;
+decode_nt({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#05] -> % Event netfail
+ case SubItem of
+ [16#00, 16#01] -> "cs"
+ end;
+ [16#00, 16#06] -> % Event qualert
+ case Item of
+ [16#00, 16#01] -> "th"
+ end
+ end;
+decode_nt(statistics, Item) ->
+ case Item of
+ [16#00, 16#01] -> "dur";
+ [16#00, 16#02] -> "os";
+ [16#00, 16#03] -> "or"
+ end.
+
+%%----------------------------------------------------------------------
+%% Name: rtp - RTP Package
+%% Version: 1
+%% Extends: nt version 1
+%% Purpose: This package is used to support packet based multimedia
+%% data transfer by means of the Real-time Transport Protocol
+%% (RTP) [RFC 1889].
+%%----------------------------------------------------------------------
+
+capabilities_rtp() ->
+ [
+ {event, "pltrans"},
+ {statistics, "ps"},
+ {statistics, "pr"},
+ {statistics, "pl"},
+ {statistics, "jit"},
+ {statistics, "delay"}
+ ].
+
+encode_rtp(event, Item) ->
+ case Item of
+ "pltrans" -> [16#00, 16#01]
+ end;
+encode_rtp({event_parameter, Item}, SubItem) ->
+ case Item of
+ "pltrans" ->
+ case SubItem of
+ "rtppltype" -> [16#00, 16#01]
+ end
+ end;
+encode_rtp(statistics, Item) ->
+ case Item of
+ "ps" -> [16#00, 16#04];
+ "pr" -> [16#00, 16#05];
+ "pl" -> [16#00, 16#06];
+ "jit" -> [16#00, 16#07];
+ "delay" -> [16#00, 16#08]
+ end.
+
+decode_rtp(event, Item) ->
+ case Item of
+ [16#00, 16#01] -> "pltrans"
+ end;
+decode_rtp({event_parameter, Item}, SubItem) ->
+ case Item of
+ [16#00, 16#01] -> % Event pltrans
+ case SubItem of
+ [16#00, 16#01] -> "rtppltype"
+ end
+ end;
+decode_rtp(statistics, Item) ->
+ case Item of
+ [16#00, 16#04] -> "ps";
+ [16#00, 16#05] -> "pr";
+ [16#00, 16#06] -> "pl";
+ [16#00, 16#07] -> "jit";
+ [16#00, 16#08] -> "delay"
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: tdmc - TDM Circuit Package
+%% Version: 1
+%% Extends: nt version 1
+%% Purpose: This package is used to support TDM circuit terminations.
+%%----------------------------------------------------------------------
+
+capabilities_tdmc() ->
+ [
+ {property, "ec"},
+ {property, "gain"}
+ ].
+
+encode_tdmc(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ "ec" -> [16#00, 16#08];
+ "gain" -> [16#00, 16#0a]
+ end
+ end.
+
+decode_tdmc(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ [16#00, 16#08] -> "ec";
+ [16#00, 16#0a] -> "gain"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: swb - SwitchBoard Package
+%% Version: 1
+%% Extends: none
+%% Purpose: This package is used to support SwitchBoard specials
+%%----------------------------------------------------------------------
+
+capabilities_swb() ->
+ [
+ {statistics, "fs"}, % Free slots
+ {statistics, "as"} % Allocated slots
+ ].
+
+encode_swb(Scope, Item) ->
+ case Scope of
+ statistics ->
+ case Item of
+ "fs" -> [16#00, 16#00];
+ "as" -> [16#00, 16#01]
+ end
+ end.
+
+decode_swb(Scope, Item) ->
+ case Scope of
+ statistics ->
+ case Item of
+ [16#00, 16#00] -> "fs";
+ [16#00, 16#01] -> "as"
+ end
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Name: native - Pseudo package
+%% Version: 1
+%% Extends: None
+%% Purpose: Native tags for media stream properties
+%%
+%% Parameters for Local descriptors and Remote descriptors are
+%% specified as tag-value pairs if binary encoding is used for the
+%% protocol. This annex contains the property names (PropertyID), the
+%% tags (Property Tag), type of the property (Type) and the values
+%% (Value).Values presented in the Value field when the field contains
+%% references shall be regarded as "information". The reference
+%% contains the normative values. If a value field does not contain a
+%% reference then the values in that field can be considered as
+%% "normative".
+%%
+%% Tags are given as hexadecimal numbers in this annex. When setting
+%% the value of a property, a MGC may underspecify the value according
+%% to one of the mechanisms specified in section 7.1.1.
+%%
+%% For type "enumeration" the value is represented by the value in brack-
+%% ets, e.g., Send(0), Receive(1).
+%%----------------------------------------------------------------------
+%%
+%% C.6. IP
+%%
+%% ________________________________________________________________
+%% | PropertyID| Tag | Type | Value |
+%% | IPv4 | 6001 | 32 BITS | Ipv4Address |
+%% | IPv6 | 6002 | 128 BITS | IPv6 Address |
+%% | Port | 6003 | Unsigned Int| Port |
+%% | Porttype | 6004 | Enumerated | TCP(0),UDP(1),SCTP(2)|
+%% |___________|____________|______________|_______________________|
+%%
+%%
+%% C.11. SDP Equivalents
+%%
+%% ______________________________________________________________
+%% | PropertyID| Tag | Type | Value |
+%% | SDP_V | B001| STRING| Protocol Version |
+%% | SDP_O | B002| STRING| Owner-creator and session ID |
+%% | SDP_S | B003| STRING| Sesson name |
+%% | SDP_I | B004| STRING| Session identifier |
+%% | SDP_U | B005| STRING| URI of descriptor |
+%% | SDC_E | B006| STRING| email address |
+%% | SDP_P | B007| STRING| phone number |
+%% | SDP_C | B008| STRING| Connection information |
+%% | SDP_B | B009| STRING| Bandwidth Information |
+%% | SDP_Z | B00A| STRING| time zone adjustment |
+%% | SDP_K | B00B| STRING| Encryption Key |
+%% | SDP_A | B00C| STRING| Zero or more session attributes|
+%% | SDP_T | B00D| STRING| Active Session Time |
+%% | SDP_R | B00E| STRING| Zero or more repeat times |
+%% | SDP_M | B00F| STRING| Media name and transport addr |
+%% | | | | Reference: IETF RFC 2327 |
+%% |___________|______|________|_________________________________|
+%%
+%%----------------------------------------------------------------------
+
+capabilities_native() ->
+ [
+ %% C.6. IP
+ {property, "IPv4"},
+ {property, "IPv6"},
+ {property, "Port"},
+ {property, "Porttype"},
+
+ %% C.11. SDP Equivalents
+ {property, "v"},
+ {property, "o"},
+ {property, "s"},
+ {property, "i"},
+ {property, "u"},
+ {property, "e"},
+ {property, "p"},
+ {property, "c"},
+ {property, "b"},
+ {property, "z"},
+ {property, "k"},
+ {property, "a"},
+ {property, "t"},
+ {property, "r"},
+ {property, "m"}
+ ].
+
+encode_native(Scope, Item) ->
+ case Scope of
+ property ->
+ case Item of
+ %% IP
+ "IPv4" -> [16#60, 16#01];
+ "IPv6" -> [16#60, 16#02];
+ "Port" -> [16#60, 16#03];
+ "Porttype" -> [16#60, 16#04];
+
+ %% SDP
+ "v" -> [16#b0, 16#01];
+ "o" -> [16#b0, 16#02];
+ "s" -> [16#b0, 16#03];
+ "i" -> [16#b0, 16#04];
+ "u" -> [16#b0, 16#05];
+ "e" -> [16#b0, 16#06];
+ "p" -> [16#b0, 16#07];
+ "c" -> [16#b0, 16#08];
+ "b" -> [16#b0, 16#09];
+ "z" -> [16#b0, 16#0a];
+ "k" -> [16#b0, 16#0b];
+ "a" -> [16#b0, 16#0c];
+ "t" -> [16#b0, 16#0d];
+ "r" -> [16#b0, 16#0e];
+ "m" -> [16#b0, 16#0f]
+ end
+ end.
+
+decode_native(Scope, [Type, Item]) ->
+ case Scope of
+ property ->
+ case Type of
+ 16#60 ->
+ case Item of
+ 16#01 -> "IPv4";
+ 16#02 -> "IPv6";
+ 16#03 -> "Port";
+ 16#04 -> "Porttype"
+ end;
+
+ 16#b0 ->
+ case Item of
+ 16#01 -> "v";
+ 16#02 -> "o";
+ 16#03 -> "s";
+ 16#04 -> "i";
+ 16#05 -> "u";
+ 16#06 -> "e";
+ 16#07 -> "p";
+ 16#08 -> "c";
+ 16#09 -> "b";
+ 16#0a -> "z";
+ 16#0b -> "k";
+ 16#0c -> "a";
+ 16#0d -> "t";
+ 16#0e -> "r";
+ 16#0f -> "m"
+ end
+ end
+ end.
+
+%% -------------------------------------------------------------------
+
+% error(Reason) ->
+% erlang:error(Reason).
+
diff --git a/lib/megaco/src/binary/megaco_binary_term_id.erl b/lib/megaco/src/binary/megaco_binary_term_id.erl
new file mode 100644
index 0000000000..f975c1ab53
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_term_id.erl
@@ -0,0 +1,187 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose : Handle ASN.1 BER encoding of Megaco/H.248
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_term_id).
+
+
+%%----------------------------------------------------------------------
+%% Include files
+%%----------------------------------------------------------------------
+
+-include_lib("megaco/include/megaco.hrl").
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+
+
+%%----------------------------------------------------------------------
+%% External exports
+%%----------------------------------------------------------------------
+
+-export([encode/2, decode/2]).
+
+
+%%----------------------------------------------------------------------
+%% Internal exports
+%%----------------------------------------------------------------------
+
+
+%%----------------------------------------------------------------------
+%% Macros
+%%----------------------------------------------------------------------
+
+-define(default_config, [8,8,8]).
+
+-define(asn_root_termination_id,
+ #'TerminationID'{wildcard = [],
+ id = [16#FF, 16#FF, 16#FF, 16#FF,
+ 16#FF, 16#FF, 16#FF, 16#FF]}).
+
+-define(megaco_all_wildcard_termination_id,
+ #megaco_term_id{contains_wildcards = true,
+ id = [[?megaco_all]]}).
+-define(megaco_choose_wildcard_termination_id,
+ #megaco_term_id{contains_wildcards = true,
+ id = [[?megaco_choose]]}).
+
+
+%%----------------------------------------------------------------------
+%% Convert a 'TerminationId' record into a ASN.1 termination id
+%% Return {ok, TermId} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode(_Config, TermId) when TermId =:= ?megaco_root_termination_id ->
+ {ok, ?asn_root_termination_id};
+encode(Config, TermId) when (TermId =:= ?megaco_all_wildcard_termination_id) andalso
+ (Config =:= ?default_config) ->
+ {ok, asn_all_tid()};
+encode(Config, TermId) when (TermId =:= ?megaco_choose_wildcard_termination_id) andalso
+ (Config =:= ?default_config) ->
+ {ok, asn_choose_tid()};
+encode(Config, #megaco_term_id{contains_wildcards = false, id = IDs}) ->
+ case (catch encode1(IDs,Config)) of
+ {'EXIT',Reason} ->
+ {error,Reason};
+ EncodedTid ->
+ {ok, EncodedTid}
+ end;
+encode(Config, #megaco_term_id{contains_wildcards = true, id = IDs}) ->
+ case (catch encode2(IDs,Config)) of
+ {'EXIT',Reason} ->
+ {error,Reason};
+ EncodedTid ->
+ {ok, EncodedTid}
+ end;
+encode(_Config, TermId) ->
+ {error, {bad_type, TermId}}.
+
+
+first_bit() ->
+ lists:sum(?default_config) - 1.
+asn_all_tid() ->
+ #'TerminationID'{wildcard = [[(2#11000000 + first_bit())]],
+ id = [0, 0, 0]}.
+asn_choose_tid() ->
+ #'TerminationID'{wildcard = [[(2#01000000 + first_bit())]],
+ id = [0, 0, 0]}.
+
+
+%%----------------------------------------------------------------------
+%% Encode without wildcards
+%%----------------------------------------------------------------------
+encode1(IDs,LevelConfig) when is_list(LevelConfig) ->
+ megaco_binary_term_id_gen:encode_without_wildcards(IDs, LevelConfig);
+
+
+%% This is only temporary. Eventually a proper encoder for this case
+%% should be implemented
+encode1(IDs,LevelConfig) when is_integer(LevelConfig) ->
+ %% megaco_binary_term_id_8lev:encode_without_wildcards(IDs, LevelConfig).
+ encode1(IDs,lists:duplicate(LevelConfig,8)).
+
+
+%%----------------------------------------------------------------------
+%% Encode with wildcards
+%%----------------------------------------------------------------------
+encode2(IDs,LevelConfig) when is_list(LevelConfig) ->
+ megaco_binary_term_id_gen:encode_with_wildcards(IDs, LevelConfig);
+
+
+%% This is only temporary. Eventually a proper encoder for this case
+%% should be implemented
+encode2(IDs,LevelConfig) when is_integer(LevelConfig) ->
+ %% megaco_binary_term_id_8lev:encode_with_wildcards(IDs, LevelConfig).
+ encode2(IDs,lists:duplicate(LevelConfig,8)).
+
+
+%%----------------------------------------------------------------------
+%% Convert a ASN.1 termination id into a 'TerminationId' record
+%% Return {ok, TerminationId} | {error, Reason}
+%%----------------------------------------------------------------------
+
+decode(_Config, TermId) when (TermId =:= ?asn_root_termination_id) ->
+ {ok, ?megaco_root_termination_id};
+decode(Config, #'TerminationID'{wildcard = [], id = IDs}) ->
+ case (catch decode1(IDs,Config)) of
+ {'EXIT',Reason} ->
+ {error,Reason};
+ MegacoTid ->
+ {ok,MegacoTid}
+ end;
+decode(Config, #'TerminationID'{wildcard = Wildcards, id = IDs}) ->
+ case (catch decode2(Wildcards,IDs,Config)) of
+ {'EXIT',Reason} ->
+ {error,Reason};
+ MegacoTid ->
+ {ok,MegacoTid}
+ end;
+decode(_Config, TermId) ->
+ {error, {bad_type, TermId}}.
+
+
+%%----------------------------------------------------------------------
+%% Decode without wildcards
+%%----------------------------------------------------------------------
+decode1(IDs, Lc) when is_list(Lc) ->
+ megaco_binary_term_id_gen:decode_without_wildcards(IDs, Lc);
+
+%% This is only temporary. Eventually a proper encoder for this case
+%% should be implemented
+decode1(IDs, Lc) when is_integer(Lc) ->
+ %% megaco_binary_term_id_8lev:decode_without_wildcards(IDs, Lc).
+ decode1(IDs,lists:duplicate(Lc,8)).
+
+
+%%----------------------------------------------------------------------
+%% Decode with wildcards
+%%----------------------------------------------------------------------
+decode2(Wildcards, IDs, Lc) when is_list(Lc) ->
+ megaco_binary_term_id_gen:decode_with_wildcards(Wildcards, IDs, Lc);
+
+%% This is only temporary. Eventually a proper encoder for this case
+%% should be implemented
+decode2(Wildcards, IDs, Lc) when is_integer(Lc) ->
+ %% megaco_binary_term_id_8lev:decode_with_wildcards(Wildcards, IDs, Lc);
+ decode2(Wildcards, IDs, lists:duplicate(Lc,8)).
+
+
+
diff --git a/lib/megaco/src/binary/megaco_binary_term_id_gen.erl b/lib/megaco/src/binary/megaco_binary_term_id_gen.erl
new file mode 100644
index 0000000000..c8192c79b6
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_term_id_gen.erl
@@ -0,0 +1,436 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose : Handle ASN.1 BER encoding of Megaco/H.248
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_term_id_gen).
+
+
+%%----------------------------------------------------------------------
+%% Include files
+%%----------------------------------------------------------------------
+
+-include_lib("megaco/include/megaco.hrl").
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+
+
+%%----------------------------------------------------------------------
+%% External exports
+%%----------------------------------------------------------------------
+
+-export([encode_without_wildcards/2, encode_with_wildcards/2,
+ decode_without_wildcards/2, decode_with_wildcards/3]).
+
+
+%%----------------------------------------------------------------------
+%% Internal exports
+%%----------------------------------------------------------------------
+
+
+%%----------------------------------------------------------------------
+%% Macros
+%%----------------------------------------------------------------------
+
+-define(asn_choose, ?megaco_choose).
+-define(asn_all, ?megaco_all).
+
+
+%%----------------------------------------------------------------------
+%% Encode without wildcards
+%%----------------------------------------------------------------------
+encode_without_wildcards(IDs,LevelConfig) when is_list(LevelConfig) ->
+ EncodedIDs = encode_ids(false,IDs,LevelConfig),
+ #'TerminationID'{wildcard = [], id = EncodedIDs}.
+
+%%----------------------------------------------------------------------
+%% Encode with wildcards
+%%----------------------------------------------------------------------
+encode_with_wildcards(IDs,LevelConfig) when is_list(LevelConfig) ->
+ Wildcards = encode_wildcards(IDs,LevelConfig),
+ EncodedIDs = encode_ids(true,IDs,LevelConfig),
+ #'TerminationID'{wildcard = Wildcards, id = EncodedIDs}.
+
+
+%%----------------------------------------------------------------------
+%% Decode without wildcards
+%%----------------------------------------------------------------------
+decode_without_wildcards(IDs,Lc) ->
+ DecodedIDs = decode_ids(IDs,Lc),
+ #megaco_term_id{contains_wildcards = false,
+ id = DecodedIDs}.
+
+
+%%----------------------------------------------------------------------
+%% Decode with wildcards
+%%----------------------------------------------------------------------
+decode_with_wildcards(Wildcards,IDs,Lc) ->
+ DecodedIDs = decode_ids(Wildcards,IDs,Lc),
+ #megaco_term_id{contains_wildcards = true,
+ id = DecodedIDs}.
+
+
+%%----------------------------------------------------------------------
+%% Convert an internal TermId to an external
+%%----------------------------------------------------------------------
+
+encode_wildcards(IDs,LevelConfig) ->
+ case (catch encode_wildcards1(IDs,LevelConfig)) of
+ {'EXIT',id_config_mismatch} ->
+ exit({id_config_mismatch,IDs,LevelConfig});
+ {'EXIT',Reason} ->
+ exit(Reason);
+ Wildcards ->
+ encode_wildcards2(Wildcards)
+ end.
+
+encode_wildcards1(IDs,LevelConfig) ->
+ encode_wildcards3(IDs,LevelConfig).
+
+encode_wildcards2(Ws) ->
+ F = fun(no_wildcard) -> false; (_) -> true end,
+ lists:filter(F,Ws).
+
+
+
+encode_wildcards3(IDs,LevelConfig) ->
+ encode_wildcards3(IDs,LevelConfig,1,lists:sum(LevelConfig)).
+
+encode_wildcards3([],[],_,_) ->
+ [];
+encode_wildcards3([Level|Levels],[BitsInLevel|BitsRest],LevelNo,TotSize) ->
+ case (catch encode_wildcard(Level,BitsInLevel,TotSize-BitsInLevel,
+ length(Levels))) of
+ {'EXIT',{Reason,Info}} ->
+ exit({Reason,{LevelNo,Info}});
+
+ no_wildcard ->
+ encode_wildcards3(Levels,BitsRest,LevelNo+1,TotSize-BitsInLevel);
+
+ {level,Wl} ->
+ [Wl|
+ encode_wildcards3(Levels,BitsRest,LevelNo+1,TotSize-BitsInLevel)];
+
+ {recursive,Wr} ->
+ [Wr];
+
+ Else ->
+ exit({wildcard_decode_error,Else})
+ end;
+encode_wildcards3(Levels,[],LevelNo,TotSize) ->
+ exit({id_config_mismatch,{Levels,LevelNo,TotSize}});
+encode_wildcards3(L,B,N,S) ->
+ exit({wildcard_encode_error,{L,B,N,S}}).
+
+
+encode_wildcard([],0,_TotBits,_RemainingIdLevels) ->
+ no_wildcard;
+encode_wildcard([],More,_TotBits,_RemainingIdLevels) ->
+ exit({to_few_bits_in_level,More});
+encode_wildcard(More,0,_TotBits,_RemainingIdLevels) ->
+ exit({to_many_bits_in_level,More});
+encode_wildcard([$0|R],Pos,TotBits,RemainingIdLevels) ->
+ encode_wildcard(R,Pos-1,TotBits,RemainingIdLevels);
+encode_wildcard([$1|R],Pos,TotBits,RemainingIdLevels) ->
+ encode_wildcard(R,Pos-1,TotBits,RemainingIdLevels);
+encode_wildcard([?asn_choose],Pos,TotBits,RemainingIdLevels) ->
+ encode_choose(Pos-1,TotBits,RemainingIdLevels);
+encode_wildcard([?asn_all],Pos,TotBits,RemainingIdLevels) ->
+ encode_all(Pos-1,TotBits,RemainingIdLevels);
+encode_wildcard([Val|_Rest],Pos,_TotBits,_RemainingIdLevels) ->
+ exit({invalid_level_content,{Pos-1,Val}}).
+
+%% This is the last level specified in the id list.
+%% Therefor it is a 'recursive' wildcard, i.e. the 'choose'
+%% apply to this level and all remaining levels.
+encode_choose(BitPosInLevel,BitsInRemainingConfigLevels,0)
+ when BitsInRemainingConfigLevels > 0 ->
+ {recursive,[16#40 + BitPosInLevel + BitsInRemainingConfigLevels]};
+
+%% The fact that there is no more bits in the level config
+%% means that this is actually the last level.
+%% It should not be a 'recursive' case but a 'level' case.
+%% Although it is (propably) correct with both.
+encode_choose(BitPosInLevel,0,0) ->
+ {recursive,[16#00 + BitPosInLevel]};
+
+%% There are more levels specified in the id list.
+%% Therefor it is a 'level' wildcard, i.e. the 'choose'
+%% apply to this level only.
+encode_choose(BitPosInLevel,BitsInRemainingConfigLevels,RemainingIdLevels)
+ when RemainingIdLevels > 0 ->
+ {level,[16#00 + BitPosInLevel + BitsInRemainingConfigLevels]}.
+
+%% This is the last level specified in the id list.
+%% Therefor it is a 'recursive' wildcard, i.e. the 'all'
+%% apply to this level and all remaining levels.
+encode_all(BitPosInLevel,BitsInRemainingConfigLevels,0)
+ when BitsInRemainingConfigLevels > 0 ->
+ {recursive,[16#c0 + BitPosInLevel + BitsInRemainingConfigLevels]};
+
+%% The fact that there is no more bits in the level config
+%% means that this is actually the last level.
+%% It should not be a 'recursive' case but a 'level' case.
+%% Although it is (propably) correct with both.
+encode_all(BitPosInLevel,0,0) ->
+ {recursive,[16#80 + BitPosInLevel]};
+
+%% There are more levels specified in the id list.
+%% Therefor it is a 'level' wildcard, i.e. the 'all'
+%% apply to this level only.
+encode_all(BitPosInLevel,BitsInRemainingConfigLevels,RemainingIdLevels)
+ when RemainingIdLevels > 0 ->
+ {level,[16#80 + BitPosInLevel + BitsInRemainingConfigLevels]}.
+
+
+encode_ids(W,IDs,Config) ->
+ encode_ids(W,IDs,Config,8,[0],false).
+
+encode_ids(_,[],[],8,[0|EncodedIDs],_) ->
+ lists:reverse(EncodedIDs);
+encode_ids(W,IDs,Config,0,EncodedIDs,Wf) ->
+ encode_ids(W,IDs,Config,8,[0|EncodedIDs],Wf);
+encode_ids(W,[L|Ls],[C|Cs],R,E,_) ->
+ case (catch encode_id_level(W,L,C,R,E)) of
+ {'EXIT',Reason} ->
+ exit(Reason);
+ {true,R1,E1} when (length(Ls) =:= 0) ->
+ encode_ids2(Cs,encode_ids1(R1,E1));
+ {WildcardFound1,R1,E1} ->
+ encode_ids(W,Ls,Cs,R1,E1,WildcardFound1);
+ {true,E2} when (length(Ls) =:= 0) ->
+ encode_ids2(Cs,E2);
+ {WildcardFound2,E2} ->
+ encode_ids(W,Ls,Cs,8,[0|E2],WildcardFound2)
+ end;
+encode_ids(W,[[]],C,R,E,Wf) when length(C) > 0 ->
+ exit({empty_last_level,{W,C,R,E,Wf}});
+encode_ids(W,[],C,R,E,false) when length(C) > 0 ->
+ exit({unexpected_eof_data,{W,C,R,E}}).
+
+encode_ids1(_R,[0|Es]) ->
+ [0|Es];
+encode_ids1(R,[E|Es]) ->
+ [(E bsl R)|Es].
+
+encode_ids2([],Es) ->
+ lists:reverse(Es);
+encode_ids2(Cs,Es) ->
+ Fill = lists:duplicate(lists:sum(Cs) div 8,0),
+ lists:reverse(Fill ++ Es).
+
+
+encode_id_level(W,L,C,R,[E|Es]) ->
+ case encode_id_level1(W,L,C,R,E) of
+ %% End Of Byte (more bits in level)
+ {eob,_WildcardFound,L1,C1,E1} ->
+ encode_id_level(W,L1,C1,8,[0,E1|Es]);
+
+ %% End Of Level (more room in byte)
+ {eol,WildcardFound,R1,E1} ->
+ {WildcardFound,R1,[E1|Es]};
+
+ %% Done; Level used up all of the byte
+ {done,WildcardFound,E1} ->
+ {WildcardFound,[E1|Es]}
+ end.
+
+
+encode_id_level1(_W,[],0,0,E) ->
+ {done,false,E};
+encode_id_level1(_W,[],0,R,E) ->
+ {eol,false,R,E};
+encode_id_level1(_W,L,C,0,E) ->
+ {eob,false,L,C,E};
+encode_id_level1(W,[$0|L],C,R,E) ->
+ encode_id_level1(W,L,C-1,R-1,E bsl 1);
+encode_id_level1(W,[$1|L],C,R,E) ->
+ encode_id_level1(W,L,C-1,R-1,(E bsl 1) + 1);
+encode_id_level1(true,[$$],C,R,E) ->
+ encode_id_level2(C,R,E,$$);
+encode_id_level1(true,[$*],C,R,E) ->
+ encode_id_level2(C,R,E,$*);
+encode_id_level1(false,[$$],C,R,_E) ->
+ exit({wildcard_error,{$$,C,R}});
+encode_id_level1(false,[$*],C,R,_E) ->
+ exit({wildcard_error,{$*,C,R}});
+encode_id_level1(_W,[L|_Ls],C,R,_E) ->
+ exit({invalid_level_content,{C,R,L}}).
+
+encode_id_level2(C,C,E,_W) ->
+ {done,true,E bsl C};
+encode_id_level2(C,R,E,W) when C > R ->
+ {eob,true,[W],C-R,E bsl R};
+encode_id_level2(C,R,E,_W) ->
+ {eol,true,R-C,E bsl C}.
+
+
+%%----------------------------------------------------------------------
+%% Convert an external TermId to an internal
+%%----------------------------------------------------------------------
+
+%% Decode ID with wildcards
+decode_ids(Ws,IDs,Config) when is_list(Config) ->
+ IDs1 = decode_ids(IDs,Config),
+ Ws1 = decode_wildcards(Ws,(length(IDs)*8) - 1),
+ decode_ids1(Ws1,IDs1);
+
+%% This is only temporary. Eventually a proper encoder for this case
+%% should be implemented.
+%% This is the case when each level is 8 bits = 1 byte and the config
+%% simply indicates the number of (1 byte) levels
+decode_ids(Ws,IDs,Config) when is_integer(Config) ->
+ decode_ids(Ws,IDs,lists:duplicate(Config,8)).
+
+
+%% Decode ID without wildcards
+decode_ids(E,Config) when is_list(Config) ->
+ decode_ids(0,E,Config,[]);
+
+%% This is only temporary. Eventually a proper encoder for this case
+%% should be implemented.
+%% This is the case when each level is 8 bits = 1 byte and the config
+%% simply indicates the number of (1 byte) levels
+decode_ids(E,Config) when is_integer(Config) ->
+ decode_ids(E,lists:duplicate(Config,8)).
+
+
+%% The [0] is the result of all the bits of the byte has been shifted out.
+decode_ids(_B,[0],[],Acc) ->
+ lists:reverse(Acc);
+decode_ids(_B,[E],[],Acc) ->
+ exit({id_config_mismatch,{two_much_data,E,Acc}});
+decode_ids(_B,E,[],Acc) ->
+ exit({id_config_mismatch,{two_much_data,E,Acc}});
+decode_ids(B,E,[L|Ls],Acc) ->
+ case (catch decode_id_level(B,E,L,[])) of
+ {Level,E1,B1} ->
+ decode_ids(B1,E1,Ls,[Level|Acc]);
+ {'EXIT',{id_config_mismatch,{Bx,Ex,Lx,Accx}}} ->
+ exit({id_level_mismatch,{B,Bx,E,Ex,L,Ls,Lx,Acc,Accx}})
+ end.
+
+
+decode_wildcards(Ws,NofBits) ->
+ lists:keysort(3,[decode_wildcard(W,NofBits) || W <- Ws]).
+
+
+%% ----------------------------------------------------------------------
+%% A decoded wildcard is a three tuple:
+%% {wildcard_type(), wildcard_level(), wildcard_offset()}
+%% wildcard_type() -> $ | *
+%% wildcard_level() -> level | recursive
+%% wildcard_offset() -> integer()
+%%
+%% The "raw" wildcard offset is measured from the end of the id bytes:
+%%
+%% 0 1 2 3 4 5 6 7
+%% -----------------
+%% | | | | | | | | |
+%% -----------------
+%%
+%% |<--------|
+%% 5
+%%
+%% The decoded wildcard offset in contrast is measured from the start
+%% of the id field:
+%%
+%% 0 1 2 3 4 5 6 7
+%% -----------------
+%% | | | | | | | | |
+%% -----------------
+%%
+%% |---->|
+%% 3
+%%
+
+decode_wildcard([W],NofBits) ->
+ {decode_wildcard_t(W band 16#80),
+ decode_wildcard_l(W band 16#40),
+ NofBits - (W band 16#3F)}.
+
+decode_wildcard_t(16#80) -> ?asn_all;
+decode_wildcard_t(16#00) -> ?asn_choose.
+
+decode_wildcard_l(16#00) -> level;
+decode_wildcard_l(16#40) -> recursive.
+
+
+decode_ids1(W,IDs) ->
+ lists:reverse(decode_ids1(W,IDs,0,[])).
+
+decode_ids1([],IDs,_,Acc) ->
+ lists:reverse(IDs) ++ Acc;
+decode_ids1([{Type,recursive,Offset}],IDs,Bp,Acc) ->
+ decode_ids2(Type,Offset,IDs,Bp,Acc);
+decode_ids1([{Type,level,Offset}|Ws],IDs,Bp,Acc) ->
+ {IDs1,IDs2,Bp1} = decode_ids3(Type,Offset,IDs,Bp,[]),
+ decode_ids1(Ws,IDs2,Bp1,IDs1++Acc);
+decode_ids1(Ws,_,_,_) ->
+ exit({invalid_wildcards,Ws}).
+
+
+%% Called when recursive wildcard found
+decode_ids2(Type,Offset,[ID|IDs],Bp,Acc) ->
+ LevelSz = length(ID),
+ Bp1 = Offset-Bp,
+ case Bp1 >= LevelSz of
+ true ->
+ decode_ids2(Type,Offset,IDs,Bp+LevelSz,[ID|Acc]);
+ false ->
+ [decode_ids4(Type,Bp1,ID)|Acc]
+ end.
+
+
+decode_ids3(Type,Offset,[ID|IDs],Bp,Acc) ->
+ LevelSz = length(ID),
+ Bp1 = Offset-Bp,
+ case Bp1 > LevelSz of
+ true ->
+ decode_ids3(Type,Offset,IDs,Bp+LevelSz,[ID|Acc]);
+ false ->
+ A1 = decode_ids4(Type,Bp1,ID),
+ {[A1|Acc],IDs,Bp+LevelSz}
+ end.
+
+
+decode_ids4(Type,0,_ID) ->
+ [Type];
+decode_ids4(Type,O,[H|T]) ->
+ [H|decode_ids4(Type,O-1,T)].
+
+
+%% E: Encoded bits -> [byte()]
+%% L: Number of nits in level
+decode_id_level(B,E,0,Acc) ->
+ {lists:reverse(Acc),E,B};
+decode_id_level(8,[_H|T],L,Acc) ->
+ decode_id_level(0,T,L,Acc);
+decode_id_level(B,[H|T],L,Acc) ->
+ Acc1 = [decode_id_level1(H band 16#80) | Acc],
+ decode_id_level(B+1,[((H bsl 1) band 16#FF) |T],L-1,Acc1);
+decode_id_level(B,E,L,Acc) ->
+ exit({id_config_mismatch,{B,E,L,Acc}}).
+
+decode_id_level1(16#80) -> $1;
+decode_id_level1(16#00) -> $0.
+
+
diff --git a/lib/megaco/src/binary/megaco_binary_transformer_prev3a.erl b/lib/megaco/src/binary/megaco_binary_transformer_prev3a.erl
new file mode 100644
index 0000000000..609947c933
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_transformer_prev3a.erl
@@ -0,0 +1,1629 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Transform internal form of Megaco/H.248 messages
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_transformer_prev3a).
+
+-include_lib("megaco/include/megaco.hrl").
+%% -include_lib("megaco/include/megaco_message.hrl").
+-include_lib("megaco/include/megaco_message_prev3a.hrl").
+-include_lib("megaco/src/app/megaco_internal.hrl").
+
+-export([tr_message/3, tr_transaction/3]).
+
+-define(DEFAULT_NAME_RESOLVER, megaco_binary_name_resolver_prev3a).
+
+-record(state, {mode, % verify | encode | decode
+ resolver_module, %
+ resolver_options}).
+
+resolve(Type, Item, State, Constraint) ->
+ case State#state.mode of
+ verify ->
+ Item;
+ encode ->
+ ?d("resolve(encode) -> encode: ~p",[Item]),
+ Mod = State#state.resolver_module,
+ Opt = State#state.resolver_options,
+ EncodedItem = Mod:encode_name(Opt, Type, Item),
+ ?d("resolve -> verify contraint for ~p",[EncodedItem]),
+ verify_constraint(EncodedItem, Constraint);
+ decode ->
+ ?d("resolve(decode) -> verify contraint for ~p",[Item]),
+ DecodedItem = verify_constraint(Item, Constraint),
+ Mod = State#state.resolver_module,
+ Opt = State#state.resolver_options,
+ ?d("resolve(decode) -> decode: ~p",[DecodedItem]),
+ Mod:decode_name(Opt, Type, DecodedItem)
+ end.
+
+verify_constraint(Item, valid) ->
+ Item;
+verify_constraint(Item, Constraint) when is_function(Constraint) ->
+ Constraint(Item).
+
+tr_message(MegaMsg, Mode, Config) ->
+ case Config of
+ [native] ->
+ MegaMsg;
+ [verify] ->
+ State = #state{mode = verify},
+ tr_MegacoMessage(MegaMsg, State);
+ [] ->
+ State = #state{mode = Mode,
+ resolver_module = ?DEFAULT_NAME_RESOLVER,
+ resolver_options = [8, 8, 8]},
+ tr_MegacoMessage(MegaMsg, State);
+ [{binary_name_resolver, {Module, Options}}] when is_atom(Module) ->
+ State = #state{mode = Mode,
+ resolver_module = Module,
+ resolver_options = Options},
+ tr_MegacoMessage(MegaMsg, State)
+ end.
+
+tr_transaction(Trans, Mode, Config) ->
+ case Config of
+ [native] ->
+ Trans;
+ [verify] ->
+ State = #state{mode = verify},
+ tr_Transaction(Trans, State);
+ [] ->
+ State = #state{mode = Mode,
+ resolver_module = ?DEFAULT_NAME_RESOLVER,
+ resolver_options = [8, 8, 8]},
+ tr_Transaction(Trans, State);
+ [{binary_name_resolver, {Module, Options}}] when is_atom(Module) ->
+ State = #state{mode = Mode,
+ resolver_module = Module,
+ resolver_options = Options},
+ tr_Transaction(Trans, State)
+ end.
+
+tr_MegacoMessage(#'MegacoMessage'{authHeader = Auth,
+ mess = Mess},
+ State) ->
+ ?d("tr_MegacoMessage -> entry with"
+ "~n Auth: ~p"
+ "~n Mess: ~p"
+ "~n State: ~p", [Auth, Mess, State]),
+ #'MegacoMessage'{authHeader = tr_opt_AuthenticationHeader(Auth, State),
+ mess = tr_Message(Mess, State)}.
+
+tr_opt_AuthenticationHeader(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_AuthenticationHeader(#'AuthenticationHeader'{secParmIndex = SPI,
+ seqNum = SN,
+ ad = AuthData},
+ State) ->
+ #'AuthenticationHeader'{secParmIndex = tr_SecurityParmIndex(SPI, State),
+ seqNum = tr_SequenceNum(SN, State),
+ ad = tr_AuthData(AuthData, State)}.
+
+tr_SecurityParmIndex(SPI, State) ->
+ tr_HEXDIG(SPI, State, 4, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_SequenceNum(SN, State) ->
+ tr_HEXDIG(SN, State, 4, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_AuthData(AuthData, State) ->
+ tr_HEXDIG(AuthData, State, 12, 32). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_Message(#'Message'{version = Version,
+ mId = MID,
+ messageBody = Body},
+ State) ->
+ #'Message'{version = tr_version(Version, State),
+ mId = tr_MId(MID, State),
+ messageBody = tr_Message_messageBody(Body, State)}.
+
+tr_version(Version, State) ->
+ tr_DIGIT(Version, State, 0, 99).
+
+tr_Message_messageBody({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ messageError -> tr_ErrorDescriptor(Val, State);
+ transactions when is_list(Val) -> [tr_Transaction(T, State) || T <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_MId({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ ip4Address -> tr_IP4Address(Val, State);
+ ip6Address -> tr_IP6Address(Val, State);
+ domainName -> tr_DomainName(Val, State);
+ deviceName -> tr_PathName(Val, State);
+ mtpAddress -> tr_mtpAddress(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_mtpAddress(MtpAddr, State) ->
+ tr_OCTET_STRING(MtpAddr, State, 2, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_DomainName(#'DomainName'{name = Name,
+ portNumber = Port},
+ State) ->
+ Domain = #'DomainName'{name = tr_STRING(Name, State), % BUGBUG: Mismatch between ASN.1 and ABNF
+ portNumber = tr_opt_portNumber(Port, State)},
+ {domainName, Domain2} = resolve(mid, {domainName, Domain}, State, valid),
+ Domain2.
+
+tr_IP4Address(#'IP4Address'{address = [A1, A2, A3, A4],
+ portNumber = Port},
+ State) ->
+ #'IP4Address'{address = [tr_V4hex(A1, State),
+ tr_V4hex(A2, State),
+ tr_V4hex(A3, State),
+ tr_V4hex(A4, State)],
+ portNumber = tr_opt_portNumber(Port, State)}.
+
+tr_V4hex(Val, State) ->
+ tr_DIGIT(Val, State, 0, 255).
+
+tr_IP6Address(_Val, _State) ->
+ error(ipv6_not_supported). %% BUGBUG: nyi
+
+tr_PathName(Path, State) ->
+ %% BUGBUG: ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
+ %% BUGBUG: ["@" pathDomainName ]
+ Constraint = fun({deviceName, Item}) -> tr_STRING(Item, State, 1, 64) end,
+ resolve(mid, {deviceName, Path}, State, Constraint).
+
+tr_Transaction({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ transactionRequest -> tr_TransactionRequest(Val, State);
+ transactionPending -> tr_TransactionPending(Val, State);
+ transactionReply -> tr_TransactionReply(Val, State);
+ transactionResponseAck -> [tr_TransactionAck(T, State) || T <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_TransactionAck(#'TransactionAck'{firstAck = First,
+ lastAck = Last},
+ State) ->
+ #'TransactionAck'{firstAck = tr_TransactionId(First, State),
+ lastAck = tr_opt_TransactionId(Last, State)}.
+
+tr_opt_TransactionId(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TransactionId(Id, State) ->
+ tr_TransactionId(Id, State).
+
+tr_TransactionId(Id, State) ->
+ tr_UINT32(Id, State).
+
+tr_TransactionRequest(#'TransactionRequest'{transactionId = Id,
+ actions = Actions},
+ State) when is_list(Actions) ->
+
+ #'TransactionRequest'{transactionId = tr_TransactionId(Id, State),
+ actions = [tr_ActionRequest(ActReq, State) || ActReq <- Actions]}.
+
+tr_TransactionPending(#'TransactionPending'{transactionId = Id},
+ State) ->
+ #'TransactionPending'{transactionId = tr_TransactionId(Id, State)}.
+
+tr_TransactionReply(#'TransactionReply'{transactionId = Id,
+ immAckRequired = ImmAck,
+ transactionResult = TransRes,
+ %% These fields are actually not
+ %% supported in this implementation,
+ %% but because the messanger module
+ %% cannot see any diff between the
+ %% various v3 implementations...
+ segmentNumber = asn1_NOVALUE,
+ segmentationComplete = asn1_NOVALUE},
+ State) ->
+ #'TransactionReply'{transactionId = tr_TransactionId(Id, State),
+ immAckRequired = tr_opt_null(ImmAck, State),
+ transactionResult = tr_TransactionReply_transactionResult(TransRes, State),
+ segmentNumber = asn1_NOVALUE,
+ segmentationComplete = asn1_NOVALUE};
+tr_TransactionReply(TR, _State) ->
+ error({unsupported_TransactionReply, TR}).
+
+tr_opt_null(asn1_NOVALUE, _State) -> asn1_NOVALUE;
+tr_opt_null('NULL', _State) -> 'NULL'.
+
+tr_TransactionReply_transactionResult({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ transactionError ->
+ tr_ErrorDescriptor(Val, State);
+ actionReplies when is_list(Val) andalso (Val =/= []) ->
+ [tr_ActionReply(ActRep, State) || ActRep <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_opt_ErrorDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ErrorDescriptor(ErrDesc, State) ->
+ tr_ErrorDescriptor(ErrDesc, State).
+
+tr_ErrorDescriptor(#'ErrorDescriptor'{errorCode = Code,
+ errorText = Text},
+ State) ->
+ #'ErrorDescriptor'{errorCode = tr_ErrorCode(Code, State),
+ errorText = tr_opt_ErrorText(Text, State)}.
+
+tr_ErrorCode(Code, State) ->
+ tr_DIGIT(Code, State, 0, 999).
+
+tr_opt_ErrorText(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ErrorText(Text, State) ->
+ tr_QUOTED_STRING(Text, State).
+
+tr_ContextID(CtxId, State) ->
+ case CtxId of
+ ?megaco_all_context_id -> ?megaco_all_context_id;
+ ?megaco_null_context_id -> ?megaco_null_context_id;
+ ?megaco_choose_context_id -> ?megaco_choose_context_id;
+ Int when is_integer(Int) -> tr_UINT32(Int, State)
+ end.
+
+tr_ActionRequest(#'ActionRequest'{contextId = CtxId,
+ contextRequest = CtxReq,
+ contextAttrAuditReq = CtxAuditReq,
+ commandRequests = CmdReqList},
+ State) ->
+ #'ActionRequest'{contextId = tr_ContextID(CtxId, State),
+ contextRequest = tr_opt_ContextRequest(CtxReq, State),
+ contextAttrAuditReq = tr_opt_ContextAttrAuditRequest(CtxAuditReq, State),
+ commandRequests = [tr_CommandRequest(CmdReq, State) || CmdReq <- CmdReqList]}.
+
+tr_ActionReply(#'ActionReply'{contextId = CtxId,
+ errorDescriptor = ErrDesc,
+ contextReply = CtxRep,
+ commandReply = CmdRepList},
+ State) ->
+ CmdRepList2 = [tr_CommandReply(CmdRep, State) || CmdRep <- CmdRepList],
+ #'ActionReply'{contextId = tr_ContextID(CtxId, State),
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State),
+ contextReply = tr_opt_ContextRequest(CtxRep, State),
+ commandReply = CmdRepList2}.
+
+tr_opt_ContextRequest(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ContextRequest(CR, State) ->
+ tr_ContextRequest(CR, State).
+
+tr_ContextRequest(#'ContextRequest'{priority = Prio,
+ emergency = Em,
+ topologyReq = TopReqList,
+ iepsCallind = Ind,
+ contextProp = Props},
+ State) ->
+ Prio2 =
+ case Prio of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_integer(Prio, State, 0, 15)
+ end,
+ Em2 =
+ case Em of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ TopReqList2 =
+ case TopReqList of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_TopologyRequest(TopReq, State) ||
+ TopReq <- TopReqList]
+ end,
+ Ind2 =
+ case Ind of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ Props2 =
+ case Props of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_PropertyParm(Prop, State) || Prop <- Props]
+ end,
+ #'ContextRequest'{priority = Prio2,
+ emergency = Em2,
+ topologyReq = TopReqList2,
+ iepsCallind = Ind2,
+ contextProp = Props2}.
+
+tr_opt_ContextAttrAuditRequest(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ContextAttrAuditRequest(CAAR, State) ->
+ tr_ContextAttrAuditRequest(CAAR, State).
+
+tr_ContextAttrAuditRequest(#'ContextAttrAuditRequest'{topology = Top,
+ emergency = Em,
+ priority = Prio,
+ iepsCallind = Ind,
+ contextPropAud = Props},
+ State) ->
+ Top2 = tr_opt_null(Top, State),
+ Em2 = tr_opt_null(Em, State),
+ Prio2 = tr_opt_null(Prio, State),
+ Ind2 = tr_opt_null(Ind, State),
+ Props2 =
+ case Props of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ [tr_indAudPropertyParm(Prop, State) || Prop <- Props]
+ end,
+ #'ContextAttrAuditRequest'{topology = Top2,
+ emergency = Em2,
+ priority = Prio2,
+ iepsCallind = Ind2,
+ contextPropAud = Props2}.
+
+tr_CommandRequest(#'CommandRequest'{command = Cmd,
+ optional = Opt,
+ wildcardReturn = Wild},
+ State) ->
+ #'CommandRequest'{optional = tr_opt_null(Opt, State),
+ wildcardReturn = tr_opt_null(Wild, State),
+ command = tr_Command(Cmd, State)}.
+
+tr_Command({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ addReq -> tr_AmmRequest(Val, State);
+ moveReq -> tr_AmmRequest(Val, State);
+ modReq -> tr_AmmRequest(Val, State);
+ subtractReq -> tr_SubtractRequest(Val, State);
+ auditCapRequest -> tr_AuditRequest(Val, State);
+ auditValueRequest -> tr_AuditRequest(Val, State);
+ notifyReq -> tr_NotifyRequest(Val, State);
+ serviceChangeReq -> tr_ServiceChangeRequest(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_CommandReply({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ addReply -> tr_AmmsReply(Val, State);
+ moveReply -> tr_AmmsReply(Val, State);
+ modReply -> tr_AmmsReply(Val, State);
+ subtractReply -> tr_AmmsReply(Val, State);
+ auditCapReply -> tr_AuditReply(Val, State);
+ auditValueReply -> tr_AuditReply(Val, State);
+ notifyReply -> tr_NotifyReply(Val, State);
+ serviceChangeReply -> tr_ServiceChangeReply(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_TopologyRequest(#'TopologyRequest'{terminationFrom = From,
+ terminationTo = To,
+ topologyDirection = Dir},
+ State) ->
+ Dir2 =
+ case Dir of
+ bothway -> bothway;
+ isolate -> isolate;
+ oneway -> oneway
+ end,
+ #'TopologyRequest'{terminationFrom = tr_TerminationID(From, State),
+ terminationTo = tr_TerminationID(To, State),
+ topologyDirection = Dir2}.
+
+tr_AmmRequest(#'AmmRequest'{terminationID = IdList,
+ descriptors = DescList},
+ State) ->
+ #'AmmRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ descriptors = tr_ammDescriptors(DescList, [], State)}.
+
+tr_ammDescriptors([], Acc, _State) ->
+ lists:reverse(Acc);
+tr_ammDescriptors([Desc|Descs], Acc, State) ->
+ case tr_ammDescriptor(Desc, State) of
+ {_, deprecated} when State#state.mode =:= encode ->
+ error({deprecated, Desc});
+ {_, deprecated} when State#state.mode =:= decode ->
+ %% SKIP
+ tr_ammDescriptors(Descs, Acc, State);
+ {_, deprecated} ->
+ %% SKIP
+ tr_ammDescriptors(Descs, Acc, State);
+ NewDesc ->
+ tr_ammDescriptors(Descs, [NewDesc|Acc], State)
+ end.
+
+tr_ammDescriptor({Tag, Desc}, State) ->
+ Desc2 =
+ case Tag of
+ mediaDescriptor -> tr_MediaDescriptor(Desc, State);
+ modemDescriptor -> tr_ModemDescriptor(Desc, State);
+ muxDescriptor -> tr_MuxDescriptor(Desc, State);
+ eventsDescriptor -> tr_EventsDescriptor(Desc, State);
+ eventBufferDescriptor -> tr_EventBufferDescriptor(Desc, State);
+ signalsDescriptor -> tr_SignalsDescriptor(Desc, State);
+ digitMapDescriptor -> tr_DigitMapDescriptor(Desc, State);
+ auditDescriptor -> tr_AuditDescriptor(Desc, State);
+ statisticsDescriptor -> tr_StatisticsDescriptor(Desc, State)
+ end,
+ {Tag, Desc2}.
+
+tr_AmmsReply(#'AmmsReply'{terminationID = IdList,
+ terminationAudit = TermAudit},
+ State) ->
+ TermAudit2 =
+ case TermAudit of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_TerminationAudit(TermAudit, State)
+ end,
+ #'AmmsReply'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ terminationAudit = TermAudit2}.
+
+tr_SubtractRequest(#'SubtractRequest'{terminationID = IdList,
+ auditDescriptor = Desc},
+ State) ->
+ #'SubtractRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ auditDescriptor = tr_opt_AuditDescriptor(Desc, State)}.
+
+tr_AuditRequest(#'AuditRequest'{terminationID = Id,
+ auditDescriptor = Desc},
+ State) ->
+ #'AuditRequest'{terminationID = tr_TerminationID(Id, State),
+ auditDescriptor = tr_AuditDescriptor(Desc, State)}.
+
+%% auditReply = (AuditValueToken / AuditCapToken )
+%% ( contextTerminationAudit / auditOther)
+%% auditOther = EQUAL TerminationID LBRKT
+%% terminationAudit RBRKT
+%% terminationAudit = auditReturnParameter *(COMMA auditReturnParameter)
+%%
+%% contextTerminationAudit = EQUAL CtxToken ( terminationIDList /
+%% LBRKT errorDescriptor RBRKT )
+
+tr_AuditReply({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ contextAuditResult ->
+ [tr_TerminationID(Id, State) || Id <- Val];
+ error ->
+ tr_ErrorDescriptor(Val, State);
+ auditResult ->
+ tr_AuditResult(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_AuditResult(#'AuditResult'{terminationID = Id,
+ terminationAuditResult = AuditRes},
+ State) ->
+ #'AuditResult'{terminationID = tr_TerminationID(Id, State),
+ terminationAuditResult = tr_TerminationAudit(AuditRes, State)}.
+
+tr_opt_AuditDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_AuditDescriptor(Desc, State) ->
+ tr_AuditDescriptor(Desc, State).
+
+%% BUGBUG BUGBUG BUGBUG
+%% With this construction it is possible to have both auditToken
+%% and auditPropertyToken, but it is actually valid?
+tr_AuditDescriptor(#'AuditDescriptor'{auditToken = Tokens,
+ auditPropertyToken = APTs},
+ State) ->
+ Tokens2 =
+ case Tokens of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_auditItem(Token, State) || Token <- Tokens]
+ end,
+ %% v2
+ APTs2 =
+ case APTs of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ [tr_indAuditParameter(APT, State) || APT <- APTs]
+ end,
+ #'AuditDescriptor'{auditToken = Tokens2,
+ auditPropertyToken = APTs2}.
+
+tr_auditItem(Token, _State) ->
+ case Token of
+ muxToken -> muxToken;
+ modemToken -> modemToken;
+ mediaToken -> mediaToken;
+ eventsToken -> eventsToken;
+ signalsToken -> signalsToken;
+ digitMapToken -> digitMapToken;
+ statsToken -> statsToken;
+ observedEventsToken -> observedEventsToken;
+ packagesToken -> packagesToken;
+ eventBufferToken -> eventBufferToken
+ end.
+
+%% --- v2 begin ---
+
+tr_indAuditParameter({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ indAudMediaDescriptor ->
+ tr_indAudMediaDescriptor(Val, State);
+ indAudEventsDescriptor ->
+ tr_indAudEventsDescriptor(Val, State);
+ indAudSignalsDescriptor ->
+ tr_indAudSignalsDescriptor(Val, State);
+ indAudDigitMapDescriptor ->
+ tr_indAudDigitMapDescriptor(Val, State);
+ indAudEventBufferDescriptor ->
+ tr_indAudEventBufferDescriptor(Val, State);
+ indAudStatisticsDescriptor ->
+ tr_indAudStatisticsDescriptor(Val, State);
+ indAudPackagesDescriptor ->
+ tr_indAudPackagesDescriptor(Val, State)
+ end,
+ {Tag, Val2}.
+
+
+%% -
+
+tr_indAudMediaDescriptor(#'IndAudMediaDescriptor'{termStateDescr = TSD,
+ streams = S},
+ State) ->
+ TSD2 =
+ case TSD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudTerminationStateDescriptor(TSD, State)
+ end,
+ S2 =
+ case S of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ {oneStream, OS} ->
+ {oneStream, tr_indAudStreamParms(OS, State)};
+ {multiStream, MS} ->
+ MS2 = [tr_indAudStreamDescriptor(MS1, State) || MS1 <- MS],
+ {multiStream, MS2}
+ end,
+ #'IndAudMediaDescriptor'{termStateDescr = TSD2,
+ streams = S2}.
+
+tr_indAudTerminationStateDescriptor(Val, State)
+ when is_record(Val, 'IndAudTerminationStateDescriptor') ->
+ #'IndAudTerminationStateDescriptor'{propertyParms = Parms,
+ eventBufferControl = EBC,
+ serviceState = SS} = Val,
+ Parms2 = [tr_indAudPropertyParm(Parm, State) || Parm <- Parms],
+ EBC2 = tr_opt_null(EBC, State),
+ SS2 = tr_opt_null(SS, State),
+ #'IndAudTerminationStateDescriptor'{propertyParms = Parms2,
+ eventBufferControl = EBC2,
+ serviceState = SS2}.
+
+
+tr_indAudStreamParms(#'IndAudStreamParms'{localControlDescriptor = LCD,
+ localDescriptor = LD,
+ remoteDescriptor = RD,
+ statisticsDescriptor = SD},
+ State) ->
+ LCD2 =
+ case LCD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalControlDescriptor(LCD, State)
+ end,
+ LD2 =
+ case LD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalRemoteDescriptor(LD, State)
+ end,
+ RD2 =
+ case RD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalRemoteDescriptor(RD, State)
+ end,
+ SD2 =
+ case SD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudStatisticsDescriptor(SD, State)
+ end,
+ #'IndAudStreamParms'{localControlDescriptor = LCD2,
+ localDescriptor = LD2,
+ remoteDescriptor = RD2,
+ statisticsDescriptor = SD2}.
+
+tr_indAudLocalControlDescriptor(Val, State)
+ when is_record(Val, 'IndAudLocalControlDescriptor') ->
+ #'IndAudLocalControlDescriptor'{streamMode = M,
+ reserveValue = V,
+ reserveGroup = G,
+ propertyParms = P} = Val,
+ M2 = tr_opt_null(M, State),
+ V2 = tr_opt_null(V, State),
+ G2 = tr_opt_null(G, State),
+ P2 = tr_indAudLocalControlDescriptor_propertyParms(P, State),
+ #'IndAudLocalControlDescriptor'{streamMode = M2,
+ reserveValue = V2,
+ reserveGroup = G2,
+ propertyParms = P2}.
+
+tr_indAudLocalControlDescriptor_propertyParms(Parms, State)
+ when is_list(Parms) andalso (length(Parms) > 0) ->
+ [tr_indAudPropertyParm(Parm, State) || Parm <- Parms];
+tr_indAudLocalControlDescriptor_propertyParms(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE.
+
+tr_indAudLocalRemoteDescriptor(#'IndAudLocalRemoteDescriptor'{propGroupID = ID,
+ propGrps = Grps},
+ State) ->
+ #'IndAudLocalRemoteDescriptor'{propGroupID = tr_opt_UINT16(ID, State),
+ propGrps = tr_indAudPropertyGroup(Grps,
+ State)}.
+
+tr_indAudPropertyGroup(Grps, State) when is_list(Grps) ->
+ [tr_indAudPropertyParm(Parm, State) || Parm <- Grps].
+
+tr_indAudPropertyParm(#'IndAudPropertyParm'{name = Name0}, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(property, Name0, State, Constraint),
+ #'IndAudPropertyParm'{name = Name}.
+
+
+tr_indAudStreamDescriptor(#'IndAudStreamDescriptor'{streamID = ID,
+ streamParms = Parms},
+ State) ->
+ #'IndAudStreamDescriptor'{streamID = tr_StreamID(ID, State),
+ streamParms = tr_indAudStreamParms(Parms,
+ State)}.
+
+
+%% -
+
+tr_indAudEventsDescriptor(#'IndAudEventsDescriptor'{requestID = RID,
+ pkgdName = Name0,
+ streamID = SID},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(event, Name0, State, Constraint),
+ #'IndAudEventsDescriptor'{requestID = tr_opt_RequestID(RID, State),
+ pkgdName = Name,
+ streamID = tr_opt_StreamID(SID, State)}.
+
+
+%% -
+
+tr_indAudSignalsDescriptor({Tag, Val}, State) ->
+ case Tag of
+ signal ->
+ {signal, tr_indAudSignal(Val, State)};
+ seqSigList ->
+ {seqSigList, tr_indAudSeqSigList(Val, State)}
+ end.
+
+tr_opt_indAudSignal(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_indAudSignal(Val, State) ->
+ tr_indAudSignal(Val, State).
+
+tr_indAudSignal(#'IndAudSignal'{signalName = Name0,
+ streamID = SID}, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(signal, Name0, State, Constraint),
+ #'IndAudSignal'{signalName = Name,
+ streamID = tr_opt_StreamID(SID, State)}.
+
+tr_indAudSeqSigList(#'IndAudSeqSigList'{id = ID,
+ signalList = SigList}, State) ->
+ #'IndAudSeqSigList'{id = tr_integer(ID, State, 0, 65535),
+ signalList = tr_opt_indAudSignal(SigList, State)}.
+
+%% -
+
+tr_indAudDigitMapDescriptor(#'IndAudDigitMapDescriptor'{digitMapName = Name},
+ State) ->
+ #'IndAudDigitMapDescriptor'{digitMapName =
+ tr_opt_DigitMapName(Name, State)}.
+
+
+%% -
+
+tr_indAudEventBufferDescriptor(#'IndAudEventBufferDescriptor'{eventName = N,
+ streamID = SID},
+ State) ->
+ ?d("tr_indAudEventBufferDescriptor -> entry with"
+ "~n N: ~p"
+ "~n SID: ~p", [N, SID]),
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(event, N, State, Constraint),
+ ?d("tr_indAudEventBufferDescriptor -> entry with"
+ "~n Name: ~p", [Name]),
+ #'IndAudEventBufferDescriptor'{eventName = Name,
+ streamID = tr_opt_StreamID(SID, State)}.
+
+%% -
+
+tr_indAudStatisticsDescriptor(#'IndAudStatisticsDescriptor'{statName = N},
+ State) ->
+ ?d("tr_indAudEventBufferDescriptor -> entry with"
+ "~n N: ~p", [N]),
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(statistics, N, State, Constraint),
+ #'IndAudStatisticsDescriptor'{statName = Name}.
+
+
+%% -
+
+tr_indAudPackagesDescriptor(#'IndAudPackagesDescriptor'{packageName = N,
+ packageVersion = V},
+ State) ->
+ ?d("tr_indAudPackagesDescriptor -> entry with"
+ "~n N: ~p"
+ "~n V: ~p", [N, V]),
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ Name = resolve(package, N, State, Constraint),
+ ?d("tr_indAudPackagesDescriptor -> entry with"
+ "~n Name: ~p", [Name]),
+ #'IndAudPackagesDescriptor'{packageName = Name,
+ packageVersion = tr_integer(V, State, 0, 99)}.
+
+%% -- v2 end --
+
+
+tr_TerminationAudit(ParmList, State) when is_list(ParmList) ->
+ do_tr_TerminationAudit(ParmList, [], State).
+
+do_tr_TerminationAudit([], Acc, _State) ->
+ lists:reverse(Acc);
+do_tr_TerminationAudit([Parm|ParmList], Acc, State) ->
+ case tr_AuditReturnParameter(Parm, State) of
+ {_, deprecated} when State#state.mode =:= encode ->
+ error({deprecated, Parm});
+ {_, deprecated} when State#state.mode =:= decode ->
+ %% SKIP
+ do_tr_TerminationAudit(ParmList, Acc, State);
+ {_, deprecated} ->
+ %% SKIP
+ do_tr_TerminationAudit(ParmList, Acc, State);
+ NewParm ->
+ do_tr_TerminationAudit(ParmList, [NewParm|Acc], State)
+ end.
+
+tr_AuditReturnParameter({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ errorDescriptor ->
+ tr_ErrorDescriptor(Val, State);
+ mediaDescriptor ->
+ tr_MediaDescriptor(Val, State);
+ modemDescriptor ->
+ tr_ModemDescriptor(Val, State);
+ muxDescriptor ->
+ tr_MuxDescriptor(Val, State);
+ eventsDescriptor ->
+ tr_EventsDescriptor(Val, State);
+ eventBufferDescriptor ->
+ tr_EventBufferDescriptor(Val, State);
+ signalsDescriptor ->
+ tr_SignalsDescriptor(Val, State);
+ digitMapDescriptor ->
+ tr_DigitMapDescriptor(Val, State);
+ observedEventsDescriptor ->
+ tr_ObservedEventsDescriptor(Val, State);
+ statisticsDescriptor ->
+ tr_StatisticsDescriptor(Val, State);
+ packagesDescriptor ->
+ tr_PackagesDescriptor(Val, State);
+ emptyDescriptors ->
+ tr_EmptyDescriptors(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_EmptyDescriptors(#'AuditDescriptor'{auditToken = Tokens},
+ State) ->
+ case Tokens of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_auditItem(Token, State) || Token <- Tokens]
+ end.
+
+tr_NotifyRequest(#'NotifyRequest'{terminationID = IdList,
+ observedEventsDescriptor = ObsDesc,
+ errorDescriptor = ErrDesc},
+ State) ->
+ %% BUGBUG: Mismatch between ASN.1 and ABNF
+ %% BUGBUG: The following ought to be a 'choice'
+ #'NotifyRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ observedEventsDescriptor = tr_ObservedEventsDescriptor(ObsDesc, State),
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State)}.
+
+tr_NotifyReply(#'NotifyReply'{terminationID = IdList,
+ errorDescriptor = ErrDesc},
+ State) ->
+ #'NotifyReply'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State)}.
+
+tr_ObservedEventsDescriptor(#'ObservedEventsDescriptor'{requestId = Id,
+ observedEventLst = Events},
+ State) when is_list(Events) ->
+ #'ObservedEventsDescriptor'{requestId = tr_RequestID(Id, State),
+ observedEventLst = [tr_ObservedEvent(E, State) || E <- Events]}.
+
+%% ;time per event, because it might be buffered
+%% observedEvent = [ TimeStamp LWSP COLON] LWSP
+%% pkgdName [ LBRKT observedEventParameter
+%% *(COMMA observedEventParameter) RBRKT ]
+%%
+%% ;at-most-once eventStream, every eventParameterName at most once
+%% observedEventParameter = eventStream / eventOther
+
+tr_ObservedEvent(#'ObservedEvent'{eventName = Name,
+ streamID = Id,
+ eventParList = Parms,
+ timeNotation = Time},
+ State) ->
+ #'ObservedEvent'{eventName = tr_EventName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ eventParList = [tr_EventParameter(P, Name, State) || P <- Parms],
+ timeNotation = tr_opt_TimeNotation(Time, State)}.
+
+tr_EventName(Name, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ resolve(event, Name, State, Constraint).
+
+tr_EventParameter(#'EventParameter'{eventParameterName = ParName,
+ value = Value,
+ extraInfo = Extra},
+ EventName,
+ State) ->
+ %% BUGBUG: event parameter name
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ N = resolve({event_parameter, EventName}, ParName, State, Constraint),
+ #'EventParameter'{eventParameterName = N,
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_ServiceChangeRequest(#'ServiceChangeRequest'{terminationID = IdList,
+ serviceChangeParms = Parms},
+ State) ->
+ #'ServiceChangeRequest'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ serviceChangeParms = tr_ServiceChangeParm(Parms, State)}.
+
+%% serviceChangeReply = ServiceChangeToken EQUAL TerminationID
+%% [LBRKT (errorDescriptor /
+%% serviceChangeReplyDescriptor) RBRKT]
+%% serviceChangeReplyDescriptor = ServicesToken LBRKT
+%% servChgReplyParm *(COMMA servChgReplyParm) RBRKT
+%%
+%% ;at-most-once. Version is REQUIRED on first ServiceChange response
+%% servChgReplyParm = (serviceChangeAddress / serviceChangeMgcId /
+%% serviceChangeProfile / serviceChangeVersion )
+tr_ServiceChangeReply(#'ServiceChangeReply'{terminationID = IdList,
+ serviceChangeResult = Res},
+ State) ->
+ #'ServiceChangeReply'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ serviceChangeResult = tr_ServiceChangeResult(Res, State)}.
+
+tr_ServiceChangeResult({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ errorDescriptor -> tr_ErrorDescriptor(Val, State);
+ serviceChangeResParms -> tr_ServiceChangeResParm(Val, State)
+ end,
+ {Tag, Val2}.
+
+%% TerminationID = "ROOT" / pathNAME / "$" / "*"
+%% ; Total length of pathNAME must not exceed 64 chars.
+%% pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
+%% ["@" pathDomainName ]
+
+tr_TerminationID(TermId, State) when State#state.mode =/= verify ->
+ resolve(term_id, TermId, State, valid);
+tr_TerminationID(#'TerminationID'{wildcard = Wild,
+ id = Id},
+ _State) ->
+ #'TerminationID'{wildcard = Wild,
+ id = Id};
+tr_TerminationID(#megaco_term_id{contains_wildcards = IsWild,
+ id = Id},
+ State) ->
+ #megaco_term_id{contains_wildcards = tr_bool(IsWild, State),
+ id = [tr_term_id_component(Sub, State) || Sub <- Id]}.
+
+tr_opt_bool(asn1_NOVALUE, _State) -> asn1_NOVALUE;
+tr_opt_bool(Bool, State) -> tr_bool(Bool, State).
+
+tr_bool(true, _State) -> true;
+tr_bool(false, _State) -> false.
+
+tr_term_id_component(Sub, _State) ->
+ case Sub of
+ all -> all;
+ choose -> choose;
+ Char when is_integer(Char) -> Char
+ end.
+
+%% mediaDescriptor = MediaToken LBRKT mediaParm *(COMMA mediaParm) RBRKT
+%% ; at-most-once per item
+%% ; and either streamParm or streamDescriptor but not both
+%% mediaParm = (streamParm / streamDescriptor /
+%% terminationStateDescriptor)
+%% ; at-most-once
+%% streamParm = ( localDescriptor / remoteDescriptor /
+%% localControlDescriptor )
+%% streamDescriptor = StreamToken EQUAL StreamID LBRKT streamParm
+%% *(COMMA streamParm) RBRKT
+tr_MediaDescriptor(#'MediaDescriptor'{termStateDescr = TermState,
+ streams = Streams},
+ State) ->
+ #'MediaDescriptor'{termStateDescr = tr_opt_TerminationStateDescriptor(TermState, State),
+ streams = tr_opt_streams(Streams, State)}.
+
+tr_opt_streams(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_streams({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ oneStream -> tr_StreamParms(Val, State);
+ multiStream -> [tr_StreamDescriptor(SD, State) || SD <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_StreamParms(#'StreamParms'{localControlDescriptor = LCD,
+ localDescriptor = LD,
+ remoteDescriptor = RD,
+ statisticsDescriptor = SD},
+ State) ->
+ LCD2 = tr_opt_LocalControlDescriptor(LCD, State),
+ LD2 = tr_opt_LocalRemoteDescriptor(LD, State),
+ RD2 = tr_opt_LocalRemoteDescriptor(RD, State),
+ SD2 = tr_opt_StatisticsDescriptor(SD, State),
+ #'StreamParms'{localControlDescriptor = LCD2,
+ localDescriptor = LD2,
+ remoteDescriptor = RD2,
+ statisticsDescriptor = SD2}.
+
+tr_StreamDescriptor(#'StreamDescriptor'{streamID = Id,
+ streamParms = Parms},
+ State) ->
+ #'StreamDescriptor'{streamID = tr_StreamID(Id, State),
+ streamParms = tr_StreamParms(Parms, State)}.
+
+%% localControlDescriptor = LocalControlToken LBRKT localParm
+%% *(COMMA localParm) RBRKT
+%%
+%% ; at-most-once per item
+%% localParm = ( streamMode / propertyParm /
+%% reservedValueMode / reservedGroupMode )
+%% reservedValueMode = ReservedValueToken EQUAL ( "ON" / "OFF" )
+%% reservedGroupMode = ReservedGroupToken EQUAL ( "ON" / "OFF" )
+%%
+%% reservedMode = ReservedToken EQUAL ( "ON" / "OFF" )
+%%
+%% streamMode = ModeToken EQUAL streamModes
+tr_opt_LocalControlDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_LocalControlDescriptor(#'LocalControlDescriptor'{streamMode = Mode,
+ reserveGroup = Group,
+ reserveValue = Value,
+ propertyParms = Props},
+ State) ->
+ #'LocalControlDescriptor'{streamMode = tr_opt_StreamMode(Mode, State),
+ reserveGroup = tr_opt_bool(Group, State),
+ reserveValue = tr_opt_bool(Value, State),
+ propertyParms = [tr_PropertyParm(P, State) || P <- Props]}.
+
+tr_opt_StreamMode(Mode, _State) ->
+ case Mode of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ sendOnly -> sendOnly;
+ recvOnly -> recvOnly;
+ sendRecv -> sendRecv;
+ inactive -> inactive;
+ loopBack -> loopBack
+ end.
+
+tr_Name(Name, State) ->
+ %% BUGBUG: transform
+ %% BUGBUG: NAME = ALPHA *63(ALPHA / DIGIT / "_" )
+ tr_STRING(Name, State, 2, 2).
+
+tr_PkgdName(Name, State) ->
+ %% BUGBUG: transform
+ %% BUGBUG: pkgdName = (NAME / "*") SLASH (ItemID / "*" )
+ tr_OCTET_STRING(Name, State, 4, 4).
+
+%% When text encoding the protocol, the descriptors consist of session
+%% descriptions as defined in SDP (RFC2327), except that the "s=", "t="
+%% and "o=" lines are optional. When multiple session descriptions are
+%% provided in one descriptor, the "v=" lines are required as delimiters;
+%% otherwise they are optional. Implementations shall accept session
+%% descriptions that are fully conformant to RFC2327. When binary
+%% encoding the protocol the descriptor consists of groups of properties
+%% (tag-value pairs) as specified in Annex C. Each such group may
+%% contain the parameters of a session description.
+tr_opt_LocalRemoteDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_LocalRemoteDescriptor(#'LocalRemoteDescriptor'{propGrps = Groups},
+ State) ->
+ #'LocalRemoteDescriptor'{propGrps = [tr_PropertyGroup(G, State) || G <- Groups]}.
+
+tr_PropertyGroup(Props, State) ->
+ [tr_PropertyGroupParm(P, State) || P <- Props].
+
+tr_PropertyGroupParm(#'PropertyParm'{name = Name,
+ value = Value},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'PropertyParm'{name = resolve(property, Name, State, Constraint),
+ value = tr_OCTET_STRING(Value, State, 0, infinity)}.
+
+tr_PropertyParm(#'PropertyParm'{name = Name,
+ value = Value,
+ extraInfo = Extra},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'PropertyParm'{name = resolve(property, Name, State, Constraint),
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_opt_extraInfo(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_extraInfo({relation, Rel}, _State) ->
+ Rel2 =
+ case Rel of
+ greaterThan -> greaterThan;
+ smallerThan -> smallerThan;
+ unequalTo -> unequalTo
+ end,
+ {relation, Rel2};
+tr_opt_extraInfo({range, Range}, State) ->
+ Range2 = tr_bool(Range, State),
+ {range, Range2};
+tr_opt_extraInfo({sublist, Sub}, State) ->
+ Sub2 = tr_bool(Sub, State),
+ {sublist, Sub2}.
+
+tr_opt_TerminationStateDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TerminationStateDescriptor(#'TerminationStateDescriptor'{propertyParms = Props,
+ eventBufferControl = Control,
+ serviceState = Service},
+ State) ->
+ #'TerminationStateDescriptor'{propertyParms = [tr_PropertyParm(P, State) || P <- Props],
+ eventBufferControl = tr_opt_EventBufferControl(Control, State),
+ serviceState = tr_opt_ServiceState(Service, State)}.
+
+tr_opt_EventBufferControl(Control, _State) ->
+ case Control of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ off -> off;
+ lockStep -> lockStep
+ end.
+
+tr_opt_ServiceState(Service, _State) ->
+ case Service of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ test -> test;
+ outOfSvc -> outOfSvc;
+ inSvc -> inSvc
+ end.
+
+tr_MuxDescriptor(#'MuxDescriptor'{muxType = Type,
+ termList = IdList},
+ State) ->
+ #'MuxDescriptor'{muxType = tr_MuxType(Type, State),
+ termList = [tr_TerminationID(Id, State) || Id <- IdList]}.
+
+tr_MuxType(Type, _State) ->
+ case Type of
+ h221 -> h221;
+ h223 -> h223;
+ h226 -> h226;
+ v76 -> v76
+ end.
+
+tr_opt_StreamID(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_StreamID(Id, State) ->
+ tr_StreamID(Id, State).
+
+tr_StreamID(Id, State) ->
+ tr_UINT16(Id, State).
+
+tr_EventsDescriptor(#'EventsDescriptor'{requestID = Id,
+ eventList = Events},
+ State) ->
+ #'EventsDescriptor'{requestID = tr_opt_RequestID(Id, State),
+ eventList = [tr_RequestedEvent(E, State) || E <- Events]}.
+
+tr_RequestedEvent(#'RequestedEvent'{pkgdName = Name,
+ streamID = Id,
+ evParList = Parms,
+ eventAction = Actions},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'RequestedEvent'{pkgdName = resolve(event, Name, State, Constraint),
+ streamID = tr_opt_StreamID(Id, State),
+ eventAction = tr_opt_RequestedActions(Actions, State),
+ evParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+tr_opt_RequestedActions(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_RequestedActions(#'RequestedActions'{keepActive = Keep,
+ eventDM = DM,
+ secondEvent = Event,
+ signalsDescriptor = SigDesc},
+ State) ->
+ #'RequestedActions'{keepActive = tr_opt_keepActive(Keep, State),
+ eventDM = tr_opt_EventDM(DM, State),
+ secondEvent = tr_opt_SecondEventsDescriptor(Event, State),
+ signalsDescriptor = tr_opt_SignalsDescriptor(SigDesc, State)}.
+
+tr_opt_keepActive(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_keepActive(Keep, State) ->
+ tr_bool(Keep, State).
+
+tr_opt_EventDM(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_EventDM({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ digitMapName -> tr_DigitMapName(Val, State);
+ digitMapValue -> tr_DigitMapValue(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_opt_SecondEventsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SecondEventsDescriptor(#'SecondEventsDescriptor'{requestID = Id,
+ eventList = Events},
+ State) ->
+ #'SecondEventsDescriptor'{requestID = tr_RequestID(Id, State), %% IG v6 6.8 withdrawn
+ eventList = [tr_SecondRequestedEvent(E, State) || E <- Events]}.
+
+tr_SecondRequestedEvent(#'SecondRequestedEvent'{pkgdName = Name,
+ streamID = Id,
+ evParList = Parms,
+ eventAction = Actions},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'SecondRequestedEvent'{pkgdName = resolve(event, Name, State, Constraint),
+ streamID = tr_opt_StreamID(Id, State),
+ eventAction = tr_opt_SecondRequestedActions(Actions, State),
+ evParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+
+tr_opt_SecondRequestedActions(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SecondRequestedActions(#'SecondRequestedActions'{keepActive = Keep,
+ eventDM = DM,
+ signalsDescriptor = SigDesc},
+ State) ->
+ #'SecondRequestedActions'{keepActive = tr_opt_keepActive(Keep, State),
+ eventDM = tr_opt_EventDM(DM, State),
+ signalsDescriptor = tr_opt_SignalsDescriptor(SigDesc, State)}.
+
+tr_EventBufferDescriptor(EventSpecs, State) ->
+ [tr_EventSpec(ES, State) || ES <- EventSpecs].
+
+tr_EventSpec(#'EventSpec'{eventName = Name,
+ streamID = Id,
+ eventParList = Parms},
+ State) ->
+ #'EventSpec'{eventName = tr_EventName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ eventParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+tr_opt_SignalsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SignalsDescriptor(SigDesc, State) ->
+ tr_SignalsDescriptor(SigDesc, State).
+
+tr_SignalsDescriptor(SigDesc, State) when is_list(SigDesc) ->
+ [tr_SignalRequest(SigReq, State) || SigReq <- SigDesc].
+
+tr_SignalRequest({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ signal -> tr_Signal(Val, State);
+ seqSigList -> tr_SeqSigList(Val, State)
+ end,
+ {Tag, Val2}.
+
+
+tr_SeqSigList(#'SeqSigList'{id = Id,
+ signalList = SigList},
+ State) when is_list(SigList) ->
+ #'SeqSigList'{id = tr_UINT16(Id, State),
+ signalList = [tr_Signal(Sig, State) || Sig <- SigList]}.
+
+tr_Signal(#'Signal'{signalName = Name,
+ streamID = SID,
+ sigType = Type,
+ duration = Dur,
+ notifyCompletion = Compl,
+ keepActive = Keep,
+ sigParList = Parms,
+ direction = Dir,
+ requestID = RID},
+ State) ->
+ Name2 = tr_SignalName(Name, State),
+ SID2 = tr_opt_StreamID(SID, State),
+ Type2 = tr_opt_SignalType(Type, State),
+ Dur2 = tr_opt_duration(Dur, State),
+ Compl2 = tr_opt_NotifyCompletion(Compl, State),
+ Keep2 = tr_opt_keepActive(Keep, State),
+ Parms2 = [tr_SigParameter(P, Name, State) || P <- Parms],
+ Dir2 = tr_opt_SignalDirection(Dir, State),
+ RID2 = tr_opt_RequestID(RID, State),
+ #'Signal'{signalName = Name2,
+ streamID = SID2,
+ sigType = Type2,
+ duration = Dur2,
+ notifyCompletion = Compl2,
+ keepActive = Keep2,
+ sigParList = Parms2,
+ direction = Dir2,
+ requestID = RID2}.
+
+tr_opt_duration(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_duration(Dur, State) ->
+ tr_UINT16(Dur, State).
+
+tr_opt_NotifyCompletion(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_NotifyCompletion(Items, State) when is_list(Items) ->
+ [tr_notifyCompletionItem(I, State) || I <- Items].
+
+tr_notifyCompletionItem(Item, _State) ->
+ case Item of
+ onTimeOut -> onTimeOut;
+ onInterruptByEvent -> onInterruptByEvent;
+ onInterruptByNewSignalDescr -> onInterruptByNewSignalDescr;
+ otherReason -> otherReason
+ end.
+
+tr_opt_SignalType(asn1_NOVALUE = Type, _State) ->
+ Type;
+tr_opt_SignalType(Type, _State) ->
+ case Type of
+ brief -> brief;
+ onOff -> onOff;
+ timeOut -> timeOut
+ end.
+
+tr_opt_SignalDirection(asn1_NOVALUE = SD, _State) ->
+ SD;
+tr_opt_SignalDirection(SD, _State) ->
+ case SD of
+ internal -> internal;
+ external -> external;
+ both -> both
+ end.
+
+tr_SignalName(Name, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ resolve(signal, Name, State, Constraint).
+
+tr_SigParameter(#'SigParameter'{sigParameterName = ParName,
+ value = Value,
+ extraInfo = Extra},
+ SigName,
+ State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ N = resolve({signal_parameter, SigName}, ParName, State, Constraint),
+ #'SigParameter'{sigParameterName = N,
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_opt_RequestID(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_RequestID(Id, State) ->
+ tr_RequestID(Id, State).
+
+tr_RequestID(Id, _State) when Id =:= ?megaco_all_request_id ->
+ ?megaco_all_request_id;
+tr_RequestID(Id, State) ->
+ tr_UINT32(Id, State).
+
+tr_ModemDescriptor(_MD, _State) ->
+ deprecated.
+
+tr_DigitMapDescriptor(#'DigitMapDescriptor'{digitMapName = Name,
+ digitMapValue = Value},
+ State) ->
+ #'DigitMapDescriptor'{digitMapName = tr_opt_DigitMapName(Name, State),
+ digitMapValue = tr_opt_DigitMapValue(Value, State)}.
+
+tr_opt_DigitMapName(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_DigitMapName(Name, State) ->
+ tr_DigitMapName(Name, State).
+
+tr_DigitMapName(Name, State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ resolve(dialplan, Name, State, Constraint).
+
+tr_opt_DigitMapValue(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_DigitMapValue(Value, State) ->
+ tr_DigitMapValue(Value, State).
+
+tr_DigitMapValue(#'DigitMapValue'{digitMapBody = Body,
+ startTimer = Start,
+ shortTimer = Short,
+ longTimer = Long},
+ State) ->
+ #'DigitMapValue'{startTimer = tr_opt_timer(Start, State),
+ shortTimer = tr_opt_timer(Short, State),
+ longTimer = tr_opt_timer(Long, State),
+ digitMapBody = tr_STRING(Body, State)}. %% BUGBUG: digitMapBody not handled at all
+
+tr_opt_timer(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_timer(Timer, State) ->
+ tr_DIGIT(Timer, State, 0, 99).
+
+tr_ServiceChangeParm(
+ #'ServiceChangeParm'{serviceChangeMethod = Method,
+ serviceChangeAddress = Addr,
+ serviceChangeVersion = Version,
+ serviceChangeProfile = Profile,
+ serviceChangeReason = Reason,
+ serviceChangeDelay = Delay,
+ serviceChangeMgcId = MgcId,
+ timeStamp = Time,
+ serviceChangeInfo = Info,
+ serviceChangeIncompleteFlag = Incomplete},
+ State) ->
+ Method2 = tr_ServiceChangeMethod(Method, State),
+ Addr2 = tr_opt_ServiceChangeAddress(Addr, State),
+ Version2 = tr_opt_serviceChangeVersion(Version, State),
+ Profile2 = tr_opt_ServiceChangeProfile(Profile, State),
+ Reason2 = tr_serviceChangeReason(Reason, State),
+ Delay2 = tr_opt_serviceChangeDelay(Delay, State),
+ MgcId2 = tr_opt_serviceChangeMgcId(MgcId, State),
+ Time2 = tr_opt_TimeNotation(Time, State),
+ Info2 = tr_opt_AuditDescriptor(Info, State),
+ Incomplete2 = tr_opt_null(Incomplete, State),
+ #'ServiceChangeParm'{serviceChangeMethod = Method2,
+ serviceChangeAddress = Addr2,
+ serviceChangeVersion = Version2,
+ serviceChangeProfile = Profile2,
+ serviceChangeReason = Reason2,
+ serviceChangeDelay = Delay2,
+ serviceChangeMgcId = MgcId2,
+ timeStamp = Time2,
+ serviceChangeInfo = Info2,
+ serviceChangeIncompleteFlag = Incomplete2}.
+
+tr_ServiceChangeMethod(Method, _State) ->
+ case Method of
+ failover -> failover;
+ forced -> forced;
+ graceful -> graceful;
+ restart -> restart;
+ disconnected -> disconnected;
+ handOff -> handOff
+ end. %% BUGBUG: extension
+
+tr_opt_ServiceChangeAddress(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ServiceChangeAddress({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ portNumber -> tr_portNumber(Val, State);
+ ip4Address -> tr_IP4Address(Val, State);
+ ip6Address -> tr_IP6Address(Val, State);
+ domainName -> tr_DomainName(Val, State);
+ deviceName -> tr_PathName(Val, State);
+ mtpAddress -> tr_mtpAddress(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_opt_serviceChangeVersion(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeVersion(Version, State) ->
+ tr_version(Version, State).
+
+tr_opt_ServiceChangeProfile(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+%% Decode
+tr_opt_ServiceChangeProfile({'ServiceChangeProfile', ProfileName}, State) ->
+ case string:tokens(ProfileName, "/") of
+ [Name0, Version0] ->
+ Name = tr_STRING(Name0, State, 1, 64),
+ Version = tr_version(list_to_integer(Version0), State),
+ #'ServiceChangeProfile'{profileName = Name,
+ version = Version}
+ end;
+%% Encode
+tr_opt_ServiceChangeProfile(#'ServiceChangeProfile'{profileName = Name0,
+ version = Version0},
+ State) ->
+ Name = tr_STRING(Name0, State, 1, 64),
+ Version = tr_version(Version0, State),
+ ProfileName = lists:flatten(io_lib:format("~s/~w", [Name, Version])),
+ {'ServiceChangeProfile', ProfileName}.
+
+tr_serviceChangeReason([_] = Reason, State) ->
+ tr_Value(Reason, State).
+
+tr_opt_serviceChangeDelay(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeDelay(Delay, State) ->
+ tr_UINT32(Delay, State).
+
+tr_opt_serviceChangeMgcId(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeMgcId(MgcId, State) ->
+ tr_MId(MgcId, State).
+
+tr_opt_portNumber(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_portNumber(Port, State) ->
+ tr_portNumber(Port, State).
+
+tr_portNumber(Port, State) when is_integer(Port) andalso (Port >= 0) ->
+ tr_UINT16(Port, State).
+
+tr_ServiceChangeResParm(#'ServiceChangeResParm'{serviceChangeMgcId = MgcId,
+ serviceChangeAddress = Addr,
+ serviceChangeVersion = Version,
+ serviceChangeProfile = Profile,
+ timeStamp = Time},
+ State) ->
+ #'ServiceChangeResParm'{serviceChangeMgcId = tr_opt_serviceChangeMgcId(MgcId, State),
+ serviceChangeAddress = tr_opt_ServiceChangeAddress(Addr, State),
+ serviceChangeVersion = tr_opt_serviceChangeVersion(Version, State),
+ serviceChangeProfile = tr_opt_ServiceChangeProfile(Profile, State),
+ timeStamp = tr_opt_TimeNotation(Time, State)}.
+
+tr_PackagesDescriptor(Items, State) when is_list(Items) ->
+ [tr_PackagesItem(I, State) || I <- Items].
+
+tr_PackagesItem(#'PackagesItem'{packageName = Name,
+ packageVersion = Version},
+ State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ #'PackagesItem'{packageName = resolve(package, Name, State, Constraint),
+ packageVersion = tr_UINT16(Version, State)}.
+
+tr_opt_StatisticsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_StatisticsDescriptor(Parms, State) ->
+ tr_StatisticsDescriptor(Parms, State).
+
+tr_StatisticsDescriptor(Parms, State) when is_list(Parms) ->
+ [tr_StatisticsParameter(P, State) || P <- Parms].
+
+tr_StatisticsParameter(#'StatisticsParameter'{statName = Name,
+ statValue = Value},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'StatisticsParameter'{statName = resolve(statistics, Name, State, Constraint),
+ statValue = tr_opt_Value(Value, State)}.
+
+tr_opt_TimeNotation(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TimeNotation(#'TimeNotation'{date = Date,
+ time = Time},
+ State) ->
+ #'TimeNotation'{date = tr_STRING(Date, State, 8, 8), % "yyyymmdd"
+ time = tr_STRING(Time, State, 8, 8)}.% "hhmmssss"
+
+%% BUGBUG: Does not verify that string must contain at least one char
+%% BUGBUG: This violation of the is required in order to comply with
+%% BUGBUG: the dd/ce ds parameter that may possibly be empty.
+
+tr_opt_Value(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_Value(Value, State) ->
+ tr_Value(Value, State).
+
+tr_Value(Strings, _State) when is_list(Strings) ->
+ [[Char || Char <- String] || String <- Strings].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Encode an octet string, escape } by \ if necessary
+tr_OCTET_STRING(String, _State, Min, Max) when is_list(String) ->
+ verify_count(length(String), Min, Max),
+ String.
+
+tr_QUOTED_STRING(String, _State) when is_list(String) ->
+ verify_count(length(String), 1, infinity),
+ String.
+
+%% The internal format of hex digits is a list of octets
+%% Min and Max means #hexDigits
+%% Leading zeros are prepended in order to fulfill Min
+tr_HEXDIG(Octets, _State, Min, Max) when is_list(Octets) ->
+ verify_count(length(Octets), Min, Max),
+ Octets.
+
+tr_DIGIT(Val, State, Min, Max) ->
+ tr_integer(Val, State, Min, Max).
+
+tr_STRING(String, _State) when is_list(String) ->
+ String.
+
+tr_STRING(String, _State, Min, Max) when is_list(String) ->
+ verify_count(length(String), Min, Max),
+ String.
+
+tr_opt_UINT16(Val, State) ->
+ tr_opt_integer(Val, State, 0, 65535).
+
+tr_UINT16(Val, State) ->
+ tr_integer(Val, State, 0, 65535).
+
+tr_UINT32(Val, State) ->
+ tr_integer(Val, State, 0, 4294967295).
+
+tr_opt_integer(asn1_NOVALUE, _State, _Min, _Max) ->
+ asn1_NOVALUE;
+tr_opt_integer(Int, State, Min, Max) ->
+ tr_integer(Int, State, Min, Max).
+
+tr_integer(Int, _State, Min, Max) ->
+ verify_count(Int, Min, Max),
+ Int.
+
+%% Verify that Count is within the range of Min and Max
+verify_count(Count, Min, Max) ->
+ if
+ is_integer(Count) ->
+ if
+ is_integer(Min) andalso (Count >= Min) ->
+ if
+ is_integer(Max) andalso (Count =< Max) ->
+ Count;
+ Max =:= infinity ->
+ Count;
+ true ->
+ error({count_too_large, Count, Max})
+ end;
+ true ->
+ error({count_too_small, Count, Min})
+ end;
+ true ->
+ error({count_not_an_integer, Count})
+ end.
+
+
+%% -------------------------------------------------------------------
+
+error(Reason) ->
+ erlang:error(Reason).
+
+
diff --git a/lib/megaco/src/binary/megaco_binary_transformer_prev3b.erl b/lib/megaco/src/binary/megaco_binary_transformer_prev3b.erl
new file mode 100644
index 0000000000..baca84bbfe
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_transformer_prev3b.erl
@@ -0,0 +1,1629 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Transform internal form of Megaco/H.248 messages
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_transformer_prev3b).
+
+-include_lib("megaco/include/megaco.hrl").
+%% -include_lib("megaco/include/megaco_message.hrl").
+-include_lib("megaco/include/megaco_message_prev3b.hrl").
+-include_lib("megaco/src/app/megaco_internal.hrl").
+
+-export([tr_message/3, tr_transaction/3]).
+
+-define(DEFAULT_NAME_RESOLVER, megaco_binary_name_resolver_prev3b).
+
+-record(state, {mode, % verify | encode | decode
+ resolver_module, %
+ resolver_options}).
+
+resolve(Type, Item, State, Constraint) ->
+ case State#state.mode of
+ verify ->
+ Item;
+ encode ->
+ ?d("resolve(encode) -> encode: ~p",[Item]),
+ Mod = State#state.resolver_module,
+ Opt = State#state.resolver_options,
+ EncodedItem = Mod:encode_name(Opt, Type, Item),
+ ?d("resolve -> verify contraint for ~p",[EncodedItem]),
+ verify_constraint(EncodedItem, Constraint);
+ decode ->
+ ?d("resolve(decode) -> verify contraint for ~p",[Item]),
+ DecodedItem = verify_constraint(Item, Constraint),
+ Mod = State#state.resolver_module,
+ Opt = State#state.resolver_options,
+ ?d("resolve(decode) -> decode: ~p",[DecodedItem]),
+ Mod:decode_name(Opt, Type, DecodedItem)
+ end.
+
+verify_constraint(Item, valid) ->
+ Item;
+verify_constraint(Item, Constraint) when is_function(Constraint) ->
+ Constraint(Item).
+
+tr_message(MegaMsg, Mode, Config) ->
+ case Config of
+ [native] ->
+ MegaMsg;
+ [verify] ->
+ State = #state{mode = verify},
+ tr_MegacoMessage(MegaMsg, State);
+ [] ->
+ State = #state{mode = Mode,
+ resolver_module = ?DEFAULT_NAME_RESOLVER,
+ resolver_options = [8, 8, 8]},
+ tr_MegacoMessage(MegaMsg, State);
+ [{binary_name_resolver, {Module, Options}}] when is_atom(Module) ->
+ State = #state{mode = Mode,
+ resolver_module = Module,
+ resolver_options = Options},
+ tr_MegacoMessage(MegaMsg, State)
+ end.
+
+tr_transaction(Trans, Mode, Config) ->
+ case Config of
+ [native] ->
+ Trans;
+ [verify] ->
+ State = #state{mode = verify},
+ tr_Transaction(Trans, State);
+ [] ->
+ State = #state{mode = Mode,
+ resolver_module = ?DEFAULT_NAME_RESOLVER,
+ resolver_options = [8, 8, 8]},
+ tr_Transaction(Trans, State);
+ [{binary_name_resolver, {Module, Options}}] when is_atom(Module) ->
+ State = #state{mode = Mode,
+ resolver_module = Module,
+ resolver_options = Options},
+ tr_Transaction(Trans, State)
+ end.
+
+tr_MegacoMessage(#'MegacoMessage'{authHeader = Auth,
+ mess = Mess},
+ State) ->
+ ?d("tr_MegacoMessage -> entry with"
+ "~n Auth: ~p"
+ "~n Mess: ~p"
+ "~n State: ~p", [Auth, Mess, State]),
+ #'MegacoMessage'{authHeader = tr_opt_AuthenticationHeader(Auth, State),
+ mess = tr_Message(Mess, State)}.
+
+tr_opt_AuthenticationHeader(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_AuthenticationHeader(#'AuthenticationHeader'{secParmIndex = SPI,
+ seqNum = SN,
+ ad = AuthData},
+ State) ->
+ #'AuthenticationHeader'{secParmIndex = tr_SecurityParmIndex(SPI, State),
+ seqNum = tr_SequenceNum(SN, State),
+ ad = tr_AuthData(AuthData, State)}.
+
+tr_SecurityParmIndex(SPI, State) ->
+ tr_HEXDIG(SPI, State, 4, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_SequenceNum(SN, State) ->
+ tr_HEXDIG(SN, State, 4, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_AuthData(AuthData, State) ->
+ tr_HEXDIG(AuthData, State, 12, 32). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_Message(#'Message'{version = Version,
+ mId = MID,
+ messageBody = Body},
+ State) ->
+ #'Message'{version = tr_version(Version, State),
+ mId = tr_MId(MID, State),
+ messageBody = tr_Message_messageBody(Body, State)}.
+
+tr_version(Version, State) ->
+ tr_DIGIT(Version, State, 0, 99).
+
+tr_Message_messageBody({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ messageError -> tr_ErrorDescriptor(Val, State);
+ transactions when is_list(Val) -> [tr_Transaction(T, State) || T <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_MId({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ ip4Address -> tr_IP4Address(Val, State);
+ ip6Address -> tr_IP6Address(Val, State);
+ domainName -> tr_DomainName(Val, State);
+ deviceName -> tr_PathName(Val, State);
+ mtpAddress -> tr_mtpAddress(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_mtpAddress(MtpAddr, State) ->
+ tr_OCTET_STRING(MtpAddr, State, 2, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_DomainName(#'DomainName'{name = Name,
+ portNumber = Port},
+ State) ->
+ Domain = #'DomainName'{name = tr_STRING(Name, State), % BUGBUG: Mismatch between ASN.1 and ABNF
+ portNumber = tr_opt_portNumber(Port, State)},
+ {domainName, Domain2} = resolve(mid, {domainName, Domain}, State, valid),
+ Domain2.
+
+tr_IP4Address(#'IP4Address'{address = [A1, A2, A3, A4],
+ portNumber = Port},
+ State) ->
+ #'IP4Address'{address = [tr_V4hex(A1, State),
+ tr_V4hex(A2, State),
+ tr_V4hex(A3, State),
+ tr_V4hex(A4, State)],
+ portNumber = tr_opt_portNumber(Port, State)}.
+
+tr_V4hex(Val, State) ->
+ tr_DIGIT(Val, State, 0, 255).
+
+tr_IP6Address(_Val, _State) ->
+ error(ipv6_not_supported). %% BUGBUG: nyi
+
+tr_PathName(Path, State) ->
+ %% BUGBUG: ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
+ %% BUGBUG: ["@" pathDomainName ]
+ Constraint = fun({deviceName, Item}) -> tr_STRING(Item, State, 1, 64) end,
+ resolve(mid, {deviceName, Path}, State, Constraint).
+
+tr_Transaction({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ transactionRequest -> tr_TransactionRequest(Val, State);
+ transactionPending -> tr_TransactionPending(Val, State);
+ transactionReply -> tr_TransactionReply(Val, State);
+ transactionResponseAck -> [tr_TransactionAck(T, State) || T <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_TransactionAck(#'TransactionAck'{firstAck = First,
+ lastAck = Last},
+ State) ->
+ #'TransactionAck'{firstAck = tr_TransactionId(First, State),
+ lastAck = tr_opt_TransactionId(Last, State)}.
+
+tr_opt_TransactionId(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TransactionId(Id, State) ->
+ tr_TransactionId(Id, State).
+
+tr_TransactionId(Id, State) ->
+ tr_UINT32(Id, State).
+
+tr_TransactionRequest(#'TransactionRequest'{transactionId = Id,
+ actions = Actions},
+ State) when is_list(Actions) ->
+
+ #'TransactionRequest'{transactionId = tr_TransactionId(Id, State),
+ actions = [tr_ActionRequest(ActReq, State) || ActReq <- Actions]}.
+
+tr_TransactionPending(#'TransactionPending'{transactionId = Id},
+ State) ->
+ #'TransactionPending'{transactionId = tr_TransactionId(Id, State)}.
+
+tr_TransactionReply(#'TransactionReply'{transactionId = Id,
+ immAckRequired = ImmAck,
+ transactionResult = TransRes,
+ %% These fields are actually not
+ %% supported in this implementation,
+ %% but because the messanger module
+ %% cannot see any diff between the
+ %% various v3 implementations...
+ segmentNumber = asn1_NOVALUE,
+ segmentationComplete = asn1_NOVALUE},
+ State) ->
+ #'TransactionReply'{transactionId = tr_TransactionId(Id, State),
+ immAckRequired = tr_opt_null(ImmAck, State),
+ transactionResult = tr_TransactionReply_transactionResult(TransRes, State),
+ segmentNumber = asn1_NOVALUE,
+ segmentationComplete = asn1_NOVALUE};
+tr_TransactionReply(TR, _State) ->
+ error({unsupported_TransactionReply, TR}).
+
+tr_opt_null(asn1_NOVALUE, _State) -> asn1_NOVALUE;
+tr_opt_null('NULL', _State) -> 'NULL'.
+
+tr_TransactionReply_transactionResult({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ transactionError ->
+ tr_ErrorDescriptor(Val, State);
+ actionReplies when is_list(Val) andalso (Val =/= []) ->
+ [tr_ActionReply(ActRep, State) || ActRep <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_opt_ErrorDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ErrorDescriptor(ErrDesc, State) ->
+ tr_ErrorDescriptor(ErrDesc, State).
+
+tr_ErrorDescriptor(#'ErrorDescriptor'{errorCode = Code,
+ errorText = Text},
+ State) ->
+ #'ErrorDescriptor'{errorCode = tr_ErrorCode(Code, State),
+ errorText = tr_opt_ErrorText(Text, State)}.
+
+tr_ErrorCode(Code, State) ->
+ tr_DIGIT(Code, State, 0, 999).
+
+tr_opt_ErrorText(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ErrorText(Text, State) ->
+ tr_QUOTED_STRING(Text, State).
+
+tr_ContextID(CtxId, State) ->
+ case CtxId of
+ ?megaco_all_context_id -> ?megaco_all_context_id;
+ ?megaco_null_context_id -> ?megaco_null_context_id;
+ ?megaco_choose_context_id -> ?megaco_choose_context_id;
+ Int when is_integer(Int) -> tr_UINT32(Int, State)
+ end.
+
+tr_ActionRequest(#'ActionRequest'{contextId = CtxId,
+ contextRequest = CtxReq,
+ contextAttrAuditReq = CtxAuditReq,
+ commandRequests = CmdReqList},
+ State) ->
+ #'ActionRequest'{contextId = tr_ContextID(CtxId, State),
+ contextRequest = tr_opt_ContextRequest(CtxReq, State),
+ contextAttrAuditReq = tr_opt_ContextAttrAuditRequest(CtxAuditReq, State),
+ commandRequests = [tr_CommandRequest(CmdReq, State) || CmdReq <- CmdReqList]}.
+
+tr_ActionReply(#'ActionReply'{contextId = CtxId,
+ errorDescriptor = ErrDesc,
+ contextReply = CtxRep,
+ commandReply = CmdRepList},
+ State) ->
+ CmdRepList2 = [tr_CommandReply(CmdRep, State) || CmdRep <- CmdRepList],
+ #'ActionReply'{contextId = tr_ContextID(CtxId, State),
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State),
+ contextReply = tr_opt_ContextRequest(CtxRep, State),
+ commandReply = CmdRepList2}.
+
+tr_opt_ContextRequest(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ContextRequest(CR, State) ->
+ tr_ContextRequest(CR, State).
+
+tr_ContextRequest(#'ContextRequest'{priority = Prio,
+ emergency = Em,
+ topologyReq = TopReqList,
+ iepscallind = Ind,
+ contextProp = Props},
+ State) ->
+ Prio2 =
+ case Prio of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_integer(Prio, State, 0, 15)
+ end,
+ Em2 =
+ case Em of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ TopReqList2 =
+ case TopReqList of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_TopologyRequest(TopReq, State) ||
+ TopReq <- TopReqList]
+ end,
+ Ind2 =
+ case Ind of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ Props2 =
+ case Props of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_PropertyParm(Prop, State) || Prop <- Props]
+ end,
+ #'ContextRequest'{priority = Prio2,
+ emergency = Em2,
+ topologyReq = TopReqList2,
+ iepscallind = Ind2,
+ contextProp = Props2}.
+
+tr_opt_ContextAttrAuditRequest(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ContextAttrAuditRequest(CAAR, State) ->
+ tr_ContextAttrAuditRequest(CAAR, State).
+
+tr_ContextAttrAuditRequest(#'ContextAttrAuditRequest'{topology = Top,
+ emergency = Em,
+ priority = Prio,
+ iepscallind = Ind,
+ contextPropAud = Props},
+ State) ->
+ Top2 = tr_opt_null(Top, State),
+ Em2 = tr_opt_null(Em, State),
+ Prio2 = tr_opt_null(Prio, State),
+ Ind2 = tr_opt_null(Ind, State),
+ Props2 =
+ case Props of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ [tr_indAudPropertyParm(Prop, State) || Prop <- Props]
+ end,
+ #'ContextAttrAuditRequest'{topology = Top2,
+ emergency = Em2,
+ priority = Prio2,
+ iepscallind = Ind2,
+ contextPropAud = Props2}.
+
+tr_CommandRequest(#'CommandRequest'{command = Cmd,
+ optional = Opt,
+ wildcardReturn = Wild},
+ State) ->
+ #'CommandRequest'{optional = tr_opt_null(Opt, State),
+ wildcardReturn = tr_opt_null(Wild, State),
+ command = tr_Command(Cmd, State)}.
+
+tr_Command({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ addReq -> tr_AmmRequest(Val, State);
+ moveReq -> tr_AmmRequest(Val, State);
+ modReq -> tr_AmmRequest(Val, State);
+ subtractReq -> tr_SubtractRequest(Val, State);
+ auditCapRequest -> tr_AuditRequest(Val, State);
+ auditValueRequest -> tr_AuditRequest(Val, State);
+ notifyReq -> tr_NotifyRequest(Val, State);
+ serviceChangeReq -> tr_ServiceChangeRequest(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_CommandReply({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ addReply -> tr_AmmsReply(Val, State);
+ moveReply -> tr_AmmsReply(Val, State);
+ modReply -> tr_AmmsReply(Val, State);
+ subtractReply -> tr_AmmsReply(Val, State);
+ auditCapReply -> tr_AuditReply(Val, State);
+ auditValueReply -> tr_AuditReply(Val, State);
+ notifyReply -> tr_NotifyReply(Val, State);
+ serviceChangeReply -> tr_ServiceChangeReply(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_TopologyRequest(#'TopologyRequest'{terminationFrom = From,
+ terminationTo = To,
+ topologyDirection = Dir},
+ State) ->
+ Dir2 =
+ case Dir of
+ bothway -> bothway;
+ isolate -> isolate;
+ oneway -> oneway
+ end,
+ #'TopologyRequest'{terminationFrom = tr_TerminationID(From, State),
+ terminationTo = tr_TerminationID(To, State),
+ topologyDirection = Dir2}.
+
+tr_AmmRequest(#'AmmRequest'{terminationID = IdList,
+ descriptors = DescList},
+ State) ->
+ #'AmmRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ descriptors = tr_ammDescriptors(DescList, [], State)}.
+
+tr_ammDescriptors([], Acc, _State) ->
+ lists:reverse(Acc);
+tr_ammDescriptors([Desc|Descs], Acc, State) ->
+ case tr_ammDescriptor(Desc, State) of
+ {_, deprecated} when State#state.mode =:= encode ->
+ error({deprecated, Desc});
+ {_, deprecated} when State#state.mode =:= decode ->
+ %% SKIP
+ tr_ammDescriptors(Descs, Acc, State);
+ {_, deprecated} ->
+ %% SKIP
+ tr_ammDescriptors(Descs, Acc, State);
+ NewDesc ->
+ tr_ammDescriptors(Descs, [NewDesc|Acc], State)
+ end.
+
+tr_ammDescriptor({Tag, Desc}, State) ->
+ Desc2 =
+ case Tag of
+ mediaDescriptor -> tr_MediaDescriptor(Desc, State);
+ modemDescriptor -> tr_ModemDescriptor(Desc, State);
+ muxDescriptor -> tr_MuxDescriptor(Desc, State);
+ eventsDescriptor -> tr_EventsDescriptor(Desc, State);
+ eventBufferDescriptor -> tr_EventBufferDescriptor(Desc, State);
+ signalsDescriptor -> tr_SignalsDescriptor(Desc, State);
+ digitMapDescriptor -> tr_DigitMapDescriptor(Desc, State);
+ auditDescriptor -> tr_AuditDescriptor(Desc, State);
+ statisticsDescriptor -> tr_StatisticsDescriptor(Desc, State)
+ end,
+ {Tag, Desc2}.
+
+tr_AmmsReply(#'AmmsReply'{terminationID = IdList,
+ terminationAudit = TermAudit},
+ State) ->
+ TermAudit2 =
+ case TermAudit of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_TerminationAudit(TermAudit, State)
+ end,
+ #'AmmsReply'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ terminationAudit = TermAudit2}.
+
+tr_SubtractRequest(#'SubtractRequest'{terminationID = IdList,
+ auditDescriptor = Desc},
+ State) ->
+ #'SubtractRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ auditDescriptor = tr_opt_AuditDescriptor(Desc, State)}.
+
+tr_AuditRequest(#'AuditRequest'{terminationID = Id,
+ auditDescriptor = Desc},
+ State) ->
+ #'AuditRequest'{terminationID = tr_TerminationID(Id, State),
+ auditDescriptor = tr_AuditDescriptor(Desc, State)}.
+
+%% auditReply = (AuditValueToken / AuditCapToken )
+%% ( contextTerminationAudit / auditOther)
+%% auditOther = EQUAL TerminationID LBRKT
+%% terminationAudit RBRKT
+%% terminationAudit = auditReturnParameter *(COMMA auditReturnParameter)
+%%
+%% contextTerminationAudit = EQUAL CtxToken ( terminationIDList /
+%% LBRKT errorDescriptor RBRKT )
+
+tr_AuditReply({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ contextAuditResult ->
+ [tr_TerminationID(Id, State) || Id <- Val];
+ error ->
+ tr_ErrorDescriptor(Val, State);
+ auditResult ->
+ tr_AuditResult(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_AuditResult(#'AuditResult'{terminationID = Id,
+ terminationAuditResult = AuditRes},
+ State) ->
+ #'AuditResult'{terminationID = tr_TerminationID(Id, State),
+ terminationAuditResult = tr_TerminationAudit(AuditRes, State)}.
+
+tr_opt_AuditDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_AuditDescriptor(Desc, State) ->
+ tr_AuditDescriptor(Desc, State).
+
+%% BUGBUG BUGBUG BUGBUG
+%% With this construction it is possible to have both auditToken
+%% and auditPropertyToken, but it is actually valid?
+tr_AuditDescriptor(#'AuditDescriptor'{auditToken = Tokens,
+ auditPropertyToken = APTs},
+ State) ->
+ Tokens2 =
+ case Tokens of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_auditItem(Token, State) || Token <- Tokens]
+ end,
+ %% v2
+ APTs2 =
+ case APTs of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ [tr_indAuditParameter(APT, State) || APT <- APTs]
+ end,
+ #'AuditDescriptor'{auditToken = Tokens2,
+ auditPropertyToken = APTs2}.
+
+tr_auditItem(Token, _State) ->
+ case Token of
+ muxToken -> muxToken;
+ modemToken -> modemToken;
+ mediaToken -> mediaToken;
+ eventsToken -> eventsToken;
+ signalsToken -> signalsToken;
+ digitMapToken -> digitMapToken;
+ statsToken -> statsToken;
+ observedEventsToken -> observedEventsToken;
+ packagesToken -> packagesToken;
+ eventBufferToken -> eventBufferToken
+ end.
+
+%% --- v2 begin ---
+
+tr_indAuditParameter({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ indAudMediaDescriptor ->
+ tr_indAudMediaDescriptor(Val, State);
+ indAudEventsDescriptor ->
+ tr_indAudEventsDescriptor(Val, State);
+ indAudSignalsDescriptor ->
+ tr_indAudSignalsDescriptor(Val, State);
+ indAudDigitMapDescriptor ->
+ tr_indAudDigitMapDescriptor(Val, State);
+ indAudEventBufferDescriptor ->
+ tr_indAudEventBufferDescriptor(Val, State);
+ indAudStatisticsDescriptor ->
+ tr_indAudStatisticsDescriptor(Val, State);
+ indAudPackagesDescriptor ->
+ tr_indAudPackagesDescriptor(Val, State)
+ end,
+ {Tag, Val2}.
+
+
+%% -
+
+tr_indAudMediaDescriptor(#'IndAudMediaDescriptor'{termStateDescr = TSD,
+ streams = S},
+ State) ->
+ TSD2 =
+ case TSD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudTerminationStateDescriptor(TSD, State)
+ end,
+ S2 =
+ case S of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ {oneStream, OS} ->
+ {oneStream, tr_indAudStreamParms(OS, State)};
+ {multiStream, MS} ->
+ MS2 = [tr_indAudStreamDescriptor(MS1, State) || MS1 <- MS],
+ {multiStream, MS2}
+ end,
+ #'IndAudMediaDescriptor'{termStateDescr = TSD2,
+ streams = S2}.
+
+tr_indAudTerminationStateDescriptor(Val, State)
+ when is_record(Val, 'IndAudTerminationStateDescriptor') ->
+ #'IndAudTerminationStateDescriptor'{propertyParms = Parms,
+ eventBufferControl = EBC,
+ serviceState = SS} = Val,
+ Parms2 = [tr_indAudPropertyParm(Parm, State) || Parm <- Parms],
+ EBC2 = tr_opt_null(EBC, State),
+ SS2 = tr_opt_null(SS, State),
+ #'IndAudTerminationStateDescriptor'{propertyParms = Parms2,
+ eventBufferControl = EBC2,
+ serviceState = SS2}.
+
+
+tr_indAudStreamParms(#'IndAudStreamParms'{localControlDescriptor = LCD,
+ localDescriptor = LD,
+ remoteDescriptor = RD,
+ statisticsDescriptor = SD},
+ State) ->
+ LCD2 =
+ case LCD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalControlDescriptor(LCD, State)
+ end,
+ LD2 =
+ case LD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalRemoteDescriptor(LD, State)
+ end,
+ RD2 =
+ case RD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalRemoteDescriptor(RD, State)
+ end,
+ SD2 =
+ case SD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudStatisticsDescriptor(SD, State)
+ end,
+ #'IndAudStreamParms'{localControlDescriptor = LCD2,
+ localDescriptor = LD2,
+ remoteDescriptor = RD2,
+ statisticsDescriptor = SD2}.
+
+tr_indAudLocalControlDescriptor(Val, State)
+ when is_record(Val, 'IndAudLocalControlDescriptor') ->
+ #'IndAudLocalControlDescriptor'{streamMode = M,
+ reserveValue = V,
+ reserveGroup = G,
+ propertyParms = P} = Val,
+ M2 = tr_opt_null(M, State),
+ V2 = tr_opt_null(V, State),
+ G2 = tr_opt_null(G, State),
+ P2 = tr_indAudLocalControlDescriptor_propertyParms(P, State),
+ #'IndAudLocalControlDescriptor'{streamMode = M2,
+ reserveValue = V2,
+ reserveGroup = G2,
+ propertyParms = P2}.
+
+tr_indAudLocalControlDescriptor_propertyParms(Parms, State)
+ when is_list(Parms) andalso (length(Parms) > 0) ->
+ [tr_indAudPropertyParm(Parm, State) || Parm <- Parms];
+tr_indAudLocalControlDescriptor_propertyParms(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE.
+
+tr_indAudLocalRemoteDescriptor(#'IndAudLocalRemoteDescriptor'{propGroupID = ID,
+ propGrps = Grps},
+ State) ->
+ #'IndAudLocalRemoteDescriptor'{propGroupID = tr_opt_UINT16(ID, State),
+ propGrps = tr_indAudPropertyGroup(Grps,
+ State)}.
+
+tr_indAudPropertyGroup(Grps, State) when is_list(Grps) ->
+ [tr_indAudPropertyParm(Parm, State) || Parm <- Grps].
+
+tr_indAudPropertyParm(#'IndAudPropertyParm'{name = Name0}, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(property, Name0, State, Constraint),
+ #'IndAudPropertyParm'{name = Name}.
+
+
+tr_indAudStreamDescriptor(#'IndAudStreamDescriptor'{streamID = ID,
+ streamParms = Parms},
+ State) ->
+ #'IndAudStreamDescriptor'{streamID = tr_StreamID(ID, State),
+ streamParms = tr_indAudStreamParms(Parms,
+ State)}.
+
+
+%% -
+
+tr_indAudEventsDescriptor(#'IndAudEventsDescriptor'{requestID = RID,
+ pkgdName = Name0,
+ streamID = SID},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(event, Name0, State, Constraint),
+ #'IndAudEventsDescriptor'{requestID = tr_opt_RequestID(RID, State),
+ pkgdName = Name,
+ streamID = tr_opt_StreamID(SID, State)}.
+
+
+%% -
+
+tr_indAudSignalsDescriptor({Tag, Val}, State) ->
+ case Tag of
+ signal ->
+ {signal, tr_indAudSignal(Val, State)};
+ seqSigList ->
+ {seqSigList, tr_indAudSeqSigList(Val, State)}
+ end.
+
+tr_opt_indAudSignal(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_indAudSignal(Val, State) ->
+ tr_indAudSignal(Val, State).
+
+tr_indAudSignal(#'IndAudSignal'{signalName = Name0,
+ streamID = SID}, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(signal, Name0, State, Constraint),
+ #'IndAudSignal'{signalName = Name,
+ streamID = tr_opt_StreamID(SID, State)}.
+
+tr_indAudSeqSigList(#'IndAudSeqSigList'{id = ID,
+ signalList = SigList}, State) ->
+ #'IndAudSeqSigList'{id = tr_integer(ID, State, 0, 65535),
+ signalList = tr_opt_indAudSignal(SigList, State)}.
+
+%% -
+
+tr_indAudDigitMapDescriptor(#'IndAudDigitMapDescriptor'{digitMapName = Name},
+ State) ->
+ #'IndAudDigitMapDescriptor'{digitMapName =
+ tr_opt_DigitMapName(Name, State)}.
+
+
+%% -
+
+tr_indAudEventBufferDescriptor(#'IndAudEventBufferDescriptor'{eventName = N,
+ streamID = SID},
+ State) ->
+ ?d("tr_indAudEventBufferDescriptor -> entry with"
+ "~n N: ~p"
+ "~n SID: ~p", [N, SID]),
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(event, N, State, Constraint),
+ ?d("tr_indAudEventBufferDescriptor -> entry with"
+ "~n Name: ~p", [Name]),
+ #'IndAudEventBufferDescriptor'{eventName = Name,
+ streamID = tr_opt_StreamID(SID, State)}.
+
+%% -
+
+tr_indAudStatisticsDescriptor(#'IndAudStatisticsDescriptor'{statName = N},
+ State) ->
+ ?d("tr_indAudEventBufferDescriptor -> entry with"
+ "~n N: ~p", [N]),
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(statistics, N, State, Constraint),
+ #'IndAudStatisticsDescriptor'{statName = Name}.
+
+
+%% -
+
+tr_indAudPackagesDescriptor(#'IndAudPackagesDescriptor'{packageName = N,
+ packageVersion = V},
+ State) ->
+ ?d("tr_indAudPackagesDescriptor -> entry with"
+ "~n N: ~p"
+ "~n V: ~p", [N, V]),
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ Name = resolve(package, N, State, Constraint),
+ ?d("tr_indAudPackagesDescriptor -> entry with"
+ "~n Name: ~p", [Name]),
+ #'IndAudPackagesDescriptor'{packageName = Name,
+ packageVersion = tr_integer(V, State, 0, 99)}.
+
+%% -- v2 end --
+
+
+tr_TerminationAudit(ParmList, State) when is_list(ParmList) ->
+ do_tr_TerminationAudit(ParmList, [], State).
+
+do_tr_TerminationAudit([], Acc, _State) ->
+ lists:reverse(Acc);
+do_tr_TerminationAudit([Parm|ParmList], Acc, State) ->
+ case tr_AuditReturnParameter(Parm, State) of
+ {_, deprecated} when State#state.mode =:= encode ->
+ error({deprecated, Parm});
+ {_, deprecated} when State#state.mode =:= decode ->
+ %% SKIP
+ do_tr_TerminationAudit(ParmList, Acc, State);
+ {_, deprecated} ->
+ %% SKIP
+ do_tr_TerminationAudit(ParmList, Acc, State);
+ NewParm ->
+ do_tr_TerminationAudit(ParmList, [NewParm|Acc], State)
+ end.
+
+tr_AuditReturnParameter({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ errorDescriptor ->
+ tr_ErrorDescriptor(Val, State);
+ mediaDescriptor ->
+ tr_MediaDescriptor(Val, State);
+ modemDescriptor ->
+ tr_ModemDescriptor(Val, State);
+ muxDescriptor ->
+ tr_MuxDescriptor(Val, State);
+ eventsDescriptor ->
+ tr_EventsDescriptor(Val, State);
+ eventBufferDescriptor ->
+ tr_EventBufferDescriptor(Val, State);
+ signalsDescriptor ->
+ tr_SignalsDescriptor(Val, State);
+ digitMapDescriptor ->
+ tr_DigitMapDescriptor(Val, State);
+ observedEventsDescriptor ->
+ tr_ObservedEventsDescriptor(Val, State);
+ statisticsDescriptor ->
+ tr_StatisticsDescriptor(Val, State);
+ packagesDescriptor ->
+ tr_PackagesDescriptor(Val, State);
+ emptyDescriptors ->
+ tr_EmptyDescriptors(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_EmptyDescriptors(#'AuditDescriptor'{auditToken = Tokens},
+ State) ->
+ case Tokens of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_auditItem(Token, State) || Token <- Tokens]
+ end.
+
+tr_NotifyRequest(#'NotifyRequest'{terminationID = IdList,
+ observedEventsDescriptor = ObsDesc,
+ errorDescriptor = ErrDesc},
+ State) ->
+ %% BUGBUG: Mismatch between ASN.1 and ABNF
+ %% BUGBUG: The following ought to be a 'choice'
+ #'NotifyRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ observedEventsDescriptor = tr_ObservedEventsDescriptor(ObsDesc, State),
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State)}.
+
+tr_NotifyReply(#'NotifyReply'{terminationID = IdList,
+ errorDescriptor = ErrDesc},
+ State) ->
+ #'NotifyReply'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State)}.
+
+tr_ObservedEventsDescriptor(#'ObservedEventsDescriptor'{requestId = Id,
+ observedEventLst = Events},
+ State) when is_list(Events) ->
+ #'ObservedEventsDescriptor'{requestId = tr_RequestID(Id, State),
+ observedEventLst = [tr_ObservedEvent(E, State) || E <- Events]}.
+
+%% ;time per event, because it might be buffered
+%% observedEvent = [ TimeStamp LWSP COLON] LWSP
+%% pkgdName [ LBRKT observedEventParameter
+%% *(COMMA observedEventParameter) RBRKT ]
+%%
+%% ;at-most-once eventStream, every eventParameterName at most once
+%% observedEventParameter = eventStream / eventOther
+
+tr_ObservedEvent(#'ObservedEvent'{eventName = Name,
+ streamID = Id,
+ eventParList = Parms,
+ timeNotation = Time},
+ State) ->
+ #'ObservedEvent'{eventName = tr_EventName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ eventParList = [tr_EventParameter(P, Name, State) || P <- Parms],
+ timeNotation = tr_opt_TimeNotation(Time, State)}.
+
+tr_EventName(Name, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ resolve(event, Name, State, Constraint).
+
+tr_EventParameter(#'EventParameter'{eventParameterName = ParName,
+ value = Value,
+ extraInfo = Extra},
+ EventName,
+ State) ->
+ %% BUGBUG: event parameter name
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ N = resolve({event_parameter, EventName}, ParName, State, Constraint),
+ #'EventParameter'{eventParameterName = N,
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_ServiceChangeRequest(#'ServiceChangeRequest'{terminationID = IdList,
+ serviceChangeParms = Parms},
+ State) ->
+ #'ServiceChangeRequest'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ serviceChangeParms = tr_ServiceChangeParm(Parms, State)}.
+
+%% serviceChangeReply = ServiceChangeToken EQUAL TerminationID
+%% [LBRKT (errorDescriptor /
+%% serviceChangeReplyDescriptor) RBRKT]
+%% serviceChangeReplyDescriptor = ServicesToken LBRKT
+%% servChgReplyParm *(COMMA servChgReplyParm) RBRKT
+%%
+%% ;at-most-once. Version is REQUIRED on first ServiceChange response
+%% servChgReplyParm = (serviceChangeAddress / serviceChangeMgcId /
+%% serviceChangeProfile / serviceChangeVersion )
+tr_ServiceChangeReply(#'ServiceChangeReply'{terminationID = IdList,
+ serviceChangeResult = Res},
+ State) ->
+ #'ServiceChangeReply'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ serviceChangeResult = tr_ServiceChangeResult(Res, State)}.
+
+tr_ServiceChangeResult({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ errorDescriptor -> tr_ErrorDescriptor(Val, State);
+ serviceChangeResParms -> tr_ServiceChangeResParm(Val, State)
+ end,
+ {Tag, Val2}.
+
+%% TerminationID = "ROOT" / pathNAME / "$" / "*"
+%% ; Total length of pathNAME must not exceed 64 chars.
+%% pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
+%% ["@" pathDomainName ]
+
+tr_TerminationID(TermId, State) when State#state.mode =/= verify ->
+ resolve(term_id, TermId, State, valid);
+tr_TerminationID(#'TerminationID'{wildcard = Wild,
+ id = Id},
+ _State) ->
+ #'TerminationID'{wildcard = Wild,
+ id = Id};
+tr_TerminationID(#megaco_term_id{contains_wildcards = IsWild,
+ id = Id},
+ State) ->
+ #megaco_term_id{contains_wildcards = tr_bool(IsWild, State),
+ id = [tr_term_id_component(Sub, State) || Sub <- Id]}.
+
+tr_opt_bool(asn1_NOVALUE, _State) -> asn1_NOVALUE;
+tr_opt_bool(Bool, State) -> tr_bool(Bool, State).
+
+tr_bool(true, _State) -> true;
+tr_bool(false, _State) -> false.
+
+tr_term_id_component(Sub, _State) ->
+ case Sub of
+ all -> all;
+ choose -> choose;
+ Char when is_integer(Char) -> Char
+ end.
+
+%% mediaDescriptor = MediaToken LBRKT mediaParm *(COMMA mediaParm) RBRKT
+%% ; at-most-once per item
+%% ; and either streamParm or streamDescriptor but not both
+%% mediaParm = (streamParm / streamDescriptor /
+%% terminationStateDescriptor)
+%% ; at-most-once
+%% streamParm = ( localDescriptor / remoteDescriptor /
+%% localControlDescriptor )
+%% streamDescriptor = StreamToken EQUAL StreamID LBRKT streamParm
+%% *(COMMA streamParm) RBRKT
+tr_MediaDescriptor(#'MediaDescriptor'{termStateDescr = TermState,
+ streams = Streams},
+ State) ->
+ #'MediaDescriptor'{termStateDescr = tr_opt_TerminationStateDescriptor(TermState, State),
+ streams = tr_opt_streams(Streams, State)}.
+
+tr_opt_streams(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_streams({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ oneStream -> tr_StreamParms(Val, State);
+ multiStream -> [tr_StreamDescriptor(SD, State) || SD <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_StreamParms(#'StreamParms'{localControlDescriptor = LCD,
+ localDescriptor = LD,
+ remoteDescriptor = RD,
+ statisticsDescriptor = SD},
+ State) ->
+ LCD2 = tr_opt_LocalControlDescriptor(LCD, State),
+ LD2 = tr_opt_LocalRemoteDescriptor(LD, State),
+ RD2 = tr_opt_LocalRemoteDescriptor(RD, State),
+ SD2 = tr_opt_StatisticsDescriptor(SD, State),
+ #'StreamParms'{localControlDescriptor = LCD2,
+ localDescriptor = LD2,
+ remoteDescriptor = RD2,
+ statisticsDescriptor = SD2}.
+
+tr_StreamDescriptor(#'StreamDescriptor'{streamID = Id,
+ streamParms = Parms},
+ State) ->
+ #'StreamDescriptor'{streamID = tr_StreamID(Id, State),
+ streamParms = tr_StreamParms(Parms, State)}.
+
+%% localControlDescriptor = LocalControlToken LBRKT localParm
+%% *(COMMA localParm) RBRKT
+%%
+%% ; at-most-once per item
+%% localParm = ( streamMode / propertyParm /
+%% reservedValueMode / reservedGroupMode )
+%% reservedValueMode = ReservedValueToken EQUAL ( "ON" / "OFF" )
+%% reservedGroupMode = ReservedGroupToken EQUAL ( "ON" / "OFF" )
+%%
+%% reservedMode = ReservedToken EQUAL ( "ON" / "OFF" )
+%%
+%% streamMode = ModeToken EQUAL streamModes
+tr_opt_LocalControlDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_LocalControlDescriptor(#'LocalControlDescriptor'{streamMode = Mode,
+ reserveGroup = Group,
+ reserveValue = Value,
+ propertyParms = Props},
+ State) ->
+ #'LocalControlDescriptor'{streamMode = tr_opt_StreamMode(Mode, State),
+ reserveGroup = tr_opt_bool(Group, State),
+ reserveValue = tr_opt_bool(Value, State),
+ propertyParms = [tr_PropertyParm(P, State) || P <- Props]}.
+
+tr_opt_StreamMode(Mode, _State) ->
+ case Mode of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ sendOnly -> sendOnly;
+ recvOnly -> recvOnly;
+ sendRecv -> sendRecv;
+ inactive -> inactive;
+ loopBack -> loopBack
+ end.
+
+tr_Name(Name, State) ->
+ %% BUGBUG: transform
+ %% BUGBUG: NAME = ALPHA *63(ALPHA / DIGIT / "_" )
+ tr_STRING(Name, State, 2, 2).
+
+tr_PkgdName(Name, State) ->
+ %% BUGBUG: transform
+ %% BUGBUG: pkgdName = (NAME / "*") SLASH (ItemID / "*" )
+ tr_OCTET_STRING(Name, State, 4, 4).
+
+%% When text encoding the protocol, the descriptors consist of session
+%% descriptions as defined in SDP (RFC2327), except that the "s=", "t="
+%% and "o=" lines are optional. When multiple session descriptions are
+%% provided in one descriptor, the "v=" lines are required as delimiters;
+%% otherwise they are optional. Implementations shall accept session
+%% descriptions that are fully conformant to RFC2327. When binary
+%% encoding the protocol the descriptor consists of groups of properties
+%% (tag-value pairs) as specified in Annex C. Each such group may
+%% contain the parameters of a session description.
+tr_opt_LocalRemoteDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_LocalRemoteDescriptor(#'LocalRemoteDescriptor'{propGrps = Groups},
+ State) ->
+ #'LocalRemoteDescriptor'{propGrps = [tr_PropertyGroup(G, State) || G <- Groups]}.
+
+tr_PropertyGroup(Props, State) ->
+ [tr_PropertyGroupParm(P, State) || P <- Props].
+
+tr_PropertyGroupParm(#'PropertyParm'{name = Name,
+ value = Value},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'PropertyParm'{name = resolve(property, Name, State, Constraint),
+ value = tr_OCTET_STRING(Value, State, 0, infinity)}.
+
+tr_PropertyParm(#'PropertyParm'{name = Name,
+ value = Value,
+ extraInfo = Extra},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'PropertyParm'{name = resolve(property, Name, State, Constraint),
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_opt_extraInfo(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_extraInfo({relation, Rel}, _State) ->
+ Rel2 =
+ case Rel of
+ greaterThan -> greaterThan;
+ smallerThan -> smallerThan;
+ unequalTo -> unequalTo
+ end,
+ {relation, Rel2};
+tr_opt_extraInfo({range, Range}, State) ->
+ Range2 = tr_bool(Range, State),
+ {range, Range2};
+tr_opt_extraInfo({sublist, Sub}, State) ->
+ Sub2 = tr_bool(Sub, State),
+ {sublist, Sub2}.
+
+tr_opt_TerminationStateDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TerminationStateDescriptor(#'TerminationStateDescriptor'{propertyParms = Props,
+ eventBufferControl = Control,
+ serviceState = Service},
+ State) ->
+ #'TerminationStateDescriptor'{propertyParms = [tr_PropertyParm(P, State) || P <- Props],
+ eventBufferControl = tr_opt_EventBufferControl(Control, State),
+ serviceState = tr_opt_ServiceState(Service, State)}.
+
+tr_opt_EventBufferControl(Control, _State) ->
+ case Control of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ off -> off;
+ lockStep -> lockStep
+ end.
+
+tr_opt_ServiceState(Service, _State) ->
+ case Service of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ test -> test;
+ outOfSvc -> outOfSvc;
+ inSvc -> inSvc
+ end.
+
+tr_MuxDescriptor(#'MuxDescriptor'{muxType = Type,
+ termList = IdList},
+ State) ->
+ #'MuxDescriptor'{muxType = tr_MuxType(Type, State),
+ termList = [tr_TerminationID(Id, State) || Id <- IdList]}.
+
+tr_MuxType(Type, _State) ->
+ case Type of
+ h221 -> h221;
+ h223 -> h223;
+ h226 -> h226;
+ v76 -> v76
+ end.
+
+tr_opt_StreamID(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_StreamID(Id, State) ->
+ tr_StreamID(Id, State).
+
+tr_StreamID(Id, State) ->
+ tr_UINT16(Id, State).
+
+tr_EventsDescriptor(#'EventsDescriptor'{requestID = Id,
+ eventList = Events},
+ State) ->
+ #'EventsDescriptor'{requestID = tr_opt_RequestID(Id, State),
+ eventList = [tr_RequestedEvent(E, State) || E <- Events]}.
+
+tr_RequestedEvent(#'RequestedEvent'{pkgdName = Name,
+ streamID = Id,
+ evParList = Parms,
+ eventAction = Actions},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'RequestedEvent'{pkgdName = resolve(event, Name, State, Constraint),
+ streamID = tr_opt_StreamID(Id, State),
+ eventAction = tr_opt_RequestedActions(Actions, State),
+ evParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+tr_opt_RequestedActions(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_RequestedActions(#'RequestedActions'{keepActive = Keep,
+ eventDM = DM,
+ secondEvent = Event,
+ signalsDescriptor = SigDesc},
+ State) ->
+ #'RequestedActions'{keepActive = tr_opt_keepActive(Keep, State),
+ eventDM = tr_opt_EventDM(DM, State),
+ secondEvent = tr_opt_SecondEventsDescriptor(Event, State),
+ signalsDescriptor = tr_opt_SignalsDescriptor(SigDesc, State)}.
+
+tr_opt_keepActive(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_keepActive(Keep, State) ->
+ tr_bool(Keep, State).
+
+tr_opt_EventDM(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_EventDM({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ digitMapName -> tr_DigitMapName(Val, State);
+ digitMapValue -> tr_DigitMapValue(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_opt_SecondEventsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SecondEventsDescriptor(#'SecondEventsDescriptor'{requestID = Id,
+ eventList = Events},
+ State) ->
+ #'SecondEventsDescriptor'{requestID = tr_RequestID(Id, State), %% IG v6 6.8 withdrawn
+ eventList = [tr_SecondRequestedEvent(E, State) || E <- Events]}.
+
+tr_SecondRequestedEvent(#'SecondRequestedEvent'{pkgdName = Name,
+ streamID = Id,
+ evParList = Parms,
+ eventAction = Actions},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'SecondRequestedEvent'{pkgdName = resolve(event, Name, State, Constraint),
+ streamID = tr_opt_StreamID(Id, State),
+ eventAction = tr_opt_SecondRequestedActions(Actions, State),
+ evParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+
+tr_opt_SecondRequestedActions(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SecondRequestedActions(#'SecondRequestedActions'{keepActive = Keep,
+ eventDM = DM,
+ signalsDescriptor = SigDesc},
+ State) ->
+ #'SecondRequestedActions'{keepActive = tr_opt_keepActive(Keep, State),
+ eventDM = tr_opt_EventDM(DM, State),
+ signalsDescriptor = tr_opt_SignalsDescriptor(SigDesc, State)}.
+
+tr_EventBufferDescriptor(EventSpecs, State) ->
+ [tr_EventSpec(ES, State) || ES <- EventSpecs].
+
+tr_EventSpec(#'EventSpec'{eventName = Name,
+ streamID = Id,
+ eventParList = Parms},
+ State) ->
+ #'EventSpec'{eventName = tr_EventName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ eventParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+tr_opt_SignalsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SignalsDescriptor(SigDesc, State) ->
+ tr_SignalsDescriptor(SigDesc, State).
+
+tr_SignalsDescriptor(SigDesc, State) when is_list(SigDesc) ->
+ [tr_SignalRequest(SigReq, State) || SigReq <- SigDesc].
+
+tr_SignalRequest({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ signal -> tr_Signal(Val, State);
+ seqSigList -> tr_SeqSigList(Val, State)
+ end,
+ {Tag, Val2}.
+
+
+tr_SeqSigList(#'SeqSigList'{id = Id,
+ signalList = SigList},
+ State) when is_list(SigList) ->
+ #'SeqSigList'{id = tr_UINT16(Id, State),
+ signalList = [tr_Signal(Sig, State) || Sig <- SigList]}.
+
+tr_Signal(#'Signal'{signalName = Name,
+ streamID = SID,
+ sigType = Type,
+ duration = Dur,
+ notifyCompletion = Compl,
+ keepActive = Keep,
+ sigParList = Parms,
+ direction = Dir,
+ requestID = RID},
+ State) ->
+ Name2 = tr_SignalName(Name, State),
+ SID2 = tr_opt_StreamID(SID, State),
+ Type2 = tr_opt_SignalType(Type, State),
+ Dur2 = tr_opt_duration(Dur, State),
+ Compl2 = tr_opt_NotifyCompletion(Compl, State),
+ Keep2 = tr_opt_keepActive(Keep, State),
+ Parms2 = [tr_SigParameter(P, Name, State) || P <- Parms],
+ Dir2 = tr_opt_SignalDirection(Dir, State),
+ RID2 = tr_opt_RequestID(RID, State),
+ #'Signal'{signalName = Name2,
+ streamID = SID2,
+ sigType = Type2,
+ duration = Dur2,
+ notifyCompletion = Compl2,
+ keepActive = Keep2,
+ sigParList = Parms2,
+ direction = Dir2,
+ requestID = RID2}.
+
+tr_opt_duration(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_duration(Dur, State) ->
+ tr_UINT16(Dur, State).
+
+tr_opt_NotifyCompletion(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_NotifyCompletion(Items, State) when is_list(Items) ->
+ [tr_notifyCompletionItem(I, State) || I <- Items].
+
+tr_notifyCompletionItem(Item, _State) ->
+ case Item of
+ onTimeOut -> onTimeOut;
+ onInterruptByEvent -> onInterruptByEvent;
+ onInterruptByNewSignalDescr -> onInterruptByNewSignalDescr;
+ otherReason -> otherReason
+ end.
+
+tr_opt_SignalType(asn1_NOVALUE = Type, _State) ->
+ Type;
+tr_opt_SignalType(Type, _State) ->
+ case Type of
+ brief -> brief;
+ onOff -> onOff;
+ timeOut -> timeOut
+ end.
+
+tr_opt_SignalDirection(asn1_NOVALUE = SD, _State) ->
+ SD;
+tr_opt_SignalDirection(SD, _State) ->
+ case SD of
+ internal -> internal;
+ external -> external;
+ both -> both
+ end.
+
+tr_SignalName(Name, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ resolve(signal, Name, State, Constraint).
+
+tr_SigParameter(#'SigParameter'{sigParameterName = ParName,
+ value = Value,
+ extraInfo = Extra},
+ SigName,
+ State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ N = resolve({signal_parameter, SigName}, ParName, State, Constraint),
+ #'SigParameter'{sigParameterName = N,
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_opt_RequestID(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_RequestID(Id, State) ->
+ tr_RequestID(Id, State).
+
+tr_RequestID(Id, _State) when Id =:= ?megaco_all_request_id ->
+ ?megaco_all_request_id;
+tr_RequestID(Id, State) ->
+ tr_UINT32(Id, State).
+
+tr_ModemDescriptor(_MD, _State) ->
+ deprecated.
+
+tr_DigitMapDescriptor(#'DigitMapDescriptor'{digitMapName = Name,
+ digitMapValue = Value},
+ State) ->
+ #'DigitMapDescriptor'{digitMapName = tr_opt_DigitMapName(Name, State),
+ digitMapValue = tr_opt_DigitMapValue(Value, State)}.
+
+tr_opt_DigitMapName(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_DigitMapName(Name, State) ->
+ tr_DigitMapName(Name, State).
+
+tr_DigitMapName(Name, State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ resolve(dialplan, Name, State, Constraint).
+
+tr_opt_DigitMapValue(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_DigitMapValue(Value, State) ->
+ tr_DigitMapValue(Value, State).
+
+tr_DigitMapValue(#'DigitMapValue'{digitMapBody = Body,
+ startTimer = Start,
+ shortTimer = Short,
+ longTimer = Long},
+ State) ->
+ #'DigitMapValue'{startTimer = tr_opt_timer(Start, State),
+ shortTimer = tr_opt_timer(Short, State),
+ longTimer = tr_opt_timer(Long, State),
+ digitMapBody = tr_STRING(Body, State)}. %% BUGBUG: digitMapBody not handled at all
+
+tr_opt_timer(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_timer(Timer, State) ->
+ tr_DIGIT(Timer, State, 0, 99).
+
+tr_ServiceChangeParm(
+ #'ServiceChangeParm'{serviceChangeMethod = Method,
+ serviceChangeAddress = Addr,
+ serviceChangeVersion = Version,
+ serviceChangeProfile = Profile,
+ serviceChangeReason = Reason,
+ serviceChangeDelay = Delay,
+ serviceChangeMgcId = MgcId,
+ timeStamp = Time,
+ serviceChangeInfo = Info,
+ serviceChangeIncompleteFlag = Incomplete},
+ State) ->
+ Method2 = tr_ServiceChangeMethod(Method, State),
+ Addr2 = tr_opt_ServiceChangeAddress(Addr, State),
+ Version2 = tr_opt_serviceChangeVersion(Version, State),
+ Profile2 = tr_opt_ServiceChangeProfile(Profile, State),
+ Reason2 = tr_serviceChangeReason(Reason, State),
+ Delay2 = tr_opt_serviceChangeDelay(Delay, State),
+ MgcId2 = tr_opt_serviceChangeMgcId(MgcId, State),
+ Time2 = tr_opt_TimeNotation(Time, State),
+ Info2 = tr_opt_AuditDescriptor(Info, State),
+ Incomplete2 = tr_opt_null(Incomplete, State),
+ #'ServiceChangeParm'{serviceChangeMethod = Method2,
+ serviceChangeAddress = Addr2,
+ serviceChangeVersion = Version2,
+ serviceChangeProfile = Profile2,
+ serviceChangeReason = Reason2,
+ serviceChangeDelay = Delay2,
+ serviceChangeMgcId = MgcId2,
+ timeStamp = Time2,
+ serviceChangeInfo = Info2,
+ serviceChangeIncompleteFlag = Incomplete2}.
+
+tr_ServiceChangeMethod(Method, _State) ->
+ case Method of
+ failover -> failover;
+ forced -> forced;
+ graceful -> graceful;
+ restart -> restart;
+ disconnected -> disconnected;
+ handOff -> handOff
+ end. %% BUGBUG: extension
+
+tr_opt_ServiceChangeAddress(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ServiceChangeAddress({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ portNumber -> tr_portNumber(Val, State);
+ ip4Address -> tr_IP4Address(Val, State);
+ ip6Address -> tr_IP6Address(Val, State);
+ domainName -> tr_DomainName(Val, State);
+ deviceName -> tr_PathName(Val, State);
+ mtpAddress -> tr_mtpAddress(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_opt_serviceChangeVersion(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeVersion(Version, State) ->
+ tr_version(Version, State).
+
+tr_opt_ServiceChangeProfile(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+%% Decode
+tr_opt_ServiceChangeProfile({'ServiceChangeProfile', ProfileName}, State) ->
+ case string:tokens(ProfileName, "/") of
+ [Name0, Version0] ->
+ Name = tr_STRING(Name0, State, 1, 64),
+ Version = tr_version(list_to_integer(Version0), State),
+ #'ServiceChangeProfile'{profileName = Name,
+ version = Version}
+ end;
+%% Encode
+tr_opt_ServiceChangeProfile(#'ServiceChangeProfile'{profileName = Name0,
+ version = Version0},
+ State) ->
+ Name = tr_STRING(Name0, State, 1, 64),
+ Version = tr_version(Version0, State),
+ ProfileName = lists:flatten(io_lib:format("~s/~w", [Name, Version])),
+ {'ServiceChangeProfile', ProfileName}.
+
+tr_serviceChangeReason([_] = Reason, State) ->
+ tr_Value(Reason, State).
+
+tr_opt_serviceChangeDelay(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeDelay(Delay, State) ->
+ tr_UINT32(Delay, State).
+
+tr_opt_serviceChangeMgcId(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeMgcId(MgcId, State) ->
+ tr_MId(MgcId, State).
+
+tr_opt_portNumber(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_portNumber(Port, State) ->
+ tr_portNumber(Port, State).
+
+tr_portNumber(Port, State) when is_integer(Port) andalso (Port >= 0) ->
+ tr_UINT16(Port, State).
+
+tr_ServiceChangeResParm(#'ServiceChangeResParm'{serviceChangeMgcId = MgcId,
+ serviceChangeAddress = Addr,
+ serviceChangeVersion = Version,
+ serviceChangeProfile = Profile,
+ timeStamp = Time},
+ State) ->
+ #'ServiceChangeResParm'{serviceChangeMgcId = tr_opt_serviceChangeMgcId(MgcId, State),
+ serviceChangeAddress = tr_opt_ServiceChangeAddress(Addr, State),
+ serviceChangeVersion = tr_opt_serviceChangeVersion(Version, State),
+ serviceChangeProfile = tr_opt_ServiceChangeProfile(Profile, State),
+ timeStamp = tr_opt_TimeNotation(Time, State)}.
+
+tr_PackagesDescriptor(Items, State) when is_list(Items) ->
+ [tr_PackagesItem(I, State) || I <- Items].
+
+tr_PackagesItem(#'PackagesItem'{packageName = Name,
+ packageVersion = Version},
+ State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ #'PackagesItem'{packageName = resolve(package, Name, State, Constraint),
+ packageVersion = tr_UINT16(Version, State)}.
+
+tr_opt_StatisticsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_StatisticsDescriptor(Parms, State) ->
+ tr_StatisticsDescriptor(Parms, State).
+
+tr_StatisticsDescriptor(Parms, State) when is_list(Parms) ->
+ [tr_StatisticsParameter(P, State) || P <- Parms].
+
+tr_StatisticsParameter(#'StatisticsParameter'{statName = Name,
+ statValue = Value},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'StatisticsParameter'{statName = resolve(statistics, Name, State, Constraint),
+ statValue = tr_opt_Value(Value, State)}.
+
+tr_opt_TimeNotation(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TimeNotation(#'TimeNotation'{date = Date,
+ time = Time},
+ State) ->
+ #'TimeNotation'{date = tr_STRING(Date, State, 8, 8), % "yyyymmdd"
+ time = tr_STRING(Time, State, 8, 8)}.% "hhmmssss"
+
+%% BUGBUG: Does not verify that string must contain at least one char
+%% BUGBUG: This violation of the is required in order to comply with
+%% BUGBUG: the dd/ce ds parameter that may possibly be empty.
+
+tr_opt_Value(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_Value(Value, State) ->
+ tr_Value(Value, State).
+
+tr_Value(Strings, _State) when is_list(Strings) ->
+ [[Char || Char <- String] || String <- Strings].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Encode an octet string, escape } by \ if necessary
+tr_OCTET_STRING(String, _State, Min, Max) when is_list(String) ->
+ verify_count(length(String), Min, Max),
+ String.
+
+tr_QUOTED_STRING(String, _State) when is_list(String) ->
+ verify_count(length(String), 1, infinity),
+ String.
+
+%% The internal format of hex digits is a list of octets
+%% Min and Max means #hexDigits
+%% Leading zeros are prepended in order to fulfill Min
+tr_HEXDIG(Octets, _State, Min, Max) when is_list(Octets) ->
+ verify_count(length(Octets), Min, Max),
+ Octets.
+
+tr_DIGIT(Val, State, Min, Max) ->
+ tr_integer(Val, State, Min, Max).
+
+tr_STRING(String, _State) when is_list(String) ->
+ String.
+
+tr_STRING(String, _State, Min, Max) when is_list(String) ->
+ verify_count(length(String), Min, Max),
+ String.
+
+tr_opt_UINT16(Val, State) ->
+ tr_opt_integer(Val, State, 0, 65535).
+
+tr_UINT16(Val, State) ->
+ tr_integer(Val, State, 0, 65535).
+
+tr_UINT32(Val, State) ->
+ tr_integer(Val, State, 0, 4294967295).
+
+tr_opt_integer(asn1_NOVALUE, _State, _Min, _Max) ->
+ asn1_NOVALUE;
+tr_opt_integer(Int, State, Min, Max) ->
+ tr_integer(Int, State, Min, Max).
+
+tr_integer(Int, _State, Min, Max) ->
+ verify_count(Int, Min, Max),
+ Int.
+
+%% Verify that Count is within the range of Min and Max
+verify_count(Count, Min, Max) ->
+ if
+ is_integer(Count) ->
+ if
+ is_integer(Min) andalso (Count >= Min) ->
+ if
+ is_integer(Max) andalso (Count =< Max) ->
+ Count;
+ Max =:= infinity ->
+ Count;
+ true ->
+ error({count_too_large, Count, Max})
+ end;
+ true ->
+ error({count_too_small, Count, Min})
+ end;
+ true ->
+ error({count_not_an_integer, Count})
+ end.
+
+
+%% -------------------------------------------------------------------
+
+error(Reason) ->
+ erlang:error(Reason).
+
+
diff --git a/lib/megaco/src/binary/megaco_binary_transformer_prev3c.erl b/lib/megaco/src/binary/megaco_binary_transformer_prev3c.erl
new file mode 100644
index 0000000000..8d2f9eea38
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_transformer_prev3c.erl
@@ -0,0 +1,1756 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Transform internal form of Megaco/H.248 messages
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_transformer_prev3c).
+
+-include_lib("megaco/include/megaco.hrl").
+%% -include_lib("megaco/include/megaco_message.hrl").
+-include_lib("megaco/include/megaco_message_prev3c.hrl").
+-include_lib("megaco/src/app/megaco_internal.hrl").
+
+-export([tr_message/3, tr_transaction/3]).
+
+-define(DEFAULT_NAME_RESOLVER, megaco_binary_name_resolver_prev3c).
+
+-record(state, {mode, % verify | encode | decode
+ resolver_module, %
+ resolver_options}).
+
+resolve(Type, Item, State, Constraint) ->
+ case State#state.mode of
+ verify ->
+ Item;
+ encode ->
+ ?d("resolve(encode) -> encode: ~p",[Item]),
+ Mod = State#state.resolver_module,
+ Opt = State#state.resolver_options,
+ EncodedItem = Mod:encode_name(Opt, Type, Item),
+ ?d("resolve -> verify contraint for ~p",[EncodedItem]),
+ verify_constraint(EncodedItem, Constraint);
+ decode ->
+ ?d("resolve(decode) -> verify contraint for ~p",[Item]),
+ DecodedItem = verify_constraint(Item, Constraint),
+ Mod = State#state.resolver_module,
+ Opt = State#state.resolver_options,
+ ?d("resolve(decode) -> decode: ~p",[DecodedItem]),
+ Mod:decode_name(Opt, Type, DecodedItem)
+ end.
+
+verify_constraint(Item, valid) ->
+ Item;
+verify_constraint(Item, Constraint) when is_function(Constraint) ->
+ Constraint(Item).
+
+tr_message(MegaMsg, Mode, Config) ->
+ case Config of
+ [native] ->
+ MegaMsg;
+ [verify] ->
+ State = #state{mode = verify},
+ tr_MegacoMessage(MegaMsg, State);
+ [] ->
+ State = #state{mode = Mode,
+ resolver_module = ?DEFAULT_NAME_RESOLVER,
+ resolver_options = [8, 8, 8]},
+ tr_MegacoMessage(MegaMsg, State);
+ [{binary_name_resolver, {Module, Options}}] when is_atom(Module) ->
+ State = #state{mode = Mode,
+ resolver_module = Module,
+ resolver_options = Options},
+ tr_MegacoMessage(MegaMsg, State)
+ end.
+
+tr_transaction(Trans, Mode, Config) ->
+ case Config of
+ [native] ->
+ Trans;
+ [verify] ->
+ State = #state{mode = verify},
+ tr_Transaction(Trans, State);
+ [] ->
+ State = #state{mode = Mode,
+ resolver_module = ?DEFAULT_NAME_RESOLVER,
+ resolver_options = [8, 8, 8]},
+ tr_Transaction(Trans, State);
+ [{binary_name_resolver, {Module, Options}}] when is_atom(Module) ->
+ State = #state{mode = Mode,
+ resolver_module = Module,
+ resolver_options = Options},
+ tr_Transaction(Trans, State)
+ end.
+
+tr_MegacoMessage(#'MegacoMessage'{authHeader = Auth,
+ mess = Mess},
+ State) ->
+ ?d("tr_MegacoMessage -> entry with"
+ "~n Auth: ~p"
+ "~n Mess: ~p"
+ "~n State: ~p", [Auth, Mess, State]),
+ #'MegacoMessage'{authHeader = tr_opt_AuthenticationHeader(Auth, State),
+ mess = tr_Message(Mess, State)}.
+
+tr_opt_AuthenticationHeader(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_AuthenticationHeader(#'AuthenticationHeader'{secParmIndex = SPI,
+ seqNum = SN,
+ ad = AuthData},
+ State) ->
+ #'AuthenticationHeader'{secParmIndex = tr_SecurityParmIndex(SPI, State),
+ seqNum = tr_SequenceNum(SN, State),
+ ad = tr_AuthData(AuthData, State)}.
+
+tr_SecurityParmIndex(SPI, State) ->
+ tr_HEXDIG(SPI, State, 4, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_SequenceNum(SN, State) ->
+ tr_HEXDIG(SN, State, 4, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_AuthData(AuthData, State) ->
+ tr_HEXDIG(AuthData, State, 12, 32). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_Message(#'Message'{version = Version,
+ mId = MID,
+ messageBody = Body},
+ State) ->
+ #'Message'{version = tr_version(Version, State),
+ mId = tr_MId(MID, State),
+ messageBody = tr_Message_messageBody(Body, State)}.
+
+tr_version(Version, State) ->
+ tr_DIGIT(Version, State, 0, 99).
+
+tr_Message_messageBody({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ messageError -> tr_ErrorDescriptor(Val, State);
+ transactions when is_list(Val) -> [tr_Transaction(T, State) || T <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_MId({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ ip4Address -> tr_IP4Address(Val, State);
+ ip6Address -> tr_IP6Address(Val, State);
+ domainName -> tr_DomainName(Val, State);
+ deviceName -> tr_PathName(Val, State);
+ mtpAddress -> tr_mtpAddress(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_mtpAddress(MtpAddr, State) ->
+ tr_OCTET_STRING(MtpAddr, State, 2, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_DomainName(#'DomainName'{name = Name,
+ portNumber = Port},
+ State) ->
+ Domain = #'DomainName'{name = tr_STRING(Name, State), % BUGBUG: Mismatch between ASN.1 and ABNF
+ portNumber = tr_opt_portNumber(Port, State)},
+ {domainName, Domain2} = resolve(mid, {domainName, Domain}, State, valid),
+ Domain2.
+
+tr_IP4Address(#'IP4Address'{address = [A1, A2, A3, A4],
+ portNumber = Port},
+ State) ->
+ #'IP4Address'{address = [tr_V4hex(A1, State),
+ tr_V4hex(A2, State),
+ tr_V4hex(A3, State),
+ tr_V4hex(A4, State)],
+ portNumber = tr_opt_portNumber(Port, State)}.
+
+tr_V4hex(Val, State) ->
+ tr_DIGIT(Val, State, 0, 255).
+
+tr_IP6Address(_Val, _State) ->
+ error(ipv6_not_supported). %% BUGBUG: nyi
+
+tr_PathName(Path, State) ->
+ %% BUGBUG: ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
+ %% BUGBUG: ["@" pathDomainName ]
+ Constraint = fun({deviceName, Item}) -> tr_STRING(Item, State, 1, 64) end,
+ resolve(mid, {deviceName, Path}, State, Constraint).
+
+tr_Transaction({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ transactionRequest -> tr_TransactionRequest(Val, State);
+ transactionPending -> tr_TransactionPending(Val, State);
+ transactionReply -> tr_TransactionReply(Val, State);
+ transactionResponseAck -> [tr_TransactionAck(T, State) || T <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_TransactionAck(#'TransactionAck'{firstAck = First,
+ lastAck = Last},
+ State) ->
+ #'TransactionAck'{firstAck = tr_TransactionId(First, State),
+ lastAck = tr_opt_TransactionId(Last, State)}.
+
+tr_opt_TransactionId(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TransactionId(Id, State) ->
+ tr_TransactionId(Id, State).
+
+tr_TransactionId(Id, State) ->
+ tr_UINT32(Id, State).
+
+tr_TransactionRequest(#'TransactionRequest'{transactionId = Id,
+ actions = Actions},
+ State) when is_list(Actions) ->
+
+ #'TransactionRequest'{transactionId = tr_TransactionId(Id, State),
+ actions = [tr_ActionRequest(ActReq, State) || ActReq <- Actions]}.
+
+tr_TransactionPending(#'TransactionPending'{transactionId = Id},
+ State) ->
+ #'TransactionPending'{transactionId = tr_TransactionId(Id, State)}.
+
+tr_TransactionReply(#'TransactionReply'{transactionId = Id,
+ immAckRequired = ImmAck,
+ transactionResult = TransRes,
+ %% These fields are actually not
+ %% supported in this implementation,
+ %% but because the messanger module
+ %% cannot see any diff between the
+ %% various v3 implementations...
+ segmentNumber = asn1_NOVALUE,
+ segmentationComplete = asn1_NOVALUE},
+ State) ->
+ #'TransactionReply'{transactionId = tr_TransactionId(Id, State),
+ immAckRequired = tr_opt_null(ImmAck, State),
+ transactionResult = tr_TransactionReply_transactionResult(TransRes, State),
+ segmentNumber = asn1_NOVALUE,
+ segmentationComplete = asn1_NOVALUE};
+tr_TransactionReply(TR, _State) ->
+ error({unsupported_TransactionReply, TR}).
+
+tr_opt_null(asn1_NOVALUE, _State) -> asn1_NOVALUE;
+tr_opt_null('NULL', _State) -> 'NULL'.
+
+tr_TransactionReply_transactionResult({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ transactionError ->
+ tr_ErrorDescriptor(Val, State);
+ actionReplies when is_list(Val) andalso (Val =/= []) ->
+ [tr_ActionReply(ActRep, State) || ActRep <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_opt_ErrorDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ErrorDescriptor(ErrDesc, State) ->
+ tr_ErrorDescriptor(ErrDesc, State).
+
+tr_ErrorDescriptor(#'ErrorDescriptor'{errorCode = Code,
+ errorText = Text},
+ State) ->
+ #'ErrorDescriptor'{errorCode = tr_ErrorCode(Code, State),
+ errorText = tr_opt_ErrorText(Text, State)}.
+
+tr_ErrorCode(Code, State) ->
+ tr_DIGIT(Code, State, 0, 999).
+
+tr_opt_ErrorText(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ErrorText(Text, State) ->
+ tr_QUOTED_STRING(Text, State).
+
+tr_ContextID(CtxId, State) ->
+ case CtxId of
+ ?megaco_all_context_id -> ?megaco_all_context_id;
+ ?megaco_null_context_id -> ?megaco_null_context_id;
+ ?megaco_choose_context_id -> ?megaco_choose_context_id;
+ Int when is_integer(Int) -> tr_UINT32(Int, State)
+ end.
+
+tr_ActionRequest(#'ActionRequest'{contextId = CtxId,
+ contextRequest = CtxReq,
+ contextAttrAuditReq = CtxAuditReq,
+ commandRequests = CmdReqList},
+ State) ->
+ #'ActionRequest'{contextId = tr_ContextID(CtxId, State),
+ contextRequest = tr_opt_ContextRequest(CtxReq, State),
+ contextAttrAuditReq = tr_opt_ContextAttrAuditRequest(CtxAuditReq, State),
+ commandRequests = [tr_CommandRequest(CmdReq, State) || CmdReq <- CmdReqList]}.
+
+tr_ActionReply(#'ActionReply'{contextId = CtxId,
+ errorDescriptor = ErrDesc,
+ contextReply = CtxRep,
+ commandReply = CmdRepList},
+ State) ->
+ CmdRepList2 = [tr_CommandReply(CmdRep, State) || CmdRep <- CmdRepList],
+ #'ActionReply'{contextId = tr_ContextID(CtxId, State),
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State),
+ contextReply = tr_opt_ContextRequest(CtxRep, State),
+ commandReply = CmdRepList2}.
+
+tr_opt_ContextRequest(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ContextRequest(CR, State) ->
+ tr_ContextRequest(CR, State).
+
+tr_ContextRequest(#'ContextRequest'{priority = Prio,
+ emergency = Em,
+ topologyReq = TopReqList,
+ iepscallind = Ind,
+ contextProp = CtxProps,
+ contextList = CtxList},
+ State) ->
+ Prio2 =
+ case Prio of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_integer(Prio, State, 0, 15)
+ end,
+ Em2 =
+ case Em of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ TopReqList2 =
+ case TopReqList of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_TopologyRequest(TopReq, State) ||
+ TopReq <- TopReqList]
+ end,
+ Ind2 =
+ case Ind of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ CtxProps2 =
+ case CtxProps of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_PropertyParm(Prop, State) || Prop <- CtxProps]
+ end,
+ CtxList2 =
+ case CtxList of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_ContextID(Id, State) || Id <- CtxList]
+ end,
+ #'ContextRequest'{priority = Prio2,
+ emergency = Em2,
+ topologyReq = TopReqList2,
+ iepscallind = Ind2,
+ contextProp = CtxProps2,
+ contextList = CtxList2}.
+
+tr_opt_ContextAttrAuditRequest(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ContextAttrAuditRequest(CAAR, State) ->
+ tr_ContextAttrAuditRequest(CAAR, State).
+
+tr_ContextAttrAuditRequest(#'ContextAttrAuditRequest'{topology = Top,
+ emergency = Em,
+ priority = Prio,
+ iepscallind = Ind,
+ contextPropAud = Props,
+ selectpriority = SPrio,
+ selectemergency = SEm,
+ selectiepscallind = SInd,
+ selectLogic = SLog},
+ State) ->
+ Top2 = tr_opt_null(Top, State),
+ Em2 = tr_opt_null(Em, State),
+ Prio2 = tr_opt_null(Prio, State),
+ Ind2 = tr_opt_null(Ind, State),
+ Props2 =
+ case Props of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ [tr_indAudPropertyParm(Prop, State) || Prop <- Props]
+ end,
+ SPrio2 =
+ case SPrio of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_integer(SPrio, State, 0, 15)
+ end,
+ SEm2 =
+ case SEm of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ SInd2 =
+ case SInd of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ SLog2 =
+ case SLog of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_SelectLogic(SLog, State)
+ end,
+ #'ContextAttrAuditRequest'{topology = Top2,
+ emergency = Em2,
+ priority = Prio2,
+ iepscallind = Ind2,
+ contextPropAud = Props2,
+ selectpriority = SPrio2,
+ selectemergency = SEm2,
+ selectiepscallind = SInd2,
+ selectLogic = SLog2}.
+
+tr_SelectLogic({andAUDITSelect, 'NULL'} = Val, _State) ->
+ Val;
+tr_SelectLogic({orAUDITSelect, 'NULL'} = Val, _State) ->
+ Val.
+
+tr_CommandRequest(#'CommandRequest'{command = Cmd,
+ optional = Opt,
+ wildcardReturn = Wild},
+ State) ->
+ #'CommandRequest'{optional = tr_opt_null(Opt, State),
+ wildcardReturn = tr_opt_null(Wild, State),
+ command = tr_Command(Cmd, State)}.
+
+tr_Command({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ addReq -> tr_AmmRequest(Val, State);
+ moveReq -> tr_AmmRequest(Val, State);
+ modReq -> tr_AmmRequest(Val, State);
+ subtractReq -> tr_SubtractRequest(Val, State);
+ auditCapRequest -> tr_AuditRequest(Val, State);
+ auditValueRequest -> tr_AuditRequest(Val, State);
+ notifyReq -> tr_NotifyRequest(Val, State);
+ serviceChangeReq -> tr_ServiceChangeRequest(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_CommandReply({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ addReply -> tr_AmmsReply(Val, State);
+ moveReply -> tr_AmmsReply(Val, State);
+ modReply -> tr_AmmsReply(Val, State);
+ subtractReply -> tr_AmmsReply(Val, State);
+ auditCapReply -> tr_AuditReply(Val, State);
+ auditValueReply -> tr_AuditReply(Val, State);
+ notifyReply -> tr_NotifyReply(Val, State);
+ serviceChangeReply -> tr_ServiceChangeReply(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_TopologyRequest(#'TopologyRequest'{terminationFrom = From,
+ terminationTo = To,
+ topologyDirection = Dir,
+ streamID = SID,
+ topologyDirectionExtension = TDE},
+ State) ->
+ Dir2 =
+ case Dir of
+ bothway -> bothway;
+ isolate -> isolate;
+ oneway -> oneway
+ end,
+ TDE2 =
+ case TDE of
+ onewayexternal -> onewayexternal;
+ onewayboth -> onewayboth;
+ asn1_NOVALUE -> asn1_NOVALUE
+ end,
+ #'TopologyRequest'{terminationFrom = tr_TerminationID(From, State),
+ terminationTo = tr_TerminationID(To, State),
+ topologyDirection = Dir2,
+ streamID = tr_opt_StreamID(SID, State),
+ topologyDirectionExtension = TDE2}.
+
+tr_AmmRequest(#'AmmRequest'{terminationID = IdList,
+ descriptors = DescList},
+ State) ->
+ #'AmmRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ descriptors = tr_ammDescriptors(DescList, [], State)}.
+
+tr_ammDescriptors([], Acc, _State) ->
+ lists:reverse(Acc);
+tr_ammDescriptors([Desc|Descs], Acc, State) ->
+ case tr_ammDescriptor(Desc, State) of
+ {_, deprecated} when State#state.mode =:= encode ->
+ error({deprecated, Desc});
+ {_, deprecated} when State#state.mode =:= decode ->
+ %% SKIP
+ tr_ammDescriptors(Descs, Acc, State);
+ {_, deprecated} ->
+ %% SKIP
+ tr_ammDescriptors(Descs, Acc, State);
+ NewDesc ->
+ tr_ammDescriptors(Descs, [NewDesc|Acc], State)
+ end.
+
+tr_ammDescriptor({Tag, Desc}, State) ->
+ Desc2 =
+ case Tag of
+ mediaDescriptor -> tr_MediaDescriptor(Desc, State);
+ modemDescriptor -> tr_ModemDescriptor(Desc, State);
+ muxDescriptor -> tr_MuxDescriptor(Desc, State);
+ eventsDescriptor -> tr_EventsDescriptor(Desc, State);
+ eventBufferDescriptor -> tr_EventBufferDescriptor(Desc, State);
+ signalsDescriptor -> tr_SignalsDescriptor(Desc, State);
+ digitMapDescriptor -> tr_DigitMapDescriptor(Desc, State);
+ auditDescriptor -> tr_AuditDescriptor(Desc, State);
+ statisticsDescriptor -> tr_StatisticsDescriptor(Desc, State)
+ end,
+ {Tag, Desc2}.
+
+tr_AmmsReply(#'AmmsReply'{terminationID = IdList,
+ terminationAudit = TermAudit},
+ State) ->
+ TermAudit2 =
+ case TermAudit of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_TerminationAudit(TermAudit, State)
+ end,
+ #'AmmsReply'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ terminationAudit = TermAudit2}.
+
+tr_SubtractRequest(#'SubtractRequest'{terminationID = IdList,
+ auditDescriptor = Desc},
+ State) ->
+ #'SubtractRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ auditDescriptor = tr_opt_AuditDescriptor(Desc, State)}.
+
+tr_AuditRequest(#'AuditRequest'{terminationID = Id,
+ auditDescriptor = Desc,
+ terminationIDList = TIDList},
+ State) ->
+ TIDList2 =
+ case TIDList of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_TerminationID(TID, State) || TID <- TIDList]
+ end,
+ #'AuditRequest'{terminationID = tr_TerminationID(Id, State),
+ auditDescriptor = tr_AuditDescriptor(Desc, State),
+ terminationIDList = TIDList2}.
+
+%% auditReply = (AuditValueToken / AuditCapToken )
+%% ( contextTerminationAudit / auditOther)
+%% auditOther = EQUAL TerminationID LBRKT
+%% terminationAudit RBRKT
+%% terminationAudit = auditReturnParameter *(COMMA auditReturnParameter)
+%%
+%% contextTerminationAudit = EQUAL CtxToken ( terminationIDList /
+%% LBRKT errorDescriptor RBRKT )
+
+tr_AuditReply({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ contextAuditResult ->
+ [tr_TerminationID(Id, State) || Id <- Val];
+ error ->
+ tr_ErrorDescriptor(Val, State);
+ auditResult ->
+ tr_AuditResult(Val, State);
+ auditResultTermList ->
+ tr_TermListAuditResult(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_AuditResult(#'AuditResult'{terminationID = Id,
+ terminationAuditResult = AuditRes},
+ State) ->
+ #'AuditResult'{terminationID = tr_TerminationID(Id, State),
+ terminationAuditResult = tr_TerminationAudit(AuditRes, State)}.
+
+tr_TermListAuditResult(
+ #'TermListAuditResult'{terminationIDList = TIDList,
+ terminationAuditResult = TAR},
+ State) ->
+ TIDList2 = [tr_TerminationID(TID, State) || TID <- TIDList],
+ TAR2 = tr_TerminationAudit(TAR, State),
+ #'TermListAuditResult'{terminationIDList = TIDList2,
+ terminationAuditResult = TAR2}.
+
+
+tr_opt_AuditDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_AuditDescriptor(Desc, State) ->
+ tr_AuditDescriptor(Desc, State).
+
+%% BUGBUG BUGBUG BUGBUG
+%% With this construction it is possible to have both auditToken
+%% and auditPropertyToken, but it is actually valid?
+tr_AuditDescriptor(#'AuditDescriptor'{auditToken = Tokens,
+ auditPropertyToken = APTs},
+ State) ->
+ Tokens2 =
+ case Tokens of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_auditItem(Token, State) || Token <- Tokens]
+ end,
+ %% v2
+ APTs2 =
+ case APTs of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ [tr_indAuditParameter(APT, State) || APT <- APTs]
+ end,
+ #'AuditDescriptor'{auditToken = Tokens2,
+ auditPropertyToken = APTs2}.
+
+tr_auditItem(Token, _State) ->
+ case Token of
+ muxToken -> muxToken;
+ modemToken -> modemToken;
+ mediaToken -> mediaToken;
+ eventsToken -> eventsToken;
+ signalsToken -> signalsToken;
+ digitMapToken -> digitMapToken;
+ statsToken -> statsToken;
+ observedEventsToken -> observedEventsToken;
+ packagesToken -> packagesToken;
+ eventBufferToken -> eventBufferToken
+ end.
+
+%% --- v2 begin ---
+
+tr_indAuditParameter({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ indAudMediaDescriptor ->
+ tr_indAudMediaDescriptor(Val, State);
+ indAudEventsDescriptor ->
+ tr_indAudEventsDescriptor(Val, State);
+ indAudSignalsDescriptor ->
+ tr_indAudSignalsDescriptor(Val, State);
+ indAudDigitMapDescriptor ->
+ tr_indAudDigitMapDescriptor(Val, State);
+ indAudEventBufferDescriptor ->
+ tr_indAudEventBufferDescriptor(Val, State);
+ indAudStatisticsDescriptor ->
+ tr_indAudStatisticsDescriptor(Val, State);
+ indAudPackagesDescriptor ->
+ tr_indAudPackagesDescriptor(Val, State)
+ end,
+ {Tag, Val2}.
+
+
+%% -
+
+tr_indAudMediaDescriptor(#'IndAudMediaDescriptor'{termStateDescr = TSD,
+ streams = S},
+ State) ->
+ TSD2 =
+ case TSD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudTerminationStateDescriptor(TSD, State)
+ end,
+ S2 =
+ case S of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ {oneStream, OS} ->
+ {oneStream, tr_indAudStreamParms(OS, State)};
+ {multiStream, MS} ->
+ MS2 = [tr_indAudStreamDescriptor(MS1, State) || MS1 <- MS],
+ {multiStream, MS2}
+ end,
+ #'IndAudMediaDescriptor'{termStateDescr = TSD2,
+ streams = S2}.
+
+tr_indAudTerminationStateDescriptor(Val, State)
+ when is_record(Val, 'IndAudTerminationStateDescriptor') ->
+ #'IndAudTerminationStateDescriptor'{propertyParms = Parms,
+ eventBufferControl = EBC,
+ serviceState = SS,
+ serviceStateSel = SSS} = Val,
+ Parms2 = [tr_indAudPropertyParm(Parm, State) || Parm <- Parms],
+ EBC2 = tr_opt_null(EBC, State),
+ SS2 = tr_opt_null(SS, State),
+ SSS2 = tr_opt_ServiceState(SSS, State),
+ #'IndAudTerminationStateDescriptor'{propertyParms = Parms2,
+ eventBufferControl = EBC2,
+ serviceState = SS2,
+ serviceStateSel = SSS2}.
+
+
+tr_indAudStreamParms(#'IndAudStreamParms'{localControlDescriptor = LCD,
+ localDescriptor = LD,
+ remoteDescriptor = RD,
+ statisticsDescriptor = SD},
+ State) ->
+ LCD2 =
+ case LCD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalControlDescriptor(LCD, State)
+ end,
+ LD2 =
+ case LD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalRemoteDescriptor(LD, State)
+ end,
+ RD2 =
+ case RD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalRemoteDescriptor(RD, State)
+ end,
+ SD2 =
+ case SD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudStatisticsDescriptor(SD, State)
+ end,
+ #'IndAudStreamParms'{localControlDescriptor = LCD2,
+ localDescriptor = LD2,
+ remoteDescriptor = RD2,
+ statisticsDescriptor = SD2}.
+
+tr_indAudLocalControlDescriptor(Val, State)
+ when is_record(Val, 'IndAudLocalControlDescriptor') ->
+ #'IndAudLocalControlDescriptor'{streamMode = M,
+ reserveValue = V,
+ reserveGroup = G,
+ propertyParms = P,
+ streamModeSel = SMS} = Val,
+ M2 = tr_opt_null(M, State),
+ V2 = tr_opt_null(V, State),
+ G2 = tr_opt_null(G, State),
+ P2 = tr_indAudLocalControlDescriptor_propertyParms(P, State),
+ SMS2 = tr_opt_StreamMode(SMS, State),
+ #'IndAudLocalControlDescriptor'{streamMode = M2,
+ reserveValue = V2,
+ reserveGroup = G2,
+ propertyParms = P2,
+ streamModeSel = SMS2}.
+
+tr_indAudLocalControlDescriptor_propertyParms(Parms, State)
+ when is_list(Parms) andalso (length(Parms) > 0) ->
+ [tr_indAudPropertyParm(Parm, State) || Parm <- Parms];
+tr_indAudLocalControlDescriptor_propertyParms(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE.
+
+tr_indAudLocalRemoteDescriptor(#'IndAudLocalRemoteDescriptor'{propGroupID = ID,
+ propGrps = Grps},
+ State) ->
+ #'IndAudLocalRemoteDescriptor'{propGroupID = tr_opt_UINT16(ID, State),
+ propGrps = tr_indAudPropertyGroup(Grps,
+ State)}.
+
+tr_indAudPropertyGroup(Grps, State) when is_list(Grps) ->
+ [tr_indAudPropertyParm(Parm, State) || Parm <- Grps].
+
+tr_indAudPropertyParm(#'IndAudPropertyParm'{name = Name0,
+ propertyParms = Prop0}, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(property, Name0, State, Constraint),
+ Prop =
+ case Prop0 of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_PropertyParm(Prop0, State)
+ end,
+ #'IndAudPropertyParm'{name = Name,
+ propertyParms = Prop}.
+
+
+tr_indAudStreamDescriptor(#'IndAudStreamDescriptor'{streamID = ID,
+ streamParms = Parms},
+ State) ->
+ #'IndAudStreamDescriptor'{streamID = tr_StreamID(ID, State),
+ streamParms = tr_indAudStreamParms(Parms,
+ State)}.
+
+
+%% -
+
+tr_indAudEventsDescriptor(#'IndAudEventsDescriptor'{requestID = RID,
+ pkgdName = Name0,
+ streamID = SID},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(event, Name0, State, Constraint),
+ #'IndAudEventsDescriptor'{requestID = tr_opt_RequestID(RID, State),
+ pkgdName = Name,
+ streamID = tr_opt_StreamID(SID, State)}.
+
+
+%% -
+
+tr_indAudSignalsDescriptor({Tag, Val}, State) ->
+ case Tag of
+ signal ->
+ {signal, tr_indAudSignal(Val, State)};
+ seqSigList ->
+ {seqSigList, tr_indAudSeqSigList(Val, State)}
+ end.
+
+tr_opt_indAudSignal(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_indAudSignal(Val, State) ->
+ tr_indAudSignal(Val, State).
+
+tr_indAudSignal(#'IndAudSignal'{signalName = Name0,
+ streamID = SID,
+ signalRequestID = RID}, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(signal, Name0, State, Constraint),
+ #'IndAudSignal'{signalName = Name,
+ streamID = tr_opt_StreamID(SID, State),
+ signalRequestID = tr_opt_RequestID(RID, State)}.
+
+tr_indAudSeqSigList(#'IndAudSeqSigList'{id = ID,
+ signalList = SigList}, State) ->
+ #'IndAudSeqSigList'{id = tr_integer(ID, State, 0, 65535),
+ signalList = tr_opt_indAudSignal(SigList, State)}.
+
+%% -
+
+tr_indAudDigitMapDescriptor(#'IndAudDigitMapDescriptor'{digitMapName = Name},
+ State) ->
+ #'IndAudDigitMapDescriptor'{digitMapName =
+ tr_opt_DigitMapName(Name, State)}.
+
+
+%% -
+
+tr_indAudEventBufferDescriptor(#'IndAudEventBufferDescriptor'{eventName = N,
+ streamID = SID},
+ State) ->
+ ?d("tr_indAudEventBufferDescriptor -> entry with"
+ "~n N: ~p"
+ "~n SID: ~p", [N, SID]),
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(event, N, State, Constraint),
+ ?d("tr_indAudEventBufferDescriptor -> entry with"
+ "~n Name: ~p", [Name]),
+ #'IndAudEventBufferDescriptor'{eventName = Name,
+ streamID = tr_opt_StreamID(SID, State)}.
+
+%% -
+
+tr_indAudStatisticsDescriptor(#'IndAudStatisticsDescriptor'{statName = N},
+ State) ->
+ ?d("tr_indAudEventBufferDescriptor -> entry with"
+ "~n N: ~p", [N]),
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(statistics, N, State, Constraint),
+ #'IndAudStatisticsDescriptor'{statName = Name}.
+
+
+%% -
+
+tr_indAudPackagesDescriptor(#'IndAudPackagesDescriptor'{packageName = N,
+ packageVersion = V},
+ State) ->
+ ?d("tr_indAudPackagesDescriptor -> entry with"
+ "~n N: ~p"
+ "~n V: ~p", [N, V]),
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ Name = resolve(package, N, State, Constraint),
+ ?d("tr_indAudPackagesDescriptor -> entry with"
+ "~n Name: ~p", [Name]),
+ #'IndAudPackagesDescriptor'{packageName = Name,
+ packageVersion = tr_integer(V, State, 0, 99)}.
+
+%% -- v2 end --
+
+
+tr_TerminationAudit(ParmList, State) when is_list(ParmList) ->
+ do_tr_TerminationAudit(ParmList, [], State).
+
+do_tr_TerminationAudit([], Acc, _State) ->
+ lists:reverse(Acc);
+do_tr_TerminationAudit([Parm|ParmList], Acc, State) ->
+ case tr_AuditReturnParameter(Parm, State) of
+ {_, deprecated} when State#state.mode =:= encode ->
+ error({deprecated, Parm});
+ {_, deprecated} when State#state.mode =:= decode ->
+ %% SKIP
+ do_tr_TerminationAudit(ParmList, Acc, State);
+ {_, deprecated} ->
+ %% SKIP
+ do_tr_TerminationAudit(ParmList, Acc, State);
+ NewParm ->
+ do_tr_TerminationAudit(ParmList, [NewParm|Acc], State)
+ end.
+
+tr_AuditReturnParameter({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ errorDescriptor ->
+ tr_ErrorDescriptor(Val, State);
+ mediaDescriptor ->
+ tr_MediaDescriptor(Val, State);
+ modemDescriptor ->
+ tr_ModemDescriptor(Val, State);
+ muxDescriptor ->
+ tr_MuxDescriptor(Val, State);
+ eventsDescriptor ->
+ tr_EventsDescriptor(Val, State);
+ eventBufferDescriptor ->
+ tr_EventBufferDescriptor(Val, State);
+ signalsDescriptor ->
+ tr_SignalsDescriptor(Val, State);
+ digitMapDescriptor ->
+ tr_DigitMapDescriptor(Val, State);
+ observedEventsDescriptor ->
+ tr_ObservedEventsDescriptor(Val, State);
+ statisticsDescriptor ->
+ tr_StatisticsDescriptor(Val, State);
+ packagesDescriptor ->
+ tr_PackagesDescriptor(Val, State);
+ emptyDescriptors ->
+ tr_EmptyDescriptors(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_EmptyDescriptors(#'AuditDescriptor'{auditToken = Tokens},
+ State) ->
+ Tokens2 =
+ case Tokens of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_auditItem(Token, State) || Token <- Tokens]
+ end,
+ #'AuditDescriptor'{auditToken = Tokens2}.
+
+tr_NotifyRequest(#'NotifyRequest'{terminationID = IdList,
+ observedEventsDescriptor = ObsDesc,
+ errorDescriptor = ErrDesc},
+ State) ->
+ %% BUGBUG: Mismatch between ASN.1 and ABNF
+ %% BUGBUG: The following ought to be a 'choice'
+ #'NotifyRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ observedEventsDescriptor = tr_ObservedEventsDescriptor(ObsDesc, State),
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State)}.
+
+tr_NotifyReply(#'NotifyReply'{terminationID = IdList,
+ errorDescriptor = ErrDesc},
+ State) ->
+ #'NotifyReply'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State)}.
+
+tr_ObservedEventsDescriptor(#'ObservedEventsDescriptor'{requestId = Id,
+ observedEventLst = Events},
+ State) when is_list(Events) ->
+ #'ObservedEventsDescriptor'{requestId = tr_RequestID(Id, State),
+ observedEventLst = [tr_ObservedEvent(E, State) || E <- Events]}.
+
+%% ;time per event, because it might be buffered
+%% observedEvent = [ TimeStamp LWSP COLON] LWSP
+%% pkgdName [ LBRKT observedEventParameter
+%% *(COMMA observedEventParameter) RBRKT ]
+%%
+%% ;at-most-once eventStream, every eventParameterName at most once
+%% observedEventParameter = eventStream / eventOther
+
+tr_ObservedEvent(#'ObservedEvent'{eventName = Name,
+ streamID = Id,
+ eventParList = Parms,
+ timeNotation = Time},
+ State) ->
+ #'ObservedEvent'{eventName = tr_EventName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ eventParList = [tr_EventParameter(P, Name, State) || P <- Parms],
+ timeNotation = tr_opt_TimeNotation(Time, State)}.
+
+tr_EventName(Name, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ resolve(event, Name, State, Constraint).
+
+tr_EventParameter(#'EventParameter'{eventParameterName = ParName,
+ value = Value,
+ extraInfo = Extra},
+ EventName,
+ State) ->
+ %% BUGBUG: event parameter name
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ N = resolve({event_parameter, EventName}, ParName, State, Constraint),
+ #'EventParameter'{eventParameterName = N,
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_ServiceChangeRequest(#'ServiceChangeRequest'{terminationID = IdList,
+ serviceChangeParms = Parms},
+ State) ->
+ #'ServiceChangeRequest'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ serviceChangeParms = tr_ServiceChangeParm(Parms, State)}.
+
+%% serviceChangeReply = ServiceChangeToken EQUAL TerminationID
+%% [LBRKT (errorDescriptor /
+%% serviceChangeReplyDescriptor) RBRKT]
+%% serviceChangeReplyDescriptor = ServicesToken LBRKT
+%% servChgReplyParm *(COMMA servChgReplyParm) RBRKT
+%%
+%% ;at-most-once. Version is REQUIRED on first ServiceChange response
+%% servChgReplyParm = (serviceChangeAddress / serviceChangeMgcId /
+%% serviceChangeProfile / serviceChangeVersion )
+tr_ServiceChangeReply(#'ServiceChangeReply'{terminationID = IdList,
+ serviceChangeResult = Res},
+ State) ->
+ #'ServiceChangeReply'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ serviceChangeResult = tr_ServiceChangeResult(Res, State)}.
+
+tr_ServiceChangeResult({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ errorDescriptor -> tr_ErrorDescriptor(Val, State);
+ serviceChangeResParms -> tr_ServiceChangeResParm(Val, State)
+ end,
+ {Tag, Val2}.
+
+%% TerminationID = "ROOT" / pathNAME / "$" / "*"
+%% ; Total length of pathNAME must not exceed 64 chars.
+%% pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
+%% ["@" pathDomainName ]
+
+tr_TerminationID(TermId, State) when State#state.mode =/= verify ->
+ resolve(term_id, TermId, State, valid);
+tr_TerminationID(#'TerminationID'{wildcard = Wild,
+ id = Id},
+ _State) ->
+ #'TerminationID'{wildcard = Wild,
+ id = Id};
+tr_TerminationID(#megaco_term_id{contains_wildcards = IsWild,
+ id = Id},
+ State) ->
+ #megaco_term_id{contains_wildcards = tr_bool(IsWild, State),
+ id = [tr_term_id_component(Sub, State) || Sub <- Id]}.
+
+tr_opt_bool(asn1_NOVALUE, _State) -> asn1_NOVALUE;
+tr_opt_bool(Bool, State) -> tr_bool(Bool, State).
+
+tr_bool(true, _State) -> true;
+tr_bool(false, _State) -> false.
+
+tr_term_id_component(Sub, _State) ->
+ case Sub of
+ all -> all;
+ choose -> choose;
+ Char when is_integer(Char) -> Char
+ end.
+
+%% mediaDescriptor = MediaToken LBRKT mediaParm *(COMMA mediaParm) RBRKT
+%% ; at-most-once per item
+%% ; and either streamParm or streamDescriptor but not both
+%% mediaParm = (streamParm / streamDescriptor /
+%% terminationStateDescriptor)
+%% ; at-most-once
+%% streamParm = ( localDescriptor / remoteDescriptor /
+%% localControlDescriptor )
+%% streamDescriptor = StreamToken EQUAL StreamID LBRKT streamParm
+%% *(COMMA streamParm) RBRKT
+tr_MediaDescriptor(#'MediaDescriptor'{termStateDescr = TermState,
+ streams = Streams},
+ State) ->
+ #'MediaDescriptor'{termStateDescr = tr_opt_TerminationStateDescriptor(TermState, State),
+ streams = tr_opt_streams(Streams, State)}.
+
+tr_opt_streams(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_streams({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ oneStream -> tr_StreamParms(Val, State);
+ multiStream -> [tr_StreamDescriptor(SD, State) || SD <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_StreamParms(#'StreamParms'{localControlDescriptor = LCD,
+ localDescriptor = LD,
+ remoteDescriptor = RD,
+ statisticsDescriptor = SD},
+ State) ->
+ LCD2 = tr_opt_LocalControlDescriptor(LCD, State),
+ LD2 = tr_opt_LocalRemoteDescriptor(LD, State),
+ RD2 = tr_opt_LocalRemoteDescriptor(RD, State),
+ SD2 = tr_opt_StatisticsDescriptor(SD, State),
+ #'StreamParms'{localControlDescriptor = LCD2,
+ localDescriptor = LD2,
+ remoteDescriptor = RD2,
+ statisticsDescriptor = SD2}.
+
+tr_StreamDescriptor(#'StreamDescriptor'{streamID = Id,
+ streamParms = Parms},
+ State) ->
+ #'StreamDescriptor'{streamID = tr_StreamID(Id, State),
+ streamParms = tr_StreamParms(Parms, State)}.
+
+%% localControlDescriptor = LocalControlToken LBRKT localParm
+%% *(COMMA localParm) RBRKT
+%%
+%% ; at-most-once per item
+%% localParm = ( streamMode / propertyParm /
+%% reservedValueMode / reservedGroupMode )
+%% reservedValueMode = ReservedValueToken EQUAL ( "ON" / "OFF" )
+%% reservedGroupMode = ReservedGroupToken EQUAL ( "ON" / "OFF" )
+%%
+%% reservedMode = ReservedToken EQUAL ( "ON" / "OFF" )
+%%
+%% streamMode = ModeToken EQUAL streamModes
+tr_opt_LocalControlDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_LocalControlDescriptor(#'LocalControlDescriptor'{streamMode = Mode,
+ reserveGroup = Group,
+ reserveValue = Value,
+ propertyParms = Props},
+ State) ->
+ #'LocalControlDescriptor'{streamMode = tr_opt_StreamMode(Mode, State),
+ reserveGroup = tr_opt_bool(Group, State),
+ reserveValue = tr_opt_bool(Value, State),
+ propertyParms = [tr_PropertyParm(P, State) || P <- Props]}.
+
+tr_opt_StreamMode(Mode, _State) ->
+ case Mode of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ sendOnly -> sendOnly;
+ recvOnly -> recvOnly;
+ sendRecv -> sendRecv;
+ inactive -> inactive;
+ loopBack -> loopBack
+ end.
+
+tr_Name(Name, State) ->
+ %% BUGBUG: transform
+ %% BUGBUG: NAME = ALPHA *63(ALPHA / DIGIT / "_" )
+ tr_STRING(Name, State, 2, 2).
+
+tr_PkgdName(Name, State) ->
+ %% BUGBUG: transform
+ %% BUGBUG: pkgdName = (NAME / "*") SLASH (ItemID / "*" )
+ tr_OCTET_STRING(Name, State, 4, 4).
+
+%% When text encoding the protocol, the descriptors consist of session
+%% descriptions as defined in SDP (RFC2327), except that the "s=", "t="
+%% and "o=" lines are optional. When multiple session descriptions are
+%% provided in one descriptor, the "v=" lines are required as delimiters;
+%% otherwise they are optional. Implementations shall accept session
+%% descriptions that are fully conformant to RFC2327. When binary
+%% encoding the protocol the descriptor consists of groups of properties
+%% (tag-value pairs) as specified in Annex C. Each such group may
+%% contain the parameters of a session description.
+tr_opt_LocalRemoteDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_LocalRemoteDescriptor(#'LocalRemoteDescriptor'{propGrps = Groups},
+ State) ->
+ #'LocalRemoteDescriptor'{propGrps = [tr_PropertyGroup(G, State) || G <- Groups]}.
+
+tr_PropertyGroup(Props, State) ->
+ [tr_PropertyGroupParm(P, State) || P <- Props].
+
+tr_PropertyGroupParm(#'PropertyParm'{name = Name,
+ value = Value},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'PropertyParm'{name = resolve(property, Name, State, Constraint),
+ value = tr_OCTET_STRING(Value, State, 0, infinity)}.
+
+tr_PropertyParm(#'PropertyParm'{name = Name,
+ value = Value,
+ extraInfo = Extra},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'PropertyParm'{name = resolve(property, Name, State, Constraint),
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_opt_extraInfo(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_extraInfo({relation, Rel}, _State) ->
+ Rel2 =
+ case Rel of
+ greaterThan -> greaterThan;
+ smallerThan -> smallerThan;
+ unequalTo -> unequalTo
+ end,
+ {relation, Rel2};
+tr_opt_extraInfo({range, Range}, State) ->
+ Range2 = tr_bool(Range, State),
+ {range, Range2};
+tr_opt_extraInfo({sublist, Sub}, State) ->
+ Sub2 = tr_bool(Sub, State),
+ {sublist, Sub2}.
+
+tr_opt_TerminationStateDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TerminationStateDescriptor(#'TerminationStateDescriptor'{propertyParms = Props,
+ eventBufferControl = Control,
+ serviceState = Service},
+ State) ->
+ #'TerminationStateDescriptor'{propertyParms = [tr_PropertyParm(P, State) || P <- Props],
+ eventBufferControl = tr_opt_EventBufferControl(Control, State),
+ serviceState = tr_opt_ServiceState(Service, State)}.
+
+tr_opt_EventBufferControl(Control, _State) ->
+ case Control of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ off -> off;
+ lockStep -> lockStep
+ end.
+
+tr_opt_ServiceState(Service, _State) ->
+ case Service of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ test -> test;
+ outOfSvc -> outOfSvc;
+ inSvc -> inSvc
+ end.
+
+tr_MuxDescriptor(#'MuxDescriptor'{muxType = Type,
+ termList = IdList},
+ State) ->
+ #'MuxDescriptor'{muxType = tr_MuxType(Type, State),
+ termList = [tr_TerminationID(Id, State) || Id <- IdList]}.
+
+tr_MuxType(Type, _State) ->
+ case Type of
+ h221 -> h221;
+ h223 -> h223;
+ h226 -> h226;
+ v76 -> v76
+ end.
+
+tr_opt_StreamID(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_StreamID(Id, State) ->
+ tr_StreamID(Id, State).
+
+tr_StreamID(Id, State) ->
+ tr_UINT16(Id, State).
+
+tr_EventsDescriptor(#'EventsDescriptor'{requestID = Id,
+ eventList = Events},
+ State) ->
+ #'EventsDescriptor'{requestID = tr_opt_RequestID(Id, State),
+ eventList = [tr_RequestedEvent(E, State) || E <- Events]}.
+
+tr_RequestedEvent(#'RequestedEvent'{pkgdName = Name,
+ streamID = Id,
+ evParList = Parms,
+ eventAction = Actions},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'RequestedEvent'{pkgdName = resolve(event, Name, State, Constraint),
+ streamID = tr_opt_StreamID(Id, State),
+ eventAction = tr_opt_RequestedActions(Actions, State),
+ evParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+tr_RegulatedEmbeddedDescriptor(
+ #'RegulatedEmbeddedDescriptor'{secondEvent = SE,
+ signalsDescriptor = SD}, State) ->
+ SE2 = tr_opt_SecondEventsDescriptor(SE, State),
+ SD2 = tr_opt_SignalsDescriptor(SD, State),
+ #'RegulatedEmbeddedDescriptor'{secondEvent = SE2,
+ signalsDescriptor = SD2}.
+
+tr_opt_NotifyBehaviour(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_NotifyBehaviour(NB, State) ->
+ tr_NotifyBehaviour(NB, State).
+
+tr_NotifyBehaviour({notifyImmediate, 'NULL'} = NB, _State) ->
+ NB;
+tr_NotifyBehaviour({notifyRegulated = Tag, Val}, State) ->
+ {Tag, tr_RegulatedEmbeddedDescriptor(Val, State)};
+tr_NotifyBehaviour({neverNotify, 'NULL'} = NB, _State) ->
+ NB.
+
+tr_opt_RequestedActions(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_RequestedActions(#'RequestedActions'{keepActive = KA,
+ eventDM = DM,
+ secondEvent = SE,
+ signalsDescriptor = SD,
+ notifyBehaviour = NB,
+ resetEventsDescriptor = RSD},
+ State) ->
+ KA2 = tr_opt_keepActive(KA, State),
+ DM2 = tr_opt_EventDM(DM, State),
+ SE2 = tr_opt_SecondEventsDescriptor(SE, State),
+ SD2 = tr_opt_SignalsDescriptor(SD, State),
+ NB2 = tr_opt_NotifyBehaviour(NB, State),
+ RSD2 = tr_opt_null(RSD, State),
+ #'RequestedActions'{keepActive = KA2,
+ eventDM = DM2,
+ secondEvent = SE2,
+ signalsDescriptor = SD2,
+ notifyBehaviour = NB2,
+ resetEventsDescriptor = RSD2}.
+
+tr_opt_keepActive(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_keepActive(Keep, State) ->
+ tr_bool(Keep, State).
+
+tr_opt_EventDM(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_EventDM({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ digitMapName -> tr_DigitMapName(Val, State);
+ digitMapValue -> tr_DigitMapValue(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_opt_SecondEventsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SecondEventsDescriptor(#'SecondEventsDescriptor'{requestID = Id,
+ eventList = Events},
+ State) ->
+ #'SecondEventsDescriptor'{requestID = tr_RequestID(Id, State), %% IG v6 6.8 withdrawn
+ eventList = [tr_SecondRequestedEvent(E, State) || E <- Events]}.
+
+tr_SecondRequestedEvent(#'SecondRequestedEvent'{pkgdName = Name,
+ streamID = Id,
+ evParList = Parms,
+ eventAction = Actions},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'SecondRequestedEvent'{pkgdName = resolve(event, Name, State, Constraint),
+ streamID = tr_opt_StreamID(Id, State),
+ eventAction = tr_opt_SecondRequestedActions(Actions, State),
+ evParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+
+tr_opt_SecondRequestedActions(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SecondRequestedActions(
+ #'SecondRequestedActions'{keepActive = KA,
+ eventDM = DM,
+ signalsDescriptor = SD,
+ notifyBehaviour = NB,
+ resetEventsDescriptor = RSD},
+ State) ->
+ KA2 = tr_opt_keepActive(KA, State),
+ DM2 = tr_opt_EventDM(DM, State),
+ SD2 = tr_opt_SignalsDescriptor(SD, State),
+ NB2 = tr_opt_NotifyBehaviour(NB, State),
+ RSD2 = tr_opt_null(RSD, State),
+ #'SecondRequestedActions'{keepActive = KA2,
+ eventDM = DM2,
+ signalsDescriptor = SD2,
+ notifyBehaviour = NB2,
+ resetEventsDescriptor = RSD2}.
+
+tr_EventBufferDescriptor(EventSpecs, State) ->
+ [tr_EventSpec(ES, State) || ES <- EventSpecs].
+
+tr_EventSpec(#'EventSpec'{eventName = Name,
+ streamID = Id,
+ eventParList = Parms},
+ State) ->
+ #'EventSpec'{eventName = tr_EventName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ eventParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+tr_opt_SignalsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SignalsDescriptor(SigDesc, State) ->
+ tr_SignalsDescriptor(SigDesc, State).
+
+tr_SignalsDescriptor(SigDesc, State) when is_list(SigDesc) ->
+ [tr_SignalRequest(SigReq, State) || SigReq <- SigDesc].
+
+tr_SignalRequest({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ signal -> tr_Signal(Val, State);
+ seqSigList -> tr_SeqSigList(Val, State)
+ end,
+ {Tag, Val2}.
+
+
+tr_SeqSigList(#'SeqSigList'{id = Id,
+ signalList = SigList},
+ State) when is_list(SigList) ->
+ #'SeqSigList'{id = tr_UINT16(Id, State),
+ signalList = [tr_Signal(Sig, State) || Sig <- SigList]}.
+
+tr_Signal(#'Signal'{signalName = Name,
+ streamID = SID,
+ sigType = Type,
+ duration = Dur,
+ notifyCompletion = Compl,
+ keepActive = Keep,
+ sigParList = Parms,
+ direction = Dir,
+ requestID = RID,
+ intersigDelay = ID},
+ State) ->
+ Name2 = tr_SignalName(Name, State),
+ SID2 = tr_opt_StreamID(SID, State),
+ Type2 = tr_opt_SignalType(Type, State),
+ Dur2 = tr_opt_UINT16(Dur, State),
+ Compl2 = tr_opt_NotifyCompletion(Compl, State),
+ Keep2 = tr_opt_keepActive(Keep, State),
+ Parms2 = [tr_SigParameter(P, Name, State) || P <- Parms],
+ Dir2 = tr_opt_SignalDirection(Dir, State),
+ RID2 = tr_opt_RequestID(RID, State),
+ ID2 = tr_opt_UINT16(ID, State),
+ #'Signal'{signalName = Name2,
+ streamID = SID2,
+ sigType = Type2,
+ duration = Dur2,
+ notifyCompletion = Compl2,
+ keepActive = Keep2,
+ sigParList = Parms2,
+ direction = Dir2,
+ requestID = RID2,
+ intersigDelay = ID2}.
+
+tr_opt_NotifyCompletion(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_NotifyCompletion(Items, State) when is_list(Items) ->
+ [tr_notifyCompletionItem(I, State) || I <- Items].
+
+tr_notifyCompletionItem(Item, _State) ->
+ case Item of
+ onTimeOut -> onTimeOut;
+ onInterruptByEvent -> onInterruptByEvent;
+ onInterruptByNewSignalDescr -> onInterruptByNewSignalDescr;
+ otherReason -> otherReason;
+ onIteration -> onIteration
+ end.
+
+tr_opt_SignalType(asn1_NOVALUE = Type, _State) ->
+ Type;
+tr_opt_SignalType(Type, _State) ->
+ case Type of
+ brief -> brief;
+ onOff -> onOff;
+ timeOut -> timeOut
+ end.
+
+tr_opt_SignalDirection(asn1_NOVALUE = SD, _State) ->
+ SD;
+tr_opt_SignalDirection(SD, _State) ->
+ case SD of
+ internal -> internal;
+ external -> external;
+ both -> both
+ end.
+
+tr_SignalName(Name, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ resolve(signal, Name, State, Constraint).
+
+tr_SigParameter(#'SigParameter'{sigParameterName = ParName,
+ value = Value,
+ extraInfo = Extra},
+ SigName,
+ State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ N = resolve({signal_parameter, SigName}, ParName, State, Constraint),
+ #'SigParameter'{sigParameterName = N,
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_opt_RequestID(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_RequestID(Id, State) ->
+ tr_RequestID(Id, State).
+
+tr_RequestID(Id, _State) when Id =:= ?megaco_all_request_id ->
+ ?megaco_all_request_id;
+tr_RequestID(Id, State) ->
+ tr_UINT32(Id, State).
+
+tr_ModemDescriptor(_MD, _State) ->
+ deprecated.
+
+tr_DigitMapDescriptor(#'DigitMapDescriptor'{digitMapName = Name,
+ digitMapValue = Value},
+ State) ->
+ #'DigitMapDescriptor'{digitMapName = tr_opt_DigitMapName(Name, State),
+ digitMapValue = tr_opt_DigitMapValue(Value, State)}.
+
+tr_opt_DigitMapName(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_DigitMapName(Name, State) ->
+ tr_DigitMapName(Name, State).
+
+tr_DigitMapName(Name, State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ resolve(dialplan, Name, State, Constraint).
+
+tr_opt_DigitMapValue(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_DigitMapValue(Value, State) ->
+ tr_DigitMapValue(Value, State).
+
+tr_DigitMapValue(#'DigitMapValue'{digitMapBody = Body,
+ startTimer = Start,
+ shortTimer = Short,
+ longTimer = Long},
+ State) ->
+ #'DigitMapValue'{startTimer = tr_opt_timer(Start, State),
+ shortTimer = tr_opt_timer(Short, State),
+ longTimer = tr_opt_timer(Long, State),
+ digitMapBody = tr_STRING(Body, State)}. %% BUGBUG: digitMapBody not handled at all
+
+tr_opt_timer(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_timer(Timer, State) ->
+ tr_DIGIT(Timer, State, 0, 99).
+
+tr_ServiceChangeParm(
+ #'ServiceChangeParm'{serviceChangeMethod = Method,
+ serviceChangeAddress = Addr,
+ serviceChangeVersion = Version,
+ serviceChangeProfile = Profile,
+ serviceChangeReason = Reason,
+ serviceChangeDelay = Delay,
+ serviceChangeMgcId = MgcId,
+ timeStamp = Time,
+ serviceChangeInfo = Info,
+ serviceChangeIncompleteFlag = Incomplete},
+ State) ->
+ Method2 = tr_ServiceChangeMethod(Method, State),
+ Addr2 = tr_opt_ServiceChangeAddress(Addr, State),
+ Version2 = tr_opt_serviceChangeVersion(Version, State),
+ Profile2 = tr_opt_ServiceChangeProfile(Profile, State),
+ Reason2 = tr_serviceChangeReason(Reason, State),
+ Delay2 = tr_opt_serviceChangeDelay(Delay, State),
+ MgcId2 = tr_opt_serviceChangeMgcId(MgcId, State),
+ Time2 = tr_opt_TimeNotation(Time, State),
+ Info2 = tr_opt_AuditDescriptor(Info, State),
+ Incomplete2 = tr_opt_null(Incomplete, State),
+ #'ServiceChangeParm'{serviceChangeMethod = Method2,
+ serviceChangeAddress = Addr2,
+ serviceChangeVersion = Version2,
+ serviceChangeProfile = Profile2,
+ serviceChangeReason = Reason2,
+ serviceChangeDelay = Delay2,
+ serviceChangeMgcId = MgcId2,
+ timeStamp = Time2,
+ serviceChangeInfo = Info2,
+ serviceChangeIncompleteFlag = Incomplete2}.
+
+tr_ServiceChangeMethod(Method, _State) ->
+ case Method of
+ failover -> failover;
+ forced -> forced;
+ graceful -> graceful;
+ restart -> restart;
+ disconnected -> disconnected;
+ handOff -> handOff
+ end. %% BUGBUG: extension
+
+tr_opt_ServiceChangeAddress(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ServiceChangeAddress({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ portNumber -> tr_portNumber(Val, State);
+ ip4Address -> tr_IP4Address(Val, State);
+ ip6Address -> tr_IP6Address(Val, State);
+ domainName -> tr_DomainName(Val, State);
+ deviceName -> tr_PathName(Val, State);
+ mtpAddress -> tr_mtpAddress(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_opt_serviceChangeVersion(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeVersion(Version, State) ->
+ tr_version(Version, State).
+
+tr_opt_ServiceChangeProfile(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+%% Decode
+tr_opt_ServiceChangeProfile({'ServiceChangeProfile', ProfileName}, State) ->
+ case string:tokens(ProfileName, "/") of
+ [Name0, Version0] ->
+ Name = tr_STRING(Name0, State, 1, 64),
+ Version = tr_version(list_to_integer(Version0), State),
+ #'ServiceChangeProfile'{profileName = Name,
+ version = Version}
+ end;
+%% Encode
+tr_opt_ServiceChangeProfile(#'ServiceChangeProfile'{profileName = Name0,
+ version = Version0},
+ State) ->
+ Name = tr_STRING(Name0, State, 1, 64),
+ Version = tr_version(Version0, State),
+ ProfileName = lists:flatten(io_lib:format("~s/~w", [Name, Version])),
+ {'ServiceChangeProfile', ProfileName}.
+
+tr_serviceChangeReason([_] = Reason, State) ->
+ tr_Value(Reason, State).
+
+tr_opt_serviceChangeDelay(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeDelay(Delay, State) ->
+ tr_UINT32(Delay, State).
+
+tr_opt_serviceChangeMgcId(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeMgcId(MgcId, State) ->
+ tr_MId(MgcId, State).
+
+tr_opt_portNumber(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_portNumber(Port, State) ->
+ tr_portNumber(Port, State).
+
+tr_portNumber(Port, State) when is_integer(Port) andalso (Port >= 0) ->
+ tr_UINT16(Port, State).
+
+tr_ServiceChangeResParm(#'ServiceChangeResParm'{serviceChangeMgcId = MgcId,
+ serviceChangeAddress = Addr,
+ serviceChangeVersion = Version,
+ serviceChangeProfile = Profile,
+ timeStamp = Time},
+ State) ->
+ #'ServiceChangeResParm'{serviceChangeMgcId = tr_opt_serviceChangeMgcId(MgcId, State),
+ serviceChangeAddress = tr_opt_ServiceChangeAddress(Addr, State),
+ serviceChangeVersion = tr_opt_serviceChangeVersion(Version, State),
+ serviceChangeProfile = tr_opt_ServiceChangeProfile(Profile, State),
+ timeStamp = tr_opt_TimeNotation(Time, State)}.
+
+tr_PackagesDescriptor(Items, State) when is_list(Items) ->
+ [tr_PackagesItem(I, State) || I <- Items].
+
+tr_PackagesItem(#'PackagesItem'{packageName = Name,
+ packageVersion = Version},
+ State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ #'PackagesItem'{packageName = resolve(package, Name, State, Constraint),
+ packageVersion = tr_UINT16(Version, State)}.
+
+tr_opt_StatisticsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_StatisticsDescriptor(Parms, State) ->
+ tr_StatisticsDescriptor(Parms, State).
+
+tr_StatisticsDescriptor(Parms, State) when is_list(Parms) ->
+ [tr_StatisticsParameter(P, State) || P <- Parms].
+
+tr_StatisticsParameter(#'StatisticsParameter'{statName = Name,
+ statValue = Value},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'StatisticsParameter'{statName = resolve(statistics, Name, State, Constraint),
+ statValue = tr_opt_Value(Value, State)}.
+
+tr_opt_TimeNotation(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TimeNotation(#'TimeNotation'{date = Date,
+ time = Time},
+ State) ->
+ #'TimeNotation'{date = tr_STRING(Date, State, 8, 8), % "yyyymmdd"
+ time = tr_STRING(Time, State, 8, 8)}.% "hhmmssss"
+
+%% BUGBUG: Does not verify that string must contain at least one char
+%% BUGBUG: This violation of the is required in order to comply with
+%% BUGBUG: the dd/ce ds parameter that may possibly be empty.
+
+tr_opt_Value(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_Value(Value, State) ->
+ tr_Value(Value, State).
+
+tr_Value(Strings, _State) when is_list(Strings) ->
+ [[Char || Char <- String] || String <- Strings].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Encode an octet string, escape } by \ if necessary
+tr_OCTET_STRING(String, _State, Min, Max) when is_list(String) ->
+ verify_count(length(String), Min, Max),
+ String.
+
+tr_QUOTED_STRING(String, _State) when is_list(String) ->
+ verify_count(length(String), 1, infinity),
+ String.
+
+%% The internal format of hex digits is a list of octets
+%% Min and Max means #hexDigits
+%% Leading zeros are prepended in order to fulfill Min
+tr_HEXDIG(Octets, _State, Min, Max) when is_list(Octets) ->
+ verify_count(length(Octets), Min, Max),
+ Octets.
+
+tr_DIGIT(Val, State, Min, Max) ->
+ tr_integer(Val, State, Min, Max).
+
+tr_STRING(String, _State) when is_list(String) ->
+ String.
+
+tr_STRING(String, _State, Min, Max) when is_list(String) ->
+ verify_count(length(String), Min, Max),
+ String.
+
+tr_opt_UINT16(Val, State) ->
+ tr_opt_integer(Val, State, 0, 65535).
+
+tr_UINT16(Val, State) ->
+ tr_integer(Val, State, 0, 65535).
+
+tr_UINT32(Val, State) ->
+ tr_integer(Val, State, 0, 4294967295).
+
+tr_opt_integer(asn1_NOVALUE, _State, _Min, _Max) ->
+ asn1_NOVALUE;
+tr_opt_integer(Int, State, Min, Max) ->
+ tr_integer(Int, State, Min, Max).
+
+tr_integer(Int, _State, Min, Max) ->
+ verify_count(Int, Min, Max),
+ Int.
+
+%% Verify that Count is within the range of Min and Max
+verify_count(Count, Min, Max) ->
+ if
+ is_integer(Count) ->
+ if
+ is_integer(Min) andalso (Count >= Min) ->
+ if
+ is_integer(Max) andalso (Count =< Max) ->
+ Count;
+ Max =:= infinity ->
+ Count;
+ true ->
+ error({count_too_large, Count, Max})
+ end;
+ true ->
+ error({count_too_small, Count, Min})
+ end;
+ true ->
+ error({count_not_an_integer, Count})
+ end.
+
+
+%% -------------------------------------------------------------------
+
+error(Reason) ->
+ erlang:error(Reason).
+
+
diff --git a/lib/megaco/src/binary/megaco_binary_transformer_v1.erl b/lib/megaco/src/binary/megaco_binary_transformer_v1.erl
new file mode 100644
index 0000000000..7236c0a9e1
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_transformer_v1.erl
@@ -0,0 +1,1261 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Transform internal form of Megaco/H.248 messages
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_transformer_v1).
+
+-include_lib("megaco/include/megaco.hrl").
+-include_lib("megaco/include/megaco_message_v1.hrl").
+
+-export([tr_message/3, tr_transaction/3]).
+
+-define(DEFAULT_NAME_RESOLVER,megaco_binary_name_resolver_v1).
+-define(error(R), erlang:error({error, R})).
+
+-record(state, {mode, % verify | encode | decode
+ resolver_module, %
+ resolver_options}).
+
+resolve(Type, Item, State, Constraint) ->
+ case State#state.mode of
+ verify ->
+ Item;
+ encode ->
+ %% i("resolve(encode) -> encode: ~p",[Item]),
+ Mod = State#state.resolver_module,
+ Opt = State#state.resolver_options,
+ EncodedItem = Mod:encode_name(Opt, Type, Item),
+ %% i("resolve -> verify contraint for ~p",[EncodedItem]),
+ verify_constraint(EncodedItem, Constraint);
+ decode ->
+ %% i("resolve(decode) -> verify contraint for ~p",[Item]),
+ DecodedItem = verify_constraint(Item, Constraint),
+ Mod = State#state.resolver_module,
+ Opt = State#state.resolver_options,
+ %% i("resolve(decode) -> decode: ~p",[DecodedItem]),
+ Mod:decode_name(Opt, Type, DecodedItem)
+ end.
+
+verify_constraint(Item, valid) ->
+ Item;
+verify_constraint(Item, Constraint) when is_function(Constraint) ->
+ Constraint(Item).
+
+tr_message(MegaMsg, Mode, Config) ->
+ case Config of
+ [native] ->
+ MegaMsg;
+ [verify] ->
+ State = #state{mode = verify},
+ tr_MegacoMessage(MegaMsg, State);
+ [] ->
+ State = #state{mode = Mode,
+ resolver_module = ?DEFAULT_NAME_RESOLVER,
+ resolver_options = [8, 8, 8]},
+ tr_MegacoMessage(MegaMsg, State);
+ [{binary_name_resolver, {Module, Options}}] when is_atom(Module) ->
+ State = #state{mode = Mode,
+ resolver_module = Module,
+ resolver_options = Options},
+ tr_MegacoMessage(MegaMsg, State)
+ end.
+
+tr_transaction(Trans, Mode, Config) ->
+ case Config of
+ [native] ->
+ Trans;
+ [verify] ->
+ State = #state{mode = verify},
+ tr_Transaction(Trans, State);
+ [] ->
+ State = #state{mode = Mode,
+ resolver_module = ?DEFAULT_NAME_RESOLVER,
+ resolver_options = [8, 8, 8]},
+ tr_Transaction(Trans, State);
+ [{binary_name_resolver, {Module, Options}}] when is_atom(Module) ->
+ State = #state{mode = Mode,
+ resolver_module = Module,
+ resolver_options = Options},
+ tr_Transaction(Trans, State)
+ end.
+
+tr_MegacoMessage(#'MegacoMessage'{authHeader = Auth,
+ mess = Mess},
+ State) ->
+ #'MegacoMessage'{authHeader = tr_opt_AuthenticationHeader(Auth, State),
+ mess = tr_Message(Mess, State)}.
+
+tr_opt_AuthenticationHeader(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_AuthenticationHeader(#'AuthenticationHeader'{secParmIndex = SPI,
+ seqNum = SN,
+ ad = AuthData},
+ State) ->
+ #'AuthenticationHeader'{secParmIndex = tr_SecurityParmIndex(SPI, State),
+ seqNum = tr_SequenceNum(SN, State),
+ ad = tr_AuthData(AuthData, State)}.
+
+tr_SecurityParmIndex(SPI, State) ->
+ tr_HEXDIG(SPI, State, 4, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_SequenceNum(SN, State) ->
+ tr_HEXDIG(SN, State, 4, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_AuthData(AuthData, State) ->
+ tr_HEXDIG(AuthData, State, 12, 32). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_Message(#'Message'{version = Version,
+ mId = MID,
+ messageBody = Body},
+ State) ->
+ #'Message'{version = tr_version(Version, State),
+ mId = tr_MId(MID, State),
+ messageBody = tr_Message_messageBody(Body, State)}.
+
+tr_version(Version, State) ->
+ tr_DIGIT(Version, State, 0, 99).
+
+tr_Message_messageBody({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ messageError -> tr_ErrorDescriptor(Val, State);
+ transactions when is_list(Val) -> [tr_Transaction(T, State) || T <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_MId({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ ip4Address -> tr_IP4Address(Val, State);
+ ip6Address -> tr_IP6Address(Val, State);
+ domainName -> tr_DomainName(Val, State);
+ deviceName -> tr_PathName(Val, State);
+ mtpAddress -> tr_mtpAddress(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_mtpAddress(MtpAddr, State) ->
+ tr_OCTET_STRING(MtpAddr, State, 2, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_DomainName(#'DomainName'{name = Name,
+ portNumber = Port},
+ State) ->
+ Domain = #'DomainName'{name = tr_STRING(Name, State), % BUGBUG: Mismatch between ASN.1 and ABNF
+ portNumber = tr_opt_portNumber(Port, State)},
+ {domainName, Domain2} = resolve(mid, {domainName, Domain}, State, valid),
+ Domain2.
+
+tr_IP4Address(#'IP4Address'{address = [A1, A2, A3, A4],
+ portNumber = Port},
+ State) ->
+ #'IP4Address'{address = [tr_V4hex(A1, State),
+ tr_V4hex(A2, State),
+ tr_V4hex(A3, State),
+ tr_V4hex(A4, State)],
+ portNumber = tr_opt_portNumber(Port, State)}.
+
+tr_V4hex(Val, State) ->
+ tr_DIGIT(Val, State, 0, 255).
+
+tr_IP6Address(_Val, _State) ->
+ ?error(ipv6_not_supported). %% BUGBUG: nyi
+
+tr_PathName(Path, State) ->
+ %% BUGBUG: ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
+ %% BUGBUG: ["@" pathDomainName ]
+ Constraint = fun({deviceName, Item}) -> tr_STRING(Item, State, 1, 64) end,
+ resolve(mid, {deviceName, Path}, State, Constraint).
+
+tr_Transaction({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ transactionRequest -> tr_TransactionRequest(Val, State);
+ transactionPending -> tr_TransactionPending(Val, State);
+ transactionReply -> tr_TransactionReply(Val, State);
+ transactionResponseAck -> [tr_TransactionAck(T, State) || T <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_TransactionAck(#'TransactionAck'{firstAck = First,
+ lastAck = Last},
+ State) ->
+ #'TransactionAck'{firstAck = tr_TransactionId(First, State),
+ lastAck = tr_opt_TransactionId(Last, State)}.
+
+tr_opt_TransactionId(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TransactionId(Id, State) ->
+ tr_TransactionId(Id, State).
+
+tr_TransactionId(Id, State) ->
+ tr_UINT32(Id, State).
+
+tr_TransactionRequest(#'TransactionRequest'{transactionId = Id,
+ actions = Actions},
+ State) when is_list(Actions) ->
+
+ #'TransactionRequest'{transactionId = tr_TransactionId(Id, State),
+ actions = [tr_ActionRequest(ActReq, State) || ActReq <- Actions]}.
+
+tr_TransactionPending(#'TransactionPending'{transactionId = Id},
+ State) ->
+ #'TransactionPending'{transactionId = tr_TransactionId(Id, State)}.
+
+tr_TransactionReply(#'TransactionReply'{transactionId = Id,
+ immAckRequired = ImmAck,
+ transactionResult = TransRes},
+ State) ->
+ #'TransactionReply'{transactionId = tr_TransactionId(Id, State),
+ immAckRequired = tr_opt_null(ImmAck, State),
+ transactionResult = tr_TransactionReply_transactionResult(TransRes, State)}.
+
+tr_opt_null(asn1_NOVALUE, _State) -> asn1_NOVALUE;
+tr_opt_null('NULL', _State) -> 'NULL'.
+
+tr_TransactionReply_transactionResult({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ transactionError ->
+ tr_ErrorDescriptor(Val, State);
+ actionReplies when is_list(Val) andalso (Val =/= []) ->
+ [tr_ActionReply(ActRep, State) || ActRep <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_opt_ErrorDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ErrorDescriptor(ErrDesc, State) ->
+ tr_ErrorDescriptor(ErrDesc, State).
+
+tr_ErrorDescriptor(#'ErrorDescriptor'{errorCode = Code,
+ errorText = Text},
+ State) ->
+ #'ErrorDescriptor'{errorCode = tr_ErrorCode(Code, State),
+ errorText = tr_opt_ErrorText(Text, State)}.
+
+tr_ErrorCode(Code, State) ->
+ tr_DIGIT(Code, State, 0, 999).
+
+tr_opt_ErrorText(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ErrorText(Text, State) ->
+ tr_QUOTED_STRING(Text, State).
+
+tr_ContextID(CtxId, State) ->
+ case CtxId of
+ ?megaco_all_context_id -> ?megaco_all_context_id;
+ ?megaco_null_context_id -> ?megaco_null_context_id;
+ ?megaco_choose_context_id -> ?megaco_choose_context_id;
+ Int when is_integer(Int) -> tr_UINT32(Int, State)
+ end.
+
+tr_ActionRequest(#'ActionRequest'{contextId = CtxId,
+ contextRequest = CtxReq,
+ contextAttrAuditReq = CtxAuditReq,
+ commandRequests = CmdReqList},
+ State) ->
+ #'ActionRequest'{contextId = tr_ContextID(CtxId, State),
+ contextRequest = tr_opt_ContextRequest(CtxReq, State),
+ contextAttrAuditReq = tr_opt_ContextAttrAuditRequest(CtxAuditReq, State),
+ commandRequests = [tr_CommandRequest(CmdReq, State) || CmdReq <- CmdReqList]}.
+
+tr_ActionReply(#'ActionReply'{contextId = CtxId,
+ errorDescriptor = ErrDesc,
+ contextReply = CtxRep,
+ commandReply = CmdRepList},
+ State) ->
+ CmdRepList2 = [tr_CommandReply(CmdRep, State) || CmdRep <- CmdRepList],
+ #'ActionReply'{contextId = tr_ContextID(CtxId, State),
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State),
+ contextReply = tr_opt_ContextRequest(CtxRep, State),
+ commandReply = CmdRepList2}.
+
+tr_opt_ContextRequest(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ContextRequest(#'ContextRequest'{priority = Prio,
+ emergency = Em,
+ topologyReq = TopReqList},
+ State) ->
+ Prio2 =
+ case Prio of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_integer(Prio, State, 0, 15)
+ end,
+ Em2 =
+ case Em of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ TopReqList2 =
+ case TopReqList of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_TopologyRequest(TopReq, State) ||
+ TopReq <- TopReqList]
+ end,
+ #'ContextRequest'{priority = Prio2,
+ emergency = Em2,
+ topologyReq = TopReqList2}.
+
+tr_opt_ContextAttrAuditRequest(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ContextAttrAuditRequest(#'ContextAttrAuditRequest'{topology = Top,
+ emergency = Em,
+ priority = Prio},
+ State) ->
+ #'ContextAttrAuditRequest'{topology = tr_opt_null(Top, State),
+ emergency = tr_opt_null(Em, State),
+ priority = tr_opt_null(Prio, State)}.
+
+tr_CommandRequest(#'CommandRequest'{command = Cmd,
+ optional = Opt,
+ wildcardReturn = Wild},
+ State) ->
+ #'CommandRequest'{optional = tr_opt_null(Opt, State),
+ wildcardReturn = tr_opt_null(Wild, State),
+ command = tr_Command(Cmd, State)}.
+
+tr_Command({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ addReq -> tr_AmmRequest(Val, State);
+ moveReq -> tr_AmmRequest(Val, State);
+ modReq -> tr_AmmRequest(Val, State);
+ subtractReq -> tr_SubtractRequest(Val, State);
+ auditCapRequest -> tr_AuditRequest(Val, State);
+ auditValueRequest -> tr_AuditRequest(Val, State);
+ notifyReq -> tr_NotifyRequest(Val, State);
+ serviceChangeReq -> tr_ServiceChangeRequest(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_CommandReply({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ addReply -> tr_AmmsReply(Val, State);
+ moveReply -> tr_AmmsReply(Val, State);
+ modReply -> tr_AmmsReply(Val, State);
+ subtractReply -> tr_AmmsReply(Val, State);
+ auditCapReply -> tr_AuditReply(Val, State);
+ auditValueReply -> tr_AuditReply(Val, State);
+ notifyReply -> tr_NotifyReply(Val, State);
+ serviceChangeReply -> tr_ServiceChangeReply(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_TopologyRequest(#'TopologyRequest'{terminationFrom = From,
+ terminationTo = To,
+ topologyDirection = Dir},
+ State) ->
+ Dir2 =
+ case Dir of
+ bothway -> bothway;
+ isolate -> isolate;
+ oneway -> oneway
+ end,
+ #'TopologyRequest'{terminationFrom = tr_TerminationID(From, State),
+ terminationTo = tr_TerminationID(To, State),
+ topologyDirection = Dir2}.
+
+tr_AmmRequest(#'AmmRequest'{terminationID = IdList,
+ descriptors = DescList},
+ State) ->
+ #'AmmRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ descriptors = [tr_ammDescriptor(Desc, State) ||
+ Desc <- DescList]}.
+
+tr_ammDescriptor({Tag, Desc}, State) ->
+ Desc2 =
+ case Tag of
+ mediaDescriptor -> tr_MediaDescriptor(Desc, State);
+ modemDescriptor -> tr_ModemDescriptor(Desc, State);
+ muxDescriptor -> tr_MuxDescriptor(Desc, State);
+ eventsDescriptor -> tr_EventsDescriptor(Desc, State);
+ eventBufferDescriptor -> tr_EventBufferDescriptor(Desc, State);
+ signalsDescriptor -> tr_SignalsDescriptor(Desc, State);
+ digitMapDescriptor -> tr_DigitMapDescriptor(Desc, State);
+ auditDescriptor -> tr_AuditDescriptor(Desc, State)
+ end,
+ {Tag, Desc2}.
+
+tr_AmmsReply(#'AmmsReply'{terminationID = IdList,
+ terminationAudit = TermAudit},
+ State) ->
+ TermAudit2 =
+ case TermAudit of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_TerminationAudit(TermAudit, State)
+ end,
+ #'AmmsReply'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ terminationAudit = TermAudit2}.
+
+tr_SubtractRequest(#'SubtractRequest'{terminationID = IdList,
+ auditDescriptor = Desc},
+ State) ->
+ #'SubtractRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ auditDescriptor = tr_opt_AuditDescriptor(Desc, State)}.
+
+tr_AuditRequest(#'AuditRequest'{terminationID = Id,
+ auditDescriptor = Desc},
+ State) ->
+ #'AuditRequest'{terminationID = tr_TerminationID(Id, State),
+ auditDescriptor = tr_AuditDescriptor(Desc, State)}.
+
+%% auditReply = (AuditValueToken / AuditCapToken )
+%% ( contextTerminationAudit / auditOther)
+%% auditOther = EQUAL TerminationID LBRKT
+%% terminationAudit RBRKT
+%% terminationAudit = auditReturnParameter *(COMMA auditReturnParameter)
+%%
+%% contextTerminationAudit = EQUAL CtxToken ( terminationIDList /
+%% LBRKT errorDescriptor RBRKT )
+
+tr_AuditReply({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ contextAuditResult ->
+ [tr_TerminationID(Id, State) || Id <- Val];
+ error ->
+ tr_ErrorDescriptor(Val, State);
+ auditResult ->
+ tr_AuditResult(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_AuditResult(#'AuditResult'{terminationID = Id,
+ terminationAuditResult = AuditRes},
+ State) ->
+ #'AuditResult'{terminationID = tr_TerminationID(Id, State),
+ terminationAuditResult = tr_TerminationAudit(AuditRes, State)}.
+
+tr_opt_AuditDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_AuditDescriptor(Desc, State) ->
+ tr_AuditDescriptor(Desc, State).
+
+tr_AuditDescriptor(#'AuditDescriptor'{auditToken = Tokens},
+ State) ->
+ Tokens2 =
+ case Tokens of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_auditItem(Token, State) || Token <- Tokens]
+ end,
+ #'AuditDescriptor'{auditToken = Tokens2}.
+
+tr_auditItem(Token, _State) ->
+ case Token of
+ muxToken -> muxToken;
+ modemToken -> modemToken;
+ mediaToken -> mediaToken;
+ eventsToken -> eventsToken;
+ signalsToken -> signalsToken;
+ digitMapToken -> digitMapToken;
+ statsToken -> statsToken;
+ observedEventsToken -> observedEventsToken;
+ packagesToken -> packagesToken;
+ eventBufferToken -> eventBufferToken
+ end.
+
+tr_TerminationAudit(ParmList, State) when is_list(ParmList) ->
+ [tr_AuditReturnParameter(Parm, State) || Parm <- ParmList].
+
+tr_AuditReturnParameter({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ errorDescriptor ->
+ tr_ErrorDescriptor(Val, State);
+ mediaDescriptor ->
+ tr_MediaDescriptor(Val, State);
+ modemDescriptor ->
+ tr_ModemDescriptor(Val, State);
+ muxDescriptor ->
+ tr_MuxDescriptor(Val, State);
+ eventsDescriptor ->
+ tr_EventsDescriptor(Val, State);
+ eventBufferDescriptor ->
+ tr_EventBufferDescriptor(Val, State);
+ signalsDescriptor ->
+ tr_SignalsDescriptor(Val, State);
+ digitMapDescriptor ->
+ tr_DigitMapDescriptor(Val, State);
+ observedEventsDescriptor ->
+ tr_ObservedEventsDescriptor(Val, State);
+ statisticsDescriptor ->
+ tr_StatisticsDescriptor(Val, State);
+ packagesDescriptor ->
+ tr_PackagesDescriptor(Val, State);
+ emptyDescriptors ->
+ tr_EmptyDescriptors(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_EmptyDescriptors(#'AuditDescriptor'{auditToken = Tokens},
+ State) ->
+ case Tokens of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_auditItem(Token, State) || Token <- Tokens]
+ end.
+
+tr_NotifyRequest(#'NotifyRequest'{terminationID = IdList,
+ observedEventsDescriptor = ObsDesc,
+ errorDescriptor = ErrDesc},
+ State) ->
+ %% BUGBUG: Mismatch between ASN.1 and ABNF
+ %% BUGBUG: The following ought to be a 'choice'
+ #'NotifyRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ observedEventsDescriptor = tr_ObservedEventsDescriptor(ObsDesc, State),
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State)}.
+
+tr_NotifyReply(#'NotifyReply'{terminationID = IdList,
+ errorDescriptor = ErrDesc},
+ State) ->
+ #'NotifyReply'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State)}.
+
+tr_ObservedEventsDescriptor(#'ObservedEventsDescriptor'{requestId = Id,
+ observedEventLst = Events},
+ State) when is_list(Events) ->
+ #'ObservedEventsDescriptor'{requestId = tr_RequestID(Id, State),
+ observedEventLst = [tr_ObservedEvent(E, State) || E <- Events]}.
+
+%% ;time per event, because it might be buffered
+%% observedEvent = [ TimeStamp LWSP COLON] LWSP
+%% pkgdName [ LBRKT observedEventParameter
+%% *(COMMA observedEventParameter) RBRKT ]
+%%
+%% ;at-most-once eventStream, every eventParameterName at most once
+%% observedEventParameter = eventStream / eventOther
+
+tr_ObservedEvent(#'ObservedEvent'{eventName = Name,
+ streamID = Id,
+ eventParList = Parms,
+ timeNotation = Time},
+ State) ->
+ #'ObservedEvent'{eventName = tr_EventName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ eventParList = [tr_EventParameter(P, Name, State) || P <- Parms],
+ timeNotation = tr_opt_TimeNotation(Time, State)}.
+
+tr_EventName(Name, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ resolve(event, Name, State, Constraint).
+
+tr_EventParameter(#'EventParameter'{eventParameterName = ParName,
+ value = Value,
+ extraInfo = Extra},
+ EventName,
+ State) ->
+ %% BUGBUG: event parameter name
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ N = resolve({event_parameter, EventName}, ParName, State, Constraint),
+ #'EventParameter'{eventParameterName = N,
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_ServiceChangeRequest(#'ServiceChangeRequest'{terminationID = IdList,
+ serviceChangeParms = Parms},
+ State) ->
+ #'ServiceChangeRequest'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ serviceChangeParms = tr_ServiceChangeParm(Parms, State)}.
+
+%% serviceChangeReply = ServiceChangeToken EQUAL TerminationID
+%% [LBRKT (errorDescriptor /
+%% serviceChangeReplyDescriptor) RBRKT]
+%% serviceChangeReplyDescriptor = ServicesToken LBRKT
+%% servChgReplyParm *(COMMA servChgReplyParm) RBRKT
+%%
+%% ;at-most-once. Version is REQUIRED on first ServiceChange response
+%% servChgReplyParm = (serviceChangeAddress / serviceChangeMgcId /
+%% serviceChangeProfile / serviceChangeVersion )
+tr_ServiceChangeReply(#'ServiceChangeReply'{terminationID = IdList,
+ serviceChangeResult = Res},
+ State) ->
+ #'ServiceChangeReply'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ serviceChangeResult = tr_ServiceChangeResult(Res, State)}.
+
+tr_ServiceChangeResult({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ errorDescriptor -> tr_ErrorDescriptor(Val, State);
+ serviceChangeResParms -> tr_ServiceChangeResParm(Val, State)
+ end,
+ {Tag, Val2}.
+
+%% TerminationID = "ROOT" / pathNAME / "$" / "*"
+%% ; Total length of pathNAME must not exceed 64 chars.
+%% pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
+%% ["@" pathDomainName ]
+
+tr_TerminationID(TermId, State) when State#state.mode =/= verify ->
+ resolve(term_id, TermId, State, valid);
+tr_TerminationID(#'TerminationID'{wildcard = Wild,
+ id = Id},
+ _State) ->
+ #'TerminationID'{wildcard = Wild,
+ id = Id};
+tr_TerminationID(#megaco_term_id{contains_wildcards = IsWild,
+ id = Id},
+ State) ->
+ #megaco_term_id{contains_wildcards = tr_bool(IsWild, State),
+ id = [tr_term_id_component(Sub, State) || Sub <- Id]}.
+
+tr_opt_bool(asn1_NOVALUE, _State) -> asn1_NOVALUE;
+tr_opt_bool(Bool, State) -> tr_bool(Bool, State).
+
+tr_bool(true, _State) -> true;
+tr_bool(false, _State) -> false.
+
+tr_term_id_component(Sub, _State) ->
+ case Sub of
+ all -> all;
+ choose -> choose;
+ Char when is_integer(Char) -> Char
+ end.
+
+%% mediaDescriptor = MediaToken LBRKT mediaParm *(COMMA mediaParm) RBRKT
+%% ; at-most-once per item
+%% ; and either streamParm or streamDescriptor but not both
+%% mediaParm = (streamParm / streamDescriptor /
+%% terminationStateDescriptor)
+%% ; at-most-once
+%% streamParm = ( localDescriptor / remoteDescriptor /
+%% localControlDescriptor )
+%% streamDescriptor = StreamToken EQUAL StreamID LBRKT streamParm
+%% *(COMMA streamParm) RBRKT
+tr_MediaDescriptor(#'MediaDescriptor'{termStateDescr = TermState,
+ streams = Streams},
+ State) ->
+ #'MediaDescriptor'{termStateDescr = tr_opt_TerminationStateDescriptor(TermState, State),
+ streams = tr_opt_streams(Streams, State)}.
+
+tr_opt_streams(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_streams({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ oneStream -> tr_StreamParms(Val, State);
+ multiStream -> [tr_StreamDescriptor(SD, State) || SD <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_StreamParms(#'StreamParms'{localControlDescriptor = Control,
+ localDescriptor = Local,
+ remoteDescriptor = Remote},
+ State) ->
+ #'StreamParms'{localControlDescriptor = tr_opt_LocalControlDescriptor(Control, State),
+ localDescriptor = tr_opt_LocalRemoteDescriptor(Local, State),
+ remoteDescriptor = tr_opt_LocalRemoteDescriptor(Remote, State)}.
+
+tr_StreamDescriptor(#'StreamDescriptor'{streamID = Id,
+ streamParms = Parms},
+ State) ->
+ #'StreamDescriptor'{streamID = tr_StreamID(Id, State),
+ streamParms = tr_StreamParms(Parms, State)}.
+
+%% localControlDescriptor = LocalControlToken LBRKT localParm
+%% *(COMMA localParm) RBRKT
+%%
+%% ; at-most-once per item
+%% localParm = ( streamMode / propertyParm /
+%% reservedValueMode / reservedGroupMode )
+%% reservedValueMode = ReservedValueToken EQUAL ( "ON" / "OFF" )
+%% reservedGroupMode = ReservedGroupToken EQUAL ( "ON" / "OFF" )
+%%
+%% reservedMode = ReservedToken EQUAL ( "ON" / "OFF" )
+%%
+%% streamMode = ModeToken EQUAL streamModes
+tr_opt_LocalControlDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_LocalControlDescriptor(#'LocalControlDescriptor'{streamMode = Mode,
+ reserveGroup = Group,
+ reserveValue = Value,
+ propertyParms = Props},
+ State) ->
+ #'LocalControlDescriptor'{streamMode = tr_opt_StreamMode(Mode, State),
+ reserveGroup = tr_opt_bool(Group, State),
+ reserveValue = tr_opt_bool(Value, State),
+ propertyParms = [tr_PropertyParm(P, State) || P <- Props]}.
+
+tr_opt_StreamMode(Mode, _State) ->
+ case Mode of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ sendOnly -> sendOnly;
+ recvOnly -> recvOnly;
+ sendRecv -> sendRecv;
+ inactive -> inactive;
+ loopBack -> loopBack
+ end.
+
+tr_Name(Name, State) ->
+ %% BUGBUG: transform
+ %% BUGBUG: NAME = ALPHA *63(ALPHA / DIGIT / "_" )
+ tr_STRING(Name, State, 2, 2).
+
+tr_PkgdName(Name, State) ->
+ %% BUGBUG: transform
+ %% BUGBUG: pkgdName = (NAME / "*") SLASH (ItemID / "*" )
+ tr_OCTET_STRING(Name, State, 4, 4).
+
+%% When text encoding the protocol, the descriptors consist of session
+%% descriptions as defined in SDP (RFC2327), except that the "s=", "t="
+%% and "o=" lines are optional. When multiple session descriptions are
+%% provided in one descriptor, the "v=" lines are required as delimiters;
+%% otherwise they are optional. Implementations shall accept session
+%% descriptions that are fully conformant to RFC2327. When binary
+%% encoding the protocol the descriptor consists of groups of properties
+%% (tag-value pairs) as specified in Annex C. Each such group may
+%% contain the parameters of a session description.
+tr_opt_LocalRemoteDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_LocalRemoteDescriptor(#'LocalRemoteDescriptor'{propGrps = Groups},
+ State) ->
+ #'LocalRemoteDescriptor'{propGrps = [tr_PropertyGroup(G, State) || G <- Groups]}.
+
+tr_PropertyGroup(Props, State) ->
+ [tr_PropertyGroupParm(P, State) || P <- Props].
+
+tr_PropertyGroupParm(#'PropertyParm'{name = Name,
+ value = Value},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'PropertyParm'{name = resolve(property, Name, State, Constraint),
+ value = tr_OCTET_STRING(Value, State, 0, infinity)}.
+
+tr_PropertyParm(#'PropertyParm'{name = Name,
+ value = Value,
+ extraInfo = Extra},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'PropertyParm'{name = resolve(property, Name, State, Constraint),
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_opt_extraInfo(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_extraInfo({relation, Rel}, _State) ->
+ Rel2 =
+ case Rel of
+ greaterThan -> greaterThan;
+ smallerThan -> smallerThan;
+ unequalTo -> unequalTo
+ end,
+ {relation, Rel2};
+tr_opt_extraInfo({range, Range}, State) ->
+ Range2 = tr_bool(Range, State),
+ {range, Range2};
+tr_opt_extraInfo({sublist, Sub}, State) ->
+ Sub2 = tr_bool(Sub, State),
+ {sublist, Sub2}.
+
+tr_opt_TerminationStateDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TerminationStateDescriptor(#'TerminationStateDescriptor'{propertyParms = Props,
+ eventBufferControl = Control,
+ serviceState = Service},
+ State) ->
+ #'TerminationStateDescriptor'{propertyParms = [tr_PropertyParm(P, State) || P <- Props],
+ eventBufferControl = tr_opt_EventBufferControl(Control, State),
+ serviceState = tr_opt_ServiceState(Service, State)}.
+
+tr_opt_EventBufferControl(Control, _State) ->
+ case Control of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ off -> off;
+ lockStep -> lockStep
+ end.
+
+tr_opt_ServiceState(Service, _State) ->
+ case Service of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ test -> test;
+ outOfSvc -> outOfSvc;
+ inSvc -> inSvc
+ end.
+
+tr_MuxDescriptor(#'MuxDescriptor'{muxType = Type,
+ termList = IdList},
+ State) ->
+ #'MuxDescriptor'{muxType = tr_MuxType(Type, State),
+ termList = [tr_TerminationID(Id, State) || Id <- IdList]}.
+
+tr_MuxType(Type, _State) ->
+ case Type of
+ h221 -> h221;
+ h223 -> h223;
+ h226 -> h226;
+ v76 -> v76
+ end.
+
+tr_opt_StreamID(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_StreamID(Id, State) ->
+ tr_StreamID(Id, State).
+
+tr_StreamID(Id, State) ->
+ tr_UINT16(Id, State).
+
+tr_EventsDescriptor(#'EventsDescriptor'{requestID = Id,
+ eventList = Events},
+ State) ->
+ #'EventsDescriptor'{requestID = tr_opt_RequestID(Id, State),
+ eventList = [tr_RequestedEvent(E, State) || E <- Events]}.
+
+tr_RequestedEvent(#'RequestedEvent'{pkgdName = Name,
+ streamID = Id,
+ evParList = Parms,
+ eventAction = Actions},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'RequestedEvent'{pkgdName = resolve(event, Name, State, Constraint),
+ streamID = tr_opt_StreamID(Id, State),
+ eventAction = tr_opt_RequestedActions(Actions, State),
+ evParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+tr_opt_RequestedActions(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_RequestedActions(#'RequestedActions'{keepActive = Keep,
+ eventDM = DM,
+ secondEvent = Event,
+ signalsDescriptor = SigDesc},
+ State) ->
+ #'RequestedActions'{keepActive = tr_opt_keepActive(Keep, State),
+ eventDM = tr_opt_EventDM(DM, State),
+ secondEvent = tr_opt_SecondEventsDescriptor(Event, State),
+ signalsDescriptor = tr_opt_SignalsDescriptor(SigDesc, State)}.
+
+tr_opt_keepActive(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_keepActive(Keep, State) ->
+ tr_bool(Keep, State).
+
+tr_opt_EventDM(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_EventDM({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ digitMapName -> tr_DigitMapName(Val, State);
+ digitMapValue -> tr_DigitMapValue(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_opt_SecondEventsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SecondEventsDescriptor(#'SecondEventsDescriptor'{requestID = Id,
+ eventList = Events},
+ State) ->
+ #'SecondEventsDescriptor'{requestID = tr_RequestID(Id, State), %% IG v6 6.8 withdrawn
+ eventList = [tr_SecondRequestedEvent(E, State) || E <- Events]}.
+
+tr_SecondRequestedEvent(#'SecondRequestedEvent'{pkgdName = Name,
+ streamID = Id,
+ evParList = Parms,
+ eventAction = Actions},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'SecondRequestedEvent'{pkgdName = resolve(event, Name, State, Constraint),
+ streamID = tr_opt_StreamID(Id, State),
+ eventAction = tr_opt_SecondRequestedActions(Actions, State),
+ evParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+
+tr_opt_SecondRequestedActions(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SecondRequestedActions(#'SecondRequestedActions'{keepActive = Keep,
+ eventDM = DM,
+ signalsDescriptor = SigDesc},
+ State) ->
+ #'SecondRequestedActions'{keepActive = tr_opt_keepActive(Keep, State),
+ eventDM = tr_opt_EventDM(DM, State),
+ signalsDescriptor = tr_opt_SignalsDescriptor(SigDesc, State)}.
+
+tr_EventBufferDescriptor(EventSpecs, State) ->
+ [tr_EventSpec(ES, State) || ES <- EventSpecs].
+
+tr_EventSpec(#'EventSpec'{eventName = Name,
+ streamID = Id,
+ eventParList = Parms},
+ State) ->
+ #'EventSpec'{eventName = tr_EventName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ eventParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+tr_opt_SignalsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SignalsDescriptor(SigDesc, State) ->
+ tr_SignalsDescriptor(SigDesc, State).
+
+tr_SignalsDescriptor(SigDesc, State) when is_list(SigDesc) ->
+ [tr_SignalRequest(SigReq, State) || SigReq <- SigDesc].
+
+tr_SignalRequest({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ signal -> tr_Signal(Val, State);
+ seqSigList -> tr_SeqSigList(Val, State)
+ end,
+ {Tag, Val2}.
+
+
+tr_SeqSigList(#'SeqSigList'{id = Id,
+ signalList = SigList},
+ State) when is_list(SigList) ->
+ #'SeqSigList'{id = tr_UINT16(Id, State),
+ signalList = [tr_Signal(Sig, State) || Sig <- SigList]}.
+
+tr_Signal(#'Signal'{signalName = Name,
+ streamID = Id,
+ sigType = Type,
+ duration = Dur,
+ notifyCompletion = Compl,
+ keepActive = Keep,
+ sigParList = Parms},
+ State) ->
+ #'Signal'{signalName = tr_SignalName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ sigType = tr_opt_SignalType(Type, State),
+ duration = tr_opt_duration(Dur, State),
+ notifyCompletion = tr_opt_NotifyCompletion(Compl, State),
+ keepActive = tr_opt_keepActive(Keep, State),
+ sigParList = [tr_SigParameter(P, Name, State) || P <- Parms]}.
+
+tr_opt_duration(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_duration(Dur, State) ->
+ tr_UINT16(Dur, State).
+
+tr_opt_NotifyCompletion(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_NotifyCompletion(Items, State) when is_list(Items) ->
+ [tr_notifyCompletionItem(I, State) || I <- Items].
+
+tr_notifyCompletionItem(Item, _State) ->
+ case Item of
+ onTimeOut -> onTimeOut;
+ onInterruptByEvent -> onInterruptByEvent;
+ onInterruptByNewSignalDescr -> onInterruptByNewSignalDescr;
+ otherReason -> otherReason
+ end.
+
+tr_opt_SignalType(Type, _State) ->
+ case Type of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ brief -> brief;
+ onOff -> onOff;
+ timeOut -> timeOut
+ end.
+
+tr_SignalName(Name, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ resolve(signal, Name, State, Constraint).
+
+tr_SigParameter(#'SigParameter'{sigParameterName = ParName,
+ value = Value,
+ extraInfo = Extra},
+ SigName,
+ State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ N = resolve({signal_parameter, SigName}, ParName, State, Constraint),
+ #'SigParameter'{sigParameterName = N,
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_opt_RequestID(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_RequestID(Id, State) ->
+ tr_RequestID(Id, State).
+
+tr_RequestID(Id, _State) when Id =:= ?megaco_all_request_id ->
+ ?megaco_all_request_id;
+tr_RequestID(Id, State) ->
+ tr_UINT32(Id, State).
+
+tr_ModemDescriptor(#'ModemDescriptor'{mtl = Types,
+ mpl = Props},
+ State) when is_list(Types) andalso is_list(Props) ->
+ %% BUGBUG: Does not handle extensionParameter
+ #'ModemDescriptor'{mtl = [tr_ModemType(T, State) || T <- Types],
+ mpl = [tr_PropertyParm(P, State) || P <- Props]}.
+
+tr_ModemType(Type, _State) ->
+ %% BUGBUG: Does not handle extensionParameter
+ case Type of
+ v18 -> v18;
+ v22 -> v22;
+ v22bis -> v22bis;
+ v32 -> v32;
+ v32bis -> v32bis;
+ v34 -> v34;
+ v90 -> v90;
+ v91 -> v91;
+ synchISDN -> synchISDN
+ end.
+
+tr_DigitMapDescriptor(#'DigitMapDescriptor'{digitMapName = Name,
+ digitMapValue = Value},
+ State) ->
+ #'DigitMapDescriptor'{digitMapName = tr_opt_DigitMapName(Name, State),
+ digitMapValue = tr_opt_DigitMapValue(Value, State)}.
+
+tr_opt_DigitMapName(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_DigitMapName(Name, State) ->
+ tr_DigitMapName(Name, State).
+
+tr_DigitMapName(Name, State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ resolve(dialplan, Name, State, Constraint).
+
+tr_opt_DigitMapValue(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_DigitMapValue(Value, State) ->
+ tr_DigitMapValue(Value, State).
+
+tr_DigitMapValue(#'DigitMapValue'{digitMapBody = Body,
+ startTimer = Start,
+ shortTimer = Short,
+ longTimer = Long},
+ State) ->
+ #'DigitMapValue'{startTimer = tr_opt_timer(Start, State),
+ shortTimer = tr_opt_timer(Short, State),
+ longTimer = tr_opt_timer(Long, State),
+ digitMapBody = tr_STRING(Body, State)}. %% BUGBUG: digitMapBody not handled at all
+
+tr_opt_timer(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_timer(Timer, State) ->
+ tr_DIGIT(Timer, State, 0, 99).
+
+tr_ServiceChangeParm(#'ServiceChangeParm'{serviceChangeMethod = Method,
+ serviceChangeAddress = Addr,
+ serviceChangeVersion = Version,
+ serviceChangeProfile = Profile,
+ serviceChangeReason = Reason,
+ serviceChangeDelay = Delay,
+ serviceChangeMgcId = MgcId,
+ timeStamp = Time},
+ State) ->
+ #'ServiceChangeParm'{serviceChangeMethod = tr_ServiceChangeMethod(Method, State),
+ serviceChangeAddress = tr_opt_ServiceChangeAddress(Addr, State),
+ serviceChangeVersion = tr_opt_serviceChangeVersion(Version, State),
+ serviceChangeProfile = tr_opt_ServiceChangeProfile(Profile, State),
+ serviceChangeReason = tr_serviceChangeReason(Reason, State),
+ serviceChangeDelay = tr_opt_serviceChangeDelay(Delay, State),
+ serviceChangeMgcId = tr_opt_serviceChangeMgcId(MgcId, State),
+ timeStamp = tr_opt_TimeNotation(Time, State)}.
+
+tr_ServiceChangeMethod(Method, _State) ->
+ case Method of
+ failover -> failover;
+ forced -> forced;
+ graceful -> graceful;
+ restart -> restart;
+ disconnected -> disconnected;
+ handOff -> handOff
+ end. %% BUGBUG: extension
+
+tr_opt_ServiceChangeAddress(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ServiceChangeAddress({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ portNumber -> tr_portNumber(Val, State);
+ ip4Address -> tr_IP4Address(Val, State);
+ ip6Address -> tr_IP6Address(Val, State);
+ domainName -> tr_DomainName(Val, State);
+ deviceName -> tr_PathName(Val, State);
+ mtpAddress -> tr_mtpAddress(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_opt_serviceChangeVersion(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeVersion(Version, State) ->
+ tr_version(Version, State).
+
+tr_opt_ServiceChangeProfile(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+%% Decode
+tr_opt_ServiceChangeProfile({'ServiceChangeProfile', ProfileName}, State) ->
+ case string:tokens(ProfileName, "/") of
+ [Name0, Version0] ->
+ Name = tr_STRING(Name0, State, 1, 64),
+ Version = tr_version(list_to_integer(Version0), State),
+ #'ServiceChangeProfile'{profileName = Name,
+ version = Version}
+ end;
+%% Encode
+tr_opt_ServiceChangeProfile(#'ServiceChangeProfile'{profileName = Name0,
+ version = Version0},
+ State) ->
+ Name = tr_STRING(Name0, State, 1, 64),
+ Version = tr_version(Version0, State),
+ ProfileName = lists:flatten(io_lib:format("~s/~w", [Name, Version])),
+ {'ServiceChangeProfile', ProfileName}.
+
+tr_serviceChangeReason([_] = Reason, State) ->
+ tr_Value(Reason, State).
+
+tr_opt_serviceChangeDelay(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeDelay(Delay, State) ->
+ tr_UINT32(Delay, State).
+
+tr_opt_serviceChangeMgcId(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeMgcId(MgcId, State) ->
+ tr_MId(MgcId, State).
+
+tr_opt_portNumber(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_portNumber(Port, State) ->
+ tr_portNumber(Port, State).
+
+tr_portNumber(Port, State) when is_integer(Port) andalso (Port >= 0) ->
+ tr_UINT16(Port, State).
+
+tr_ServiceChangeResParm(#'ServiceChangeResParm'{serviceChangeMgcId = MgcId,
+ serviceChangeAddress = Addr,
+ serviceChangeVersion = Version,
+ serviceChangeProfile = Profile,
+ timeStamp = Time},
+ State) ->
+ #'ServiceChangeResParm'{serviceChangeMgcId = tr_opt_serviceChangeMgcId(MgcId, State),
+ serviceChangeAddress = tr_opt_ServiceChangeAddress(Addr, State),
+ serviceChangeVersion = tr_opt_serviceChangeVersion(Version, State),
+ serviceChangeProfile = tr_opt_ServiceChangeProfile(Profile, State),
+ timeStamp = tr_opt_TimeNotation(Time, State)}.
+
+tr_PackagesDescriptor(Items, State) when is_list(Items) ->
+ [tr_PackagesItem(I, State) || I <- Items].
+
+tr_PackagesItem(#'PackagesItem'{packageName = Name,
+ packageVersion = Version},
+ State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ #'PackagesItem'{packageName = resolve(package, Name, State, Constraint),
+ packageVersion = tr_UINT16(Version, State)}.
+
+tr_StatisticsDescriptor(Parms, State) when is_list(Parms) ->
+ [tr_StatisticsParameter(P, State) || P <- Parms].
+
+tr_StatisticsParameter(#'StatisticsParameter'{statName = Name,
+ statValue = Value},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'StatisticsParameter'{statName = resolve(statistics, Name, State, Constraint),
+ statValue = tr_opt_Value(Value, State)}.
+
+tr_opt_TimeNotation(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TimeNotation(#'TimeNotation'{date = Date,
+ time = Time},
+ State) ->
+ #'TimeNotation'{date = tr_STRING(Date, State, 8, 8), % "yyyymmdd"
+ time = tr_STRING(Time, State, 8, 8)}.% "hhmmssss"
+
+%% BUGBUG: Does not verify that string must contain at least one char
+%% BUGBUG: This violation of the is required in order to comply with
+%% BUGBUG: the dd/ce ds parameter that may possibly be empty.
+
+tr_opt_Value(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_Value(Value, State) ->
+ tr_Value(Value, State).
+
+tr_Value(Strings, _State) when is_list(Strings) ->
+ [[Char || Char <- String] || String <- Strings].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Encode an octet string, escape } by \ if necessary
+tr_OCTET_STRING(String, _State, Min, Max) when is_list(String) ->
+ verify_count(length(String), Min, Max),
+ String.
+
+tr_QUOTED_STRING(String, _State) when is_list(String) ->
+ verify_count(length(String), 1, infinity),
+ String.
+
+%% The internal format of hex digits is a list of octets
+%% Min and Max means #hexDigits
+%% Leading zeros are prepended in order to fulfill Min
+tr_HEXDIG(Octets, _State, Min, Max) when is_list(Octets) ->
+ verify_count(length(Octets), Min, Max),
+ Octets.
+
+tr_DIGIT(Val, State, Min, Max) ->
+ tr_integer(Val, State, Min, Max).
+
+tr_STRING(String, _State) when is_list(String) ->
+ String.
+
+tr_STRING(String, _State, Min, Max) when is_list(String) ->
+ verify_count(length(String), Min, Max),
+ String.
+
+tr_UINT16(Val, State) ->
+ tr_integer(Val, State, 0, 65535).
+
+tr_UINT32(Val, State) ->
+ tr_integer(Val, State, 0, 4294967295).
+
+tr_integer(Int, _State, Min, Max) ->
+ verify_count(Int, Min, Max),
+ Int.
+
+%% Verify that Count is within the range of Min and Max
+verify_count(Count, Min, Max) ->
+ if
+ is_integer(Count) ->
+ if
+ is_integer(Min) andalso (Count >= Min) ->
+ if
+ is_integer(Max) andalso (Count =< Max) ->
+ Count;
+ Max =:= infinity ->
+ Count;
+ true ->
+ ?error({count_too_large, Count, Max})
+ end;
+ true ->
+ ?error({count_too_small, Count, Min})
+ end;
+ true ->
+ ?error({count_not_an_integer, Count})
+ end.
+
+
+% i(F,A) ->
+% %% i(true,F,A).
+% i(get(dbg),F,A).
+
+% i(true,F,A) ->
+% S1 = io_lib:format("TRANSF-v1: " ++ F ++ "~n",A),
+% S2 = lists:flatten(S1),
+% io:format("~s",[S2]);
+% i(_,_F,_A) ->
+% ok.
diff --git a/lib/megaco/src/binary/megaco_binary_transformer_v2.erl b/lib/megaco/src/binary/megaco_binary_transformer_v2.erl
new file mode 100644
index 0000000000..686e384a29
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_transformer_v2.erl
@@ -0,0 +1,1544 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Transform internal form of Megaco/H.248 messages
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_transformer_v2).
+
+-include_lib("megaco/include/megaco.hrl").
+%% -include_lib("megaco/include/megaco_message.hrl").
+-include_lib("megaco/include/megaco_message_v2.hrl").
+
+-export([tr_message/3, tr_transaction/3]).
+
+-define(DEFAULT_NAME_RESOLVER,megaco_binary_name_resolver_v2).
+-define(error(R), erlang:error({error, R})).
+
+-record(state, {mode, % verify | encode | decode
+ resolver_module, %
+ resolver_options}).
+
+resolve(Type, Item, State, Constraint) ->
+ case State#state.mode of
+ verify ->
+ Item;
+ encode ->
+ %% i("resolve(encode) -> encode: ~p",[Item]),
+ Mod = State#state.resolver_module,
+ Opt = State#state.resolver_options,
+ EncodedItem = Mod:encode_name(Opt, Type, Item),
+ %% i("resolve -> verify contraint for ~p",[EncodedItem]),
+ verify_constraint(EncodedItem, Constraint);
+ decode ->
+ %% i("resolve(decode) -> verify contraint for ~p",[Item]),
+ DecodedItem = verify_constraint(Item, Constraint),
+ Mod = State#state.resolver_module,
+ Opt = State#state.resolver_options,
+ %% i("resolve(decode) -> decode: ~p",[DecodedItem]),
+ Mod:decode_name(Opt, Type, DecodedItem)
+ end.
+
+verify_constraint(Item, valid) ->
+ Item;
+verify_constraint(Item, Constraint) when is_function(Constraint) ->
+ Constraint(Item).
+
+tr_message(MegaMsg, Mode, Config) ->
+ case Config of
+ [native] ->
+ MegaMsg;
+ [verify] ->
+ State = #state{mode = verify},
+ tr_MegacoMessage(MegaMsg, State);
+ [] ->
+ State = #state{mode = Mode,
+ resolver_module = ?DEFAULT_NAME_RESOLVER,
+ resolver_options = [8, 8, 8]},
+ tr_MegacoMessage(MegaMsg, State);
+ [{binary_name_resolver, {Module, Options}}] when is_atom(Module) ->
+ State = #state{mode = Mode,
+ resolver_module = Module,
+ resolver_options = Options},
+ tr_MegacoMessage(MegaMsg, State)
+ end.
+
+tr_transaction(Trans, Mode, Config) ->
+ case Config of
+ [native] ->
+ Trans;
+ [verify] ->
+ State = #state{mode = verify},
+ tr_Transaction(Trans, State);
+ [] ->
+ State = #state{mode = Mode,
+ resolver_module = ?DEFAULT_NAME_RESOLVER,
+ resolver_options = [8, 8, 8]},
+ tr_Transaction(Trans, State);
+ [{binary_name_resolver, {Module, Options}}] when is_atom(Module) ->
+ State = #state{mode = Mode,
+ resolver_module = Module,
+ resolver_options = Options},
+ tr_Transaction(Trans, State)
+ end.
+
+tr_MegacoMessage(#'MegacoMessage'{authHeader = Auth,
+ mess = Mess},
+ State) ->
+% i("tr_MegacoMessage -> entry with"
+% "~n Auth: ~p"
+% "~n Mess: ~p"
+% "~n State: ~p", [Auth, Mess, State]),
+ #'MegacoMessage'{authHeader = tr_opt_AuthenticationHeader(Auth, State),
+ mess = tr_Message(Mess, State)}.
+
+tr_opt_AuthenticationHeader(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_AuthenticationHeader(#'AuthenticationHeader'{secParmIndex = SPI,
+ seqNum = SN,
+ ad = AuthData},
+ State) ->
+ #'AuthenticationHeader'{secParmIndex = tr_SecurityParmIndex(SPI, State),
+ seqNum = tr_SequenceNum(SN, State),
+ ad = tr_AuthData(AuthData, State)}.
+
+tr_SecurityParmIndex(SPI, State) ->
+ tr_HEXDIG(SPI, State, 4, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_SequenceNum(SN, State) ->
+ tr_HEXDIG(SN, State, 4, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_AuthData(AuthData, State) ->
+ tr_HEXDIG(AuthData, State, 12, 32). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_Message(#'Message'{version = Version,
+ mId = MID,
+ messageBody = Body},
+ State) ->
+ #'Message'{version = tr_version(Version, State),
+ mId = tr_MId(MID, State),
+ messageBody = tr_Message_messageBody(Body, State)}.
+
+tr_version(Version, State) ->
+ tr_DIGIT(Version, State, 0, 99).
+
+tr_Message_messageBody({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ messageError -> tr_ErrorDescriptor(Val, State);
+ transactions when is_list(Val) -> [tr_Transaction(T, State) || T <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_MId({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ ip4Address -> tr_IP4Address(Val, State);
+ ip6Address -> tr_IP6Address(Val, State);
+ domainName -> tr_DomainName(Val, State);
+ deviceName -> tr_PathName(Val, State);
+ mtpAddress -> tr_mtpAddress(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_mtpAddress(MtpAddr, State) ->
+ tr_OCTET_STRING(MtpAddr, State, 2, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_DomainName(#'DomainName'{name = Name,
+ portNumber = Port},
+ State) ->
+ Domain = #'DomainName'{name = tr_STRING(Name, State), % BUGBUG: Mismatch between ASN.1 and ABNF
+ portNumber = tr_opt_portNumber(Port, State)},
+ {domainName, Domain2} = resolve(mid, {domainName, Domain}, State, valid),
+ Domain2.
+
+tr_IP4Address(#'IP4Address'{address = [A1, A2, A3, A4],
+ portNumber = Port},
+ State) ->
+ #'IP4Address'{address = [tr_V4hex(A1, State),
+ tr_V4hex(A2, State),
+ tr_V4hex(A3, State),
+ tr_V4hex(A4, State)],
+ portNumber = tr_opt_portNumber(Port, State)}.
+
+tr_V4hex(Val, State) ->
+ tr_DIGIT(Val, State, 0, 255).
+
+tr_IP6Address(_Val, _State) ->
+ ?error(ipv6_not_supported). %% BUGBUG: nyi
+
+tr_PathName(Path, State) ->
+ %% BUGBUG: ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
+ %% BUGBUG: ["@" pathDomainName ]
+ Constraint = fun({deviceName, Item}) -> tr_STRING(Item, State, 1, 64) end,
+ resolve(mid, {deviceName, Path}, State, Constraint).
+
+tr_Transaction({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ transactionRequest -> tr_TransactionRequest(Val, State);
+ transactionPending -> tr_TransactionPending(Val, State);
+ transactionReply -> tr_TransactionReply(Val, State);
+ transactionResponseAck -> [tr_TransactionAck(T, State) || T <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_TransactionAck(#'TransactionAck'{firstAck = First,
+ lastAck = Last},
+ State) ->
+ #'TransactionAck'{firstAck = tr_TransactionId(First, State),
+ lastAck = tr_opt_TransactionId(Last, State)}.
+
+tr_opt_TransactionId(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TransactionId(Id, State) ->
+ tr_TransactionId(Id, State).
+
+tr_TransactionId(Id, State) ->
+ tr_UINT32(Id, State).
+
+tr_TransactionRequest(#'TransactionRequest'{transactionId = Id,
+ actions = Actions},
+ State) when is_list(Actions) ->
+
+ #'TransactionRequest'{transactionId = tr_TransactionId(Id, State),
+ actions = [tr_ActionRequest(ActReq, State) || ActReq <- Actions]}.
+
+tr_TransactionPending(#'TransactionPending'{transactionId = Id},
+ State) ->
+ #'TransactionPending'{transactionId = tr_TransactionId(Id, State)}.
+
+tr_TransactionReply(#'TransactionReply'{transactionId = Id,
+ immAckRequired = ImmAck,
+ transactionResult = TransRes},
+ State) ->
+ #'TransactionReply'{transactionId = tr_TransactionId(Id, State),
+ immAckRequired = tr_opt_null(ImmAck, State),
+ transactionResult = tr_TransactionReply_transactionResult(TransRes, State)}.
+
+tr_opt_null(asn1_NOVALUE, _State) -> asn1_NOVALUE;
+tr_opt_null('NULL', _State) -> 'NULL'.
+
+tr_TransactionReply_transactionResult({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ transactionError ->
+ tr_ErrorDescriptor(Val, State);
+ actionReplies when is_list(Val) andalso (Val =/= []) ->
+ [tr_ActionReply(ActRep, State) || ActRep <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_opt_ErrorDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ErrorDescriptor(ErrDesc, State) ->
+ tr_ErrorDescriptor(ErrDesc, State).
+
+tr_ErrorDescriptor(#'ErrorDescriptor'{errorCode = Code,
+ errorText = Text},
+ State) ->
+ #'ErrorDescriptor'{errorCode = tr_ErrorCode(Code, State),
+ errorText = tr_opt_ErrorText(Text, State)}.
+
+tr_ErrorCode(Code, State) ->
+ tr_DIGIT(Code, State, 0, 999).
+
+tr_opt_ErrorText(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ErrorText(Text, State) ->
+ tr_QUOTED_STRING(Text, State).
+
+tr_ContextID(CtxId, State) ->
+ case CtxId of
+ ?megaco_all_context_id -> ?megaco_all_context_id;
+ ?megaco_null_context_id -> ?megaco_null_context_id;
+ ?megaco_choose_context_id -> ?megaco_choose_context_id;
+ Int when is_integer(Int) -> tr_UINT32(Int, State)
+ end.
+
+tr_ActionRequest(#'ActionRequest'{contextId = CtxId,
+ contextRequest = CtxReq,
+ contextAttrAuditReq = CtxAuditReq,
+ commandRequests = CmdReqList},
+ State) ->
+ #'ActionRequest'{contextId = tr_ContextID(CtxId, State),
+ contextRequest = tr_opt_ContextRequest(CtxReq, State),
+ contextAttrAuditReq = tr_opt_ContextAttrAuditRequest(CtxAuditReq, State),
+ commandRequests = [tr_CommandRequest(CmdReq, State) || CmdReq <- CmdReqList]}.
+
+tr_ActionReply(#'ActionReply'{contextId = CtxId,
+ errorDescriptor = ErrDesc,
+ contextReply = CtxRep,
+ commandReply = CmdRepList},
+ State) ->
+ CmdRepList2 = [tr_CommandReply(CmdRep, State) || CmdRep <- CmdRepList],
+ #'ActionReply'{contextId = tr_ContextID(CtxId, State),
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State),
+ contextReply = tr_opt_ContextRequest(CtxRep, State),
+ commandReply = CmdRepList2}.
+
+tr_opt_ContextRequest(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ContextRequest(#'ContextRequest'{priority = Prio,
+ emergency = Em,
+ topologyReq = TopReqList},
+ State) ->
+ Prio2 =
+ case Prio of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_integer(Prio, State, 0, 15)
+ end,
+ Em2 =
+ case Em of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ TopReqList2 =
+ case TopReqList of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_TopologyRequest(TopReq, State) ||
+ TopReq <- TopReqList]
+ end,
+ #'ContextRequest'{priority = Prio2,
+ emergency = Em2,
+ topologyReq = TopReqList2}.
+
+tr_opt_ContextAttrAuditRequest(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ContextAttrAuditRequest(#'ContextAttrAuditRequest'{topology = Top,
+ emergency = Em,
+ priority = Prio},
+ State) ->
+ #'ContextAttrAuditRequest'{topology = tr_opt_null(Top, State),
+ emergency = tr_opt_null(Em, State),
+ priority = tr_opt_null(Prio, State)}.
+
+tr_CommandRequest(#'CommandRequest'{command = Cmd,
+ optional = Opt,
+ wildcardReturn = Wild},
+ State) ->
+ #'CommandRequest'{optional = tr_opt_null(Opt, State),
+ wildcardReturn = tr_opt_null(Wild, State),
+ command = tr_Command(Cmd, State)}.
+
+tr_Command({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ addReq -> tr_AmmRequest(Val, State);
+ moveReq -> tr_AmmRequest(Val, State);
+ modReq -> tr_AmmRequest(Val, State);
+ subtractReq -> tr_SubtractRequest(Val, State);
+ auditCapRequest -> tr_AuditRequest(Val, State);
+ auditValueRequest -> tr_AuditRequest(Val, State);
+ notifyReq -> tr_NotifyRequest(Val, State);
+ serviceChangeReq -> tr_ServiceChangeRequest(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_CommandReply({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ addReply -> tr_AmmsReply(Val, State);
+ moveReply -> tr_AmmsReply(Val, State);
+ modReply -> tr_AmmsReply(Val, State);
+ subtractReply -> tr_AmmsReply(Val, State);
+ auditCapReply -> tr_AuditReply(Val, State);
+ auditValueReply -> tr_AuditReply(Val, State);
+ notifyReply -> tr_NotifyReply(Val, State);
+ serviceChangeReply -> tr_ServiceChangeReply(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_TopologyRequest(#'TopologyRequest'{terminationFrom = From,
+ terminationTo = To,
+ topologyDirection = Dir},
+ State) ->
+ Dir2 =
+ case Dir of
+ bothway -> bothway;
+ isolate -> isolate;
+ oneway -> oneway
+ end,
+ #'TopologyRequest'{terminationFrom = tr_TerminationID(From, State),
+ terminationTo = tr_TerminationID(To, State),
+ topologyDirection = Dir2}.
+
+tr_AmmRequest(#'AmmRequest'{terminationID = IdList,
+ descriptors = DescList},
+ State) ->
+ #'AmmRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ descriptors = tr_ammDescriptors(DescList, [], State)}.
+
+tr_ammDescriptors([], Acc, _State) ->
+ lists:reverse(Acc);
+tr_ammDescriptors([Desc|Descs], Acc, State) ->
+ case tr_ammDescriptor(Desc, State) of
+ {_, deprecated} when State#state.mode =:= encode ->
+ ?error({deprecated, Desc});
+ {_, deprecated} when State#state.mode =:= decode ->
+ %% SKIP
+ tr_ammDescriptors(Descs, Acc, State);
+ {_, deprecated} ->
+ %% SKIP
+ tr_ammDescriptors(Descs, Acc, State);
+ NewDesc ->
+ tr_ammDescriptors(Descs, [NewDesc|Acc], State)
+ end.
+
+tr_ammDescriptor({Tag, Desc}, State) ->
+ Desc2 =
+ case Tag of
+ mediaDescriptor -> tr_MediaDescriptor(Desc, State);
+ modemDescriptor -> tr_ModemDescriptor(Desc, State);
+ muxDescriptor -> tr_MuxDescriptor(Desc, State);
+ eventsDescriptor -> tr_EventsDescriptor(Desc, State);
+ eventBufferDescriptor -> tr_EventBufferDescriptor(Desc, State);
+ signalsDescriptor -> tr_SignalsDescriptor(Desc, State);
+ digitMapDescriptor -> tr_DigitMapDescriptor(Desc, State);
+ auditDescriptor -> tr_AuditDescriptor(Desc, State)
+ end,
+ {Tag, Desc2}.
+
+tr_AmmsReply(#'AmmsReply'{terminationID = IdList,
+ terminationAudit = TermAudit},
+ State) ->
+ TermAudit2 =
+ case TermAudit of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_TerminationAudit(TermAudit, State)
+ end,
+ #'AmmsReply'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ terminationAudit = TermAudit2}.
+
+tr_SubtractRequest(#'SubtractRequest'{terminationID = IdList,
+ auditDescriptor = Desc},
+ State) ->
+ #'SubtractRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ auditDescriptor = tr_opt_AuditDescriptor(Desc, State)}.
+
+tr_AuditRequest(#'AuditRequest'{terminationID = Id,
+ auditDescriptor = Desc},
+ State) ->
+ #'AuditRequest'{terminationID = tr_TerminationID(Id, State),
+ auditDescriptor = tr_AuditDescriptor(Desc, State)}.
+
+%% auditReply = (AuditValueToken / AuditCapToken )
+%% ( contextTerminationAudit / auditOther)
+%% auditOther = EQUAL TerminationID LBRKT
+%% terminationAudit RBRKT
+%% terminationAudit = auditReturnParameter *(COMMA auditReturnParameter)
+%%
+%% contextTerminationAudit = EQUAL CtxToken ( terminationIDList /
+%% LBRKT errorDescriptor RBRKT )
+
+tr_AuditReply({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ contextAuditResult ->
+ [tr_TerminationID(Id, State) || Id <- Val];
+ error ->
+ tr_ErrorDescriptor(Val, State);
+ auditResult ->
+ tr_AuditResult(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_AuditResult(#'AuditResult'{terminationID = Id,
+ terminationAuditResult = AuditRes},
+ State) ->
+ #'AuditResult'{terminationID = tr_TerminationID(Id, State),
+ terminationAuditResult = tr_TerminationAudit(AuditRes, State)}.
+
+tr_opt_AuditDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_AuditDescriptor(Desc, State) ->
+ tr_AuditDescriptor(Desc, State).
+
+%% BUGBUG BUGBUG BUGBUG
+%% With this construction it is possible to have both auditToken
+%% and auditPropertyToken, but it is actually valid?
+tr_AuditDescriptor(#'AuditDescriptor'{auditToken = Tokens,
+ auditPropertyToken = APTs},
+ State) ->
+ Tokens2 =
+ case Tokens of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_auditItem(Token, State) || Token <- Tokens]
+ end,
+ %% v2
+ APTs2 =
+ case APTs of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ [tr_indAuditParameter(APT, State) || APT <- APTs]
+ end,
+ #'AuditDescriptor'{auditToken = Tokens2,
+ auditPropertyToken = APTs2}.
+
+tr_auditItem(Token, _State) ->
+ case Token of
+ muxToken -> muxToken;
+ modemToken -> modemToken;
+ mediaToken -> mediaToken;
+ eventsToken -> eventsToken;
+ signalsToken -> signalsToken;
+ digitMapToken -> digitMapToken;
+ statsToken -> statsToken;
+ observedEventsToken -> observedEventsToken;
+ packagesToken -> packagesToken;
+ eventBufferToken -> eventBufferToken
+ end.
+
+%% --- v2 begin ---
+
+tr_indAuditParameter({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ indAudMediaDescriptor ->
+ tr_indAudMediaDescriptor(Val, State);
+ indAudEventsDescriptor ->
+ tr_indAudEventsDescriptor(Val, State);
+ indAudSignalsDescriptor ->
+ tr_indAudSignalsDescriptor(Val, State);
+ indAudDigitMapDescriptor ->
+ tr_indAudDigitMapDescriptor(Val, State);
+ indAudEventBufferDescriptor ->
+ tr_indAudEventBufferDescriptor(Val, State);
+ indAudStatisticsDescriptor ->
+ tr_indAudStatisticsDescriptor(Val, State);
+ indAudPackagesDescriptor ->
+ tr_indAudPackagesDescriptor(Val, State)
+ end,
+ {Tag, Val2}.
+
+
+%% -
+
+tr_indAudMediaDescriptor(#'IndAudMediaDescriptor'{termStateDescr = TSD,
+ streams = S},
+ State) ->
+ TSD2 =
+ case TSD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudTerminationStateDescriptor(TSD, State)
+ end,
+ S2 =
+ case S of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ {oneStream, OS} ->
+ {oneStream, tr_indAudStreamParms(OS, State)};
+ {multiStream, MS} ->
+ MS2 = [tr_indAudStreamDescriptor(MS1, State) || MS1 <- MS],
+ {multiStream, MS2}
+ end,
+ #'IndAudMediaDescriptor'{termStateDescr = TSD2,
+ streams = S2}.
+
+tr_indAudTerminationStateDescriptor(Val, State)
+ when is_record(Val, 'IndAudTerminationStateDescriptor') ->
+ #'IndAudTerminationStateDescriptor'{propertyParms = Parms,
+ eventBufferControl = EBC,
+ serviceState = SS} = Val,
+ Parms2 = [tr_indAudPropertyParm(Parm, State) || Parm <- Parms],
+ EBC2 = tr_opt_null(EBC, State),
+ SS2 = tr_opt_null(SS, State),
+ #'IndAudTerminationStateDescriptor'{propertyParms = Parms2,
+ eventBufferControl = EBC2,
+ serviceState = SS2}.
+
+
+tr_indAudStreamParms(#'IndAudStreamParms'{localControlDescriptor = LCD,
+ localDescriptor = LD,
+ remoteDescriptor = RD},
+ State) ->
+ LCD2 =
+ case LCD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalControlDescriptor(LCD, State)
+ end,
+ LD2 =
+ case LD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalRemoteDescriptor(LD, State)
+ end,
+ RD2 =
+ case RD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalRemoteDescriptor(RD, State)
+ end,
+ #'IndAudStreamParms'{localControlDescriptor = LCD2,
+ localDescriptor = LD2,
+ remoteDescriptor = RD2}.
+
+tr_indAudLocalControlDescriptor(Val, State)
+ when is_record(Val, 'IndAudLocalControlDescriptor') ->
+ #'IndAudLocalControlDescriptor'{streamMode = M,
+ reserveValue = V,
+ reserveGroup = G,
+ propertyParms = P} = Val,
+ M2 = tr_opt_null(M, State),
+ V2 = tr_opt_null(V, State),
+ G2 = tr_opt_null(G, State),
+ P2 = tr_indAudLocalControlDescriptor_propertyParms(P, State),
+ #'IndAudLocalControlDescriptor'{streamMode = M2,
+ reserveValue = V2,
+ reserveGroup = G2,
+ propertyParms = P2}.
+
+tr_indAudLocalControlDescriptor_propertyParms(Parms, State)
+ when is_list(Parms) andalso (length(Parms) > 0) ->
+ [tr_indAudPropertyParm(Parm, State) || Parm <- Parms];
+tr_indAudLocalControlDescriptor_propertyParms(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE.
+
+tr_indAudLocalRemoteDescriptor(#'IndAudLocalRemoteDescriptor'{propGroupID = ID,
+ propGrps = Grps},
+ State) ->
+ #'IndAudLocalRemoteDescriptor'{propGroupID = tr_opt_UINT16(ID, State),
+ propGrps = tr_indAudPropertyGroup(Grps,
+ State)}.
+
+tr_indAudPropertyGroup(Grps, State) when is_list(Grps) ->
+ [tr_indAudPropertyParm(Parm, State) || Parm <- Grps].
+
+tr_indAudPropertyParm(#'IndAudPropertyParm'{name = Name0}, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(property, Name0, State, Constraint),
+ #'IndAudPropertyParm'{name = Name}.
+
+
+tr_indAudStreamDescriptor(#'IndAudStreamDescriptor'{streamID = ID,
+ streamParms = Parms},
+ State) ->
+ #'IndAudStreamDescriptor'{streamID = tr_StreamID(ID, State),
+ streamParms = tr_indAudStreamParms(Parms,
+ State)}.
+
+
+%% -
+
+tr_indAudEventsDescriptor(#'IndAudEventsDescriptor'{requestID = RID,
+ pkgdName = Name0,
+ streamID = SID},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(event, Name0, State, Constraint),
+ #'IndAudEventsDescriptor'{requestID = tr_opt_RequestID(RID, State),
+ pkgdName = Name,
+ streamID = tr_opt_StreamID(SID, State)}.
+
+
+%% -
+
+tr_indAudSignalsDescriptor({Tag, Val}, State) ->
+ case Tag of
+ signal ->
+ {signal, tr_indAudSignal(Val, State)};
+ seqSigList ->
+ {seqSigList, tr_indAudSeqSigList(Val, State)}
+ end.
+
+tr_opt_indAudSignal(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_indAudSignal(Val, State) ->
+ tr_indAudSignal(Val, State).
+
+tr_indAudSignal(#'IndAudSignal'{signalName = Name0,
+ streamID = SID}, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(signal, Name0, State, Constraint),
+ #'IndAudSignal'{signalName = Name,
+ streamID = tr_opt_StreamID(SID, State)}.
+
+tr_indAudSeqSigList(#'IndAudSeqSigList'{id = ID,
+ signalList = SigList}, State) ->
+ #'IndAudSeqSigList'{id = tr_integer(ID, State, 0, 65535),
+ signalList = tr_opt_indAudSignal(SigList, State)}.
+
+%% -
+
+tr_indAudDigitMapDescriptor(#'IndAudDigitMapDescriptor'{digitMapName = Name},
+ State) ->
+ #'IndAudDigitMapDescriptor'{digitMapName =
+ tr_opt_DigitMapName(Name, State)}.
+
+
+%% -
+
+tr_indAudEventBufferDescriptor(#'IndAudEventBufferDescriptor'{eventName = N,
+ streamID = SID},
+ State) ->
+% i("tr_indAudEventBufferDescriptor -> entry with"
+% "~n N: ~p"
+% "~n SID: ~p", [N, SID]),
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(event, N, State, Constraint),
+% i("tr_indAudEventBufferDescriptor -> entry with"
+% "~n Name: ~p", [Name]),
+ #'IndAudEventBufferDescriptor'{eventName = Name,
+ streamID = tr_opt_StreamID(SID, State)}.
+
+%% -
+
+tr_indAudStatisticsDescriptor(#'IndAudStatisticsDescriptor'{statName = N},
+ State) ->
+% i("tr_indAudEventBufferDescriptor -> entry with"
+% "~n N: ~p"
+% "~n SID: ~p", [N, SID]),
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(statistics, N, State, Constraint),
+ #'IndAudStatisticsDescriptor'{statName = Name}.
+
+
+%% -
+
+tr_indAudPackagesDescriptor(#'IndAudPackagesDescriptor'{packageName = N,
+ packageVersion = V},
+ State) ->
+% i("tr_indAudPackagesDescriptor -> entry with"
+% "~n N: ~p"
+% "~n V: ~p", [N, V]),
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ Name = resolve(package, N, State, Constraint),
+% i("tr_indAudPackagesDescriptor -> entry with"
+% "~n Name: ~p", [Name]),
+ #'IndAudPackagesDescriptor'{packageName = Name,
+ packageVersion = tr_integer(V, State, 0, 99)}.
+
+%% -- v2 end --
+
+
+tr_TerminationAudit(ParmList, State) when is_list(ParmList) ->
+ do_tr_TerminationAudit(ParmList, [], State).
+
+do_tr_TerminationAudit([], Acc, _State) ->
+ lists:reverse(Acc);
+do_tr_TerminationAudit([Parm|ParmList], Acc, State) ->
+ case tr_AuditReturnParameter(Parm, State) of
+ {_, deprecated} when State#state.mode =:= encode ->
+ ?error({deprecated, Parm});
+ {_, deprecated} when State#state.mode =:= decode ->
+ %% SKIP
+ do_tr_TerminationAudit(ParmList, Acc, State);
+ {_, deprecated} ->
+ %% SKIP
+ do_tr_TerminationAudit(ParmList, Acc, State);
+ NewParm ->
+ do_tr_TerminationAudit(ParmList, [NewParm|Acc], State)
+ end.
+
+tr_AuditReturnParameter({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ errorDescriptor ->
+ tr_ErrorDescriptor(Val, State);
+ mediaDescriptor ->
+ tr_MediaDescriptor(Val, State);
+ modemDescriptor ->
+ tr_ModemDescriptor(Val, State);
+ muxDescriptor ->
+ tr_MuxDescriptor(Val, State);
+ eventsDescriptor ->
+ tr_EventsDescriptor(Val, State);
+ eventBufferDescriptor ->
+ tr_EventBufferDescriptor(Val, State);
+ signalsDescriptor ->
+ tr_SignalsDescriptor(Val, State);
+ digitMapDescriptor ->
+ tr_DigitMapDescriptor(Val, State);
+ observedEventsDescriptor ->
+ tr_ObservedEventsDescriptor(Val, State);
+ statisticsDescriptor ->
+ tr_StatisticsDescriptor(Val, State);
+ packagesDescriptor ->
+ tr_PackagesDescriptor(Val, State);
+ emptyDescriptors ->
+ tr_EmptyDescriptors(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_EmptyDescriptors(#'AuditDescriptor'{auditToken = Tokens},
+ State) ->
+ case Tokens of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_auditItem(Token, State) || Token <- Tokens]
+ end.
+
+tr_NotifyRequest(#'NotifyRequest'{terminationID = IdList,
+ observedEventsDescriptor = ObsDesc,
+ errorDescriptor = ErrDesc},
+ State) ->
+ %% BUGBUG: Mismatch between ASN.1 and ABNF
+ %% BUGBUG: The following ought to be a 'choice'
+ #'NotifyRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ observedEventsDescriptor = tr_ObservedEventsDescriptor(ObsDesc, State),
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State)}.
+
+tr_NotifyReply(#'NotifyReply'{terminationID = IdList,
+ errorDescriptor = ErrDesc},
+ State) ->
+ #'NotifyReply'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State)}.
+
+tr_ObservedEventsDescriptor(#'ObservedEventsDescriptor'{requestId = Id,
+ observedEventLst = Events},
+ State) when is_list(Events) ->
+ #'ObservedEventsDescriptor'{requestId = tr_RequestID(Id, State),
+ observedEventLst = [tr_ObservedEvent(E, State) || E <- Events]}.
+
+%% ;time per event, because it might be buffered
+%% observedEvent = [ TimeStamp LWSP COLON] LWSP
+%% pkgdName [ LBRKT observedEventParameter
+%% *(COMMA observedEventParameter) RBRKT ]
+%%
+%% ;at-most-once eventStream, every eventParameterName at most once
+%% observedEventParameter = eventStream / eventOther
+
+tr_ObservedEvent(#'ObservedEvent'{eventName = Name,
+ streamID = Id,
+ eventParList = Parms,
+ timeNotation = Time},
+ State) ->
+ #'ObservedEvent'{eventName = tr_EventName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ eventParList = [tr_EventParameter(P, Name, State) || P <- Parms],
+ timeNotation = tr_opt_TimeNotation(Time, State)}.
+
+tr_EventName(Name, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ resolve(event, Name, State, Constraint).
+
+tr_EventParameter(#'EventParameter'{eventParameterName = ParName,
+ value = Value,
+ extraInfo = Extra},
+ EventName,
+ State) ->
+ %% BUGBUG: event parameter name
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ N = resolve({event_parameter, EventName}, ParName, State, Constraint),
+ #'EventParameter'{eventParameterName = N,
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_ServiceChangeRequest(#'ServiceChangeRequest'{terminationID = IdList,
+ serviceChangeParms = Parms},
+ State) ->
+ #'ServiceChangeRequest'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ serviceChangeParms = tr_ServiceChangeParm(Parms, State)}.
+
+%% serviceChangeReply = ServiceChangeToken EQUAL TerminationID
+%% [LBRKT (errorDescriptor /
+%% serviceChangeReplyDescriptor) RBRKT]
+%% serviceChangeReplyDescriptor = ServicesToken LBRKT
+%% servChgReplyParm *(COMMA servChgReplyParm) RBRKT
+%%
+%% ;at-most-once. Version is REQUIRED on first ServiceChange response
+%% servChgReplyParm = (serviceChangeAddress / serviceChangeMgcId /
+%% serviceChangeProfile / serviceChangeVersion )
+tr_ServiceChangeReply(#'ServiceChangeReply'{terminationID = IdList,
+ serviceChangeResult = Res},
+ State) ->
+ #'ServiceChangeReply'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ serviceChangeResult = tr_ServiceChangeResult(Res, State)}.
+
+tr_ServiceChangeResult({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ errorDescriptor -> tr_ErrorDescriptor(Val, State);
+ serviceChangeResParms -> tr_ServiceChangeResParm(Val, State)
+ end,
+ {Tag, Val2}.
+
+%% TerminationID = "ROOT" / pathNAME / "$" / "*"
+%% ; Total length of pathNAME must not exceed 64 chars.
+%% pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
+%% ["@" pathDomainName ]
+
+tr_TerminationID(TermId, State) when State#state.mode =/= verify ->
+ resolve(term_id, TermId, State, valid);
+tr_TerminationID(#'TerminationID'{wildcard = Wild,
+ id = Id},
+ _State) ->
+ #'TerminationID'{wildcard = Wild,
+ id = Id};
+tr_TerminationID(#megaco_term_id{contains_wildcards = IsWild,
+ id = Id},
+ State) ->
+ #megaco_term_id{contains_wildcards = tr_bool(IsWild, State),
+ id = [tr_term_id_component(Sub, State) || Sub <- Id]}.
+
+tr_opt_bool(asn1_NOVALUE, _State) -> asn1_NOVALUE;
+tr_opt_bool(Bool, State) -> tr_bool(Bool, State).
+
+tr_bool(true, _State) -> true;
+tr_bool(false, _State) -> false.
+
+tr_term_id_component(Sub, _State) ->
+ case Sub of
+ all -> all;
+ choose -> choose;
+ Char when is_integer(Char) -> Char
+ end.
+
+%% mediaDescriptor = MediaToken LBRKT mediaParm *(COMMA mediaParm) RBRKT
+%% ; at-most-once per item
+%% ; and either streamParm or streamDescriptor but not both
+%% mediaParm = (streamParm / streamDescriptor /
+%% terminationStateDescriptor)
+%% ; at-most-once
+%% streamParm = ( localDescriptor / remoteDescriptor /
+%% localControlDescriptor )
+%% streamDescriptor = StreamToken EQUAL StreamID LBRKT streamParm
+%% *(COMMA streamParm) RBRKT
+tr_MediaDescriptor(#'MediaDescriptor'{termStateDescr = TermState,
+ streams = Streams},
+ State) ->
+ #'MediaDescriptor'{termStateDescr = tr_opt_TerminationStateDescriptor(TermState, State),
+ streams = tr_opt_streams(Streams, State)}.
+
+tr_opt_streams(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_streams({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ oneStream -> tr_StreamParms(Val, State);
+ multiStream -> [tr_StreamDescriptor(SD, State) || SD <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_StreamParms(#'StreamParms'{localControlDescriptor = Control,
+ localDescriptor = Local,
+ remoteDescriptor = Remote},
+ State) ->
+ #'StreamParms'{localControlDescriptor = tr_opt_LocalControlDescriptor(Control, State),
+ localDescriptor = tr_opt_LocalRemoteDescriptor(Local, State),
+ remoteDescriptor = tr_opt_LocalRemoteDescriptor(Remote, State)}.
+
+tr_StreamDescriptor(#'StreamDescriptor'{streamID = Id,
+ streamParms = Parms},
+ State) ->
+ #'StreamDescriptor'{streamID = tr_StreamID(Id, State),
+ streamParms = tr_StreamParms(Parms, State)}.
+
+%% localControlDescriptor = LocalControlToken LBRKT localParm
+%% *(COMMA localParm) RBRKT
+%%
+%% ; at-most-once per item
+%% localParm = ( streamMode / propertyParm /
+%% reservedValueMode / reservedGroupMode )
+%% reservedValueMode = ReservedValueToken EQUAL ( "ON" / "OFF" )
+%% reservedGroupMode = ReservedGroupToken EQUAL ( "ON" / "OFF" )
+%%
+%% reservedMode = ReservedToken EQUAL ( "ON" / "OFF" )
+%%
+%% streamMode = ModeToken EQUAL streamModes
+tr_opt_LocalControlDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_LocalControlDescriptor(#'LocalControlDescriptor'{streamMode = Mode,
+ reserveGroup = Group,
+ reserveValue = Value,
+ propertyParms = Props},
+ State) ->
+ #'LocalControlDescriptor'{streamMode = tr_opt_StreamMode(Mode, State),
+ reserveGroup = tr_opt_bool(Group, State),
+ reserveValue = tr_opt_bool(Value, State),
+ propertyParms = [tr_PropertyParm(P, State) || P <- Props]}.
+
+tr_opt_StreamMode(Mode, _State) ->
+ case Mode of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ sendOnly -> sendOnly;
+ recvOnly -> recvOnly;
+ sendRecv -> sendRecv;
+ inactive -> inactive;
+ loopBack -> loopBack
+ end.
+
+tr_Name(Name, State) ->
+ %% BUGBUG: transform
+ %% BUGBUG: NAME = ALPHA *63(ALPHA / DIGIT / "_" )
+ tr_STRING(Name, State, 2, 2).
+
+tr_PkgdName(Name, State) ->
+ %% BUGBUG: transform
+ %% BUGBUG: pkgdName = (NAME / "*") SLASH (ItemID / "*" )
+ tr_OCTET_STRING(Name, State, 4, 4).
+
+%% When text encoding the protocol, the descriptors consist of session
+%% descriptions as defined in SDP (RFC2327), except that the "s=", "t="
+%% and "o=" lines are optional. When multiple session descriptions are
+%% provided in one descriptor, the "v=" lines are required as delimiters;
+%% otherwise they are optional. Implementations shall accept session
+%% descriptions that are fully conformant to RFC2327. When binary
+%% encoding the protocol the descriptor consists of groups of properties
+%% (tag-value pairs) as specified in Annex C. Each such group may
+%% contain the parameters of a session description.
+tr_opt_LocalRemoteDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_LocalRemoteDescriptor(#'LocalRemoteDescriptor'{propGrps = Groups},
+ State) ->
+ #'LocalRemoteDescriptor'{propGrps = [tr_PropertyGroup(G, State) || G <- Groups]}.
+
+tr_PropertyGroup(Props, State) ->
+ [tr_PropertyGroupParm(P, State) || P <- Props].
+
+tr_PropertyGroupParm(#'PropertyParm'{name = Name,
+ value = Value},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'PropertyParm'{name = resolve(property, Name, State, Constraint),
+ value = tr_OCTET_STRING(Value, State, 0, infinity)}.
+
+tr_PropertyParm(#'PropertyParm'{name = Name,
+ value = Value,
+ extraInfo = Extra},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'PropertyParm'{name = resolve(property, Name, State, Constraint),
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_opt_extraInfo(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_extraInfo({relation, Rel}, _State) ->
+ Rel2 =
+ case Rel of
+ greaterThan -> greaterThan;
+ smallerThan -> smallerThan;
+ unequalTo -> unequalTo
+ end,
+ {relation, Rel2};
+tr_opt_extraInfo({range, Range}, State) ->
+ Range2 = tr_bool(Range, State),
+ {range, Range2};
+tr_opt_extraInfo({sublist, Sub}, State) ->
+ Sub2 = tr_bool(Sub, State),
+ {sublist, Sub2}.
+
+tr_opt_TerminationStateDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TerminationStateDescriptor(#'TerminationStateDescriptor'{propertyParms = Props,
+ eventBufferControl = Control,
+ serviceState = Service},
+ State) ->
+ #'TerminationStateDescriptor'{propertyParms = [tr_PropertyParm(P, State) || P <- Props],
+ eventBufferControl = tr_opt_EventBufferControl(Control, State),
+ serviceState = tr_opt_ServiceState(Service, State)}.
+
+tr_opt_EventBufferControl(Control, _State) ->
+ case Control of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ off -> off;
+ lockStep -> lockStep
+ end.
+
+tr_opt_ServiceState(Service, _State) ->
+ case Service of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ test -> test;
+ outOfSvc -> outOfSvc;
+ inSvc -> inSvc
+ end.
+
+tr_MuxDescriptor(#'MuxDescriptor'{muxType = Type,
+ termList = IdList},
+ State) ->
+ #'MuxDescriptor'{muxType = tr_MuxType(Type, State),
+ termList = [tr_TerminationID(Id, State) || Id <- IdList]}.
+
+tr_MuxType(Type, _State) ->
+ case Type of
+ h221 -> h221;
+ h223 -> h223;
+ h226 -> h226;
+ v76 -> v76
+ end.
+
+tr_opt_StreamID(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_StreamID(Id, State) ->
+ tr_StreamID(Id, State).
+
+tr_StreamID(Id, State) ->
+ tr_UINT16(Id, State).
+
+tr_EventsDescriptor(#'EventsDescriptor'{requestID = Id,
+ eventList = Events},
+ State) ->
+ #'EventsDescriptor'{requestID = tr_opt_RequestID(Id, State),
+ eventList = [tr_RequestedEvent(E, State) || E <- Events]}.
+
+tr_RequestedEvent(#'RequestedEvent'{pkgdName = Name,
+ streamID = Id,
+ evParList = Parms,
+ eventAction = Actions},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'RequestedEvent'{pkgdName = resolve(event, Name, State, Constraint),
+ streamID = tr_opt_StreamID(Id, State),
+ eventAction = tr_opt_RequestedActions(Actions, State),
+ evParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+tr_opt_RequestedActions(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_RequestedActions(#'RequestedActions'{keepActive = Keep,
+ eventDM = DM,
+ secondEvent = Event,
+ signalsDescriptor = SigDesc},
+ State) ->
+ #'RequestedActions'{keepActive = tr_opt_keepActive(Keep, State),
+ eventDM = tr_opt_EventDM(DM, State),
+ secondEvent = tr_opt_SecondEventsDescriptor(Event, State),
+ signalsDescriptor = tr_opt_SignalsDescriptor(SigDesc, State)}.
+
+tr_opt_keepActive(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_keepActive(Keep, State) ->
+ tr_bool(Keep, State).
+
+tr_opt_EventDM(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_EventDM({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ digitMapName -> tr_DigitMapName(Val, State);
+ digitMapValue -> tr_DigitMapValue(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_opt_SecondEventsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SecondEventsDescriptor(#'SecondEventsDescriptor'{requestID = Id,
+ eventList = Events},
+ State) ->
+ #'SecondEventsDescriptor'{requestID = tr_RequestID(Id, State), %% IG v6 6.8 withdrawn
+ eventList = [tr_SecondRequestedEvent(E, State) || E <- Events]}.
+
+tr_SecondRequestedEvent(#'SecondRequestedEvent'{pkgdName = Name,
+ streamID = Id,
+ evParList = Parms,
+ eventAction = Actions},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'SecondRequestedEvent'{pkgdName = resolve(event, Name, State, Constraint),
+ streamID = tr_opt_StreamID(Id, State),
+ eventAction = tr_opt_SecondRequestedActions(Actions, State),
+ evParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+
+tr_opt_SecondRequestedActions(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SecondRequestedActions(#'SecondRequestedActions'{keepActive = Keep,
+ eventDM = DM,
+ signalsDescriptor = SigDesc},
+ State) ->
+ #'SecondRequestedActions'{keepActive = tr_opt_keepActive(Keep, State),
+ eventDM = tr_opt_EventDM(DM, State),
+ signalsDescriptor = tr_opt_SignalsDescriptor(SigDesc, State)}.
+
+tr_EventBufferDescriptor(EventSpecs, State) ->
+ [tr_EventSpec(ES, State) || ES <- EventSpecs].
+
+tr_EventSpec(#'EventSpec'{eventName = Name,
+ streamID = Id,
+ eventParList = Parms},
+ State) ->
+ #'EventSpec'{eventName = tr_EventName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ eventParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+tr_opt_SignalsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SignalsDescriptor(SigDesc, State) ->
+ tr_SignalsDescriptor(SigDesc, State).
+
+tr_SignalsDescriptor(SigDesc, State) when is_list(SigDesc) ->
+ [tr_SignalRequest(SigReq, State) || SigReq <- SigDesc].
+
+tr_SignalRequest({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ signal -> tr_Signal(Val, State);
+ seqSigList -> tr_SeqSigList(Val, State)
+ end,
+ {Tag, Val2}.
+
+
+tr_SeqSigList(#'SeqSigList'{id = Id,
+ signalList = SigList},
+ State) when is_list(SigList) ->
+ #'SeqSigList'{id = tr_UINT16(Id, State),
+ signalList = [tr_Signal(Sig, State) || Sig <- SigList]}.
+
+tr_Signal(#'Signal'{signalName = Name,
+ streamID = Id,
+ sigType = Type,
+ duration = Dur,
+ notifyCompletion = Compl,
+ keepActive = Keep,
+ sigParList = Parms},
+ State) ->
+ #'Signal'{signalName = tr_SignalName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ sigType = tr_opt_SignalType(Type, State),
+ duration = tr_opt_duration(Dur, State),
+ notifyCompletion = tr_opt_NotifyCompletion(Compl, State),
+ keepActive = tr_opt_keepActive(Keep, State),
+ sigParList = [tr_SigParameter(P, Name, State) || P <- Parms]}.
+
+tr_opt_duration(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_duration(Dur, State) ->
+ tr_UINT16(Dur, State).
+
+tr_opt_NotifyCompletion(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_NotifyCompletion(Items, State) when is_list(Items) ->
+ [tr_notifyCompletionItem(I, State) || I <- Items].
+
+tr_notifyCompletionItem(Item, _State) ->
+ case Item of
+ onTimeOut -> onTimeOut;
+ onInterruptByEvent -> onInterruptByEvent;
+ onInterruptByNewSignalDescr -> onInterruptByNewSignalDescr;
+ otherReason -> otherReason
+ end.
+
+tr_opt_SignalType(Type, _State) ->
+ case Type of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ brief -> brief;
+ onOff -> onOff;
+ timeOut -> timeOut
+ end.
+
+tr_SignalName(Name, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ resolve(signal, Name, State, Constraint).
+
+tr_SigParameter(#'SigParameter'{sigParameterName = ParName,
+ value = Value,
+ extraInfo = Extra},
+ SigName,
+ State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ N = resolve({signal_parameter, SigName}, ParName, State, Constraint),
+ #'SigParameter'{sigParameterName = N,
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_opt_RequestID(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_RequestID(Id, State) ->
+ tr_RequestID(Id, State).
+
+tr_RequestID(Id, _State) when Id =:= ?megaco_all_request_id ->
+ ?megaco_all_request_id;
+tr_RequestID(Id, State) ->
+ tr_UINT32(Id, State).
+
+tr_ModemDescriptor(_MD, _State) ->
+ deprecated.
+% tr_ModemDescriptor(#'ModemDescriptor'{mtl = Types,
+% mpl = Props},
+% State) when list(Types), list(Props) ->
+% %% BUGBUG: Does not handle extensionParameter
+% #'ModemDescriptor'{mtl = [tr_ModemType(T, State) || T <- Types],
+% mpl = [tr_PropertyParm(P, State) || P <- Props]}.
+
+% tr_ModemType(Type, _State) ->
+% %% BUGBUG: Does not handle extensionParameter
+% case Type of
+% v18 -> v18;
+% v22 -> v22;
+% v22bis -> v22bis;
+% v32 -> v32;
+% v32bis -> v32bis;
+% v34 -> v34;
+% v90 -> v90;
+% v91 -> v91;
+% synchISDN -> synchISDN
+% end.
+
+tr_DigitMapDescriptor(#'DigitMapDescriptor'{digitMapName = Name,
+ digitMapValue = Value},
+ State) ->
+ #'DigitMapDescriptor'{digitMapName = tr_opt_DigitMapName(Name, State),
+ digitMapValue = tr_opt_DigitMapValue(Value, State)}.
+
+tr_opt_DigitMapName(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_DigitMapName(Name, State) ->
+ tr_DigitMapName(Name, State).
+
+tr_DigitMapName(Name, State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ resolve(dialplan, Name, State, Constraint).
+
+tr_opt_DigitMapValue(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_DigitMapValue(Value, State) ->
+ tr_DigitMapValue(Value, State).
+
+tr_DigitMapValue(#'DigitMapValue'{digitMapBody = Body,
+ startTimer = Start,
+ shortTimer = Short,
+ longTimer = Long},
+ State) ->
+ #'DigitMapValue'{startTimer = tr_opt_timer(Start, State),
+ shortTimer = tr_opt_timer(Short, State),
+ longTimer = tr_opt_timer(Long, State),
+ digitMapBody = tr_STRING(Body, State)}. %% BUGBUG: digitMapBody not handled at all
+
+tr_opt_timer(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_timer(Timer, State) ->
+ tr_DIGIT(Timer, State, 0, 99).
+
+tr_ServiceChangeParm(#'ServiceChangeParm'{serviceChangeMethod = Method,
+ serviceChangeAddress = Addr,
+ serviceChangeVersion = Version,
+ serviceChangeProfile = Profile,
+ serviceChangeReason = Reason,
+ serviceChangeDelay = Delay,
+ serviceChangeMgcId = MgcId,
+ timeStamp = Time,
+ serviceChangeInfo = Info},
+ State) ->
+ #'ServiceChangeParm'{serviceChangeMethod = tr_ServiceChangeMethod(Method, State),
+ serviceChangeAddress = tr_opt_ServiceChangeAddress(Addr, State),
+ serviceChangeVersion = tr_opt_serviceChangeVersion(Version, State),
+ serviceChangeProfile = tr_opt_ServiceChangeProfile(Profile, State),
+ serviceChangeReason = tr_serviceChangeReason(Reason, State),
+ serviceChangeDelay = tr_opt_serviceChangeDelay(Delay, State),
+ serviceChangeMgcId = tr_opt_serviceChangeMgcId(MgcId, State),
+ timeStamp = tr_opt_TimeNotation(Time, State),
+ serviceChangeInfo = tr_opt_AuditDescriptor(Info, State)}.
+
+tr_ServiceChangeMethod(Method, _State) ->
+ case Method of
+ failover -> failover;
+ forced -> forced;
+ graceful -> graceful;
+ restart -> restart;
+ disconnected -> disconnected;
+ handOff -> handOff
+ end. %% BUGBUG: extension
+
+tr_opt_ServiceChangeAddress(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ServiceChangeAddress({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ portNumber -> tr_portNumber(Val, State);
+ ip4Address -> tr_IP4Address(Val, State);
+ ip6Address -> tr_IP6Address(Val, State);
+ domainName -> tr_DomainName(Val, State);
+ deviceName -> tr_PathName(Val, State);
+ mtpAddress -> tr_mtpAddress(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_opt_serviceChangeVersion(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeVersion(Version, State) ->
+ tr_version(Version, State).
+
+tr_opt_ServiceChangeProfile(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+%% Decode
+tr_opt_ServiceChangeProfile({'ServiceChangeProfile', ProfileName}, State) ->
+ case string:tokens(ProfileName, "/") of
+ [Name0, Version0] ->
+ Name = tr_STRING(Name0, State, 1, 64),
+ Version = tr_version(list_to_integer(Version0), State),
+ #'ServiceChangeProfile'{profileName = Name,
+ version = Version}
+ end;
+%% Encode
+tr_opt_ServiceChangeProfile(#'ServiceChangeProfile'{profileName = Name0,
+ version = Version0},
+ State) ->
+ Name = tr_STRING(Name0, State, 1, 64),
+ Version = tr_version(Version0, State),
+ ProfileName = lists:flatten(io_lib:format("~s/~w", [Name, Version])),
+ {'ServiceChangeProfile', ProfileName}.
+
+tr_serviceChangeReason([_] = Reason, State) ->
+ tr_Value(Reason, State).
+
+tr_opt_serviceChangeDelay(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeDelay(Delay, State) ->
+ tr_UINT32(Delay, State).
+
+tr_opt_serviceChangeMgcId(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeMgcId(MgcId, State) ->
+ tr_MId(MgcId, State).
+
+tr_opt_portNumber(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_portNumber(Port, State) ->
+ tr_portNumber(Port, State).
+
+tr_portNumber(Port, State) when is_integer(Port) andalso (Port >= 0) ->
+ tr_UINT16(Port, State).
+
+tr_ServiceChangeResParm(#'ServiceChangeResParm'{serviceChangeMgcId = MgcId,
+ serviceChangeAddress = Addr,
+ serviceChangeVersion = Version,
+ serviceChangeProfile = Profile,
+ timeStamp = Time},
+ State) ->
+ #'ServiceChangeResParm'{serviceChangeMgcId = tr_opt_serviceChangeMgcId(MgcId, State),
+ serviceChangeAddress = tr_opt_ServiceChangeAddress(Addr, State),
+ serviceChangeVersion = tr_opt_serviceChangeVersion(Version, State),
+ serviceChangeProfile = tr_opt_ServiceChangeProfile(Profile, State),
+ timeStamp = tr_opt_TimeNotation(Time, State)}.
+
+tr_PackagesDescriptor(Items, State) when is_list(Items) ->
+ [tr_PackagesItem(I, State) || I <- Items].
+
+tr_PackagesItem(#'PackagesItem'{packageName = Name,
+ packageVersion = Version},
+ State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ #'PackagesItem'{packageName = resolve(package, Name, State, Constraint),
+ packageVersion = tr_UINT16(Version, State)}.
+
+tr_StatisticsDescriptor(Parms, State) when is_list(Parms) ->
+ [tr_StatisticsParameter(P, State) || P <- Parms].
+
+tr_StatisticsParameter(#'StatisticsParameter'{statName = Name,
+ statValue = Value},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'StatisticsParameter'{statName = resolve(statistics, Name, State, Constraint),
+ statValue = tr_opt_Value(Value, State)}.
+
+tr_opt_TimeNotation(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TimeNotation(#'TimeNotation'{date = Date,
+ time = Time},
+ State) ->
+ #'TimeNotation'{date = tr_STRING(Date, State, 8, 8), % "yyyymmdd"
+ time = tr_STRING(Time, State, 8, 8)}.% "hhmmssss"
+
+%% BUGBUG: Does not verify that string must contain at least one char
+%% BUGBUG: This violation of the is required in order to comply with
+%% BUGBUG: the dd/ce ds parameter that may possibly be empty.
+
+tr_opt_Value(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_Value(Value, State) ->
+ tr_Value(Value, State).
+
+tr_Value(Strings, _State) when is_list(Strings) ->
+ [[Char || Char <- String] || String <- Strings].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Encode an octet string, escape } by \ if necessary
+tr_OCTET_STRING(String, _State, Min, Max) when is_list(String) ->
+ verify_count(length(String), Min, Max),
+ String.
+
+tr_QUOTED_STRING(String, _State) when is_list(String) ->
+ verify_count(length(String), 1, infinity),
+ String.
+
+%% The internal format of hex digits is a list of octets
+%% Min and Max means #hexDigits
+%% Leading zeros are prepended in order to fulfill Min
+tr_HEXDIG(Octets, _State, Min, Max) when is_list(Octets) ->
+ verify_count(length(Octets), Min, Max),
+ Octets.
+
+tr_DIGIT(Val, State, Min, Max) ->
+ tr_integer(Val, State, Min, Max).
+
+tr_STRING(String, _State) when is_list(String) ->
+ String.
+
+tr_STRING(String, _State, Min, Max) when is_list(String) ->
+ verify_count(length(String), Min, Max),
+ String.
+
+tr_opt_UINT16(Val, State) ->
+ tr_opt_integer(Val, State, 0, 65535).
+
+tr_UINT16(Val, State) ->
+ tr_integer(Val, State, 0, 65535).
+
+tr_UINT32(Val, State) ->
+ tr_integer(Val, State, 0, 4294967295).
+
+tr_opt_integer(asn1_NOVALUE, _State, _Min, _Max) ->
+ asn1_NOVALUE;
+tr_opt_integer(Int, State, Min, Max) ->
+ tr_integer(Int, State, Min, Max).
+
+tr_integer(Int, _State, Min, Max) ->
+ verify_count(Int, Min, Max),
+ Int.
+
+%% Verify that Count is within the range of Min and Max
+verify_count(Count, Min, Max) ->
+ if
+ is_integer(Count) ->
+ if
+ is_integer(Min) andalso (Count >= Min) ->
+ if
+ is_integer(Max) andalso (Count =< Max) ->
+ Count;
+ Max =:= infinity ->
+ Count;
+ true ->
+ ?error({count_too_large, Count, Max})
+ end;
+ true ->
+ ?error({count_too_small, Count, Min})
+ end;
+ true ->
+ ?error({count_not_an_integer, Count})
+ end.
+
+
+% i(F,A) ->
+% S1 = io_lib:format("TRANSF-v2: " ++ F ++ "~n",A),
+% S2 = lists:flatten(S1),
+% io:format("~s",[S2]).
diff --git a/lib/megaco/src/binary/megaco_binary_transformer_v3.erl b/lib/megaco/src/binary/megaco_binary_transformer_v3.erl
new file mode 100644
index 0000000000..cef49b03fd
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_binary_transformer_v3.erl
@@ -0,0 +1,1763 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Transform internal form of Megaco/H.248 messages
+%%----------------------------------------------------------------------
+
+-module(megaco_binary_transformer_v3).
+
+-include_lib("megaco/include/megaco.hrl").
+%% -include_lib("megaco/include/megaco_message.hrl").
+-include_lib("megaco/include/megaco_message_v3.hrl").
+-include_lib("megaco/src/app/megaco_internal.hrl").
+
+-export([tr_message/3, tr_transaction/3]).
+
+-define(DEFAULT_NAME_RESOLVER, megaco_binary_name_resolver_v3).
+
+-record(state, {mode, % verify | encode | decode
+ resolver_module, %
+ resolver_options}).
+
+resolve(Type, Item, State, Constraint) ->
+ case State#state.mode of
+ verify ->
+ Item;
+ encode ->
+ ?d("resolve(encode) -> encode: ~p",[Item]),
+ Mod = State#state.resolver_module,
+ Opt = State#state.resolver_options,
+ EncodedItem = Mod:encode_name(Opt, Type, Item),
+ ?d("resolve -> verify contraint for ~p",[EncodedItem]),
+ verify_constraint(EncodedItem, Constraint);
+ decode ->
+ ?d("resolve(decode) -> verify contraint for ~p",[Item]),
+ DecodedItem = verify_constraint(Item, Constraint),
+ Mod = State#state.resolver_module,
+ Opt = State#state.resolver_options,
+ ?d("resolve(decode) -> decode: ~p",[DecodedItem]),
+ Mod:decode_name(Opt, Type, DecodedItem)
+ end.
+
+verify_constraint(Item, valid) ->
+ Item;
+verify_constraint(Item, Constraint) when is_function(Constraint) ->
+ Constraint(Item).
+
+tr_message(MegaMsg, Mode, Config) ->
+ case Config of
+ [native] ->
+ MegaMsg;
+ [verify] ->
+ State = #state{mode = verify},
+ tr_MegacoMessage(MegaMsg, State);
+ [] ->
+ State = #state{mode = Mode,
+ resolver_module = ?DEFAULT_NAME_RESOLVER,
+ resolver_options = [8, 8, 8]},
+ tr_MegacoMessage(MegaMsg, State);
+ [{binary_name_resolver, {Module, Options}}] when is_atom(Module) ->
+ State = #state{mode = Mode,
+ resolver_module = Module,
+ resolver_options = Options},
+ tr_MegacoMessage(MegaMsg, State)
+ end.
+
+tr_transaction(Trans, Mode, Config) ->
+ case Config of
+ [native] ->
+ Trans;
+ [verify] ->
+ State = #state{mode = verify},
+ tr_Transaction(Trans, State);
+ [] ->
+ State = #state{mode = Mode,
+ resolver_module = ?DEFAULT_NAME_RESOLVER,
+ resolver_options = [8, 8, 8]},
+ tr_Transaction(Trans, State);
+ [{binary_name_resolver, {Module, Options}}] when is_atom(Module) ->
+ State = #state{mode = Mode,
+ resolver_module = Module,
+ resolver_options = Options},
+ tr_Transaction(Trans, State)
+ end.
+
+tr_MegacoMessage(#'MegacoMessage'{authHeader = Auth,
+ mess = Mess},
+ State) ->
+ ?d("tr_MegacoMessage -> entry with"
+ "~n Auth: ~p"
+ "~n Mess: ~p"
+ "~n State: ~p", [Auth, Mess, State]),
+ #'MegacoMessage'{authHeader = tr_opt_AuthenticationHeader(Auth, State),
+ mess = tr_Message(Mess, State)}.
+
+tr_opt_AuthenticationHeader(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_AuthenticationHeader(#'AuthenticationHeader'{secParmIndex = SPI,
+ seqNum = SN,
+ ad = AuthData},
+ State) ->
+ #'AuthenticationHeader'{secParmIndex = tr_SecurityParmIndex(SPI, State),
+ seqNum = tr_SequenceNum(SN, State),
+ ad = tr_AuthData(AuthData, State)}.
+
+tr_SecurityParmIndex(SPI, State) ->
+ tr_HEXDIG(SPI, State, 4, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_SequenceNum(SN, State) ->
+ tr_HEXDIG(SN, State, 4, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_AuthData(AuthData, State) ->
+ tr_HEXDIG(AuthData, State, 12, 32). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_Message(#'Message'{version = Version,
+ mId = MID,
+ messageBody = Body},
+ State) ->
+ #'Message'{version = tr_version(Version, State),
+ mId = tr_MId(MID, State),
+ messageBody = tr_Message_messageBody(Body, State)}.
+
+tr_version(Version, State) ->
+ tr_DIGIT(Version, State, 0, 99).
+
+tr_Message_messageBody({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ messageError -> tr_ErrorDescriptor(Val, State);
+ transactions when is_list(Val) -> [tr_Transaction(T, State) || T <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_MId({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ ip4Address -> tr_IP4Address(Val, State);
+ ip6Address -> tr_IP6Address(Val, State);
+ domainName -> tr_DomainName(Val, State);
+ deviceName -> tr_PathName(Val, State);
+ mtpAddress -> tr_mtpAddress(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_mtpAddress(MtpAddr, State) ->
+ tr_OCTET_STRING(MtpAddr, State, 2, 4). % BUGBUG: Mismatch between ASN.1 and ABNF
+
+tr_DomainName(#'DomainName'{name = Name,
+ portNumber = Port},
+ State) ->
+ Domain = #'DomainName'{name = tr_STRING(Name, State), % BUGBUG: Mismatch between ASN.1 and ABNF
+ portNumber = tr_opt_portNumber(Port, State)},
+ {domainName, Domain2} = resolve(mid, {domainName, Domain}, State, valid),
+ Domain2.
+
+tr_IP4Address(#'IP4Address'{address = [A1, A2, A3, A4],
+ portNumber = Port},
+ State) ->
+ #'IP4Address'{address = [tr_V4hex(A1, State),
+ tr_V4hex(A2, State),
+ tr_V4hex(A3, State),
+ tr_V4hex(A4, State)],
+ portNumber = tr_opt_portNumber(Port, State)}.
+
+tr_V4hex(Val, State) ->
+ tr_DIGIT(Val, State, 0, 255).
+
+tr_IP6Address(_Val, _State) ->
+ error(ipv6_not_supported). %% BUGBUG: nyi
+
+tr_PathName(Path, State) ->
+ %% BUGBUG: ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
+ %% BUGBUG: ["@" pathDomainName ]
+ Constraint = fun({deviceName, Item}) -> tr_STRING(Item, State, 1, 64) end,
+ resolve(mid, {deviceName, Path}, State, Constraint).
+
+tr_Transaction({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ transactionRequest -> tr_TransactionRequest(Val, State);
+ transactionPending -> tr_TransactionPending(Val, State);
+ transactionReply -> tr_TransactionReply(Val, State);
+ transactionResponseAck -> [tr_TransactionAck(T, State) || T <- Val];
+ segmentReply -> tr_SegmentReply(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_TransactionAck(#'TransactionAck'{firstAck = First,
+ lastAck = Last},
+ State) ->
+ #'TransactionAck'{firstAck = tr_TransactionId(First, State),
+ lastAck = tr_opt_TransactionId(Last, State)}.
+
+tr_opt_TransactionId(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TransactionId(Id, State) ->
+ tr_TransactionId(Id, State).
+
+tr_TransactionId(Id, State) ->
+ tr_UINT32(Id, State).
+
+tr_TransactionRequest(#'TransactionRequest'{transactionId = Id,
+ actions = Actions},
+ State) when is_list(Actions) ->
+
+ #'TransactionRequest'{transactionId = tr_TransactionId(Id, State),
+ actions = [tr_ActionRequest(ActReq, State) || ActReq <- Actions]}.
+
+tr_TransactionPending(#'TransactionPending'{transactionId = Id},
+ State) ->
+ #'TransactionPending'{transactionId = tr_TransactionId(Id, State)}.
+
+tr_TransactionReply(#'TransactionReply'{transactionId = Id,
+ immAckRequired = ImmAck,
+ transactionResult = TransRes,
+ segmentNumber = SN,
+ segmentationComplete = SC},
+ State) ->
+ #'TransactionReply'{transactionId = tr_TransactionId(Id, State),
+ immAckRequired = tr_opt_null(ImmAck, State),
+ transactionResult = tr_TransactionReply_transactionResult(TransRes, State),
+ segmentNumber = tr_opt_SegmentNumber(SN, State),
+ segmentationComplete = tr_opt_null(SC, State)}.
+
+tr_opt_null(asn1_NOVALUE, _State) -> asn1_NOVALUE;
+tr_opt_null('NULL', _State) -> 'NULL'.
+
+tr_SegmentNumber(Num, State) ->
+ tr_UINT16(Num, State).
+
+tr_opt_SegmentNumber(Num, State) ->
+ tr_opt_UINT16(Num, State).
+
+tr_SegmentReply(#'SegmentReply'{transactionId = TID,
+ segmentNumber = SN,
+ segmentationComplete = SC}, State) ->
+ #'SegmentReply'{transactionId = tr_TransactionId(TID, State),
+ segmentNumber = tr_SegmentNumber(SN, State),
+ segmentationComplete = tr_opt_null(SC, State)}.
+
+tr_TransactionReply_transactionResult({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ transactionError ->
+ tr_ErrorDescriptor(Val, State);
+ actionReplies when is_list(Val) andalso (Val =/= []) ->
+ [tr_ActionReply(ActRep, State) || ActRep <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_opt_ErrorDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ErrorDescriptor(ErrDesc, State) ->
+ tr_ErrorDescriptor(ErrDesc, State).
+
+tr_ErrorDescriptor(#'ErrorDescriptor'{errorCode = Code,
+ errorText = Text},
+ State) ->
+ #'ErrorDescriptor'{errorCode = tr_ErrorCode(Code, State),
+ errorText = tr_opt_ErrorText(Text, State)}.
+
+tr_ErrorCode(Code, State) ->
+ tr_DIGIT(Code, State, 0, 999).
+
+tr_opt_ErrorText(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ErrorText(Text, State) ->
+ tr_QUOTED_STRING(Text, State).
+
+tr_ContextID(CtxId, State) ->
+ case CtxId of
+ ?megaco_all_context_id -> ?megaco_all_context_id;
+ ?megaco_null_context_id -> ?megaco_null_context_id;
+ ?megaco_choose_context_id -> ?megaco_choose_context_id;
+ Int when is_integer(Int) -> tr_UINT32(Int, State)
+ end.
+
+tr_ActionRequest(#'ActionRequest'{contextId = CtxId,
+ contextRequest = CtxReq,
+ contextAttrAuditReq = CtxAuditReq,
+ commandRequests = CmdReqList},
+ State) ->
+ #'ActionRequest'{contextId = tr_ContextID(CtxId, State),
+ contextRequest = tr_opt_ContextRequest(CtxReq, State),
+ contextAttrAuditReq = tr_opt_ContextAttrAuditRequest(CtxAuditReq, State),
+ commandRequests = [tr_CommandRequest(CmdReq, State) || CmdReq <- CmdReqList]}.
+
+tr_ActionReply(#'ActionReply'{contextId = CtxId,
+ errorDescriptor = ErrDesc,
+ contextReply = CtxRep,
+ commandReply = CmdRepList},
+ State) ->
+ CmdRepList2 = [tr_CommandReply(CmdRep, State) || CmdRep <- CmdRepList],
+ #'ActionReply'{contextId = tr_ContextID(CtxId, State),
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State),
+ contextReply = tr_opt_ContextRequest(CtxRep, State),
+ commandReply = CmdRepList2}.
+
+tr_opt_ContextRequest(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ContextRequest(CR, State) ->
+ tr_ContextRequest(CR, State).
+
+tr_ContextRequest(#'ContextRequest'{priority = Prio,
+ emergency = Em,
+ topologyReq = TopReqList,
+ iepscallind = Ind,
+ contextProp = CtxProps,
+ contextList = CtxList},
+ State) ->
+ Prio2 =
+ case Prio of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_integer(Prio, State, 0, 15)
+ end,
+ Em2 =
+ case Em of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ TopReqList2 =
+ case TopReqList of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_TopologyRequest(TopReq, State) ||
+ TopReq <- TopReqList]
+ end,
+ Ind2 =
+ case Ind of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ CtxProps2 =
+ case CtxProps of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_PropertyParm(Prop, State) || Prop <- CtxProps]
+ end,
+ CtxList2 =
+ case CtxList of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_ContextID(Id, State) || Id <- CtxList]
+ end,
+ #'ContextRequest'{priority = Prio2,
+ emergency = Em2,
+ topologyReq = TopReqList2,
+ iepscallind = Ind2,
+ contextProp = CtxProps2,
+ contextList = CtxList2}.
+
+tr_opt_ContextAttrAuditRequest(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ContextAttrAuditRequest(CAAR, State) ->
+ tr_ContextAttrAuditRequest(CAAR, State).
+
+tr_ContextAttrAuditRequest(#'ContextAttrAuditRequest'{topology = Top,
+ emergency = Em,
+ priority = Prio,
+ iepscallind = Ind,
+ contextPropAud = Props,
+ selectpriority = SPrio,
+ selectemergency = SEm,
+ selectiepscallind = SInd,
+ selectLogic = SLog},
+ State) ->
+ Top2 = tr_opt_null(Top, State),
+ Em2 = tr_opt_null(Em, State),
+ Prio2 = tr_opt_null(Prio, State),
+ Ind2 = tr_opt_null(Ind, State),
+ Props2 =
+ case Props of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ [tr_indAudPropertyParm(Prop, State) || Prop <- Props]
+ end,
+ SPrio2 =
+ case SPrio of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_integer(SPrio, State, 0, 15)
+ end,
+ SEm2 =
+ case SEm of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ SInd2 =
+ case SInd of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ false -> false;
+ true -> true
+ end,
+ SLog2 =
+ case SLog of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_SelectLogic(SLog, State)
+ end,
+ #'ContextAttrAuditRequest'{topology = Top2,
+ emergency = Em2,
+ priority = Prio2,
+ iepscallind = Ind2,
+ contextPropAud = Props2,
+ selectpriority = SPrio2,
+ selectemergency = SEm2,
+ selectiepscallind = SInd2,
+ selectLogic = SLog2}.
+
+tr_SelectLogic({andAUDITSelect, 'NULL'} = Val, _State) ->
+ Val;
+tr_SelectLogic({orAUDITSelect, 'NULL'} = Val, _State) ->
+ Val.
+
+tr_CommandRequest(#'CommandRequest'{command = Cmd,
+ optional = Opt,
+ wildcardReturn = Wild},
+ State) ->
+ #'CommandRequest'{optional = tr_opt_null(Opt, State),
+ wildcardReturn = tr_opt_null(Wild, State),
+ command = tr_Command(Cmd, State)}.
+
+tr_Command({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ addReq -> tr_AmmRequest(Val, State);
+ moveReq -> tr_AmmRequest(Val, State);
+ modReq -> tr_AmmRequest(Val, State);
+ subtractReq -> tr_SubtractRequest(Val, State);
+ auditCapRequest -> tr_AuditRequest(Val, State);
+ auditValueRequest -> tr_AuditRequest(Val, State);
+ notifyReq -> tr_NotifyRequest(Val, State);
+ serviceChangeReq -> tr_ServiceChangeRequest(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_CommandReply({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ addReply -> tr_AmmsReply(Val, State);
+ moveReply -> tr_AmmsReply(Val, State);
+ modReply -> tr_AmmsReply(Val, State);
+ subtractReply -> tr_AmmsReply(Val, State);
+ auditCapReply -> tr_AuditReply(Val, State);
+ auditValueReply -> tr_AuditReply(Val, State);
+ notifyReply -> tr_NotifyReply(Val, State);
+ serviceChangeReply -> tr_ServiceChangeReply(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_TopologyRequest(#'TopologyRequest'{terminationFrom = From,
+ terminationTo = To,
+ topologyDirection = Dir,
+ streamID = SID,
+ topologyDirectionExtension = TDE},
+ State) ->
+ Dir2 =
+ case Dir of
+ bothway -> bothway;
+ isolate -> isolate;
+ oneway -> oneway
+ end,
+ TDE2 =
+ case TDE of
+ onewayexternal -> onewayexternal;
+ onewayboth -> onewayboth;
+ asn1_NOVALUE -> asn1_NOVALUE
+ end,
+ #'TopologyRequest'{terminationFrom = tr_TerminationID(From, State),
+ terminationTo = tr_TerminationID(To, State),
+ topologyDirection = Dir2,
+ streamID = tr_opt_StreamID(SID, State),
+ topologyDirectionExtension = TDE2}.
+
+tr_AmmRequest(#'AmmRequest'{terminationID = IdList,
+ descriptors = DescList},
+ State) ->
+ #'AmmRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ descriptors = tr_ammDescriptors(DescList, [], State)}.
+
+tr_ammDescriptors([], Acc, _State) ->
+ lists:reverse(Acc);
+tr_ammDescriptors([Desc|Descs], Acc, State) ->
+ case tr_ammDescriptor(Desc, State) of
+ {_, deprecated} when State#state.mode =:= encode ->
+ error({deprecated, Desc});
+ {_, deprecated} when State#state.mode =:= decode ->
+ %% SKIP
+ tr_ammDescriptors(Descs, Acc, State);
+ {_, deprecated} ->
+ %% SKIP
+ tr_ammDescriptors(Descs, Acc, State);
+ NewDesc ->
+ tr_ammDescriptors(Descs, [NewDesc|Acc], State)
+ end.
+
+tr_ammDescriptor({Tag, Desc}, State) ->
+ Desc2 =
+ case Tag of
+ mediaDescriptor -> tr_MediaDescriptor(Desc, State);
+ modemDescriptor -> tr_ModemDescriptor(Desc, State);
+ muxDescriptor -> tr_MuxDescriptor(Desc, State);
+ eventsDescriptor -> tr_EventsDescriptor(Desc, State);
+ eventBufferDescriptor -> tr_EventBufferDescriptor(Desc, State);
+ signalsDescriptor -> tr_SignalsDescriptor(Desc, State);
+ digitMapDescriptor -> tr_DigitMapDescriptor(Desc, State);
+ auditDescriptor -> tr_AuditDescriptor(Desc, State);
+ statisticsDescriptor -> tr_StatisticsDescriptor(Desc, State)
+ end,
+ {Tag, Desc2}.
+
+tr_AmmsReply(#'AmmsReply'{terminationID = IdList,
+ terminationAudit = TermAudit},
+ State) ->
+ TermAudit2 =
+ case TermAudit of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_TerminationAudit(TermAudit, State)
+ end,
+ #'AmmsReply'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ terminationAudit = TermAudit2}.
+
+tr_SubtractRequest(#'SubtractRequest'{terminationID = IdList,
+ auditDescriptor = Desc},
+ State) ->
+ #'SubtractRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ auditDescriptor = tr_opt_AuditDescriptor(Desc, State)}.
+
+tr_AuditRequest(#'AuditRequest'{terminationID = Id,
+ auditDescriptor = Desc,
+ terminationIDList = TIDList},
+ State) ->
+ TIDList2 =
+ case TIDList of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_TerminationID(TID, State) || TID <- TIDList]
+ end,
+ #'AuditRequest'{terminationID = tr_TerminationID(Id, State),
+ auditDescriptor = tr_AuditDescriptor(Desc, State),
+ terminationIDList = TIDList2}.
+
+%% auditReply = (AuditValueToken / AuditCapToken )
+%% ( contextTerminationAudit / auditOther)
+%% auditOther = EQUAL TerminationID LBRKT
+%% terminationAudit RBRKT
+%% terminationAudit = auditReturnParameter *(COMMA auditReturnParameter)
+%%
+%% contextTerminationAudit = EQUAL CtxToken ( terminationIDList /
+%% LBRKT errorDescriptor RBRKT )
+
+tr_AuditReply({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ contextAuditResult ->
+ [tr_TerminationID(Id, State) || Id <- Val];
+ error ->
+ tr_ErrorDescriptor(Val, State);
+ auditResult ->
+ tr_AuditResult(Val, State);
+ auditResultTermList ->
+ tr_TermListAuditResult(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_AuditResult(#'AuditResult'{terminationID = Id,
+ terminationAuditResult = AuditRes},
+ State) ->
+ #'AuditResult'{terminationID = tr_TerminationID(Id, State),
+ terminationAuditResult = tr_TerminationAudit(AuditRes, State)}.
+
+tr_TermListAuditResult(
+ #'TermListAuditResult'{terminationIDList = TIDList,
+ terminationAuditResult = TAR},
+ State) ->
+ TIDList2 = [tr_TerminationID(TID, State) || TID <- TIDList],
+ TAR2 = tr_TerminationAudit(TAR, State),
+ #'TermListAuditResult'{terminationIDList = TIDList2,
+ terminationAuditResult = TAR2}.
+
+
+tr_opt_AuditDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_AuditDescriptor(Desc, State) ->
+ tr_AuditDescriptor(Desc, State).
+
+%% BUGBUG BUGBUG BUGBUG
+%% With this construction it is possible to have both auditToken
+%% and auditPropertyToken, but it is actually valid?
+tr_AuditDescriptor(#'AuditDescriptor'{auditToken = Tokens,
+ auditPropertyToken = APTs},
+ State) ->
+ Tokens2 =
+ case Tokens of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_auditItem(Token, State) || Token <- Tokens]
+ end,
+ %% v2
+ APTs2 =
+ case APTs of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ [tr_indAuditParameter(APT, State) || APT <- APTs]
+ end,
+ #'AuditDescriptor'{auditToken = Tokens2,
+ auditPropertyToken = APTs2}.
+
+tr_auditItem(Token, _State) ->
+ case Token of
+ muxToken -> muxToken;
+ modemToken -> modemToken;
+ mediaToken -> mediaToken;
+ eventsToken -> eventsToken;
+ signalsToken -> signalsToken;
+ digitMapToken -> digitMapToken;
+ statsToken -> statsToken;
+ observedEventsToken -> observedEventsToken;
+ packagesToken -> packagesToken;
+ eventBufferToken -> eventBufferToken
+ end.
+
+%% --- v2 begin ---
+
+tr_indAuditParameter({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ indAudMediaDescriptor ->
+ tr_indAudMediaDescriptor(Val, State);
+ indAudEventsDescriptor ->
+ tr_indAudEventsDescriptor(Val, State);
+ indAudSignalsDescriptor ->
+ tr_indAudSignalsDescriptor(Val, State);
+ indAudDigitMapDescriptor ->
+ tr_indAudDigitMapDescriptor(Val, State);
+ indAudEventBufferDescriptor ->
+ tr_indAudEventBufferDescriptor(Val, State);
+ indAudStatisticsDescriptor ->
+ tr_indAudStatisticsDescriptor(Val, State);
+ indAudPackagesDescriptor ->
+ tr_indAudPackagesDescriptor(Val, State)
+ end,
+ {Tag, Val2}.
+
+
+%% -
+
+tr_indAudMediaDescriptor(#'IndAudMediaDescriptor'{termStateDescr = TSD,
+ streams = S},
+ State) ->
+ TSD2 =
+ case TSD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudTerminationStateDescriptor(TSD, State)
+ end,
+ S2 =
+ case S of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ {oneStream, OS} ->
+ {oneStream, tr_indAudStreamParms(OS, State)};
+ {multiStream, MS} ->
+ MS2 = [tr_indAudStreamDescriptor(MS1, State) || MS1 <- MS],
+ {multiStream, MS2}
+ end,
+ #'IndAudMediaDescriptor'{termStateDescr = TSD2,
+ streams = S2}.
+
+tr_indAudTerminationStateDescriptor(Val, State)
+ when is_record(Val, 'IndAudTerminationStateDescriptor') ->
+ #'IndAudTerminationStateDescriptor'{propertyParms = Parms,
+ eventBufferControl = EBC,
+ serviceState = SS,
+ serviceStateSel = SSS} = Val,
+ Parms2 = [tr_indAudPropertyParm(Parm, State) || Parm <- Parms],
+ EBC2 = tr_opt_null(EBC, State),
+ SS2 = tr_opt_null(SS, State),
+ SSS2 = tr_opt_ServiceState(SSS, State),
+ #'IndAudTerminationStateDescriptor'{propertyParms = Parms2,
+ eventBufferControl = EBC2,
+ serviceState = SS2,
+ serviceStateSel = SSS2}.
+
+
+tr_indAudStreamParms(#'IndAudStreamParms'{localControlDescriptor = LCD,
+ localDescriptor = LD,
+ remoteDescriptor = RD,
+ statisticsDescriptor = SD},
+ State) ->
+ LCD2 =
+ case LCD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalControlDescriptor(LCD, State)
+ end,
+ LD2 =
+ case LD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalRemoteDescriptor(LD, State)
+ end,
+ RD2 =
+ case RD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudLocalRemoteDescriptor(RD, State)
+ end,
+ SD2 =
+ case SD of
+ asn1_NOVALUE ->
+ asn1_NOVALUE;
+ _ ->
+ tr_indAudStatisticsDescriptor(SD, State)
+ end,
+ #'IndAudStreamParms'{localControlDescriptor = LCD2,
+ localDescriptor = LD2,
+ remoteDescriptor = RD2,
+ statisticsDescriptor = SD2}.
+
+tr_indAudLocalControlDescriptor(Val, State)
+ when is_record(Val, 'IndAudLocalControlDescriptor') ->
+ #'IndAudLocalControlDescriptor'{streamMode = M,
+ reserveValue = V,
+ reserveGroup = G,
+ propertyParms = P,
+ streamModeSel = SMS} = Val,
+ M2 = tr_opt_null(M, State),
+ V2 = tr_opt_null(V, State),
+ G2 = tr_opt_null(G, State),
+ P2 = tr_indAudLocalControlDescriptor_propertyParms(P, State),
+ SMS2 = tr_opt_StreamMode(SMS, State),
+ #'IndAudLocalControlDescriptor'{streamMode = M2,
+ reserveValue = V2,
+ reserveGroup = G2,
+ propertyParms = P2,
+ streamModeSel = SMS2}.
+
+tr_indAudLocalControlDescriptor_propertyParms(Parms, State)
+ when is_list(Parms) andalso (length(Parms) > 0) ->
+ [tr_indAudPropertyParm(Parm, State) || Parm <- Parms];
+tr_indAudLocalControlDescriptor_propertyParms(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE.
+
+tr_indAudLocalRemoteDescriptor(#'IndAudLocalRemoteDescriptor'{propGroupID = ID,
+ propGrps = Grps},
+ State) ->
+ #'IndAudLocalRemoteDescriptor'{propGroupID = tr_opt_UINT16(ID, State),
+ propGrps = tr_indAudPropertyGroup(Grps,
+ State)}.
+
+tr_indAudPropertyGroup(Grps, State) when is_list(Grps) ->
+ [tr_indAudPropertyParm(Parm, State) || Parm <- Grps].
+
+tr_indAudPropertyParm(#'IndAudPropertyParm'{name = Name0,
+ propertyParms = Prop0}, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(property, Name0, State, Constraint),
+ Prop =
+ case Prop0 of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> tr_PropertyParm(Prop0, State)
+ end,
+ #'IndAudPropertyParm'{name = Name,
+ propertyParms = Prop}.
+
+
+tr_indAudStreamDescriptor(#'IndAudStreamDescriptor'{streamID = ID,
+ streamParms = Parms},
+ State) ->
+ #'IndAudStreamDescriptor'{streamID = tr_StreamID(ID, State),
+ streamParms = tr_indAudStreamParms(Parms,
+ State)}.
+
+
+%% -
+
+tr_indAudEventsDescriptor(#'IndAudEventsDescriptor'{requestID = RID,
+ pkgdName = Name0,
+ streamID = SID},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(event, Name0, State, Constraint),
+ #'IndAudEventsDescriptor'{requestID = tr_opt_RequestID(RID, State),
+ pkgdName = Name,
+ streamID = tr_opt_StreamID(SID, State)}.
+
+
+%% -
+
+tr_indAudSignalsDescriptor({Tag, Val}, State) ->
+ case Tag of
+ signal ->
+ {signal, tr_indAudSignal(Val, State)};
+ seqSigList ->
+ {seqSigList, tr_indAudSeqSigList(Val, State)}
+ end.
+
+tr_opt_indAudSignal(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_indAudSignal(Val, State) ->
+ tr_indAudSignal(Val, State).
+
+tr_indAudSignal(#'IndAudSignal'{signalName = Name0,
+ streamID = SID,
+ signalRequestID = RID}, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(signal, Name0, State, Constraint),
+ #'IndAudSignal'{signalName = Name,
+ streamID = tr_opt_StreamID(SID, State),
+ signalRequestID = tr_opt_RequestID(RID, State)}.
+
+tr_indAudSeqSigList(#'IndAudSeqSigList'{id = ID,
+ signalList = SigList}, State) ->
+ #'IndAudSeqSigList'{id = tr_integer(ID, State, 0, 65535),
+ signalList = tr_opt_indAudSignal(SigList, State)}.
+
+%% -
+
+tr_indAudDigitMapDescriptor(#'IndAudDigitMapDescriptor'{digitMapName = Name},
+ State) ->
+ #'IndAudDigitMapDescriptor'{digitMapName =
+ tr_opt_DigitMapName(Name, State)}.
+
+
+%% -
+
+tr_indAudEventBufferDescriptor(#'IndAudEventBufferDescriptor'{eventName = N,
+ streamID = SID},
+ State) ->
+ ?d("tr_indAudEventBufferDescriptor -> entry with"
+ "~n N: ~p"
+ "~n SID: ~p", [N, SID]),
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(event, N, State, Constraint),
+ ?d("tr_indAudEventBufferDescriptor -> entry with"
+ "~n Name: ~p", [Name]),
+ #'IndAudEventBufferDescriptor'{eventName = Name,
+ streamID = tr_opt_StreamID(SID, State)}.
+
+%% -
+
+tr_indAudStatisticsDescriptor(#'IndAudStatisticsDescriptor'{statName = N},
+ State) ->
+ ?d("tr_indAudEventBufferDescriptor -> entry with"
+ "~n N: ~p", [N]),
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ Name = resolve(statistics, N, State, Constraint),
+ #'IndAudStatisticsDescriptor'{statName = Name}.
+
+
+%% -
+
+tr_indAudPackagesDescriptor(#'IndAudPackagesDescriptor'{packageName = N,
+ packageVersion = V},
+ State) ->
+ ?d("tr_indAudPackagesDescriptor -> entry with"
+ "~n N: ~p"
+ "~n V: ~p", [N, V]),
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ Name = resolve(package, N, State, Constraint),
+ ?d("tr_indAudPackagesDescriptor -> entry with"
+ "~n Name: ~p", [Name]),
+ #'IndAudPackagesDescriptor'{packageName = Name,
+ packageVersion = tr_integer(V, State, 0, 99)}.
+
+%% -- v2 end --
+
+
+tr_TerminationAudit(ParmList, State) when is_list(ParmList) ->
+ do_tr_TerminationAudit(ParmList, [], State).
+
+do_tr_TerminationAudit([], Acc, _State) ->
+ lists:reverse(Acc);
+do_tr_TerminationAudit([Parm|ParmList], Acc, State) ->
+ case tr_AuditReturnParameter(Parm, State) of
+ {_, deprecated} when State#state.mode =:= encode ->
+ error({deprecated, Parm});
+ {_, deprecated} when State#state.mode =:= decode ->
+ %% SKIP
+ do_tr_TerminationAudit(ParmList, Acc, State);
+ {_, deprecated} ->
+ %% SKIP
+ do_tr_TerminationAudit(ParmList, Acc, State);
+ NewParm ->
+ do_tr_TerminationAudit(ParmList, [NewParm|Acc], State)
+ end.
+
+tr_AuditReturnParameter({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ errorDescriptor ->
+ tr_ErrorDescriptor(Val, State);
+ mediaDescriptor ->
+ tr_MediaDescriptor(Val, State);
+ modemDescriptor ->
+ tr_ModemDescriptor(Val, State);
+ muxDescriptor ->
+ tr_MuxDescriptor(Val, State);
+ eventsDescriptor ->
+ tr_EventsDescriptor(Val, State);
+ eventBufferDescriptor ->
+ tr_EventBufferDescriptor(Val, State);
+ signalsDescriptor ->
+ tr_SignalsDescriptor(Val, State);
+ digitMapDescriptor ->
+ tr_DigitMapDescriptor(Val, State);
+ observedEventsDescriptor ->
+ tr_ObservedEventsDescriptor(Val, State);
+ statisticsDescriptor ->
+ tr_StatisticsDescriptor(Val, State);
+ packagesDescriptor ->
+ tr_PackagesDescriptor(Val, State);
+ emptyDescriptors ->
+ tr_EmptyDescriptors(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_EmptyDescriptors(#'AuditDescriptor'{auditToken = Tokens},
+ State) ->
+ Tokens2 =
+ case Tokens of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ _ -> [tr_auditItem(Token, State) || Token <- Tokens]
+ end,
+ #'AuditDescriptor'{auditToken = Tokens2}.
+
+tr_NotifyRequest(#'NotifyRequest'{terminationID = IdList,
+ observedEventsDescriptor = ObsDesc,
+ errorDescriptor = ErrDesc},
+ State) ->
+ %% BUGBUG: Mismatch between ASN.1 and ABNF
+ %% BUGBUG: The following ought to be a 'choice'
+ #'NotifyRequest'{terminationID = [tr_TerminationID(Id, State) ||
+ Id <- IdList],
+ observedEventsDescriptor = tr_ObservedEventsDescriptor(ObsDesc, State),
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State)}.
+
+tr_NotifyReply(#'NotifyReply'{terminationID = IdList,
+ errorDescriptor = ErrDesc},
+ State) ->
+ #'NotifyReply'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ errorDescriptor = tr_opt_ErrorDescriptor(ErrDesc, State)}.
+
+tr_ObservedEventsDescriptor(#'ObservedEventsDescriptor'{requestId = Id,
+ observedEventLst = Events},
+ State) when is_list (Events) ->
+ #'ObservedEventsDescriptor'{requestId = tr_RequestID(Id, State),
+ observedEventLst = [tr_ObservedEvent(E, State) || E <- Events]}.
+
+%% ;time per event, because it might be buffered
+%% observedEvent = [ TimeStamp LWSP COLON] LWSP
+%% pkgdName [ LBRKT observedEventParameter
+%% *(COMMA observedEventParameter) RBRKT ]
+%%
+%% ;at-most-once eventStream, every eventParameterName at most once
+%% observedEventParameter = eventStream / eventOther
+
+tr_ObservedEvent(#'ObservedEvent'{eventName = Name,
+ streamID = Id,
+ eventParList = Parms,
+ timeNotation = Time},
+ State) ->
+ #'ObservedEvent'{eventName = tr_EventName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ eventParList = [tr_EventParameter(P, Name, State) || P <- Parms],
+ timeNotation = tr_opt_TimeNotation(Time, State)}.
+
+tr_EventName(Name, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ resolve(event, Name, State, Constraint).
+
+tr_EventParameter(#'EventParameter'{eventParameterName = ParName,
+ value = Value,
+ extraInfo = Extra},
+ EventName,
+ State) ->
+ %% BUGBUG: event parameter name
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ N = resolve({event_parameter, EventName}, ParName, State, Constraint),
+ #'EventParameter'{eventParameterName = N,
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_ServiceChangeRequest(#'ServiceChangeRequest'{terminationID = IdList,
+ serviceChangeParms = Parms},
+ State) ->
+ #'ServiceChangeRequest'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ serviceChangeParms = tr_ServiceChangeParm(Parms, State)}.
+
+%% serviceChangeReply = ServiceChangeToken EQUAL TerminationID
+%% [LBRKT (errorDescriptor /
+%% serviceChangeReplyDescriptor) RBRKT]
+%% serviceChangeReplyDescriptor = ServicesToken LBRKT
+%% servChgReplyParm *(COMMA servChgReplyParm) RBRKT
+%%
+%% ;at-most-once. Version is REQUIRED on first ServiceChange response
+%% servChgReplyParm = (serviceChangeAddress / serviceChangeMgcId /
+%% serviceChangeProfile / serviceChangeVersion )
+tr_ServiceChangeReply(#'ServiceChangeReply'{terminationID = IdList,
+ serviceChangeResult = Res},
+ State) ->
+ #'ServiceChangeReply'{terminationID = [tr_TerminationID(Id, State) || Id <- IdList],
+ serviceChangeResult = tr_ServiceChangeResult(Res, State)}.
+
+tr_ServiceChangeResult({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ errorDescriptor -> tr_ErrorDescriptor(Val, State);
+ serviceChangeResParms -> tr_ServiceChangeResParm(Val, State)
+ end,
+ {Tag, Val2}.
+
+%% TerminationID = "ROOT" / pathNAME / "$" / "*"
+%% ; Total length of pathNAME must not exceed 64 chars.
+%% pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
+%% ["@" pathDomainName ]
+
+tr_TerminationID(TermId, State) when State#state.mode =/= verify ->
+ resolve(term_id, TermId, State, valid);
+tr_TerminationID(#'TerminationID'{wildcard = Wild,
+ id = Id},
+ _State) ->
+ #'TerminationID'{wildcard = Wild,
+ id = Id};
+tr_TerminationID(#megaco_term_id{contains_wildcards = IsWild,
+ id = Id},
+ State) ->
+ #megaco_term_id{contains_wildcards = tr_bool(IsWild, State),
+ id = [tr_term_id_component(Sub, State) || Sub <- Id]}.
+
+tr_opt_bool(asn1_NOVALUE, _State) -> asn1_NOVALUE;
+tr_opt_bool(Bool, State) -> tr_bool(Bool, State).
+
+tr_bool(true, _State) -> true;
+tr_bool(false, _State) -> false.
+
+tr_term_id_component(Sub, _State) ->
+ case Sub of
+ all -> all;
+ choose -> choose;
+ Char when is_integer(Char) -> Char
+ end.
+
+%% mediaDescriptor = MediaToken LBRKT mediaParm *(COMMA mediaParm) RBRKT
+%% ; at-most-once per item
+%% ; and either streamParm or streamDescriptor but not both
+%% mediaParm = (streamParm / streamDescriptor /
+%% terminationStateDescriptor)
+%% ; at-most-once
+%% streamParm = ( localDescriptor / remoteDescriptor /
+%% localControlDescriptor )
+%% streamDescriptor = StreamToken EQUAL StreamID LBRKT streamParm
+%% *(COMMA streamParm) RBRKT
+tr_MediaDescriptor(#'MediaDescriptor'{termStateDescr = TermState,
+ streams = Streams},
+ State) ->
+ #'MediaDescriptor'{termStateDescr = tr_opt_TerminationStateDescriptor(TermState, State),
+ streams = tr_opt_streams(Streams, State)}.
+
+tr_opt_streams(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_streams({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ oneStream -> tr_StreamParms(Val, State);
+ multiStream -> [tr_StreamDescriptor(SD, State) || SD <- Val]
+ end,
+ {Tag, Val2}.
+
+tr_StreamParms(#'StreamParms'{localControlDescriptor = LCD,
+ localDescriptor = LD,
+ remoteDescriptor = RD,
+ statisticsDescriptor = SD},
+ State) ->
+ LCD2 = tr_opt_LocalControlDescriptor(LCD, State),
+ LD2 = tr_opt_LocalRemoteDescriptor(LD, State),
+ RD2 = tr_opt_LocalRemoteDescriptor(RD, State),
+ SD2 = tr_opt_StatisticsDescriptor(SD, State),
+ #'StreamParms'{localControlDescriptor = LCD2,
+ localDescriptor = LD2,
+ remoteDescriptor = RD2,
+ statisticsDescriptor = SD2}.
+
+tr_StreamDescriptor(#'StreamDescriptor'{streamID = Id,
+ streamParms = Parms},
+ State) ->
+ #'StreamDescriptor'{streamID = tr_StreamID(Id, State),
+ streamParms = tr_StreamParms(Parms, State)}.
+
+%% localControlDescriptor = LocalControlToken LBRKT localParm
+%% *(COMMA localParm) RBRKT
+%%
+%% ; at-most-once per item
+%% localParm = ( streamMode / propertyParm /
+%% reservedValueMode / reservedGroupMode )
+%% reservedValueMode = ReservedValueToken EQUAL ( "ON" / "OFF" )
+%% reservedGroupMode = ReservedGroupToken EQUAL ( "ON" / "OFF" )
+%%
+%% reservedMode = ReservedToken EQUAL ( "ON" / "OFF" )
+%%
+%% streamMode = ModeToken EQUAL streamModes
+tr_opt_LocalControlDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_LocalControlDescriptor(#'LocalControlDescriptor'{streamMode = Mode,
+ reserveGroup = Group,
+ reserveValue = Value,
+ propertyParms = Props},
+ State) ->
+ #'LocalControlDescriptor'{streamMode = tr_opt_StreamMode(Mode, State),
+ reserveGroup = tr_opt_bool(Group, State),
+ reserveValue = tr_opt_bool(Value, State),
+ propertyParms = [tr_PropertyParm(P, State) || P <- Props]}.
+
+tr_opt_StreamMode(Mode, _State) ->
+ case Mode of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ sendOnly -> sendOnly;
+ recvOnly -> recvOnly;
+ sendRecv -> sendRecv;
+ inactive -> inactive;
+ loopBack -> loopBack
+ end.
+
+tr_Name(Name, State) ->
+ %% BUGBUG: transform
+ %% BUGBUG: NAME = ALPHA *63(ALPHA / DIGIT / "_" )
+ tr_STRING(Name, State, 2, 2).
+
+tr_PkgdName(Name, State) ->
+ %% BUGBUG: transform
+ %% BUGBUG: pkgdName = (NAME / "*") SLASH (ItemID / "*" )
+ tr_OCTET_STRING(Name, State, 4, 4).
+
+%% When text encoding the protocol, the descriptors consist of session
+%% descriptions as defined in SDP (RFC2327), except that the "s=", "t="
+%% and "o=" lines are optional. When multiple session descriptions are
+%% provided in one descriptor, the "v=" lines are required as delimiters;
+%% otherwise they are optional. Implementations shall accept session
+%% descriptions that are fully conformant to RFC2327. When binary
+%% encoding the protocol the descriptor consists of groups of properties
+%% (tag-value pairs) as specified in Annex C. Each such group may
+%% contain the parameters of a session description.
+tr_opt_LocalRemoteDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_LocalRemoteDescriptor(#'LocalRemoteDescriptor'{propGrps = Groups},
+ State) ->
+ #'LocalRemoteDescriptor'{propGrps = [tr_PropertyGroup(G, State) || G <- Groups]}.
+
+tr_PropertyGroup(Props, State) ->
+ [tr_PropertyGroupParm(P, State) || P <- Props].
+
+tr_PropertyGroupParm(#'PropertyParm'{name = Name,
+ value = Value},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'PropertyParm'{name = resolve(property, Name, State, Constraint),
+ value = tr_OCTET_STRING(Value, State, 0, infinity)}.
+
+tr_PropertyParm(#'PropertyParm'{name = Name,
+ value = Value,
+ extraInfo = Extra},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'PropertyParm'{name = resolve(property, Name, State, Constraint),
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_opt_extraInfo(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_extraInfo({relation, Rel}, _State) ->
+ Rel2 =
+ case Rel of
+ greaterThan -> greaterThan;
+ smallerThan -> smallerThan;
+ unequalTo -> unequalTo
+ end,
+ {relation, Rel2};
+tr_opt_extraInfo({range, Range}, State) ->
+ Range2 = tr_bool(Range, State),
+ {range, Range2};
+tr_opt_extraInfo({sublist, Sub}, State) ->
+ Sub2 = tr_bool(Sub, State),
+ {sublist, Sub2}.
+
+tr_opt_TerminationStateDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TerminationStateDescriptor(#'TerminationStateDescriptor'{propertyParms = Props,
+ eventBufferControl = Control,
+ serviceState = Service},
+ State) ->
+ #'TerminationStateDescriptor'{propertyParms = [tr_PropertyParm(P, State) || P <- Props],
+ eventBufferControl = tr_opt_EventBufferControl(Control, State),
+ serviceState = tr_opt_ServiceState(Service, State)}.
+
+tr_opt_EventBufferControl(Control, _State) ->
+ case Control of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ off -> off;
+ lockStep -> lockStep
+ end.
+
+tr_opt_ServiceState(Service, _State) ->
+ case Service of
+ asn1_NOVALUE -> asn1_NOVALUE;
+ test -> test;
+ outOfSvc -> outOfSvc;
+ inSvc -> inSvc
+ end.
+
+tr_MuxDescriptor(#'MuxDescriptor'{muxType = Type,
+ termList = IdList},
+ State) ->
+ #'MuxDescriptor'{muxType = tr_MuxType(Type, State),
+ termList = [tr_TerminationID(Id, State) || Id <- IdList]}.
+
+tr_MuxType(Type, _State) ->
+ case Type of
+ h221 -> h221;
+ h223 -> h223;
+ h226 -> h226;
+ v76 -> v76
+ end.
+
+tr_opt_StreamID(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_StreamID(Id, State) ->
+ tr_StreamID(Id, State).
+
+tr_StreamID(Id, State) ->
+ tr_UINT16(Id, State).
+
+tr_EventsDescriptor(#'EventsDescriptor'{requestID = Id,
+ eventList = Events},
+ State) ->
+ #'EventsDescriptor'{requestID = tr_opt_RequestID(Id, State),
+ eventList = [tr_RequestedEvent(E, State) || E <- Events]}.
+
+tr_RequestedEvent(#'RequestedEvent'{pkgdName = Name,
+ streamID = Id,
+ evParList = Parms,
+ eventAction = Actions},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'RequestedEvent'{pkgdName = resolve(event, Name, State, Constraint),
+ streamID = tr_opt_StreamID(Id, State),
+ eventAction = tr_opt_RequestedActions(Actions, State),
+ evParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+tr_RegulatedEmbeddedDescriptor(
+ #'RegulatedEmbeddedDescriptor'{secondEvent = SE,
+ signalsDescriptor = SD}, State) ->
+ SE2 = tr_opt_SecondEventsDescriptor(SE, State),
+ SD2 = tr_opt_SignalsDescriptor(SD, State),
+ #'RegulatedEmbeddedDescriptor'{secondEvent = SE2,
+ signalsDescriptor = SD2}.
+
+tr_opt_NotifyBehaviour(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_NotifyBehaviour(NB, State) ->
+ tr_NotifyBehaviour(NB, State).
+
+tr_NotifyBehaviour({notifyImmediate, 'NULL'} = NB, _State) ->
+ NB;
+tr_NotifyBehaviour({notifyRegulated = Tag, Val}, State) ->
+ {Tag, tr_RegulatedEmbeddedDescriptor(Val, State)};
+tr_NotifyBehaviour({neverNotify, 'NULL'} = NB, _State) ->
+ NB.
+
+tr_opt_RequestedActions(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_RequestedActions(#'RequestedActions'{keepActive = KA,
+ eventDM = DM,
+ secondEvent = SE,
+ signalsDescriptor = SD,
+ notifyBehaviour = NB,
+ resetEventsDescriptor = RSD},
+ State) ->
+ KA2 = tr_opt_keepActive(KA, State),
+ DM2 = tr_opt_EventDM(DM, State),
+ SE2 = tr_opt_SecondEventsDescriptor(SE, State),
+ SD2 = tr_opt_SignalsDescriptor(SD, State),
+ NB2 = tr_opt_NotifyBehaviour(NB, State),
+ RSD2 = tr_opt_null(RSD, State),
+ #'RequestedActions'{keepActive = KA2,
+ eventDM = DM2,
+ secondEvent = SE2,
+ signalsDescriptor = SD2,
+ notifyBehaviour = NB2,
+ resetEventsDescriptor = RSD2}.
+
+tr_opt_keepActive(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_keepActive(Keep, State) ->
+ tr_bool(Keep, State).
+
+tr_opt_EventDM(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_EventDM({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ digitMapName -> tr_DigitMapName(Val, State);
+ digitMapValue -> tr_DigitMapValue(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_opt_SecondEventsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SecondEventsDescriptor(#'SecondEventsDescriptor'{requestID = Id,
+ eventList = Events},
+ State) ->
+ #'SecondEventsDescriptor'{requestID = tr_RequestID(Id, State), %% IG v6 6.8 withdrawn
+ eventList = [tr_SecondRequestedEvent(E, State) || E <- Events]}.
+
+tr_SecondRequestedEvent(#'SecondRequestedEvent'{pkgdName = Name,
+ streamID = Id,
+ evParList = Parms,
+ eventAction = Actions},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'SecondRequestedEvent'{pkgdName = resolve(event, Name, State, Constraint),
+ streamID = tr_opt_StreamID(Id, State),
+ eventAction = tr_opt_SecondRequestedActions(Actions, State),
+ evParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+
+tr_opt_SecondRequestedActions(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SecondRequestedActions(
+ #'SecondRequestedActions'{keepActive = KA,
+ eventDM = DM,
+ signalsDescriptor = SD,
+ notifyBehaviour = NB,
+ resetEventsDescriptor = RSD},
+ State) ->
+ KA2 = tr_opt_keepActive(KA, State),
+ DM2 = tr_opt_EventDM(DM, State),
+ SD2 = tr_opt_SignalsDescriptor(SD, State),
+ NB2 = tr_opt_NotifyBehaviour(NB, State),
+ RSD2 = tr_opt_null(RSD, State),
+ #'SecondRequestedActions'{keepActive = KA2,
+ eventDM = DM2,
+ signalsDescriptor = SD2,
+ notifyBehaviour = NB2,
+ resetEventsDescriptor = RSD2}.
+
+tr_EventBufferDescriptor(EventSpecs, State) ->
+ [tr_EventSpec(ES, State) || ES <- EventSpecs].
+
+tr_EventSpec(#'EventSpec'{eventName = Name,
+ streamID = Id,
+ eventParList = Parms},
+ State) ->
+ #'EventSpec'{eventName = tr_EventName(Name, State),
+ streamID = tr_opt_StreamID(Id, State),
+ eventParList = [tr_EventParameter(P, Name, State) || P <- Parms]}.
+
+tr_opt_SignalsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_SignalsDescriptor(SigDesc, State) ->
+ tr_SignalsDescriptor(SigDesc, State).
+
+tr_SignalsDescriptor(SigDesc, State) when is_list(SigDesc) ->
+ [tr_SignalRequest(SigReq, State) || SigReq <- SigDesc].
+
+tr_SignalRequest({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ signal -> tr_Signal(Val, State);
+ seqSigList -> tr_SeqSigList(Val, State)
+ end,
+ {Tag, Val2}.
+
+
+tr_SeqSigList(#'SeqSigList'{id = Id,
+ signalList = SigList},
+ State) when is_list(SigList) ->
+ #'SeqSigList'{id = tr_UINT16(Id, State),
+ signalList = [tr_Signal(Sig, State) || Sig <- SigList]}.
+
+tr_Signal(#'Signal'{signalName = Name,
+ streamID = SID,
+ sigType = Type,
+ duration = Dur,
+ notifyCompletion = Compl,
+ keepActive = Keep,
+ sigParList = Parms,
+ direction = Dir,
+ requestID = RID,
+ intersigDelay = ID},
+ State) ->
+ Name2 = tr_SignalName(Name, State),
+ SID2 = tr_opt_StreamID(SID, State),
+ Type2 = tr_opt_SignalType(Type, State),
+ Dur2 = tr_opt_UINT16(Dur, State),
+ Compl2 = tr_opt_NotifyCompletion(Compl, State),
+ Keep2 = tr_opt_keepActive(Keep, State),
+ Parms2 = [tr_SigParameter(P, Name, State) || P <- Parms],
+ Dir2 = tr_opt_SignalDirection(Dir, State),
+ RID2 = tr_opt_RequestID(RID, State),
+ ID2 = tr_opt_UINT16(ID, State),
+ #'Signal'{signalName = Name2,
+ streamID = SID2,
+ sigType = Type2,
+ duration = Dur2,
+ notifyCompletion = Compl2,
+ keepActive = Keep2,
+ sigParList = Parms2,
+ direction = Dir2,
+ requestID = RID2,
+ intersigDelay = ID2}.
+
+tr_opt_NotifyCompletion(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_NotifyCompletion(Items, State) when is_list(Items) ->
+ [tr_notifyCompletionItem(I, State) || I <- Items].
+
+tr_notifyCompletionItem(Item, _State) ->
+ case Item of
+ onTimeOut -> onTimeOut;
+ onInterruptByEvent -> onInterruptByEvent;
+ onInterruptByNewSignalDescr -> onInterruptByNewSignalDescr;
+ otherReason -> otherReason;
+ onIteration -> onIteration
+ end.
+
+tr_opt_SignalType(asn1_NOVALUE = Type, _State) ->
+ Type;
+tr_opt_SignalType(Type, _State) ->
+ case Type of
+ brief -> brief;
+ onOff -> onOff;
+ timeOut -> timeOut
+ end.
+
+tr_opt_SignalDirection(asn1_NOVALUE = SD, _State) ->
+ SD;
+tr_opt_SignalDirection(SD, _State) ->
+ case SD of
+ internal -> internal;
+ external -> external;
+ both -> both
+ end.
+
+tr_SignalName(Name, State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ resolve(signal, Name, State, Constraint).
+
+tr_SigParameter(#'SigParameter'{sigParameterName = ParName,
+ value = Value,
+ extraInfo = Extra},
+ SigName,
+ State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ N = resolve({signal_parameter, SigName}, ParName, State, Constraint),
+ #'SigParameter'{sigParameterName = N,
+ value = tr_Value(Value, State),
+ extraInfo = tr_opt_extraInfo(Extra, State)}.
+
+tr_opt_RequestID(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_RequestID(Id, State) ->
+ tr_RequestID(Id, State).
+
+tr_RequestID(Id, _State) when Id =:= ?megaco_all_request_id ->
+ ?megaco_all_request_id;
+tr_RequestID(Id, State) ->
+ tr_UINT32(Id, State).
+
+tr_ModemDescriptor(_MD, _State) ->
+ deprecated.
+
+tr_DigitMapDescriptor(#'DigitMapDescriptor'{digitMapName = Name,
+ digitMapValue = Value},
+ State) ->
+ #'DigitMapDescriptor'{digitMapName = tr_opt_DigitMapName(Name, State),
+ digitMapValue = tr_opt_DigitMapValue(Value, State)}.
+
+tr_opt_DigitMapName(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_DigitMapName(Name, State) ->
+ tr_DigitMapName(Name, State).
+
+tr_DigitMapName(Name, State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ resolve(dialplan, Name, State, Constraint).
+
+tr_opt_DigitMapValue(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_DigitMapValue(Value, State) ->
+ tr_DigitMapValue(Value, State).
+
+tr_DigitMapValue(#'DigitMapValue'{digitMapBody = Body,
+ startTimer = Start,
+ shortTimer = Short,
+ longTimer = Long},
+ State) ->
+ #'DigitMapValue'{startTimer = tr_opt_timer(Start, State),
+ shortTimer = tr_opt_timer(Short, State),
+ longTimer = tr_opt_timer(Long, State),
+ digitMapBody = tr_STRING(Body, State)}. %% BUGBUG: digitMapBody not handled at all
+
+tr_opt_timer(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_timer(Timer, State) ->
+ tr_DIGIT(Timer, State, 0, 99).
+
+tr_ServiceChangeParm(
+ #'ServiceChangeParm'{serviceChangeMethod = Method,
+ serviceChangeAddress = Addr,
+ serviceChangeVersion = Version,
+ serviceChangeProfile = Profile,
+ serviceChangeReason = Reason,
+ serviceChangeDelay = Delay,
+ serviceChangeMgcId = MgcId,
+ timeStamp = Time,
+ serviceChangeInfo = Info,
+ serviceChangeIncompleteFlag = Incomplete},
+ State) ->
+ Method2 = tr_ServiceChangeMethod(Method, State),
+ Addr2 = tr_opt_ServiceChangeAddress(Addr, State),
+ Version2 = tr_opt_serviceChangeVersion(Version, State),
+ Profile2 = tr_opt_ServiceChangeProfile(Profile, State),
+ Reason2 = tr_serviceChangeReason(Reason, State),
+ Delay2 = tr_opt_serviceChangeDelay(Delay, State),
+ MgcId2 = tr_opt_serviceChangeMgcId(MgcId, State),
+ Time2 = tr_opt_TimeNotation(Time, State),
+ Info2 = tr_opt_AuditDescriptor(Info, State),
+ Incomplete2 = tr_opt_null(Incomplete, State),
+ #'ServiceChangeParm'{serviceChangeMethod = Method2,
+ serviceChangeAddress = Addr2,
+ serviceChangeVersion = Version2,
+ serviceChangeProfile = Profile2,
+ serviceChangeReason = Reason2,
+ serviceChangeDelay = Delay2,
+ serviceChangeMgcId = MgcId2,
+ timeStamp = Time2,
+ serviceChangeInfo = Info2,
+ serviceChangeIncompleteFlag = Incomplete2}.
+
+tr_ServiceChangeMethod(Method, _State) ->
+ case Method of
+ failover -> failover;
+ forced -> forced;
+ graceful -> graceful;
+ restart -> restart;
+ disconnected -> disconnected;
+ handOff -> handOff
+ end. %% BUGBUG: extension
+
+tr_opt_ServiceChangeAddress(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_ServiceChangeAddress({Tag, Val}, State) ->
+ Val2 =
+ case Tag of
+ portNumber -> tr_portNumber(Val, State);
+ ip4Address -> tr_IP4Address(Val, State);
+ ip6Address -> tr_IP6Address(Val, State);
+ domainName -> tr_DomainName(Val, State);
+ deviceName -> tr_PathName(Val, State);
+ mtpAddress -> tr_mtpAddress(Val, State)
+ end,
+ {Tag, Val2}.
+
+tr_opt_serviceChangeVersion(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeVersion(Version, State) ->
+ tr_version(Version, State).
+
+tr_opt_ServiceChangeProfile(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+%% Decode
+tr_opt_ServiceChangeProfile({'ServiceChangeProfile', ProfileName}, State) ->
+ case string:tokens(ProfileName, "/") of
+ [Name0, Version0] ->
+ Name = tr_STRING(Name0, State, 1, 64),
+ Version = tr_version(list_to_integer(Version0), State),
+ #'ServiceChangeProfile'{profileName = Name,
+ version = Version}
+ end;
+%% Encode
+tr_opt_ServiceChangeProfile(#'ServiceChangeProfile'{profileName = Name0,
+ version = Version0},
+ State) ->
+ Name = tr_STRING(Name0, State, 1, 64),
+ Version = tr_version(Version0, State),
+ ProfileName = lists:flatten(io_lib:format("~s/~w", [Name, Version])),
+ {'ServiceChangeProfile', ProfileName}.
+
+tr_serviceChangeReason([_] = Reason, State) ->
+ tr_Value(Reason, State).
+
+tr_opt_serviceChangeDelay(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeDelay(Delay, State) ->
+ tr_UINT32(Delay, State).
+
+tr_opt_serviceChangeMgcId(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_serviceChangeMgcId(MgcId, State) ->
+ tr_MId(MgcId, State).
+
+tr_opt_portNumber(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_portNumber(Port, State) ->
+ tr_portNumber(Port, State).
+
+tr_portNumber(Port, State) when is_integer(Port) andalso (Port >= 0) ->
+ tr_UINT16(Port, State).
+
+tr_ServiceChangeResParm(#'ServiceChangeResParm'{serviceChangeMgcId = MgcId,
+ serviceChangeAddress = Addr,
+ serviceChangeVersion = Version,
+ serviceChangeProfile = Profile,
+ timeStamp = Time},
+ State) ->
+ #'ServiceChangeResParm'{serviceChangeMgcId = tr_opt_serviceChangeMgcId(MgcId, State),
+ serviceChangeAddress = tr_opt_ServiceChangeAddress(Addr, State),
+ serviceChangeVersion = tr_opt_serviceChangeVersion(Version, State),
+ serviceChangeProfile = tr_opt_ServiceChangeProfile(Profile, State),
+ timeStamp = tr_opt_TimeNotation(Time, State)}.
+
+tr_PackagesDescriptor(Items, State) when is_list(Items) ->
+ [tr_PackagesItem(I, State) || I <- Items].
+
+tr_PackagesItem(#'PackagesItem'{packageName = Name,
+ packageVersion = Version},
+ State) ->
+ Constraint = fun(Item) -> tr_Name(Item, State) end,
+ #'PackagesItem'{packageName = resolve(package, Name, State, Constraint),
+ packageVersion = tr_UINT16(Version, State)}.
+
+tr_opt_StatisticsDescriptor(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_StatisticsDescriptor(Parms, State) ->
+ tr_StatisticsDescriptor(Parms, State).
+
+tr_StatisticsDescriptor(Parms, State) when is_list(Parms) ->
+ [tr_StatisticsParameter(P, State) || P <- Parms].
+
+tr_StatisticsParameter(#'StatisticsParameter'{statName = Name,
+ statValue = Value},
+ State) ->
+ Constraint = fun(Item) -> tr_PkgdName(Item, State) end,
+ #'StatisticsParameter'{statName = resolve(statistics, Name, State, Constraint),
+ statValue = tr_opt_Value(Value, State)}.
+
+tr_opt_TimeNotation(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_TimeNotation(#'TimeNotation'{date = Date,
+ time = Time},
+ State) ->
+ #'TimeNotation'{date = tr_STRING(Date, State, 8, 8), % "yyyymmdd"
+ time = tr_STRING(Time, State, 8, 8)}.% "hhmmssss"
+
+%% BUGBUG: Does not verify that string must contain at least one char
+%% BUGBUG: This violation of the is required in order to comply with
+%% BUGBUG: the dd/ce ds parameter that may possibly be empty.
+
+tr_opt_Value(asn1_NOVALUE, _State) ->
+ asn1_NOVALUE;
+tr_opt_Value(Value, State) ->
+ tr_Value(Value, State).
+
+tr_Value(Strings, _State) when is_list(Strings) ->
+ [[Char || Char <- String] || String <- Strings].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Encode an octet string, escape } by \ if necessary
+tr_OCTET_STRING(String, _State, Min, Max) when is_list(String) ->
+ verify_count(length(String), Min, Max),
+ String.
+
+tr_QUOTED_STRING(String, _State) when is_list(String) ->
+ verify_count(length(String), 1, infinity),
+ String.
+
+%% The internal format of hex digits is a list of octets
+%% Min and Max means #hexDigits
+%% Leading zeros are prepended in order to fulfill Min
+tr_HEXDIG(Octets, _State, Min, Max) when is_list(Octets) ->
+ verify_count(length(Octets), Min, Max),
+ Octets.
+
+tr_DIGIT(Val, State, Min, Max) ->
+ tr_integer(Val, State, Min, Max).
+
+tr_STRING(String, _State) when is_list(String) ->
+ String.
+
+tr_STRING(String, _State, Min, Max) when is_list(String) ->
+ verify_count(length(String), Min, Max),
+ String.
+
+tr_opt_UINT16(Val, State) ->
+ tr_opt_integer(Val, State, 0, 65535).
+
+tr_UINT16(Val, State) ->
+ tr_integer(Val, State, 0, 65535).
+
+tr_UINT32(Val, State) ->
+ tr_integer(Val, State, 0, 4294967295).
+
+tr_opt_integer(asn1_NOVALUE, _State, _Min, _Max) ->
+ asn1_NOVALUE;
+tr_opt_integer(Int, State, Min, Max) ->
+ tr_integer(Int, State, Min, Max).
+
+tr_integer(Int, _State, Min, Max) ->
+ verify_count(Int, Min, Max),
+ Int.
+
+%% Verify that Count is within the range of Min and Max
+verify_count(Count, Min, Max) ->
+ if
+ is_integer(Count) ->
+ if
+ is_integer(Min) andalso (Count >= Min) ->
+ if
+ is_integer(Max) andalso (Count =< Max) ->
+ Count;
+ Max =:= infinity ->
+ Count;
+ true ->
+ error({count_too_large, Count, Max})
+ end;
+ true ->
+ error({count_too_small, Count, Min})
+ end;
+ true ->
+ error({count_not_an_integer, Count})
+ end.
+
+
+%% -------------------------------------------------------------------
+
+error(Reason) ->
+ erlang:error(Reason).
+
+
diff --git a/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3a.set.asn b/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3a.set.asn
new file mode 100644
index 0000000000..b9ba7ffdb4
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3a.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3a.asn
diff --git a/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3b.set.asn b/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3b.set.asn
new file mode 100644
index 0000000000..0437bde310
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3b.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3b.asn
diff --git a/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3c.set.asn b/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3c.set.asn
new file mode 100644
index 0000000000..e78055fbad
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3c.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3c.asn
diff --git a/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v1.set.asn b/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v1.set.asn
new file mode 100644
index 0000000000..0f5a92dba1
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v1.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v1.asn
diff --git a/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v2.set.asn b/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v2.set.asn
new file mode 100644
index 0000000000..7fc82b127f
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v2.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v2.asn
diff --git a/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v3.set.asn b/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v3.set.asn
new file mode 100644
index 0000000000..1d7950a283
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v3.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v3.asn
diff --git a/lib/megaco/src/binary/megaco_per_bin_encoder.erl b/lib/megaco/src/binary/megaco_per_bin_encoder.erl
new file mode 100644
index 0000000000..f7280f4e04
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_bin_encoder.erl
@@ -0,0 +1,447 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose : Handle ASN.1 PER encoding of Megaco/H.248
+%%----------------------------------------------------------------------
+
+-module(megaco_per_bin_encoder).
+
+-behaviour(megaco_encoder).
+
+-export([encode_message/3, decode_message/3,
+ decode_mini_message/3,
+
+ encode_transaction/3,
+ encode_action_requests/3,
+ encode_action_request/3,
+ encode_action_reply/3,
+
+ version_of/2]).
+
+%% Backward compatible functions:
+-export([encode_message/2, decode_message/2]).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+
+-define(V1_ASN1_MOD, megaco_per_bin_media_gateway_control_v1).
+-define(V2_ASN1_MOD, megaco_per_bin_media_gateway_control_v2).
+-define(V3_ASN1_MOD, megaco_per_bin_media_gateway_control_v3).
+-define(PREV3A_ASN1_MOD, megaco_per_bin_media_gateway_control_prev3a).
+-define(PREV3B_ASN1_MOD, megaco_per_bin_media_gateway_control_prev3b).
+-define(PREV3C_ASN1_MOD, megaco_per_bin_media_gateway_control_prev3c).
+-define(V1_ASN1_MOD_DRV, megaco_per_bin_drv_media_gateway_control_v1).
+-define(V2_ASN1_MOD_DRV, megaco_per_bin_drv_media_gateway_control_v2).
+-define(V3_ASN1_MOD_DRV, megaco_per_bin_drv_media_gateway_control_v3).
+-define(PREV3A_ASN1_MOD_DRV, megaco_per_bin_drv_media_gateway_control_prev3a).
+-define(PREV3B_ASN1_MOD_DRV, megaco_per_bin_drv_media_gateway_control_prev3b).
+-define(PREV3C_ASN1_MOD_DRV, megaco_per_bin_drv_media_gateway_control_prev3c).
+
+-define(V1_TRANS_MOD, megaco_binary_transformer_v1).
+-define(V2_TRANS_MOD, megaco_binary_transformer_v2).
+-define(V3_TRANS_MOD, megaco_binary_transformer_v3).
+-define(PREV3A_TRANS_MOD, megaco_binary_transformer_prev3a).
+-define(PREV3B_TRANS_MOD, megaco_binary_transformer_prev3b).
+-define(PREV3C_TRANS_MOD, megaco_binary_transformer_prev3c).
+
+-define(BIN_LIB, megaco_binary_encoder_lib).
+
+
+%%----------------------------------------------------------------------
+%% Detect (check/get) message version
+%% Return {ok, Version} | {error, Reason}
+%%----------------------------------------------------------------------
+
+version_of([{version3,v3},driver|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD_DRV, ?V2_ASN1_MOD_DRV, ?V3_ASN1_MOD_DRV],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3c},driver|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD_DRV, ?V2_ASN1_MOD_DRV, ?PREV3C_ASN1_MOD_DRV],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3b},driver|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD_DRV, ?V2_ASN1_MOD_DRV, ?PREV3B_ASN1_MOD_DRV],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3a},driver|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD_DRV, ?V2_ASN1_MOD_DRV, ?PREV3A_ASN1_MOD_DRV],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([driver|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD_DRV, ?V2_ASN1_MOD_DRV, ?V3_ASN1_MOD_DRV],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,v3}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3c}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3C_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3b}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3B_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3a}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3A_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+version_of(EC, Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders).
+
+
+%%----------------------------------------------------------------------
+%% Convert a 'MegacoMessage' record into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_message(EC,
+ #'MegacoMessage'{mess = #'Message'{version = V}} = MegaMsg) ->
+ encode_message(EC, V, MegaMsg).
+
+
+%% -- Version 1 --
+
+encode_message([{version3, _},driver|EC], 1, MegaMsg) ->
+ AsnMod = ?V1_ASN1_MOD_DRV,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([driver|EC], 1, MegaMsg) ->
+ AsnMod = ?V1_ASN1_MOD_DRV,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,_}|EC], 1, MegaMsg) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+encode_message(EC, 1, MegaMsg) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+
+%% -- Version 2 --
+
+encode_message([{version3,_},driver|EC], 2, MegaMsg) ->
+ AsnMod = ?V2_ASN1_MOD_DRV,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([driver|EC], 2, MegaMsg) ->
+ AsnMod = ?V2_ASN1_MOD_DRV,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,_}|EC], 2, MegaMsg) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+encode_message(EC, 2, MegaMsg) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+
+%% -- Version 3 --
+
+encode_message([{version3,v3},driver|EC], 3, MegaMsg) ->
+ AsnMod = ?V3_ASN1_MOD_DRV,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3c},driver|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3C_ASN1_MOD_DRV,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3b},driver|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3B_ASN1_MOD_DRV,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3a},driver|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3A_ASN1_MOD_DRV,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([driver|EC], 3, MegaMsg) ->
+ AsnMod = ?V3_ASN1_MOD_DRV,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,v3}|EC], 3, MegaMsg) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3c}|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3C_ASN1_MOD,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3b}|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3B_ASN1_MOD,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3a}|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3A_ASN1_MOD,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+encode_message(EC, 3, MegaMsg) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list).
+
+
+%%----------------------------------------------------------------------
+%% Convert a transaction (or transactions in the case of ack) record(s)
+%% into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+%% encode_transaction([] = EC, 1, Trans) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction([native] = EC, 1, Trans) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction([driver|EC], 1, Trans) ->
+%% AsnMod = ?V1_ASN1_MOD_DRV,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+encode_transaction(_EC, 1, _Trans) ->
+ %% AsnMod = ?V1_ASN1_MOD,
+ %% TransMod = ?V1_TRANS_MOD,
+ %% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+ %% io_list);
+ {error, not_implemented};
+
+%% encode_transaction([] = EC, 2, Trans) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction([native] = EC, 2, Trans) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction([driver|EC], 2, Trans) ->
+%% AsnMod = ?V2_ASN1_MOD_DRV,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+encode_transaction(_EC, 2, _Trans) ->
+ %% AsnMod = ?V2_ASN1_MOD,
+ %% TransMod = ?V2_TRANS_MOD,
+ %% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+ %% io_list).
+ {error, not_implemented};
+
+%% encode_transaction([] = EC, 3, Trans) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction([native] = EC, 3, Trans) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+%% encode_transaction([driver|EC], 3, Trans) ->
+%% AsnMod = ?V3_ASN1_MOD_DRV,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+encode_transaction(_EC, 3, _Trans) ->
+ %% AsnMod = ?V3_ASN1_MOD,
+ %% TransMod = ?V3_TRANS_MOD,
+ %% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod, %% io_list).
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a list of ActionRequest record's into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_requests(_EC, 1, ActReqs) when is_list(ActReqs) ->
+ %% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list);
+ {error, not_implemented};
+encode_action_requests(_EC, 2, ActReqs) when is_list(ActReqs) ->
+ %% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented};
+encode_action_requests(_EC, 3, ActReqs) when is_list(ActReqs) ->
+ %% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a ActionRequest record into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_request(_EC, 1, _ActReq) ->
+ %% ?BIN_LIB:encode_action_request(EC, ActReq,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list);
+ {error, not_implemented};
+encode_action_request(_EC, 2, _ActReq) ->
+ %% ?BIN_LIB:encode_action_request(EC, ActReq,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented};
+encode_action_request(_EC, 3, _ActReq) ->
+ %% ?BIN_LIB:encode_action_request(EC, ActReq,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a action reply into a deep io list
+%% Not yest supported by this binary codec!
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_action_reply(_EC, _V, _AcionReply) ->
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a binary into a 'MegacoMessage' record
+%% Return {ok, MegacoMessageRecord} | {error, Reason}
+%%----------------------------------------------------------------------
+
+decode_message(EC, Binary) ->
+ decode_message(EC, 1, Binary).
+
+%% PER does not support partial decode, so this means V1
+decode_message(EC, dynamic, Binary) ->
+ decode_message(EC, 1, Binary);
+
+
+%% -- Version 1 --
+
+decode_message([{version3,_},driver|EC], 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD_DRV,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([driver|EC], 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD_DRV,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,_}|EC], 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+decode_message(EC, 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+
+%% -- Version 2 --
+
+decode_message([{version3,_},driver|EC], 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD_DRV,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([driver|EC], 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD_DRV,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,_}|EC], 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+decode_message(EC, 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+
+%% -- Version 3 --
+
+decode_message([{version3,v3},driver|EC], 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD_DRV,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3c},driver|EC], 3, Binary) ->
+ AsnMod = ?PREV3C_ASN1_MOD_DRV,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3b},driver|EC], 3, Binary) ->
+ AsnMod = ?PREV3B_ASN1_MOD_DRV,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3a},driver|EC], 3, Binary) ->
+ AsnMod = ?PREV3A_ASN1_MOD_DRV,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([driver|EC], 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD_DRV,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,v3}|EC], 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3c}|EC], 3, Binary) ->
+ AsnMod = ?PREV3C_ASN1_MOD,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3b}|EC], 3, Binary) ->
+ AsnMod = ?PREV3B_ASN1_MOD,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3a}|EC], 3, Binary) ->
+ AsnMod = ?PREV3A_ASN1_MOD,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+%% All values we need to take (special) care of has been delt with,
+%% so just pass the rest on
+decode_message(EC, 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary).
+
+
+decode_mini_message(_EC, _Vsn, _Bin) ->
+ {error, not_implemented}.
diff --git a/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3a.set.asn b/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3a.set.asn
new file mode 100644
index 0000000000..b9ba7ffdb4
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3a.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3a.asn
diff --git a/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3b.set.asn b/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3b.set.asn
new file mode 100644
index 0000000000..0437bde310
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3b.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3b.asn
diff --git a/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3c.set.asn b/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3c.set.asn
new file mode 100644
index 0000000000..e78055fbad
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3c.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3c.asn
diff --git a/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_v1.set.asn b/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_v1.set.asn
new file mode 100644
index 0000000000..0f5a92dba1
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_v1.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v1.asn
diff --git a/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_v2.set.asn b/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_v2.set.asn
new file mode 100644
index 0000000000..7fc82b127f
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_v2.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v2.asn
diff --git a/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_v3.set.asn b/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_v3.set.asn
new file mode 100644
index 0000000000..1d7950a283
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_bin_media_gateway_control_v3.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v3.asn
diff --git a/lib/megaco/src/binary/megaco_per_encoder.erl b/lib/megaco/src/binary/megaco_per_encoder.erl
new file mode 100644
index 0000000000..596e621c65
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_encoder.erl
@@ -0,0 +1,291 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose : Handle ASN.1 PER encoding of Megaco/H.248
+%%----------------------------------------------------------------------
+
+-module(megaco_per_encoder).
+
+-behaviour(megaco_encoder).
+
+-export([encode_message/3, decode_message/3,
+ decode_mini_message/3,
+
+ encode_transaction/3,
+ encode_action_requests/3,
+ encode_action_request/3,
+ encode_action_reply/3,
+
+ version_of/2]).
+
+%% Backward compatible functions:
+-export([encode_message/2, decode_message/2]).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+
+-define(V1_ASN1_MOD, megaco_per_media_gateway_control_v1).
+-define(V2_ASN1_MOD, megaco_per_media_gateway_control_v2).
+-define(V3_ASN1_MOD, megaco_per_media_gateway_control_v3).
+-define(PREV3A_ASN1_MOD, megaco_per_media_gateway_control_prev3a).
+-define(PREV3B_ASN1_MOD, megaco_per_media_gateway_control_prev3b).
+-define(PREV3C_ASN1_MOD, megaco_per_media_gateway_control_prev3c).
+
+-define(V1_TRANS_MOD, megaco_binary_transformer_v1).
+-define(V2_TRANS_MOD, megaco_binary_transformer_v2).
+-define(V3_TRANS_MOD, megaco_binary_transformer_v3).
+-define(PREV3A_TRANS_MOD, megaco_binary_transformer_prev3a).
+-define(PREV3B_TRANS_MOD, megaco_binary_transformer_prev3b).
+-define(PREV3C_TRANS_MOD, megaco_binary_transformer_prev3c).
+
+-define(BIN_LIB, megaco_binary_encoder_lib).
+
+
+%%----------------------------------------------------------------------
+%% Detect (check/get) message version
+%% Return {ok, Version} | {error, Reason}
+%%----------------------------------------------------------------------
+
+version_of([{version3,v3}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3c}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3C_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3b}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3B_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3a}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3A_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of(EC, Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders).
+
+
+%%----------------------------------------------------------------------
+%% Convert a 'MegacoMessage' record into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_message(EC,
+ #'MegacoMessage'{mess = #'Message'{version = V}} = MegaMsg) ->
+ encode_message(EC, V, MegaMsg).
+
+
+%% -- Version 1 --
+
+encode_message([{version3,_}|EC], 1, MegaMsg) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message(EC, 1, MegaMsg) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+
+%% -- Version 2 --
+
+encode_message([{version3,_}|EC], 2, MegaMsg) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message(EC, 2, MegaMsg) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+
+
+%% -- Version 3 --
+
+encode_message([{version3,v3}|EC], 3, MegaMsg) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3c}|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3C_ASN1_MOD,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3b}|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3B_ASN1_MOD,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message([{version3,prev3a}|EC], 3, MegaMsg) ->
+ AsnMod = ?PREV3A_ASN1_MOD,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list);
+encode_message(EC, 3, MegaMsg) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:encode_message(EC, MegaMsg, AsnMod, TransMod, io_list).
+
+
+%%----------------------------------------------------------------------
+%% Convert a transaction (or transactions in the case of ack) record(s)
+%% into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_transaction(_EC, 1, _Trans) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented};
+encode_transaction(_EC, 2, _Trans) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented};
+encode_transaction(_EC, 3, _Trans) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_transaction(EC, Trans, AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a list of ActionRequest record's into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_requests(_EC, 1, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented};
+encode_action_requests(_EC, 2, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented};
+encode_action_requests(_EC, 3, ActReqs) when is_list(ActReqs) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+%% AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a ActionRequest record into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_request(_EC, 1, _ActReq) ->
+%% AsnMod = ?V1_ASN1_MOD,
+%% TransMod = ?V1_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented};
+encode_action_request(_EC, 2, _ActReq) ->
+%% AsnMod = ?V2_ASN1_MOD,
+%% TransMod = ?V2_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented};
+encode_action_request(_EC, 3, _ActReq) ->
+%% AsnMod = ?V3_ASN1_MOD,
+%% TransMod = ?V3_TRANS_MOD,
+%% ?BIN_LIB:encode_action_request(EC, ActReq,
+%% AsnMod, TransMod,
+%% io_list);
+ {error, not_implemented}.
+
+
+
+%%----------------------------------------------------------------------
+%% Convert a action reply into a deep io list
+%% Not yest supported by this binary codec!
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_action_reply(_EC, _V, _AcionReply) ->
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a binary into a 'MegacoMessage' record
+%% Return {ok, MegacoMessageRecord} | {error, Reason}
+%%----------------------------------------------------------------------
+
+decode_message(EC, Binary) ->
+ decode_message(EC, 1, Binary).
+
+%% PER does not support partial decode, so this means V1
+decode_message(EC, dynamic, Binary) ->
+ decode_message(EC, 1, Binary);
+
+
+%% -- Version 1 --
+
+decode_message([{version3,_}|EC], 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, io_list);
+decode_message(EC, 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, io_list);
+
+%% -- Version 2 --
+
+decode_message([{version3,_}|EC], 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, io_list);
+decode_message(EC, 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, io_list);
+
+%% -- Version 3 --
+
+decode_message([{version3,v3}|EC], 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, io_list);
+decode_message([{version3,prev3c}|EC], 3, Binary) ->
+ AsnMod = ?PREV3C_ASN1_MOD,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, io_list);
+decode_message([{version3,prev3b}|EC], 3, Binary) ->
+ AsnMod = ?PREV3B_ASN1_MOD,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, io_list);
+decode_message([{version3,prev3a}|EC], 3, Binary) ->
+ AsnMod = ?PREV3A_ASN1_MOD,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, io_list);
+decode_message(EC, 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, io_list).
+
+decode_mini_message(_EC, _Vsn, _Bin) ->
+ {error, not_implemented}.
diff --git a/lib/megaco/src/binary/megaco_per_media_gateway_control_prev3a.set.asn b/lib/megaco/src/binary/megaco_per_media_gateway_control_prev3a.set.asn
new file mode 100644
index 0000000000..b9ba7ffdb4
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_media_gateway_control_prev3a.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3a.asn
diff --git a/lib/megaco/src/binary/megaco_per_media_gateway_control_prev3b.set.asn b/lib/megaco/src/binary/megaco_per_media_gateway_control_prev3b.set.asn
new file mode 100644
index 0000000000..0437bde310
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_media_gateway_control_prev3b.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3b.asn
diff --git a/lib/megaco/src/binary/megaco_per_media_gateway_control_prev3c.set.asn b/lib/megaco/src/binary/megaco_per_media_gateway_control_prev3c.set.asn
new file mode 100644
index 0000000000..e78055fbad
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_media_gateway_control_prev3c.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-prev3c.asn
diff --git a/lib/megaco/src/binary/megaco_per_media_gateway_control_v1.set.asn b/lib/megaco/src/binary/megaco_per_media_gateway_control_v1.set.asn
new file mode 100644
index 0000000000..0f5a92dba1
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_media_gateway_control_v1.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v1.asn
diff --git a/lib/megaco/src/binary/megaco_per_media_gateway_control_v2.set.asn b/lib/megaco/src/binary/megaco_per_media_gateway_control_v2.set.asn
new file mode 100644
index 0000000000..7fc82b127f
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_media_gateway_control_v2.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v2.asn
diff --git a/lib/megaco/src/binary/megaco_per_media_gateway_control_v3.set.asn b/lib/megaco/src/binary/megaco_per_media_gateway_control_v3.set.asn
new file mode 100644
index 0000000000..1d7950a283
--- /dev/null
+++ b/lib/megaco/src/binary/megaco_per_media_gateway_control_v3.set.asn
@@ -0,0 +1 @@
+MEDIA-GATEWAY-CONTROL-v3.asn
diff --git a/lib/megaco/src/binary/modules.mk b/lib/megaco/src/binary/modules.mk
new file mode 100644
index 0000000000..a86ce2aecc
--- /dev/null
+++ b/lib/megaco/src/binary/modules.mk
@@ -0,0 +1,128 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+MODULES = \
+ megaco_binary_encoder \
+ megaco_binary_encoder_lib \
+ megaco_ber_encoder \
+ megaco_ber_media_gateway_control_v1 \
+ megaco_ber_media_gateway_control_v2 \
+ megaco_ber_media_gateway_control_prev3a \
+ megaco_ber_media_gateway_control_prev3b \
+ megaco_ber_media_gateway_control_prev3c \
+ megaco_ber_media_gateway_control_v3 \
+ megaco_ber_bin_encoder \
+ megaco_ber_bin_media_gateway_control_v1 \
+ megaco_ber_bin_media_gateway_control_v2 \
+ megaco_ber_bin_media_gateway_control_prev3a \
+ megaco_ber_bin_media_gateway_control_prev3b \
+ megaco_ber_bin_media_gateway_control_prev3c \
+ megaco_ber_bin_media_gateway_control_v3 \
+ megaco_ber_bin_drv_media_gateway_control_v1 \
+ megaco_ber_bin_drv_media_gateway_control_v2 \
+ megaco_ber_bin_drv_media_gateway_control_prev3a \
+ megaco_ber_bin_drv_media_gateway_control_prev3b \
+ megaco_ber_bin_drv_media_gateway_control_prev3c \
+ megaco_ber_bin_drv_media_gateway_control_v3 \
+ megaco_per_encoder \
+ megaco_per_media_gateway_control_v1 \
+ megaco_per_media_gateway_control_v2 \
+ megaco_per_media_gateway_control_prev3a \
+ megaco_per_media_gateway_control_prev3b \
+ megaco_per_media_gateway_control_prev3c \
+ megaco_per_media_gateway_control_v3 \
+ megaco_per_bin_encoder \
+ megaco_per_bin_media_gateway_control_v1 \
+ megaco_per_bin_media_gateway_control_v2 \
+ megaco_per_bin_media_gateway_control_prev3a \
+ megaco_per_bin_media_gateway_control_prev3b \
+ megaco_per_bin_media_gateway_control_prev3c \
+ megaco_per_bin_media_gateway_control_v3 \
+ megaco_per_bin_drv_media_gateway_control_v1 \
+ megaco_per_bin_drv_media_gateway_control_v2 \
+ megaco_per_bin_drv_media_gateway_control_prev3a \
+ megaco_per_bin_drv_media_gateway_control_prev3b \
+ megaco_per_bin_drv_media_gateway_control_prev3c \
+ megaco_per_bin_drv_media_gateway_control_v3 \
+ megaco_binary_name_resolver_v1 \
+ megaco_binary_name_resolver_v2 \
+ megaco_binary_name_resolver_prev3a \
+ megaco_binary_name_resolver_prev3b \
+ megaco_binary_name_resolver_prev3c \
+ megaco_binary_name_resolver_v3 \
+ megaco_binary_term_id \
+ megaco_binary_term_id_gen \
+ megaco_binary_transformer_v1 \
+ megaco_binary_transformer_v2 \
+ megaco_binary_transformer_prev3a \
+ megaco_binary_transformer_prev3b \
+ megaco_binary_transformer_prev3c \
+ megaco_binary_transformer_v3
+
+INTERNAL_HRL_FILES =
+
+ASN1_V1_SPEC = MEDIA-GATEWAY-CONTROL-v1
+ASN1_V2_SPEC = MEDIA-GATEWAY-CONTROL-v2
+ASN1_PREV3A_SPEC = MEDIA-GATEWAY-CONTROL-prev3a
+ASN1_PREV3B_SPEC = MEDIA-GATEWAY-CONTROL-prev3b
+ASN1_PREV3C_SPEC = MEDIA-GATEWAY-CONTROL-prev3c
+ASN1_V3_SPEC = MEDIA-GATEWAY-CONTROL-v3
+
+BER_ASN1_V1_SPEC = megaco_ber_media_gateway_control_v1
+BER_BIN_ASN1_V1_SPEC = megaco_ber_bin_media_gateway_control_v1
+BER_BIN_DRV_ASN1_V1_SPEC = megaco_ber_bin_drv_media_gateway_control_v1
+PER_ASN1_V1_SPEC = megaco_per_media_gateway_control_v1
+PER_BIN_ASN1_V1_SPEC = megaco_per_bin_media_gateway_control_v1
+PER_BIN_DRV_ASN1_V1_SPEC = megaco_per_bin_drv_media_gateway_control_v1
+
+BER_ASN1_V2_SPEC = megaco_ber_media_gateway_control_v2
+BER_BIN_ASN1_V2_SPEC = megaco_ber_bin_media_gateway_control_v2
+BER_BIN_DRV_ASN1_V2_SPEC = megaco_ber_bin_drv_media_gateway_control_v2
+PER_ASN1_V2_SPEC = megaco_per_media_gateway_control_v2
+PER_BIN_ASN1_V2_SPEC = megaco_per_bin_media_gateway_control_v2
+PER_BIN_DRV_ASN1_V2_SPEC = megaco_per_bin_drv_media_gateway_control_v2
+
+BER_ASN1_PREV3A_SPEC = megaco_ber_media_gateway_control_prev3a
+BER_BIN_ASN1_PREV3A_SPEC = megaco_ber_bin_media_gateway_control_prev3a
+BER_BIN_DRV_ASN1_PREV3A_SPEC = megaco_ber_bin_drv_media_gateway_control_prev3a
+PER_ASN1_PREV3A_SPEC = megaco_per_media_gateway_control_prev3a
+PER_BIN_ASN1_PREV3A_SPEC = megaco_per_bin_media_gateway_control_prev3a
+PER_BIN_DRV_ASN1_PREV3A_SPEC = megaco_per_bin_drv_media_gateway_control_prev3a
+
+BER_ASN1_PREV3B_SPEC = megaco_ber_media_gateway_control_prev3b
+BER_BIN_ASN1_PREV3B_SPEC = megaco_ber_bin_media_gateway_control_prev3b
+BER_BIN_DRV_ASN1_PREV3B_SPEC = megaco_ber_bin_drv_media_gateway_control_prev3b
+PER_ASN1_PREV3B_SPEC = megaco_per_media_gateway_control_prev3b
+PER_BIN_ASN1_PREV3B_SPEC = megaco_per_bin_media_gateway_control_prev3b
+PER_BIN_DRV_ASN1_PREV3B_SPEC = megaco_per_bin_drv_media_gateway_control_prev3b
+
+BER_ASN1_PREV3C_SPEC = megaco_ber_media_gateway_control_prev3c
+BER_BIN_ASN1_PREV3C_SPEC = megaco_ber_bin_media_gateway_control_prev3c
+BER_BIN_DRV_ASN1_PREV3C_SPEC = megaco_ber_bin_drv_media_gateway_control_prev3c
+PER_ASN1_PREV3C_SPEC = megaco_per_media_gateway_control_prev3c
+PER_BIN_ASN1_PREV3C_SPEC = megaco_per_bin_media_gateway_control_prev3c
+PER_BIN_DRV_ASN1_PREV3C_SPEC = megaco_per_bin_drv_media_gateway_control_prev3c
+
+BER_ASN1_V3_SPEC = megaco_ber_media_gateway_control_v3
+BER_BIN_ASN1_V3_SPEC = megaco_ber_bin_media_gateway_control_v3
+BER_BIN_DRV_ASN1_V3_SPEC = megaco_ber_bin_drv_media_gateway_control_v3
+PER_ASN1_V3_SPEC = megaco_per_media_gateway_control_v3
+PER_BIN_ASN1_V3_SPEC = megaco_per_bin_media_gateway_control_v3
+PER_BIN_DRV_ASN1_V3_SPEC = megaco_per_bin_drv_media_gateway_control_v3
+
diff --git a/lib/megaco/src/binary/old/megaco_ber_bin_drv_encoder.erl b/lib/megaco/src/binary/old/megaco_ber_bin_drv_encoder.erl
new file mode 100644
index 0000000000..a9217940a1
--- /dev/null
+++ b/lib/megaco/src/binary/old/megaco_ber_bin_drv_encoder.erl
@@ -0,0 +1,319 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose : Handle ASN.1 BER encoding of Megaco/H.248
+%%----------------------------------------------------------------------
+
+-module(megaco_ber_bin_drv_encoder).
+
+-behaviour(megaco_encoder).
+
+-export([encode_message/3, decode_message/3,
+ decode_mini_message/3,
+
+ encode_transaction/3,
+ encode_action_requests/3,
+ encode_action_request/3,
+ encode_action_reply/3,
+
+ version_of/2]).
+
+%% Backward compatible functions:
+-export([encode_message/2, decode_message/2]).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+
+-define(V1_ASN1_MOD, megaco_ber_bin_drv_media_gateway_control_v1).
+-define(V2_ASN1_MOD, megaco_ber_bin_drv_media_gateway_control_v2).
+-define(V3_ASN1_MOD, megaco_ber_bin_drv_media_gateway_control_v3).
+-define(PREV3A_ASN1_MOD, megaco_ber_bin_drv_media_gateway_control_prev3a).
+-define(PREV3B_ASN1_MOD, megaco_ber_bin_drv_media_gateway_control_prev3b).
+-define(PREV3C_ASN1_MOD, megaco_ber_bin_drv_media_gateway_control_prev3c).
+
+-define(V1_TRANS_MOD, megaco_binary_transformer_v1).
+-define(V2_TRANS_MOD, megaco_binary_transformer_v2).
+-define(V3_TRANS_MOD, megaco_binary_transformer_v3).
+-define(PREV3A_TRANS_MOD, megaco_binary_transformer_prev3a).
+-define(PREV3B_TRANS_MOD, megaco_binary_transformer_prev3b).
+-define(PREV3C_TRANS_MOD, megaco_binary_transformer_prev3c).
+
+-define(BIN_LIB, megaco_binary_encoder_lib).
+
+
+%%----------------------------------------------------------------------
+%% Detect (check) which version a message is
+%% Return {ok, Version} | {error, Reason}
+%%----------------------------------------------------------------------
+
+version_of([{version3,v3}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3c}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3C_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3b}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3B_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of([{version3,prev3a}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3A_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
+version_of(EC, Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders).
+
+
+%%----------------------------------------------------------------------
+%% Convert a 'MegacoMessage' record into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+
+encode_message(EC,
+ #'MegacoMessage'{mess = #'Message'{version = V}} = MegaMsg) ->
+ encode_message(EC, V, MegaMsg).
+
+encode_message([{version3,_}|EC], 1, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg, ?V1_ASN1_MOD, ?V1_TRANS_MOD, io_list);
+encode_message(EC, 1, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg, ?V1_ASN1_MOD, ?V1_TRANS_MOD, io_list);
+encode_message([{version3,_}|EC], 2, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg, ?V2_ASN1_MOD, ?V2_TRANS_MOD, io_list);
+encode_message(EC, 2, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg, ?V2_ASN1_MOD, ?V2_TRANS_MOD, io_list);
+encode_message([{version3,v3}|EC], 3, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg, ?V3_ASN1_MOD, ?V3_TRANS_MOD, io_list);
+encode_message([{version3,prev3c}|EC], 3, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg,
+ ?PREV3C_ASN1_MOD, ?PREV3C_TRANS_MOD, io_list);
+encode_message([{version3,prev3b}|EC], 3, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg,
+ ?PREV3B_ASN1_MOD, ?PREV3B_TRANS_MOD, io_list);
+encode_message([{version3,prev3a}|EC], 3, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg,
+ ?PREV3A_ASN1_MOD, ?PREV3A_TRANS_MOD, io_list);
+encode_message(EC, 3, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg, ?V3_ASN1_MOD, ?V3_TRANS_MOD, io_list).
+
+
+%%----------------------------------------------------------------------
+%% Convert a transaction (or transactions in the case of ack) record(s)
+%% into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_transaction(EC, 1, Trans) ->
+ %% ?BIN_LIB:encode_transaction(EC, Trans,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list);
+ {error, not_implemented};
+encode_transaction(EC, 2, Trans) ->
+ %% ?BIN_LIB:encode_transaction(EC, Trans,
+ %% ?V2_ASN1_MOD,
+ %% ?V2_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented};
+encode_transaction(EC, 3, Trans) ->
+ %% ?BIN_LIB:encode_transaction(EC, Trans,
+ %% ?V3_ASN1_MOD,
+ %% ?V3_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a list of ActionRequest record's into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_requests(EC, 1, ActReqs) when is_list(ActReqs) ->
+ %% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list);
+ {error, not_implemented};
+encode_action_requests(EC, 2, ActReqs) when is_list(ActReqs) ->
+ %% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+ %% ?V2_ASN1_MOD,
+ %% ?V2_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented};
+encode_action_requests(EC, 3, ActReqs) when is_list(ActReqs) ->
+ %% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+ %% ?V3_ASN1_MOD,
+ %% ?V3_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a ActionRequest record into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_request(EC, 1, ActReq) ->
+ %% ?BIN_LIB:encode_action_request(EC, ActReq,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list);
+ {error, not_implemented};
+encode_action_request(EC, 2, ActReq) ->
+ %% ?BIN_LIB:encode_action_request(EC, ActReq,
+ %% ?V2_ASN1_MOD,
+ %% ?V2_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented};
+encode_action_request(EC, 3, ActReq) ->
+ %% ?BIN_LIB:encode_action_request(EC, ActReq,
+ %% ?V3_ASN1_MOD,
+ %% ?V3_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a action reply into a deep io list
+%% Not yest supported by this binary codec!
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_action_reply(_EC, _V, _AcionReply) ->
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a binary into a 'MegacoMessage' record
+%% Return {ok, MegacoMessageRecord} | {error, Reason}
+%%----------------------------------------------------------------------
+
+%% Old decode function
+decode_message(EC, Binary) ->
+ decode_message(EC, 1, Binary).
+
+%% Select from message
+%% This does not work at the moment so, we use version 1 for this
+decode_message([{version3,v3}|EC], dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD, ?V2_TRANS_MOD},
+ {?V3_ASN1_MOD, ?V3_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+decode_message([{version3,prev3c}|EC], dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD, ?V2_TRANS_MOD},
+ {?PREV3C_ASN1_MOD, ?PREV3C_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+decode_message([{version3,prev3b}|EC], dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD, ?V2_TRANS_MOD},
+ {?PREV3B_ASN1_MOD, ?PREV3B_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+decode_message([{version3,prev3a}|EC], dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD, ?V2_TRANS_MOD},
+ {?PREV3A_ASN1_MOD, ?PREV3A_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+decode_message(EC, dynamic, Binary) ->
+ Mods = [{?V1_ASN1_MOD, ?V1_TRANS_MOD},
+ {?V2_ASN1_MOD, ?V2_TRANS_MOD},
+ {?V3_ASN1_MOD, ?V3_TRANS_MOD}],
+ ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
+
+decode_message([{version3,_}|EC], 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message(EC, 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+decode_message([{version3,_}|EC], 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message(EC, 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+decode_message([{version3,v3}|EC], 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3c}|EC], 3, Binary) ->
+ AsnMod = ?PREV3C_ASN1_MOD,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3b}|EC], 3, Binary) ->
+ AsnMod = ?PREV3B_ASN1_MOD,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3a}|EC], 3, Binary) ->
+ AsnMod = ?PREV3A_ASN1_MOD,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message(EC, 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+
+decode_mini_message([{version3,v3}|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3c}|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3C_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3b}|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3B_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message([{version3,prev3a}|EC], dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3A_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+decode_mini_message(EC, dynamic, Bin) ->
+ Mods = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
+
+decode_mini_message([{version3,_}|EC], 1, Bin) ->
+ AsnMod = ?V1_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message(EC, 1, Bin) ->
+ AsnMod = ?V1_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,_}|EC], 2, Bin) ->
+ AsnMod = ?V2_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message(EC, 2, Bin) ->
+ AsnMod = ?V2_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,v3}|EC], 3, Bin) ->
+ AsnMod = ?V3_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3c}|EC], 3, Bin) ->
+ AsnMod = ?PREV3C_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3b}|EC], 3, Bin) ->
+ AsnMod = ?PREV3B_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message([{version3,prev3a}|EC], 3, Bin) ->
+ AsnMod = ?PREV3A_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
+decode_mini_message(EC, 3, Bin) ->
+ AsnMod = ?V3_ASN1_MOD,
+ ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary).
diff --git a/lib/megaco/src/binary/old/megaco_per_bin_drv_encoder.erl b/lib/megaco/src/binary/old/megaco_per_bin_drv_encoder.erl
new file mode 100644
index 0000000000..0afe6d9f36
--- /dev/null
+++ b/lib/megaco/src/binary/old/megaco_per_bin_drv_encoder.erl
@@ -0,0 +1,255 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose : Handle ASN.1 PER encoding of Megaco/H.248
+%%----------------------------------------------------------------------
+
+-module(megaco_per_bin_drv_encoder).
+
+-behaviour(megaco_encoder).
+
+-export([encode_message/2, decode_message/2,
+ encode_message/3, decode_message/3,
+ decode_mini_message/3,
+
+ encode_transaction/3,
+ encode_action_requests/3,
+ encode_action_request/3,
+ encode_action_reply/3,
+
+ version_of/2]).
+
+-include_lib("megaco/src/engine/megaco_message_internal.hrl").
+
+-define(V1_ASN1_MOD, megaco_per_bin_drv_media_gateway_control_v1).
+-define(V2_ASN1_MOD, megaco_per_bin_drv_media_gateway_control_v2).
+-define(V3_ASN1_MOD, megaco_per_bin_drv_media_gateway_control_v3).
+-define(PREV3A_ASN1_MOD, megaco_per_bin_drv_media_gateway_control_prev3a).
+-define(PREV3B_ASN1_MOD, megaco_per_bin_drv_media_gateway_control_prev3b).
+-define(PREV3C_ASN1_MOD, megaco_per_bin_drv_media_gateway_control_prev3c).
+
+-define(V1_TRANS_MOD, megaco_binary_transformer_v1).
+-define(V2_TRANS_MOD, megaco_binary_transformer_v2).
+-define(V3_TRANS_MOD, megaco_binary_transformer_V3).
+-define(PREV3A_TRANS_MOD, megaco_binary_transformer_prev3a).
+-define(PREV3B_TRANS_MOD, megaco_binary_transformer_prev3b).
+-define(PREV3C_TRANS_MOD, megaco_binary_transformer_prev3c).
+
+-define(BIN_LIB, megaco_binary_encoder_lib).
+
+
+%%----------------------------------------------------------------------
+%% Detect (check) which version a message is
+%% Return {ok, Version} | {error, Reason}
+%%----------------------------------------------------------------------
+
+version_of([{version3,v3}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3c}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3C_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3b}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3B_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of([{version3,prev3a}|EC], Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3A_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders);
+version_of(EC, Binary) ->
+ Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
+ ?BIN_LIB:version_of(EC, Binary, 1, Decoders).
+
+
+%%----------------------------------------------------------------------
+%% Convert a 'MegacoMessage' record into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_message(EC,
+ #'MegacoMessage'{mess = #'Message'{version = V}} = MegaMsg) ->
+ encode_message(EC, V, MegaMsg).
+
+encode_message([{version3,_}|EC], 1, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg, ?V1_ASN1_MOD, ?V1_TRANS_MOD, io_list);
+encode_message(EC, 1, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg, ?V1_ASN1_MOD, ?V1_TRANS_MOD, io_list);
+encode_message([{version3,_}|EC], 2, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg, ?V2_ASN1_MOD, ?V2_TRANS_MOD, io_list);
+encode_message(EC, 2, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg, ?V2_ASN1_MOD, ?V2_TRANS_MOD, io_list);
+encode_message([{version3,v3}|EC], 3, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg, ?V3_ASN1_MOD, ?V3_TRANS_MOD, io_list);
+encode_message([{version3,prev3c}|EC], 3, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg,
+ ?PREV3C_ASN1_MOD, ?PREV3C_TRANS_MOD, io_list);
+encode_message([{version3,prev3b}|EC], 3, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg,
+ ?PREV3B_ASN1_MOD, ?PREV3B_TRANS_MOD, io_list);
+encode_message([{version3,prev3a}|EC], 3, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg,
+ ?PREV3A_ASN1_MOD, ?PREV3A_TRANS_MOD, io_list);
+encode_message(EC, 3, MegaMsg) ->
+ ?BIN_LIB:encode_message(EC, MegaMsg, ?V3_ASN1_MOD, ?V3_TRANS_MOD, io_list).
+
+
+%%----------------------------------------------------------------------
+%% Convert a transaction (or transactions in the case of ack) record(s)
+%% into a binary
+%% Return {ok, Binary} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_transaction(_EC, 1, _Trans) ->
+ %% ?BIN_LIB:encode_transaction(EC,
+ %% Trans,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list);
+ {error, not_implemented};
+encode_transaction(_EC, 2, _Trans) ->
+ %% ?BIN_LIB:encode_transaction(EC,
+ %% Trans,
+ %% ?V2_ASN1_MOD,
+ %% ?V2_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented};
+encode_transaction(EC, prev3a, Trans) ->
+ %% ?BIN_LIB:encode_transaction(EC, Trans,
+ %% ?V3_ASN1_MOD,
+ %% ?V3_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented};
+encode_transaction(EC, 3, Trans) ->
+ encode_transaction(EC, prev3a, Trans).
+
+
+%%----------------------------------------------------------------------
+%% Convert a list of ActionRequest record's into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_requests(_EC, 1, ActReqs) when is_list(ActReqs) ->
+ %% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list);
+ {error, not_implemented};
+encode_action_requests(_EC, 2, ActReqs) when is_list(ActReqs) ->
+ %% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented};
+encode_action_requests(EC, 3, ActReqs) when is_list(ActReqs) ->
+ %% ?BIN_LIB:encode_action_requests(EC, ActReqs,
+ %% ?V3_ASN1_MOD,
+ %% ?V3_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a ActionRequest record into a binary
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+encode_action_request(_EC, 1, _ActReq) ->
+ %% ?BIN_LIB:encode_action_request(EC, ActReq,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list);
+ {error, not_implemented};
+encode_action_request(_EC, 2, _ActReq) ->
+ %% ?BIN_LIB:encode_action_request(EC, ActReq,
+ %% ?V1_ASN1_MOD,
+ %% ?V1_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented};
+encode_action_request(EC, 3, ActReq) ->
+ %% ?BIN_LIB:encode_action_request(EC, ActReq,
+ %% ?V3_ASN1_MOD,
+ %% ?V3_TRANS_MOD,
+ %% io_list).
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a action reply into a deep io list
+%% Not yest supported by this binary codec!
+%% Return {ok, DeepIoList} | {error, Reason}
+%%----------------------------------------------------------------------
+
+encode_action_reply(_EC, _V, _AcionReply) ->
+ {error, not_implemented}.
+
+
+%%----------------------------------------------------------------------
+%% Convert a binary into a 'MegacoMessage' record
+%% Return {ok, MegacoMessageRecord} | {error, Reason}
+%%----------------------------------------------------------------------
+
+%% Old decode function
+decode_message(EC, Binary) ->
+ decode_message(EC, 1, Binary).
+
+%% PER does not support partial decode, so this means V1
+decode_message(EC, dynamic, Binary) ->
+ decode_message(EC, 1, Binary);
+
+decode_message([{version3,_}|EC], 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message(EC, 1, Binary) ->
+ AsnMod = ?V1_ASN1_MOD,
+ TransMod = ?V1_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+decode_message([{version3,_}|EC], 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message(EC, 2, Binary) ->
+ AsnMod = ?V2_ASN1_MOD,
+ TransMod = ?V2_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+
+decode_message([{version3,v3}|EC], 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3c}|EC], 3, Binary) ->
+ AsnMod = ?PREV3C_ASN1_MOD,
+ TransMod = ?PREV3C_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3b}|EC], 3, Binary) ->
+ AsnMod = ?PREV3B_ASN1_MOD,
+ TransMod = ?PREV3B_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message([{version3,prev3a}|EC], 3, Binary) ->
+ AsnMod = ?PREV3A_ASN1_MOD,
+ TransMod = ?PREV3A_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
+decode_message(EC, 3, Binary) ->
+ AsnMod = ?V3_ASN1_MOD,
+ TransMod = ?V3_TRANS_MOD,
+ ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary).
+
+decode_mini_message(_EC, _Vsn, _Bin) ->
+ {error, not_implemented}.
+