altos: Modernize the plugin to simplify it

This commit is contained in:
Richard Hughes 2019-10-05 20:43:03 +01:00
parent 989acf12e7
commit 5c68f8c81f
4 changed files with 39 additions and 206 deletions

View File

@ -2,6 +2,10 @@
[DeviceInstanceId=USB\VID_1D50&PID_60C6]
Plugin = altos
Flags = none
Name = Altos ChaosKey
CounterpartGuid = USB\VID_FFFE&PID_000A
[DeviceInstanceId=USB\VID_FFFE&PID_000A]
Plugin = altos
Flags = is-bootloader
Name = Altos [bootloader]

View File

@ -18,11 +18,7 @@
struct _FuAltosDevice {
FuUsbDevice parent_instance;
FuAltosDeviceKind kind;
guint32 serial[9];
gchar *guid;
gchar *tty;
gchar *version;
guint64 addr_base;
guint64 addr_bound;
struct termios tty_termios;
@ -38,64 +34,16 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevClient, g_object_unref)
#pragma clang diagnostic pop
#endif
/**
* fu_altos_device_kind_from_string:
* @kind: the string.
*
* Converts the text representation to an enumerated value.
*
* Returns: (transfer full): a #FuAltosDeviceKind, or %FU_ALTOS_DEVICE_KIND_UNKNOWN for unknown.
*
* Since: 0.1.0
**/
FuAltosDeviceKind
fu_altos_device_kind_from_string (const gchar *kind)
{
if (g_strcmp0 (kind, "BOOTLOADER") == 0)
return FU_ALTOS_DEVICE_KIND_BOOTLOADER;
if (g_strcmp0 (kind, "CHAOSKEY") == 0)
return FU_ALTOS_DEVICE_KIND_CHAOSKEY;
return FU_ALTOS_DEVICE_KIND_UNKNOWN;
}
/**
* fu_altos_device_kind_to_string:
* @kind: the #FuAltosDeviceKind.
*
* Converts the enumerated value to an text representation.
*
* Returns: string version of @kind
*
* Since: 0.1.0
**/
const gchar *
fu_altos_device_kind_to_string (FuAltosDeviceKind kind)
{
if (kind == FU_ALTOS_DEVICE_KIND_BOOTLOADER)
return "BOOTLOADER";
if (kind == FU_ALTOS_DEVICE_KIND_CHAOSKEY)
return "CHAOSKEY";
return NULL;
}
static void
fu_altos_device_finalize (GObject *object)
{
FuAltosDevice *self = FU_ALTOS_DEVICE (object);
g_free (self->guid);
g_free (self->tty);
g_free (self->version);
G_OBJECT_CLASS (fu_altos_device_parent_class)->finalize (object);
}
FuAltosDeviceKind
fu_altos_device_get_kind (FuAltosDevice *self)
{
return self->kind;
}
static gboolean
fu_altos_device_find_tty (FuAltosDevice *self, GError **error)
{
@ -296,7 +244,7 @@ fu_altos_device_write_firmware (FuDevice *device,
g_autoptr(GString) buf = g_string_new (NULL);
/* check kind */
if (self->kind != FU_ALTOS_DEVICE_KIND_BOOTLOADER) {
if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
@ -435,7 +383,7 @@ fu_altos_device_read_firmware (FuDevice *device, GError **error)
g_autoptr(GString) buf = g_string_new (NULL);
/* check kind */
if (self->kind != FU_ALTOS_DEVICE_KIND_BOOTLOADER) {
if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
@ -561,83 +509,52 @@ fu_altos_device_probe (FuDevice *device, GError **error)
{
FuAltosDevice *self = FU_ALTOS_DEVICE (device);
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self));
const gchar *version_prefix = "ChaosKey-hw-1.0-sw-";
guint8 version_idx;
g_autofree gchar *version = NULL;
g_autoptr(FuDeviceLocker) locker = NULL;
/* bootloader uses tty */
if (self->kind == FU_ALTOS_DEVICE_KIND_BOOTLOADER)
if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER))
return fu_altos_device_probe_bootloader (self, error);
/* get version */
if (self->kind == FU_ALTOS_DEVICE_KIND_CHAOSKEY) {
const gchar *version_prefix = "ChaosKey-hw-1.0-sw-";
guint8 version_idx;
g_autofree gchar *version = NULL;
g_autoptr(FuDeviceLocker) locker = NULL;
/* open */
locker = fu_device_locker_new (usb_device, error);
if (locker == NULL)
return FALSE;
/* open */
locker = fu_device_locker_new (usb_device, error);
if (locker == NULL)
return FALSE;
/* get string */
version_idx = g_usb_device_get_product_index (usb_device);
version = g_usb_device_get_string_descriptor (usb_device,
version_idx,
error);
if (version == NULL)
return FALSE;
if (!g_str_has_prefix (version, version_prefix)) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"not a ChaosKey v1.0 device: %s",
version);
return FALSE;
}
fu_device_set_version (FU_DEVICE (self), version + 19,
FWUPD_VERSION_FORMAT_TRIPLET);
/* get string */
version_idx = g_usb_device_get_product_index (usb_device);
version = g_usb_device_get_string_descriptor (usb_device,
version_idx,
error);
if (version == NULL)
return FALSE;
if (!g_str_has_prefix (version, version_prefix)) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"not a ChaosKey v1.0 device: %s",
version);
return FALSE;
}
fu_device_set_version (FU_DEVICE (self), version + 19,
FWUPD_VERSION_FORMAT_TRIPLET);
/* success */
return TRUE;
}
/* now with kind and usb_device set */
static void
fu_altos_device_init_real (FuAltosDevice *self)
{
/* allowed, but requires manual bootloader step */
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
/* set default vendor */
fu_device_set_vendor (FU_DEVICE (self), "altusmetrum.org");
/* set name */
switch (self->kind) {
case FU_ALTOS_DEVICE_KIND_BOOTLOADER:
fu_device_set_name (FU_DEVICE (self), "Altos [bootloader]");
break;
case FU_ALTOS_DEVICE_KIND_CHAOSKEY:
fu_device_set_name (FU_DEVICE (self), "Altos ChaosKey");
break;
default:
g_assert_not_reached ();
break;
}
/* set one line summary */
fu_device_set_summary (FU_DEVICE (self),
"A USB hardware random number generator");
/* only the bootloader can do the update */
if (self->kind != FU_ALTOS_DEVICE_KIND_BOOTLOADER) {
fu_device_add_flag (FU_DEVICE (self),
FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER);
}
}
static void
fu_altos_device_init (FuAltosDevice *self)
{
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_set_vendor (FU_DEVICE (self), "altusmetrum.org");
fu_device_set_summary (FU_DEVICE (self), "A USB hardware random number generator");
/* requires manual step */
if (!fu_device_has_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_IS_BOOTLOADER))
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER);
}
static void
@ -651,32 +568,3 @@ fu_altos_device_class_init (FuAltosDeviceClass *klass)
klass_device->read_firmware = fu_altos_device_read_firmware;
object_class->finalize = fu_altos_device_finalize;
}
typedef struct {
guint16 vid;
guint16 pid;
FuAltosDeviceKind kind;
} FuAltosDeviceVidPid;
FuAltosDevice *
fu_altos_device_new (FuUsbDevice *device)
{
const FuAltosDeviceVidPid vidpids[] = {
{ 0xfffe, 0x000a, FU_ALTOS_DEVICE_KIND_BOOTLOADER },
{ 0x1d50, 0x60c6, FU_ALTOS_DEVICE_KIND_CHAOSKEY },
{ 0x0000, 0x0000, FU_ALTOS_DEVICE_KIND_UNKNOWN }
};
/* set kind */
for (guint j = 0; vidpids[j].vid != 0x0000; j++) {
if (fu_usb_device_get_vid (device) == vidpids[j].vid &&
fu_usb_device_get_pid (device) == vidpids[j].pid) {
FuAltosDevice *self = g_object_new (FU_TYPE_ALTOS_DEVICE, NULL);
fu_device_incorporate (FU_DEVICE (self), FU_DEVICE (device));
self->kind = vidpids[j].kind;
fu_altos_device_init_real (self);
return self;
}
}
return NULL;
}

