modem: add firmware interface

This commit is contained in:
Thomas Tuttle
2011-09-01 18:53:25 -04:00
parent 4c514bfd6d
commit 953701a6f8
8 changed files with 635 additions and 2 deletions

View File

@@ -6,6 +6,7 @@
<tp:version>0.5</tp:version>
<tp:copyright>Copyright (C) 2008 Novell, Inc.</tp:copyright>
<tp:copyright>Copyright (C) 2008 - 2010 Red Hat, Inc.</tp:copyright>
<tp:copyright>Copyright (C) 2011 The Chromium OS Authors</tp:copyright>
<tp:license xmlns="http://www.w3.org/1999/xhtml">
<p>This program is free software; you can redistribute it and/or modify
@@ -26,6 +27,7 @@
<xi:include href="org.freedesktop.ModemManager.xml"/>
<xi:include href="org.freedesktop.ModemManager.Modem.xml"/>
<xi:include href="org.freedesktop.ModemManager.Modem.Simple.xml"/>
<xi:include href="org.freedesktop.ModemManager.Modem.Firmware.xml"/>
<xi:include href="org.freedesktop.ModemManager.Modem.Location.xml"/>
<xi:include href="org.freedesktop.ModemManager.Modem.Cdma.xml"/>
<xi:include href="org.freedesktop.ModemManager.Modem.Gsm.xml"/>

View File

@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.ModemManager.Modem.Firmware">
<tp:docstring>
This interface allows clients to select or install firmware images on
modems.
Firmware slots and firmware images are identified by arbitrary opaque
strings.
Firmware images are represented as dictionaries of properties.
Certain properties are pre-defined, and some are required:
Name (string, required): A user-readable name for the firmware image.
Version (string, optional): The version of the firmware. The format is
unspecified; tools attempting to upgrade firmware automatically must
understand the versioning scheme used by the modem driver they are
interacting with. May be displayed to the user.
</tp:docstring>
<method name="List">
<tp:docstring>
List installed and available firmware images.
Depending on the type of modem, installed images may be stored on the
host or the modem. The distinction between "installed" and
"available" is not one of where the firmware is stored, but that
installed images can be selected non-destructively, while available
images must be installed into a slot, possibly overwriting another
installed image.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol"
value="impl_modem_firmware_list" />
<arg name="selected" type="s" direction="out">
<tp:docstring>
The identifier of the selected firmware slot, or the empty string if
no slot is selected (such as if all slots are empty, or no slots
exist).
</tp:docstring>
</arg>
<arg name="installed" type="a{sa{sv}}" direction="out">
<tp:docstring>
A dictionary of slots into which firmware is and/or can be
installed. The key of each entry is the identifier of the slot,
and the value is either an empty dictionary if the slot is empty,
or a dictionary of properties of the firmware image installed in
that slot.
The slot identifiers and the mapping between slots and firmware
images are guaranteed to remain stable only as long as the modem
remains present.
</tp:docstring>
</arg>
<arg name="available" type="a{sa{sv}}" direction="out">
<tp:docstring>
A dictionary of available firmware images. The key of each entry is
the identifier of the image, and the value is a dictionary of
properties of the image.
The image identifiers are guaranteed to remain stable only as long
as the modem remains present.
</tp:docstring>
</arg>
</method>
<method name="Select">
<tp:docstring>
Selects a different firmware image to use, and immediately resets the
modem so that it begins using the new firmware image.
Select will fail if the identifier does not match any of the slot
identifiers returned by List, or if the slot could not be selected
for some reason.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
<annotation name="org.freedesktop.DBus.GLib.CSymbol"
value="impl_modem_firmware_select" />
<arg name="slot" type="s" direction="in">
<tp:docstring>
The identifier of the firmware slot to select.
</tp:docstring>
</arg>
</method>
<method name="Install">
<tp:docstring>
Install an available firmware image into a slot.
Install does not guarantee that the image will be installed into the
specified slot, but does guarantee that, if the slot is empty, no
image will be overwritten, and if the slot is not empty, no image
other than the one in that slot will be overwritten.
Install will fail if either of the identifiers is invalid, or if the
image could not be installed into the slot for some reason.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
<annotation name="org.freedesktop.DBus.GLib.CSymbol"
value="impl_modem_firmware_install" />
<arg name="image" type="s" direction="in">
<tp:docstring>
The identifier of the firmware image to install.
</tp:docstring>
</arg>
<arg name="slot" type="s" direction="in">
<tp:docstring>
The identifier of the slot into which the firmware should be
installed.
</tp:docstring>
</arg>
</method>
</interface>
</node>

