Google Talk voice protocol disclosed!
Just experimenting how to make any xmpp client capable of understanding google proprietary voip protocol. At start, to make the google talk client think that your xmpp client is voip capable, it is enough to send a presence as such:
<presence to="originatingparty@gmail.com/Talk.v64EC3F606D" >
<status/>
<priority>0</priority>
<c xmlns="http://jabber.org/protocol/caps" node="http://www.google.com/xmpp/client/caps" ext="voice-v1" ver="1.0.0.64" />
<x xmlns="jabber:x:delay" stamp="20050828T17:14:25" />
</presence>
Soon the google client receives that, it shows the "phone" icon at the right of the contact-nickname.
When google talk starts a telephone call, it sends an iq as such:
<iq from="originatingparty@gmail.com/Talk.v64EC3F606D" type="set" id="21" >
<session xmlns="http://www.google.com/session" initiator="originatingparty@gmail.com/Talk.v64EC3F606D" type="initiate" id="3688330360" >
<description xmlns="http://www.google.com/session/phone">
<payload-type id="103" name="ISAC" />
<payload-type id="97" name="IPCMWB" />
<payload-type id="102" name="iLBC" />
<payload-type id="4" name="G723" />
<payload-type id="100" name="EG711U" />
<payload-type id="101" name="EG711A" />
<payload-type id="0" name="PCMU" />
<payload-type id="8" name="PCMA" />
<payload-type id="13" name="CN" />
</description>
</session>
</iq>
This packet has two functions:
- maybe specify the codec it understands
- verify that the other party is really capable of doing voip
In fact the client receiving the call has to send this iq soon before a short timeout ends:
<iq to="originatingparty@gmail.com/Talk.v64EC3F606D" type="result" id="aaad" />
Without waiting for the user to press on the "Accept" button, each client exchanges with the other such an information:
<iq from="originatingparty@gmail.com/Talk.v64EC3F606D" type="set" id="60" to="ppippero@gmail.com/Talk.v64ED37AA3E" >
<session xmlns="http://www.google.com/session" initiator="originatingparty@gmail.com/Talk.v64EC3F606D" type="candidates" id="3688330360" >
<candidate protocol="udp" preference="0.9" port="4123" password="kuyxAgKfRZcteQWf" address="217.201.14.129" network="2" username="1T0ThiQiPQkWj/Qe" generation="0" type="stun" name="rtp" />
</session>
</iq>
<iq from="originatingparty@gmail.com/Talk.v64EC3F606D" type="set" id="59" to="ppippero@gmail.com/Talk.v64ED37AA3E" >
<session xmlns="http://www.google.com/session" initiator="originatingparty@gmail.com/Talk.v64EC3F606D" type="candidates" id="3688330360" >
<candidate protocol="udp" preference="1" port="4126" password="4k6c4IZUOTY8pCKl" address="192.168.152.1" network="4" username="dPq07nMRccpHLZML" generation="0" type="local" name="rtp" />
</session>
</iq>
Note that some ports are declared as local, some other as stun. That's all for now ;-). Ah, the transport protocol appears to be RTP: I will just grabbing some traffic with ethereal and check if it is really simple RTP.
Hi, a nice new interface for ::mo'time