View File

@ -13,24 +13,4 @@ G_BEGIN_DECLS
#define FU_TYPE_ALTOS_DEVICE (fu_altos_device_get_type ())
G_DECLARE_FINAL_TYPE (FuAltosDevice, fu_altos_device, FU, ALTOS_DEVICE, FuUsbDevice)
typedef enum {
FU_ALTOS_DEVICE_KIND_UNKNOWN,
FU_ALTOS_DEVICE_KIND_BOOTLOADER,
FU_ALTOS_DEVICE_KIND_CHAOSKEY,
/*< private >*/
FU_ALTOS_DEVICE_KIND_LAST
} FuAltosDeviceKind;
typedef enum {
FU_ALTOS_DEVICE_WRITE_FIRMWARE_FLAG_NONE = 0,
FU_ALTOS_DEVICE_WRITE_FIRMWARE_FLAG_REBOOT = 1 << 0,
/*< private >*/
FU_ALTOS_DEVICE_WRITE_FIRMWARE_FLAG_LAST
} FuAltosDeviceWriteFirmwareFlag;
FuAltosDevice *fu_altos_device_new (FuUsbDevice *device);
FuAltosDeviceKind fu_altos_device_kind_from_string (const gchar *kind);
const gchar *fu_altos_device_kind_to_string (FuAltosDeviceKind kind);
FuAltosDeviceKind fu_altos_device_get_kind (FuAltosDevice *device);
G_END_DECLS

