AnsweredAssumed Answered

Packet Filter for the initial presence when joining a MUC room

Question asked by Anno van Vliet on Nov 18, 2014
Latest reply on Nov 19, 2014 by Flow

When joining a room using MultiUserChat?.join the responses are not always correctly handled

Test case:

f.i. User wants to join a room that is blocked for him

<presence id="3SWrl-51" to="blockedroom@huis.straat.stad/User"> <x xmlns="http://jabber.org/protocol/muc"> <password/> </x> </presence> 

The server (M-Link) returns a response with a non expected From Adress:

<presence id="3SWrl-51" to="anno@test.xmpp/resource" from="blockedroom@huis.straat.stad" type="error"> <x xmlns="http://jabber.org/protocol/muc"/> <error type="auth"> <registration-required xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/> </error> </presence> 

The Smack code does not recognise the response in this case while it is waiting for a response with the complete RoomJID + nickname as the from address and returns with a NoResponseException.

 

A possible solution is:

 

Take also the PacketID in account.

 

diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java
index cd3b26d..068a221 100644
--- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java
+++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java
@@ -47,8 +47,10 @@
 import org.jivesoftware.smack.filter.MessageTypeFilter;
 import org.jivesoftware.smack.filter.MessageWithSubjectFilter;
 import org.jivesoftware.smack.filter.NotFilter;
+import org.jivesoftware.smack.filter.OrFilter;
 import org.jivesoftware.smack.filter.PacketExtensionFilter;
 import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.filter.PacketIDFilter;
 import org.jivesoftware.smack.filter.PacketTypeFilter;
 import org.jivesoftware.smack.filter.ToFilter;
 import org.jivesoftware.smack.packet.IQ;
@@ -284,8 +286,8 @@
         joinPresence.addExtension(mucInitialPresence);

         // Wait for a presence packet back from the server.
-        PacketFilter responseFilter = new AndFilter(FromMatchesFilter.createFull(room + "/"
-                        + nickname), new PacketTypeFilter(Presence.class));
+        PacketFilter responseFilter = new AndFilter(new OrFilter(new PacketIDFilter(joinPresence.getPacketID()),
+                        FromMatchesFilter.createFull(room + "/" + nickname)), new PacketTypeFilter(Presence.class));

         // Setup the messageListeners and presenceListeners *before* the join presence is send.
         connection.addPacketListener(messageListener, fromRoomGroupchatFilter);

Outcomes