From 30e814dd4bf414314ff611452362582419f3f05d Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Tue, 24 May 2016 22:20:58 +0200 Subject: XEP-0198: Add 'h' attribute to element If a resume request is rejected because the session timed out, indicate the number of handled stanzas as per version 1.5 of XEP-0198. --- tools/xmpp_codec.erl | 45 ++++++++++++++++++++++++++++++++------------- tools/xmpp_codec.hrl | 1 + tools/xmpp_codec.spec | 7 +++++-- 3 files changed, 38 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/xmpp_codec.erl b/tools/xmpp_codec.erl index 52950feac..ef1421962 100644 --- a/tools/xmpp_codec.erl +++ b/tools/xmpp_codec.erl @@ -2174,7 +2174,7 @@ encode({sm_resumed, _, _, _} = Resumed) -> encode_sm_resumed(Resumed, []); encode({sm_r, _} = R) -> encode_sm_r(R, []); encode({sm_a, _, _} = A) -> encode_sm_a(A, []); -encode({sm_failed, _, _} = Failed) -> +encode({sm_failed, _, _, _} = Failed) -> encode_sm_failed(Failed, []); encode({offline_item, _, _} = Item) -> encode_offline_item(Item, @@ -2597,7 +2597,7 @@ pp(sm_resume, 3) -> [h, previd, xmlns]; pp(sm_resumed, 3) -> [h, previd, xmlns]; pp(sm_r, 1) -> [xmlns]; pp(sm_a, 2) -> [h, xmlns]; -pp(sm_failed, 2) -> [reason, xmlns]; +pp(sm_failed, 3) -> [reason, h, xmlns]; pp(offline_item, 2) -> [node, action]; pp(offline, 3) -> [items, purge, fetch]; pp(mix_join, 2) -> [jid, subscribe]; @@ -2963,9 +2963,9 @@ decode_sm_failed(__TopXMLNS, __IgnoreEls, {xmlel, <<"failed">>, _attrs, _els}) -> Reason = decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, undefined), - Xmlns = decode_sm_failed_attrs(__TopXMLNS, _attrs, - undefined), - {sm_failed, Reason, Xmlns}. + {H, Xmlns} = decode_sm_failed_attrs(__TopXMLNS, _attrs, + undefined, undefined), + {sm_failed, Reason, H, Xmlns}. decode_sm_failed_els(__TopXMLNS, __IgnoreEls, [], Reason) -> @@ -3285,20 +3285,25 @@ decode_sm_failed_els(__TopXMLNS, __IgnoreEls, Reason). decode_sm_failed_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], _Xmlns) -> - decode_sm_failed_attrs(__TopXMLNS, _attrs, _val); -decode_sm_failed_attrs(__TopXMLNS, [_ | _attrs], + [{<<"h">>, _val} | _attrs], _H, Xmlns) -> + decode_sm_failed_attrs(__TopXMLNS, _attrs, _val, Xmlns); +decode_sm_failed_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], H, _Xmlns) -> + decode_sm_failed_attrs(__TopXMLNS, _attrs, H, _val); +decode_sm_failed_attrs(__TopXMLNS, [_ | _attrs], H, Xmlns) -> - decode_sm_failed_attrs(__TopXMLNS, _attrs, Xmlns); -decode_sm_failed_attrs(__TopXMLNS, [], Xmlns) -> - decode_sm_failed_attr_xmlns(__TopXMLNS, Xmlns). + decode_sm_failed_attrs(__TopXMLNS, _attrs, H, Xmlns); +decode_sm_failed_attrs(__TopXMLNS, [], H, Xmlns) -> + {decode_sm_failed_attr_h(__TopXMLNS, H), + decode_sm_failed_attr_xmlns(__TopXMLNS, Xmlns)}. -encode_sm_failed({sm_failed, Reason, Xmlns}, +encode_sm_failed({sm_failed, Reason, H, Xmlns}, _xmlns_attrs) -> _els = lists:reverse('encode_sm_failed_$reason'(Reason, [])), _attrs = encode_sm_failed_attr_xmlns(Xmlns, - _xmlns_attrs), + encode_sm_failed_attr_h(H, + _xmlns_attrs)), {xmlel, <<"failed">>, _attrs, _els}. 'encode_sm_failed_$reason'(undefined, _acc) -> _acc; @@ -3443,6 +3448,20 @@ encode_sm_failed({sm_failed, Reason, Xmlns}, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) | _acc]. +decode_sm_failed_attr_h(__TopXMLNS, undefined) -> + undefined; +decode_sm_failed_attr_h(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"h">>, <<"failed">>, __TopXMLNS}}); + _res -> _res + end. + +encode_sm_failed_attr_h(undefined, _acc) -> _acc; +encode_sm_failed_attr_h(_val, _acc) -> + [{<<"h">>, enc_int(_val)} | _acc]. + decode_sm_failed_attr_xmlns(__TopXMLNS, undefined) -> undefined; decode_sm_failed_attr_xmlns(__TopXMLNS, _val) -> _val. diff --git a/tools/xmpp_codec.hrl b/tools/xmpp_codec.hrl index b2773a6c1..6d4b750b6 100644 --- a/tools/xmpp_codec.hrl +++ b/tools/xmpp_codec.hrl @@ -440,6 +440,7 @@ -record(sasl_mechanisms, {list = [] :: [binary()]}). -record(sm_failed, {reason :: atom() | #gone{} | #redirect{}, + h :: non_neg_integer(), xmlns :: binary()}). -record(error, {type :: 'auth' | 'cancel' | 'continue' | 'modify' | 'wait', diff --git a/tools/xmpp_codec.spec b/tools/xmpp_codec.spec index 536a11dfb..acf9c3bb7 100644 --- a/tools/xmpp_codec.spec +++ b/tools/xmpp_codec.spec @@ -2351,8 +2351,11 @@ -xml(sm_failed, #elem{name = <<"failed">>, xmlns = [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], - result = {sm_failed, '$reason', '$xmlns'}, - attrs = [#attr{name = <<"xmlns">>}], + result = {sm_failed, '$reason', '$h', '$xmlns'}, + attrs = [#attr{name = <<"h">>, + dec = {dec_int, [0, infinity]}, + enc = {enc_int, []}}, + #attr{name = <<"xmlns">>}], refs = [#ref{name = error_bad_request, min = 0, max = 1, label = '$reason'}, #ref{name = error_conflict, -- cgit v1.2.3