Kindle Apps & Services
The Kindle has many apps/services which communicate via LIPC, a custom IPC system based on DBus.
LIPC values are wrapped in square brackets (
[]), these should be excluded when writing to a LIPC entry
This entire section is a
WIPand isincomplete
How to use
LIPC can be interacted with through the command line as so:
lipc-set-prop <name> <property> <value> # Set a property value
lipc-set-prop com.lab126.powerd preventScreenSaver 1 # Disable screensaver
lipc-set-prop com.lab126.appmgrd start app://com.lab126.booklet.home # Open the home "app"
lipc-get-prop <name> <property> # Get a property value
lipc-get-prop com.lab126.btfd isBtchRunning # Check if BTch is running
Identifying what process owns a service
To get the pid of the process that owns/registered a service, the following command can be used (where <name> is the name of the service, such as com.lab126.btService):
dbus-send --system --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.GetConnectionUnixProcessID string:<name> # Longer Command
gdbus call -y -d org.freedesktop.DBus -o / -m org.freedesktop.DBus.GetConnectionUnixProcessID <name> # Slightly Shorter Command
Then, you can use ps -p <pid> to get the name of the process, or use ps u -p <pid> to get the full process command line.
List of apps/services
The following list was obtained via the following command run on the Kindle:
lipc-probe -a -v
Integrating with LIPC
For simple uses, it’s easiest to run lipc-get-prop and lipc-set-prop as a subprocess.
If you need read/write access to hash properties and events, it may be easier to link with liblipc.so and use the reverse-engineered headers in openlipc, or a Lua wrapper, openlipclua.
Implementation details
DBus is built upon methods, which can have parameters and return values, and signals, which are broadcasts (with optional extra data, but no return values).
LIPC’s fundamental objects are properties and events, which are built upon those DBus concepts. All LIPC operations happen on DBus’s system bus. Just like DBus connections can request a specific name with dbus_bus_request_name, this can be done for a connection to request an LIPC service name.
LIPC events
An LIPC event has a source service, an event name, and an optional list of int/string parameters.
LIPC events are identical to DBus signals with a specific format. The path is always /default and the name set to interface.member, where interface is the LIPC service name and member is the LIPC event name.
Events can have int32 or string DBus types as the payload.
LIPC properties
LIPC properties are DBus method calls. Similar to events, they use /default as the path, and interface.member for the name.
Method calls: get and set
Member names depend on the type of the property and whether the request is read or write: the word get or set, followed by the property name, and suffixed with Int or Str.
Hash property access is always considered a set and has the suffix Has.
String and int properties pass the new value directly as a normal DBus parameter.
Hash properties are more complex, and they haven’t been fully reverse engineered. They’re based on DBus and shared memory, which contains GLib GHashTables (as well as mutexes and other metadata).
The final DBus method parameter is the optional sender name.
Return values
All get and set property access has at least one return value: a uint32 status.
get calls will additionally include a string or int32 DBus value containing the property value, or an optional uint32 pointer for hasharray access.
Examples from dbus-monitor
dbus-monitor ships in the Kindle firmware on production devices. It can be used to monitor the DBus system bus; in other words, it can be used to watch LIPC events and see when properties are accessed or modified.
Allowing dbus-monitor to see method calls
By default, DBus permissions only allow dbus-monitor --system to see events (and not method calls). This can be modified, but this is dangerous, as you’re modifying a core component of the Kindle OS.
The Kindle comes with a /etc/dbus-1/system-local.conf config file: you can add “eavesdrop” permissions to show method calls too. Keeping the existing content and updating according to the linked documentation should give something like this:
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Our well-known bus type, do not change this -->
<type>system</type>
<standard_system_servicedirs/>
<policy user="root">
<allow eavesdrop="true"/>
<allow eavesdrop="true" send_destination="*"/>
</policy>
</busconfig>
Ensure the written file is valid XML, and restart the Kindle to apply the change. At this point, dbus-monitor --system should show method calls in addition to signals.
This is an example from dbus-monitor showing an int property being read: the quick settings panel reading the current screen brightness. (Note the get prefix and Int suffix.) The return value has a zero status (success) and the value 10. This method has no parameters other than the optional sender name (com.lab126.kppsettings).
method call sender=:1.179 -> dest=com.lab126.powerd serial=1498 path=/default; interface=com.lab126.powerd; member=getflIntensityInt
string "com.lab126.kppsettings"
method return sender=:1.5 -> dest=:1.179 reply_serial=1498
uint32 0
int32 10
This LIPC event connectionAvailable was sent by com.lab126.cmd to notify listeners the Kindle has a WiFi connection, and that connection can reach the internet.
signal sender=:1.21 -> dest=(null destination) serial=4453 path=/default; interface=com.lab126.cmd; member=connectionAvailable
string "wifi"
string "internet"
Hasharray properties don’t show anything useful; their only data is a pointer:
method call sender=:1.8 -> dest=com.lab126.readingstreams serial=1029 path=/default; interface=com.lab126.readingstreams; member=setshowContextHas
uint32 0
uint32 1478258684
string "com.lab126.appmgrd"