I added fake caps&features to Z-XMPP to simulate iChat’s AV support. List of the caps&features that I added:
this.featuresExt["ice"] = ["apple:iq:vc:ice"];
this.featuresExt["recauth"] = ["apple:iq:vc:recauth"];
this.featuresExt["rdserver"] = ["apple:iq:rd:server"];
this.featuresExt["maudio"] = ["apple:iq:vc:multiaudio"];
this.featuresExt["audio"] = ["apple:iq:vc:audio"];
this.featuresExt["rdclient"] = ["apple:iq:rd:client"];
this.featuresExt["mvideo"] = ["apple:iq:vc:multivideo"];
this.featuresExt["auxvideo"] = ["apple:iq:vc:auxvideo"];
this.featuresExt["rdmuxing"] = ["apple:iq:rd:muxing"];
this.featuresExt["avcap"] = ["apple:iq:vc:capable"];
this.featuresExt["avavail"] = ["apple:iq:vc:available"];
this.featuresExt["video"] = ["apple:iq:vc:video"];
And here’s what I get when I press call:
The long thing is a hexadecimal (yes, hex — strangely not base64) string which, when decoded, is pretty much binary looking. There are a few things that seem to be strings. Let’s try to find something readable in the string:
(removed since the binary text included some characters that confused various XML decoders; use a hex to string converter such as this one)
This mentions the caller and the receiver of the call. We can also see several interesting strings such as NSMutableDictionary, NSDictionary and NSObject; that is the inheritance path for NSMutableDictionary in Objective-C. This invitation looks like something serialized in Objective-C into some binary format, then converted into hex, inserted in XMPP XML, and sent over the wire. In fact… “bplist”… that sounds oddly similar to b-plist… binary plist? That could probably be easily decoded with an Objective-C based XMPP client!
Not only that: decoding that with, for example, Python (import binascii, binascii.unhexlify(data)) and writing to file with extension .plist shows that we can open this in Apple’s Property List Editor, uncovering VCICEData (a large binary blob – “data”), VCInviteesList (an array), VCOrderIsFinal (a boolean set to false), VCSecurityEnabled (a boolean set to false), and VCSessionID (a “number”).
VCInviteesList members are two dictionaries. In the dictionaries, we have these items: ardRole (number 0), error (number 0), invitedBy (string with caller jid), presentityID (string with caller or callee jid), presentityName (string with caller’s or callee’s name), sendingAudio (boolean set to true), sendingVideo (boolean set to false), state (0 with caller, 2 with callee), usingICE (boolean set to false with caller, true with callee), and finally vcPartyID (string with entity’s jid suffixed by 1 or 2, depending on place in array).
Surprisingly, iChat ignores completely when an iq-error stanza is sent to signify that the feature needed to parse iq-query is not supported.
Googling for AVChatConferenceData surprisingly uncovers nothing. Could it really be that noone has yet tried to discover how iChat’s AV works in combination with XMPP?
Oh, and canceling the call goes like this:
I’m not sure I’ll keep on pursuing this, especially since I didn’t write a client to play with. I’m not keen on studying Telepathy, Gabble, Sofia-SIP and Farsight, closest thing one could find to something opensource that could be used to implement iChat’s SIP-based AV. I don’t exactly have the time required to write a full XMPP client for desktops or iOS just to BEGIN trying to figure out iChat’s AV — maybe I’ll be crazy enough some time in the future 🙂