View File

@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.ModemManager1.Modem.Firmware">
<tp:docstring>
This interface allows clients to select or install firmware images on
modems.
Firmware slots and firmware images are identified by arbitrary opaque
strings.
Firmware images are represented as dictionaries of properties.
Certain properties are pre-defined, and some are required:
Name (string, required): A user-readable name for the firmware image.
Version (string, optional): The version of the firmware. The format is
unspecified; tools attempting to upgrade firmware automatically must
understand the versioning scheme used by the modem driver they are
interacting with. May be displayed to the user.
</tp:docstring>
<method name="List">
<tp:docstring>
List installed and available firmware images.
Depending on the type of modem, installed images may be stored on the
host or the modem. The distinction between "installed" and
"available" is not one of where the firmware is stored, but that
installed images can be selected non-destructively, while available
images must be installed into a slot, possibly overwriting another
installed image.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol"
value="impl_modem_firmware_list" />
<arg name="selected" type="s" direction="out">
<tp:docstring>
The identifier of the selected firmware slot, or the empty string if
no slot is selected (such as if all slots are empty, or no slots
exist).
</tp:docstring>
</arg>
<arg name="installed" type="a{sa{sv}}" direction="out">
<tp:docstring>
A dictionary of slots into which firmware is and/or can be
installed. The key of each entry is the identifier of the slot,
and the value is either an empty dictionary if the slot is empty,
or a dictionary of properties of the firmware image installed in
that slot.
The slot identifiers and the mapping between slots and firmware
images are guaranteed to remain stable only as long as the modem
remains present.
</tp:docstring>
</arg>
<arg name="available" type="a{sa{sv}}" direction="out">
<tp:docstring>
A dictionary of available firmware images. The key of each entry is
the identifier of the image, and the value is a dictionary of
properties of the image.
The image identifiers are guaranteed to remain stable only as long
as the modem remains present.
</tp:docstring>
</arg>
</method>
<method name="Select">
<tp:docstring>
Selects a different firmware image to use, and immediately resets the
modem so that it begins using the new firmware image.
Select will fail if the identifier does not match any of the slot
identifiers returned by List, or if the slot could not be selected
for some reason.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
<annotation name="org.freedesktop.DBus.GLib.CSymbol"
value="impl_modem_firmware_select" />
<arg name="slot" type="s" direction="in">
<tp:docstring>
The identifier of the firmware slot to select.
</tp:docstring>
</arg>
</method>
<method name="Install">
<tp:docstring>
Install an available firmware image into a slot.
Install does not guarantee that the image will be installed into the
specified slot, but does guarantee that, if the slot is empty, no
image will be overwritten, and if the slot is not empty, no image
other than the one in that slot will be overwritten.
Install will fail if either of the identifiers is invalid, or if the
image could not be installed into the slot for some reason.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
<annotation name="org.freedesktop.DBus.GLib.CSymbol"
value="impl_modem_firmware_install" />
<arg name="image" type="s" direction="in">
<tp:docstring>
The identifier of the firmware image to install.
</tp:docstring>
</arg>
<arg name="slot" type="s" direction="in">
<tp:docstring>
The identifier of the slot into which the firmware should be
installed.
</tp:docstring>
</arg>
</method>
</interface>
</node>

View File

@@ -72,4 +72,13 @@
</defaults>
</action>
<action id="org.freedesktop.ModemManager.Firmware">
<_description>Query and manage firmware on a mobile broadband device</_description>
<_message>System policy prevents querying or managing this device's firmware.</_message>
<defaults>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
</action>
</policyconfig>

View File

@@ -122,7 +122,9 @@ modem_manager_SOURCES = \
mm-properties-changed-signal.c \
mm-properties-changed-signal.h \
mm-modem-location.c \
mm-modem-location.h
mm-modem-location.h \
mm-modem-firmware.c \
mm-modem-firmware.h
mm-manager-glue.h: $(top_srcdir)/introspection/org.freedesktop.ModemManager.xml
$(AM_V_GEN) dbus-binding-tool --prefix=mm_manager --mode=glib-server --output=$@ $<
@@ -165,8 +167,11 @@ BUILT_SOURCES = \
mm-modem-location-glue.h: $(top_srcdir)/introspection/org.freedesktop.ModemManager.Modem.Location.xml
$(AM_V_GEN) dbus-binding-tool --prefix=mm_modem_location --mode=glib-server --output=$@ $<
mm-modem-firmware-glue.h: $(top_srcdir)/introspection/org.freedesktop.ModemManager.Modem.Firmware.xml
$(AM_V_GEN) dbus-binding-tool --prefix=mm_modem_firmware --mode=glib-server --output=$@ $<
modem_manager_SOURCES += $(loc_sources)
BUILT_SOURCES += mm-modem-location-glue.h
BUILT_SOURCES += mm-modem-location-glue.h mm-modem-firmware-glue.h
CLEANFILES = $(BUILT_SOURCES)

View File

@@ -29,6 +29,7 @@
#define MM_AUTHORIZATION_SMS "org.freedesktop.ModemManager.SMS"
#define MM_AUTHORIZATION_USSD "org.freedesktop.ModemManager.USSD"
#define MM_AUTHORIZATION_LOCATION "org.freedesktop.ModemManager.Location"
#define MM_AUTHORIZATION_FIRMWARE "org.freedesktop.ModemManager.Firmware"
/******************/

316
src/mm-modem-firmware.c Normal file
View File

