📄 megaco_text_parser_v3.hrl
字号:
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %% $Id$%%%%----------------------------------------------------------------------%% Purpose : Define semantic text parser actions%%-----------------------------------------------------------------------include_lib("megaco/include/megaco.hrl").-include_lib("megaco/include/megaco_message_prev3a.hrl").-include("megaco_text_tokens.hrl").make_safe_token({_TokenTag, Line, Text}) -> {safeToken, Line, Text}.ensure_value({safeToken, _Line, Text}) -> ensure_value(Text);ensure_value({'QuotedChars', _Line, Text}) -> ensure_value(Text);ensure_value(Text) when list(Text) -> Text. %% BUGBUG: ensure length%% NAME = ALPHA *63(ALPHA / DIGIT / "_" )ensure_NAME({_TokenTag, _Line, Text}) -> Text. %% BUGBUG: ensure length and charsensure_requestID({safeToken, _Line, "*"}) -> ?megaco_all_request_id;ensure_requestID(RequestId) -> ensure_uint32(RequestId).ensure_streamID(StreamId) -> ensure_uint16(StreamId).ensure_auth_header(SpiToken, SnToken, AdToken) -> Spi = ensure_hex(SpiToken, 8, 8), Sn = ensure_hex(SnToken, 8, 8), Ad = ensure_hex(AdToken, 24, 64), #'AuthenticationHeader'{secParmIndex = Spi, seqNum = Sn, ad = Ad}.%% ContextID = (UINT32 / "*" / "-" / "$")ensure_contextID({_TokenTag, _Line, Text}) -> case Text of "*" -> ?megaco_all_context_id; "-" -> ?megaco_null_context_id; "\$" -> ?megaco_choose_context_id; Int -> ensure_uint32(Int) end.ensure_domainAddress([{_T, _L, _A} = Addr0], Port) -> Addr = ensure_ip4addr(Addr0), {ip4Address, #'IP4Address'{address = Addr, portNumber = Port}};ensure_domainAddress([colon,colon], Port) -> Addr = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], {ip6Address, #'IP6Address'{address = Addr, portNumber = Port}};ensure_domainAddress(Addr0, Port) -> Addr = ensure_ip6addr(Addr0), {ip6Address, #'IP6Address'{address = Addr, portNumber = Port}}.ensure_ip4addr({TokenTag, Line, Addr}) -> case string:tokens(Addr, [$.]) of [T1, T2, T3, T4] -> A1 = ensure_uint({TokenTag, Line, T1}, 0, 255), A2 = ensure_uint({TokenTag, Line, T2}, 0, 255), A3 = ensure_uint({TokenTag, Line, T3}, 0, 255), A4 = ensure_uint({TokenTag, Line, T4}, 0, 255), [A1, A2, A3, A4]; _ -> return_error(Line, {bad_IP4address, Addr}) end.ensure_ip6addr([colon,colon|T]) -> [H1|T1] = lists:reverse(T), case do_ensure_ip6addr(T1, true, [ensure_hex4_or_ip4addr(H1)], 1) of {true, A} when length(A) == 16 -> A; {true, B} when length(B) < 16 -> lists:duplicate(16 - length(B), 0) ++ B; {true, C} -> throw({error, {?MODULE, {bad_mid_ip6addr_length, C}}}) end;ensure_ip6addr(L) -> case lists:reverse(L) of [colon, colon| T] -> case do_ensure_ip6addr(T, true, [], 1) of {true, A} when length(A) == 16 -> A; {true, B} when length(B) < 16 -> B ++ lists:duplicate(16 - length(B), 0); {true, C} -> throw({error, {?MODULE, {bad_mid_ip6addr_length, C}}}) end; [H|L1] -> % A (last element) could be an ip4 address case do_ensure_ip6addr(L1,false,[ensure_hex4_or_ip4addr(H)],1) of {false, A} when length(A) == 16 -> A; %% allow a pad even if the address is full (i.e. 16) {true, B} when length(B) =< 17 -> do_ensure_ip6addr_padding(B, 0); {Pad, C} -> throw({error, {?MODULE, {bad_mid_ip6addr_length, Pad, C}}}) end end.do_ensure_ip6addr([], Pad, Acc, _) -> {Pad, lists:flatten(Acc)};do_ensure_ip6addr([colon,colon|T], false, Acc, Line) -> do_ensure_ip6addr(T, true, [pad|Acc], Line);do_ensure_ip6addr([colon,colon|T], true, Acc, Line) -> return_error(Line, {bad_mid_duplicate_padding, T, Acc});do_ensure_ip6addr([colon|T], Pad, Acc, Line) -> do_ensure_ip6addr(T, Pad, Acc, Line);do_ensure_ip6addr([{_, Line, _} = A|T], Pad, Acc, _) -> do_ensure_ip6addr(T, Pad, [ensure_hex4(A)|Acc], Line).do_ensure_ip6addr_padding([], _) -> [];do_ensure_ip6addr_padding([pad|T], N) -> lists:duplicate(16 - (N + length(T)), 0) ++ T;do_ensure_ip6addr_padding([H|T], N) -> [H|do_ensure_ip6addr_padding(T, N+1)].ensure_hex4_or_ip4addr({TokenTag, Line, Addr} = V) -> case string:tokens(Addr, [$.]) of [T1, T2, T3, T4] -> A1 = ensure_uint({TokenTag, Line, T1}, 0, 255), A2 = ensure_uint({TokenTag, Line, T2}, 0, 255), A3 = ensure_uint({TokenTag, Line, T3}, 0, 255), A4 = ensure_uint({TokenTag, Line, T4}, 0, 255), [A1, A2, A3, A4]; _ -> ensure_hex4(V) %% %% BMK BMK BMK %% %% Here we should test for hexseq %% return_error(Line, {bad_IP4address, Addr}) end.ensure_hex4({_TokenTag, Line, Hex4}) when length(Hex4) =< 4, length(Hex4) > 0 -> case (catch do_ensure_hex4(Hex4)) of IL when list(IL), length(IL) == 2 -> IL; Error -> return_error(Line, {bad_hex4, Hex4, Error}) end.do_ensure_hex4([_H1, _H2, _H3, _H4] = H) -> hex_to_int(H, []);do_ensure_hex4([H2, H3, H4]) -> hex_to_int([$0, H2, H3, H4], []);do_ensure_hex4([H3, H4]) -> hex_to_int([$0, $0, H3, H4], []);do_ensure_hex4([H4]) -> hex_to_int([$0, $0, $0, H4], []).ensure_domainName({_TokenTag, _Line, Name}, Port) -> %% BUGBUG: validate name {domainName, #'DomainName'{name = Name, portNumber = Port}}.%% extensionParameter= "X" ("-" / "+") 1*6(ALPHA / DIGIT)ensure_extensionParameter({_TokenTag, Line, Text}) -> case Text of [X, S | _Chars] -> if X /= $X, X /= $x, S /= $+, S /= $- -> return_error(Line, {bad_extension_parameter, Text}); true -> {extension_parameter, Text} end; _ -> return_error(Line, {bad_extension_parameter, Text}) end.ensure_message(MegacopToken, MID, Body) -> #'ServiceChangeProfile'{profileName = Name, version = Version} = ensure_profile(MegacopToken), case Name of "megaco" -> #'Message'{version = Version, mId = MID, messageBody = Body}; [$!] -> #'Message'{version = Version, mId = MID, messageBody = Body} end.%% Corr1:%% As of corr 1 ModemDescriptor has been deprecated.%% and since this functon is only used when creating%% a ModemDescriptor, iit is removed.%% modemType = (V32bisToken / V22bisToken / V18Token / %% V22Token / V32Token / V34Token / V90Token / %% V91Token / SynchISDNToken / extensionParameter)%% ensure_modemType({_TokenTag, _Line, Text} = Token) ->%% case Text of%% "v32b" -> v32bis;%% "v22b" -> v22bis;%% "v18" -> v18;%% "v22" -> v22;%% "v32" -> v32;%% "v34" -> v34;%% "v90" -> v90;%% "v91" -> v91;%% "synchisdn" -> synchISDN;%% "sn" -> synchISDN;%% [$x | _] -> ensure_extensionParameter(Token)%% end.%% An mtp address is five octets longensure_mtpAddress({_TokenTag, _Line, Addr}) -> %% BUGBUG: validate address {mtpAddress, Addr}.%% MuxType = ( H221Token / H223Token / H226Token / V76Token / extensionParameter )ensure_muxType({_TokenTag, _Line, Text} = Token) -> case Text of "h221" -> h221; "h223" -> h223; "h226" -> h226; "v76" -> v76; "nx64k" -> nx64k; % v2 [$x | _] -> ensure_extensionParameter(Token) end.%% packagesItem = NAME "-" UINT16%% NAME = ALPHA *63(ALPHA / DIGIT / "_" )ensure_packagesItem({TokenTag, Line, Text}) -> case string:tokens(Text, [$-]) of [Name, Version] -> #'PackagesItem'{packageName = ensure_NAME({TokenTag, Line, Name}), packageVersion = ensure_uint({TokenTag, Line, Version}, 0, 99)}; _ -> return_error(Line, {bad_PackagesItem, Text}) end.%% pkgdName = (PackageName / "*") SLASH (ItemID / "*" )%% PackageName = NAME%% ItemID = NAMEensure_pkgdName({TokenTag, Line, Text}) -> case string:tokens(Text, [$/]) of [Name, Item] -> ensure_name_or_star({TokenTag, Line, Name}), ensure_name_or_star({TokenTag, Line, Item}), Text; _ -> return_error(Line, {bad_pkgdName, Text}) end.ensure_name_or_star({_, _, Name}) when Name == "*" -> Name;ensure_name_or_star(Name) -> ensure_NAME(Name).%% v2 - startmerge_indAudMediaDescriptor({termStateDescr, Val}) -> #'IndAudMediaDescriptor'{termStateDescr = Val};merge_indAudMediaDescriptor({streamParm, Val}) -> #'IndAudMediaDescriptor'{streams = {oneStream, Val}};merge_indAudMediaDescriptor({streamDescr, Val}) -> #'IndAudMediaDescriptor'{streams = {multiStream, [Val]}}.merge_indAudLocalControlDescriptor(Parms) -> do_merge_indAudLocalControlDescriptor(Parms, #'IndAudLocalControlDescriptor'{}). do_merge_indAudLocalControlDescriptor([Parm | Parms], Desc) -> case Parm of modeToken when Desc#'IndAudLocalControlDescriptor'.streamMode == asn1_NOVALUE -> Desc2 = Desc#'IndAudLocalControlDescriptor'{streamMode = 'NULL'}, do_merge_indAudLocalControlDescriptor(Parms, Desc2); reservedGroupToken when Desc#'IndAudLocalControlDescriptor'.reserveGroup == asn1_NOVALUE -> Desc2 = Desc#'IndAudLocalControlDescriptor'{reserveGroup = 'NULL'}, do_merge_indAudLocalControlDescriptor(Parms, Desc2); reservedValueToken when Desc#'IndAudLocalControlDescriptor'.reserveValue == asn1_NOVALUE -> Desc2 = Desc#'IndAudLocalControlDescriptor'{reserveValue = 'NULL'}, do_merge_indAudLocalControlDescriptor(Parms, Desc2); {pkgdName, Val} when Desc#'IndAudLocalControlDescriptor'.propertyParms == asn1_NOVALUE -> PropParms = [#'IndAudPropertyParm'{name = Val}], Desc2 = Desc#'IndAudLocalControlDescriptor'{propertyParms = PropParms}, do_merge_indAudLocalControlDescriptor(Parms, Desc2); {pkgdName, Val} when list(Desc#'IndAudLocalControlDescriptor'.propertyParms) -> PropParms = Desc#'IndAudLocalControlDescriptor'.propertyParms, PropParms2 = [#'IndAudPropertyParm'{name = Val} | PropParms], Desc2 = Desc#'IndAudLocalControlDescriptor'{propertyParms = PropParms2}, do_merge_indAudLocalControlDescriptor(Parms, Desc2) end;do_merge_indAudLocalControlDescriptor([], Desc) -> case Desc#'IndAudLocalControlDescriptor'.propertyParms of [_ | _] = PropParms -> % List has more then one element PropParms2= lists:reverse(PropParms), Desc#'IndAudLocalControlDescriptor'{propertyParms = PropParms2}; _ -> Desc end.ensure_indAudLocalParm(Token) -> case Token of {safeToken, _Line, "mode"} -> modeToken; {safeToken, _Line, "mo"} -> modeToken; {safeToken, _Line, "reservedgroup"} -> reservedGroupToken; {safeToken, _Line, "rg"} -> reservedGroupToken; {safeToken, _Line, "reservedvalue"} -> reservedValueToken; {safeToken, _Line, "rv"} -> reservedValueToken; PkgdName -> {pkgdName, ensure_pkgdName(PkgdName)} end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -