aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/diameter/doc/src/diameter.xml4
-rw-r--r--lib/diameter/src/base/diameter_gen.erl45
-rw-r--r--lib/diameter/src/base/diameter_traffic.erl4
-rw-r--r--lib/diameter/test/diameter_traffic_SUITE.erl5
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,