diff options
-rw-r--r-- | lib/diameter/doc/src/diameter.xml | 4 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_gen.erl | 45 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_traffic.erl | 4 | ||||
-rw-r--r-- | lib/diameter/test/diameter_traffic_SUITE.erl | 5 |
4 files changed, 36 insertions, 22 deletions
diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml index b7be184058..c31929c3f0 100644 --- a/lib/diameter/doc/src/diameter.xml +++ b/lib/diameter/doc/src/diameter.xml @@ -810,8 +810,8 @@ dictionary file in question. If <c>list</c> or <c>map</c> then a <c>[Name | Avps]</c> pair where <c>Avps</c> is either a list of AVP name/values pairs or a map keyed on AVP names respectively. -If <c>false</c> then the representation is omitted and <c>msg</c> and -<c>value</c> fields are set to <c>false</c>. +If <c>false</c> then the representation is as the atom-value message +name, or <c>undefined</c> for a Grouped AVP. See also &codec_message;.</p> <p> diff --git a/lib/diameter/src/base/diameter_gen.erl b/lib/diameter/src/base/diameter_gen.erl index 763f70d877..e8f637dd53 100644 --- a/lib/diameter/src/base/diameter_gen.erl +++ b/lib/diameter/src/base/diameter_gen.erl @@ -230,7 +230,7 @@ enc(AvpName, Value, Opts, Mod) -> %% --------------------------------------------------------------------------- -spec decode_avps(parent_name(), binary(), map()) - -> {parent_record() | false, [avp()], Failed} + -> {parent_record() | parent_name(), [avp()], Failed} when Failed :: [{5000..5999, #diameter_avp{}}]. decode_avps(Name, Bin, #{module := Mod, decode_format := Fmt} = Opts) -> @@ -301,7 +301,7 @@ decode(Bin, Code, Vid, DataLen, Pad, M, P, Name, Mod, Fmt, Strict, Opts0, type = type(NameT), index = Idx}, - Dec = decode(Data, Name, NameT, Mod, Opts, Avp), %% decode + Dec = decode1(Data, Name, NameT, Mod, Fmt, Opts, Avp), Acc = decode(T, Name, Mod, Fmt, Strict, Opts, Idx+1, AM),%% recurse acc(Acc, Dec, I, Name, Field, Arity, Strict, Mod, Opts); _ -> @@ -449,10 +449,10 @@ field({AvpName, _}) -> field(_) -> 'AVP'. -%% decode/6 +%% decode1/7 %% AVP not in dictionary. -decode(_Data, _Name, 'AVP', _Mod, _Opts, Avp) -> +decode1(_Data, _Name, 'AVP', _Mod, _Fmt, _Opts, Avp) -> Avp; %% 6733, 4.4: @@ -502,7 +502,7 @@ decode(_Data, _Name, 'AVP', _Mod, _Opts, Avp) -> %% defined the RFC's "unrecognized", which is slightly stronger than %% "not defined".) -decode(Data, Name, {AvpName, Type}, Mod, Opts, Avp) -> +decode1(Data, Name, {AvpName, Type}, Mod, Fmt, Opts, Avp) -> #{dictionary := AppMod, failed_avp := Failed} = Opts, @@ -516,26 +516,39 @@ decode(Data, Name, {AvpName, Type}, Mod, Opts, Avp) -> %% list of component AVPs. try avp_decode(Data, AvpName, Opts, DecMod, Mod) of - {Rec, As} when Type == 'Grouped' -> - A = Avp#diameter_avp{value = Rec}, - [A | As]; - V when Type /= 'Grouped' -> - Avp#diameter_avp{value = V} + V -> + set(Type, Fmt, Avp, V) catch throw: {?MODULE, T} -> - decode_error(Failed, T, Avp); + decode_error(Failed, Fmt, T, Avp); error: Reason -> decode_error(Failed, Reason, Name, Mod, Opts, Avp) end. -%% decode_error/3 +%% set/4 + +set('Grouped', false, Avp, V) -> + {_Rec, As} = V, + [Avp | As]; + +set('Grouped', _, Avp, V) -> + {Rec, As} = V, + [Avp#diameter_avp{value = Rec} | As]; + +set(_, _, Avp, V) -> + Avp#diameter_avp{value = V}. + +%% decode_error/4 %% %% Error when decoding a grouped AVP. -decode_error(true, {Rec, _, _}, Avp) -> +decode_error(true, false, _, Avp) -> + Avp; + +decode_error(true, _, {Rec, _, _}, Avp) -> Avp#diameter_avp{value = Rec}; -decode_error(false, {_, ComponentAvps, [{RC,A} | _]}, Avp) -> +decode_error(false, _, {_, ComponentAvps, [{RC,A} | _]}, Avp) -> {RC, [Avp | ComponentAvps], Avp#diameter_avp{data = [A]}}. %% decode_error/6 @@ -817,8 +830,8 @@ empty(Name, #{module := Mod} = Opts) -> %% newrec/4 -newrec(false = No, _, _, _) -> - No; +newrec(false, _, Name, _) -> + Name; newrec(record, Mod, Name, T) when T /= decode -> diff --git a/lib/diameter/src/base/diameter_traffic.erl b/lib/diameter/src/base/diameter_traffic.erl index 5ee598f513..3cc1c7cce5 100644 --- a/lib/diameter/src/base/diameter_traffic.erl +++ b/lib/diameter/src/base/diameter_traffic.erl @@ -1992,10 +1992,10 @@ avp_decode(Dict, 'Experimental-Result' = N, #diameter_avp{data = Bin} {V,_} = Dict:avp(decode, Bin, N, decode_opts(Dict)), Avp#diameter_avp{name = N, value = V}; -avp_decode(Dict, Name, #diameter_avp{value = X, +avp_decode(Dict, Name, #diameter_avp{value = undefined, data = Bin} = Avp) - when is_binary(Bin), X == undefined orelse X == false -> + when is_binary(Bin) -> V = Dict:avp(decode, Bin, Name, decode_opts(Dict)), Avp#diameter_avp{name = Name, value = V}; diff --git a/lib/diameter/test/diameter_traffic_SUITE.erl b/lib/diameter/test/diameter_traffic_SUITE.erl index 2bc00bf4a1..403d417636 100644 --- a/lib/diameter/test/diameter_traffic_SUITE.erl +++ b/lib/diameter/test/diameter_traffic_SUITE.erl @@ -1161,7 +1161,7 @@ to_map(#diameter_packet{header = H, msg = Rec}, %% No record decode: do it ourselves. to_map(#diameter_packet{header = H, - msg = false, + msg = Name, bin = Bin}, #group{server_decoding = false, strings = B}) -> @@ -1169,8 +1169,9 @@ to_map(#diameter_packet{header = H, string_decode => B, strict_mbit => true, rfc => 6733}, - #diameter_packet{msg = [_MsgName | _Map] = Msg} + #diameter_packet{msg = [MsgName | _Map] = Msg} = diameter_codec:decode(dict(H), Opts, Bin), + {MsgName, _} = {Name, Msg}, %% assert Msg. dict(#diameter_header{application_id = Id, |