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.
« Previous 1 2 3 4 Next »
Buy this article as PDF
Pages: 8
(incl. VAT)