View File

@ -16,44 +16,5 @@ fu_plugin_init (FuPlugin *plugin)
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_REQUIRES_QUIRK, FU_QUIRKS_PLUGIN);
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_SUPPORTS_PROTOCOL, "org.altusmetrum.altos");
}
gboolean
fu_plugin_usb_device_added (FuPlugin *plugin, FuUsbDevice *device, GError **error)
{
GUsbDevice *usb_device = fu_usb_device_get_dev (device);
const gchar *platform_id = NULL;
g_autofree gchar *runtime_id = NULL;
g_autoptr(FuAltosDevice) dev = NULL;
/* get kind */
dev = fu_altos_device_new (device);
if (dev == NULL)
return TRUE;
/* get device properties */
if (!fu_device_probe (FU_DEVICE (dev), error))
return FALSE;
/* only the bootloader can do the update */
platform_id = g_usb_device_get_platform_id (usb_device);
runtime_id = g_strdup_printf ("%s-runtime", platform_id);
if (fu_altos_device_get_kind (dev) == FU_ALTOS_DEVICE_KIND_BOOTLOADER) {
FuDevice *dev_runtime;
dev_runtime = fu_plugin_cache_lookup (plugin, runtime_id);
if (dev_runtime != NULL) {
const gchar *guid = fu_device_get_guid_default (dev_runtime);
g_debug ("adding runtime GUID of %s", guid);
fu_device_add_counterpart_guid (FU_DEVICE (dev), guid);
fu_device_set_version (FU_DEVICE (dev),
fu_device_get_version (dev_runtime),
fu_device_get_version_format (dev_runtime));
}
} else {
fu_plugin_cache_add (plugin, runtime_id, dev);
}
/* success */
fu_plugin_device_add (plugin, FU_DEVICE (dev));
return TRUE;
fu_plugin_set_device_gtype (plugin, FU_TYPE_ALTOS_DEVICE);
}