Changeset 40270 in project


Ignore:
Timestamp:
07/10/21 13:48:05 (3 weeks ago)
Author:
ecloud
Message:

finally spell D-Bus correctly; update examples

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wiki/eggref/5/dbus

    r39964 r40270  
    77=== Overview
    88
    9 This is a binding for libdbus 1.x.  DBus is a popular IPC (inter-process communication) protocol which is often used between system components (for example hald informs applications when new hardware becomes available, gpsd informs apps when the location has changed, or an application requests gsmd to place a phone call).
     9This is a binding for libdbus 1.x.  D-Bus is a popular IPC (inter-process communication) protocol which is often used between system components (for example hald informs applications when new hardware becomes available, gpsd informs apps when the location has changed, or an application requests gsmd to place a phone call).
    1010
    1111=== Goals & status
     
    1818<tr><td>register a procedure as a handler which will be called when a signal is received</td><td>yes</td></tr>
    1919<tr><td>register a procedure as a method which can be called from another process</td><td>yes</td></tr>
    20 <tr><td>assign a path to a TinyClos object and map applicable generic functions as dbus methods</td><td></td></tr>
     20<tr><td>assign a path to a TinyClos object and map applicable generic functions as D-Bus methods</td><td></td></tr>
    2121<tr><td>create proxy methods matching remote methods</td><td>yes</td></tr>
    2222<tr><td>create proxy objects matching remote objects (so that all the remote object's applicable methods are made into local proxy methods)</td><td></td></tr>
     
    2626<tr><td>registered methods and signal-handlers are automatically included in the Introspectable interface implementation</td><td></td></tr>
    2727<tr><td>user code to do any of the above should be minimal: abstract away the orthogonal extra steps (open a connection, start a polling thread, etc.)</td><td>yes</td></tr>
    28 <tr><td>support all DBus data types for method parameters and return values</td><td></td></tr>
     28<tr><td>support all D-Bus data types for method parameters and return values</td><td></td></tr>
    2929</table>
    3030
     
    5555; bus : The aggregator and dispatcher of messages between processes.  The usual choices are system bus, session bus or an app-specific bus.  This egg uses the session bus by default.  It is the same bus used by desktop session services, like KDE components for example.  Accessing the system bus requires special permission.  An app-specific bus does not promote application interoperability.  So that leaves the session bus as generally being the most appropriate.
    5656
    57 ; bus name : A unique identifier for a DBus client.  Every DBus client is automatically assigned a bus name.  These consist of a colon character ':' followed by some numbers.  You can see these in the DBus traffic in the output of dbus-monitor.  DBus clients that want to listen for method calls can request a second bus name, a so-called well-known bus name, which is a name by which other DBus clients can refer to them.  Well-known bus names are what you use in the 'service' field of a method call.
     57; bus name : A unique identifier for a D-Bus client.  Every D-Bus client is automatically assigned a bus name.  These consist of a colon character ':' followed by some numbers.  You can see these in the D-Bus traffic in the output of dbus-monitor.  D-Bus clients that want to listen for method calls can request a second bus name, a so-called well-known bus name, which is a name by which other D-Bus clients can refer to them.  Well-known bus names are what you use in the 'service' field of a method call.
    5858
    5959; service : A well-known bus name giving the destination of a method call.  Conventionally, these look like reversed domain names.  Signals do not use services.
    6060
    61 ; path : A DBus-exposed API can be conceptually organized into a hierarchy.  Paths index into this hierarchy with notation familiarly derived from file and URL paths, where path components are separated by slashes '/'.  The program might map path components to actual objects in memory, but this is not required.  The default path, when not given, is "/".
     61; path : A D-Bus-exposed API can be conceptually organized into a hierarchy.  Paths index into this hierarchy with notation familiarly derived from file and URL paths, where path components are separated by slashes '/'.  The program might map path components to actual objects in memory, but this is not required.  The default path, when not given, is "/".
    6262
    6363; interface : a partitioned set of methods which is being offered, like a Java interface or an abstract class.  An interface is technically optional when registering a method or signal handler, but this egg currently requires it.
     
    6767; signal : a one-to-many notification from one process to any others which happen to be listening for that particular notification.  A signal message does not include a service because it does not have a specific destination.  Signals are one way; there is no explicit reply from the receivers.
    6868
    69 ; method call : a one-to-one message between DBus clients.  The caller can pass arguments, and the handler sends a method return message back with the result.
     69; method call : a one-to-one message between D-Bus clients.  The caller can pass arguments, and the handler sends a method return message back with the result.
    7070
    7171; method return : the message type of the response to a method call.
     
    7373; method : a scheme function to be invoked when a particular method call message is received.  Its result will be sent back to the calling client as a method return.
    7474
    75 ; message : the DBus-protocol representation of a signal or a method call passing across the DBus connection between two processes.
     75; message : the D-Bus-protocol representation of a signal or a method call passing across the D-Bus connection between two processes.
    7676
    7777And this egg introduces one more:
     
    8181This egg does not yet fully support making methods, signal handlers, and interfaces discoverable by other clients.
    8282
    83 === DBus in general
    84 
    85 Use dbus-monitor to see all the dbus traffic (on the session bus by default).
     83=== D-Bus in general
     84
     85Use dbus-monitor to see all the D-Bus traffic (on the session bus by default).
    8686
    8787A many-to-many "bus" exists as a running dbus-daemon process.  Each application which is interested in using that bus connects to the daemon via Unix-domain sockets.  The daemon collects incoming messages and dispatches them to the connected processes which have expressed interest in receiving particular categories of messages.  Usually there is one running instance of dbus-daemon for the system bus, and one running instance for each session bus: each user who is logged in and running a desktop session is typically running one instance of the daemon.
     
    9191=== Data types
    9292
    93 DBus protocol (unlike XML, for example) allows sending real native datatypes across the connection.  In fact it provides more data types than does Chicken.  So when you pass some parameters along with a method call, these are the default conversions:
     93D-Bus protocol (unlike XML, for example) allows sending real native datatypes across the connection.  In fact it provides more data types than does Chicken.  So when you pass some parameters along with a method call, these are the default conversions:
    9494
    9595<table>
    96 <tr><th>Chicken data type</th><th>DBus data type</th></tr>
     96<tr><th>Chicken data type</th><th>D-Bus data type</th></tr>
    9797<tr><td>fixnum</td><td>DBUS_TYPE_INT32</td></tr>
    9898<tr><td>flonum</td><td>DBUS_TYPE_DOUBLE</td></tr>
     
    104104TODO that table needs updating: 64-bit ints are there, signed and unsigned, variants, dictionaries, structs etc.  Also need to explain about unboxing.
    105105
    106 When a DBus message is received, the parameters are converted similarly, but unsupported DBus types will be converted to #f.
    107 
    108 Watch out for cases when Chicken converts an integer to a flonum, because it was too large to fit in a fixnum.  It will go across the DBus connection as a double, which might not be what you wanted.
     106When a D-Bus message is received, the parameters are converted similarly, but unsupported D-Bus types will be converted to #f.
     107
     108Watch out for cases when Chicken converts an integer to a flonum, because it was too large to fit in a fixnum.  It will go across the D-Bus connection as a double, which might not be what you wanted.
    109109
    110110=== Exported functions
     
    146146
    147147Provide a handler to be called when the current process receives a
    148 DBus signal which matches the given context and the given signal name.
     148D-Bus signal which matches the given context and the given signal name.
    149149Start a SRFI-18 thread to poll for incoming signals (unless polling
    150150has been disabled on this bus).
     
    154154
    155155Provide a handler (a method body) to be called when the current
    156 process receives a DBus message which matches the given context and
     156process receives a D-Bus message which matches the given context and
    157157the given method name.  Start a SRFI-18 thread to poll for incoming
    158158messages (unless polling has been disabled on this bus).
     
    167167<procedure>(poll-for-message #!key (bus session-bus) (timeout 0))</procedure>
    168168
    169 Check once whether any incoming DBus message is waiting on a
     169Check once whether any incoming D-Bus message is waiting on a
    170170particular bus, and if so, dispatch it to the appropriate callback
    171171(which you have previously registered using {{register-method}}
     
    208208These are in the examples subdirectory in svn, and included with the egg too.
    209209
    210 ==== Examples you can test with QT
    211 
    212 QT includes a DBUS remote-controlled car example.  E.g. it might be located in {{/usr/share/qt4/examples/qdbus/remotecontrolledcar/car}} depending on your distro.  If you run the car, you can cause the wheels of the car to turn to the right by doing this:
     210==== Examples you can test with [[https://en.wikipedia.org/wiki/Qt_(software)|Qt]]
     211
     212Qt includes a D-Bus remote-controlled car example.  E.g. it might be located in {{/usr/share/doc/qt6/examples/dbus/remotecontrolledcar}} depending on your distro.  If you run the car, you can cause the wheels of the car to turn to the right by doing this:
    213213
    214214<enscript highlight=scheme>
    215 (use dbus)
    216 
    217 (define rc-car-context
    218   (make-context
    219    service: 'com.trolltech.CarExample
    220    interface: 'com.trolltech.Examples.CarInterface
    221    path: '/Car))
    222 
    223 (call rc-car-context "turnRight")
     215(import (prefix dbus dbus:))
     216
     217(define rc-car-context (dbus:make-context
     218        service: 'org.example.CarExample
     219        interface: 'org.example.Examples.CarInterface
     220        path: '/Car))
     221
     222(dbus:call rc-car-context "turnRight")
    224223</enscript>
    225224
    226225That example called a method but it did not expect any return values.
    227226
    228 Now suppose you want to simulate the car, so you can use the above example to control your own car rather than the QT one.  And suppose you want to poll for messages manually rather than via the default SRFI-18 polling thread:
     227Now suppose you want to simulate the car, so you can use the above example to control your own car rather than the Qt one.  And suppose you want to poll for messages manually rather than via the default SRFI-18 polling thread:
    229228
    230229<enscript highlight=scheme>
    231 (use dbus)
     230(import (prefix dbus dbus:) (chicken format))
     231
     232(dbus:default-signal-handler (lambda (ctx mber args)
     233        ((dbus:printing-signal-handler) ctx mber args)
     234        (dbus:dump-callback-table)))
    232235
    233236(define (turn-right) (printf "car is turning to the right~%"))
    234237(define (turn-left) (printf "car is turning to the left~%"))
    235238
    236 (define rc-car-context
    237   (make-context
    238    service: 'com.trolltech.CarExample
    239    path: '/Car
    240    interface: 'com.trolltech.Examples.CarInterface ))
    241 
    242 (enable-polling-thread! enable: #f)
    243 
    244 (register-method rc-car-context "turnRight" turn-right)
    245 (register-method rc-car-context "turnLeft" turn-left)
     239(define rc-car-context (dbus:make-context
     240        service: 'org.example.CarExample
     241        path: '/Car
     242        interface: 'org.example.Examples.CarInterface ))
     243
     244(dbus:enable-polling-thread!
     245        enable: #f)
     246
     247(dbus:register-method rc-car-context "turnRight" turn-right)
     248(dbus:register-method rc-car-context "turnLeft" turn-left)
    246249
    247250(let loop ()
    248   (poll-for-message)
    249   (loop))
     251        (dbus:poll-for-message)
     252        (loop))
    250253</enscript>
    251254
     
    254257If the polling thread doesn't work, and you would prefer to poll manually, you can call {{(enable-polling-thread! enable: #f)}} to stop the thread (or to prevent it from being started when you register a new method), and then call {{poll-for-message periodically}}.  Both of those functions can take an optional bus: parameter (which defaults to {{session-bus}}, naturally).  {{poll-for-message}} can also take an optional timeout: parameter (which is 0 by default, so that it is a non-blocking call).
    255258
    256 ==== Examples based on the DBus Tutorial
    257 
    258 The next example, taken from the [[http://dbus.freedesktop.org/doc/dbus/libdbus-tutorial.html|DBus tutorial]], shows how to deal with return values.  First the "listener" program which will answer the query:
     259==== Examples based on the D-Bus Tutorial
     260
     261The next example, taken from the [[http://dbus.freedesktop.org/doc/dbus/libdbus-tutorial.html|D-Bus tutorial]], shows how to deal with return values.  First the "listener" program which will answer the query:
    259262
    260263<enscript highlight=scheme>
    261 (use dbus)
     264(import (prefix dbus dbus:) (chicken format))
     265
    262266(define (query . params)
    263   (printf "got a query; params: ~s~%" params)
    264   ;; the response to the query:
    265   `(#t 42))
    266 
    267 (define ctxt
    268   (make-context
    269     service: 'test.method.server
    270     interface: 'test.method.Type
    271     path: '/test/method/Object))
    272 
    273 (register-method ctxt "Method" query)
     267        (printf "got a query; params: ~s~%" params)
     268        ;; the response to the query:
     269        `(#t 42))
     270
     271(define ctxt (dbus:make-context
     272        service: 'test.method.server
     273        interface: 'test.method.Type
     274        path: '/test/method/Object))
     275
     276(dbus:register-method ctxt "Method" query)
    274277</enscript>
    275278
     
    277280
    278281<enscript highlight=scheme>
    279 (use dbus)
    280 
    281 (define ctxt
    282   (make-context
    283      service: 'test.method.server
    284      interface: 'test.method.Type
    285      path: '/test/method/Object))
    286 
    287 (let ([response
    288        (call ctxt "Method" "query"
    289              "What is the meaning of life, the universe and everything?") ])
    290   (printf "sent a very important query with a known answer; got flippant response ~s~%" response)
    291   (if (and (list? response) (eq? 42 (cadr response)))
    292       (printf "bingo!~%")
    293       (printf "and the answer is wrong too!  Bad supercomputer, bad!~%")))
     282(import (prefix dbus dbus:) (chicken format))
     283
     284(define ctxt (dbus:make-context
     285        service: 'test.method.server
     286        interface: 'test.method.Type
     287        path: '/test/method/Object))
     288
     289(define remote-method (dbus:make-method-proxy ctxt "Method"))
     290
     291(let ([response (remote-method "query"
     292                "What is the meaning of life, the universe and everything?") ])
     293
     294        (printf "sent a very important query with a known answer; got flippant response ~s~%" response)
     295        (if (and (list? response) (eq? 42 (cadr response)))
     296                (printf "bingo!~%")
     297                (printf "and the answer is wrong too!  Bad supercomputer, bad!~%")))
    294298</enscript>
    295299
Note: See TracChangeset for help on using the changeset viewer.