82 last_ack = new_ack; |
82 last_ack = new_ack; |
83 elseif new_ack < last_ack then |
83 elseif new_ack < last_ack then |
84 stream:warn("Received bad ack for "..new_ack.." when last ack was "..last_ack); |
84 stream:warn("Received bad ack for "..new_ack.." when last ack was "..last_ack); |
85 end |
85 end |
86 elseif stanza.name == "enabled" then |
86 elseif stanza.name == "enabled" then |
|
87 stream.pre_smacks_features = nil; |
87 |
88 |
88 if stanza.attr.id then |
89 if stanza.attr.id then |
89 stream.resumption_token = stanza.attr.id; |
90 stream.resumption_token = stanza.attr.id; |
90 stream:hook("closed", on_close, 100); |
91 stream:hook("closed", on_close, 100); |
91 stream:hook("disconnected", on_disconnect, 100); |
92 stream:hook("disconnected", on_disconnect, 100); |
92 end |
93 end |
93 elseif stanza.name == "resumed" then |
94 elseif stanza.name == "resumed" then |
|
95 stream.pre_smacks_features = nil; |
94 local new_ack = tonumber(stanza.attr.h); |
96 local new_ack = tonumber(stanza.attr.h); |
95 if new_ack > last_ack then |
97 if new_ack > last_ack then |
96 local old_unacked = #outgoing_queue; |
98 local old_unacked = #outgoing_queue; |
97 for i=last_ack+1,new_ack do |
99 for i=last_ack+1,new_ack do |
98 table.remove(outgoing_queue, 1); |
100 table.remove(outgoing_queue, 1); |
104 stream:send(outgoing_queue[i]); |
106 stream:send(outgoing_queue[i]); |
105 end |
107 end |
106 outgoing_queue = {}; |
108 outgoing_queue = {}; |
107 stream:debug("Resumed successfully"); |
109 stream:debug("Resumed successfully"); |
108 stream:event("resumed"); |
110 stream:event("resumed"); |
|
111 elseif stanza.name == "failed" then |
|
112 stream.bound = nil |
|
113 stream.smacks = nil |
|
114 last_ack = 0 |
|
115 handled_stanza_count = 0; |
|
116 |
|
117 -- TODO ack using final h value from <failed/> if present |
|
118 outgoing_queue = {}; -- TODO fire some delivery failures |
|
119 |
|
120 local features = stream.pre_smacks_features; |
|
121 stream.pre_smacks_features = nil; |
|
122 |
|
123 -- should trigger a bind and then a new smacks session |
|
124 stream:event("stream-features", features); |
109 else |
125 else |
110 stream:warn("Don't know how to handle "..xmlns_sm.."/"..stanza.name); |
126 stream:warn("Don't know how to handle "..xmlns_sm.."/"..stanza.name); |
111 end |
127 end |
112 end |
128 end |
113 |
129 |
124 end |
140 end |
125 end |
141 end |
126 |
142 |
127 local function on_features(features) |
143 local function on_features(features) |
128 if features:get_child("sm", xmlns_sm) then |
144 if features:get_child("sm", xmlns_sm) then |
|
145 stream.pre_smacks_features = features; |
129 stream.stream_management_supported = true; |
146 stream.stream_management_supported = true; |
130 if stream.smacks and stream.bound then -- Already enabled in a previous session - resume |
147 if stream.smacks and stream.bound then -- Already enabled in a previous session - resume |
131 stream:debug("Resuming stream with %d handled stanzas", handled_stanza_count); |
148 stream:debug("Resuming stream with %d handled stanzas", handled_stanza_count); |
132 stream:send(verse.stanza("resume", { xmlns = xmlns_sm, |
149 stream:send(verse.stanza("resume", { xmlns = xmlns_sm, |
133 h = tostring(handled_stanza_count), previd = stream.resumption_token })); |
150 h = tostring(handled_stanza_count), previd = stream.resumption_token })); |