Files
ModemManager/src/mm-modem.c
Jason Glasgow 2dbca0baf8 core: make modem StateChanged signal consistent with API documentation
The new and old state arguments were flipped.
2011-03-31 15:29:12 -05:00

993 lines
31 KiB
C

/* -*- 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) 2008 - 2009 Novell, Inc.
* Copyright (C) 2009 - 2010 Red Hat, Inc.
*/
#include <config.h>
#include <string.h>
#include <dbus/dbus-glib.h>
#include "mm-modem.h"
#include "mm-log.h"
#include "mm-errors.h"
#include "mm-callback-info.h"
#include "mm-marshal.h"
static void impl_modem_enable (MMModem *modem, gboolean enable, DBusGMethodInvocation *context);
static void impl_modem_connect (MMModem *modem, const char *number, DBusGMethodInvocation *context);
static void impl_modem_disconnect (MMModem *modem, DBusGMethodInvocation *context);
static void impl_modem_get_ip4_config (MMModem *modem, DBusGMethodInvocation *context);
static void impl_modem_get_info (MMModem *modem, DBusGMethodInvocation *context);
static void impl_modem_reset (MMModem *modem, DBusGMethodInvocation *context);
static void impl_modem_factory_reset (MMModem *modem, const char *code, DBusGMethodInvocation *context);
#include "mm-modem-glue.h"
/* Should be used from callbacks to check whether the modem was removed after
* the callback's operation was started, but before the callback itself was
* called, in which case the MMModem passed to the callback is NULL.
*/
GError *
mm_modem_check_removed (MMModem *self, const GError *error)
{
if (!self) {
/* If the modem was NULL, the error *should* have been
* MM_MODEM_ERROR_REMOVED. If it wasn't, make it that.
*/
return g_error_new_literal (MM_MODEM_ERROR,
MM_MODEM_ERROR_REMOVED,
"The modem was removed.");
}
return error ? g_error_copy (error) : NULL;
}
static void
async_op_not_supported (MMModem *self,
MMModemFn callback,
gpointer user_data)
{
MMCallbackInfo *info;
info = mm_callback_info_new (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
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);
}
void
mm_modem_enable (MMModem *self,
MMModemFn callback,
gpointer user_data)
{
MMModemState state;
g_return_if_fail (MM_IS_MODEM (self));
g_return_if_fail (callback != NULL);
state = mm_modem_get_state (self);
if (state >= MM_MODEM_STATE_ENABLED) {
MMCallbackInfo *info;
info = mm_callback_info_new (self, callback, user_data);
if (state == MM_MODEM_STATE_ENABLING) {
info->error = g_error_new_literal (MM_MODEM_ERROR,
MM_MODEM_ERROR_OPERATION_IN_PROGRESS,
"The device is already being enabled.");
} else {
/* Already enabled */
}
mm_callback_info_schedule (info);
return;
}
if (MM_MODEM_GET_INTERFACE (self)->enable)
MM_MODEM_GET_INTERFACE (self)->enable (self, callback, user_data);
else
async_op_not_supported (self, callback, user_data);
}
static void
finish_disable (MMModem *self,
MMModemFn callback,
gpointer user_data)
{
if (MM_MODEM_GET_INTERFACE (self)->disable)
MM_MODEM_GET_INTERFACE (self)->disable (self, callback, user_data);
else
async_op_not_supported (self, callback, user_data);
}
typedef struct {
MMModemFn callback;
gpointer user_data;
} DisableDisconnectInfo;
static void
disable_disconnect_done (MMModem *self,
GError *error,
gpointer user_data)
{
DisableDisconnectInfo *cb_data = user_data;
GError *tmp_error = NULL;
/* Check for modem removal */
if (g_error_matches (error, MM_MODEM_ERROR, MM_MODEM_ERROR_REMOVED))
tmp_error = g_error_copy (error);
else if (!self) {
tmp_error = g_error_new_literal (MM_MODEM_ERROR,
MM_MODEM_ERROR_REMOVED,
"The modem was removed.");
}
/* And send an immediate error reply if the modem was removed */
if (tmp_error) {
cb_data->callback (NULL, tmp_error, cb_data->user_data);
g_free (cb_data);
g_error_free (tmp_error);
return;
}
if (error) {
char *device = mm_modem_get_device (self);
/* Don't really care what the error was; log it and proceed to disable */
g_warning ("%s: (%s): error disconnecting the modem while disabling: (%d) %s",
__func__,
device,
error ? error->code : -1,
error && error->message ? error->message : "(unknown)");
g_free (device);
}
finish_disable (self, cb_data->callback, cb_data->user_data);
g_free (cb_data);
}
void
mm_modem_disable (MMModem *self,
MMModemFn callback,
gpointer user_data)
{
MMModemState state;
g_return_if_fail (MM_IS_MODEM (self));
g_return_if_fail (callback != NULL);
state = mm_modem_get_state (self);
if (state <= MM_MODEM_STATE_DISABLING) {
MMCallbackInfo *info;
info = mm_callback_info_new (self, callback, user_data);
if (state == MM_MODEM_STATE_DISABLING) {
info->error = g_error_new_literal (MM_MODEM_ERROR,
MM_MODEM_ERROR_OPERATION_IN_PROGRESS,
"The device is already being disabled.");
} else {
/* Already disabled */
}
mm_callback_info_schedule (info);
return;
}
/* If the modem is connected, disconnect it */
if (state >= MM_MODEM_STATE_CONNECTING) {
DisableDisconnectInfo *cb_data;
cb_data = g_malloc0 (sizeof (DisableDisconnectInfo));
cb_data->callback = callback;
cb_data->user_data = user_data;
mm_modem_disconnect (self, disable_disconnect_done, cb_data);
} else
finish_disable (self, callback, user_data);
}
static void
impl_modem_enable (MMModem *modem,
gboolean enable,
DBusGMethodInvocation *context)
{
if (enable)
mm_modem_enable (modem, async_call_done, context);
else
mm_modem_disable (modem, async_call_done, context);
}
void
mm_modem_connect (MMModem *self,
const char *number,
MMModemFn callback,
gpointer user_data)
{
MMModemState state;
g_return_if_fail (MM_IS_MODEM (self));
g_return_if_fail (callback != NULL);
g_return_if_fail (number != NULL);
state = mm_modem_get_state (self);
if (state >= MM_MODEM_STATE_CONNECTING) {
MMCallbackInfo *info;
/* Already connecting */
info = mm_callback_info_new (self, callback, user_data);
if (state == MM_MODEM_STATE_CONNECTING) {
info->error = g_error_new_literal (MM_MODEM_ERROR,
MM_MODEM_ERROR_OPERATION_IN_PROGRESS,
"The device is already being connected.");
} else {
/* already connected */
}
mm_callback_info_schedule (info);
return;
}
if (MM_MODEM_GET_INTERFACE (self)->connect)
MM_MODEM_GET_INTERFACE (self)->connect (self, number, callback, user_data);
else
async_op_not_supported (self, callback, user_data);
}
static void
impl_modem_connect (MMModem *modem,
const char *number,
DBusGMethodInvocation *context)
{
mm_modem_connect (modem, number, async_call_done, context);
}
static void
get_ip4_invoke (MMCallbackInfo *info)
{
MMModemIp4Fn callback = (MMModemIp4Fn) info->callback;
callback (info->modem,
GPOINTER_TO_UINT (mm_callback_info_get_data (info, "ip4-address")),
(GArray *) mm_callback_info_get_data (info, "ip4-dns"),
info->error, info->user_data);
}
void
mm_modem_get_ip4_config (MMModem *self,
MMModemIp4Fn callback,
gpointer user_data)
{
g_return_if_fail (MM_IS_MODEM (self));
g_return_if_fail (callback != NULL);
if (MM_MODEM_GET_INTERFACE (self)->get_ip4_config)
MM_MODEM_GET_INTERFACE (self)->get_ip4_config (self, callback, user_data);
else {
MMCallbackInfo *info;
info = mm_callback_info_new_full (self,
get_ip4_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);
}
}
static void
value_array_add_uint (GValueArray *array, guint32 i)
{
GValue value = { 0, };
g_value_init (&value, G_TYPE_UINT);
g_value_set_uint (&value, i);
g_value_array_append (array, &value);
g_value_unset (&value);
}
static void
get_ip4_done (MMModem *modem,
guint32 address,
GArray *dns,
GError *error,
gpointer user_data)
{
DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
if (error)
dbus_g_method_return_error (context, error);
else {
GValueArray *array;
guint32 dns1 = 0;
guint32 dns2 = 0;
guint32 dns3 = 0;
array = g_value_array_new (4);
if (dns) {
if (dns->len > 0)
dns1 = g_array_index (dns, guint32, 0);
if (dns->len > 1)
dns2 = g_array_index (dns, guint32, 1);
if (dns->len > 2)
dns3 = g_array_index (dns, guint32, 2);
}
value_array_add_uint (array, address);
value_array_add_uint (array, dns1);
value_array_add_uint (array, dns2);
value_array_add_uint (array, dns3);
dbus_g_method_return (context, array);
}
}
static void
impl_modem_get_ip4_config (MMModem *modem,
DBusGMethodInvocation *context)
{
mm_modem_get_ip4_config (modem, get_ip4_done, context);
}
void
mm_modem_disconnect (MMModem *self,
MMModemFn callback,
gpointer user_data)
{
MMModemState state;
g_return_if_fail (MM_IS_MODEM (self));
g_return_if_fail (callback != NULL);
state = mm_modem_get_state (self);
if (state <= MM_MODEM_STATE_DISCONNECTING) {
MMCallbackInfo *info;
/* Already connecting */
info = mm_callback_info_new (self, callback, user_data);
if (state == MM_MODEM_STATE_DISCONNECTING) {
info->error = g_error_new_literal (MM_MODEM_ERROR,
MM_MODEM_ERROR_OPERATION_IN_PROGRESS,
"The device is already being disconnected.");
} else {
/* already disconnected */
}
mm_callback_info_schedule (info);
return;
}
if (MM_MODEM_GET_INTERFACE (self)->disconnect)
MM_MODEM_GET_INTERFACE (self)->disconnect (self, callback, user_data);
else
async_op_not_supported (self, callback, user_data);
}
static void
impl_modem_disconnect (MMModem *modem,
DBusGMethodInvocation *context)
{
mm_modem_disconnect (modem, async_call_done, context);
}
static void
info_call_done (MMModem *self,
const char *manufacturer,
const char *model,
const char *version,
GError *error,
gpointer user_data)
{
DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
if (error)
dbus_g_method_return_error (context, error);
else {
GValueArray *array;
GValue value = { 0, };
array = g_value_array_new (3);
/* Manufacturer */
g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, manufacturer);
g_value_array_append (array, &value);
g_value_unset (&value);
/* Model */
g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, model);
g_value_array_append (array, &value);
g_value_unset (&value);
/* Version */
g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, version);
g_value_array_append (array, &value);
g_value_unset (&value);
dbus_g_method_return (context, array);
}
}
static void
info_invoke (MMCallbackInfo *info)
{
MMModemInfoFn callback = (MMModemInfoFn) info->callback;
callback (info->modem, NULL, NULL, NULL, info->error, info->user_data);
}
static void
info_call_not_supported (MMModem *self,
MMModemInfoFn callback,
gpointer user_data)
{
MMCallbackInfo *info;
info = mm_callback_info_new_full (MM_MODEM (self), info_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_get_info (MMModem *self,
MMModemInfoFn callback,
gpointer user_data)
{
g_return_if_fail (MM_IS_MODEM (self));
g_return_if_fail (callback != NULL);
if (MM_MODEM_GET_INTERFACE (self)->get_info)
MM_MODEM_GET_INTERFACE (self)->get_info (self, callback, user_data);
else
info_call_not_supported (self, callback, user_data);
}
static void
impl_modem_get_info (MMModem *modem,
DBusGMethodInvocation *context)
{
mm_modem_get_info (modem, info_call_done, context);
}
/*****************************************************************************/
static void
reset_auth_cb (MMAuthRequest *req,
GObject *owner,
DBusGMethodInvocation *context,
gpointer user_data)
{
MMModem *self = MM_MODEM (owner);
GError *error = NULL;
/* Return any authorization error, otherwise try to reset the modem */
if (!mm_modem_auth_finish (self, req, &error)) {
dbus_g_method_return_error (context, error);
g_error_free (error);
} else
mm_modem_reset (self, async_call_done, context);
}
static void
impl_modem_reset (MMModem *modem, DBusGMethodInvocation *context)
{
GError *error = NULL;
/* Make sure the caller is authorized to reset the device */
if (!mm_modem_auth_request (MM_MODEM (modem),
MM_AUTHORIZATION_DEVICE_CONTROL,
context,
reset_auth_cb,
NULL, NULL,
&error)) {
dbus_g_method_return_error (context, error);
g_error_free (error);
}
}
void
mm_modem_reset (MMModem *self,
MMModemFn callback,
gpointer user_data)
{
g_return_if_fail (MM_IS_MODEM (self));
g_return_if_fail (callback != NULL);
if (MM_MODEM_GET_INTERFACE (self)->reset)
MM_MODEM_GET_INTERFACE (self)->reset (self, callback, user_data);
else
async_op_not_supported (self, callback, user_data);
}
/*****************************************************************************/
static void
factory_reset_auth_cb (MMAuthRequest *req,
GObject *owner,
DBusGMethodInvocation *context,
gpointer user_data)
{
MMModem *self = MM_MODEM (owner);
const char *code = user_data;
GError *error = NULL;
/* Return any authorization error, otherwise try to reset the modem */
if (!mm_modem_auth_finish (self, req, &error)) {
dbus_g_method_return_error (context, error);
g_error_free (error);
} else
mm_modem_factory_reset (self, code, async_call_done, context);
}
static void
impl_modem_factory_reset (MMModem *modem,
const char *code,
DBusGMethodInvocation *context)
{
GError *error = NULL;
/* Make sure the caller is authorized to reset the device */
if (!mm_modem_auth_request (MM_MODEM (modem),
MM_AUTHORIZATION_DEVICE_CONTROL,
context,
factory_reset_auth_cb,
g_strdup (code),
g_free,
&error)) {
dbus_g_method_return_error (context, error);
g_error_free (error);
}
}
void
mm_modem_factory_reset (MMModem *self,
const char *code,
MMModemFn callback,
gpointer user_data)
{
g_return_if_fail (MM_IS_MODEM (self));
g_return_if_fail (callback != NULL);
g_return_if_fail (code != NULL);
if (MM_MODEM_GET_INTERFACE (self)->factory_reset)
MM_MODEM_GET_INTERFACE (self)->factory_reset (self, code, callback, user_data);
else
async_op_not_supported (self, callback, user_data);
}
/*****************************************************************************/
void
mm_modem_get_supported_charsets (MMModem *self,
MMModemUIntFn callback,
gpointer user_data)
{
MMCallbackInfo *info;
g_return_if_fail (MM_IS_MODEM (self));
g_return_if_fail (callback != NULL);
if (MM_MODEM_GET_INTERFACE (self)->get_supported_charsets)
MM_MODEM_GET_INTERFACE (self)->get_supported_charsets (self, callback, user_data);
else {
info = mm_callback_info_uint_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);
}
}
void
mm_modem_set_charset (MMModem *self,
MMModemCharset charset,
MMModemFn callback,
gpointer user_data)
{
MMCallbackInfo *info;
g_return_if_fail (charset != MM_MODEM_CHARSET_UNKNOWN);
g_return_if_fail (MM_IS_MODEM (self));
g_return_if_fail (callback != NULL);
if (MM_MODEM_GET_INTERFACE (self)->set_charset)
MM_MODEM_GET_INTERFACE (self)->set_charset (self, charset, callback, user_data);
else {
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);
}
}
/*****************************************************************************/
gboolean
mm_modem_owns_port (MMModem *self,
const char *subsys,
const char *name)
{
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
g_return_val_if_fail (subsys, FALSE);
g_return_val_if_fail (name, FALSE);
g_assert (MM_MODEM_GET_INTERFACE (self)->owns_port);
return MM_MODEM_GET_INTERFACE (self)->owns_port (self, subsys, name);
}
gboolean
mm_modem_grab_port (MMModem *self,
const char *subsys,
const char *name,
MMPortType suggested_type,
gpointer user_data,
GError **error)
{
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
g_return_val_if_fail (subsys, FALSE);
g_return_val_if_fail (name, FALSE);
g_assert (MM_MODEM_GET_INTERFACE (self)->grab_port);
return MM_MODEM_GET_INTERFACE (self)->grab_port (self, subsys, name, suggested_type, user_data, error);
}
void
mm_modem_release_port (MMModem *self,
const char *subsys,
const char *name)
{
g_return_if_fail (self != NULL);
g_return_if_fail (MM_IS_MODEM (self));
g_return_if_fail (subsys);
g_return_if_fail (name);
g_assert (MM_MODEM_GET_INTERFACE (self)->release_port);
MM_MODEM_GET_INTERFACE (self)->release_port (self, subsys, name);
}
gboolean
mm_modem_get_valid (MMModem *self)
{
gboolean valid = FALSE;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
g_object_get (G_OBJECT (self), MM_MODEM_VALID, &valid, NULL);
return valid;
}
char *
mm_modem_get_device (MMModem *self)
{
char *device;
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (MM_IS_MODEM (self), NULL);
g_object_get (G_OBJECT (self), MM_MODEM_MASTER_DEVICE, &device, NULL);
return device;
}
MMModemState
mm_modem_get_state (MMModem *self)
{
MMModemState state = MM_MODEM_STATE_UNKNOWN;
g_object_get (G_OBJECT (self), MM_MODEM_STATE, &state, NULL);
return state;
}
static const char *
state_to_string (MMModemState state)
{
switch (state) {
case MM_MODEM_STATE_UNKNOWN:
return "unknown";
case MM_MODEM_STATE_DISABLED:
return "disabled";
case MM_MODEM_STATE_DISABLING:
return "disabling";
case MM_MODEM_STATE_ENABLING:
return "enabling";
case MM_MODEM_STATE_ENABLED:
return "enabled";
case MM_MODEM_STATE_SEARCHING:
return "searching";
case MM_MODEM_STATE_REGISTERED:
return "registered";
case MM_MODEM_STATE_DISCONNECTING:
return "disconnecting";
case MM_MODEM_STATE_CONNECTING:
return "connecting";
case MM_MODEM_STATE_CONNECTED:
return "connected";
default:
g_assert_not_reached ();
break;
}
g_assert_not_reached ();
return "(invalid)";
}
void
mm_modem_set_state (MMModem *self,
MMModemState new_state,
MMModemStateReason reason)
{
MMModemState old_state = MM_MODEM_STATE_UNKNOWN;
const char *dbus_path;
g_object_get (G_OBJECT (self), MM_MODEM_STATE, &old_state, NULL);
if (new_state != old_state) {
g_object_set (G_OBJECT (self), MM_MODEM_STATE, new_state, NULL);
g_signal_emit_by_name (G_OBJECT (self), "state-changed", old_state, new_state, reason);
dbus_path = (const char *) g_object_get_data (G_OBJECT (self), DBUS_PATH_TAG);
if (dbus_path) {
mm_info ("Modem %s: state changed (%s -> %s)",
dbus_path,
state_to_string (old_state),
state_to_string (new_state));
}
}
}
/*****************************************************************************/
gboolean
mm_modem_auth_request (MMModem *self,
const char *authorization,
DBusGMethodInvocation *context,
MMAuthRequestCb callback,
gpointer callback_data,
GDestroyNotify notify,
GError **error)
{
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
g_return_val_if_fail (authorization != NULL, FALSE);
g_return_val_if_fail (context != NULL, FALSE);
g_return_val_if_fail (callback != NULL, FALSE);
g_return_val_if_fail (MM_MODEM_GET_INTERFACE (self)->auth_request, FALSE);
return MM_MODEM_GET_INTERFACE (self)->auth_request (self,
authorization,
context,
callback,
callback_data,
notify,
error);
}
gboolean
mm_modem_auth_finish (MMModem *self,
MMAuthRequest *req,
GError **error)
{
gboolean success;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
g_return_val_if_fail (req != NULL, FALSE);
g_return_val_if_fail (MM_MODEM_GET_INTERFACE (self)->auth_finish, FALSE);
success = MM_MODEM_GET_INTERFACE (self)->auth_finish (self, req, error);
/* If the request failed, the implementor *should* return an error */
if (!success && error)
g_warn_if_fail (*error != NULL);
return success;
}
/*****************************************************************************/
static void
mm_modem_init (gpointer g_iface)
{
GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
static gboolean initialized = FALSE;
if (initialized)
return;
/* Properties */
g_object_interface_install_property
(g_iface,
g_param_spec_string (MM_MODEM_DATA_DEVICE,
"Device",
"Data device",
NULL,
G_PARAM_READWRITE));
g_object_interface_install_property
(g_iface,
g_param_spec_string (MM_MODEM_MASTER_DEVICE,
"MasterDevice",
"Master modem parent device of all the modem's ports",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_interface_install_property
(g_iface,
g_param_spec_string (MM_MODEM_DRIVER,
"Driver",
"Driver",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_interface_install_property
(g_iface,
g_param_spec_string (MM_MODEM_PLUGIN,
"Plugin",
"Plugin name",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_interface_install_property
(g_iface,
g_param_spec_uint (MM_MODEM_TYPE,
"Type",
"Type",
0, G_MAXUINT32, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_interface_install_property
(g_iface,
g_param_spec_uint (MM_MODEM_IP_METHOD,
"IP method",
"IP configuration method",
MM_MODEM_IP_METHOD_PPP,
MM_MODEM_IP_METHOD_DHCP,
MM_MODEM_IP_METHOD_PPP,
G_PARAM_READWRITE));
g_object_interface_install_property
(g_iface,
g_param_spec_boolean (MM_MODEM_VALID,
"Valid",
"Modem is valid",
FALSE,
G_PARAM_READABLE));
g_object_interface_install_property
(g_iface,
g_param_spec_uint (MM_MODEM_STATE,
"State",
"State",
MM_MODEM_STATE_UNKNOWN,
MM_MODEM_STATE_LAST,
MM_MODEM_STATE_UNKNOWN,
G_PARAM_READWRITE));
g_object_interface_install_property
(g_iface,
g_param_spec_boolean (MM_MODEM_ENABLED,
"Enabled",
"Modem is enabled",
FALSE,
G_PARAM_READABLE));
g_object_interface_install_property
(g_iface,
g_param_spec_string (MM_MODEM_EQUIPMENT_IDENTIFIER,
"EquipmentIdentifier",
"The equipment identifier of the device",
NULL,
G_PARAM_READABLE));
g_object_interface_install_property
(g_iface,
g_param_spec_string (MM_MODEM_DEVICE_IDENTIFIER,
"DeviceIdentifier",
"A best-effort identifer of the device",
NULL,
G_PARAM_READABLE));
g_object_interface_install_property
(g_iface,
g_param_spec_string (MM_MODEM_UNLOCK_REQUIRED,
"UnlockRequired",
"Whether or not the modem requires an unlock "
"code to become usable, and if so, which unlock code is required",
NULL,
G_PARAM_READABLE));
g_object_interface_install_property
(g_iface,
g_param_spec_uint (MM_MODEM_UNLOCK_RETRIES,
"UnlockRetries",
"The remaining number of unlock attempts",
0, G_MAXUINT32, 0,
G_PARAM_READABLE));
g_object_interface_install_property
(g_iface,
g_param_spec_uint (MM_MODEM_HW_VID,
"Hardware vendor ID",
"Hardware vendor ID",
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_interface_install_property
(g_iface,
g_param_spec_uint (MM_MODEM_HW_PID,
"Hardware product ID",
"Hardware product ID",
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/* Signals */
g_signal_new ("state-changed",
iface_type,
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (MMModem, state_changed),
NULL, NULL,
mm_marshal_VOID__UINT_UINT_UINT,
G_TYPE_NONE, 3,
G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
initialized = TRUE;
}
GType
mm_modem_get_type (void)
{
static GType modem_type = 0;
if (!G_UNLIKELY (modem_type)) {
const GTypeInfo modem_info = {
sizeof (MMModem), /* class_size */
mm_modem_init, /* base_init */
NULL, /* base_finalize */
NULL,
NULL, /* class_finalize */
NULL, /* class_data */
0,
0, /* n_preallocs */
NULL
};
modem_type = g_type_register_static (G_TYPE_INTERFACE,
"MMModem",
&modem_info, 0);
g_type_interface_add_prerequisite (modem_type, G_TYPE_OBJECT);
dbus_g_object_type_install_info (modem_type, &dbus_glib_mm_modem_object_info);
}
return modem_type;
}