mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-13 17:23:20 +00:00
Flesh out the provider interface and allow offline updates
This commit is contained in:
parent
8dbfb1c478
commit
8bbfdf49a8
@ -1,3 +1,4 @@
|
||||
policy/org.freedesktop.fwupd.policy.in
|
||||
src/fu-debug.c
|
||||
src/fu-main.c
|
||||
src/fu-util.c
|
||||
|
@ -57,8 +57,12 @@ libexec_PROGRAMS = \
|
||||
fwupd_SOURCES = \
|
||||
fu-cleanup.h \
|
||||
fu-common.h \
|
||||
fu-debug.c \
|
||||
fu-debug.h \
|
||||
fu-device.c \
|
||||
fu-device.h \
|
||||
fu-provider.c \
|
||||
fu-provider.h \
|
||||
fu-provider-uefi.c \
|
||||
fu-provider-uefi.h \
|
||||
fu-resources.c \
|
||||
|
@ -26,4 +26,7 @@
|
||||
#define FWUPD_DBUS_SERVICE "org.freedesktop.fwupd"
|
||||
#define FWUPD_DBUS_INTERFACE "org.freedesktop.fwupd"
|
||||
|
||||
#define FU_ERROR 1
|
||||
#define FU_ERROR_INTERNAL 0
|
||||
|
||||
#endif /* __FU_COMMON_H */
|
||||
|
210
src/fu-debug.c
Normal file
210
src/fu-debug.c
Normal file
@ -0,0 +1,210 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2010-2015 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* Licensed under the GNU General Public License Version 2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <fu-debug.h>
|
||||
|
||||
static gboolean _verbose = FALSE;
|
||||
static gboolean _console = FALSE;
|
||||
|
||||
/**
|
||||
* fu_debug_is_verbose:
|
||||
**/
|
||||
gboolean
|
||||
fu_debug_is_verbose (void)
|
||||
{
|
||||
/* local first */
|
||||
if (_verbose)
|
||||
return TRUE;
|
||||
|
||||
/* fall back to env variable */
|
||||
if (g_getenv ("VERBOSE") != NULL)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fu_debug_ignore_cb:
|
||||
**/
|
||||
static void
|
||||
fu_debug_ignore_cb (const gchar *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const gchar *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
/* syslog */
|
||||
switch (log_level) {
|
||||
case G_LOG_LEVEL_INFO:
|
||||
g_print ("%s\n", message);
|
||||
case G_LOG_LEVEL_CRITICAL:
|
||||
case G_LOG_LEVEL_ERROR:
|
||||
case G_LOG_LEVEL_WARNING:
|
||||
g_print ("%s\n", message);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_debug_handler_cb:
|
||||
**/
|
||||
static void
|
||||
fu_debug_handler_cb (const gchar *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const gchar *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
gchar str_time[255];
|
||||
time_t the_time;
|
||||
|
||||
/* syslog */
|
||||
switch (log_level) {
|
||||
case G_LOG_LEVEL_INFO:
|
||||
g_print ("%s\n", message);
|
||||
case G_LOG_LEVEL_CRITICAL:
|
||||
case G_LOG_LEVEL_ERROR:
|
||||
case G_LOG_LEVEL_WARNING:
|
||||
g_print ("%s\n", message);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* time header */
|
||||
time (&the_time);
|
||||
strftime (str_time, 254, "%H:%M:%S", localtime (&the_time));
|
||||
|
||||
/* no color please, we're British */
|
||||
if (!_console) {
|
||||
if (log_level == G_LOG_LEVEL_DEBUG) {
|
||||
g_print ("%s\t%s\n",
|
||||
str_time, message);
|
||||
} else {
|
||||
g_print ("***\n%s\t%s\n***\n",
|
||||
str_time, message);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* critical is also in red */
|
||||
if (log_level == G_LOG_LEVEL_CRITICAL ||
|
||||
log_level == G_LOG_LEVEL_ERROR) {
|
||||
g_print ("%c[%dm%s\t", 0x1B, 32, str_time);
|
||||
g_print ("%c[%dm%s\n%c[%dm", 0x1B, 31, message, 0x1B, 0);
|
||||
} else {
|
||||
/* debug in blue */
|
||||
g_print ("%c[%dm%s\t", 0x1B, 32, str_time);
|
||||
g_print ("%c[%dm%s\n%c[%dm", 0x1B, 34, message, 0x1B, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_debug_pre_parse_hook:
|
||||
*/
|
||||
static gboolean
|
||||
fu_debug_pre_parse_hook (GOptionContext *context,
|
||||
GOptionGroup *group,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
const GOptionEntry main_entries[] = {
|
||||
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &_verbose,
|
||||
/* TRANSLATORS: turn on all debugging */
|
||||
N_("Show debugging information for all files"), NULL },
|
||||
{ NULL}
|
||||
};
|
||||
|
||||
/* add main entry */
|
||||
g_option_context_add_main_entries (context, main_entries, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_debug_destroy:
|
||||
*/
|
||||
void
|
||||
fu_debug_destroy (void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_debug_setup:
|
||||
*/
|
||||
void
|
||||
fu_debug_setup (gboolean enabled)
|
||||
{
|
||||
if (enabled) {
|
||||
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR |
|
||||
G_LOG_LEVEL_CRITICAL);
|
||||
g_log_set_handler (G_LOG_DOMAIN,
|
||||
G_LOG_LEVEL_ERROR |
|
||||
G_LOG_LEVEL_CRITICAL |
|
||||
G_LOG_LEVEL_DEBUG |
|
||||
G_LOG_LEVEL_WARNING,
|
||||
fu_debug_handler_cb, NULL);
|
||||
} else {
|
||||
/* hide all debugging */
|
||||
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
|
||||
fu_debug_ignore_cb, NULL);
|
||||
}
|
||||
|
||||
/* are we on an actual TTY? */
|
||||
_console = (isatty (fileno (stdout)) == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_debug_post_parse_hook:
|
||||
*/
|
||||
static gboolean
|
||||
fu_debug_post_parse_hook (GOptionContext *context,
|
||||
GOptionGroup *group,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
/* verbose? */
|
||||
fu_debug_setup (_verbose);
|
||||
g_debug ("Verbose debugging %s (on console %i)",
|
||||
_verbose ? "enabled" : "disabled", _console);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_debug_get_option_group:
|
||||
*/
|
||||
GOptionGroup *
|
||||
fu_debug_get_option_group (void)
|
||||
{
|
||||
GOptionGroup *group;
|
||||
group = g_option_group_new ("debug",
|
||||
_("Debugging Options"),
|
||||
_("Show debugging options"),
|
||||
NULL, NULL);
|
||||
g_option_group_set_parse_hooks (group,
|
||||
fu_debug_pre_parse_hook,
|
||||
fu_debug_post_parse_hook);
|
||||
return group;
|
||||
}
|
32
src/fu-debug.h
Normal file
32
src/fu-debug.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2010-2011 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* Licensed under the GNU General Public License Version 2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef __CD_DEBUG_H__
|
||||
#define __CD_DEBUG_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
gboolean fu_debug_is_verbose (void);
|
||||
GOptionGroup *fu_debug_get_option_group (void);
|
||||
void fu_debug_setup (gboolean enabled);
|
||||
void fu_debug_destroy (void);
|
||||
|
||||
#endif /* __CD_DEBUG_H__ */
|
116
src/fu-main.c
116
src/fu-main.c
@ -29,19 +29,17 @@
|
||||
|
||||
#include "fu-cleanup.h"
|
||||
#include "fu-common.h"
|
||||
#include "fu-debug.h"
|
||||
#include "fu-device.h"
|
||||
#include "fu-provider-uefi.h"
|
||||
#include "fu-resources.h"
|
||||
|
||||
#define FU_ERROR 1
|
||||
#define FU_ERROR_INTERNAL 0
|
||||
|
||||
typedef struct {
|
||||
GDBusConnection *connection;
|
||||
GDBusNodeInfo *introspection_daemon;
|
||||
GMainLoop *loop;
|
||||
GPtrArray *devices;
|
||||
FuProviderUefi *provider_uefi;
|
||||
GPtrArray *providers;
|
||||
} FuMainPrivate;
|
||||
|
||||
/**
|
||||
@ -62,6 +60,23 @@ fu_main_get_device_list_as_strv (FuMainPrivate *priv)
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_main_get_device_by_id:
|
||||
**/
|
||||
static FuDevice *
|
||||
fu_main_get_device_by_id (FuMainPrivate *priv, const gchar *id)
|
||||
{
|
||||
FuDevice *device_tmp;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < priv->devices->len; i++) {
|
||||
device_tmp = g_ptr_array_index (priv->devices, i);
|
||||
if (g_strcmp0 (fu_device_get_id (device_tmp), id) == 0)
|
||||
return device_tmp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_main_daemon_method_call:
|
||||
**/
|
||||
@ -74,6 +89,8 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
|
||||
FuMainPrivate *priv = (FuMainPrivate *) user_data;
|
||||
GVariant *val;
|
||||
|
||||
g_debug ("Called %s()", method_name);
|
||||
|
||||
/* return 'as' */
|
||||
if (g_strcmp0 (method_name, "GetDevices") == 0) {
|
||||
_cleanup_strv_free_ gchar **devices = NULL;
|
||||
@ -83,6 +100,55 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
|
||||
return;
|
||||
}
|
||||
|
||||
/* return '' */
|
||||
if (g_strcmp0 (method_name, "UpdateOffline") == 0) {
|
||||
GDBusMessage *message;
|
||||
GUnixFDList *fd_list;
|
||||
FuDevice *device;
|
||||
const gchar *id = NULL;
|
||||
gint32 fd_handle = 0;
|
||||
gint fd;
|
||||
_cleanup_error_free_ GError *error = NULL;
|
||||
|
||||
/* check the id exists */
|
||||
g_variant_get (parameters, "(&sh)", &id, &fd_handle);
|
||||
device = fu_main_get_device_by_id (priv, id);
|
||||
if (device == NULL) {
|
||||
g_dbus_method_invocation_return_error (invocation,
|
||||
FU_ERROR,
|
||||
FU_ERROR_INTERNAL,
|
||||
"no such ID %s",
|
||||
id);
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the fd */
|
||||
message = g_dbus_method_invocation_get_message (invocation);
|
||||
fd_list = g_dbus_message_get_unix_fd_list (message);
|
||||
if (fd_list == NULL || g_unix_fd_list_get_length (fd_list) != 1) {
|
||||
g_dbus_method_invocation_return_error (invocation,
|
||||
FU_ERROR,
|
||||
FU_ERROR_INTERNAL,
|
||||
"invalid handle");
|
||||
return;
|
||||
}
|
||||
fd = g_unix_fd_list_get (fd_list, fd_handle, &error);
|
||||
if (fd < 0) {
|
||||
g_dbus_method_invocation_return_gerror (invocation,
|
||||
error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: run the correct provider that can handle this */
|
||||
// if (!fu_provider_update_offline (provider, device, fd, &error)) {
|
||||
// g_dbus_method_invocation_return_gerror (invocation,
|
||||
// error);
|
||||
// return;
|
||||
// }
|
||||
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* we suck */
|
||||
g_dbus_method_invocation_return_error (invocation,
|
||||
FU_ERROR,
|
||||
@ -148,8 +214,16 @@ fu_main_on_name_acquired_cb (GDBusConnection *connection,
|
||||
gpointer user_data)
|
||||
{
|
||||
FuMainPrivate *priv = (FuMainPrivate *) user_data;
|
||||
fu_provider_uefi_coldplug (priv->provider_uefi);
|
||||
FuProvider *provider;
|
||||
guint i;
|
||||
|
||||
g_debug ("FuMain: acquired name: %s", name);
|
||||
for (i = 0; i < priv->providers->len; i++) {
|
||||
_cleanup_error_free_ GError *error = NULL;
|
||||
provider = g_ptr_array_index (priv->providers, i);
|
||||
if (!fu_provider_coldplug (FU_PROVIDER (provider), &error))
|
||||
g_warning ("Failed to coldplug: %s", error->message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -202,7 +276,7 @@ fu_main_load_introspection (const gchar *filename, GError **error)
|
||||
* cd_main_provider_device_added_cb:
|
||||
**/
|
||||
static void
|
||||
cd_main_provider_device_added_cb (FuProviderUefi *provider_uefi,
|
||||
cd_main_provider_device_added_cb (FuProvider *provider,
|
||||
FuDevice *device,
|
||||
gpointer user_data)
|
||||
{
|
||||
@ -214,7 +288,7 @@ cd_main_provider_device_added_cb (FuProviderUefi *provider_uefi,
|
||||
* cd_main_provider_device_removed_cb:
|
||||
**/
|
||||
static void
|
||||
cd_main_provider_device_removed_cb (FuProviderUefi *provider_uefi,
|
||||
cd_main_provider_device_removed_cb (FuProvider *provider,
|
||||
FuDevice *device,
|
||||
gpointer user_data)
|
||||
{
|
||||
@ -222,6 +296,21 @@ cd_main_provider_device_removed_cb (FuProviderUefi *provider_uefi,
|
||||
g_ptr_array_remove (priv->devices, g_object_ref (device));
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_main_add_provider:
|
||||
**/
|
||||
static void
|
||||
fu_main_add_provider (FuMainPrivate *priv, FuProvider *provider)
|
||||
{
|
||||
g_signal_connect (provider, "device-added",
|
||||
G_CALLBACK (cd_main_provider_device_added_cb),
|
||||
priv);
|
||||
g_signal_connect (provider, "device-removed",
|
||||
G_CALLBACK (cd_main_provider_device_removed_cb),
|
||||
priv);
|
||||
g_ptr_array_add (priv->providers, provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* main:
|
||||
**/
|
||||
@ -256,6 +345,7 @@ main (int argc, char *argv[])
|
||||
g_set_application_name (_("Firmware Update"));
|
||||
context = g_option_context_new (NULL);
|
||||
g_option_context_add_main_entries (context, options, NULL);
|
||||
g_option_context_add_group (context, fu_debug_get_option_group ());
|
||||
g_option_context_set_summary (context, _("Firmware Update D-Bus Service"));
|
||||
ret = g_option_context_parse (context, &argc, &argv, &error);
|
||||
if (!ret) {
|
||||
@ -268,13 +358,10 @@ main (int argc, char *argv[])
|
||||
priv = g_new0 (FuMainPrivate, 1);
|
||||
priv->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
priv->loop = g_main_loop_new (NULL, FALSE);
|
||||
priv->provider_uefi = fu_provider_uefi_new ();
|
||||
g_signal_connect (priv->provider_uefi, "device-added",
|
||||
G_CALLBACK (cd_main_provider_device_added_cb),
|
||||
priv);
|
||||
g_signal_connect (priv->provider_uefi, "device-removed",
|
||||
G_CALLBACK (cd_main_provider_device_removed_cb),
|
||||
priv);
|
||||
|
||||
/* add providers */
|
||||
priv->providers = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
fu_main_add_provider (priv, fu_provider_uefi_new ());
|
||||
|
||||
/* load introspection from file */
|
||||
priv->introspection_daemon = fu_main_load_introspection (FWUPD_DBUS_INTERFACE ".xml",
|
||||
@ -319,6 +406,7 @@ out:
|
||||
g_object_unref (priv->connection);
|
||||
if (priv->introspection_daemon != NULL)
|
||||
g_dbus_node_info_unref (priv->introspection_daemon);
|
||||
g_ptr_array_unref (priv->providers);
|
||||
g_ptr_array_unref (priv->devices);
|
||||
g_free (priv);
|
||||
}
|
||||
|
@ -40,15 +40,7 @@ struct _FuProviderUefiPrivate
|
||||
GPtrArray *array_devices;
|
||||
};
|
||||
|
||||
enum {
|
||||
SIGNAL_SENSOR_ADDED,
|
||||
SIGNAL_SENSOR_REMOVED,
|
||||
SIGNAL_LAST
|
||||
};
|
||||
|
||||
static guint signals[SIGNAL_LAST] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (FuProviderUefi, fu_provider_uefi, G_TYPE_OBJECT)
|
||||
G_DEFINE_TYPE (FuProviderUefi, fu_provider_uefi, FU_TYPE_PROVIDER)
|
||||
|
||||
/**
|
||||
* fu_provider_uefi_get_by_id:
|
||||
@ -72,19 +64,34 @@ fu_provider_uefi_get_by_id (FuProviderUefi *provider_uefi,
|
||||
return device;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_provider_uefi_update_offline:
|
||||
**/
|
||||
static gboolean
|
||||
fu_provider_uefi_update_offline (FuProvider *provider,
|
||||
FuDevice *device,
|
||||
gint fd,
|
||||
GError **error)
|
||||
{
|
||||
//FIXME
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_provider_uefi_coldplug:
|
||||
**/
|
||||
void
|
||||
fu_provider_uefi_coldplug (FuProviderUefi *provider_uefi)
|
||||
static gboolean
|
||||
fu_provider_uefi_coldplug (FuProvider *provider, GError **error)
|
||||
{
|
||||
// FuProviderUefi *provider_uefi = FU_PROVIDER_UEFI (provider);
|
||||
_cleanup_object_unref_ FuDevice *dev = NULL;
|
||||
|
||||
//FIXME
|
||||
g_debug ("Adding fake UEFI device");
|
||||
dev = fu_device_new ();
|
||||
fu_device_set_id (dev, "819b858e-c52c-402f-80e1-5b311b6c1959");
|
||||
g_signal_emit (provider_uefi, signals[SIGNAL_SENSOR_ADDED], 0, dev);
|
||||
fu_provider_emit_added (provider, dev);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,20 +100,12 @@ fu_provider_uefi_coldplug (FuProviderUefi *provider_uefi)
|
||||
static void
|
||||
fu_provider_uefi_class_init (FuProviderUefiClass *klass)
|
||||
{
|
||||
FuProviderClass *provider_class = FU_PROVIDER_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
provider_class->coldplug = fu_provider_uefi_coldplug;
|
||||
provider_class->update_offline = fu_provider_uefi_update_offline;
|
||||
object_class->finalize = fu_provider_uefi_finalize;
|
||||
signals[SIGNAL_SENSOR_ADDED] =
|
||||
g_signal_new ("device-added",
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (FuProviderUefiClass, device_added),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, FU_TYPE_DEVICE);
|
||||
signals[SIGNAL_SENSOR_REMOVED] =
|
||||
g_signal_new ("device-removed",
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (FuProviderUefiClass, device_removed),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, FU_TYPE_DEVICE);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (FuProviderUefiPrivate));
|
||||
}
|
||||
@ -138,11 +137,10 @@ fu_provider_uefi_finalize (GObject *object)
|
||||
/**
|
||||
* fu_provider_uefi_new:
|
||||
**/
|
||||
FuProviderUefi *
|
||||
FuProvider *
|
||||
fu_provider_uefi_new (void)
|
||||
{
|
||||
FuProviderUefi *provider_uefi;
|
||||
provider_uefi = g_object_new (FU_TYPE_PROVIDER_UEFI, NULL);
|
||||
return FU_PROVIDER_UEFI (provider_uefi);
|
||||
FuProviderUefi *provider;
|
||||
provider = g_object_new (FU_TYPE_PROVIDER_UEFI, NULL);
|
||||
return FU_PROVIDER (provider);
|
||||
}
|
||||
|
||||
|
@ -25,16 +25,15 @@
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "fu-device.h"
|
||||
#include "fu-provider-uefi.h"
|
||||
#include "fu-provider.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define FU_TYPE_PROVIDER_UEFI (fu_provider_uefi_get_type ())
|
||||
#define FU_PROVIDER_UEFI(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), FU_TYPE_PROVIDER_UEFI, FuProviderUefi))
|
||||
#define FU_PROVIDER_UEFI_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), FU_TYPE_PROVIDER_UEFI, FuProviderUefiClass))
|
||||
//#define FU_PROVIDER_UEFI_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), FU_TYPE_PROVIDER_UEFI, FuProviderUefiClass))
|
||||
#define FU_IS_PROVIDER_UEFI(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), FU_TYPE_PROVIDER_UEFI))
|
||||
#define FU_IS_PROVIDER_UEFI_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), FU_TYPE_PROVIDER_UEFI))
|
||||
#define FU_PROVIDER_UEFI_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), FU_TYPE_PROVIDER_UEFI, FuProviderUefiClass))
|
||||
//#define FU_IS_PROVIDER_UEFI_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), FU_TYPE_PROVIDER_UEFI))
|
||||
|
||||
typedef struct _FuProviderUefiPrivate FuProviderUefiPrivate;
|
||||
typedef struct _FuProviderUefi FuProviderUefi;
|
||||
@ -42,22 +41,17 @@ typedef struct _FuProviderUefiClass FuProviderUefiClass;
|
||||
|
||||
struct _FuProviderUefi
|
||||
{
|
||||
GObject parent;
|
||||
FuProvider parent;
|
||||
FuProviderUefiPrivate *priv;
|
||||
};
|
||||
|
||||
struct _FuProviderUefiClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
void (* device_added) (FuProviderUefi *provider_uefi,
|
||||
FuDevice *device);
|
||||
void (* device_removed) (FuProviderUefi *provider_uefi,
|
||||
FuDevice *device);
|
||||
FuProviderClass parent_class;
|
||||
};
|
||||
|
||||
GType fu_provider_uefi_get_type (void);
|
||||
FuProviderUefi *fu_provider_uefi_new (void);
|
||||
void fu_provider_uefi_coldplug (FuProviderUefi *provider_uefi);
|
||||
FuProvider *fu_provider_uefi_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
135
src/fu-provider.c
Normal file
135
src/fu-provider.c
Normal file
@ -0,0 +1,135 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* Licensed under the GNU General Public License Version 2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "fu-cleanup.h"
|
||||
#include "fu-common.h"
|
||||
#include "fu-device.h"
|
||||
#include "fu-provider-uefi.h"
|
||||
|
||||
static void fu_provider_finalize (GObject *object);
|
||||
|
||||
#define FU_PROVIDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), FU_TYPE_PROVIDER, FuProviderPrivate))
|
||||
|
||||
enum {
|
||||
SIGNAL_DEVICE_ADDED,
|
||||
SIGNAL_DEVICE_REMOVED,
|
||||
SIGNAL_LAST
|
||||
};
|
||||
|
||||
static guint signals[SIGNAL_LAST] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (FuProvider, fu_provider, G_TYPE_OBJECT)
|
||||
|
||||
/**
|
||||
* fu_provider_coldplug:
|
||||
**/
|
||||
gboolean
|
||||
fu_provider_coldplug (FuProvider *provider, GError **error)
|
||||
{
|
||||
FuProviderClass *klass = FU_PROVIDER_GET_CLASS (provider);
|
||||
if (klass->coldplug != NULL)
|
||||
return klass->coldplug (provider, error);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_provider_update_offline:
|
||||
**/
|
||||
gboolean
|
||||
fu_provider_update_offline (FuProvider *provider,
|
||||
FuDevice *device,
|
||||
gint fd,
|
||||
GError **error)
|
||||
{
|
||||
FuProviderClass *klass = FU_PROVIDER_GET_CLASS (provider);
|
||||
if (klass->update_offline == NULL) {
|
||||
g_set_error_literal (error,
|
||||
FU_ERROR,
|
||||
FU_ERROR_INTERNAL,
|
||||
"No offline update functionality");
|
||||
return FALSE;
|
||||
}
|
||||
return klass->update_offline (provider, device, fd, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_provider_emit_added:
|
||||
**/
|
||||
void
|
||||
fu_provider_emit_added (FuProvider *provider, FuDevice *device)
|
||||
{
|
||||
g_debug ("emit added: %s", fu_device_get_id (device));
|
||||
g_signal_emit (provider, signals[SIGNAL_DEVICE_ADDED], 0, device);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_provider_emit_removed:
|
||||
**/
|
||||
void
|
||||
fu_provider_emit_removed (FuProvider *provider, FuDevice *device)
|
||||
{
|
||||
g_debug ("emit removed: %s", fu_device_get_id (device));
|
||||
g_signal_emit (provider, signals[SIGNAL_DEVICE_REMOVED], 0, device);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_provider_class_init:
|
||||
**/
|
||||
static void
|
||||
fu_provider_class_init (FuProviderClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
object_class->finalize = fu_provider_finalize;
|
||||
signals[SIGNAL_DEVICE_ADDED] =
|
||||
g_signal_new ("device-added",
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (FuProviderClass, device_added),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, FU_TYPE_DEVICE);
|
||||
signals[SIGNAL_DEVICE_REMOVED] =
|
||||
g_signal_new ("device-removed",
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (FuProviderClass, device_removed),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, FU_TYPE_DEVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_provider_init:
|
||||
**/
|
||||
static void
|
||||
fu_provider_init (FuProvider *provider)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_provider_finalize:
|
||||
**/
|
||||
static void
|
||||
fu_provider_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (fu_provider_parent_class)->finalize (object);
|
||||
}
|
81
src/fu-provider.h
Normal file
81
src/fu-provider.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* Licensed under the GNU General Public License Version 2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef __FU_PROVIDER_H
|
||||
#define __FU_PROVIDER_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "fu-device.h"
|
||||
#include "fu-provider.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define FU_TYPE_PROVIDER (fu_provider_get_type ())
|
||||
#define FU_PROVIDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), FU_TYPE_PROVIDER, FuProvider))
|
||||
#define FU_PROVIDER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), FU_TYPE_PROVIDER, FuProviderClass))
|
||||
#define FU_IS_PROVIDER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), FU_TYPE_PROVIDER))
|
||||
#define FU_IS_PROVIDER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), FU_TYPE_PROVIDER))
|
||||
#define FU_PROVIDER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), FU_TYPE_PROVIDER, FuProviderClass))
|
||||
|
||||
typedef struct _FuProvider FuProvider;
|
||||
typedef struct _FuProviderClass FuProviderClass;
|
||||
|
||||
struct _FuProvider
|
||||
{
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
struct _FuProviderClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* vfunc */
|
||||
gboolean (*coldplug) (FuProvider *provider,
|
||||
GError **error);
|
||||
gboolean (*update_offline) (FuProvider *provider,
|
||||
FuDevice *device,
|
||||
gint fd,
|
||||
GError **error);
|
||||
|
||||
/* signals */
|
||||
void (* device_added) (FuProvider *provider,
|
||||
FuDevice *device);
|
||||
void (* device_removed) (FuProvider *provider,
|
||||
FuDevice *device);
|
||||
};
|
||||
|
||||
GType fu_provider_get_type (void);
|
||||
void fu_provider_emit_added (FuProvider *provider,
|
||||
FuDevice *device);
|
||||
void fu_provider_emit_removed (FuProvider *provider,
|
||||
FuDevice *device);
|
||||
gboolean fu_provider_coldplug (FuProvider *provider,
|
||||
GError **error);
|
||||
gboolean fu_provider_update_offline (FuProvider *provider,
|
||||
FuDevice *device,
|
||||
gint fd,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __FU_PROVIDER_H */
|
||||
|
@ -21,11 +21,13 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <fcntl.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gio/gunixfdlist.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fu-cleanup.h"
|
||||
#include "fu-common.h"
|
||||
@ -194,7 +196,7 @@ fu_util_get_devices (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
_cleanup_object_unref_ GDBusConnection *conn = NULL;
|
||||
_cleanup_object_unref_ GDBusProxy *proxy = NULL;
|
||||
_cleanup_variant_unref_ GVariant *val = NULL;
|
||||
const gchar **guids = NULL;
|
||||
const gchar **ids = NULL;
|
||||
guint i;
|
||||
|
||||
conn = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
|
||||
@ -219,12 +221,12 @@ fu_util_get_devices (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
error);
|
||||
if (val == NULL)
|
||||
return FALSE;
|
||||
g_variant_get (val, "(^a&s)", &guids);
|
||||
g_assert (guids != NULL);
|
||||
if (guids[0] == NULL)
|
||||
g_variant_get (val, "(^a&s)", &ids);
|
||||
g_assert (ids != NULL);
|
||||
if (ids[0] == NULL)
|
||||
g_print ("No hardware detected with firmware update capaility\n");
|
||||
for (i = 0; guids[i] != NULL; i++)
|
||||
g_print ("%i: %s\n", i, guids[i]);
|
||||
for (i = 0; ids[i] != NULL; i++)
|
||||
g_print ("%i: %s\n", i, ids[i]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -234,7 +236,63 @@ fu_util_get_devices (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
static gboolean
|
||||
fu_util_update_offline (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
{
|
||||
//FIXME
|
||||
GVariant *body;
|
||||
gint retval;
|
||||
gint fd;
|
||||
_cleanup_object_unref_ GDBusConnection *conn = NULL;
|
||||
_cleanup_object_unref_ GDBusMessage *message = NULL;
|
||||
_cleanup_object_unref_ GDBusMessage *request = NULL;
|
||||
_cleanup_object_unref_ GUnixFDList *fd_list = NULL;
|
||||
|
||||
if (g_strv_length (values) != 2) {
|
||||
g_set_error_literal (error,
|
||||
FU_ERROR,
|
||||
FU_ERROR_INTERNAL,
|
||||
"Invalid arguments: expected 'id' 'filename'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
conn = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
|
||||
if (conn == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* open file */
|
||||
fd = open (values[1], O_RDONLY);
|
||||
if (fd < 0) {
|
||||
g_set_error (error,
|
||||
FU_ERROR,
|
||||
FU_ERROR_INTERNAL,
|
||||
"failed to open %s",
|
||||
values[1]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* set out of band file descriptor */
|
||||
fd_list = g_unix_fd_list_new ();
|
||||
retval = g_unix_fd_list_append (fd_list, fd, NULL);
|
||||
g_assert (retval != -1);
|
||||
request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE,
|
||||
FWUPD_DBUS_PATH,
|
||||
FWUPD_DBUS_INTERFACE,
|
||||
"UpdateOffline");
|
||||
g_dbus_message_set_unix_fd_list (request, fd_list);
|
||||
|
||||
/* g_unix_fd_list_append did a dup() already */
|
||||
close (fd);
|
||||
|
||||
/* send message */
|
||||
body = g_variant_new ("(sh)", values[0], fd);
|
||||
g_dbus_message_set_body (request, body);
|
||||
message = g_dbus_connection_send_message_with_reply_sync (conn,
|
||||
request,
|
||||
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
NULL,
|
||||
error);
|
||||
if (message == NULL)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -31,10 +31,10 @@
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
<arg type='as' name='devices' direction='out'>
|
||||
<arg type='as' name='ids' direction='out'>
|
||||
<doc:doc>
|
||||
<doc:summary>
|
||||
<doc:para>An array of GUIDs.</doc:para>
|
||||
<doc:para>An array of IDs.</doc:para>
|
||||
</doc:summary>
|
||||
</doc:doc>
|
||||
</arg>
|
||||
@ -49,10 +49,10 @@
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
<arg type='s' name='guid' direction='in'>
|
||||
<arg type='s' name='id' direction='in'>
|
||||
<doc:doc>
|
||||
<doc:summary>
|
||||
<doc:para>A GUID of the hardware to update.</doc:para>
|
||||
<doc:para>An ID, typically a GUID of the hardware to update.</doc:para>
|
||||
</doc:summary>
|
||||
</doc:doc>
|
||||
</arg>
|
||||
|
Loading…
Reference in New Issue
Block a user