Files
ModemManager/src/mm-modem.c
Eric Shienbrood e7b6b2dc1c core: keep track of all PIN retry counts
Added a PinRetryCounts property on org.freedesktop.ModemManager.Modem.
This is dictionary that records the number of PIN tries remaining
for each of the possible PIN code types for which the modem is
capable of reporting the count. Also, these counts are kept up
to date across ChangePin and EnablePin operations, not just when
an unlock is attempted.
2011-11-16 17:42:50 -06:00

984 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"
#define MM_MODEM_PIN_RETRY_COUNTS_PROP_TYPE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_UINT))
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_CONNECTED,
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_boxed (MM_MODEM_PIN_RETRY_COUNTS,
"PinRetryCounts",
"The remaining number of attempts for each PIN type",
MM_MODEM_PIN_RETRY_COUNTS_PROP_TYPE,
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;
}