@@ -0,0 +1,316 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* 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:
*
* Copyright (C) 2011 The Chromium OS Authors
*/
#include <string.h>
#include <dbus/dbus-glib.h>
#include "mm-modem-firmware.h"
#include "mm-errors.h"
#include "mm-callback-info.h"
#include "mm-marshal.h"
static void impl_modem_firmware_list (MMModemFirmware *modem,
DBusGMethodInvocation *context);
static void impl_modem_firmware_select (MMModemFirmware *modem,
const char *slot,
DBusGMethodInvocation *context);
static void impl_modem_firmware_install (MMModemFirmware *modem,
const char *image,
const char *slot,
DBusGMethodInvocation *context);
#include "mm-modem-firmware-glue.h"
static void
async_call_done (MMModem *modem, GError *error, gpointer user_data)
{
DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
if (error)
dbus_g_method_return_error (context, error);
else
dbus_g_method_return (context);
}
static void
async_call_not_supported (MMModemFirmware *self,
MMModemFn callback,
gpointer user_data)
{
MMCallbackInfo *info;
info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
"Operation not supported");
mm_callback_info_schedule (info);
}
static void
firmware_list_done (MMModemFirmware *self,
const char *selected,
GHashTable *installed,
GHashTable *available,
GError *error,
gpointer user_data)
{
DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
if (error)
dbus_g_method_return_error (context, error);
else
dbus_g_method_return (context, selected, installed, available);
}
/*****************************************************************************/
static void
firmware_list_invoke (MMCallbackInfo *info)
{
MMModemFirmwareListFn callback = (MMModemFirmwareListFn) info->callback;
callback (MM_MODEM_FIRMWARE (info->modem), NULL, NULL, NULL, info->error, info->user_data);
}
void
mm_modem_firmware_list (MMModemFirmware *self,
MMModemFirmwareListFn callback,
gpointer user_data)
{
g_return_if_fail (MM_IS_MODEM_FIRMWARE (self));
g_return_if_fail (callback != NULL);
if (MM_MODEM_FIRMWARE_GET_INTERFACE (self)->list)
MM_MODEM_FIRMWARE_GET_INTERFACE (self)->list (self, callback, user_data);
else {
MMCallbackInfo *info;
info = mm_callback_info_new_full (MM_MODEM (self),
firmware_list_invoke,
G_CALLBACK (callback),
user_data);
info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
"Operation not supported");
mm_callback_info_schedule (info);
}
}
void
mm_modem_firmware_select (MMModemFirmware *self,
const char *slot,
MMModemFn callback,
gpointer user_data)
{
g_return_if_fail (MM_IS_MODEM_FIRMWARE (self));
g_return_if_fail (slot != NULL);
g_return_if_fail (callback != NULL);
if (MM_MODEM_FIRMWARE_GET_INTERFACE (self)->select)
MM_MODEM_FIRMWARE_GET_INTERFACE (self)->select (self, slot, callback, user_data);
else
async_call_not_supported (self, async_call_done, user_data);
}
void
mm_modem_firmware_install (MMModemFirmware *self,
const char *image,
const char *slot,
MMModemFn callback,
gpointer user_data)
{
g_return_if_fail (MM_IS_MODEM_FIRMWARE (self));
g_return_if_fail (slot != NULL);
g_return_if_fail (callback != NULL);
if (MM_MODEM_FIRMWARE_GET_INTERFACE (self)->install)
MM_MODEM_FIRMWARE_GET_INTERFACE (self)->install (self, image, slot, callback, user_data);
else
async_call_not_supported (self, async_call_done, user_data);
}
typedef struct {
char *image;
char *slot;
} FirmwareAuthInfo;
static void
firmware_auth_info_destroy (gpointer data)
{
FirmwareAuthInfo *info = data;
g_free (info->image);
g_free (info->slot);
memset (info, 0, sizeof (FirmwareAuthInfo));
g_free (info);
}
static FirmwareAuthInfo *
firmware_auth_info_new (const char *image,
const char *slot)
{
FirmwareAuthInfo *info;
info = g_malloc0 (sizeof (FirmwareAuthInfo));
info->image = g_strdup(image);
info->slot = g_strdup(slot);
return info;
}
static void
firmware_list_auth_cb (MMAuthRequest *req,
GObject *owner,
DBusGMethodInvocation *context,
gpointer user_data)
{
MMModemFirmware *self = MM_MODEM_FIRMWARE (owner);
GError *error = NULL;
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
dbus_g_method_return_error (context, error);
g_error_free (error);
} else
mm_modem_firmware_list (self, firmware_list_done, context);
}
static void
impl_modem_firmware_list (MMModemFirmware *modem, DBusGMethodInvocation *context)
{
GError *error = NULL;
if (!mm_modem_auth_request (MM_MODEM (modem),
MM_AUTHORIZATION_FIRMWARE,
context,
firmware_list_auth_cb,
NULL,
NULL,
&error)) {
dbus_g_method_return_error (context, error);
g_error_free(error);
}
}
static void
firmware_select_auth_cb (MMAuthRequest *req,
GObject *owner,
DBusGMethodInvocation *context,
gpointer user_data)
{
MMModemFirmware *self = MM_MODEM_FIRMWARE (owner);
FirmwareAuthInfo *info = user_data;
const char *slot = info->slot;
GError *error = NULL;
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
dbus_g_method_return_error (context, error);
g_error_free (error);
} else
mm_modem_firmware_select (self, slot, async_call_done, context);
}
static void
impl_modem_firmware_select (MMModemFirmware *modem,
const char *slot,
DBusGMethodInvocation *context)
{
GError *error = NULL;
FirmwareAuthInfo *info;
info = firmware_auth_info_new (NULL, slot);
if (!mm_modem_auth_request (MM_MODEM (modem),
MM_AUTHORIZATION_FIRMWARE,
context,
firmware_select_auth_cb,
info,
firmware_auth_info_destroy,
&error)) {
dbus_g_method_return_error (context, error);
g_error_free (error);
}
}
static void
firmware_install_auth_cb (MMAuthRequest *req,
GObject *owner,
DBusGMethodInvocation *context,
gpointer user_data)
{
MMModemFirmware *self = MM_MODEM_FIRMWARE (owner);
FirmwareAuthInfo *info = user_data;
const char *image = info->image;
const char *slot = info->slot;
GError *error = NULL;
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
dbus_g_method_return_error (context, error);
g_error_free (error);
} else
mm_modem_firmware_install (self, image, slot, async_call_done, context);
}
static void
impl_modem_firmware_install (MMModemFirmware *modem,
const char *image,
const char *slot,
DBusGMethodInvocation *context)
{
GError *error = NULL;
FirmwareAuthInfo *info;
info = firmware_auth_info_new (image, slot);
if (!mm_modem_auth_request (MM_MODEM (modem),
MM_AUTHORIZATION_FIRMWARE,
context,
firmware_install_auth_cb,
info,
firmware_auth_info_destroy,
&error)) {
dbus_g_method_return_error (context, error);
g_error_free (error);
}
}
GType
mm_modem_firmware_get_type (void)
{
static GType firmware_type = 0;
if (!G_UNLIKELY (firmware_type)) {
const GTypeInfo firmware_info = {
sizeof (MMModemFirmware), /* class_size */
NULL, /* base_init */
NULL, /* base_finalize */
NULL,
NULL, /* class_finalize */
NULL, /* class_data */
0,
0, /* n_preallocs */
NULL
};
firmware_type = g_type_register_static (G_TYPE_INTERFACE,
"MMModemFirmware",
&firmware_info, 0);
g_type_interface_add_prerequisite (firmware_type, G_TYPE_OBJECT);
dbus_g_object_type_install_info (firmware_type, &dbus_glib_mm_modem_firmware_object_info);
}
return firmware_type;
}

