iChat and Smack

Good afternoon, all. I’‘m interested in writing some software to work with Apple’‘s iChat IM client. The protocol used by iChat when in peer-to-peer mode is a derivative of Jabber/XMPP. Just how derived, I don’'t know just yet.

The first thing I need to tackle is creating a session between an iChat client and my own code. I believe what I need to do is create a light-weight server instance that can receive the XMPP stream from the client. From what I’'ve seen, Smack only allows me to initiate a connection to a server, and not set up a network socket that will listen for connections from a client.

Does anyone have any suggestions on how I can proceed, using the Smack API?



Yep, Smack is only a client library and can’‘t act as a server. It might be possible to re-use some of the Smack code for doing parsing of ichat streams, but I don’‘t know anything about how ichat works, so it’'s tough to say if this would actually work.



Kind of what I thought…

I’‘m looking at the Smack code now and my first attempt will be to subclass XMPPConnection and use a constructor that takes a socket that’‘s connected to the peer. From what I’‘ve seen of the protocol to this point, that may work without too much further work. I’‘ll keep y’'all posted and contribute code back if I get anything workable.

I should preface my comments here by saying that I’‘ve dabbled with Jabber for a couple of years on and off, but don’'t know the spec by heart.

That being said: I added one class (iChatXMPPConnection) and modified PacketReader and I have succeeded in exchanging messages between my test class and an iChat client. I modified PacketReader to set the connectionID field to “-1” if no connection id could be found in the stream:stream/ element. There’'s a comment in XMPPConnection::getConnectionID() that states that connectionID may be null if not sent by the server, but PacketReader closes the connection if there is no connectionID.

One pecularity I’‘ve noticed, and I don’‘t know if this is related to a bug in Smack or not: iChat opens the connection and immediately dumps the first message you type. It does not open the connection when a peer is discovered. The upshot of this is that I am unable to capture the first message, presumably because the message has already been read by the reader before I get my PacketListener in place. I’'m going to look at modifying the Smack code to allow me to set up my listeners before giving it a socket to play with. Any thoughts?


If you’‘re still around, I’'d be interested to hear what changes you made specifically to communicate with iChat clients.