Skip to content

Commit 467e495

Browse files
Merge pull request #83 from clintharrison/clint/add-lipc-info
Add some more details about how LIPC works
2 parents 0fbef13 + f85597d commit 467e495

2 files changed

Lines changed: 115 additions & 3 deletions

File tree

content/kindle-apps-and-services/_index.md

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ weight: 100
55
---
66

77
# Kindle Apps & Services
8-
The Kindle has many apps/services which communicated via `LIPC`, which is similar to `dbus` in many respsects.
8+
The Kindle has many apps/services which communicate via `LIPC`, a custom IPC system based on DBus.
99

1010
<blockquote class="info">
1111
LIPC values are wrapped in square brackets (`[]`), these should be excluded when writing to a LIPC entry
@@ -43,4 +43,97 @@ Then, you can use `ps -p <pid>` to get the name of the process, or use `ps u -p
4343
The following list was obtained via the following command run on the Kindle:
4444
~~~bash
4545
lipc-probe -a -v
46-
~~~
46+
~~~
47+
48+
## Integrating with LIPC
49+
50+
For simple uses, it's easiest to run `lipc-get-prop` and `lipc-set-prop` as a subprocess.
51+
52+
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](https://github.com/notmarek/openlipc), or a Lua wrapper, [openlipclua](https://github.com/NiLuJe/openlipclua).
53+
54+
## Implementation details
55+
56+
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).
57+
58+
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.
59+
60+
### LIPC events
61+
62+
An LIPC event has a source service, an event name, and an optional list of int/string parameters.
63+
64+
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.
65+
66+
Events can have `int32` or `string` DBus types as the payload.
67+
68+
### LIPC properties
69+
70+
LIPC properties are DBus method calls. Similar to events, they use `/default` as the path, and `interface.member` for the name.
71+
72+
#### Method calls: get and set
73+
74+
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`.
75+
Hash property access is always considered a `set` and has the suffix `Has`.
76+
77+
String and int properties pass the new value directly as a normal DBus parameter.
78+
79+
Hash properties are more complex, and they haven't been fully reverse engineered. They're based on DBus and shared memory, which contains [GLib `GHashTable`s](https://www.manpagez.com/html/glib/glib-2.42.1/glib-Hash-Tables.php#g-hash-table-new-full) (as well as mutexes and other metadata).
80+
81+
The final DBus method parameter is the optional _sender_ name.
82+
83+
#### Return values
84+
85+
All `get` and `set` property access has at least one return value: a `uint32` status.
86+
87+
`get` calls will additionally include a `string` or `int32` DBus value containing the property value, or an optional `uint32` pointer for hasharray access.
88+
89+
### Examples from `dbus-monitor`
90+
91+
`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.
92+
93+
{{< details summary="Allowing `dbus-monitor` to see method calls" >}}
94+
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.
95+
96+
The Kindle comes with a `/etc/dbus-1/system-local.conf` config file: you can [add "eavesdrop" permissions](https://wiki.ubuntu.com/DebuggingDBus#How_to_monitor_the_system_bus) to show method calls too. Keeping the existing content and updating according to the linked documentation should give something like this:
97+
98+
```xml
99+
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
100+
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
101+
<busconfig>
102+
<!-- Our well-known bus type, do not change this -->
103+
<type>system</type>
104+
<standard_system_servicedirs/>
105+
106+
<policy user="root">
107+
<allow eavesdrop="true"/>
108+
<allow eavesdrop="true" send_destination="*"/>
109+
</policy>
110+
</busconfig>
111+
```
112+
113+
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.
114+
{{< /details >}}
115+
116+
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`).
117+
118+
~~~plaintext
119+
method call sender=:1.179 -> dest=com.lab126.powerd serial=1498 path=/default; interface=com.lab126.powerd; member=getflIntensityInt
120+
string "com.lab126.kppsettings"
121+
method return sender=:1.5 -> dest=:1.179 reply_serial=1498
122+
uint32 0
123+
int32 10
124+
~~~
125+
126+
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.
127+
~~~plaintext
128+
signal sender=:1.21 -> dest=(null destination) serial=4453 path=/default; interface=com.lab126.cmd; member=connectionAvailable
129+
string "wifi"
130+
string "internet"
131+
~~~
132+
133+
Hasharray properties don't show anything useful; their only data is a pointer:
134+
~~~plaintext
135+
method call sender=:1.8 -> dest=com.lab126.readingstreams serial=1029 path=/default; interface=com.lab126.readingstreams; member=setshowContextHas
136+
uint32 0
137+
uint32 1478258684
138+
string "com.lab126.appmgrd"
139+
~~~

static/assets/css/global.css

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,25 @@ a:hover {
145145
margin: 0px auto;
146146
}
147147

148+
.mainContent details
149+
{
150+
border-radius: 3px;
151+
background-color: var(--background-accent);
152+
padding: 1em;
153+
}
154+
155+
.mainContent details p:last-child
156+
{
157+
/* Inside a collapsible details element, the default margin on a final paragraph looks bad :( */
158+
margin-bottom: 0;
159+
}
160+
161+
.mainContent details:open summary {
162+
padding-bottom: 0.5em;
163+
border-bottom: solid 3px var(--background-second-accent);
164+
margin-bottom: 1em;
165+
}
166+
148167
.navbar
149168
{
150169
position: sticky;
@@ -269,7 +288,7 @@ code
269288
font-family: 'Courier New', Courier, monospace;
270289
}
271290

272-
pre.highlight
291+
.highlight pre
273292
{
274293
padding: 1em;
275294
}

0 commit comments

Comments
 (0)