72
src/mm-modem-firmware.h Normal file
View File

@@ -0,0 +1,72 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* 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:
*
* Copyright (C) 2011 The Chromium OS Authors
*/
#ifndef MM_MODEM_FIRMWARE_H
#define MM_MODEM_FIRMWARE_H
#include <mm-modem.h>
#define MM_TYPE_MODEM_FIRMWARE (mm_modem_firmware_get_type ())
#define MM_MODEM_FIRMWARE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM_FIRMWARE, MMModemFirmware))
#define MM_IS_MODEM_FIRMWARE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM_FIRMWARE))
#define MM_MODEM_FIRMWARE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_MODEM_FIRMWARE, MMModemFirmware))
typedef struct _MMModemFirmware MMModemFirmware;
typedef void (*MMModemFirmwareListFn) (MMModemFirmware *modem,
const char *selected,
GHashTable *installed,
GHashTable *available,
GError *error,
gpointer user_data);
struct _MMModemFirmware {
GTypeInterface g_iface;
/* Methods */
void (*list) (MMModemFirmware *modem,
MMModemFirmwareListFn callback,
gpointer user_data);
void (*select) (MMModemFirmware *modem,
const char *slot,
MMModemFn callback,
gpointer user_data);
void (*install) (MMModemFirmware *modem,
const char *image,
const char *slot,
MMModemFn callback,
gpointer user_data);
};
GType mm_modem_firmware_get_type (void);
void mm_modem_firmware_list (MMModemFirmware *self,
MMModemFirmwareListFn callback,
gpointer user_data);
void mm_modem_firmware_select (MMModemFirmware *self,
const char *slot,
MMModemFn callback,
gpointer user_data);
void mm_modem_firmware_install (MMModemFirmware *self,
const char *image,
const char *slot,
MMModemFn callback,
gpointer user_data);
#endif /* MM_MODEM_FIRMWARE_H */