User:Magick777/Adventures with D-Bus
(→Step 1: dbus-monitor) |
|||
(15 intermediate revisions not shown) | |||
Line 1: | Line 1: | ||
- | This page started because I'm trying to figure out D- | + | This page started because I'm trying to figure out D-Bus, as a relative newbie to Python and Telepathy, and the documentation is, shall we say, "fragmented". All the D-Bus recipes on the Wiki don't seem to include a simple way to place a call via the sofiasip client. The Telepathy documentation speaks to a vague architecture, not to my [[Nokia N900|N900]]'s implementation of it, and seems better for someone who wants to write a whole new interface than someone who just wants to use an existing one. I've read more source code and more forum posts than you can shake a stick at and I'm still none the wiser. So, this is a generic HOWTO for newbies (written by one) on how to track down an existing application's behaviour on D-Bus and replicate it. Work in progress September 2010. |
- | + | ||
- | So, this is a generic HOWTO for newbies (written by one) on how to track down an existing application's behaviour on D- | + | |
== Step 1: dbus-monitor == | == Step 1: dbus-monitor == | ||
- | After some playing around with dbus-monitor, I've established that when I make a SIP call via the inbuilt Phone application, the first thing that happens on the session bus is: | + | After some playing around with <code>dbus-monitor</code>, I've established that when I make a SIP call via the inbuilt Phone application, the first thing that happens on the session bus is: |
- | + | <pre> | |
- | + | method call sender=:1.121 -> | |
- | + | dest=org.freedesktop.Telepathy.AccountManager | |
- | + | serial=439 | |
- | + | path=/org/freedesktop/Telepathy/Account/sofiasip/sip/_31030137_40sipgate_2eco_2euk0; | |
- | + | interface=com.nokia.Account.Interface.ChannelRequests; | |
- | + | member=Create | |
- | + | array [ | |
- | + | dict entry( | |
- | + | string "org.freedesktop.Telepathy.Channel.TargetHandleType" | |
- | + | variant uint32 1 | |
- | + | ) | |
- | + | dict entry( | |
- | + | string "org.freedesktop.Telepathy.Channel.TargetID" | |
- | + | variant string "sip:50000@sipgate.co.uk" | |
- | + | ) | |
- | + | dict entry( | |
- | + | string "org.freedesktop.Telepathy.Channel.ChannelType" | |
- | + | variant string "org.freedesktop.Telepathy.Channel.Type.StreamedMedia" | |
- | + | ) | |
- | + | ] | |
- | + | uint64 14701758 | |
+ | string "" | ||
+ | </pre> | ||
and, for a call to a PSTN number, via a different SIP account: | and, for a call to a PSTN number, via a different SIP account: | ||
- | + | <pre> | |
- | + | method call sender=:1.191 -> | |
- | + | dest=org.freedesktop.Telepathy.AccountManager | |
- | + | serial=500 | |
- | + | path=/org/freedesktop/Telepathy/Account/sofiasip/sip/_330147398_40sip_2evoipfone_2eco_2euk0; | |
- | + | interface=com.nokia.Account.Interface.ChannelRequests; | |
- | + | member=Create | |
- | + | array [ | |
- | + | dict entry( | |
- | + | string "org.freedesktop.Telepathy.Channel.TargetHandleType" | |
- | + | variant uint32 1 | |
- | + | ) | |
- | + | dict entry( | |
- | + | string "org.freedesktop.Telepathy.Channel.ChannelType" | |
- | + | variant string "org.freedesktop.Telepathy.Channel.Type.StreamedMedia" | |
- | + | ) | |
- | + | dict entry( | |
- | + | string "org.freedesktop.Telepathy.Channel.TargetID" | |
- | + | variant string "08081703703" | |
- | + | ) | |
- | + | ] | |
- | + | uint64 1284595510 | |
+ | string "" | ||
+ | </pre> | ||
From this, we can deduce that: | From this, we can deduce that: | ||
- | + | * we need to make a method call over D-Bus to initiate the SIP call | |
- | + | * we need to send it to <code>org.freedesktop.Telepathy.AccountManager</code> | |
- | + | * our path is <code>/org/freedesktop/Telepathy/Account/</code> plus SofiaSIP account path | |
- | + | ** which can be found via "mc-tool list" (package libmissioncontrol-utils) | |
- | + | ** or, no doubt, via D-Bus, but we'll worry about that later | |
- | + | * our interface is <code>com.nokia.Account.Interface.ChannelRequests</code> | |
- | + | * the action we must take on that interface is to Create (a new channel) | |
- | + | * for which we must supply an array of dicts, a number and an empty string | |
- | + | ** TargetHandleType is 1 | |
- | + | ** ChannelType is StreamedMedia | |
+ | ** Target ID contains our destination SIP address or phone number | ||
+ | ** not sure what that <code>uint64</code> is about, some kind of timestamp? | ||
+ | |||
+ | and we can hope that, if we can pack up that set of instructions and deliver it to telepathy-sofiasip, it will (hopefully) place a call for us. | ||
+ | |||
+ | == Step 2: dbus-send (actually, a false step) == | ||
+ | |||
+ | I spent a while playing with dbus-send and reading the forums, until a thread led me to the following statement in the (fine) manual page: | ||
+ | |||
+ | '''"dbus-send does not permit empty containers or nested containers (e.g. arrays of variants)"''' | ||
+ | |||
+ | We can assume that <code>dbus-send</code> isn't going to like an array of dicts any more than it likes an array of variants, ergo, that what we want to do cannot be done with <code>dbus-send</code>. That would explain why there's no simple recipe on the Wiki, then. Well, if we can't use <code>dbus-send</code>, I guess we'll have to resort to Python. That's going to be fun; I'm not in the habit of conversing with reptiles. | ||
+ | |||
+ | == Step 3: python == | ||
+ | |||
+ | The only example I could find of a shell script making a D-Bus method call is the "athome" script on the [[DbusScripts]] page, which in theory should act as a starting point for what I want to do. | ||
+ | |||
+ | <source lang="python"> | ||
+ | #!/usr/bin/python | ||
+ | |||
+ | import dbus | ||
+ | import sys | ||
+ | import re | ||
+ | import telepathy | ||
+ | |||
+ | # This gets us a connnection to the session bus | ||
+ | bus = dbus.SessionBus() | ||
+ | |||
+ | # This would seem to set up a proxy object, referring to our target SIP account | ||
+ | account = bus.get_object('org.freedesktop.Telepathy.AccountManager', | ||
+ | '/org/freedesktop/Telepathy/Account/sofiasip/sip/_309517129090') | ||
+ | |||
+ | # This would seem to make a method call on the object | ||
+ | #account.Set('org.freedesktop.Telepathy.Account', 'RequestedPresence', \ | ||
+ | # dbus.Struct(( dbus.UInt32( presence_const) , presence_text, ""), signature='uss'), | ||
+ | # dbus_interface='org.freedesktop.DBus.Properties') | ||
+ | |||
+ | # We need to make a method call to Create a new channel | ||
+ | |||
+ | account.Set('org.freedesktop.Telepathy.Account', 'RequestedPresence', \ | ||
+ | dbus.Struct(( dbus.UInt32( presence_const) , presence_text, ""), signature='uss'), | ||
+ | dbus_interface='org.freedesktop.DBus.Properties') | ||
+ | </source> | ||
+ | |||
+ | [[Category:Python]] |
Latest revision as of 16:13, 12 May 2013
This page started because I'm trying to figure out D-Bus, as a relative newbie to Python and Telepathy, and the documentation is, shall we say, "fragmented". All the D-Bus recipes on the Wiki don't seem to include a simple way to place a call via the sofiasip client. The Telepathy documentation speaks to a vague architecture, not to my N900's implementation of it, and seems better for someone who wants to write a whole new interface than someone who just wants to use an existing one. I've read more source code and more forum posts than you can shake a stick at and I'm still none the wiser. So, this is a generic HOWTO for newbies (written by one) on how to track down an existing application's behaviour on D-Bus and replicate it. Work in progress September 2010.
[edit] Step 1: dbus-monitor
After some playing around with dbus-monitor
, I've established that when I make a SIP call via the inbuilt Phone application, the first thing that happens on the session bus is:
method call sender=:1.121 -> dest=org.freedesktop.Telepathy.AccountManager serial=439 path=/org/freedesktop/Telepathy/Account/sofiasip/sip/_31030137_40sipgate_2eco_2euk0; interface=com.nokia.Account.Interface.ChannelRequests; member=Create array [ dict entry( string "org.freedesktop.Telepathy.Channel.TargetHandleType" variant uint32 1 ) dict entry( string "org.freedesktop.Telepathy.Channel.TargetID" variant string "sip:50000@sipgate.co.uk" ) dict entry( string "org.freedesktop.Telepathy.Channel.ChannelType" variant string "org.freedesktop.Telepathy.Channel.Type.StreamedMedia" ) ] uint64 14701758 string ""
and, for a call to a PSTN number, via a different SIP account:
method call sender=:1.191 -> dest=org.freedesktop.Telepathy.AccountManager serial=500 path=/org/freedesktop/Telepathy/Account/sofiasip/sip/_330147398_40sip_2evoipfone_2eco_2euk0; interface=com.nokia.Account.Interface.ChannelRequests; member=Create array [ dict entry( string "org.freedesktop.Telepathy.Channel.TargetHandleType" variant uint32 1 ) dict entry( string "org.freedesktop.Telepathy.Channel.ChannelType" variant string "org.freedesktop.Telepathy.Channel.Type.StreamedMedia" ) dict entry( string "org.freedesktop.Telepathy.Channel.TargetID" variant string "08081703703" ) ] uint64 1284595510 string ""
From this, we can deduce that:
- we need to make a method call over D-Bus to initiate the SIP call
- we need to send it to
org.freedesktop.Telepathy.AccountManager
- our path is
/org/freedesktop/Telepathy/Account/
plus SofiaSIP account path- which can be found via "mc-tool list" (package libmissioncontrol-utils)
- or, no doubt, via D-Bus, but we'll worry about that later
- our interface is
com.nokia.Account.Interface.ChannelRequests
- the action we must take on that interface is to Create (a new channel)
- for which we must supply an array of dicts, a number and an empty string
- TargetHandleType is 1
- ChannelType is StreamedMedia
- Target ID contains our destination SIP address or phone number
- not sure what that
uint64
is about, some kind of timestamp?
and we can hope that, if we can pack up that set of instructions and deliver it to telepathy-sofiasip, it will (hopefully) place a call for us.
[edit] Step 2: dbus-send (actually, a false step)
I spent a while playing with dbus-send and reading the forums, until a thread led me to the following statement in the (fine) manual page:
"dbus-send does not permit empty containers or nested containers (e.g. arrays of variants)"
We can assume that dbus-send
isn't going to like an array of dicts any more than it likes an array of variants, ergo, that what we want to do cannot be done with dbus-send
. That would explain why there's no simple recipe on the Wiki, then. Well, if we can't use dbus-send
, I guess we'll have to resort to Python. That's going to be fun; I'm not in the habit of conversing with reptiles.
[edit] Step 3: python
The only example I could find of a shell script making a D-Bus method call is the "athome" script on the DbusScripts page, which in theory should act as a starting point for what I want to do.
#!/usr/bin/python import dbus import sys import re import telepathy # This gets us a connnection to the session bus bus = dbus.SessionBus() # This would seem to set up a proxy object, referring to our target SIP account account = bus.get_object('org.freedesktop.Telepathy.AccountManager', '/org/freedesktop/Telepathy/Account/sofiasip/sip/_309517129090') # This would seem to make a method call on the object #account.Set('org.freedesktop.Telepathy.Account', 'RequestedPresence', \ # dbus.Struct(( dbus.UInt32( presence_const) , presence_text, ""), signature='uss'), # dbus_interface='org.freedesktop.DBus.Properties') # We need to make a method call to Create a new channel account.Set('org.freedesktop.Telepathy.Account', 'RequestedPresence', \ dbus.Struct(( dbus.UInt32( presence_const) , presence_text, ""), signature='uss'), dbus_interface='org.freedesktop.DBus.Properties')
- This page was last modified on 12 May 2013, at 16:13.
- This page has been accessed 13,179 times.