Commit 536e0e4f authored by spiiroin's avatar spiiroin

[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: spiiroin's avatarSimo Piiroinen <simo.piiroinen@jollamobile.com>
parent 43c89f3b
......@@ -97,6 +97,7 @@ PKG_CHECK_MODULES([USB_MODED], [
gio-2.0
libudev
libkmod
ssu-sysinfo
])
AC_SUBST(USB_MODED_LIBS)
......
......@@ -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
......
......@@ -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().
*
......@@ -152,10 +66,15 @@ EXIT:
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().
*
......@@ -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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment