mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-25 22:40:50 +00:00
195 lines
5.4 KiB
C
195 lines
5.4 KiB
C
/*
|
|
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1+
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "fu-redfish-network-device.h"
|
|
#include "fu-redfish-network.h"
|
|
|
|
struct _FuRedfishNetworkDevice {
|
|
GObject parent_instance;
|
|
gchar *object_path;
|
|
};
|
|
|
|
G_DEFINE_TYPE(FuRedfishNetworkDevice, fu_redfish_network_device, G_TYPE_OBJECT)
|
|
|
|
gboolean
|
|
fu_redfish_network_device_get_state(FuRedfishNetworkDevice *self,
|
|
FuRedfishNetworkDeviceState *state,
|
|
GError **error)
|
|
{
|
|
g_autoptr(GVariant) retval = NULL;
|
|
g_autoptr(GDBusProxy) proxy = NULL;
|
|
|
|
g_return_val_if_fail(FU_IS_REDFISH_NETWORK_DEVICE(self), FALSE);
|
|
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
|
|
|
/* connect to device */
|
|
proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
|
|
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
|
NULL,
|
|
NETWORK_MANAGER_SERVICE_NAME,
|
|
self->object_path,
|
|
NETWORK_MANAGER_INTERFACE_DEVICE,
|
|
NULL,
|
|
error);
|
|
if (proxy == NULL)
|
|
return FALSE;
|
|
retval = g_dbus_proxy_get_cached_property(proxy, "State");
|
|
if (retval == NULL) {
|
|
g_set_error_literal(error,
|
|
G_IO_ERROR,
|
|
G_IO_ERROR_NOT_CONNECTED,
|
|
"could not find State");
|
|
return FALSE;
|
|
}
|
|
if (state != NULL)
|
|
*state = g_variant_get_uint32(retval);
|
|
return TRUE;
|
|
}
|
|
|
|
gboolean
|
|
fu_redfish_network_device_connect(FuRedfishNetworkDevice *self, GError **error)
|
|
{
|
|
g_autoptr(GDBusProxy) proxy = NULL;
|
|
g_autoptr(GTimer) timer = g_timer_new();
|
|
g_autoptr(GVariant) success = NULL;
|
|
|
|
g_return_val_if_fail(FU_IS_REDFISH_NETWORK_DEVICE(self), FALSE);
|
|
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
|
|
|
/* connect to manager */
|
|
proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
|
|
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
|
NULL,
|
|
NETWORK_MANAGER_SERVICE_NAME,
|
|
NETWORK_MANAGER_PATH,
|
|
NETWORK_MANAGER_INTERFACE,
|
|
NULL,
|
|
error);
|
|
if (proxy == NULL)
|
|
return FALSE;
|
|
|
|
/* activate with some good defaults */
|
|
success = g_dbus_proxy_call_sync(proxy,
|
|
"ActivateConnection",
|
|
g_variant_new("(ooo)", "/", self->object_path, "/"),
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1,
|
|
NULL,
|
|
error);
|
|
if (success == NULL)
|
|
return FALSE;
|
|
|
|
/* wait until the network interface comes up */
|
|
do {
|
|
FuRedfishNetworkDeviceState state = FU_REDFISH_NETWORK_DEVICE_STATE_UNKNOWN;
|
|
if (!fu_redfish_network_device_get_state(self, &state, error))
|
|
return FALSE;
|
|
if (g_getenv("FWUPD_REDFISH_VERBOSE") != NULL) {
|
|
g_debug("%s device state is now %u", self->object_path, state);
|
|
}
|
|
if (state == FU_REDFISH_NETWORK_DEVICE_STATE_CONNECTED)
|
|
return TRUE;
|
|
g_usleep(50 * 1000);
|
|
} while (g_timer_elapsed(timer, NULL) < 5.f);
|
|
|
|
/* timed out */
|
|
g_set_error_literal(error,
|
|
G_IO_ERROR,
|
|
G_IO_ERROR_TIMED_OUT,
|
|
"could not activate connection");
|
|
return FALSE;
|
|
}
|
|
|
|
gchar *
|
|
fu_redfish_network_device_get_address(FuRedfishNetworkDevice *self, GError **error)
|
|
{
|
|
g_autofree gchar *address = NULL;
|
|
g_autoptr(GDBusProxy) proxy = NULL;
|
|
g_autoptr(GDBusProxy) proxy2 = NULL;
|
|
g_autoptr(GVariant) addr_data = NULL;
|
|
g_autoptr(GVariant) ip4_config = NULL;
|
|
|
|
g_return_val_if_fail(FU_IS_REDFISH_NETWORK_DEVICE(self), NULL);
|
|
g_return_val_if_fail(error == NULL || *error == NULL, NULL);
|
|
|
|
/* connect to device */
|
|
proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
|
|
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
|
NULL,
|
|
NETWORK_MANAGER_SERVICE_NAME,
|
|
self->object_path,
|
|
NETWORK_MANAGER_INTERFACE_DEVICE,
|
|
NULL,
|
|
error);
|
|
if (proxy == NULL)
|
|
return NULL;
|
|
ip4_config = g_dbus_proxy_get_cached_property(proxy, "Ip4Config");
|
|
if (ip4_config == NULL) {
|
|
g_set_error_literal(error,
|
|
G_IO_ERROR,
|
|
G_IO_ERROR_NOT_CONNECTED,
|
|
"could not find IPv4 config");
|
|
return NULL;
|
|
}
|
|
proxy2 = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
|
|
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
|
NULL,
|
|
NETWORK_MANAGER_SERVICE_NAME,
|
|
g_variant_get_string(ip4_config, NULL),
|
|
NETWORK_MANAGER_INTERFACE_IP4_CONFIG,
|
|
NULL,
|
|
error);
|
|
if (proxy2 == NULL)
|
|
return NULL;
|
|
|
|
addr_data = g_dbus_proxy_get_cached_property(proxy2, "AddressData");
|
|
if (addr_data != NULL) {
|
|
g_autoptr(GVariant) addr_data0 = g_variant_get_child_value(addr_data, 0);
|
|
g_autoptr(GVariantDict) dict = g_variant_dict_new(addr_data0);
|
|
g_variant_dict_lookup(dict, "address", "s", &address);
|
|
}
|
|
if (address == NULL) {
|
|
g_set_error_literal(error,
|
|
G_IO_ERROR,
|
|
G_IO_ERROR_NOT_CONNECTED,
|
|
"could not find IP address for device");
|
|
return NULL;
|
|
}
|
|
|
|
/* success */
|
|
return g_steal_pointer(&address);
|
|
}
|
|
|
|
FuRedfishNetworkDevice *
|
|
fu_redfish_network_device_new(const gchar *object_path)
|
|
{
|
|
FuRedfishNetworkDevice *self = g_object_new(FU_TYPE_REDFISH_NETWORK_DEVICE, NULL);
|
|
self->object_path = g_strdup(object_path);
|
|
return self;
|
|
}
|
|
|
|
static void
|
|
fu_redfish_network_device_init(FuRedfishNetworkDevice *self)
|
|
{
|
|
}
|
|
|
|
static void
|
|
fu_redfish_network_device_finalize(GObject *object)
|
|
{
|
|
FuRedfishNetworkDevice *self = FU_REDFISH_NETWORK_DEVICE(object);
|
|
g_free(self->object_path);
|
|
G_OBJECT_CLASS(fu_redfish_network_device_parent_class)->finalize(object);
|
|
}
|
|
|
|
static void
|
|
fu_redfish_network_device_class_init(FuRedfishNetworkDeviceClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
|
object_class->finalize = fu_redfish_network_device_finalize;
|
|
}
|