Controlling the Raspberry Pi with Android via the WebSocket protocol

Phase 2

The code initializes the D-Bus system bus during phase 2. The D-Bus helps the server send asynchronous messages to connected clients. The bus functions independently of WebSocket communication. Initialization starts when the program calls the g_bus_get_sync() function of the GLib library and connects itself according to lines 16 through 21 of Listing 4 with the selected system bus.

Listing 4

WebSocketsServer.c (Phase 2)

01 [...]
02 g_dbus_connection_signal_subscribe (connection,
03                                     "org.freedesktop.UDisks",
04                                     NULL,
05                                     "DeviceAdded",
06                                     NULL,
07                                     NULL,
08                                     G_DBUS_SIGNAL_FLAGS_NONE,
09                                     dbus_notification_callback,
10                                     NULL,
11                                     NULL);
12 [...]
13
14 GDBusConnection *connection = NULL;
15
16 connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
17 if (connection == NULL)
18   {
19     printf ("Can't connect to system bus: %s\n", error->message);
20     g_error_free (error);
21   }
22 [...]

If initialization succeeds, then the program subscribes to messages about system events that involve the D-Bus, such as the connection of a USB stick to the corresponding USB port, as shown in Figure 4. This requires that the program first inform the daemon that administers the D-Bus regarding the type of system events it wants to know about.

The server side of the WebSocket application implements the process technically described as "subscription" via the g_dbus_connection_signal_subscribe() function, as shown in lines 2 through 11 in Listing 4. The function makes the GLib library available at the same time. The subscription in this sample project will react at this point to a DeviceAdded signal sent by udisks as soon as a USB stick is plugged into the Raspberry Pi.

D-Bus takes care of interprocess communication (IPC) [8] in most Linux distros. The developer first has to analyze the data that is returned by the dbus-monitor tool so that the program also registers the correct signal via the g_dbus_connection_signal_subscribe() function. A list of all signals sent across the D-Bus is displayed on the Raspberry Pi via:

dbus-monitor --system

The user looking to choose a mass storage device to connect to the USB port should definitely look at the information that udisks outputs (Listing 5).

Listing 5

Excerpt of D-Bus Output

01 [...]
02 signal sender=:1.6 -> dest=(null destination) serial=81 path=/org/freedesktop/UDisks; interface=org.freedesktop.UDisks; member=DeviceAdded
03    object path "/org/freedesktop/UDisks/devices/sda"
04 signal sender=:1.6 -> dest=(null destination) serial=83 path=/org/freedesktop/UDisks; interface=org.freedesktop.UDisks; member=DeviceAdded
05    object path "/org/freedesktop/UDisks/devices/sda1"
06 [...]

The interface name according to the D-bus project nomenclature for the udisks tool is org.freedesktop.UDisks. The signal name is DeviceAdded. The server function g_dbus_connection_signal_subscribe() needs this information to identify the USB plug-in events unambiguously.

The function from line 2 in Listing 4 also has to know the name of the callback function that it should trigger when it recognizes the DeviceAdded signal. The name is dbus_notification_callback().

Main Loop

The program now concludes the initialization and subscription phases and establishes two callbacks. These are my_callback() and dbus_notification_callback(). The callback functions help pass certain events via the D-Bus to mobile devices.

The while loop shown in Listing 6 waits for pending events. Its primary task is to keep an eye on the libwebsocket_service() function. The loop also accepts connections and triggers the previously defined callback function when the server receives data from clients. Once this happens, the g_main_context_iteration() function (line 11) goes into action. It iterates once over the GLib main loop to test whether D-Bus messages are pending.

Listing 6

while() Loop

01 [...]
02 while (cnt >= 0 && !exit_loop) {
03
04   cnt = libwebsocket_service (context, 10);
05
06   if (send_notification) {
07     libwebsocket_callback_on_writable_all_protocol (&protocols[0]);
08     send_notification = FALSE;
09   }
10
11   g_main_context_iteration (NULL, FALSE);
12 }
13 [...]

As a result, if a user connects a USB stick to the Raspberry Pi, the D-Bus generates the DeviceAdded signal, after which the dbus_notification_callback() function sets the send_notification flag, which in turn calls libwebsocket_callback_on_writable_all_protocol() into play. The function triggers the previously defined callback functionmy_callback() that now sends broadcast messages to all connected clients.

Buy this article as PDF

Express-Checkout as PDF

Pages: 8

Price $2.95
(incl. VAT)

Buy Raspberry Pi Geek

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content