Below are my raw notes I took for my own use before deciding to write a general-consumption tutorial. These will disappear as the document grows and will be completely removed prior to the first draft being released.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Creating my DBus bus for the TCSP server and clients. - Create the system bus 'org.tle-bu.tcsp' \- Listen on unix socket file as defined in 'tle-bu.conf'. - "Bus Names" are the names of connections on the bus, NOT the name of the bus itself. \- Each bus name will reflect a connected client. - To specify a particular method call on a given object instance, the structure is: \- Address -> [Bus Name] -> Path -> Interface -> Method - [Bus Name] is optional and only needed when there using the dbus-daemon. Direct connections don't require the bus name, as there is no Bus daemon). - The Interface is also somewhat optional, but not using it when the Method name could be ambiguous could cause trouble as it would be hard to know what Interface in particular to call the Method on. So yeah, just use it. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- DBus stuff; - valid Object Paths; start with '/', no double-slash, no trailing slash. |- /org/freedesktop/DBus/Local is reserved. |- All elements must use only '[a-z][A-Z][0-9]_' \- Is heirarchal, like a FS. - valid Interface Names; Must contain at least two elements. |- Elements separated by '.', no double-period, no beginning or trailing period. |- When type STRING, must be UTF-8, elements must only use '[a-z][A-Z][0-9]_'. \- org.freedesktop.DBus.Local is reserved. - valid Bus Names; All the same restrictions as Interface names, except; |- May use '-' in element names. |- May beging with a colon (:). This defines unique connection names. \- A Bus name stays with the connection it's entire life. - Member names must not begin with a period, or have a period anywhere in it's name. \- Must contain only '[a-z][A-Z][0-9]_' characters. Because an element can't contain a period, the last item in an Interface string is known to be the element. \- ie: org.freedesktop.DBus.StartServiceByName -> org.freedesktop.DBus = Interface, StartServiceByName = element Each line ends in '\r\n'. Server addresses are in the format 'transport:(key=value(,key2=value))'. \- ie: 'unix:path=/tmp/dbus-test' = unix socket with the path /tmp/dbus-test -- I want to listen to the system bus. |- This Object path should be in the environment var DBUS_SYSTEM_BUS_ADDRESS |- If that var is not set, look in the socket unix:path=/var/run/dbus/system_bus_socket \- Look for '.service' files? '/usr/share/dbus-1/services/*.service' on Ubuntu - This seems to be static and has info on the above: # cat /etc/dbus-1/system.conf - "Bus Names" are the names of connections on the bus, NOT the name of the bus itself. - When a bus comes up, it's assigned a "unique connection name", which you can see because it starts with a colon (ie: ':34-907'). If a given bus name is closed and another with the same name is started, it will be unique because of this. - Names (elements?) on a given bus, however, can be relinquished and then picked back up by something else. - An 'object' is a DBus communication end-point. To avoid this, use a unique name, not a well-known one. - Every bus has an object itself, which represents that bus. Information about the bus can be collect by sending a request to this object. - DBus "Proxies" are like APIs for a given language; they are the proxy bindings used to talk to a given bus. - It is general practice to use an object path based on a domain you use to avoid stepping on other program's toes. Ie: '/org/tle_bu' or '/com/alteeve'. This is not a requirement though, and any object path name(s) can be used. - Objects have two 'Members'; they are 'Methods' and 'Signals', referred to by a name (ie: 'OnClicked', etc). - Methods; Operations that can be invoked on an object with optional input ("In Parameters") and output ("return values" or "out parameters"). - Signals; Broadcasts from an object (which may contain a "payload") to zero or more interested listeners. - Interfaces; a group of Objects (more details, less C++/Java/Qt comparisons...) - Proxies are (generally) provided by a given program language's bindings (Net::DBus in perl). In perl parlance, this is a file handle to a remote object. When acting on it, it appears as a local filehandle or variable, but in fact it is making a call to the remote object, waiting for the reply and processing the reply transparently. - When an app connects to a given bus, it is assigned a 'Unique Connection Name' which starts with a colon (:). (ie: ':34-907'). The number means nothing in itself, it serves to be unique only. If a name is assigned to an application, it is said to "Own" that name (ie: '/org/tle_bu/FooBar', where 'FooBar' is the owned name). This name to UCN mapping is very similar to domain-to-IP mapping. 'FooBar' means nothing in itself, but it's value is in it's mapping to ':34-907'. Like a domain, this allows to look for an Object without needing to know what the UCN is or if it's changed. Other applications that then talk to the UCN or owned name talk to the owning application. - If the owning application of a given name closes or crashes, the operating system will send out a notification message (signal?). Applications can then watch for these signals and react appropriately. This is refered to as 'lifecycle tracking'. - This can also be used to make sure an application is only running once. Your application could check to see if 'FooBar' already has an owner and, if so, exit (or do whatever). - During the establishment of a symetrical connection, applications are either a Server, listening for a connection, or a client, which sends the connection request. After the connection is up, this Client/Server concept is no longer relevant. - Most often, you app will connect as a client to the 'dbus-daemon'. - A DBus 'Address' is where a server listens for connections from clients. An address could be a Unix socket (ie: unix:path=/path/to/socket), a TCP address (format?) or any other transport later defined by the DBus spec. If you're a corner case and not using the 'dbus-daemon', you will need to pre-define where the server will watch for connections. - To specify a particular method call on a given object instance, the structure is: \- Address -> [Bus Name] -> Path -> Interface -> Method - [Bus Name] is optional and only needed when there using the dbus-daemon. Direct connections don't require the bus name, as there is no Bus daemon). - The Interface is also somewhat optional, but not using it when the Method name could be ambiguous could cause trouble as it would be hard to know what Interface in particular to call the Method on. So yeah, just use it. - Messages; There are four types, and with sufficiently advanced bindings (Net::DBus?), they will not be a concern. However... |- Method call messages asking to invoke a method on an object (like calling an SR) |- Method return messages returning the results of an invoked object (like the return from a SR). |- Error messages returning an exception caused by invoking a method. \- Signal messages are notifications of a signal having been emitted. - So then, you send a method call message, and wait for a reply message or an error message. Or, you listen for signal messages and do something when they show up. - A message consists of a header (made up of fields) and a body (containing arguments). - A header contains the routing info (sender bus, destination bus, method or signal name, body type signature, etc). The body type signature is an ascii string describing the body's binary data. Ie: the type code 'ii' indicates that the body is two 32-bit integers. - The body is the payload. - Calling a method (see: http://dbus.freedesktop.org/doc/dbus-tutorial.html -> Behind the scenes); - A method call consists of two messages; a method call sent from A to B with a unique serial number, and a reply from B to A referencing the serial number so that A can match reply messages to given calls. - These calls are handled by the bus daemon. - The calling method can contain data to be given to the destination method, and the reply message can be an error or returned data. - The dbus-daemon never alters the order it delivers method calls (like a fifo) but it can not enforce how or in what order reply messages come back. This is where matching the serial number on reply messages to the serial number of the calling method is important. - A signal message consists on one message sent from one method to zero or more listening processes (broadcast). - A signal may have a payload, but it does not have a return value. It is a broadcast only. - Listening processes register with the bus-daemon using match rules, and when the daemon receives a signal that matches those rules, the listening process is notified. The sender has no knowledge of this and frankly, doesn't give a damn. - - MADI: org.freedesktop.DBus.Introspectable takes no arguments and returns an XML string describing the interfaces, methods and signals of an object. -=-=-=-=- dbus-monitor output format; <message_type> <unix_time> <?serial_number?> <?> <Object_Path> <Interface_Name> <?Arguments?>
|Any questions, feedback, advice, complaints or meanderings are welcome.|
|Us: Alteeve's Niche!||Support: Mailing List||IRC: #clusterlabs on Freenode||© Alteeve's Niche! Inc. 1997-2019|
|legal stuff: All info is provided "As-Is". Do not use anything here unless you are willing and able to take responsibility for your own actions.|