Q:
- So, telepathy is a spec and an implementation?
A:
- Yeah. Well, one spec, and a bunch of implementations. The API boils down to a number of basic concepts. You have handles, which are nouns. Handles represent things like contacts, rooms, contact lists. You have channels, which are things you do with handles. A channel might be a text conversation with a contact, or a list of contacts.
Q:
- Not an IRC channel - that's a handle?
A:
- Right. So I can request a handle for an IRC channel, but that doesn't mean I've joined it. I can refer to it without doing things with it. Channels belong to connections, and connections belong to connection managers.
Q:
- Gabble, Salut, ...
A:
- Right. Generaly, you get a connection manager object by reading .manager files, which tell you which protocols that CM supports and which parameters each protocol accepts. Given the unique name of a connection manager, you can create a D-Bus proxy for it.
Q:
- Ok. So all the Telepathy components talk D-Bus to each other?
A:
- Yes. The specification only specifies the D-Bus APIs. And we specify some file formats. About D-Bus: the main things to know are connections and objects, and the bus itself, i guess. When you connect to a D-Bus bus, you are given a unique ID. Other programs that are connected to the bus can use this unique ID to communicate with you. The unique ID looks like ":1.123".
In Addition to the unique ID, you can request what's variously known as a "well known name" or a "service name". Only one person can hold a given name at a time. A well known name might be "org.freedesktop.Telepathy.ConnectionManager.gabble".
Q:
- Right, so you can connect to the well known name.
A:
- Right. It's a bit like DNS. Everybody has an IP address. You can attach names to addresses. The bus daemon is responsible for forwarding messages between all of its clients. Usually, you have one system-wide bus daemon ("the system bus"), and a session bus, per X session. You can create extra busses whenever you like using d-bus launch. And we do this e.g. in Gabble for the tests, so that the tests are isolated from whatever might be running in your session. Each connection to the bus can have any number of objects, and each object is addressed using a unix-like path (e.g. "/org/freedesktop/Telepathy/ConnectionManager/gabble").
Q:
- Why not just "/gabble", if you're connected to the right thing?
A:
- Good question. That's so you can provide multiple services at once. When you receive a method call, it has your unique address rather than your well-known address (IIRC), so you can't do virtual hosting. And in theory, a library you're using might want to add its own objects to your D-Bus connection.
A:
So, going back to .manager files. D-Bus doesn't read your .manager files, they're Telepathy-specific, but Telepathy clients do. If I'm a Telepathy client, and I've found a file "gabble.manager" and I want to use gabble, I can construct a proxy for the ConnectionManager object as follows: ('org.freedesktop.Telepathy.ConnectionMananger.%s' % 'gabble', '/org/freedesktop/Telepathy/ConnectionManager/%s' % 'gabble') The clever bit is this: if none of its clients is providing the "org.freedesktop.Telepathy.gabble" name, the bus daemon will look through a bunch of files it has, to see if any of them tell it how it might start a program that provides that service. This is called D-Bus service activation, and it's totally transparent. So, if I construct my D-Bus object proxy for gabble, then call RequestConnection on it, and gabble isn't running, then the D-Bus daemon can use gabble's .service file to run Gabble. And then, once it connects, it calls RequestMethod on it and, to the calling process, it's as though gabble was there all along. There's one more D-Bus concept I haven't mentioned - interfaces. Every method and signal is qualified by an interface, and each D-Bus object can provide multiple interfaces. Telepathy interfaces all start with org.freedesktop.Telepathy. The RequestConnection I mentioned earlier is on the org.freedesktop.Telepathy.ConnectionManager interface. In fact, the Telepathy spec is organised by interface.
Q:
- (Except OLPC specific interfaces start with org.laptop.Telepathy)
A:
- Good point! You can extend your Telepathy implementation with any extra interfaces you want. Though of course we encourage people to try and improve the Telepathy spec instead of extending it privately.
A:
So, as you've probably gathered, once you have a connection manager, you can request connections using RequestConnection. And, given a connection, you can get handles using RequestHandles and channels using RequestChannels. Requesting handles is pretty simple.
Q:
- So you can get the handle of a JID, say, or a MUC - and then connect to it?
A:
Right. Let's do an example. Say I want to talk with you. On the connection interface, i call RequestHandles(1, ['your@jid.org']). The 1 is the type of handle i want (1 == contact). This returns something like [2], ie. a list of numbers, with one number for each string I passed in. Once I have that, I can request a channel with you: RequestChannel('org.freedesktop.Telepathy.Channel.Type.Text', 1, 2, True). The "org..." is the interface I want, 1 is the handle type, 2 is the handle, the 'True' is for other Telepathy clients and tells them "don't try to automatically handle this channel". If the CM is happy with my request, it returns a string, which is a D-Bus object path, and I can construct a proxy for the channel object by combining the connection's bus name with the new object path. I can then call methods on the channel object.
Q:
- So, what are TUBES?
A:
- The idea behind tubes is: "If I can talk with this person over some IM protocol, why can't program on my machine talk to programs on their machine?" There's lots of programs you have that you might want to be able to talk to their programs. E.g. your VNC client, their VNC server. For OLPC, those programs are activities.
Q:
- And this gets through NAT...
A:
- Right. The idea is that tubes gets you from A to B, whatever it takes. Whether that's by going through the server, the server connection that you already have open, or doing cunning NAT traversal stuff. For now, we've only got one kind of tube, which are D-Bus tubes (D-Tubes), which essentially let you pretend that a D-Bus object on machine B is actually on machine A. Stream tubes will be like TCP connections. We might have datagram tubes at some point (e.g. UDP-like).
Q:
- So things that already talk D-Bus can just talk D-Tubes?
A:
- Almost, yeah. You do need to keep track of the participants. Your D-Bus connection looks like a lot like any other D-Bus connection, except there's no bus daemon so you can't call methods on it (you do stuff like acquire a well-known name by calling methods on the bus daemon).
Q:
- So you're already connected to a specific object?
A:
- Not quite. You can still have as many objects as you like, but you're limited to your unique name. So you have to go in with some idea of which methods you'll be calling. Each D-Bus tube has a service string, which tells you what you can expect to do with that tube. The service might be org.laptop.Activity.Browser, which tells you that you can expect to receive signals telling you that your contact browsed to a different page.
Q:
- What are the signatures? What do they signify?
A:
- They're D-Bus types. D-Bus has its own type system. It has different kinds of integers, floats, strings, and a compound structures: arrays, dictionaries, structures. So, u == uint32, au == array of uint32, a(uu) == array of (struct of uint32, uint32), s == string, a{su} == dictionary of (string to uint), aau == array of (array of uint32).
http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-signatures has the complete list. There's also D-Bus introspection, which is a way to ask a D-Bus object which interfaces it supports, including a list of methods/signals and their signatures

