1
%% ``The contents of this file are subject to the Erlang Public License,
2
%% Version 1.1, (the "License"); you may not use this file except in
3
%% compliance with the License. You should have received a copy of the
4
%% Erlang Public License along with this software. If not, it can be
5
%% retrieved via the world wide web at http://www.erlang.org/.
7
%% Software distributed under the License is distributed on an "AS IS"
8
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
%% the License for the specific language governing rights and limitations
12
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
14
%% AB. All Rights Reserved.''
18
%%----------------------------------------------------------------------
19
%% Purpose: Encode V2 Megaco/H.248 text messages from internal form
20
%% The following was changed:
21
%% - MuxType (Nx64kToken)
22
%% - auditItem (terminationAudit)
23
%% - serviceChangeParm (auditItem)
25
%% The following was added:
27
%%----------------------------------------------------------------------
29
%% -define(d(F,A), io:format("~w:" ++ F ++ "~n", [?MODULE|A])).
31
-define(META_ENC(Type, Item), Item) .
32
%% -define(META_ENC(Type, Item), megaco_meta_package:encode(text, Type, Item)).
33
%% -define(META_DEC(Type, Item), megaco_meta_package:decode(text, Type, Item)).
35
enc_MegacoMessage(Val) ->
37
enc_MegacoMessage(Val, State).
39
enc_MegacoMessage(Val, State)
40
when record(Val, 'MegacoMessage') ->
43
enc_AuthenticationHeader(Val#'MegacoMessage'.authHeader, State),
44
enc_Message(Val#'MegacoMessage'.mess, State)
47
%% Note that encoding the transaction this way
48
%% make the message look a bit strange.
49
enc_Transaction(Val) ->
51
enc_Transaction(Val, State).
53
%% Note that encoding the action request's this way
54
%% make the message look a bit strange.
55
enc_ActionRequests(Val) ->
57
enc_TransactionRequest_actions(Val, State).
59
%% Note that encoding the action request this way
60
%% make the message look a bit strange.
61
enc_ActionRequest(Val) ->
63
enc_ActionRequest(Val, State).
65
enc_CommandRequest(Val) ->
67
enc_CommandRequest(Val, State).
69
enc_ActionReply(Val) ->
71
enc_ActionReply(Val, State).
73
enc_AuthenticationHeader(asn1_NOVALUE, _State) ->
75
enc_AuthenticationHeader(Val, State)
76
when record(Val, 'AuthenticationHeader') ->
80
enc_SecurityParmIndex(Val#'AuthenticationHeader'.secParmIndex, State),
82
enc_SequenceNum(Val#'AuthenticationHeader'.seqNum, State),
84
enc_AuthData(Val#'AuthenticationHeader'.ad, State),
88
enc_SecurityParmIndex({'SecurityParmIndex',Val}, State) ->
89
enc_SecurityParmIndex(Val, State);
90
enc_SecurityParmIndex(Val, State) ->
93
enc_HEXDIG(Val, State, 8, 8)
96
enc_SequenceNum({'SequenceNum',Val}, State) ->
97
enc_SequenceNum(Val, State);
98
enc_SequenceNum(Val, State) ->
101
enc_HEXDIG(Val, State, 8, 8)
104
enc_AuthData({'AuthData',Val}, State) ->
105
enc_AuthData(Val, State);
106
enc_AuthData(Val, State) ->
109
enc_HEXDIG(Val, State, 24, 64) %% OTP-4710
112
enc_Message(Val, State)
113
when record(Val, 'Message') ->
117
enc_version(Val#'Message'.version, State),
119
enc_MId(Val#'Message'.mId, State),
121
enc_Message_messageBody(Val#'Message'.messageBody, State)
124
enc_version(Val, State) when integer(Val), Val >= 0 ->
125
enc_DIGIT(Val, State, 0, 99).
127
enc_Message_messageBody({'Message_messageBody',Val}, State) ->
128
enc_Message_messageBody(Val, State);
129
enc_Message_messageBody({Tag, Val}, State) ->
132
enc_ErrorDescriptor(Val, State);
134
enc_Message_messageBody_transactions(Val, State);
136
error({invalid_messageBody_tag, Tag})
139
enc_Message_messageBody_transactions({'Message_messageBody_transactions',Val},
141
enc_Message_messageBody_transactions(Val, State);
142
enc_Message_messageBody_transactions(Val, State)
143
when list(Val), Val /= []->
144
[enc_Transaction(T, State) || T <- Val].
146
enc_MId({'MId',Val}, State) ->
148
enc_MId({Tag, Val}, State) ->
151
enc_IP4Address(Val, State);
153
enc_IP6Address(Val, State);
155
enc_DomainName(Val, State);
157
enc_PathName(Val, State);
159
enc_mtpAddress(Val, State);
161
error({invalid_MId_tag, Tag})
164
enc_mtpAddress(Val, State) ->
168
enc_OCTET_STRING(Val, State, 2, 4),
172
enc_DomainName(Val, State)
173
when record(Val, 'DomainName') ->
176
%% BUGBUG: (ALPHA / DIGIT) *63(ALPHA / DIGIT / "-" / ".")
177
enc_STRING(Val#'DomainName'.name, State, 1, 64),
179
case Val#'DomainName'.portNumber of
185
enc_portNumber(PortNumber, State)
190
enc_IP4Address(Val, State)
191
when record(Val, 'IP4Address') ->
192
[A1, A2, A3, A4] = Val#'IP4Address'.address,
195
enc_V4hex(A1, State),
197
enc_V4hex(A2, State),
199
enc_V4hex(A3, State),
201
enc_V4hex(A4, State),
203
case Val#'IP4Address'.portNumber of
209
enc_portNumber(PortNumber, State)
214
enc_V4hex(Val, State) ->
215
enc_DIGIT(Val, State, 0, 255).
217
enc_IP6Address(Val, State)
218
when record(Val, 'IP6Address'),
219
list(Val#'IP6Address'.address),
220
length(Val#'IP6Address'.address) == 16 ->
223
enc_IP6Address_address(Val#'IP6Address'.address, State),
225
case Val#'IP6Address'.portNumber of
231
enc_portNumber(PortNumber, State)
236
enc_IP6Address_address([0, 0|Addr], State) ->
237
enc_IP6Address_address2(Addr, 1, false, true, State);
238
enc_IP6Address_address(Addr, State) ->
239
enc_IP6Address_address2(Addr, 0, false, false, State).
241
enc_IP6Address_address2([0,0], 0, _Padding, _First, _State) ->
243
enc_IP6Address_address2([0,0], PadN, false, true, _State) when PadN > 0 ->
244
[$:, $:]; % Padding from the beginning (all zero's)
245
enc_IP6Address_address2([0,0], PadN, false, false, _State) when PadN > 0 ->
246
[$:]; % Padding in the middle or end
247
enc_IP6Address_address2([0,0], _, true, _First, _State) ->
249
enc_IP6Address_address2([N1,N2], 0, _Padding, _First, State) ->
250
[enc_hex4([N1, N2], State)];
251
enc_IP6Address_address2([N1,N2], 1, _Padding, _First, State) ->
252
[$0, $:, enc_hex4([N1, N2], State)];
253
enc_IP6Address_address2([N1,N2], PadN, false, true, State) when PadN > 1 ->
254
[$:, $:, enc_hex4([N1, N2], State)];
255
enc_IP6Address_address2([N1,N2], PadN, false, false, State) when PadN > 1 ->
256
[$:, enc_hex4([N1, N2], State)];
257
enc_IP6Address_address2([N1,N2], _PadN, true, _First, State) ->
258
[enc_hex4([N1, N2], State)];
259
enc_IP6Address_address2([0, 0|Ns], PadN, false, First, State) ->
260
enc_IP6Address_address2(Ns, PadN+1, false, First, State);
261
enc_IP6Address_address2([0, 0|Ns], _PadN, true, _First, State) ->
265
enc_IP6Address_address2(Ns, 0, true, false, State)
267
enc_IP6Address_address2([N1, N2|Ns], 0, Padded, _First, State) ->
269
enc_hex4([N1, N2], State),
271
enc_IP6Address_address2(Ns, 0, Padded, false, State)
273
enc_IP6Address_address2([N1, N2|Ns], 1, Padded, _First, State) ->
277
enc_hex4([N1, N2], State),
279
enc_IP6Address_address2(Ns, 0, Padded, false, State)
281
enc_IP6Address_address2([N1, N2|Ns], PadN, false, true, State) when PadN > 1 ->
282
%% Padding from the beginning
286
enc_hex4([N1, N2], State),
288
enc_IP6Address_address2(Ns, 0, true, false, State)
290
enc_IP6Address_address2([N1, N2|Ns], PadN, false, false, State)
293
$:, %% The other ':' has already added
294
enc_hex4([N1, N2], State),
296
enc_IP6Address_address2(Ns, 0, true, false, State)
298
enc_IP6Address_address2([N1, N2|Ns], _PadN, true, _First, State) ->
300
enc_hex4([N1, N2], State),
302
enc_IP6Address_address2(Ns, 0, true, false, State)
306
enc_hex4([0,0], _State) ->
308
enc_hex4([0,N], _State) ->
310
enc_hex4([N1, N2], _State) when N2 =< 15 ->
311
[hex(N1), $0, hex(N2)];
312
enc_hex4([N1, N2], _State) ->
315
enc_PathName({'PathName',Val}, State) ->
316
enc_PathName(Val, State);
317
enc_PathName(Val, State) ->
318
%% BUGBUG: ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
319
%% BUGBUG: ["@" pathDomainName ]
320
enc_STRING(Val, State, 1, 64).
322
enc_Transaction(Bin, _State) when binary(Bin) ->
323
[Bin]; %% Already encoded...
324
enc_Transaction({'Transaction',Val}, State) ->
325
enc_Transaction(Val, State);
326
enc_Transaction({Tag, Val}, State) ->
328
transactionRequest ->
329
enc_TransactionRequest(Val, State);
330
transactionPending ->
331
enc_TransactionPending(Val, State);
333
enc_TransactionReply(Val, State);
334
transactionResponseAck ->
335
enc_TransactionResponseAck(Val, State);
337
error({invalid_Transaction_tag, Tag})
340
enc_TransactionResponseAck([Mand | Opt], State) ->
343
?LBRKT_INDENT(State),
344
[enc_TransactionAck(Mand, State) |
345
[[?COMMA_INDENT(State), enc_TransactionAck(Val, State)] || Val <- Opt]],
349
enc_TransactionAck(Val, State)
350
when record(Val, 'TransactionAck') ->
352
enc_TransactionId(Val#'TransactionAck'.firstAck, ?INC_INDENT(State)),
353
case Val#'TransactionAck'.lastAck of
357
["-",enc_TransactionId(LastAck, State)]
361
enc_TransactionId({'TransactionId',Val}, State) ->
362
enc_TransactionId(Val, State);
363
enc_TransactionId(Val, State) ->
364
enc_UINT32(Val, State).
366
enc_TransactionRequest(#'TransactionRequest'{transactionId = Tid,
367
actions = Acts}, State) ->
371
enc_TransactionId(Tid, State),
372
?LBRKT_INDENT(State),
373
enc_TransactionRequest_actions(Acts, ?INC_INDENT(State)),
376
enc_TransactionRequest(Bin, _State) when binary(Bin) ->
379
enc_TransactionRequest_actions(Bin, _State) when binary(Bin) ->
380
[Bin]; %% Already encoded...
381
enc_TransactionRequest_actions({'TransactionRequest_actions',Val}, State) ->
382
enc_TransactionRequest_actions(Val, State);
383
enc_TransactionRequest_actions([Mand | Opt], State) ->
384
[enc_ActionRequest(Mand, State) |
385
[[?COMMA_INDENT(State), enc_ActionRequest(Val, State)] || Val <- Opt]].
387
enc_TransactionPending(#'TransactionPending'{transactionId = Tid}, State) ->
390
enc_TransactionId(Tid, State),
391
?LBRKT_INDENT(State),
394
enc_TransactionPending(Bin, _State) when binary(Bin) ->
397
enc_TransactionReply(#'TransactionReply'{transactionId = Tid,
398
immAckRequired = Req,
399
transactionResult = Res}, State) ->
403
enc_TransactionId(Tid, State),
404
?LBRKT_INDENT(State),
405
enc_immAckRequired(Req, State),
406
enc_TransactionReply_transactionResult(Res, ?INC_INDENT(State)),
409
enc_TransactionReply(Bin, _State) when binary(Bin) ->
412
enc_immAckRequired(Val, _State) ->
417
[?ImmAckRequiredToken, ?COMMA_INDENT(?INC_INDENT(_State))]
420
enc_TransactionReply_transactionResult({'TransactionReply_transactionResult',
422
enc_TransactionReply_transactionResult(Val, State);
423
enc_TransactionReply_transactionResult({Tag, Val}, State) ->
426
enc_ErrorDescriptor(Val, State);
428
enc_TransactionReply_transactionResult_actionReplies(Val, State);
430
error({invalid_TransactionReply_transactionResult_tag, Tag})
433
enc_TransactionReply_transactionResult_actionReplies({'TransactionReply_transactionResult_actionReplies',Val}, State) ->
434
enc_TransactionReply_transactionResult_actionReplies(Val, State);
435
enc_TransactionReply_transactionResult_actionReplies([Mand | Opt], State) ->
436
[enc_ActionReply(Mand, State),
437
[[?COMMA_INDENT(State), enc_ActionReply(Val, State)] || Val <- Opt]].
439
enc_ErrorDescriptor(Val, State)
440
when record(Val, 'ErrorDescriptor') ->
444
enc_ErrorCode(Val#'ErrorDescriptor'.errorCode, State),
446
case Val#'ErrorDescriptor'.errorText of
450
enc_ErrorText(ErrorText, State)
455
enc_ErrorCode({'ErrorCode',Val}, State)->
456
enc_ErrorCode(Val, State);
457
enc_ErrorCode(Val, State) ->
458
enc_DIGIT(Val, State, 0, 999).
460
enc_ErrorText({'ErrorText',Val}, State) ->
461
enc_ErrorText(Val, State);
462
enc_ErrorText(Val, State) ->
463
enc_QUOTED_STRING(Val, State).
465
enc_ContextID({'ContextID',Val}, State) ->
466
enc_ContextID(Val, State);
467
enc_ContextID(Val, State) ->
469
?megaco_all_context_id -> $*;
470
?megaco_null_context_id -> $-;
471
?megaco_choose_context_id -> $$;
472
Int when integer(Int) -> enc_UINT32(Int, State)
475
enc_ActionRequest(Bin, _State) when binary(Bin) ->
476
[Bin]; %% Already encoded...
477
enc_ActionRequest(Val, State)
478
when record(Val, 'ActionRequest') ->
482
enc_ContextID(Val#'ActionRequest'.contextId, State),
483
?LBRKT_INDENT(State),
484
enc_list([{[Val#'ActionRequest'.contextRequest],
485
fun enc_ContextRequest/2},
486
{[Val#'ActionRequest'.contextAttrAuditReq],
487
fun enc_ContextAttrAuditRequest/2},
488
{Val#'ActionRequest'.commandRequests,
489
fun enc_CommandRequest/2}],
495
enc_ActionReply(#'ActionReply'{contextId = Id,
496
errorDescriptor = ED,
497
contextReply = CtxRep,
498
commandReply = CmdRep},
500
% d("enc_ActionReply -> entry with"
504
% "~n CmdRep: ~p", [Id, ED, CtxRep, CmdRep]),
508
enc_ContextID(Id, State),
509
?LBRKT_INDENT(State),
510
do_enc_ActionReply(ED, CtxRep, CmdRep, State),
514
do_enc_ActionReply(asn1_NOVALUE, CtxRep, [], State)
515
when CtxRep =/= asn1_NOVALUE ->
516
% d("do_enc_ActionReply -> entry with"
517
% "~n CtxRep: ~p", [CtxRep]),
519
enc_ContextRequest(CtxRep, ?INC_INDENT(State))
521
do_enc_ActionReply(asn1_NOVALUE, CtxRep, CmdRep, State)
522
when CtxRep =/= asn1_NOVALUE, CmdRep =/= [] ->
523
% d("do_enc_ActionReply -> entry with"
525
% "~n CmdRep: ~p", [CtxRep, CmdRep]),
527
enc_ContextRequest(CtxRep, ?INC_INDENT(State)),
528
?COMMA_INDENT(?INC_INDENT(State)),
529
enc_list([{CmdRep, fun enc_CommandReply/2}],
532
do_enc_ActionReply(asn1_NOVALUE, asn1_NOVALUE, CmdRep, State)
533
when CmdRep =/= [] ->
534
% d("do_enc_ActionReply -> entry with"
535
% "~n CmdRep: ~p", [CmdRep]),
537
enc_list([{CmdRep, fun enc_CommandReply/2}],
540
do_enc_ActionReply(ED, CtxRep, [], State)
541
when ED =/= asn1_NOVALUE, CtxRep =/= asn1_NOVALUE ->
542
% d("do_enc_ActionReply -> entry with"
544
% "~n CtxRep: ~p", [ED, CtxRep]),
546
enc_ContextRequest(CtxRep, ?INC_INDENT(State)),
547
?COMMA_INDENT(?INC_INDENT(State)),
548
enc_list([{[ED], fun enc_ErrorDescriptor/2}], % Indention cosmetics
551
do_enc_ActionReply(ED, asn1_NOVALUE, CmdRep, State)
552
when ED =/= asn1_NOVALUE, CmdRep =/= [] ->
553
% d("do_enc_ActionReply -> entry with"
555
% "~n CmdRep: ~p", [ED, CmdRep]),
557
enc_list([{CmdRep, fun enc_CommandReply/2},
558
{[ED], fun enc_ErrorDescriptor/2}], % Indention cosmetics
561
do_enc_ActionReply(ED, CtxRep, CmdRep, State)
562
when ED =/= asn1_NOVALUE, CtxRep =/= asn1_NOVALUE, CmdRep =/= [] ->
563
% d("do_enc_ActionReply -> entry with"
566
% "~n CmdRep: ~p", [ED, CtxRep, CmdRep]),
568
enc_ContextRequest(CtxRep, ?INC_INDENT(State)),
569
?COMMA_INDENT(?INC_INDENT(State)),
570
enc_list([{CmdRep, fun enc_CommandReply/2},
571
{[ED], fun enc_ErrorDescriptor/2}], % Indention cosmetics
574
do_enc_ActionReply(ED, asn1_NOVALUE, [], State)
575
when ED =/= asn1_NOVALUE ->
576
% d("do_enc_ActionReply -> entry with"
577
% "~n ED: ~p", [ED]),
579
enc_ErrorDescriptor(ED, ?INC_INDENT(State))
583
enc_ContextRequest_priority(asn1_NOVALUE, _State) ->
585
enc_ContextRequest_priority(Val, _State) ->
586
{[Val], fun(X,S) -> [?PriorityToken,?EQUAL,enc_UINT16(X, S)] end}.
588
enc_ContextRequest_emergency(asn1_NOVALUE, _State) ->
590
enc_ContextRequest_emergency(true, _State) ->
591
{[?EmergencyToken], fun(Elem, _) -> Elem end};
592
enc_ContextRequest_emergency(false, _State) ->
593
{[?EmergencyOffToken], fun(Elem, _) -> Elem end}.
595
enc_ContextRequest_topologyReq(asn1_NOVALUE, _State) ->
597
enc_ContextRequest_topologyReq({'ContextRequest_topologyReq',
598
asn1_NOVALUE}, _State) ->
600
enc_ContextRequest_topologyReq({'ContextRequest_topologyReq',
602
{List, fun enc_TopologyRequest/2};
603
enc_ContextRequest_topologyReq(List, _State) ->
604
{[List], fun enc_TopologyRequest/2}.
606
enc_ContextRequest_iepsCallind(asn1_NOVALUE, _State) ->
608
enc_ContextRequest_iepsCallind(false, _State) ->
610
% enc_ContextRequest_iepsCallind(false, _State) ->
611
% {[?IEPS_XXXX_Token], fun(Elem, _) -> Elem end};
612
enc_ContextRequest_iepsCallind(true, _State) ->
613
{[?IEPSToken], fun(Elem, _) -> Elem end}.
615
enc_ContextRequest_contextProp(asn1_NOVALUE, _State) ->
617
enc_ContextRequest_contextProp([], _State) ->
619
enc_ContextRequest_contextProp([PP], _State) ->
620
{[PP], fun enc_PropertyParm/2};
621
enc_ContextRequest_contextProp(PPs, _State) when list(PPs) ->
622
error({at_most_one_contextProp, PPs}).
624
enc_ContextRequest(asn1_NOVALUE, _State) ->
626
enc_ContextRequest(#'ContextRequest'{priority = asn1_NOVALUE,
627
emergency = asn1_NOVALUE,
628
topologyReq = asn1_NOVALUE,
629
iepsCallind = asn1_NOVALUE,
630
contextProp = asn1_NOVALUE}, _State) ->
632
enc_ContextRequest(#'ContextRequest'{priority = asn1_NOVALUE,
633
emergency = asn1_NOVALUE,
635
iepsCallind = asn1_NOVALUE,
636
contextProp = []}, _State) ->
638
enc_ContextRequest(#'ContextRequest'{priority = Prio,
642
contextProp = CP}, State) ->
645
?LBRKT_INDENT(State),
646
enc_list([enc_ContextRequest_priority(Prio, State),
647
enc_ContextRequest_emergency(Em, State),
648
enc_ContextRequest_topologyReq(TR, State),
649
enc_ContextRequest_iepsCallind(Ieps, State),
650
enc_ContextRequest_contextProp(CP, State)],
655
enc_ContextAttrAuditRequest(
656
#'ContextAttrAuditRequest'{topology = asn1_NOVALUE,
657
emergency = asn1_NOVALUE,
658
priority = asn1_NOVALUE,
659
iepsCallind = asn1_NOVALUE,
660
contextPropAud = asn1_NOVALUE}, _State) ->
662
enc_ContextAttrAuditRequest(
663
#'ContextAttrAuditRequest'{topology = asn1_NOVALUE,
664
emergency = asn1_NOVALUE,
665
priority = asn1_NOVALUE,
666
iepsCallind = asn1_NOVALUE,
667
contextPropAud = []}, _State) ->
669
enc_ContextAttrAuditRequest(CAAR, State) ->
672
?LBRKT_INDENT(State),
673
enc_IndAudContextAttrDescriptor(CAAR, ?INC_INDENT(State)),
677
enc_IndAudContextAttrDescriptor(
678
#'ContextAttrAuditRequest'{topology = Top,
682
contextPropAud = CPA}, State) ->
685
?LBRKT_INDENT(State),
686
enc_list([{[Top], fun('NULL', _) -> ?TopologyToken end},
687
{[Em], fun('NULL', _) -> ?EmergencyToken end},
688
{[Prio], fun('NULL', _) -> ?PriorityToken end},
689
{[Ieps], fun('NULL', _) -> ?IEPSToken end},
690
{CPA, fun enc_IndAudPropertyParm/2}],
695
enc_CommandRequest(Val, State)
696
when record(Val, 'CommandRequest') ->
697
% d("enc_CommandRequest -> entry with"
698
% "~n Val: ~p", [Val]),
700
case Val#'CommandRequest'.optional of
706
case Val#'CommandRequest'.wildcardReturn of
712
enc_Command(Val#'CommandRequest'.command, State)
715
enc_Command({'Command',Val}, State) ->
716
enc_Command(Val, State);
717
enc_Command({Tag, Val}, State) ->
718
% d("enc_Command -> entry with"
720
% "~n Val: ~p", [Tag, Val]),
723
[?AddToken, enc_AmmRequest(Val, State)];
725
[?MoveToken, enc_AmmRequest(Val, State)];
727
[?ModifyToken, enc_AmmRequest(Val, State)];
729
[?SubtractToken, enc_SubtractRequest(Val, State)];
731
[?AuditCapToken, enc_AuditRequest(Val, State)];
733
[?AuditValueToken, enc_AuditRequest(Val, State)];
735
[?NotifyToken, enc_NotifyRequest(Val, State)];
737
[?ServiceChangeToken, enc_ServiceChangeRequest(Val, State)];
739
error({invalid_Command_tag, Tag})
742
enc_CommandReply({'CommandReply',Val}, State) ->
743
enc_CommandReply(Val, State);
744
enc_CommandReply({Tag, Val}, State) ->
745
% d("enc_CommandReply -> entry with"
747
% "~n Val: ~p", [Tag, Val]),
750
[?AddToken, enc_AmmsReply(Val, State)];
752
[?MoveToken, enc_AmmsReply(Val, State)];
754
[?ModifyToken, enc_AmmsReply(Val, State)];
756
[?SubtractToken, enc_AmmsReply(Val, State)];
758
[?AuditCapToken, enc_AuditReply(Val, State)];
760
[?AuditValueToken, enc_AuditReply(Val, State)];
762
[?NotifyToken, enc_NotifyReply(Val, State)];
763
serviceChangeReply ->
764
[?ServiceChangeToken, enc_ServiceChangeReply(Val, State)];
766
error({invalid_CommandReply_tag, Tag})
769
enc_TopologyRequest(Val, State)
773
?LBRKT_INDENT(State),
774
enc_list([{Val, fun enc_TopologyRequest1/2}],?INC_INDENT(State)),
778
enc_TopologyRequest1(#'TopologyRequest'{terminationFrom = From,
780
topologyDirection = Dir}, State) ->
782
enc_TerminationID(From, State),
783
?COMMA_INDENT(State),
784
enc_TerminationID(To, State),
785
?COMMA_INDENT(State),
786
enc_TopologyDirection(Dir, State)
789
enc_TopologyDirection(bothway, _State) ->
791
enc_TopologyDirection(isolate, _State) ->
793
enc_TopologyDirection(oneway, _State) ->
795
enc_TopologyDirection(Top, _State) ->
796
error({illegal_TopologyDirection, Top}).
798
enc_AmmRequest(Val, State)
799
when record(Val, 'AmmRequest') ->
800
% d("enc_AmmRequest -> entry with"
801
% "~n Val: ~p", [Val]),
803
%% Assume that Token is added elsewhere
805
enc_TerminationIDList1(Val#'AmmRequest'.terminationID, State),
807
enc_list([{Val#'AmmRequest'.descriptors, fun enc_ammDescriptor/2}],
812
enc_ammDescriptor({Tag, Desc}, State) ->
813
% d("enc_ammDescriptor -> entry with"
815
% "~n Desc: ~p", [Tag, Desc]),
817
mediaDescriptor -> enc_MediaDescriptor(Desc, State);
818
modemDescriptor -> enc_ModemDescriptor(Desc, State);
819
muxDescriptor -> enc_MuxDescriptor(Desc, State);
820
eventsDescriptor -> enc_EventsDescriptor(Desc, State);
821
eventBufferDescriptor -> enc_EventBufferDescriptor(Desc, State);
822
signalsDescriptor -> enc_SignalsDescriptor(Desc, State);
823
digitMapDescriptor -> enc_DigitMapDescriptor(Desc, State);
824
auditDescriptor -> enc_AuditDescriptor(Desc, State);
825
statisticsDescriptor -> enc_StatisticsDescriptor(Desc, State);
827
error({invalid_ammDescriptor_tag, Tag})
830
enc_AmmsReply(#'AmmsReply'{terminationID = ID,
831
terminationAudit = asn1_NOVALUE}, State) ->
832
% d("enc_AmmsReply(asn1_NOVALUE) -> entry with"
833
% "~n ID: ~p", [ID]),
836
enc_TerminationIDList1(ID, State)
838
enc_AmmsReply(#'AmmsReply'{terminationID = ID,
839
terminationAudit = []}, State) ->
840
% d("enc_AmmsReply([]) -> entry with"
841
% "~n ID: ~p", [ID]),
844
enc_TerminationIDList1(ID, State)
846
enc_AmmsReply(#'AmmsReply'{terminationID = ID,
847
terminationAudit = Res}, State) ->
848
% d("enc_AmmsReply -> entry with"
850
% "~n Res: ~p", [ID, Res]),
853
enc_TerminationIDList1(ID, State),
854
case lists:flatten(enc_TerminationAudit(Res, ?INC_INDENT(State))) of
859
?LBRKT_INDENT(State),
866
enc_SubtractRequest(Val, State)
867
when record(Val, 'SubtractRequest') ->
869
%% Assume that Token is added elsewhere
871
enc_TerminationIDList1(Val#'SubtractRequest'.terminationID, State),
872
case Val#'SubtractRequest'.auditDescriptor of
877
?LBRKT_INDENT(State) ,
878
enc_AuditDescriptor(AuditDescr, ?INC_INDENT(State)),
884
enc_AuditRequest(Val, State)
885
when record(Val, 'AuditRequest') ->
886
% d("enc_AuditRequest -> entry with"
887
% "~n Val: ~p", [Val]),
889
%% Assume that Token is added elsewhere
891
enc_TerminationIDList1([Val#'AuditRequest'.terminationID], State),
892
case Val#'AuditRequest'.auditDescriptor of
897
?LBRKT_INDENT(State) ,
898
enc_AuditDescriptor(AuditDescr, ?INC_INDENT(State)),
904
%% auditReply = (AuditValueToken / AuditCapToken )
905
%% ( contextTerminationAudit / auditOther)
906
%% auditOther = EQUAL TerminationID LBRKT
907
%% terminationAudit RBRKT
908
%% terminationAudit = auditReturnParameter *(COMMA auditReturnParameter)
910
%% contextTerminationAudit = EQUAL CtxToken ( terminationIDList /
911
%% LBRKT errorDescriptor RBRKT )
912
enc_AuditReply({Tag, Val}, State) ->
914
contextAuditResult ->
918
enc_TerminationIDListN(Val, State)
924
?LBRKT_INDENT(State),
925
enc_ErrorDescriptor(Val, ?INC_INDENT(State)),
928
auditResult when record(Val, 'AuditResult') ->
929
enc_auditOther(Val, State);
931
error({invalid_auditResult, Val});
933
error({invalid_AuditReply_tag, Tag})
936
enc_auditOther(#'AuditResult'{terminationID = ID,
937
terminationAuditResult = asn1_NOVALUE}, State) ->
940
enc_TerminationID(ID, State)
942
enc_auditOther(#'AuditResult'{terminationID = ID,
943
terminationAuditResult = []}, State) ->
946
enc_TerminationID(ID, State)
948
enc_auditOther(#'AuditResult'{terminationID = ID,
949
terminationAuditResult = Res}, State) ->
952
enc_TerminationID(ID, State),
953
case lists:flatten(enc_TerminationAudit(Res, ?INC_INDENT(State))) of
958
?LBRKT_INDENT(State),
966
enc_AuditDescriptor(#'AuditDescriptor'{auditToken = asn1_NOVALUE,
967
auditPropertyToken = asn1_NOVALUE},
969
% d("enc_AuditDescriptor(asn1_NOVALUE) -> entry"),
974
enc_AuditDescriptor(#'AuditDescriptor'{auditToken = [],
975
auditPropertyToken = asn1_NOVALUE},
977
% d("enc_AuditDescriptor([]) -> entry"),
982
enc_AuditDescriptor(#'AuditDescriptor'{auditToken = List,
983
auditPropertyToken = asn1_NOVALUE},
985
% d("enc_AuditDescriptor -> entry with",
986
% "~n List: ~p", [List]),
990
?LBRKT_INDENT(State),
991
enc_list([{List, fun enc_auditItem/2}], ?INC_INDENT(State)),
996
enc_AuditDescriptor(#'AuditDescriptor'{auditToken = asn1_NOVALUE,
997
auditPropertyToken = Prop},
999
% d("enc_AuditDescriptor -> entry with",
1000
% "~n Prop: ~p", [Prop]),
1004
?LBRKT_INDENT(State),
1005
enc_auditPropertyToken(Prop, ?INC_INDENT(State)),
1006
?RBRKT_INDENT(State)
1009
enc_AuditDescriptor(#'AuditDescriptor'{auditToken = List,
1010
auditPropertyToken = Prop},
1012
% d("enc_AuditDescriptor -> entry with",
1014
% "~n Prop: ~p", [List, Prop]),
1018
?LBRKT_INDENT(State),
1019
enc_list([{List, fun enc_auditItem/2}], ?INC_INDENT(State)),
1020
?COMMA_INDENT(State),
1021
enc_auditPropertyToken(Prop, ?INC_INDENT(State)), % v2
1022
?RBRKT_INDENT(State)
1026
enc_auditItem(signalsToken, _State) ->
1028
enc_auditItem(eventBufferToken, _State) ->
1030
enc_auditItem(eventsToken, _State) ->
1032
enc_auditItem(Val, State) ->
1033
enc_auditReturnItem(Val, State).
1036
enc_auditReturnItem(muxToken, _State) ->
1038
enc_auditReturnItem(modemToken, _State) ->
1040
enc_auditReturnItem(mediaToken, _State) ->
1042
enc_auditReturnItem(digitMapToken, _State) ->
1044
enc_auditReturnItem(statsToken, _State) ->
1046
enc_auditReturnItem(observedEventsToken, _State) ->
1047
?ObservedEventsToken;
1048
enc_auditReturnItem(packagesToken, _State) ->
1054
enc_auditPropertyToken([], _State) ->
1056
enc_auditPropertyToken([Param | Params], State) ->
1057
% d("enc_auditPropertyToken -> entry with",
1058
% "~n Param: ~p", [Param]),
1059
[enc_IndAudauditReturnParameter(Param, State),
1060
[[?COMMA_INDENT(State),
1061
enc_IndAudauditReturnParameter(P, State)] || P <- Params]].
1064
enc_IndAudauditReturnParameter({Tag, Val}, State) ->
1066
indAudMediaDescriptor ->
1067
enc_IndAudMediaDescriptor(Val, State);
1068
indAudEventsDescriptor ->
1069
enc_IndAudEventsDescriptor(Val, State);
1070
indAudSignalsDescriptor ->
1071
enc_IndAudSignalsDescriptor(Val, State);
1072
indAudDigitMapDescriptor ->
1073
enc_IndAudDigitMapDescriptor(Val, State);
1074
indAudEventBufferDescriptor ->
1075
enc_IndAudEventBufferDescriptor(Val, State);
1076
indAudStatisticsDescriptor ->
1077
enc_IndAudStatisticsDescriptor(Val, State);
1078
indAudPackagesDescriptor ->
1079
enc_IndAudPackagesDescriptor(Val, State);
1081
error({invalid_IndAudauditReturnParameter_tag, Tag})
1084
%% The ASN.1 does not limit to just one of termStateDescr or streams,
1085
%% but the ABNF seams to do that...
1086
enc_IndAudMediaDescriptor(
1087
#'IndAudMediaDescriptor'{termStateDescr = asn1_NOVALUE,
1088
streams = Streams}, State) ->
1089
% d("enc_IndAudMediaDescriptor -> entry with",
1090
% "~n Streams: ~p", [Streams]),
1093
?LBRKT_INDENT(State),
1094
enc_IndAudMediaDescriptor_streams(Streams, ?INC_INDENT(State)),
1095
?RBRKT_INDENT(State)
1097
enc_IndAudMediaDescriptor(#'IndAudMediaDescriptor'{termStateDescr = TSD,
1098
streams = asn1_NOVALUE},
1100
% d("enc_IndAudMediaDescriptor -> entry with",
1101
% "~n TSD: ~p", [TSD]),
1104
?LBRKT_INDENT(State),
1105
enc_IndAudTerminationStateDescriptor(TSD, ?INC_INDENT(State)),
1106
?RBRKT_INDENT(State)
1109
enc_IndAudMediaDescriptor_streams({Tag, Val}, State) ->
1110
% d("enc_IndAudMediaDescriptor_streams -> entry with",
1112
% "~n Val: ~p", [Tag, Val]),
1115
enc_IndAudStreamParms(Val, State);
1117
enc_IndAudMediaDescriptor_multiStream(Val, State);
1119
error({invalid_IndAudMediaDescriptor_streams_tag, Tag})
1122
enc_IndAudTerminationStateDescriptor(
1123
#'IndAudTerminationStateDescriptor'{propertyParms = [],
1124
eventBufferControl = asn1_NOVALUE,
1125
serviceState = 'NULL'}, _State) ->
1127
?TerminationStateToken,
1128
?LBRKT_INDENT(_State),
1129
?ServiceStatesToken,
1130
?RBRKT_INDENT(_State)
1132
enc_IndAudTerminationStateDescriptor(
1133
#'IndAudTerminationStateDescriptor'{propertyParms = [],
1134
eventBufferControl = 'NULL',
1135
serviceState = asn1_NOVALUE}, _State) ->
1137
?TerminationStateToken,
1138
?LBRKT_INDENT(_State),
1140
?RBRKT_INDENT(_State)
1142
enc_IndAudTerminationStateDescriptor(
1143
#'IndAudTerminationStateDescriptor'{propertyParms = [Parms],
1144
eventBufferControl = asn1_NOVALUE,
1145
serviceState = asn1_NOVALUE}, State) ->
1146
#'IndAudPropertyParm'{name = Name} = Parms,
1148
?TerminationStateToken,
1149
?LBRKT_INDENT(State),
1150
enc_PkgdName(Name, State),
1151
?RBRKT_INDENT(State)
1154
%% In text, localDescriptor and remoteDescriptor are not allowed!!
1155
enc_IndAudStreamParms(
1156
#'IndAudStreamParms'{localControlDescriptor = LCD,
1157
localDescriptor = asn1_NOVALUE,
1158
remoteDescriptor = asn1_NOVALUE,
1159
statisticsDescriptor = SD}, State) ->
1160
% d("enc_IndAudStreamParms -> entry with"
1162
% "~n SD: ~p", [LCD, SD]),
1164
enc_list([{[LCD], fun enc_IndAudLocalControlDescriptor/2},
1165
{[SD], fun enc_IndAudStatisticsDescriptor/2}],
1169
enc_IndAudLocalControlDescriptor(Val, State)
1170
when record(Val, 'IndAudLocalControlDescriptor') ->
1173
?LBRKT_INDENT(State),
1174
enc_list([{[Val#'IndAudLocalControlDescriptor'.streamMode],
1175
fun('NULL', _) -> ?ModeToken end},
1176
{[Val#'IndAudLocalControlDescriptor'.reserveValue],
1177
fun('NULL', _) -> ?ReservedValueToken end},
1178
{[Val#'IndAudLocalControlDescriptor'.reserveGroup],
1179
fun('NULL', _) -> ?ReservedGroupToken end},
1180
{Val#'IndAudLocalControlDescriptor'.propertyParms,
1181
fun enc_IndAudPropertyParm/2}],
1182
?INC_INDENT(State)),
1183
?RBRKT_INDENT(State)
1186
enc_IndAudPropertyParm(#'IndAudPropertyParm'{name = PkgdName}, State) ->
1187
enc_PkgdName(PkgdName, State).
1189
enc_IndAudMediaDescriptor_multiStream([Val], State) ->
1190
% d("enc_IndAudMediaDescriptor_multiStream -> entry with"
1191
% "~n Val: ~p", [Val]),
1193
enc_IndAudStreamDescriptor(Val, ?INC_INDENT(State))
1195
enc_IndAudMediaDescriptor_multiStream(Vals, _State) when list(Vals) ->
1196
error({invalid_IndAudMediaDescriptor_multiStream_length, Vals});
1197
enc_IndAudMediaDescriptor_multiStream(Val, _State) ->
1198
error({invalid_IndAudMediaDescriptor_multiStream, Val}).
1200
enc_IndAudStreamDescriptor(#'IndAudStreamDescriptor'{streamID = SID,
1201
streamParms = Parms},
1203
% d("enc_IndAudStreamDescriptor -> entry with"
1205
% "~n Parms: ~p", [SID, Parms]),
1209
enc_StreamID(SID, State),
1210
?LBRKT_INDENT(State),
1211
enc_IndAudStreamParms(Parms, ?INC_INDENT(State)),
1212
?RBRKT_INDENT(State)
1215
enc_IndAudEventBufferDescriptor(Val, State)
1216
when record(Val, 'IndAudEventBufferDescriptor') ->
1217
#'IndAudEventBufferDescriptor'{eventName = EvName,
1218
streamID = ID} = Val,
1221
?LBRKT_INDENT(State),
1222
enc_PkgdName(EvName, State),
1223
enc_IndAudEventBufferDescriptor_eventSpec(ID, ?INC_INDENT(State)),
1224
?RBRKT_INDENT(State)
1227
enc_IndAudEventBufferDescriptor_eventSpec(asn1_NOVALUE, _State) ->
1230
enc_IndAudEventBufferDescriptor_eventSpec({eventParameterName, ParamName},
1233
?LBRKT_INDENT(State),
1234
enc_Name(ParamName, State),
1235
?RBRKT_INDENT(State)
1237
enc_IndAudEventBufferDescriptor_eventSpec(ID, State) ->
1239
?LBRKT_INDENT(State),
1240
enc_eventStream(ID, ?INC_INDENT(State)),
1241
?RBRKT_INDENT(State)
1244
enc_IndAudEventsDescriptor(Val, State)
1245
when record(Val, 'IndAudEventsDescriptor') ->
1246
#'IndAudEventsDescriptor'{requestID = ReqID,
1248
streamID = asn1_NOVALUE} = Val,
1252
enc_RequestID(ReqID, State),
1253
?LBRKT_INDENT(State),
1254
enc_PkgdName(Name, State),
1255
?RBRKT_INDENT(State)
1259
enc_IndAudSignalsDescriptor(Val, State) ->
1262
?LBRKT_INDENT(State),
1263
enc_IndAudSignalsDescriptor_value(Val, ?INC_INDENT(State)),
1264
?RBRKT_INDENT(State)
1267
enc_IndAudSignalsDescriptor_value({signal, Val}, State) ->
1268
enc_IndAudSignal(Val, State);
1269
enc_IndAudSignalsDescriptor_value({seqSigList, Val}, State) ->
1270
enc_IndAudSeqSigList(Val, State).
1272
enc_IndAudSignal(#'IndAudSignal'{signalName = SignalName,
1273
streamID = asn1_NOVALUE}, State) ->
1275
enc_SignalName(SignalName, State)
1278
enc_IndAudSeqSigList(#'IndAudSeqSigList'{id = ID,
1284
enc_UINT16(ID, State),
1285
?LBRKT_INDENT(State),
1286
enc_IndAudSignal(Parm, ?INC_INDENT(State)),
1287
?RBRKT_INDENT(State)
1290
enc_IndAudDigitMapDescriptor(#'IndAudDigitMapDescriptor'{digitMapName = Name},
1295
enc_DigitMapName(Name, State)
1298
enc_IndAudStatisticsDescriptor(#'IndAudStatisticsDescriptor'{statName = Name},
1300
% d("enc_IndAudStatisticsDescriptor -> entry with"
1301
% "~n Name: ~p", [Name]),
1304
?LBRKT_INDENT(State),
1305
enc_PkgdName(Name, State),
1306
?RBRKT_INDENT(State)
1310
enc_IndAudPackagesDescriptor(#'IndAudPackagesDescriptor'{packageName = N,
1311
packageVersion = V},
1315
?LBRKT_INDENT(State),
1318
enc_UINT16(V, State),
1319
?RBRKT_INDENT(State)
1326
enc_TerminationAudit({'TerminationAudit',Val}, State) ->
1327
enc_TerminationAudit(Val, State);
1328
enc_TerminationAudit([], _State) ->
1330
enc_TerminationAudit([Mand | Opt], State) ->
1331
% d("enc_TerminationAudit -> entry with"
1332
% "~n Mand: ~p", [Mand]),
1333
[enc_AuditReturnParameter(Mand, State),
1334
[[?COMMA_INDENT(State), enc_AuditReturnParameter(Val, State)] || Val <- Opt]].
1336
enc_AuditReturnParameter({'AuditReturnParameter',Val}, State) ->
1337
enc_AuditReturnParameter(Val, State);
1338
enc_AuditReturnParameter({Tag, Val}, State) ->
1339
% d("enc_AuditReturnParameter -> entry with"
1341
% "~n Val: ~p", [Tag, Val]),
1344
enc_MediaDescriptor(Val, State);
1346
enc_ModemDescriptor(Val, State);
1348
enc_MuxDescriptor(Val, State);
1350
enc_EventsDescriptor(Val, State);
1351
signalsDescriptor ->
1352
enc_SignalsDescriptor(Val, State);
1353
digitMapDescriptor ->
1354
enc_DigitMapDescriptor(Val, State);
1355
observedEventsDescriptor ->
1356
enc_ObservedEventsDescriptor(Val, State);
1357
eventBufferDescriptor ->
1358
enc_EventBufferDescriptor(Val, State);
1359
statisticsDescriptor ->
1360
enc_StatisticsDescriptor(Val, State);
1361
packagesDescriptor ->
1362
enc_PackagesDescriptor(Val, State);
1364
enc_ErrorDescriptor(Val, State);
1366
enc_EmptyDescriptors(Val, State);
1368
error({invalid_AuditReturnParameter_tag, Tag})
1371
enc_EmptyDescriptors(#'AuditDescriptor'{auditToken = asn1_NOVALUE}, _State) ->
1373
enc_EmptyDescriptors(#'AuditDescriptor'{auditToken = []}, _State) ->
1375
enc_EmptyDescriptors(#'AuditDescriptor'{auditToken = List}, State) ->
1376
enc_list([{List, fun enc_auditReturnItem/2}], ?INC_INDENT(State)).
1379
enc_NotifyRequest(Val, State)
1380
when record(Val, 'NotifyRequest') ->
1382
%% Assume that Token is added elsewhere
1384
enc_TerminationIDList1(Val#'NotifyRequest'.terminationID, State),
1385
?LBRKT_INDENT(State),
1386
%% BUGBUG: Mismatch between ASN.1 and ABNF
1387
%% BUGBUG: The following ought to be a 'choice'
1388
case Val#'NotifyRequest'.errorDescriptor of
1390
OED = Val#'NotifyRequest'.observedEventsDescriptor,
1391
enc_ObservedEventsDescriptor(OED, ?INC_INDENT(State));
1393
enc_ErrorDescriptor(ErrorDescr, ?INC_INDENT(State))
1395
?RBRKT_INDENT(State)
1398
enc_NotifyReply(Val, State)
1399
when record(Val, 'NotifyReply') ->
1401
%% Assume that Token is added elsewhere
1403
case Val#'NotifyReply'.terminationID of
1405
error(asn1_not_compliant_with_abnf);
1407
enc_TerminationIDList1(TermId, State)
1409
case Val#'NotifyReply'.errorDescriptor of
1414
?LBRKT_INDENT(State),
1415
enc_ErrorDescriptor(ErrorDescr, ?INC_INDENT(State)),
1416
?RBRKT_INDENT(State)
1421
enc_ObservedEventsDescriptor(Val, State)
1422
when record(Val, 'ObservedEventsDescriptor') ->
1424
?ObservedEventsToken,
1426
enc_RequestID(Val#'ObservedEventsDescriptor'.requestId, State),
1427
?LBRKT_INDENT(State),
1428
enc_observedEventsDescriptors(Val#'ObservedEventsDescriptor'.observedEventLst, ?INC_INDENT(State)),
1429
?RBRKT_INDENT(State)
1432
enc_observedEventsDescriptors([Mand | Opt], State) ->
1433
[enc_ObservedEvent(Mand, State),
1434
[[?COMMA_INDENT(State), enc_ObservedEvent(Val, State)] || Val <- Opt]].
1436
%% ;time per event, because it might be buffered
1437
%% observedEvent = [ TimeStamp LWSP COLON] LWSP
1438
%% pkgdName [ LBRKT observedEventParameter
1439
%% *(COMMA observedEventParameter) RBRKT ]
1441
%% ;at-most-once eventStream, every eventParameterName at most once
1442
%% observedEventParameter = eventStream / eventOther
1443
enc_ObservedEvent(Val, State)
1444
when record(Val, 'ObservedEvent') ->
1446
case Val#'ObservedEvent'.timeNotation of
1451
enc_TimeNotation(TimeStamp, State),
1457
enc_EventName(Val#'ObservedEvent'.eventName, State),
1459
enc_list([{[Val#'ObservedEvent'.streamID], fun enc_eventStream/2},
1460
{Val#'ObservedEvent'.eventParList, fun enc_eventOther/2}],
1461
?INC_INDENT(State)),
1465
enc_EventName({'EventName',Val}, State) ->
1466
enc_EventName(Val, State);
1467
enc_EventName(Val, State) ->
1468
PkgdName = ?META_ENC(event, Val),
1469
enc_PkgdName(PkgdName, State).
1471
enc_eventStream(Val, State) ->
1475
enc_StreamID(Val, State)
1478
enc_eventOther(#'EventParameter'{eventParameterName = Name,
1480
extraInfo = Extra}, State) ->
1482
enc_Name(Name, State),
1483
enc_propertyParmValues(Value, Extra, State)
1486
enc_ServiceChangeRequest(Val, State)
1487
when record(Val, 'ServiceChangeRequest') ->
1489
%% Assume that Token is added elsewhere
1491
enc_TerminationIDList1(Val#'ServiceChangeRequest'.terminationID, State),
1492
?LBRKT_INDENT(State),
1493
enc_ServiceChangeParm(Val#'ServiceChangeRequest'.serviceChangeParms,
1494
?INC_INDENT(State)),
1495
?RBRKT_INDENT(State)
1498
%% serviceChangeReply = ServiceChangeToken EQUAL TerminationID
1499
%% [LBRKT (errorDescriptor /
1500
%% serviceChangeReplyDescriptor) RBRKT]
1501
%% serviceChangeReplyDescriptor = ServicesToken LBRKT
1502
%% servChgReplyParm *(COMMA servChgReplyParm) RBRKT
1504
%% ;at-most-once. Version is REQUIRED on first ServiceChange response
1505
%% servChgReplyParm = (serviceChangeAddress / serviceChangeMgcId /
1506
%% serviceChangeProfile / serviceChangeVersion )
1507
enc_ServiceChangeReply(Val, State)
1508
when record(Val, 'ServiceChangeReply') ->
1510
%% Assume that Token is added elsewhere
1512
enc_TerminationIDList1(Val#'ServiceChangeReply'.terminationID, State),
1513
enc_ServiceChangeResult(Val#'ServiceChangeReply'.serviceChangeResult, State)
1516
enc_ServiceChangeResult({'ServiceChangeResult',Val}, State) ->
1517
enc_ServiceChangeResult(Val, State);
1518
enc_ServiceChangeResult({Tag, Val}, State) ->
1522
?LBRKT_INDENT(State),
1523
enc_ErrorDescriptor(Val, ?INC_INDENT(State)),
1524
?RBRKT_INDENT(State)
1526
serviceChangeResParms ->
1527
case enc_ServiceChangeResParm(Val, ?INC_INDENT(?INC_INDENT(State))) of
1532
?LBRKT_INDENT(State),
1540
end(?INC_INDENT(State)),
1541
?RBRKT_INDENT(State)
1545
error({invalid_ServiceChangeResult_tag, Tag})
1548
%% Required length of termination ID list is 1
1549
enc_TerminationIDList1({'TerminationIDList',Val}, State) ->
1550
enc_TerminationIDList1(Val, State);
1551
enc_TerminationIDList1([Singleton], State) ->
1552
enc_TerminationID(Singleton, State).
1554
%% No required length of termination ID list
1555
enc_TerminationIDListN({'TerminationIDList',Val}, State) ->
1556
enc_TerminationIDListN(Val, State);
1557
enc_TerminationIDListN([TID], State) ->
1559
?LBRKT_INDENT(State),
1560
enc_TerminationID(TID, State),
1561
?RBRKT_INDENT(State)
1563
enc_TerminationIDListN(TIDs, State) ->
1565
?LBRKT_INDENT(State),
1566
enc_list([{TIDs, fun enc_TerminationID/2}], State),
1567
?RBRKT_INDENT(State)
1570
%% TerminationID = "ROOT" / pathNAME / "$" / "*"
1571
%% ; Total length of pathNAME must not exceed 64 chars.
1572
%% pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
1573
%% ["@" pathDomainName ]
1574
enc_TerminationID(Tid, State)
1575
when record(Tid, megaco_term_id) ->
1576
List = [{Tid#megaco_term_id.id, fun enc_tid_component/2 }],
1577
enc_list(List, State, fun(_S) -> ?SLASH end, false).
1579
enc_tid_component(Component, State) when list(Component) ->
1580
[enc_tid_sub_component(Sub, State) || Sub <- Component];
1581
enc_tid_component(Invalid, _State) ->
1582
error({invalid_id_list_component, Invalid}).
1584
enc_tid_sub_component(Sub, _State) ->
1587
choose -> ?megaco_choose;
1588
Char when integer(Char) -> Char
1591
%% mediaDescriptor = MediaToken LBRKT mediaParm *(COMMA mediaParm) RBRKT
1592
%% ; at-most-once per item
1593
%% ; and either streamParm or streamDescriptor but not both
1594
%% mediaParm = (streamParm / streamDescriptor /
1595
%% terminationStateDescriptor)
1597
%% streamParm = ( localDescriptor / remoteDescriptor /
1598
%% localControlDescriptor )
1599
%% streamDescriptor = StreamToken EQUAL StreamID LBRKT streamParm
1600
%% *(COMMA streamParm) RBRKT
1601
enc_MediaDescriptor(Val, State)
1602
when record(Val, 'MediaDescriptor') ->
1605
?LBRKT_INDENT(State),
1606
enc_list([{[Val#'MediaDescriptor'.termStateDescr],
1607
fun enc_TerminationStateDescriptor/2} |
1608
decompose_streams(Val#'MediaDescriptor'.streams)],
1609
?INC_INDENT(State)),
1610
?RBRKT_INDENT(State)
1613
decompose_streams(asn1_NOVALUE) ->
1615
decompose_streams({'MediaDescriptor_streams',Val}) ->
1616
decompose_streams(Val);
1617
decompose_streams({Tag, Val}) ->
1620
decompose_StreamParms(Val);
1622
[{Val, fun enc_StreamDescriptor/2}];
1624
error({invalid_streams_tag, Tag})
1627
decompose_StreamParms(Val)
1628
when record(Val, 'StreamParms') ->
1630
{[Val#'StreamParms'.localControlDescriptor],
1631
fun enc_LocalControlDescriptor/2},
1632
{[Val#'StreamParms'.localDescriptor],
1633
fun enc_localDescriptor/2},
1634
{[Val#'StreamParms'.remoteDescriptor],
1635
fun enc_remoteDescriptor/2},
1636
{[Val#'StreamParms'.statisticsDescriptor],
1637
fun enc_StatisticsDescriptor/2}
1640
enc_StreamDescriptor(Val, State)
1641
when record(Val, 'StreamDescriptor') ->
1645
enc_StreamID(Val#'StreamDescriptor'.streamID, State),
1646
?LBRKT_INDENT(State),
1647
enc_list(decompose_StreamParms(Val#'StreamDescriptor'.streamParms),
1648
?INC_INDENT(State)),
1649
?RBRKT_INDENT(State)
1652
%% localControlDescriptor = LocalControlToken LBRKT localParm
1653
%% *(COMMA localParm) RBRKT
1655
%% ; at-most-once per item
1656
%% localParm = ( streamMode / propertyParm /
1657
%% reservedValueMode / reservedGroupMode )
1658
%% reservedValueMode = ReservedValueToken EQUAL ( "ON" / "OFF" )
1659
%% reservedGroupMode = ReservedGroupToken EQUAL ( "ON" / "OFF" )
1661
%% reservedMode = ReservedToken EQUAL ( "ON" / "OFF" )
1663
%% streamMode = ModeToken EQUAL streamModes
1664
enc_LocalControlDescriptor(
1665
#'LocalControlDescriptor'{streamMode = asn1_NOVALUE,
1666
reserveValue = asn1_NOVALUE,
1667
reserveGroup = asn1_NOVALUE,
1668
propertyParms = []}, _State) ->
1669
error({invalid_LocalControlDescriptor, empty});
1670
enc_LocalControlDescriptor(
1671
#'LocalControlDescriptor'{streamMode = SM,
1674
propertyParms = PPs}, State) ->
1677
?LBRKT_INDENT(State),
1678
enc_list([{[SM], fun enc_StreamMode/2},
1679
{[RG], fun enc_reservedGroupMode/2},
1680
{[RV], fun enc_reservedValueMode/2},
1681
{PPs, fun enc_PropertyParm/2}], ?INC_INDENT(State)),
1682
?RBRKT_INDENT(State)
1685
enc_reservedGroupMode(Val, _State) ->
1687
?ReservedGroupToken,
1695
enc_reservedValueMode(Val, _State) ->
1697
?ReservedValueToken,
1705
enc_StreamMode({'StreamMode',Val}, State) ->
1706
enc_StreamMode(Val, State);
1707
enc_StreamMode(Val, _State) ->
1712
sendOnly -> ?SendonlyToken;
1713
recvOnly -> ?RecvonlyToken;
1714
sendRecv -> ?SendrecvToken;
1715
inactive -> ?InactiveToken;
1716
loopBack -> ?LoopbackToken
1720
enc_Name({'Name',Val}, State) ->
1721
enc_Name(Val, State);
1722
enc_Name(Val, State) ->
1723
%% BUGBUG: NAME = ALPHA *63(ALPHA / DIGIT / "_" )
1724
enc_STRING(Val, State, 1, 64).
1726
enc_PkgdName({'PkgdName', Val}, State) ->
1727
enc_PkgdName(Val, State);
1728
enc_PkgdName(Val, State) ->
1729
%% BUGBUG: pkgdName = (NAME / "*") SLASH (ItemID / "*" )
1730
enc_OCTET_STRING(Val, State, 1, 64).
1732
enc_localDescriptor(Val, State)
1733
when record(Val, 'LocalRemoteDescriptor') ->
1737
enc_LocalRemoteDescriptor(Val, State),
1738
?RBRKT_INDENT(State)
1741
enc_remoteDescriptor(Val, State)
1742
when record(Val, 'LocalRemoteDescriptor') ->
1746
enc_LocalRemoteDescriptor(Val, State),
1747
?RBRKT_INDENT(State)
1750
%% When text encoding the protocol, the descriptors consist of session
1751
%% descriptions as defined in SDP (RFC2327), except that the "s=", "t="
1752
%% and "o=" lines are optional. When multiple session descriptions are
1753
%% provided in one descriptor, the "v=" lines are required as delimiters;
1754
%% otherwise they are optional. Implementations shall accept session
1755
%% descriptions that are fully conformant to RFC2327. When binary
1756
%% encoding the protocol the descriptor consists of groups of properties
1757
%% (tag-value pairs) as specified in Annex C. Each such group may
1758
%% contain the parameters of a session description.
1759
enc_LocalRemoteDescriptor(Val, State)
1760
when record(Val, 'LocalRemoteDescriptor') ->
1761
case Val#'LocalRemoteDescriptor'.propGrps of
1766
enc_PropertyGroup(OptV, opt_v, State) |
1767
[enc_PropertyGroup(M, mand_v, State) || M <- MandV]]
1770
enc_PropertyGroup({'PropertyGroup',Val}, RequiresV, State) ->
1771
enc_PropertyGroup(Val, RequiresV, State);
1772
enc_PropertyGroup([H | _T] = List, mand_v, State)
1773
when record(H, 'PropertyParm'), H#'PropertyParm'.name == "v" ->
1774
enc_PropertyGroup(List, opt_v, State);
1775
enc_PropertyGroup(PG, opt_v, State) ->
1777
[[enc_PropertyGroupParm(PP, State), ?CrToken, ?LfToken] || PP <- PG]
1780
enc_PropertyGroupParm(Val, State)
1781
when record(Val, 'PropertyParm') ->
1782
[OctetString] = Val#'PropertyParm'.value,
1784
enc_PkgdName(Val#'PropertyParm'.name, State),
1786
enc_OCTET_STRING(OctetString, State, 0, infinity)
1789
%% propertyParm = pkgdName parmValue
1790
%% parmValue = (EQUAL alternativeValue/ INEQUAL VALUE)
1791
%% alternativeValue = ( VALUE / LSBRKT VALUE *(COMMA VALUE) RSBRKT /
1792
%% LSBRKT VALUE DOT DOT VALUE RSBRKT )
1793
enc_PropertyParm(Val, State)
1794
when record(Val, 'PropertyParm') ->
1795
PkgdName = ?META_ENC(property, Val#'PropertyParm'.name),
1797
enc_PkgdName(PkgdName, State),
1798
enc_propertyParmValues(Val#'PropertyParm'.value,
1799
Val#'PropertyParm'.extraInfo,
1803
enc_propertyParmValues([Single], asn1_NOVALUE, State) ->
1806
enc_Value(Single, State)
1808
enc_propertyParmValues([Single], {relation, Rel}, State) ->
1810
greaterThan -> [$>, enc_Value(Single, State)];
1811
smallerThan -> [$<, enc_Value(Single, State)];
1812
unequalTo -> [$#, enc_Value(Single, State)]
1814
enc_propertyParmValues([Low, High], {range, true}, State)->
1819
enc_Value(Low, State),
1821
enc_Value(High, State),
1824
enc_propertyParmValues(Values, {sublist, true}, State)->
1825
%% sublist (i.e. A AND B AND ...)
1828
?LSBRKT_INDENT(State),
1829
enc_list([{Values, fun enc_Value/2}], ?INC_INDENT(State)),
1830
?RSBRKT_INDENT(State)
1832
enc_propertyParmValues(Values, {sublist, false}, State) ->
1833
%% alternatives (i.e. A OR B OR ...)
1836
?LBRKT_INDENT(State),
1837
enc_list([{Values, fun enc_Value/2}], ?INC_INDENT(State)),
1838
?RBRKT_INDENT(State)
1840
enc_propertyParmValues(V, EI, _State) ->
1841
error({invalid_property_parm_values, V, EI}).
1843
enc_TerminationStateDescriptor(Val, State)
1844
when record(Val, 'TerminationStateDescriptor') ->
1846
?TerminationStateToken,
1847
?LBRKT_INDENT(State),
1848
enc_list([{Val#'TerminationStateDescriptor'.propertyParms,
1849
fun enc_PropertyParm/2},
1850
{[Val#'TerminationStateDescriptor'.eventBufferControl],
1851
fun enc_eventBufferControl/2},
1852
{[Val#'TerminationStateDescriptor'.serviceState],
1853
fun enc_serviceState/2}],
1854
?INC_INDENT(State)),
1855
?RBRKT_INDENT(State)
1858
enc_eventBufferControl(Val, _State) ->
1865
lockStep -> ?LockStepToken
1869
enc_serviceState({'ServiceState',Val}, State) ->
1870
enc_serviceState(Val, State);
1871
enc_serviceState(Val, _State) ->
1873
?ServiceStatesToken,
1877
outOfSvc -> ?OutOfSvcToken;
1878
inSvc -> ?InSvcToken
1882
enc_MuxDescriptor(Val, State)
1883
when record(Val, 'MuxDescriptor') ->
1887
enc_MuxType(Val#'MuxDescriptor'.muxType, State),
1888
enc_TerminationIDListN(Val#'MuxDescriptor'.termList, State)
1891
enc_MuxType({'MuxType',Val}, State) ->
1892
enc_MuxType(Val, State);
1893
enc_MuxType(Val, _State) ->
1899
%% extensionParameter
1900
nx64k -> ?Nx64kToken % v2
1903
enc_StreamID({'StreamID',Val}, State) ->
1904
enc_StreamID(Val, State);
1905
enc_StreamID(Val, State) ->
1906
enc_UINT16(Val, State).
1908
enc_EventsDescriptor(Val, State)
1909
when record(Val, 'EventsDescriptor') ->
1910
#'EventsDescriptor'{requestID = RequestId,
1911
eventList = Events} = Val,
1913
RequestId == asn1_NOVALUE, Events == [] ->
1918
RequestId /= asn1_NOVALUE, Events /= [] ->
1922
enc_RequestID(RequestId, State),
1923
?LBRKT_INDENT(State),
1924
enc_list([{Events, fun enc_RequestedEvent/2}],
1925
?INC_INDENT(State)),
1926
?RBRKT_INDENT(State)
1930
enc_RequestedEvent(Val, State)
1931
when record(Val, 'RequestedEvent') ->
1932
PkgdName = ?META_ENC(event, Val#'RequestedEvent'.pkgdName),
1934
enc_PkgdName(PkgdName, State),
1936
enc_list([{[Val#'RequestedEvent'.streamID], fun enc_eventStream/2},
1937
{Val#'RequestedEvent'.evParList, fun enc_eventOther/2} |
1938
decompose_requestedActions(Val#'RequestedEvent'.eventAction)],
1939
?INC_INDENT(State)),
1943
decompose_requestedActions(asn1_NOVALUE) ->
1947
%% This in the ABNF:
1948
%% at-most-once each of KeepActiveToken , eventDM and eventStream
1949
%% at most one of either embedWithSig or embedNoSig but not both
1950
%% KeepActiveToken and embedWithSig must not both be present
1954
decompose_requestedActions(#'RequestedActions'{keepActive = KA,
1957
signalsDescriptor = SD})
1959
SD /= asn1_NOVALUE, SD /= [] ->
1961
{[EDM], fun enc_EventDM/2},
1962
{[{SE, SD}], fun enc_embedWithSig/2}
1966
decompose_requestedActions(#'RequestedActions'{keepActive = KA,
1969
signalsDescriptor = SD})
1970
when SD == asn1_NOVALUE; SD == [] ->
1972
{[KA], fun enc_keepActive/2},
1973
{[EDM], fun enc_EventDM/2},
1974
{[SE], fun enc_embedNoSig/2}
1977
%% Fallback, if everything else failes....
1978
decompose_requestedActions(#'RequestedActions'{keepActive = KA,
1981
signalsDescriptor = SD}) ->
1983
{[KA], fun enc_keepActive/2},
1984
{[EDM], fun enc_EventDM/2},
1985
{[{SE, SD}], fun enc_embedWithSig/2}
1988
enc_embedNoSig(#'SecondEventsDescriptor'{requestID = RID,
1989
eventList = Evs}, State) ->
1992
?LBRKT_INDENT(State),
1993
enc_embedFirst(RID, Evs, ?INC_INDENT(State)),
1994
?RBRKT_INDENT(State)
1997
enc_embedWithSig({asn1_NOVALUE, SD}, State) ->
2000
?LBRKT_INDENT(State),
2001
enc_SignalsDescriptor(SD, ?INC_INDENT(State)),
2002
?RBRKT_INDENT(State)
2004
enc_embedWithSig({#'SecondEventsDescriptor'{requestID = RID,
2005
eventList = Evs}, SD}, State) ->
2008
?LBRKT_INDENT(State),
2009
enc_SignalsDescriptor(SD, ?INC_INDENT(State)),
2010
?COMMA_INDENT(?INC_INDENT(State)),
2011
enc_embedFirst(RID, Evs, ?INC_INDENT(State)),
2012
?RBRKT_INDENT(State)
2015
enc_keepActive(Val, _State) ->
2017
true -> [?KeepActiveToken];
2021
enc_EventDM({'EventDM',Val}, State) ->
2022
enc_EventDM(Val, State);
2023
enc_EventDM({Tag, Val}, State) ->
2029
enc_DigitMapName(Val, State)
2034
?LBRKT_INDENT(State),
2035
enc_DigitMapValue(Val, ?INC_INDENT(State)),
2036
?RBRKT_INDENT(State)
2039
error({invalid_EventDM_tag, Tag})
2043
enc_embedFirst(RID, Evs, State)
2044
when RID /= asn1_NOVALUE, list(Evs), Evs /= [] ->
2045
%% d("enc_embedFirst -> entry with"
2047
%% "~n Evs: ~p", [RID, Evs]),
2051
enc_RequestID(RID, State),
2052
?LBRKT_INDENT(State),
2053
enc_list([{Evs, fun enc_SecondRequestedEvent/2}], ?INC_INDENT(State)),
2054
?RBRKT_INDENT(State)
2056
enc_embedFirst(_RID, _Evs, _State) ->
2057
%% d("enc_embedFirst -> entry"),
2063
enc_SecondRequestedEvent(#'SecondRequestedEvent'{pkgdName = N,
2066
eventAction = EA}, State) ->
2067
PkgdName = ?META_ENC(event, N),
2069
enc_PkgdName(PkgdName, State),
2072
[{[SID], fun enc_eventStream/2},
2073
{EPL, fun enc_eventOther/2} |
2074
decompose_secondRequestedActions(EA)],
2075
?INC_INDENT(State)),
2079
decompose_secondRequestedActions(asn1_NOVALUE) ->
2081
decompose_secondRequestedActions(Val)
2082
when record(Val, 'SecondRequestedActions') ->
2084
{[Val#'SecondRequestedActions'.keepActive],
2085
fun enc_keepActive/2},
2086
{[Val#'SecondRequestedActions'.eventDM],
2088
{[Val#'SecondRequestedActions'.signalsDescriptor],
2089
fun enc_embeddedSignalsDescriptor/2}
2092
enc_embeddedSignalsDescriptor(Val, State) ->
2095
?LBRKT_INDENT(State),
2096
enc_SignalsDescriptor(Val, ?INC_INDENT(State)),
2097
?RBRKT_INDENT(State)
2100
enc_EventBufferDescriptor({'EventBufferDescriptor',Val}, State) ->
2101
enc_EventBufferDescriptor(Val, State);
2102
enc_EventBufferDescriptor([Mand | Opt], State) ->
2105
?LBRKT_INDENT(State),
2106
enc_eventSpecs([Mand | Opt], ?INC_INDENT(State)),
2107
?RBRKT_INDENT(State)
2110
enc_eventSpecs([Mand | Opt], State) ->
2111
[enc_eventSpecs(Mand, State),
2112
[[?COMMA_INDENT(State), enc_eventSpec(Val, State)] || Val <- Opt]].
2114
enc_eventSpec(Val, State)
2115
when record(Val, 'EventSpec') ->
2117
enc_EventName(Val#'EventSpec'.eventName, State),
2119
enc_list([{[Val#'EventSpec'.streamID], fun enc_eventStream/2},
2120
{Val#'EventSpec'.eventParList, fun enc_eventOther/2}],
2121
?INC_INDENT(State)),
2125
enc_SignalsDescriptor({'SignalsDescriptor',Val}, State) ->
2126
enc_SignalsDescriptor(Val, State);
2127
enc_SignalsDescriptor([], _State) ->
2131
enc_SignalsDescriptor(List, State) when list(List) ->
2134
?LBRKT_INDENT(State),
2135
enc_list([{List, fun enc_SignalRequest/2}], ?INC_INDENT(State)),
2136
?RBRKT_INDENT(State)
2139
enc_SignalRequest({'SignalRequest',Val}, State) ->
2140
enc_SignalRequest(Val, State);
2141
enc_SignalRequest({Tag, Val}, State) ->
2144
enc_Signal(Val, State);
2146
enc_SeqSigList(Val, State);
2148
error({invalid_SignalRequest_tag, Tag})
2152
enc_SeqSigList(Val, State)
2153
when record(Val, 'SeqSigList') ->
2157
enc_UINT16(Val#'SeqSigList'.id, State),
2158
?LBRKT_INDENT(State),
2159
enc_list([{Val#'SeqSigList'.signalList, fun enc_Signal/2}],
2160
?INC_INDENT(State)),
2161
?RBRKT_INDENT(State)
2164
enc_Signal(Val, State)
2165
when record(Val, 'Signal') ->
2167
enc_SignalName(Val#'Signal'.signalName, State),
2169
enc_list([{[Val#'Signal'.streamID], fun enc_sigStream/2},
2170
{[Val#'Signal'.sigType], fun enc_sigSignalType/2},
2171
{[Val#'Signal'.duration], fun enc_sigDuration/2},
2172
{[Val#'Signal'.notifyCompletion], fun enc_notifyCompletion/2},
2173
{[Val#'Signal'.keepActive], fun enc_keepActive/2},
2174
{Val#'Signal'.sigParList, fun enc_sigOther/2},
2175
{[Val#'Signal'.direction], fun enc_SignalDirection/2},
2176
{[Val#'Signal'.requestID], fun enc_sigRequestID/2}],
2177
?INC_INDENT(State)),
2181
enc_sigStream(Val, State) ->
2185
enc_StreamID(Val, State)
2188
enc_sigSignalType(Val, State) ->
2192
enc_SignalType(Val, State)
2195
enc_sigDuration(Val, State) ->
2199
enc_UINT16(Val, State)
2202
enc_notifyCompletion(List, State) when list(List) ->
2204
?NotifyCompletionToken,
2206
?LBRKT_INDENT(State),
2207
enc_list([{List, fun enc_notifyCompletionItem/2}], ?INC_INDENT(State)),
2208
?RBRKT_INDENT(State)
2211
enc_notifyCompletionItem(Val, _State) ->
2213
onTimeOut -> ?TimeOutToken;
2214
onInterruptByEvent -> ?InterruptByEventToken;
2215
onInterruptByNewSignalDescr -> ?InterruptByNewSignalsDescrToken;
2216
otherReason -> ?OtherReasonToken
2219
enc_SignalType({'SignalType',Val}, State) ->
2220
enc_SignalType(Val, State);
2221
enc_SignalType(Val, _State) ->
2223
brief -> ?BriefToken;
2224
onOff -> ?OnOffToken;
2225
timeOut -> ?TimeOutToken
2228
enc_SignalName({'SignalName',Val}, State)->
2229
enc_SignalName(Val, State);
2230
enc_SignalName(Val, State) ->
2231
PkgdName = ?META_ENC(signal, Val),
2232
enc_PkgdName(PkgdName, State).
2234
enc_sigOther(Val, State)
2235
when record(Val, 'SigParameter') ->
2237
enc_Name(Val#'SigParameter'.sigParameterName, State),
2238
enc_propertyParmValues(Val#'SigParameter'.value,
2239
Val#'SigParameter'.extraInfo,
2243
enc_SignalDirection({'SignalDirection', Val}, State) ->
2244
enc_SignalDirection(Val, State);
2245
enc_SignalDirection(Val, _State) ->
2250
internal -> ?InternalToken;
2251
external -> ?ExternalToken;
2256
enc_sigRequestID(Val, State) ->
2260
enc_RequestID(Val, State)
2263
enc_RequestID({'RequestID',Val}, State) ->
2264
enc_RequestID(Val, State);
2265
enc_RequestID(Val, _State) when Val == ?megaco_all_request_id ->
2267
enc_RequestID(Val, State) ->
2268
enc_UINT32(Val, State).
2270
enc_ModemDescriptor(MD, _State) ->
2271
error({deprecated, MD}).
2274
%% As of corr 1 ModemDescriptor has been deprecated.
2275
%% 7.1.2: ...shall not be included as part of a transmitted content and,
2276
%% if received, shall either be ignored or processed at the option
2277
%% of the implementation. ...
2278
%% enc_ModemDescriptor(#'ModemDescriptor'{mtl = [Val],
2280
%% nonStandardData = asn1_NOVALUE},
2285
%% enc_ModemType(Val, State)
2287
%% enc_ModemDescriptor(Val, State)
2288
%% when record(Val, 'ModemDescriptor') ->
2292
%% enc_list([{Val#'ModemDescriptor'.mtl, fun enc_ModemType/2}], State),
2294
%% enc_opt_brackets(
2295
%% enc_list([{Val#'ModemDescriptor'.mpl, fun enc_PropertyParm/2}],
2296
%% ?INC_INDENT(State)),
2298
%% %% BUGBUG: Is PropertyParm == NAME parmValue?
2301
%% enc_ModemDescriptor(Val, State)
2302
%% when record(Val, 'ModemDescriptor') ->
2305
%% %% BUGBUG: Does never generate: EQUAL modemType
2307
%% enc_list([{Val#'ModemDescriptor'.mtl, fun enc_ModemType/2}], State),
2309
%% enc_opt_brackets(
2310
%% enc_list([{Val#'ModemDescriptor'.mpl, fun enc_PropertyParm/2}],
2311
%% ?INC_INDENT(State)),
2313
%% %% BUGBUG: Is PropertyParm == NAME parmValue?
2316
%% Corr1: See ModemDescriptor above
2317
%% enc_ModemType({'ModemType',Val}, State)->
2318
%% enc_ModemType(Val, State);
2319
%% enc_ModemType(Val, _State) ->
2320
%% %% BUGBUG: Does not handle extensionParameter
2322
%% v18 -> ?V18Token;
2323
%% v22 -> ?V22Token;
2324
%% v22bis -> ?V22bisToken;
2325
%% v32 -> ?V32Token;
2326
%% v32bis -> ?V32bisToken;
2327
%% v34 -> ?V34Token;
2328
%% v90 -> ?V90Token;
2329
%% v91 -> ?V91Token;
2330
%% synchISDN -> ?SynchISDNToken
2333
enc_DigitMapDescriptor(Val, State)
2334
when record(Val, 'DigitMapDescriptor') ->
2338
enc_DigitMapName(Val#'DigitMapDescriptor'.digitMapName, State),
2339
?LBRKT_INDENT(State),
2340
enc_DigitMapValue(Val#'DigitMapDescriptor'.digitMapValue,
2341
?INC_INDENT(State)),
2342
?RBRKT_INDENT(State)
2345
enc_DigitMapName({'DigitMapName',Val}, State) ->
2346
enc_DigitMapName(Val, State);
2347
enc_DigitMapName(Val, State) ->
2348
enc_Name(Val, State).
2350
enc_DigitMapValue(Val, State)
2351
when record(Val, 'DigitMapValue') ->
2353
enc_timer(Val#'DigitMapValue'.startTimer, $T, State),
2354
enc_timer(Val#'DigitMapValue'.shortTimer, $S, State),
2355
enc_timer(Val#'DigitMapValue'.longTimer, $L, State),
2356
enc_timer(Val#'DigitMapValue'.durationTimer, $Z, State),
2357
%% BUGBUG: digitMapBody not handled at all
2358
enc_STRING(Val#'DigitMapValue'.digitMapBody, State, 0, infinity)
2361
enc_timer(asn1_NOVALUE, _Prefix, _State) ->
2363
enc_timer(Timer, Prefix, State) ->
2367
enc_DIGIT(Timer, State, 0, 99),
2368
?COMMA_INDENT(State)
2371
enc_ServiceChangeParm(Val, State)
2372
when record(Val, 'ServiceChangeParm') ->
2375
?LBRKT_INDENT(State),
2376
enc_list([{[Val#'ServiceChangeParm'.serviceChangeMethod],
2377
fun enc_ServiceChangeMethod/2},
2378
{[Val#'ServiceChangeParm'.serviceChangeAddress],
2379
fun enc_ServiceChangeAddress/2},
2380
{[Val#'ServiceChangeParm'.serviceChangeVersion],
2381
fun enc_serviceChangeVersion/2},
2382
{[Val#'ServiceChangeParm'.serviceChangeProfile],
2383
fun enc_ServiceChangeProfile/2},
2384
{[{reason, Val#'ServiceChangeParm'.serviceChangeReason}],
2385
fun enc_serviceChangeReason/2},
2386
{[Val#'ServiceChangeParm'.serviceChangeDelay],
2387
fun enc_serviceChangeDelay/2},
2388
{[Val#'ServiceChangeParm'.serviceChangeMgcId],
2389
fun enc_serviceChangeMgcId/2},
2390
{[Val#'ServiceChangeParm'.timeStamp],
2391
fun enc_TimeNotation/2},
2392
{Val#'ServiceChangeParm'.serviceChangeInfo,
2393
fun enc_AuditDescriptor/2},
2394
{[Val#'ServiceChangeParm'.serviceChangeIncompleteFlag],
2395
fun('NULL', _) -> ?ServiceChangeIncompleteToken end}],
2396
?INC_INDENT(State)),
2397
?RBRKT_INDENT(State)
2401
enc_ServiceChangeMethod({'ServiceChangeMethod',Val}, State) ->
2402
enc_ServiceChangeMethod(Val, State);
2403
enc_ServiceChangeMethod(Val, _State) ->
2408
failover -> ?FailoverToken;
2409
forced -> ?ForcedToken;
2410
graceful -> ?GracefulToken;
2411
restart -> ?RestartToken;
2412
disconnected -> ?DisconnectedToken;
2413
handOff -> ?HandOffToken
2415
%% BUGBUG: extension
2418
enc_ServiceChangeAddress({'ServiceChangeAddress',Val}, State) ->
2419
enc_ServiceChangeAddress(Val, State);
2420
enc_ServiceChangeAddress({Tag, Val}, State) ->
2422
?ServiceChangeAddressToken,
2426
enc_portNumber(Val, State);
2428
enc_IP4Address(Val, State);
2430
enc_IP6Address(Val, State);
2432
enc_DomainName(Val, State);
2434
enc_PathName(Val, State);
2436
enc_mtpAddress(Val, State);
2438
error({invalid_ServiceChangeAddress_tag, Tag})
2442
enc_serviceChangeVersion(Val, State) ->
2446
enc_version(Val, State)
2449
enc_ServiceChangeProfile(#'ServiceChangeProfile'{profileName = Name,
2455
enc_Name(Name, State),
2457
enc_version(Version, State)
2460
enc_serviceChangeReason({reason, Val}, State) ->
2464
[List] when list(List) ->
2468
enc_QUOTED_STRING(List,State) % OTP-4632 enc_Value(List, State)
2472
enc_serviceChangeDelay(Val, State) ->
2476
enc_UINT32(Val, State)
2479
enc_serviceChangeMgcId(Val, State) ->
2486
enc_portNumber(Val, State) when integer(Val), Val >= 0 ->
2487
enc_UINT16(Val, State).
2489
enc_ServiceChangeResParm(Val, State)
2490
when record(Val, 'ServiceChangeResParm') ->
2491
enc_list([{[Val#'ServiceChangeResParm'.serviceChangeAddress],
2492
fun enc_ServiceChangeAddress/2},
2493
{[Val#'ServiceChangeResParm'.serviceChangeVersion],
2494
fun enc_serviceChangeVersion/2},
2495
{[Val#'ServiceChangeResParm'.serviceChangeProfile],
2496
fun enc_ServiceChangeProfile/2},
2497
{[Val#'ServiceChangeResParm'.serviceChangeMgcId],
2498
fun enc_serviceChangeMgcId/2},
2499
{[Val#'ServiceChangeResParm'.timeStamp],
2500
fun enc_TimeNotation/2}],
2503
enc_PackagesDescriptor({'PackagesDescriptor',Val}, State) ->
2504
enc_PackagesDescriptor(Val, State);
2505
enc_PackagesDescriptor(Val, State) ->
2508
?LBRKT_INDENT(State),
2509
enc_list([{Val, fun enc_PackagesItem/2}], ?INC_INDENT(State)),
2510
?RBRKT_INDENT(State)
2513
enc_PackagesItem(Val, State)
2514
when record(Val, 'PackagesItem') ->
2515
PkgdName = ?META_ENC(package, Val#'PackagesItem'.packageName),
2517
enc_Name(PkgdName, State),
2519
enc_UINT16(Val#'PackagesItem'.packageVersion, State)
2522
enc_StatisticsDescriptor({'StatisticsDescriptor',Val}, State) ->
2523
enc_StatisticsDescriptor(Val, State);
2524
enc_StatisticsDescriptor(List, State) when list(List) ->
2527
?LBRKT_INDENT(State),
2528
enc_list([{List, fun enc_StatisticsParameter/2}], ?INC_INDENT(State)),
2529
?RBRKT_INDENT(State)
2532
enc_StatisticsParameter(Val, State)
2533
when record(Val, 'StatisticsParameter') ->
2534
PkgdName = ?META_ENC(statistics, Val#'StatisticsParameter'.statName),
2535
case Val#'StatisticsParameter'.statValue of
2538
enc_PkgdName(PkgdName, State)
2540
[StatVal] when list(StatVal) ->
2542
enc_PkgdName(PkgdName, State),
2544
enc_Value(StatVal, State)
2548
enc_TimeNotation(Val, State)
2549
when record(Val, 'TimeNotation') ->
2551
enc_STRING(Val#'TimeNotation'.date, State, 8, 8), % "yyyymmdd"
2553
enc_STRING(Val#'TimeNotation'.time, State, 8, 8) % "hhmmssss"
2556
%% BUGBUG: Does not verify that string must contain at least one char
2557
%% BUGBUG: This violation of the is required in order to comply with
2558
%% BUGBUG: the dd/ce ds parameter that may possibly be empty.
2559
enc_Value({'Value',Val}, State) ->
2560
enc_Value(Val, State);
2561
enc_Value(String, _State) ->
2562
case quoted_string_count(String, 0, true) of
2564
[?DQUOTE, String, ?DQUOTE];
2566
[?DQUOTE, String, ?DQUOTE];
2571
quoted_string_count([H | T], Count, IsSafe) ->
2572
case ?classify_char(H) of
2573
safe_char -> quoted_string_count(T, Count + 1, IsSafe);
2574
rest_char -> quoted_string_count(T, Count + 1, false);
2575
white_space -> quoted_string_count(T, Count + 1, false);
2576
_ -> error({illegal_char, H})
2578
quoted_string_count([], Count, IsSafe) ->
2581
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2583
%% Encode an octet string, escape } by \ if necessary
2584
enc_OCTET_STRING(List, State, Min, Max) ->
2585
do_enc_OCTET_STRING(List, State, Min, Max, 0).
2587
do_enc_OCTET_STRING([H | T], State, Min, Max, Count) ->
2590
[$\\, H | do_enc_OCTET_STRING(T, State, Min, Max, Count + 1)];
2592
[H | do_enc_OCTET_STRING(T, State, Min, Max, Count + 1)]
2594
do_enc_OCTET_STRING([], _State, Min, Max, Count) ->
2595
verify_count(Count, Min, Max),
2598
enc_QUOTED_STRING(String, _State) when list(String) ->
2599
{_IsSafe, Count} = quoted_string_count(String, 0, true),
2600
verify_count(Count, 1, infinity),
2601
[?DQUOTE, String, ?DQUOTE].
2603
%% The internal format of hex digits is a list of octets
2604
%% Min and Max means #hexDigits
2605
%% Leading zeros are prepended in order to fulfill Min
2606
enc_HEXDIG(Octets, State, Min, Max) when list(Octets) ->
2607
do_enc_HEXDIG(Octets, State, Min, Max, 0, []).
2609
do_enc_HEXDIG([Octet | Rest], State, Min, Max, Count, Acc)
2610
when Octet >= 0, Octet =< 255 ->
2611
Hex = hex(Octet), % OTP-4921
2614
Acc2 = [[$0|Hex]|Acc], % OTP-4921
2615
do_enc_HEXDIG(Rest, State, Min, Max, Count + 2, ["0" | Acc2]);
2617
Acc2 = [Hex|Acc], % OTP-4921
2618
do_enc_HEXDIG(Rest, State, Min, Max, Count + 2, Acc2)
2620
do_enc_HEXDIG([], State, Min, Max, Count, Acc)
2621
when integer(Min), Count < Min ->
2622
do_enc_HEXDIG([0], State, Min, Max, Count, Acc);
2623
do_enc_HEXDIG([], _State, Min, Max, Count, Acc) -> %% OTP-4710
2624
verify_count(Count, Min, Max),
2627
enc_DIGIT(Val, State, Min, Max) ->
2628
enc_integer(Val, State, Min, Max).
2630
enc_STRING(String, _State, Min, Max) when list(String) ->
2631
verify_count(length(String), Min, Max),
2634
enc_UINT16(Val, State) ->
2635
enc_integer(Val, State, 0, 65535).
2637
enc_UINT32(Val, State) ->
2638
enc_integer(Val, State, 0, 4294967295).
2640
enc_integer(Val, _State, Min, Max) ->
2641
verify_count(Val, Min, Max),
2642
integer_to_list(Val).
2644
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2645
%% Encodes a list of elements with separator tokens between
2646
%% the elements. Optional asn1_NOVALUE values are ignored.
2648
enc_list(List, State) ->
2649
enc_list(List, State, fun(_S) -> ?COMMA_INDENT(_S) end, false).
2651
enc_list([{Elems, ElemEncoder} | Tail], State, SepEncoder, NeedsSep) ->
2652
case do_enc_list(Elems, State, ElemEncoder, SepEncoder, NeedsSep) of
2654
enc_list(Tail, State, SepEncoder, NeedsSep);
2657
enc_list(Tail, State, SepEncoder, true)]
2659
enc_list([], _State, _SepEncoder, _NeedsSep) ->
2661
enc_list(asn1_NOVALUE, _State, _SepEncoder, _NeedsSep) ->
2663
enc_list(A, B, C, D) ->
2664
error({invalid_list, A, B, C, D}).
2666
do_enc_list(asn1_NOVALUE, _State, _ElemEncoder, _SepEncoder, _NeedsSep) ->
2668
do_enc_list([], _State, _ElemEncoder, _SepEncoder, _NeedsSep) ->
2670
do_enc_list([asn1_NOVALUE | T], State, ElemEncoder, SepEncoder, NeedsSep) ->
2671
do_enc_list(T, State, ElemEncoder, SepEncoder, NeedsSep);
2672
do_enc_list([H | T], State, ElemEncoder, SepEncoder, NeedsSep)
2673
when function(ElemEncoder), function(SepEncoder) ->
2674
case ElemEncoder(H, State) of
2676
do_enc_list(T, State, ElemEncoder, SepEncoder, NeedsSep);
2677
List when NeedsSep == true ->
2679
List, do_enc_list(T, State, ElemEncoder, SepEncoder, true)];
2680
List when NeedsSep == false ->
2682
do_enc_list(T, State, ElemEncoder, SepEncoder, true)]
2685
%% Add brackets if list is non-empty
2686
enc_opt_brackets([], _State) ->
2688
enc_opt_brackets(List, _State) when list(List) ->
2689
[?LBRKT_INDENT(_State), List, ?RBRKT_INDENT(_State)].
2691
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2693
%% Int -> list of hex chars
2695
hexi(get_lo_bits(Int, 4), []).
2697
hexi({0, Lo}, Ack) ->
2699
hexi({Hi, Lo} , Ack) ->
2700
hexi(get_lo_bits(Hi, 4), [hex4(Lo) | Ack]).
2702
hex4(Int) when Int < 10 ->
2707
get_lo_bits(Int, Size) ->
2708
Lo = Int band ones_mask(Size),
2715
%% Verify that Count is within the range of Min and Max
2716
verify_count(Count, Min, Max) ->
2720
integer(Min), Count >= Min ->
2722
integer(Max), Count =< Max ->
2727
error({count_too_large, Count, Max})
2730
error({count_too_small, Count, Min})
2733
error({count_not_an_integer, Count})
2736
%% -------------------------------------------------------------------
2739
erlang:fault(Reason).
2742
%% -------------------------------------------------------------------
2747
%% d(get(dbg), F, A).
2750
%% io:format("~p:" ++ F ++ "~n", [?MODULE | A]);