Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[ssu] Use ssusysinfo instead of SSU D-Bus interface
During bootup usb-moded needs device name / model information before
the system has reached a point where SSU daemon can be started. This
can cause systemd deadlocks and/or timeouts as usb-moded waits for SSU
daemon and the rest of the bootup is blocked until usb-moded reaches
ready state.

Use ssu-sysinfo C-library that can provide the device details required
by usb-moded without using any IPC mechanisms.

Signed-off-by: Simo Piiroinen <simo.piiroinen@jollamobile.com>
  • Loading branch information
spiiroin committed Dec 7, 2016
1 parent 43c89f3 commit 536e0e4
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 113 deletions.
1 change: 1 addition & 0 deletions configure.ac
Expand Up @@ -97,6 +97,7 @@ PKG_CHECK_MODULES([USB_MODED], [
gio-2.0
libudev
libkmod
ssu-sysinfo
])

AC_SUBST(USB_MODED_LIBS)
Expand Down
1 change: 1 addition & 0 deletions rpm/usb-moded.spec
Expand Up @@ -15,6 +15,7 @@ BuildRequires: pkgconfig(udev)
BuildRequires: pkgconfig(libkmod)
BuildRequires: doxygen
BuildRequires: pkgconfig(libsystemd-daemon)
BuildRequires: pkgconfig(ssu-sysinfo)

Requires: lsof
Requires: usb-moded-configs
Expand Down
150 changes: 37 additions & 113 deletions src/usb_moded-ssu.c
Expand Up @@ -21,129 +21,43 @@
*/

#include <glib.h>

#include <dbus/dbus.h>

#include <ssusysinfo.h>
#include "usb_moded-ssu.h"
#include "usb_moded-log.h"
#include "usb_moded-dbus-private.h"

/** SSU D-Bus service name */
#define SSU_DBUS_SERVICE "org.nemo.ssu"

/** Default SSU D-Bus object path */
#define SSU_DBUS_OBJECT "/org/nemo/ssu"
/** Cached ssu-sysinfo handle */
static ssusysinfo_t *ssu_instance = 0;

/** SSU D-Bus interface */
#define SSU_DBUS_INTERFACE "org.nemo.ssu"
/** Flag for ssu-sysinfo instance has been initialized */
static gboolean ssu_intialized = FALSE;

/** SSU displayName D-Bus method call */
#define SSU_DBUS_GET_DISPLAY_NAME "displayName"

/** SsuDisplayType enum adapted from ssu c++ headers */
typedef enum
/** Atexit callback for releasing cached ssu-sysinfo handle */
static void ssu_free_handle(void)
{
/** Manufacturer, like ACME Corp.
* Board mappings key "deviceManufacturer" */
SsuDeviceManufacturer = 0,

/** Marketed device name, like Pogoblaster 3000.
* Board mappings key "prettyModel" */
SsuDeviceModel = 1,
/* Make sure instance does not get created on exit path */
ssu_intialized = TRUE;

/** Type designation, like NCC-1701.
* Beard mappings key "deviceDesignation" */
SsuDeviceDesignation = 2,
} SsuDisplayType;
/* Release existing instance */
ssusysinfo_delete(ssu_instance),
ssu_instance = 0;
}

/** Wrapper for making synchronous org.nemo.ssu.displayName() method calls
/** Helper for obtaining ssu-sysinfo handle on demand
*
* Caller must release non-null return value with g_free().
*
* @param type_id display name type to query
*
* @return human readable string, or NULL in case of errors
* @return ssu-sysinfo, or NULL in case of errors
*/
static gchar *
usb_moded_get_ssu_display_name(SsuDisplayType type_id)
static ssusysinfo_t *ssu_get_handle(void)
{
gchar *res = 0;
DBusConnection *con = 0;
DBusMessage *req = 0;
DBusMessage *rsp = 0;
dbus_int32_t arg = type_id;
const char *val = 0;
DBusError err = DBUS_ERROR_INIT;

if( !(con = usb_moded_dbus_get_connection()) ) {
log_err("not connected to system bus");
goto EXIT;
}

req = dbus_message_new_method_call(SSU_DBUS_SERVICE,
SSU_DBUS_OBJECT,
SSU_DBUS_INTERFACE,
SSU_DBUS_GET_DISPLAY_NAME);

if( !req ) {
log_err("could not create method call message");
goto EXIT;
}

if( !dbus_message_append_args(req,
DBUS_TYPE_INT32, &arg,
DBUS_TYPE_INVALID) ) {
log_err("could not add method call parameters");
goto EXIT;
}

rsp = dbus_connection_send_with_reply_and_block(con, req, -1, &err);
if( !rsp ) {
/* Be less verbose with failures that are expected
* if ssu service is not installed on the device. */
if( !strcmp(err.name, DBUS_ERROR_SERVICE_UNKNOWN) ) {
log_debug("%s D-Bus service is not available",
SSU_DBUS_SERVICE);
}
else {
log_err("did not get reply: %s: %s",
err.name, err.message);
}
goto EXIT;
}

if( dbus_set_error_from_message(&err, rsp) ) {
log_err("got error reply: %s: %s", err.name, err.message);
goto EXIT;
}

if( !dbus_message_get_args(rsp, &err,
DBUS_TYPE_STRING, &val,
DBUS_TYPE_INVALID) ) {
log_err("could not parse reply: %s: %s",
err.name, err.message);
goto EXIT;
}

res = g_strdup(val);

EXIT:

dbus_error_free(&err);

if( rsp )
dbus_message_unref(rsp);
if( req )
dbus_message_unref(req);
if( con )
dbus_connection_unref(con);

log_debug("ssu displayName(%d) -> %s", type_id, res ?: "N/A");

return res;
/* Attempt only once */
if( !ssu_intialized ) {
ssu_intialized = TRUE;
ssu_instance = ssusysinfo_create();
atexit(ssu_free_handle);
}
return ssu_instance;
}

/** Query device manufacturer name from the SSU D-Bus service
/** Read device manufacturer name from the SSU configuration
*
* Caller must release non-null return value with g_free().
*
Expand All @@ -152,10 +66,15 @@ usb_moded_get_ssu_display_name(SsuDisplayType type_id)
gchar *
ssu_get_manufacturer_name(void)
{
return usb_moded_get_ssu_display_name(SsuDeviceManufacturer);
gchar *res = 0;
const char *val = ssusysinfo_device_manufacturer(ssu_get_handle());
if( val && strcmp(val, "UNKNOWN") )
res = g_strdup(val);
log_debug("%s() -> %s", __FUNCTION__, res ?: "N/A");
return res;
}

/** Query device model name from the SSU D-Bus service
/** Read device model name from the SSU configuration
*
* Caller must release non-null return value with g_free().
*
Expand All @@ -164,5 +83,10 @@ ssu_get_manufacturer_name(void)
gchar *
ssu_get_product_name(void)
{
return usb_moded_get_ssu_display_name(SsuDeviceModel);
gchar *res = 0;
const char *val = ssusysinfo_device_pretty_name(ssu_get_handle());
if( val && strcmp(val, "UNKNOWN") )
res = g_strdup(val);
log_debug("%s() -> %s", __FUNCTION__, res ?: "N/A");
return res;
}

0 comments on commit 536e0e4

Please sign in to comment.