powered by Jive Software

Extending Smack -- stream-based file transfer

Dear Smack users/developers,

I’'ve been working on extending Smack of stream-initiation-based file transfers. I have an interesting problem, however and I hope that maybe some of you can help. I defined new types of packets for , and and provided providers for them. This part works and all those packets are recognized and parsed successfully.

Later on, I want my application (JBother in this case) to act upon arrival of those packets so I create a PacketListener for StreamInitiation object and add it to XMPPConnection method.

Now comes the funny part: so far this code works when packets are coming in/to a certain client only: Psi. I’'ve spent lots of time trying to figure out why Smack does not pass my packets to my PacketListener when those are sent from other Jabber clients (tkabber, JBother).

I attach some code below. First, adding a packet listener:

private static SmackxStreamInitiationListener siListener = new SmackxStreamInitiationListener();

(…)

// this filter will listen to three types of messages:

// , and

filter = new OrFilter(new PacketTypeFilter ( Streamhost.class ),

new PacketTypeFilter ( StreamhostUsed.class ));

OrFilter filter2 = new OrFilter(new PacketTypeFilter (StreamInitiation.class),

filter);

connection.addPacketListener( siListener, filter2 );

where connection is XMPPConnection object.

Definition of SmackxStreamInitationListener:

/**

  • incoming StreamInitiation packets are processed by this class.

  • the main task is to reply to it offering byteatream to the caller

*/

public class SmackxStreamInitiationListener implements PacketListener

{

private static String fId = “$Id$”;

public static final String BYTESTREAMS = “http://jabber.org/protocol/bytestreams”;

public SmackxStreamInitiationListener()

{

}

public void processPacket(Packet packet)

{

//

if (packet instanceof StreamInitiation) {

//

if ( ((IQ)packet).getType() == IQ.Type.SET )

{

StreamInitiation si = (StreamInitiation)packet;

if(si.getFeature().providesBytestreamOption())

{

// inform the user that someone wants to send him/her a file

// popup “accept file” window. It will take the action from here

FileReceiveDialog frd = new FileReceiveDialog(si);

PacketFilter filter = new PacketTypeFilter( Streamhost.class );

BuddyList.getSingleton().getConnection().addPacketListener(frd, filter);

frd.setVisible(true);

}

else

{

IQ errorPacket = new IQ() {

public String getChildElementXML() {

return null;

}

};

errorPacket.setTo(si.getFrom());

errorPacket.setFrom(si.getTo());

errorPacket.setType(IQ.Type.ERROR);

errorPacket.setPacketID(packet.getPacketID());

errorPacket.setError(new XMPPError(400,"<bad-request xmlns=“urn:ietf:params:xml:ns:xmpp-stanzas”/>\n"

        + "<bad-profile xmlns=\"http://jabber.org/protocol/si\">"));

sendPacket(errorPacket);

return;

}

}

}

//

else if(((IQ)packet).getType() == IQ.Type.RESULT)

{

// I guess nothing, such packets are not sent but this needs to be verified

}

}

I would be very grateful for pointing me in some direction on this.

Greetings from cold & rainy Netherlands,

c.