%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2005-2010. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% %% %CopyrightEnd% %% %% %%---------------------------------------------------------------------- %% Purpose: Encode V3 Megaco/H.248 text messages from internal form %%---------------------------------------------------------------------- %% -define(d(F,A), io:format("~w:" ++ F ++ "~n", [?MODULE|A])). -define(META_ENC(Type, Item), Item) . %% -define(META_ENC(Type, Item), megaco_meta_package:encode(text, Type, Item)). %% -define(META_DEC(Type, Item), megaco_meta_package:decode(text, Type, Item)). enc_MegacoMessage(Val) -> State = ?INIT_INDENT, enc_MegacoMessage(Val, State). enc_MegacoMessage(#'MegacoMessage'{authHeader = asn1_NOVALUE, mess = Mess}, State) -> [ ?LWSP, enc_Message(Mess, State) ]; enc_MegacoMessage(#'MegacoMessage'{authHeader = Auth, mess = Mess}, State) -> [ ?LWSP, enc_AuthenticationHeader(Auth, State), enc_Message(Mess, State) ]. %% Note that encoding the transaction this way %% make the message look a bit strange. enc_Transaction(Val) -> State = ?INIT_INDENT, enc_Transaction(Val, State). %% Note that encoding the action request's this way %% make the message look a bit strange. enc_ActionRequests(Val) -> State = ?INIT_INDENT, enc_TransactionRequest_actions(Val, State). %% Note that encoding the action request this way %% make the message look a bit strange. enc_ActionRequest(Val) -> State = ?INIT_INDENT, enc_ActionRequest(Val, State). enc_CommandRequest(Val) -> State = ?INIT_INDENT, enc_CommandRequest(Val, State). enc_ActionReply(Val) -> State = ?INIT_INDENT, enc_ActionReply(Val, State). enc_AuthenticationHeader(asn1_NOVALUE, _State) -> []; enc_AuthenticationHeader(Val, State) when is_record(Val, 'AuthenticationHeader') -> [ ?AuthToken, ?EQUAL, enc_SecurityParmIndex(Val#'AuthenticationHeader'.secParmIndex, State), ?COLON, enc_SequenceNum(Val#'AuthenticationHeader'.seqNum, State), ?COLON, enc_AuthData(Val#'AuthenticationHeader'.ad, State), ?SEP_INDENT(State) ]. enc_SecurityParmIndex({'SecurityParmIndex',Val}, State) -> enc_SecurityParmIndex(Val, State); enc_SecurityParmIndex(Val, State) -> [ "0x", enc_HEXDIG(Val, State, 8, 8) ]. enc_SequenceNum({'SequenceNum',Val}, State) -> enc_SequenceNum(Val, State); enc_SequenceNum(Val, State) -> [ "0x", enc_HEXDIG(Val, State, 8, 8) ]. enc_AuthData({'AuthData',Val}, State) -> enc_AuthData(Val, State); enc_AuthData(Val, State) -> [ "0x", enc_HEXDIG(Val, State, 24, 64) %% OTP-4710 ]. enc_Message(Val, State) when is_record(Val, 'Message') -> [ ?MegacopToken, ?SLASH, enc_version(Val#'Message'.version, State), ?SEP, enc_MId(Val#'Message'.mId, State), ?SEP_INDENT(State), enc_Message_messageBody(Val#'Message'.messageBody, State) ]. enc_version(Val, State) when is_integer(Val) and (Val >= 0) -> enc_DIGIT(Val, State, 0, 99). enc_Message_messageBody({'Message_messageBody',Val}, State) -> enc_Message_messageBody(Val, State); enc_Message_messageBody({Tag, Val}, State) -> case Tag of messageError -> enc_ErrorDescriptor(Val, State); transactions -> enc_Message_messageBody_transactions(Val, State); _ -> error({invalid_messageBody_tag, Tag}) end. enc_Message_messageBody_transactions({'Message_messageBody_transactions',Val}, State) -> enc_Message_messageBody_transactions(Val, State); enc_Message_messageBody_transactions(Val, State) when is_list(Val) and (Val /= []) -> [enc_Transaction(T, State) || T <- Val]. enc_MId({'MId',Val}, State) -> enc_MId(Val, State); enc_MId({Tag, Val}, State) -> case Tag of ip4Address -> enc_IP4Address(Val, State); ip6Address -> enc_IP6Address(Val, State); domainName -> enc_DomainName(Val, State); deviceName -> enc_PathName(Val, State); mtpAddress -> enc_mtpAddress(Val, State); _ -> error({invalid_MId_tag, Tag}) end. enc_mtpAddress(Val, State) -> [ ?MtpToken, ?LBRKT, enc_OCTET_STRING(Val, State, 2, 4), ?RBRKT ]. enc_DomainName(#'DomainName'{portNumber = asn1_NOVALUE, name = Name}, State) -> [ $<, %% BUGBUG: (ALPHA / DIGIT) *63(ALPHA / DIGIT / "-" / ".") enc_STRING(Name, State, 1, 64), $> ]; enc_DomainName(#'DomainName'{portNumber = PortNumber, name = Name}, State) -> [ $<, %% BUGBUG: (ALPHA / DIGIT) *63(ALPHA / DIGIT / "-" / ".") enc_STRING(Name, State, 1, 64), $>, $:, enc_portNumber(PortNumber, State) ]. enc_IP4Address(#'IP4Address'{portNumber = asn1_NOVALUE, address = [A1, A2, A3, A4]}, State) -> [ $[, enc_V4hex(A1, State), ?DOT, enc_V4hex(A2, State), ?DOT, enc_V4hex(A3, State), ?DOT, enc_V4hex(A4, State), $] ]; enc_IP4Address(#'IP4Address'{portNumber = PortNumber, address = [A1, A2, A3, A4]}, State) -> [ $[, enc_V4hex(A1, State), ?DOT, enc_V4hex(A2, State), ?DOT, enc_V4hex(A3, State), ?DOT, enc_V4hex(A4, State), $], $:, enc_portNumber(PortNumber, State) ]. enc_V4hex(Val, State) -> enc_DIGIT(Val, State, 0, 255). enc_IP6Address(#'IP6Address'{portNumber = asn1_NOVALUE, address = Addr}, State) when is_list(Addr) andalso (length(Addr) == 16) -> [ $[, enc_IP6Address_address(Addr, State), $] ]; enc_IP6Address(#'IP6Address'{portNumber = PortNumber, address = Addr}, State) when is_list(Addr) andalso (length(Addr) == 16) -> [ $[, enc_IP6Address_address(Addr, State), $], $:, enc_portNumber(PortNumber, State) ]. enc_IP6Address_address([0, 0|Addr], State) -> enc_IP6Address_address2(Addr, 1, false, true, State); enc_IP6Address_address(Addr, State) -> enc_IP6Address_address2(Addr, 0, false, false, State). enc_IP6Address_address2([0,0], 0, _Padding, _First, _State) -> [$0]; enc_IP6Address_address2([0,0], PadN, false, true, _State) when PadN > 0 -> [$:, $:]; % Padding from the beginning (all zero's) enc_IP6Address_address2([0,0], PadN, false, false, _State) when PadN > 0 -> [$:]; % Padding in the middle or end enc_IP6Address_address2([0,0], _, true, _First, _State) -> [$0]; enc_IP6Address_address2([N1,N2], 0, _Padding, _First, State) -> [enc_hex4([N1, N2], State)]; enc_IP6Address_address2([N1,N2], 1, _Padding, _First, State) -> [$0, $:, enc_hex4([N1, N2], State)]; enc_IP6Address_address2([N1,N2], PadN, false, true, State) when PadN > 1 -> [$:, $:, enc_hex4([N1, N2], State)]; enc_IP6Address_address2([N1,N2], PadN, false, false, State) when PadN > 1 -> [$:, enc_hex4([N1, N2], State)]; enc_IP6Address_address2([N1,N2], _PadN, true, _First, State) -> [enc_hex4([N1, N2], State)]; enc_IP6Address_address2([0, 0|Ns], PadN, false, First, State) -> enc_IP6Address_address2(Ns, PadN+1, false, First, State); enc_IP6Address_address2([0, 0|Ns], _PadN, true, _First, State) -> [ $0, $:, enc_IP6Address_address2(Ns, 0, true, false, State) ]; enc_IP6Address_address2([N1, N2|Ns], 0, Padded, _First, State) -> [ enc_hex4([N1, N2], State), $:, enc_IP6Address_address2(Ns, 0, Padded, false, State) ]; enc_IP6Address_address2([N1, N2|Ns], 1, Padded, _First, State) -> [ $0, $:, enc_hex4([N1, N2], State), $:, enc_IP6Address_address2(Ns, 0, Padded, false, State) ]; enc_IP6Address_address2([N1, N2|Ns], PadN, false, true, State) when PadN > 1 -> %% Padding from the beginning [ $:, $:, enc_hex4([N1, N2], State), $:, enc_IP6Address_address2(Ns, 0, true, false, State) ]; enc_IP6Address_address2([N1, N2|Ns], PadN, false, false, State) when PadN > 1 -> [ $:, %% The other ':' has already added enc_hex4([N1, N2], State), $:, enc_IP6Address_address2(Ns, 0, true, false, State) ]; enc_IP6Address_address2([N1, N2|Ns], _PadN, true, _First, State) -> [ enc_hex4([N1, N2], State), $:, enc_IP6Address_address2(Ns, 0, true, false, State) ]. enc_hex4([0,0], _State) -> $0; enc_hex4([0,N], _State) -> hex(N); enc_hex4([N1, N2], _State) when N2 =< 15 -> [hex(N1), $0, hex(N2)]; enc_hex4([N1, N2], _State) -> [hex(N1), hex(N2)]. enc_PathName({'PathName',Val}, State) -> enc_PathName(Val, State); enc_PathName(Val, State) -> %% BUGBUG: ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" ) %% BUGBUG: ["@" pathDomainName ] enc_STRING(Val, State, 1, 64). enc_Transaction(Bin, _State) when is_binary(Bin) -> [Bin]; %% Already encoded... enc_Transaction({'Transaction',Val}, State) -> enc_Transaction(Val, State); enc_Transaction({Tag, Val}, State) -> case Tag of transactionRequest -> enc_TransactionRequest(Val, State); transactionPending -> enc_TransactionPending(Val, State); transactionReply -> enc_TransactionReply(Val, State); transactionResponseAck -> enc_TransactionResponseAck(Val, State); segmentReply -> enc_SegmentReply(Val, State); _ -> error({invalid_Transaction_tag, Tag}) end. enc_TransactionResponseAck([Mand], State) -> [ ?ResponseAckToken, ?LBRKT_INDENT(State), [enc_TransactionAck(Mand, State)], ?RBRKT_INDENT(State) ]; enc_TransactionResponseAck([Mand | Opt], State) -> [ ?ResponseAckToken, ?LBRKT_INDENT(State), [enc_TransactionAck(Mand, State) | [[?COMMA_INDENT(State), enc_TransactionAck(Val, State)] || Val <- Opt]], ?RBRKT_INDENT(State) ]. enc_TransactionAck(Val, State) when is_record(Val, 'TransactionAck') -> [ enc_TransactionId(Val#'TransactionAck'.firstAck, ?INC_INDENT(State)), case Val#'TransactionAck'.lastAck of asn1_NOVALUE -> []; LastAck -> ["-",enc_TransactionId(LastAck, State)] end ]. enc_TransactionId({'TransactionId',Val}, State) -> enc_TransactionId(Val, State); enc_TransactionId(Val, State) -> enc_UINT32(Val, State). enc_TransactionRequest(#'TransactionRequest'{transactionId = Tid, actions = Acts}, State) -> [ ?TransToken, ?EQUAL, enc_TransactionId(Tid, State), ?LBRKT_INDENT(State), enc_TransactionRequest_actions(Acts, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_TransactionRequest(Bin, _State) when is_binary(Bin) -> [Bin]. enc_TransactionRequest_actions(Bin, _State) when is_binary(Bin) -> [Bin]; %% Already encoded... enc_TransactionRequest_actions({'TransactionRequest_actions',Val}, State) -> enc_TransactionRequest_actions(Val, State); enc_TransactionRequest_actions([Mand], State) -> [enc_ActionRequest(Mand, State)]; enc_TransactionRequest_actions([Mand | Opt], State) -> [enc_ActionRequest(Mand, State) | [[?COMMA_INDENT(State), enc_ActionRequest(Val, State)] || Val <- Opt]]. enc_TransactionPending(#'TransactionPending'{transactionId = Tid}, State) -> [?PendingToken, ?EQUAL, enc_TransactionId(Tid, State), ?LBRKT_INDENT(State), ?RBRKT_INDENT(State) ]; enc_TransactionPending(Bin, _State) when is_binary(Bin) -> [Bin]. enc_TransactionReply(#'TransactionReply'{transactionId = Tid, immAckRequired = asn1_NOVALUE, transactionResult = Res, segmentNumber = asn1_NOVALUE, segmentationComplete = asn1_NOVALUE }, State) -> [ ?ReplyToken, ?EQUAL, enc_TransactionId(Tid, State), ?LBRKT_INDENT(State), enc_TransactionReply_transactionResult(Res, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_TransactionReply(#'TransactionReply'{transactionId = Tid, immAckRequired = Req, transactionResult = Res, segmentNumber = asn1_NOVALUE, segmentationComplete = asn1_NOVALUE }, State) -> [ ?ReplyToken, ?EQUAL, enc_TransactionId(Tid, State), ?LBRKT_INDENT(State), enc_immAckRequired(Req, State), enc_TransactionReply_transactionResult(Res, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_TransactionReply(#'TransactionReply'{transactionId = Tid, immAckRequired = Req, transactionResult = Res, segmentNumber = SegNo, segmentationComplete = asn1_NOVALUE }, State) -> [ ?ReplyToken, ?EQUAL, enc_TransactionId(Tid, State), ?SLASH, enc_SegmentNumber(SegNo, State), ?LBRKT_INDENT(State), enc_immAckRequired(Req, State), enc_TransactionReply_transactionResult(Res, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_TransactionReply(#'TransactionReply'{transactionId = Tid, immAckRequired = Req, transactionResult = Res, segmentNumber = SegNo, segmentationComplete = 'NULL' }, State) -> [ ?ReplyToken, ?EQUAL, enc_TransactionId(Tid, State), ?SLASH, enc_SegmentNumber(SegNo, State), ?SLASH, ?SegmentationCompleteToken, ?LBRKT_INDENT(State), enc_immAckRequired(Req, State), enc_TransactionReply_transactionResult(Res, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_TransactionReply(Bin, _State) when is_binary(Bin) -> [Bin]. enc_SegmentReply({'SegmentReply', SR}, State) -> enc_SegmentReply(SR, State); enc_SegmentReply(#'SegmentReply'{transactionId = TID, segmentNumber = SegNo, segmentationComplete = asn1_NOVALUE }, State) -> [ ?MessageSegmentToken, ?EQUAL, enc_TransactionId(TID, State), ?SLASH, enc_SegmentNumber(SegNo, State) ]; enc_SegmentReply(#'SegmentReply'{transactionId = TID, segmentNumber = SegNo, segmentationComplete = 'NULL' }, State) -> [ ?MessageSegmentToken, ?EQUAL, enc_TransactionId(TID, State), ?SLASH, enc_SegmentNumber(SegNo, State), ?SLASH, ?SegmentationCompleteToken ]; enc_SegmentReply(Bin, _State) when is_binary(Bin) -> [Bin]. enc_SegmentNumber({'SegmentNumber', SN}, State) -> enc_SegmentNumber(SN, State); enc_SegmentNumber(SN, State) -> enc_UINT16(SN, State). enc_immAckRequired(Val, _State) -> case Val of asn1_NOVALUE -> []; 'NULL' -> [?ImmAckRequiredToken, ?COMMA_INDENT(?INC_INDENT(_State))] end. enc_TransactionReply_transactionResult({'TransactionReply_transactionResult', Val}, State) -> enc_TransactionReply_transactionResult(Val, State); enc_TransactionReply_transactionResult({Tag, Val}, State) -> case Tag of transactionError -> enc_ErrorDescriptor(Val, State); actionReplies -> enc_TransactionReply_transactionResult_actionReplies(Val, State); _ -> error({invalid_TransactionReply_transactionResult_tag, Tag}) end. enc_TransactionReply_transactionResult_actionReplies({'TransactionReply_transactionResult_actionReplies',Val}, State) -> enc_TransactionReply_transactionResult_actionReplies(Val, State); enc_TransactionReply_transactionResult_actionReplies([Mand], State) -> [enc_ActionReply(Mand, State)]; enc_TransactionReply_transactionResult_actionReplies([Mand | Opt], State) -> [enc_ActionReply(Mand, State), [[?COMMA_INDENT(State), enc_ActionReply(Val, State)] || Val <- Opt]]. enc_ErrorDescriptor(#'ErrorDescriptor'{errorText = asn1_NOVALUE, errorCode = Code}, State) -> [ ?ErrorToken, ?EQUAL, enc_ErrorCode(Code, State), ?LBRKT, ?RBRKT ]; enc_ErrorDescriptor(#'ErrorDescriptor'{errorText = Text, errorCode = Code}, State) -> [ ?ErrorToken, ?EQUAL, enc_ErrorCode(Code, State), ?LBRKT, enc_ErrorText(Text, State), ?RBRKT ]. enc_ErrorCode({'ErrorCode',Val}, State)-> enc_ErrorCode(Val, State); enc_ErrorCode(Val, State) -> enc_DIGIT(Val, State, 0, 999). enc_ErrorText({'ErrorText',Val}, State) -> enc_ErrorText(Val, State); enc_ErrorText(Val, State) -> enc_QUOTED_STRING(Val, State). enc_ContextID({'ContextID',Val}, State) -> enc_ContextID(Val, State); enc_ContextID(Val, State) -> case Val of ?megaco_all_context_id -> $*; ?megaco_null_context_id -> $-; ?megaco_choose_context_id -> $$; Int when is_integer(Int) -> enc_UINT32(Int, State) end. enc_ActionRequest(Bin, _State) when is_binary(Bin) -> [Bin]; %% Already encoded... enc_ActionRequest(#'ActionRequest'{contextId = CID, contextRequest = asn1_NOVALUE, contextAttrAuditReq = asn1_NOVALUE, commandRequests = CmdReqs}, State) -> [ ?CtxToken, ?EQUAL, enc_ContextID(CID, State), ?LBRKT_INDENT(State), enc_list([{CmdReqs, fun enc_CommandRequest/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_ActionRequest(#'ActionRequest'{contextId = CID, contextRequest = CtxReq, contextAttrAuditReq = asn1_NOVALUE, commandRequests = CmdReqs}, State) -> [ ?CtxToken, ?EQUAL, enc_ContextID(CID, State), ?LBRKT_INDENT(State), enc_list([{[CtxReq], fun enc_ContextRequest/2}, {CmdReqs, fun enc_CommandRequest/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_ActionRequest(#'ActionRequest'{contextId = CID, contextRequest = CtxReq, contextAttrAuditReq = CtxAAR, commandRequests = CmdReqs}, State) -> [ ?CtxToken, ?EQUAL, enc_ContextID(CID, State), ?LBRKT_INDENT(State), enc_list([{[CtxReq], fun enc_ContextRequest/2}, {[CtxAAR], fun enc_ContextAttrAuditRequest/2}, {CmdReqs, fun enc_CommandRequest/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_ActionReply(Bin, _State) when is_binary(Bin) -> [Bin]; % Already encoded... %% OTP-5085 enc_ActionReply(#'ActionReply'{contextId = Id, errorDescriptor = asn1_NOVALUE, contextReply = asn1_NOVALUE, commandReply = []}, State) -> %% d("enc_ActionReply -> entry with" %% "~n Id: ~p", [Id]), [ ?CtxToken, ?EQUAL, enc_ContextID(Id, State) ]; enc_ActionReply(#'ActionReply'{contextId = Id, errorDescriptor = ED, contextReply = CtxRep, commandReply = CmdRep}, State) -> %% d("enc_ActionReply -> entry with" %% "~n Id: ~p" %% "~n ED: ~p" %% "~n CtxRep: ~p" %% "~n CmdRep: ~p", [Id, ED, CtxRep, CmdRep]), [ ?CtxToken, ?EQUAL, enc_ContextID(Id, State), ?LBRKT_INDENT(State), do_enc_ActionReply(ED, CtxRep, CmdRep, State), ?RBRKT_INDENT(State) ]. do_enc_ActionReply(asn1_NOVALUE, CtxRep, [], State) when CtxRep =/= asn1_NOVALUE -> [ enc_ContextRequest(CtxRep, ?INC_INDENT(State)) ]; do_enc_ActionReply(asn1_NOVALUE, CtxRep, CmdRep, State) when (CtxRep =/= asn1_NOVALUE) and (CmdRep =/= []) -> [ enc_ContextRequest(CtxRep, ?INC_INDENT(State)), ?COMMA_INDENT(?INC_INDENT(State)), enc_list([{CmdRep, fun enc_CommandReply/2}], ?INC_INDENT(State)) ]; do_enc_ActionReply(asn1_NOVALUE, asn1_NOVALUE, CmdRep, State) when CmdRep =/= [] -> [ enc_list([{CmdRep, fun enc_CommandReply/2}], ?INC_INDENT(State)) ]; do_enc_ActionReply(ED, CtxRep, [], State) when (ED =/= asn1_NOVALUE) and (CtxRep =/= asn1_NOVALUE) -> [ enc_ContextRequest(CtxRep, ?INC_INDENT(State)), ?COMMA_INDENT(?INC_INDENT(State)), enc_list([{[ED], fun enc_ErrorDescriptor/2}], % Indention cosmetics ?INC_INDENT(State)) ]; do_enc_ActionReply(ED, asn1_NOVALUE, CmdRep, State) when (ED =/= asn1_NOVALUE) and (CmdRep =/= []) -> [ enc_list([{CmdRep, fun enc_CommandReply/2}, {[ED], fun enc_ErrorDescriptor/2}], % Indention cosmetics ?INC_INDENT(State)) ]; do_enc_ActionReply(ED, CtxRep, CmdRep, State) when (ED =/= asn1_NOVALUE) and (CtxRep =/= asn1_NOVALUE) and (CmdRep =/= []) -> [ enc_ContextRequest(CtxRep, ?INC_INDENT(State)), ?COMMA_INDENT(?INC_INDENT(State)), enc_list([{CmdRep, fun enc_CommandReply/2}, {[ED], fun enc_ErrorDescriptor/2}], % Indention cosmetics ?INC_INDENT(State)) ]; do_enc_ActionReply(ED, asn1_NOVALUE, [], State) when ED =/= asn1_NOVALUE -> [ enc_ErrorDescriptor(ED, ?INC_INDENT(State)) ]. enc_ContextRequest_priority(asn1_NOVALUE, _State) -> {[], dummy}; enc_ContextRequest_priority(Val, _State) -> {[Val], fun(X,S) -> [?PriorityToken,?EQUAL,enc_UINT16(X, S)] end}. enc_ContextRequest_emergency(asn1_NOVALUE, _State) -> {[], dummy}; enc_ContextRequest_emergency(true, _State) -> {[?EmergencyToken], fun(Elem, _) -> Elem end}; enc_ContextRequest_emergency(false, _State) -> {[?EmergencyOffToken], fun(Elem, _) -> Elem end}. enc_ContextRequest_topologyReq(asn1_NOVALUE, _State) -> {[], dummy}; enc_ContextRequest_topologyReq({'ContextRequest_topologyReq', asn1_NOVALUE}, _State) -> {[], dummy}; enc_ContextRequest_topologyReq({'ContextRequest_topologyReq', List}, _State) -> {List, fun enc_TopologyRequest/2}; enc_ContextRequest_topologyReq(List, _State) -> {[List], fun enc_TopologyRequest/2}. enc_ContextRequest_iepscallind(asn1_NOVALUE, _State) -> {[], dummy}; enc_ContextRequest_iepscallind(Bool, _State) -> {[Bool], fun enc_iepsValue/2}. enc_ContextRequest_contextProp(asn1_NOVALUE, _State) -> {[], dummy}; enc_ContextRequest_contextProp([], _State) -> {[], dummy}; enc_ContextRequest_contextProp(Props, _State) -> {[Props], fun(Elem, S) -> enc_contextAttrDescriptor(Elem, contextProps, S) end}. enc_ContextRequest_contextList(asn1_NOVALUE, _State) -> {[], dummy}; enc_ContextRequest_contextList([], _State) -> {[], dummy}; enc_ContextRequest_contextList(Props, _State) -> {[Props], fun(Elem, S) -> enc_contextAttrDescriptor(Elem, contextList, S) end}. enc_contextAttrDescriptor([Mand|Opt], contextProps, State) -> [ ?ContextAttrToken, ?LBRKT_INDENT(State), [enc_PropertyParm(Mand, State) | [[?COMMA_INDENT(State), enc_PropertyParm(Val, State)] || Val <- Opt]], ?RBRKT_INDENT(State) ]; enc_contextAttrDescriptor(CtxIdList, contextList, State) -> [ ?ContextAttrToken, ?LBRKT_INDENT(State), enc_contextIdList(CtxIdList, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_contextIdList([Mand|Opt], State) -> State2 = ?INC_INDENT(State), [ ?ContextListToken, ?EQUAL, ?LBRKT_INDENT(State), [enc_ContextID(Mand, State2) | [[?COMMA_INDENT(State2), enc_ContextID(Val, State2)] || Val <- Opt]], ?RBRKT_INDENT(State) ]. enc_ContextRequest(asn1_NOVALUE, _State) -> []; enc_ContextRequest(#'ContextRequest'{priority = asn1_NOVALUE, emergency = asn1_NOVALUE, topologyReq = asn1_NOVALUE, iepscallind = asn1_NOVALUE, contextProp = asn1_NOVALUE, contextList = asn1_NOVALUE}, _State) -> []; enc_ContextRequest(#'ContextRequest'{priority = asn1_NOVALUE, emergency = asn1_NOVALUE, topologyReq = [], iepscallind = asn1_NOVALUE, contextProp = [], contextList = []}, _State) -> []; enc_ContextRequest(#'ContextRequest'{priority = Prio, emergency = Em, topologyReq = TR, iepscallind = Ieps, contextProp = CP, contextList = CL}, State) -> [ enc_list([enc_ContextRequest_priority(Prio, State), enc_ContextRequest_emergency(Em, State), enc_ContextRequest_topologyReq(TR, State), enc_ContextRequest_iepscallind(Ieps, State), enc_ContextRequest_contextProp(CP, State), enc_ContextRequest_contextList(CL, State)], State) ]. %% -- contextAudit -- %% contextAudit = ContextAuditToken LBRKT %% (contextAuditProperties *(COMMA contextAuditProperties)) / %% indAudcontextAttrDesscriptor %% RBRKT %% contextAuditProperties = %% (TopologyToken / EmergencyToken / PriorityToken / %% IEPSToken / pkgdName / contextAuditSelect) %% contextAuditSelect = %% priority / emergencyValue / iepsValue / %% contextAttrDescriptor / auditSelectLogic %% indAudcontextAttrDesscriptor = %% ContextAttrToken LBRKT %% (contextAuditProperties *(COMMA contextAuditProperties)) %% RBRKT %% %% This could actually either be %% a) a list of contextAuditProperties: %% contextAuditProperties *(COMMA contextAuditProperties) %% b) a indAudcontextAttrDescriptor %% But since b) actually has the same content as a) with %% the extra ContextAttrToken, there does not seem to be any %% reason for using it. enc_ContextAttrAuditRequest(asn1_NOVALUE, _State) -> []; enc_ContextAttrAuditRequest( #'ContextAttrAuditRequest'{topology = asn1_NOVALUE, emergency = asn1_NOVALUE, priority = asn1_NOVALUE, iepscallind = asn1_NOVALUE, contextPropAud = asn1_NOVALUE, selectpriority = asn1_NOVALUE, selectemergency = asn1_NOVALUE, selectiepscallind = asn1_NOVALUE, selectLogic = asn1_NOVALUE}, _State) -> []; enc_ContextAttrAuditRequest( #'ContextAttrAuditRequest'{topology = asn1_NOVALUE, emergency = asn1_NOVALUE, priority = asn1_NOVALUE, iepscallind = asn1_NOVALUE, contextPropAud = [], selectpriority = asn1_NOVALUE, selectemergency = asn1_NOVALUE, selectiepscallind = asn1_NOVALUE, selectLogic = asn1_NOVALUE}, _State) -> []; enc_ContextAttrAuditRequest( #'ContextAttrAuditRequest'{topology = Top, emergency = Em, priority = Prio, iepscallind = Ieps, contextPropAud = CPA, selectpriority = SPrio, selectemergency = SEm, selectiepscallind = SIeps, selectLogic = SL}, State) -> [ ?ContextAuditToken, ?LBRKT_INDENT(State), enc_list([{[Top], fun('NULL', _) -> ?TopologyToken end}, {[Em], fun('NULL', _) -> ?EmergencyToken end}, {[Prio], fun('NULL', _) -> ?PriorityToken end}, {[Ieps], fun('NULL', _) -> ?IEPSToken end}, {CPA, fun enc_IndAudPropertyParm/2}, enc_ContextAttrAuditRequest_selectpriority(SPrio, State), enc_ContextAttrAuditRequest_selectemergency(SEm, State), enc_ContextAttrAuditRequest_selectiepscallind(SIeps, State), enc_ContextAttrAuditRequest_selectLogic(SL, State)], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_ContextAttrAuditRequest_selectpriority(asn1_NOVALUE, _State) -> {[], dummy}; enc_ContextAttrAuditRequest_selectpriority(SPrio, _State) -> {[SPrio], fun(X,S) -> [?PriorityToken,?EQUAL,enc_UINT16(X, S)] end}. enc_ContextAttrAuditRequest_selectemergency(asn1_NOVALUE, _State) -> {[], dummy}; enc_ContextAttrAuditRequest_selectemergency(SEm, _State) -> {[SEm], fun(X,S) -> enc_emergencyValue(X, S) end}. enc_ContextAttrAuditRequest_selectiepscallind(asn1_NOVALUE, _State) -> {[], dummy}; enc_ContextAttrAuditRequest_selectiepscallind(SEm, _State) -> {[SEm], fun(X,S) -> enc_iepsValue(X, S) end}. enc_ContextAttrAuditRequest_selectLogic(asn1_NOVALUE, _State) -> {[], dummy}; enc_ContextAttrAuditRequest_selectLogic({andAUDITSelect, 'NULL'}, _State) -> {[], dummy}; % This is default so, there is no reason to add it enc_ContextAttrAuditRequest_selectLogic({orAUDITSelect, 'NULL'}, _State) -> {[?OrAUDITselectToken], fun(Elem, _) -> Elem end}. enc_emergencyValue(true, _) -> [?EmergencyValueToken,?EQUAL,?EmergencyToken]; enc_emergencyValue(_, _) -> [?EmergencyValueToken,?EQUAL,?EmergencyOffToken]. %% enc_IndAudContextAttrDescriptor( %% #'ContextAttrAuditRequest'{topology = Top, %% emergency = Em, %% priority = Prio, %% iepscallind = Ieps, %% contextPropAud = CPA, %% selectpriority = SelPrio, %% selectemergency = SelEm, %% selectiepscallind = SelIeps, %% selectLogic = SelLog}, State) -> %% [ %% ?ContextAttrToken, %% ?LBRKT_INDENT(State), %% enc_list([{[Top], fun('NULL', _) -> ?TopologyToken end}, %% {[Em], fun('NULL', _) -> ?EmergencyToken end}, %% {[Prio], fun('NULL', _) -> ?PriorityToken end}, %% {[Ieps], fun('NULL', _) -> ?IEPSToken end}, %% {CPA, fun enc_IndAudPropertyParm/2}], %% ?INC_INDENT(State)), %% ?RBRKT_INDENT(State) %% ]. enc_CommandRequest(#'CommandRequest'{optional = asn1_NOVALUE, wildcardReturn = asn1_NOVALUE, command = Cmd}, State) -> [ enc_Command(Cmd, State) ]; enc_CommandRequest(#'CommandRequest'{optional = 'NULL', wildcardReturn = asn1_NOVALUE, command = Cmd}, State) -> [ "O-", enc_Command(Cmd, State) ]; enc_CommandRequest(#'CommandRequest'{optional = asn1_NOVALUE, wildcardReturn = 'NULL', command = Cmd}, State) -> [ "W-", enc_Command(Cmd, State) ]; enc_CommandRequest(#'CommandRequest'{optional = 'NULL', wildcardReturn = 'NULL', command = Cmd}, State) -> [ "O-", "W-", enc_Command(Cmd, State) ]. enc_Command({'Command',Val}, State) -> enc_Command(Val, State); enc_Command({Tag, Val}, State) -> %% d("enc_Command -> entry with" %% "~n Tag: ~p" %% "~n Val: ~p", [Tag, Val]), case Tag of addReq -> [?AddToken, enc_AmmRequest(Val, State)]; moveReq -> [?MoveToken, enc_AmmRequest(Val, State)]; modReq -> [?ModifyToken, enc_AmmRequest(Val, State)]; subtractReq -> [?SubtractToken, enc_SubtractRequest(Val, State)]; auditCapRequest -> [?AuditCapToken, enc_AuditRequest(Val, State)]; auditValueRequest -> [?AuditValueToken, enc_AuditRequest(Val, State)]; notifyReq -> [?NotifyToken, enc_NotifyRequest(Val, State)]; serviceChangeReq -> [?ServiceChangeToken, enc_ServiceChangeRequest(Val, State)]; _ -> error({invalid_Command_tag, Tag}) end. enc_CommandReply({'CommandReply',Val}, State) -> enc_CommandReply(Val, State); enc_CommandReply({Tag, Val}, State) -> %% d("enc_CommandReply -> entry with" %% "~n Tag: ~p" %% "~n Val: ~p", [Tag, Val]), case Tag of addReply -> [?AddToken, enc_AmmsReply(Val, State)]; moveReply -> [?MoveToken, enc_AmmsReply(Val, State)]; modReply -> [?ModifyToken, enc_AmmsReply(Val, State)]; subtractReply -> [?SubtractToken, enc_AmmsReply(Val, State)]; auditCapReply -> [?AuditCapToken, enc_AuditReply(Val, State)]; auditValueReply -> [?AuditValueToken, enc_AuditReply(Val, State)]; notifyReply -> [?NotifyToken, enc_NotifyReply(Val, State)]; serviceChangeReply -> [?ServiceChangeToken, enc_ServiceChangeReply(Val, State)]; _ -> error({invalid_CommandReply_tag, Tag}) end. enc_TopologyRequest(Val, State) when is_list(Val) -> [ ?TopologyToken, ?LBRKT_INDENT(State), enc_list([{Val, fun enc_TopologyRequest1/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_TopologyRequest1( #'TopologyRequest'{terminationFrom = From, terminationTo = To, topologyDirection = TD, streamID = asn1_NOVALUE, % OPTIONAL topologyDirectionExtension = asn1_NOVALUE % OPTIONAL }, State) -> [ enc_TerminationID(From, State), ?COMMA_INDENT(State), enc_TerminationID(To, State), ?COMMA_INDENT(State), enc_TopologyDirection(TD, State) ]; enc_TopologyRequest1( #'TopologyRequest'{terminationFrom = From, terminationTo = To, topologyDirection = TD, streamID = SID, % OPTIONAL topologyDirectionExtension = asn1_NOVALUE}, % OPTIONAL State) when (SID =/= asn1_NOVALUE) -> [ enc_TerminationID(From, State), ?COMMA_INDENT(State), enc_TerminationID(To, State), ?COMMA_INDENT(State), enc_TopologyDirection(TD, State), ?COMMA_INDENT(State), enc_StreamID(SID, State) ]; enc_TopologyRequest1( #'TopologyRequest'{terminationFrom = From, terminationTo = To, topologyDirection = TD, streamID = asn1_NOVALUE, % OPTIONAL topologyDirectionExtension = TDE}, % OPTIONAL State) when (TDE =/= asn1_NOVALUE) -> [ enc_TerminationID(From, State), ?COMMA_INDENT(State), enc_TerminationID(To, State), ?COMMA_INDENT(State), enc_TopologyDirection(TD, State), ?COMMA_INDENT(State), enc_TopologyDirectionExtension(TDE, State) ]; enc_TopologyRequest1( #'TopologyRequest'{terminationFrom = From, terminationTo = To, topologyDirection = TD, streamID = SID, % OPTIONAL topologyDirectionExtension = TDE}, % OPTIONAL State) when (SID =/= asn1_NOVALUE) and (TDE =/= asn1_NOVALUE) -> [ enc_TerminationID(From, State), ?COMMA_INDENT(State), enc_TerminationID(To, State), ?COMMA_INDENT(State), enc_TopologyDirection(TD, State), ?COMMA_INDENT(State), enc_StreamID(SID, State), ?COMMA_INDENT(State), enc_TopologyDirectionExtension(TDE, State) ]. enc_TopologyDirection(bothway, _State) -> ?BothwayToken; enc_TopologyDirection(isolate, _State) -> ?IsolateToken; enc_TopologyDirection(oneway, _State) -> ?OnewayToken. enc_TopologyDirectionExtension(onewayexternal, _State) -> ?OnewayExternalToken; enc_TopologyDirectionExtension(onewayboth, _State) -> ?OnewayBothToken. enc_iepsValue(Val, _State) -> [ ?IEPSToken, ?EQUAL, case Val of false -> ?OffToken; true -> ?OnToken end ]. enc_AmmRequest(#'AmmRequest'{terminationID = TIDs, descriptors = Ds}, State) -> [ %% Assume that Token is added elsewhere ?EQUAL, enc_termIDList(TIDs, State), enc_opt_brackets( enc_list([{Ds, fun enc_ammDescriptor/2}], ?INC_INDENT(State)), State) ]. enc_ammDescriptor({Tag, Desc}, State) -> case Tag of mediaDescriptor -> enc_MediaDescriptor(Desc, State); modemDescriptor -> enc_ModemDescriptor(Desc, State); muxDescriptor -> enc_MuxDescriptor(Desc, State); eventsDescriptor -> enc_EventsDescriptor(Desc, State); eventBufferDescriptor -> enc_EventBufferDescriptor(Desc, State); signalsDescriptor -> enc_SignalsDescriptor(Desc, State); digitMapDescriptor -> enc_DigitMapDescriptor(Desc, State); auditDescriptor -> enc_AuditDescriptor(Desc, State); statisticsDescriptor -> enc_StatisticsDescriptor(Desc, State); _ -> error({invalid_ammDescriptor_tag, Tag}) end. enc_AmmsReply(#'AmmsReply'{terminationID = TIDs, terminationAudit = asn1_NOVALUE}, State) -> [ ?EQUAL, enc_termIDList(TIDs, State) ]; enc_AmmsReply(#'AmmsReply'{terminationID = TIDs, terminationAudit = []}, State) -> [ ?EQUAL, enc_termIDList(TIDs, State) ]; enc_AmmsReply(#'AmmsReply'{terminationID = TIDs, terminationAudit = Res}, State) -> [ ?EQUAL, enc_termIDList(TIDs, State), case lists:flatten(enc_TerminationAudit(Res, ?INC_INDENT(State))) of [] -> []; L -> [ ?LBRKT_INDENT(State), L, ?RBRKT_INDENT(State) ] end ]. enc_SubtractRequest(#'SubtractRequest'{terminationID = TIDs, auditDescriptor = asn1_NOVALUE}, State) -> [ %% Assume that Token is added elsewhere ?EQUAL, enc_termIDList(TIDs, State) ]; enc_SubtractRequest(#'SubtractRequest'{terminationID = TIDs, auditDescriptor = AD}, State) -> [ %% Assume that Token is added elsewhere ?EQUAL, enc_termIDList(TIDs, State), ?LBRKT_INDENT(State), enc_AuditDescriptor(AD, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_AuditRequest(#'AuditRequest'{terminationID = TID, auditDescriptor = asn1_NOVALUE, terminationIDList = asn1_NOVALUE}, State) -> [ %% Assume that Token is added elsewhere ?EQUAL, enc_termIDList([TID], State) ]; enc_AuditRequest(#'AuditRequest'{terminationID = TID, auditDescriptor = asn1_NOVALUE, terminationIDList = [TID|_] = TIDList}, State) -> [ %% Assume that Token is added elsewhere ?EQUAL, enc_termIDList(TIDList, State) ]; enc_AuditRequest(#'AuditRequest'{terminationID = TID, auditDescriptor = asn1_NOVALUE, terminationIDList = TIDList}, _State) -> error({invalid_terminationID, TID, TIDList}); enc_AuditRequest(#'AuditRequest'{terminationID = TID, auditDescriptor = AD, terminationIDList = asn1_NOVALUE}, State) -> [ %% Assume that Token is added elsewhere ?EQUAL, enc_termIDList([TID], State), ?LBRKT_INDENT(State), enc_AuditDescriptor(AD, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_AuditRequest(#'AuditRequest'{terminationID = TID, auditDescriptor = AD, terminationIDList = [TID|_] = TIDList}, State) -> [ %% Assume that Token is added elsewhere ?EQUAL, enc_termIDList(TIDList, State), ?LBRKT_INDENT(State), enc_AuditDescriptor(AD, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_AuditRequest(#'AuditRequest'{terminationID = TID, auditDescriptor = _AD, terminationIDList = TIDList}, _State) -> error({invalid_terminationID, TID, TIDList}). %% auditReply = (AuditValueToken / AuditCapToken ) %% ( contextTerminationAudit / auditOther) %% auditOther = EQUAL TerminationID LBRKT %% terminationAudit RBRKT %% terminationAudit = auditReturnParameter *(COMMA auditReturnParameter) %% %% contextTerminationAudit = EQUAL CtxToken ( terminationIDList / %% LBRKT errorDescriptor RBRKT ) enc_AuditReply({Tag, Val}, State) -> %% d("enc_AuditReply -> entry with" %% "~n Tag: ~p" %% "~n Val: ~p", [Tag, Val]), case Tag of contextAuditResult -> [ ?EQUAL, ?CtxToken, enc_TerminationIDList(Val, State) ]; error -> [ ?EQUAL, ?CtxToken, ?LBRKT_INDENT(State), enc_ErrorDescriptor(Val, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; auditResult when is_record(Val, 'AuditResult') -> enc_auditOther(Val, State); auditResult -> error({invalid_auditResult, Val}); auditResultTermList -> enc_TermListAuditResult(Val, State); _ -> error({invalid_AuditReply_tag, Tag}) end. %% This is actually the same as AuditResult with the exception %% that instead of terminationID we have terminationIDList. enc_TermListAuditResult( #'TermListAuditResult'{terminationIDList = TIDList, terminationAuditResult = asn1_NOVALUE}, State) -> %% d("enc_TermListAuditResult -> entry with" %% "~n TIDList: ~p", [TIDList]), [ ?EQUAL, enc_termIDList(TIDList, State) ]; enc_TermListAuditResult( #'TermListAuditResult'{terminationIDList = TIDList, terminationAuditResult = []}, State) -> %% d("enc_TermListAuditResult -> entry with" %% "~n TIDList: ~p", [TIDList]), [ ?EQUAL, enc_termIDList(TIDList, State) ]; enc_TermListAuditResult( #'TermListAuditResult'{terminationIDList = TIDList, terminationAuditResult = TAR}, State) -> %% d("enc_TermListAuditResult -> entry with" %% "~n TIDList: ~p" %% "~n TAR: ~p", [TIDList, TAR]), [ ?EQUAL, enc_termIDList(TIDList, State), case lists:flatten(enc_TerminationAudit(TAR, ?INC_INDENT(State))) of [] -> []; L -> [ ?LBRKT_INDENT(State), L, ?RBRKT_INDENT(State) ] end ]. enc_auditOther(#'AuditResult'{terminationID = TID, terminationAuditResult = asn1_NOVALUE}, State) -> [ ?EQUAL, enc_termIDList([TID], State) ]; enc_auditOther(#'AuditResult'{terminationID = TID, terminationAuditResult = []}, State) -> [ ?EQUAL, enc_termIDList([TID], State) ]; enc_auditOther(#'AuditResult'{terminationID = TID, terminationAuditResult = Res}, State) -> [ ?EQUAL, enc_termIDList([TID], State), case lists:flatten(enc_TerminationAudit(Res, ?INC_INDENT(State))) of [] -> []; L -> [ ?LBRKT_INDENT(State), L, ?RBRKT_INDENT(State) ] end ]. enc_AuditDescriptor(#'AuditDescriptor'{auditToken = asn1_NOVALUE, auditPropertyToken = asn1_NOVALUE}, _State) -> % d("enc_AuditDescriptor(asn1_NOVALUE) -> entry"), [ ?AuditToken, [?LBRKT, ?RBRKT] ]; enc_AuditDescriptor(#'AuditDescriptor'{auditToken = [], auditPropertyToken = asn1_NOVALUE}, _State) -> % d("enc_AuditDescriptor([]) -> entry"), [ ?AuditToken, [?LBRKT, ?RBRKT] ]; enc_AuditDescriptor(#'AuditDescriptor'{auditToken = List, auditPropertyToken = asn1_NOVALUE}, State) -> [ ?AuditToken, [ ?LBRKT_INDENT(State), enc_list([{List, fun enc_auditItem/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ] ]; %% - v2 - enc_AuditDescriptor(#'AuditDescriptor'{auditToken = asn1_NOVALUE, auditPropertyToken = Prop}, State) -> [ ?AuditToken, [ ?LBRKT_INDENT(State), enc_auditPropertyToken(Prop, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ] ]; enc_AuditDescriptor(#'AuditDescriptor'{auditToken = List, auditPropertyToken = Prop}, State) -> [ ?AuditToken, [ ?LBRKT_INDENT(State), enc_list([{List, fun enc_auditItem/2}], ?INC_INDENT(State)), ?COMMA_INDENT(State), enc_auditPropertyToken(Prop, ?INC_INDENT(State)), % v2 ?RBRKT_INDENT(State) ] ]. enc_auditItem(signalsToken, _State) -> ?SignalsToken; enc_auditItem(eventBufferToken, _State) -> ?EventBufferToken; enc_auditItem(eventsToken, _State) -> ?EventsToken; enc_auditItem(Val, State) -> enc_auditReturnItem(Val, State). enc_auditReturnItem(muxToken, _State) -> ?MuxToken; enc_auditReturnItem(modemToken, _State) -> ?ModemToken; enc_auditReturnItem(mediaToken, _State) -> ?MediaToken; enc_auditReturnItem(digitMapToken, _State) -> ?DigitMapToken; enc_auditReturnItem(statsToken, _State) -> ?StatsToken; enc_auditReturnItem(observedEventsToken, _State) -> ?ObservedEventsToken; enc_auditReturnItem(packagesToken, _State) -> ?PackagesToken. %% - v2 begin - enc_auditPropertyToken([], _State) -> []; enc_auditPropertyToken([Param | Params], State) -> [enc_IndAudauditReturnParameter(Param, State), [[?COMMA_INDENT(State), enc_IndAudauditReturnParameter(P, State)] || P <- Params]]. enc_IndAudauditReturnParameter({Tag, Val}, State) -> case Tag of indAudMediaDescriptor -> enc_IndAudMediaDescriptor(Val, State); indAudEventsDescriptor -> enc_IndAudEventsDescriptor(Val, State); indAudSignalsDescriptor -> enc_IndAudSignalsDescriptor(Val, State); indAudDigitMapDescriptor -> enc_IndAudDigitMapDescriptor(Val, State); indAudEventBufferDescriptor -> enc_IndAudEventBufferDescriptor(Val, State); indAudStatisticsDescriptor -> enc_IndAudStatisticsDescriptor(Val, State); indAudPackagesDescriptor -> enc_IndAudPackagesDescriptor(Val, State); _ -> error({invalid_IndAudauditReturnParameter_tag, Tag}) end. enc_IndAudMediaDescriptor( #'IndAudMediaDescriptor'{termStateDescr = asn1_NOVALUE, streams = Streams}, State) -> [ ?MediaToken, ?LBRKT_INDENT(State), enc_IndAudMediaDescriptor_streams(Streams, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_IndAudMediaDescriptor( #'IndAudMediaDescriptor'{termStateDescr = TSD, streams = asn1_NOVALUE}, State) -> [ ?MediaToken, ?LBRKT_INDENT(State), enc_IndAudTerminationStateDescriptor(TSD, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_IndAudMediaDescriptor( #'IndAudMediaDescriptor'{termStateDescr = TSD, streams = Streams}, State) -> [ ?MediaToken, ?LBRKT_INDENT(State), enc_IndAudTerminationStateDescriptor(TSD, ?INC_INDENT(State)), ?COMMA_INDENT(State), enc_IndAudMediaDescriptor_streams(Streams, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_IndAudMediaDescriptor_streams({oneStream, Val}, State) -> enc_IndAudStreamParms(Val, State); enc_IndAudMediaDescriptor_streams({multiStream, Val}, State) -> enc_IndAudMediaDescriptor_multiStream(Val, State); enc_IndAudMediaDescriptor_streams({Tag, _Val}, _State) -> error({invalid_IndAudMediaDescriptor_streams_tag, Tag}). enc_IndAudTerminationStateDescriptor( #'IndAudTerminationStateDescriptor'{propertyParms = [], eventBufferControl = asn1_NOVALUE, serviceState = 'NULL', serviceStateSel = asn1_NOVALUE}, _State) -> [ ?TerminationStateToken, ?LBRKT_INDENT(_State), ?ServiceStatesToken, ?RBRKT_INDENT(_State) ]; enc_IndAudTerminationStateDescriptor( #'IndAudTerminationStateDescriptor'{propertyParms = [], eventBufferControl = asn1_NOVALUE, serviceState = asn1_NOVALUE, serviceStateSel = SSS}, State) when SSS =/= asn1_NOVALUE -> [ ?TerminationStateToken, ?LBRKT_INDENT(State), enc_serviceState(SSS, State), ?RBRKT_INDENT(State) ]; enc_IndAudTerminationStateDescriptor( #'IndAudTerminationStateDescriptor'{propertyParms = [], eventBufferControl = 'NULL', serviceState = asn1_NOVALUE, serviceStateSel = asn1_NOVALUE}, _State) -> [ ?TerminationStateToken, ?LBRKT_INDENT(_State), ?BufferToken, ?RBRKT_INDENT(_State) ]; enc_IndAudTerminationStateDescriptor( #'IndAudTerminationStateDescriptor'{propertyParms = [Parms], eventBufferControl = asn1_NOVALUE, serviceState = asn1_NOVALUE, serviceStateSel = asn1_NOVALUE}, State) -> #'IndAudPropertyParm'{name = Name} = Parms, [ ?TerminationStateToken, ?LBRKT_INDENT(State), enc_PkgdName(Name, State), ?RBRKT_INDENT(State) ]. enc_IndAudStreamParms( #'IndAudStreamParms'{localControlDescriptor = LCD, localDescriptor = LD, remoteDescriptor = RD, statisticsDescriptor = SD}, State) -> [ enc_list([{[LCD], fun enc_IndAudLocalControlDescriptor/2}, {[LD], fun enc_remoteDescriptor/2}, {[RD], fun enc_localDescriptor/2}, {[SD], fun enc_IndAudStatisticsDescriptor/2}], ?INC_INDENT(State)) ]. enc_IndAudLocalControlDescriptor( #'IndAudLocalControlDescriptor'{streamMode = SM, reserveValue = RV, reserveGroup = RG, propertyParms = PP, streamModeSel = asn1_NOVALUE}, State) -> [ ?LocalControlToken, ?LBRKT_INDENT(State), enc_list([{[SM], fun('NULL', _) -> ?ModeToken end}, {[RV], fun('NULL', _) -> ?ReservedValueToken end}, {[RG], fun('NULL', _) -> ?ReservedGroupToken end}, {PP, fun enc_IndAudPropertyParm/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_IndAudLocalControlDescriptor( #'IndAudLocalControlDescriptor'{streamMode = asn1_NOVALUE, reserveValue = RV, reserveGroup = RG, propertyParms = PP, streamModeSel = SMS}, State) -> [ ?LocalControlToken, ?LBRKT_INDENT(State), enc_list([{[RV], fun('NULL', _) -> ?ReservedValueToken end}, {[RG], fun('NULL', _) -> ?ReservedGroupToken end}, { PP, fun enc_IndAudPropertyParm/2}, {[SMS], fun enc_StreamMode/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_IndAudPropertyParm(#'IndAudPropertyParm'{name = Name, propertyParms = PP}, State) -> [ enc_list([{[Name], fun enc_PkgdName/2}, {[PP], fun enc_PropertyParm/2}], State) ]. enc_IndAudMediaDescriptor_multiStream(Val, State) when is_list(Val) -> [ enc_list([{Val, fun enc_IndAudStreamDescriptor/2}], State) ]; enc_IndAudMediaDescriptor_multiStream(Val, _State) -> error({invalid_IndAudMediaDescriptor_multiStream, Val}). enc_IndAudStreamDescriptor(#'IndAudStreamDescriptor'{streamID = SID, streamParms = Parms}, State) -> [ ?StreamToken, ?EQUAL, enc_StreamID(SID, State), ?LBRKT_INDENT(State), enc_IndAudStreamParms(Parms, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_IndAudEventBufferDescriptor( #'IndAudEventBufferDescriptor'{eventName = EvName, streamID = ID}, State) -> [ ?EventBufferToken, ?LBRKT_INDENT(State), enc_PkgdName(EvName, State), enc_IndAudEventBufferDescriptor_eventSpec(ID, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_IndAudEventBufferDescriptor_eventSpec(asn1_NOVALUE, _State) -> [ ]; enc_IndAudEventBufferDescriptor_eventSpec({eventParameterName, ParamName}, State) -> [ ?LBRKT_INDENT(State), enc_Name(ParamName, State), ?RBRKT_INDENT(State) ]; enc_IndAudEventBufferDescriptor_eventSpec({eventStream, ID}, State) -> [ ?LBRKT_INDENT(State), enc_eventStream(ID, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_IndAudEventBufferDescriptor_eventSpec(ID, State) -> [ ?LBRKT_INDENT(State), enc_eventStream(ID, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_IndAudEventsDescriptor( #'IndAudEventsDescriptor'{requestID = asn1_NOVALUE, pkgdName = Name, streamID = asn1_NOVALUE}, State) -> [ ?EventsToken, ?LBRKT_INDENT(State), enc_PkgdName(Name, State), ?RBRKT_INDENT(State) ]; enc_IndAudEventsDescriptor( #'IndAudEventsDescriptor'{requestID = RID, pkgdName = Name, streamID = asn1_NOVALUE}, State) -> [ ?EventsToken, ?EQUAL, enc_RequestID(RID, State), ?LBRKT_INDENT(State), enc_PkgdName(Name, State), ?RBRKT_INDENT(State) ]. enc_IndAudSignalsDescriptor(asn1_NOVALUE, _State) -> [ ?SignalsToken, ?LBRKT_INDENT(_State), ?RBRKT_INDENT(_State) ]; enc_IndAudSignalsDescriptor(Val, State) -> [ ?SignalsToken, ?LBRKT_INDENT(State), enc_IndAudSignalsDescriptor_value(Val, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_IndAudSignalsDescriptor_value({signal, Val}, State) -> enc_IndAudSignal(Val, State); enc_IndAudSignalsDescriptor_value({seqSigList, Val}, State) -> enc_IndAudSeqSigList(Val, State). enc_IndAudSignal(#'IndAudSignal'{signalName = SignalName, streamID = asn1_NOVALUE, signalRequestID = asn1_NOVALUE}, State) -> [ enc_SignalName(SignalName, State) ]; enc_IndAudSignal(#'IndAudSignal'{signalName = SignalName, streamID = SID, signalRequestID = SRID}, State) -> [ enc_SignalName(SignalName, State), ?LBRKT_INDENT(State), enc_list([{[SID], fun enc_StreamID/2}, {[SRID], fun enc_sigRequestID/2}], State), ?RBRKT_INDENT(State) ]. enc_IndAudSeqSigList(#'IndAudSeqSigList'{id = ID, signalList = asn1_NOVALUE}, State) -> [ ?SignalListToken, ?EQUAL, enc_UINT16(ID, State) ]; enc_IndAudSeqSigList(#'IndAudSeqSigList'{id = ID, signalList = SL}, State) -> [ ?SignalListToken, ?EQUAL, enc_UINT16(ID, State), ?LBRKT_INDENT(State), enc_IndAudSignal(SL, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_IndAudDigitMapDescriptor(#'IndAudDigitMapDescriptor'{digitMapName = Name}, State) -> [ ?DigitMapToken, ?EQUAL, enc_DigitMapName(Name, State) ]. enc_IndAudStatisticsDescriptor(#'IndAudStatisticsDescriptor'{statName = Name}, State) -> [ ?StatsToken, ?LBRKT_INDENT(State), enc_PkgdName(Name, State), ?RBRKT_INDENT(State) ]. enc_IndAudPackagesDescriptor(#'IndAudPackagesDescriptor'{packageName = N, packageVersion = V}, State) -> [ ?PackagesToken, ?LBRKT_INDENT(State), enc_Name(N, State), "-", enc_UINT16(V, State), ?RBRKT_INDENT(State) ]. %% - v2 end - enc_TerminationAudit({'TerminationAudit', Val}, State) -> enc_TerminationAudit(Val, State); enc_TerminationAudit([Mand | Opt], State) -> [enc_AuditReturnParameter(Mand, State), [[?COMMA_INDENT(State), enc_AuditReturnParameter(Val, State)] || Val <- Opt]]. enc_AuditReturnParameter({'AuditReturnParameter',Val}, State) -> enc_AuditReturnParameter(Val, State); enc_AuditReturnParameter({Tag, Val}, State) -> %% d("enc_AuditReturnParameter -> entry with" %% "~n Tag: ~p" %% "~n Val: ~p", [Tag, Val]), case Tag of mediaDescriptor -> enc_MediaDescriptor(Val, State); modemDescriptor -> enc_ModemDescriptor(Val, State); muxDescriptor -> enc_MuxDescriptor(Val, State); eventsDescriptor -> enc_EventsDescriptor(Val, State); signalsDescriptor -> enc_SignalsDescriptor(Val, State); digitMapDescriptor -> enc_DigitMapDescriptor(Val, State); observedEventsDescriptor -> enc_ObservedEventsDescriptor(Val, State); eventBufferDescriptor -> enc_EventBufferDescriptor(Val, State); statisticsDescriptor -> enc_StatisticsDescriptor(Val, State); packagesDescriptor -> enc_PackagesDescriptor(Val, State); errorDescriptor -> enc_ErrorDescriptor(Val, State); emptyDescriptors -> enc_EmptyDescriptors(Val, State); _ -> error({invalid_AuditReturnParameter_tag, Tag}) end. enc_EmptyDescriptors(#'AuditDescriptor'{auditToken = asn1_NOVALUE}, _State) -> []; enc_EmptyDescriptors(#'AuditDescriptor'{auditToken = []}, _State) -> []; enc_EmptyDescriptors(#'AuditDescriptor'{auditToken = List}, State) -> %% d("enc_AuditReturnParameter -> entry with" %% "~n List: ~p", [List]), enc_list([{List, fun enc_auditReturnItem/2}], State). enc_NotifyRequest(#'NotifyRequest'{terminationID = TIDs, observedEventsDescriptor = OED, errorDescriptor = asn1_NOVALUE}, State) -> [ %% Assume that Token is added elsewhere ?EQUAL, enc_termIDList(TIDs, State), ?LBRKT_INDENT(State), enc_ObservedEventsDescriptor(OED, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_NotifyRequest(#'NotifyRequest'{terminationID = TIDs, observedEventsDescriptor = OED, errorDescriptor = ED}, State) -> [ %% Assume that Token is added elsewhere ?EQUAL, enc_termIDList(TIDs, State), ?LBRKT_INDENT(State), enc_ObservedEventsDescriptor(OED, ?INC_INDENT(State)), ?COMMA, enc_ErrorDescriptor(ED, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_NotifyReply(#'NotifyReply'{terminationID = TIDs, errorDescriptor = asn1_NOVALUE}, State) -> [ %% Assume that Token is added elsewhere ?EQUAL, enc_termIDList(TIDs, State) ]; enc_NotifyReply(#'NotifyReply'{terminationID = TIDs, errorDescriptor = ED}, State) -> [ %% Assume that Token is added elsewhere ?EQUAL, enc_termIDList(TIDs, State), ?LBRKT_INDENT(State), enc_ErrorDescriptor(ED, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_ObservedEventsDescriptor( #'ObservedEventsDescriptor'{requestId = RID, observedEventLst = OEL}, State) -> [ ?ObservedEventsToken, ?EQUAL, enc_RequestID(RID, State), ?LBRKT_INDENT(State), enc_observedEvents(OEL, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_observedEvents([Mand | Opt], State) -> [enc_ObservedEvent(Mand, State), [[?COMMA_INDENT(State), enc_ObservedEvent(Val, State)] || Val <- Opt]]. %% ;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 enc_ObservedEvent(#'ObservedEvent'{eventName = EN, streamID = SID, eventParList = EPL, timeNotation = asn1_NOVALUE}, State) -> [ ?LWSP, enc_EventName(EN, State), enc_opt_brackets( enc_list([{[SID], fun enc_eventStream/2}, { EPL, fun enc_eventOther/2}], ?INC_INDENT(State)), State) ]; enc_ObservedEvent(#'ObservedEvent'{eventName = EN, streamID = SID, eventParList = EPL, timeNotation = TN}, State) -> [ enc_TimeNotation(TN, State), ?LWSP, ?COLON, ?LWSP, enc_EventName(EN, State), enc_opt_brackets( enc_list([{[SID], fun enc_eventStream/2}, {EPL, fun enc_eventOther/2}], ?INC_INDENT(State)), State) ]. enc_EventName({'EventName', Val}, State) -> enc_EventName(Val, State); enc_EventName(Val, State) -> PkgdName = ?META_ENC(event, Val), enc_PkgdName(PkgdName, State). enc_eventStream(Val, State) -> [ ?StreamToken, ?EQUAL, enc_StreamID(Val, State) ]. %% The value is already encoded enc_eventOther(#megaco_event_parameter{name = Name, value = Value}, State) when is_list(Value) -> [ enc_Name(Name, State), ?EqualToken, Value ]; %% Special treatment of the ds parameter of the dd/ce event enc_eventOther(#'EventParameter'{eventParameterName = "ds" = Name, value = [DigitString], extraInfo = asn1_NOVALUE}, State) -> [ enc_Name(Name, State), ?EqualToken, enc_DigitString(DigitString, State) ]; enc_eventOther(#'EventParameter'{eventParameterName = Name, value = Value, extraInfo = Extra}, State) -> [ enc_Name(Name, State), enc_propertyParmValues(Value, Extra, State) ]. enc_ServiceChangeRequest( #'ServiceChangeRequest'{terminationID = TIDs, serviceChangeParms = Parms}, State) -> [ %% Assume that Token is added elsewhere ?EQUAL, enc_termIDList(TIDs, State), ?LBRKT_INDENT(State), enc_ServiceChangeParm(Parms, ?INC_INDENT(State)), ?RBRKT_INDENT(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 ) enc_ServiceChangeReply( #'ServiceChangeReply'{terminationID = TIDs, serviceChangeResult = Res}, State) -> [ %% Assume that Token is added elsewhere ?EQUAL, enc_termIDList(TIDs, State), enc_ServiceChangeResult(Res, State) ]. enc_ServiceChangeResult({'ServiceChangeResult', Val}, State) -> enc_ServiceChangeResult(Val, State); enc_ServiceChangeResult({errorDescriptor, Val}, State) -> [ ?LBRKT_INDENT(State), enc_ErrorDescriptor(Val, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_ServiceChangeResult({serviceChangeResParms, Val}, State) -> case enc_ServiceChangeResParm(Val, ?INC_INDENT(?INC_INDENT(State))) of [] -> []; ResParms -> [ ?LBRKT_INDENT(State), ?ServicesToken, fun(_S) -> [ ?LBRKT_INDENT(_S), ResParms, ?RBRKT_INDENT(_S) ] end(?INC_INDENT(State)), ?RBRKT_INDENT(State) ] end; enc_ServiceChangeResult({Tag, _}, _State) -> error({invalid_ServiceChangeResult_tag, Tag}). %% Required length of termination ID list is 1 %% enc_TerminationIDList1({'TerminationIDList',Val}, State) -> %% enc_TerminationIDList1(Val, State); %% enc_TerminationIDList1([Singleton], State) -> %% enc_TerminationID(Singleton, State). %% No required length of termination ID list enc_TerminationIDList({'TerminationIDList',Val}, State) -> enc_TerminationIDList(Val, State); enc_TerminationIDList([TID], State) -> [ ?LBRKT_INDENT(State), enc_TerminationID(TID, State), ?RBRKT_INDENT(State) ]; enc_TerminationIDList(TIDs, State) -> [ ?LBRKT_INDENT(State), enc_list([{TIDs, fun enc_TerminationID/2}], State), ?RBRKT_INDENT(State) ]. enc_termIDList({'TerminationIDList',Val}, State) -> enc_termIDList(Val, State); enc_termIDList([Singleton], State) -> enc_TerminationID(Singleton, State); enc_termIDList(TidList, State) when is_list(TidList) and (length(TidList) > 1) -> %% d("enc_termIDList -> entry with" %% "~n TidList: ~p", [TidList]), State2 = ?INC_INDENT(State), [ ?LSBRKT_INDENT(State), enc_list([{TidList, fun enc_TerminationID/2}], State2), ?RSBRKT_INDENT(State) ]. %% TerminationID = "ROOT" / pathNAME / "$" / "*" %% ; Total length of pathNAME must not exceed 64 chars. %% pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" ) %% ["@" pathDomainName ] enc_TerminationID(Tid, State) when is_record(Tid, megaco_term_id) -> List = [{Tid#megaco_term_id.id, fun enc_tid_component/2 }], enc_list(List, State, fun(_S) -> ?SLASH end, false). enc_tid_component(Component, State) when is_list(Component) -> [enc_tid_sub_component(Sub, State) || Sub <- Component]; enc_tid_component(Invalid, _State) -> error({invalid_id_list_component, Invalid}). enc_tid_sub_component(all = _Sub, _State) -> ?megaco_all; enc_tid_sub_component(choose = _Sub, _State) -> ?megaco_choose; enc_tid_sub_component(Char, _State) when is_integer(Char) -> Char; enc_tid_sub_component(Invalid, _State) -> error({invalid_id_list_sub_component, Invalid}). %% enc_tid_sub_component(Sub, _State) -> %% case Sub of %% all -> ?megaco_all; %% choose -> ?megaco_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 enc_MediaDescriptor(#'MediaDescriptor'{termStateDescr = TSD, streams = Streams}, State) -> [ ?MediaToken, ?LBRKT_INDENT(State), enc_list([{[TSD], fun enc_TerminationStateDescriptor/2} | decompose_streams(Streams)], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. decompose_streams(asn1_NOVALUE) -> []; decompose_streams({'MediaDescriptor_streams',Val}) -> decompose_streams(Val); decompose_streams({Tag, Val}) -> case Tag of oneStream -> decompose_StreamParms(Val); multiStream -> [{Val, fun enc_StreamDescriptor/2}]; _ -> error({invalid_streams_tag, Tag}) end. decompose_StreamParms(Val) when is_record(Val, 'StreamParms') -> [ {[Val#'StreamParms'.localControlDescriptor], fun enc_LocalControlDescriptor/2}, {[Val#'StreamParms'.localDescriptor], fun enc_localDescriptor/2}, {[Val#'StreamParms'.remoteDescriptor], fun enc_remoteDescriptor/2}, {[Val#'StreamParms'.statisticsDescriptor], fun enc_StatisticsDescriptor/2} ]. enc_StreamDescriptor(Val, State) when is_record(Val, 'StreamDescriptor') -> [ ?StreamToken, ?EQUAL, enc_StreamID(Val#'StreamDescriptor'.streamID, State), ?LBRKT_INDENT(State), enc_list(decompose_StreamParms(Val#'StreamDescriptor'.streamParms), ?INC_INDENT(State)), ?RBRKT_INDENT(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 enc_LocalControlDescriptor( #'LocalControlDescriptor'{streamMode = asn1_NOVALUE, reserveValue = asn1_NOVALUE, reserveGroup = asn1_NOVALUE, propertyParms = []}, _State) -> error({invalid_LocalControlDescriptor, empty}); enc_LocalControlDescriptor( #'LocalControlDescriptor'{streamMode = SM, reserveValue = RV, reserveGroup = RG, propertyParms = PPs}, State) -> [ ?LocalControlToken, ?LBRKT_INDENT(State), enc_list([{[SM], fun enc_StreamMode/2}, {[RG], fun enc_reservedGroupMode/2}, {[RV], fun enc_reservedValueMode/2}, {PPs, fun enc_PropertyParm/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_reservedGroupMode(Val, _State) -> [ ?ReservedGroupToken, ?EQUAL, case Val of false -> ?OffToken; true -> ?OnToken end ]. enc_reservedValueMode(Val, _State) -> [ ?ReservedValueToken, ?EQUAL, case Val of false -> ?OffToken; true -> ?OnToken end ]. enc_StreamMode({'StreamMode',Val}, State) -> enc_StreamMode(Val, State); enc_StreamMode(Val, _State) -> [ ?ModeToken, ?EQUAL, case Val of sendOnly -> ?SendonlyToken; recvOnly -> ?RecvonlyToken; sendRecv -> ?SendrecvToken; inactive -> ?InactiveToken; loopBack -> ?LoopbackToken end ]. enc_Name({'Name',Val}, State) -> enc_Name(Val, State); enc_Name(Val, State) -> %% BUGBUG: NAME = ALPHA *63(ALPHA / DIGIT / "_" ) enc_STRING(Val, State, 1, 64). enc_PkgdName({'PkgdName', Val}, State) -> enc_PkgdName(Val, State); enc_PkgdName(Val, _State) -> %% BUGBUG: pkgdName = (NAME / "*") SLASH (ItemID / "*" ) %% enc_OCTET_STRING(Val, _State, 1, 64). if is_list(Val) -> Length = length(Val), if (Length >= 1) -> if (Length =< 64) -> Val; true -> error({pkgdName_toolong, Length, 64}) end; true -> error({pkgdName_tooshort, Length, 1}) end; true -> error({invalid_PkgdName, Val}) end. enc_localDescriptor(Val, State) when is_record(Val, 'LocalRemoteDescriptor') -> [ ?LocalToken, ?LBRKT, enc_LocalRemoteDescriptor(Val, State), ?RBRKT_INDENT(State) ]. enc_remoteDescriptor(Val, State) when is_record(Val, 'LocalRemoteDescriptor') -> [ ?RemoteToken, ?LBRKT, enc_LocalRemoteDescriptor(Val, State), ?RBRKT_INDENT(State) ]. %% 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. enc_LocalRemoteDescriptor(Val, State) when is_record(Val, 'LocalRemoteDescriptor') -> case Val#'LocalRemoteDescriptor'.propGrps of [] -> []; [OptV | MandV] -> [?LfToken, enc_PropertyGroup(OptV, opt_v, State) | [enc_PropertyGroup(M, mand_v, State) || M <- MandV]] end. enc_PropertyGroup({'PropertyGroup',Val}, RequiresV, State) -> enc_PropertyGroup(Val, RequiresV, State); enc_PropertyGroup([H | _T] = List, mand_v, State) when is_record(H, 'PropertyParm') and (H#'PropertyParm'.name == "v") -> enc_PropertyGroup(List, opt_v, State); enc_PropertyGroup(PG, opt_v, State) -> [ [[enc_PropertyGroupParm(PP, State), ?CrToken, ?LfToken] || PP <- PG] ]. enc_PropertyGroupParm(Val, State) when is_record(Val, 'PropertyParm') -> [OctetString] = Val#'PropertyParm'.value, [ enc_PkgdName(Val#'PropertyParm'.name, State), ?EqualToken, enc_OCTET_STRING(OctetString, State, 0, infinity) ]. %% propertyParm = pkgdName parmValue %% parmValue = (EQUAL alternativeValue/ INEQUAL VALUE) %% alternativeValue = ( VALUE / LSBRKT VALUE *(COMMA VALUE) RSBRKT / %% LSBRKT VALUE DOT DOT VALUE RSBRKT ) enc_PropertyParm(Val, State) when is_record(Val, 'PropertyParm') -> PkgdName = ?META_ENC(property, Val#'PropertyParm'.name), [ enc_PkgdName(PkgdName, State), enc_propertyParmValues(Val#'PropertyParm'.value, Val#'PropertyParm'.extraInfo, State) ]. enc_propertyParmValues([Single], asn1_NOVALUE, State) -> [ ?EqualToken, enc_Value(Single, State) ]; enc_propertyParmValues([Single], {relation, Rel}, State) -> case Rel of greaterThan -> [$>, enc_Value(Single, State)]; smallerThan -> [$<, enc_Value(Single, State)]; unequalTo -> [$#, enc_Value(Single, State)] end; enc_propertyParmValues([Low, High], {range, true}, State)-> %% Exact two values [ ?EQUAL, ?LSBRKT, enc_Value(Low, State), ?COLON, enc_Value(High, State), ?RSBRKT ]; enc_propertyParmValues(Values, {sublist, true}, State)-> %% sublist (i.e. A AND B AND ...) [ ?EQUAL, ?LSBRKT_INDENT(State), enc_list([{Values, fun enc_Value/2}], ?INC_INDENT(State)), ?RSBRKT_INDENT(State) ]; enc_propertyParmValues(Values, {sublist, false}, State) -> %% alternatives (i.e. A OR B OR ...) [ ?EQUAL, ?LBRKT_INDENT(State), enc_list([{Values, fun enc_Value/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_propertyParmValues(V, EI, _State) -> error({invalid_property_parm_values, V, EI}). enc_TerminationStateDescriptor(Val, State) when is_record(Val, 'TerminationStateDescriptor') -> [ ?TerminationStateToken, ?LBRKT_INDENT(State), enc_list([{Val#'TerminationStateDescriptor'.propertyParms, fun enc_PropertyParm/2}, {[Val#'TerminationStateDescriptor'.eventBufferControl], fun enc_eventBufferControl/2}, {[Val#'TerminationStateDescriptor'.serviceState], fun enc_serviceState/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_eventBufferControl(Val, _State) -> [ ?BufferToken, ?EQUAL, case Val of off -> ?OffToken; lockStep -> ?LockStepToken end ]. enc_serviceState({'ServiceState',Val}, State) -> enc_serviceState(Val, State); enc_serviceState(Val, _State) -> [ ?ServiceStatesToken, ?EQUAL, case Val of test -> ?TestToken; outOfSvc -> ?OutOfSvcToken; inSvc -> ?InSvcToken end ]. enc_MuxDescriptor(Val, State) when is_record(Val, 'MuxDescriptor') -> [ ?MuxToken, ?EQUAL, enc_MuxType(Val#'MuxDescriptor'.muxType, State), enc_TerminationIDList(Val#'MuxDescriptor'.termList, State) ]. enc_MuxType({'MuxType',Val}, State) -> enc_MuxType(Val, State); enc_MuxType(Val, _State) -> case Val of h221 -> ?H221Token; h223 -> ?H223Token; h226 -> ?H226Token; v76 -> ?V76Token; %% extensionParameter nx64k -> ?Nx64kToken % v2 end. enc_StreamID({'StreamID',Val}, State) -> enc_StreamID(Val, State); enc_StreamID(Val, State) -> enc_UINT16(Val, State). enc_EventsDescriptor(#'EventsDescriptor'{requestID = asn1_NOVALUE, eventList = []}, _State) -> [ ?EventsToken ]; enc_EventsDescriptor(#'EventsDescriptor'{requestID = RID, eventList = Evs}, State) when (RID =/= asn1_NOVALUE) and (Evs =/= []) -> [ ?EventsToken, ?EQUAL, enc_RequestID(RID, State), ?LBRKT_INDENT(State), enc_list([{Evs, fun enc_RequestedEvent/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_EventsDescriptor(#'EventsDescriptor'{requestID = RID, eventList = Evs}, _State) -> error({invalid_EventsDescriptor, RID, Evs}). enc_RequestedEvent(#'RequestedEvent'{pkgdName = N, streamID = asn1_NOVALUE, eventAction = asn1_NOVALUE, evParList = []}, State) -> PkgdName = ?META_ENC(event, N), [ enc_PkgdName(PkgdName, State) ]; enc_RequestedEvent(#'RequestedEvent'{pkgdName = N, streamID = SID, eventAction = EA, evParList = EPL}, State) -> PkgdName = ?META_ENC(event, N), [ enc_PkgdName(PkgdName, State), ?LBRKT_INDENT(State), enc_list([{[SID], fun enc_eventStream/2}, {EPL, fun enc_eventOther/2} | decompose_requestedActions(EA)], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. decompose_requestedActions(asn1_NOVALUE) -> []; decompose_requestedActions( #'RequestedActions'{keepActive = asn1_NOVALUE, eventDM = asn1_NOVALUE, secondEvent = asn1_NOVALUE, signalsDescriptor = asn1_NOVALUE, notifyBehaviour = asn1_NOVALUE, resetEventsDescriptor = asn1_NOVALUE}) -> []; %% %% This in the ABNF: %% at-most-once each of %% - KeepActiveToken %% - notifyBehaviour %% - eventDM %% - ResetEventsDescriptor %% - eventStream %% at most one of either embedWithSig or embedNoSig but not both %% KeepActiveToken and embedWithSig must not both be present %% %% embedWithSig decompose_requestedActions(#'RequestedActions'{keepActive = KA, eventDM = EDM, secondEvent = SE, signalsDescriptor = SD, notifyBehaviour = NB, resetEventsDescriptor = RED}) when (KA =/= true) and ((SD =/= asn1_NOVALUE) and (SD =/= [])) -> [ {[EDM], fun enc_EventDM/2}, {[{SE, SD}], fun enc_embedWithSig/2}, {[NB], fun enc_notifyBehaviour/2}, {[RED], fun('NULL', _) -> ?ResetEventsDescriptorToken end} ]; %% embedNoSig decompose_requestedActions(#'RequestedActions'{keepActive = KA, eventDM = EDM, secondEvent = SE, signalsDescriptor = SD, notifyBehaviour = NB, resetEventsDescriptor = RED}) when (SD == asn1_NOVALUE) or (SD == []) -> [ {[KA], fun enc_keepActive/2}, {[EDM], fun enc_EventDM/2}, {[SE], fun enc_embedNoSig/2}, {[NB], fun enc_notifyBehaviour/2}, {[RED], fun('NULL', _) -> ?ResetEventsDescriptorToken end} ]; %% Fallback, if everything else failes.... decompose_requestedActions(#'RequestedActions'{keepActive = KA, eventDM = EDM, secondEvent = SE, signalsDescriptor = SD, notifyBehaviour = NB, resetEventsDescriptor = RED}) -> [ {[KA], fun enc_keepActive/2}, {[EDM], fun enc_EventDM/2}, {[{SE, SD}], fun enc_embedWithSig/2}, {[NB], fun enc_notifyBehaviour/2}, {[RED], fun('NULL', _) -> ?ResetEventsDescriptorToken end} ]. enc_embedNoSig(#'SecondEventsDescriptor'{requestID = RID, eventList = Evs}, State) -> [ ?EmbedToken, ?LBRKT_INDENT(State), enc_embedFirst(RID, Evs, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_embedWithSig({asn1_NOVALUE, SD}, State) -> [ ?EmbedToken, ?LBRKT_INDENT(State), enc_SignalsDescriptor(SD, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_embedWithSig({#'SecondEventsDescriptor'{requestID = RID, eventList = Evs}, SD}, State) -> [ ?EmbedToken, ?LBRKT_INDENT(State), enc_SignalsDescriptor(SD, ?INC_INDENT(State)), ?COMMA_INDENT(?INC_INDENT(State)), enc_embedFirst(RID, Evs, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_keepActive(Val, _State) -> case Val of true -> [?KeepActiveToken]; false -> [] end. enc_EventDM({'EventDM',Val}, State) -> enc_EventDM(Val, State); enc_EventDM({Tag, Val}, State) -> case Tag of digitMapName -> [ ?DigitMapToken, ?EQUAL, enc_DigitMapName(Val, State) ]; digitMapValue -> [ ?DigitMapToken, ?LBRKT_INDENT(State), enc_DigitMapValue(Val, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; _ -> error({invalid_EventDM_tag, Tag}) end. enc_embedFirst(RID, Evs, State) when (RID =/= asn1_NOVALUE) and (is_list(Evs) and (Evs =/= [])) -> %% d("enc_embedFirst -> entry with" %% "~n RID: ~p" %% "~n Evs: ~p", [RID, Evs]), [ ?EventsToken, ?EQUAL, enc_RequestID(RID, State), ?LBRKT_INDENT(State), enc_list([{Evs, fun enc_SecondRequestedEvent/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_embedFirst(_RID, _Evs, _State) -> %% d("enc_embedFirst -> entry"), [ ?EventsToken ]. enc_notifyBehaviour({notifyImmediate, 'NULL'}, _State) -> [?NotifyImmediateToken]; enc_notifyBehaviour({notifyRegulated, Val}, State) -> enc_RegulatedEmbeddedDescriptor(Val, State); enc_notifyBehaviour({neverNotify, 'NULL'}, _State) -> [?NeverNotifyToken]; enc_notifyBehaviour({Tag, Val}, _State) -> error({invalid_notifyBehaviour, Tag, Val}). enc_RegulatedEmbeddedDescriptor( #'RegulatedEmbeddedDescriptor'{secondEvent = asn1_NOVALUE, signalsDescriptor = asn1_NOVALUE}, _State) -> [ ?NotifyRegulatedToken ]; enc_RegulatedEmbeddedDescriptor( #'RegulatedEmbeddedDescriptor'{secondEvent = SE, signalsDescriptor = asn1_NOVALUE}, State) -> [ ?NotifyRegulatedToken, ?LBRKT_INDENT(State), enc_embedNoSig(SE, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_RegulatedEmbeddedDescriptor( #'RegulatedEmbeddedDescriptor'{secondEvent = SE, signalsDescriptor = SD}, State) -> [ ?NotifyRegulatedToken, ?LBRKT_INDENT(State), enc_embedWithSig({SE, SD}, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_RegulatedEmbeddedDescriptor(Val, _State) -> error({invalid_RegulatedEmbeddedDescriptor, Val}). enc_SecondRequestedEvent(#'SecondRequestedEvent'{pkgdName = N, streamID = asn1_NOVALUE, eventAction = asn1_NOVALUE, evParList = []}, State) -> PkgdName = ?META_ENC(event, N), [ enc_PkgdName(PkgdName, State) ]; enc_SecondRequestedEvent(#'SecondRequestedEvent'{pkgdName = N, streamID = SID, eventAction = EA, evParList = EPL}, State) -> PkgdName = ?META_ENC(event, N), [ enc_PkgdName(PkgdName, State), ?LBRKT_INDENT(State), enc_list([{[SID], fun enc_eventStream/2}, {EPL, fun enc_eventOther/2} | decompose_secondRequestedActions(EA)], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. %% %% This in the ABNF: %% at-most-once each of %% - KeepActiveToken %% - notifyBehaviour %% - eventDM %% - ResetEventsDescriptor %% - eventStream %% KeepActiveToken and embedWithSig must not both be present %% decompose_secondRequestedActions(asn1_NOVALUE) -> []; decompose_secondRequestedActions( #'SecondRequestedActions'{keepActive = asn1_NOVALUE, eventDM = asn1_NOVALUE, signalsDescriptor = asn1_NOVALUE, notifyBehaviour = asn1_NOVALUE, resetEventsDescriptor = asn1_NOVALUE}) -> []; decompose_secondRequestedActions( #'SecondRequestedActions'{keepActive = KA, eventDM = EDM, signalsDescriptor = SD, notifyBehaviour = NB, resetEventsDescriptor = RED}) when (KA =/= true) and ((SD =/= asn1_NOVALUE) and (SD =/= [])) -> [ {[EDM], fun enc_EventDM/2}, {[SD], fun enc_embedSig/2}, {[NB], fun enc_notifyBehaviour/2}, {[RED], fun('NULL', _) -> ?ResetEventsDescriptorToken end} ]; decompose_secondRequestedActions( #'SecondRequestedActions'{keepActive = KA, eventDM = EDM, signalsDescriptor = SD, notifyBehaviour = NB, resetEventsDescriptor = RED}) when (SD == asn1_NOVALUE) or (SD == []) -> [ {[KA], fun enc_keepActive/2}, {[EDM], fun enc_EventDM/2}, {[NB], fun enc_notifyBehaviour/2}, {[RED], fun('NULL', _) -> ?ResetEventsDescriptorToken end} ]; decompose_secondRequestedActions(SRA) -> error({invalid_SecondRequestedActions, SRA}). enc_embedSig(Val, State) -> [ ?EmbedToken, ?LBRKT_INDENT(State), enc_SignalsDescriptor(Val, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_EventBufferDescriptor({'EventBufferDescriptor',Val}, State) -> enc_EventBufferDescriptor(Val, State); enc_EventBufferDescriptor([], _State) -> [ ?EventBufferToken ]; enc_EventBufferDescriptor(EvSpecs, State) when is_list(EvSpecs) andalso (length(EvSpecs) >= 1) -> [ ?EventBufferToken, ?LBRKT_INDENT(State), enc_eventSpecs(EvSpecs, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_EventBufferDescriptor(EvSpecs, _State) -> error({bad_eventSpecs, EvSpecs}). enc_eventSpecs([Mand | Opt], State) -> [enc_eventSpec(Mand, State), [[?COMMA_INDENT(State), enc_eventSpec(Val, State)] || Val <- Opt]]. enc_eventSpec(#'EventSpec'{eventName = N, streamID = asn1_NOVALUE, eventParList = []}, State) -> [ enc_EventName(N, State) ]; enc_eventSpec(#'EventSpec'{eventName = N, streamID = SID, eventParList = EPL}, State) -> [ enc_EventName(N, State), ?LBRKT_INDENT(State), enc_list([{[SID], fun enc_eventStream/2}, {EPL, fun enc_eventOther/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_SignalsDescriptor({'SignalsDescriptor',Val}, State) -> enc_SignalsDescriptor(Val, State); enc_SignalsDescriptor([], _State) -> [ ?SignalsToken ]; enc_SignalsDescriptor(SigRequests, State) when is_list(SigRequests) -> [ ?SignalsToken, ?LBRKT_INDENT(State), enc_list([{SigRequests, fun enc_SignalRequest/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_SignalRequest({'SignalRequest',Val}, State) -> enc_SignalRequest(Val, State); enc_SignalRequest({Tag, Val}, State) -> case Tag of signal -> enc_Signal(Val, State); seqSigList -> enc_SeqSigList(Val, State); _ -> error({invalid_SignalRequest_tag, Tag}) end. enc_SeqSigList(Val, State) when is_record(Val, 'SeqSigList') -> [ ?SignalListToken, ?EQUAL, enc_UINT16(Val#'SeqSigList'.id, State), ?LBRKT_INDENT(State), enc_list([{Val#'SeqSigList'.signalList, fun enc_Signal/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_Signal(#'Signal'{signalName = SN, streamID = SID, sigType = ST, duration = Du, notifyCompletion = NC, keepActive = KA, sigParList = SPL, direction = Di, requestID = RID, intersigDelay = ISD}, State) -> [ enc_SignalName(SN, State), enc_opt_brackets( enc_list([{[SID], fun enc_sigStream/2}, {[ST], fun enc_sigSignalType/2}, {[Du], fun enc_sigDuration/2}, {[NC], fun enc_notifyCompletion/2}, {[KA], fun enc_keepActive/2}, {SPL, fun enc_sigOther/2}, {[Di], fun enc_SignalDirection/2}, {[RID], fun enc_sigRequestID/2}, {[ISD], fun enc_sigIntsigDelay/2}], ?INC_INDENT(State)), State) ]. enc_sigStream(Val, State) -> [ ?StreamToken, ?EQUAL, enc_StreamID(Val, State) ]. enc_sigSignalType(Val, State) -> [ ?SignalTypeToken, ?EQUAL, enc_SignalType(Val, State) ]. enc_sigDuration(Val, State) -> [ ?DurationToken, ?EQUAL, enc_UINT16(Val, State) ]. enc_notifyCompletion(List, State) when is_list(List) -> [ ?NotifyCompletionToken, ?EQUAL, ?LBRKT_INDENT(State), enc_list([{List, fun enc_notifyCompletionItem/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_notifyCompletionItem(Val, _State) -> case Val of onTimeOut -> ?TimeOutToken; onInterruptByEvent -> ?InterruptByEventToken; onInterruptByNewSignalDescr -> ?InterruptByNewSignalsDescrToken; otherReason -> ?OtherReasonToken; onIteration -> ?IterationToken end. enc_SignalType({'SignalType',Val}, State) -> enc_SignalType(Val, State); enc_SignalType(Val, _State) -> case Val of brief -> ?BriefToken; onOff -> ?OnOffToken; timeOut -> ?TimeOutToken end. enc_SignalName({'SignalName',Val}, State)-> enc_SignalName(Val, State); enc_SignalName(Val, State) -> PkgdName = ?META_ENC(signal, Val), enc_PkgdName(PkgdName, State). enc_sigOther(Val, State) when is_record(Val, 'SigParameter') -> [ enc_Name(Val#'SigParameter'.sigParameterName, State), enc_propertyParmValues(Val#'SigParameter'.value, Val#'SigParameter'.extraInfo, State) ]. enc_SignalDirection({'SignalDirection', Val}, State) -> enc_SignalDirection(Val, State); enc_SignalDirection(Val, _State) -> [ ?DirectionToken, ?EQUAL, case Val of internal -> ?InternalToken; external -> ?ExternalToken; both -> ?BothToken end ]. enc_sigRequestID(Val, State) -> [ ?RequestIDToken, ?EQUAL, enc_RequestID(Val, State) ]. enc_RequestID({'RequestID',Val}, State) -> enc_RequestID(Val, State); enc_RequestID(Val, _State) when Val == ?megaco_all_request_id -> "*"; enc_RequestID(Val, State) -> enc_UINT32(Val, State). enc_sigIntsigDelay(Val, State) -> [ ?IntsigDelayToken, ?EQUAL, enc_UINT16(Val, State) ]. enc_ModemDescriptor(MD, _State) -> error({deprecated, MD}). %% Corr1: %% As of corr 1 ModemDescriptor has been deprecated. %% 7.1.2: ...shall not be included as part of a transmitted content and, %% if received, shall either be ignored or processed at the option %% of the implementation. ... %% enc_ModemDescriptor(#'ModemDescriptor'{mtl = [Val], %% mpl = [], %% nonStandardData = asn1_NOVALUE}, %% State) -> %% [ %% ?ModemToken, %% ?EQUAL, %% enc_ModemType(Val, State) %% ]; %% enc_ModemDescriptor(Val, State) %% when record(Val, 'ModemDescriptor') -> %% [ %% ?ModemToken, %% ?LSBRKT, %% enc_list([{Val#'ModemDescriptor'.mtl, fun enc_ModemType/2}], State), %% ?RSBRKT, %% enc_opt_brackets( %% enc_list([{Val#'ModemDescriptor'.mpl, fun enc_PropertyParm/2}], %% ?INC_INDENT(State)), %% State) %% %% BUGBUG: Is PropertyParm == NAME parmValue? %% ]. %% enc_ModemDescriptor(Val, State) %% when record(Val, 'ModemDescriptor') -> %% [ %% ?ModemToken, %% %% BUGBUG: Does never generate: EQUAL modemType %% ?LSBRKT, %% enc_list([{Val#'ModemDescriptor'.mtl, fun enc_ModemType/2}], State), %% ?RSBRKT, %% enc_opt_brackets( %% enc_list([{Val#'ModemDescriptor'.mpl, fun enc_PropertyParm/2}], %% ?INC_INDENT(State)), %% State) %% %% BUGBUG: Is PropertyParm == NAME parmValue? %% ]. %% Corr1: See ModemDescriptor above %% enc_ModemType({'ModemType',Val}, State)-> %% enc_ModemType(Val, State); %% enc_ModemType(Val, _State) -> %% %% BUGBUG: Does not handle extensionParameter %% case Val of %% v18 -> ?V18Token; %% v22 -> ?V22Token; %% v22bis -> ?V22bisToken; %% v32 -> ?V32Token; %% v32bis -> ?V32bisToken; %% v34 -> ?V34Token; %% v90 -> ?V90Token; %% v91 -> ?V91Token; %% synchISDN -> ?SynchISDNToken %% end. enc_DigitMapDescriptor(#'DigitMapDescriptor'{digitMapName = asn1_NOVALUE, digitMapValue = Value}, State) when (Value =/= asn1_NOVALUE) -> [ ?DigitMapToken, ?EQUAL, ?LBRKT_INDENT(State), enc_DigitMapValue(Value, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_DigitMapDescriptor(#'DigitMapDescriptor'{digitMapName = Name, digitMapValue = asn1_NOVALUE}, State) when (Name =/= asn1_NOVALUE) -> [ ?DigitMapToken, ?EQUAL, enc_DigitMapName(Name, State) ]; enc_DigitMapDescriptor(#'DigitMapDescriptor'{digitMapName = Name, digitMapValue = Value}, State) when (Name =/= asn1_NOVALUE) andalso (Value =/= asn1_NOVALUE) -> [ ?DigitMapToken, ?EQUAL, enc_DigitMapName(Name, State), ?LBRKT_INDENT(State), enc_DigitMapValue(Value, ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]; enc_DigitMapDescriptor(BadVal, _State) -> error({invalid_DigitMapDescriptor, BadVal}). enc_DigitMapName({'DigitMapName',Val}, State) -> enc_DigitMapName(Val, State); enc_DigitMapName(Val, State) -> enc_Name(Val, State). enc_DigitMapValue(Val, State) when is_record(Val, 'DigitMapValue') -> [ enc_timer(Val#'DigitMapValue'.startTimer, $T, State), enc_timer(Val#'DigitMapValue'.shortTimer, $S, State), enc_timer(Val#'DigitMapValue'.longTimer, $L, State), enc_timer(Val#'DigitMapValue'.durationTimer, $Z, State), %% BUGBUG: digitMapBody not handled at all enc_STRING(Val#'DigitMapValue'.digitMapBody, State, 0, infinity) ]. enc_timer(asn1_NOVALUE, _Prefix, _State) -> []; enc_timer(Timer, Prefix, State) -> [ Prefix, ?COLON, enc_DIGIT(Timer, State, 0, 99), ?COMMA_INDENT(State) ]. enc_ServiceChangeParm(Val, State) when is_record(Val, 'ServiceChangeParm') -> [ ?ServicesToken, ?LBRKT_INDENT(State), enc_list([{[Val#'ServiceChangeParm'.serviceChangeMethod], fun enc_ServiceChangeMethod/2}, {[Val#'ServiceChangeParm'.serviceChangeAddress], fun enc_ServiceChangeAddress/2}, {[Val#'ServiceChangeParm'.serviceChangeVersion], fun enc_serviceChangeVersion/2}, {[Val#'ServiceChangeParm'.serviceChangeProfile], fun enc_ServiceChangeProfile/2}, {[{reason, Val#'ServiceChangeParm'.serviceChangeReason}], fun enc_serviceChangeReason/2}, {[Val#'ServiceChangeParm'.serviceChangeDelay], fun enc_serviceChangeDelay/2}, {[Val#'ServiceChangeParm'.serviceChangeMgcId], fun enc_serviceChangeMgcId/2}, {[Val#'ServiceChangeParm'.timeStamp], fun enc_TimeNotation/2}, {Val#'ServiceChangeParm'.serviceChangeInfo, fun enc_AuditDescriptor/2}, {[Val#'ServiceChangeParm'.serviceChangeIncompleteFlag], fun('NULL', _) -> ?ServiceChangeIncompleteToken end}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_ServiceChangeMethod({'ServiceChangeMethod',Val}, State) -> enc_ServiceChangeMethod(Val, State); enc_ServiceChangeMethod(Val, _State) -> [ ?MethodToken, ?EQUAL, case Val of failover -> ?FailoverToken; forced -> ?ForcedToken; graceful -> ?GracefulToken; restart -> ?RestartToken; disconnected -> ?DisconnectedToken; handOff -> ?HandOffToken; _ -> error({invalid_ServiceChangeMethod, Val}) end ]. enc_ServiceChangeAddress({'ServiceChangeAddress',Val}, State) -> enc_ServiceChangeAddress(Val, State); enc_ServiceChangeAddress({Tag, Val}, State) -> [ ?ServiceChangeAddressToken, ?EQUAL, case Tag of portNumber -> enc_portNumber(Val, State); ip4Address -> enc_IP4Address(Val, State); ip6Address -> enc_IP6Address(Val, State); domainName -> enc_DomainName(Val, State); deviceName -> enc_PathName(Val, State); mtpAddress -> enc_mtpAddress(Val, State); _ -> error({invalid_ServiceChangeAddress_tag, Tag}) end ]. enc_serviceChangeVersion(Val, State) -> [ ?VersionToken, ?EQUAL, enc_version(Val, State) ]. enc_ServiceChangeProfile(#'ServiceChangeProfile'{profileName = Name, version = Version}, State) -> [ ?ProfileToken, ?EQUAL, enc_Name(Name, State), ?SLASH, enc_version(Version, State) ]. enc_serviceChangeReason({reason, Val}, State) -> case Val of asn1_NOVALUE -> []; [List] when is_list(List) -> [ ?ReasonToken, ?EQUAL, enc_QUOTED_STRING(List,State) % OTP-4632 enc_Value(List, State) ] end. enc_serviceChangeDelay(Val, State) -> [ ?DelayToken, ?EQUAL, enc_UINT32(Val, State) ]. enc_serviceChangeMgcId(Val, State) -> [ ?MgcIdToken, ?EQUAL, enc_MId(Val, State) ]. enc_portNumber(Val, State) when is_integer(Val) and (Val >= 0) -> enc_UINT16(Val, State). enc_ServiceChangeResParm(Val, State) when is_record(Val, 'ServiceChangeResParm') -> enc_list([{[Val#'ServiceChangeResParm'.serviceChangeAddress], fun enc_ServiceChangeAddress/2}, {[Val#'ServiceChangeResParm'.serviceChangeVersion], fun enc_serviceChangeVersion/2}, {[Val#'ServiceChangeResParm'.serviceChangeProfile], fun enc_ServiceChangeProfile/2}, {[Val#'ServiceChangeResParm'.serviceChangeMgcId], fun enc_serviceChangeMgcId/2}, {[Val#'ServiceChangeResParm'.timeStamp], fun enc_TimeNotation/2}], State). enc_PackagesDescriptor({'PackagesDescriptor',Val}, State) -> enc_PackagesDescriptor(Val, State); enc_PackagesDescriptor(Val, State) -> [ ?PackagesToken, ?LBRKT_INDENT(State), enc_list([{Val, fun enc_PackagesItem/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_PackagesItem(Val, State) when is_record(Val, 'PackagesItem') -> PkgdName = ?META_ENC(package, Val#'PackagesItem'.packageName), [ enc_Name(PkgdName, State), "-", enc_UINT16(Val#'PackagesItem'.packageVersion, State) ]. enc_StatisticsDescriptor({'StatisticsDescriptor',Val}, State) -> enc_StatisticsDescriptor(Val, State); enc_StatisticsDescriptor(List, State) when is_list(List) -> [ ?StatsToken, ?LBRKT_INDENT(State), enc_list([{List, fun enc_StatisticsParameter/2}], ?INC_INDENT(State)), ?RBRKT_INDENT(State) ]. enc_StatisticsParameter(Val, State) when is_record(Val, 'StatisticsParameter') -> PkgdName = ?META_ENC(statistics, Val#'StatisticsParameter'.statName), case Val#'StatisticsParameter'.statValue of asn1_NOVALUE -> [ enc_PkgdName(PkgdName, State) ]; [StatVal] when is_list(StatVal) -> [ enc_PkgdName(PkgdName, State), ?EQUAL, enc_Value(StatVal, State) ] end. enc_TimeNotation(Val, State) when is_record(Val, 'TimeNotation') -> [ enc_STRING(Val#'TimeNotation'.date, State, 8, 8), % "yyyymmdd" "T", enc_STRING(Val#'TimeNotation'.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. enc_Value({'Value',Val}, State) -> enc_Value(Val, State); enc_Value(String, _State) -> case quoted_string_count(String, 0, true, false) of {_, 0, _} -> [?DQUOTE, String, ?DQUOTE]; {false, _, _} -> [?DQUOTE, String, ?DQUOTE]; {true, _, _} -> [String] end. quoted_string_count([?DoubleQuoteToken | T], 0 = Count, _IsSafe, _MaybeQuoted) -> %% Already a quoted string. Make sure it ends quoted_string_count(T, Count + 1, true, true); quoted_string_count([?DoubleQuoteToken], Count, IsSafe, true = MaybeQuoted) -> %% An explicitly quoted string {IsSafe, Count, MaybeQuoted}; quoted_string_count([H | T], Count, IsSafe, MaybeQuoted) -> case ?classify_char(H) of safe_char_upper -> quoted_string_count(T, Count + 1, IsSafe, MaybeQuoted); safe_char -> quoted_string_count(T, Count + 1, IsSafe, MaybeQuoted); rest_char -> quoted_string_count(T, Count + 1, false, MaybeQuoted); white_space -> quoted_string_count(T, Count + 1, false, MaybeQuoted); _ -> error({illegal_char, H}) end; quoted_string_count([], _Count, _IsSafe, true = _MaybeQuoted) -> error({illegal_char, ?DoubleQuoteToken}); quoted_string_count([], Count, IsSafe, MaybeQuoted) -> {IsSafe, Count, MaybeQuoted}. enc_DigitString(String, _State) when is_list(String) -> [?DQUOTE, String, ?DQUOTE]. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Encode an octet string, escape } by \ if necessary enc_OCTET_STRING(List, State, Min, Max) -> do_enc_OCTET_STRING(List, State, Min, Max, 0). do_enc_OCTET_STRING([H | T], State, Min, Max, Count) -> case H of $} -> [$\\, H | do_enc_OCTET_STRING(T, State, Min, Max, Count + 1)]; _ -> [H | do_enc_OCTET_STRING(T, State, Min, Max, Count + 1)] end; do_enc_OCTET_STRING([], _State, Min, Max, Count) -> verify_count(Count, Min, Max), []. enc_QUOTED_STRING(String, _State) when is_list(String) -> case quoted_string_count(String, 0, true, false) of {_IsSafe, Count, false = _QuotedString} -> verify_count(Count, 1, infinity), [?DQUOTE, String, ?DQUOTE]; {_IsSafe, Count, true = _QuotedString} -> verify_count(Count, 3, infinity), % quotes not included in the count [String] end. %% 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 enc_HEXDIG(Octets, State, Min, Max) when is_list(Octets) -> do_enc_HEXDIG(Octets, State, Min, Max, 0, []). do_enc_HEXDIG([Octet | Rest], State, Min, Max, Count, Acc) when (Octet >= 0) and (Octet =< 255) -> Hex = hex(Octet), % OTP-4921 if Octet =< 15 -> Acc2 = [[$0|Hex]|Acc], % OTP-4921 do_enc_HEXDIG(Rest, State, Min, Max, Count + 2, ["0" | Acc2]); true -> Acc2 = [Hex|Acc], % OTP-4921 do_enc_HEXDIG(Rest, State, Min, Max, Count + 2, Acc2) end; do_enc_HEXDIG([], State, Min, Max, Count, Acc) when is_integer(Min) and (Count < Min) -> do_enc_HEXDIG([0], State, Min, Max, Count, Acc); do_enc_HEXDIG([], _State, Min, Max, Count, Acc) -> %% OTP-4710 verify_count(Count, Min, Max), lists:reverse(Acc). enc_DIGIT(Val, State, Min, Max) -> enc_integer(Val, State, Min, Max). enc_STRING(String, _State, Min, Max) when is_list(String) -> verify_count(length(String), Min, Max), String. enc_UINT16(Val, State) -> enc_integer(Val, State, 0, 65535). enc_UINT32(Val, State) -> enc_integer(Val, State, 0, 4294967295). enc_integer(Val, _State, Min, Max) -> verify_count(Val, Min, Max), integer_to_list(Val). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Encodes a list of elements with separator tokens between %% the elements. Optional asn1_NOVALUE values are ignored. enc_list(List, State) -> enc_list(List, State, fun(_S) -> ?COMMA_INDENT(_S) end, false). enc_list([], _State, _SepEncoder, _NeedsSep) -> []; enc_list([{Elems, ElemEncoder} | Tail], State, SepEncoder, NeedsSep) -> case do_enc_list(Elems, State, ElemEncoder, SepEncoder, NeedsSep) of [] -> enc_list(Tail, State, SepEncoder, NeedsSep); List -> [List, enc_list(Tail, State, SepEncoder, true)] end; enc_list(A, B, C, D) -> error({invalid_list, A, B, C, D}). do_enc_list(asn1_NOVALUE, _State, _ElemEncoder, _SepEncoder, _NeedsSep) -> []; do_enc_list([], _State, _ElemEncoder, _SepEncoder, _NeedsSep) -> []; do_enc_list([asn1_NOVALUE | T], State, ElemEncoder, SepEncoder, NeedsSep) -> do_enc_list(T, State, ElemEncoder, SepEncoder, NeedsSep); do_enc_list([H | T], State, ElemEncoder, SepEncoder, NeedsSep) when is_function(ElemEncoder) and is_function(SepEncoder) -> case ElemEncoder(H, State) of [] -> do_enc_list(T, State, ElemEncoder, SepEncoder, NeedsSep); List when NeedsSep == true -> [SepEncoder(State), List, do_enc_list(T, State, ElemEncoder, SepEncoder, true)]; List when NeedsSep == false -> [List, do_enc_list(T, State, ElemEncoder, SepEncoder, true)] end. %% Add brackets if list is non-empty enc_opt_brackets([], _State) -> []; enc_opt_brackets(List, _State) when is_list(List) -> [?LBRKT_INDENT(_State), List, ?RBRKT_INDENT(_State)]. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Int -> list of hex chars hex(Int) -> hexi(get_lo_bits(Int, 4), []). hexi({0, Lo}, Ack) -> [hex4(Lo) | Ack]; hexi({Hi, Lo} , Ack) -> hexi(get_lo_bits(Hi, 4), [hex4(Lo) | Ack]). hex4(Int) when Int < 10 -> Int + $0; hex4(Int) -> ($A - 10) + Int. get_lo_bits(Int, Size) -> Lo = Int band ones_mask(Size), Hi = Int bsr Size, {Hi, Lo}. ones_mask(Ones) -> (1 bsl Ones) - 1. %% 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. %% ------------------------------------------------------------------- %% d(F) -> %% d(F,[]). %% d(F, A) -> %% d(get(dbg), F, A). %% d(true, F, A) -> %% io:format("~p:" ++ F ++"~n", [?MODULE | A]); %% d(_, _, _) -> %% ok.