Implement simple interface.

This commit is contained in:
Tambet Ingo
2009-01-19 10:45:18 +02:00
parent 423637272a
commit 17b739c73d
6 changed files with 513 additions and 0 deletions
+1
View File
@@ -11,4 +11,5 @@ EXTRA_DIST = \
mm-modem-gsm-mbm.xml \
mm-modem-gsm-network.xml \
mm-modem-gsm-sms.xml \
mm-modem-simple.xml \
mm-serial-error.xml
+58
View File
@@ -0,0 +1,58 @@
<?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.Simple">
<method name="Connect">
<tp:docstring>
Do everything needed to connect the modem.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_modem_simple_connect"/>
<arg name="properties" type="a{sv}" direction="in">
<tp:docstring>
Dictionary of properties needed to get the modem connected.
Each implementation is free to add it's own specific key-value pairs. The predefined
common ones are:
'pin' : string
'network_id' : string
'band' : uint
'network_mode' : uint
'apn' : string
'number' : string
</tp:docstring>
</arg>
</method>
<!--
<method name="Disconnect">
<tp:docstring>
Disconnect modem.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_modem_simple_disconnect"/>
</method>
-->
<method name="GetStatus">
<tp:docstring>
Get the modem status.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_modem_simple_get_status"/>
<arg name="properties" type="a{sv}" direction="out">
<tp:docstring>
Dictionary of properties.
Each implementation is free to add it's own specific key-value pairs. The predefined
common ones are:
'state' : uint (always)
'signal_quality' : uint (state >= registered)
'operator_code' : string (state >= registered)
'operator_name' : string (state >= registered)
'band' : uint (state >= registered)
'network_mode' : uint (state >= registered)
</tp:docstring>
</arg>
</method>
</interface>
</node>
+6
View File
@@ -29,6 +29,8 @@ modem_manager_SOURCES = \
mm-modem-gsm-card.h \
mm-modem-gsm-network.c \
mm-modem-gsm-network.h \
mm-modem-simple.c \
mm-modem-simple.h \
mm-options.c \
mm-options.h \
mm-plugin.c \
@@ -46,6 +48,9 @@ mm-manager-glue.h: $(top_srcdir)/introspection/mm-manager.xml
mm-modem-glue.h: $(top_srcdir)/introspection/mm-modem.xml
dbus-binding-tool --prefix=mm_modem --mode=glib-server --output=$@ $<
mm-modem-simple-glue.h: $(top_srcdir)/introspection/mm-modem-simple.xml
dbus-binding-tool --prefix=mm_modem_simple --mode=glib-server --output=$@ $<
mm-modem-cdma-glue.h: $(top_srcdir)/introspection/mm-modem-cdma.xml
dbus-binding-tool --prefix=mm_modem_cdma --mode=glib-server --output=$@ $<
@@ -59,6 +64,7 @@ mm-modem-gsm-network-glue.h: $(top_srcdir)/introspection/mm-modem-gsm-network.xm
BUILT_SOURCES = \
mm-manager-glue.h \
mm-modem-glue.h \
mm-modem-simple-glue.h \
mm-modem-cdma-glue.h \
mm-modem-gsm-card-glue.h \
mm-modem-gsm-network-glue.h
+260
View File
@@ -6,6 +6,7 @@
#include "mm-generic-gsm.h"
#include "mm-modem-gsm-card.h"
#include "mm-modem-gsm-network.h"
#include "mm-modem-simple.h"
#include "mm-errors.h"
#include "mm-callback-info.h"
#include "mm-serial-parsers.h"
@@ -1078,6 +1079,253 @@ get_signal_quality (MMModemGsmNetwork *modem,
mm_serial_queue_command (MM_SERIAL (modem), "+CSQ", 3, get_signal_quality_done, info);
}
/*****************************************************************************/
/* MMModemSimple interface */
typedef enum {
SIMPLE_STATE_BEGIN = 0,
SIMPLE_STATE_ENABLE,
SIMPLE_STATE_CHECK_PIN,
SIMPLE_STATE_REGISTER,
SIMPLE_STATE_SET_APN,
SIMPLE_STATE_CONNECT,
SIMPLE_STATE_DONE
} SimpleState;
static const char *
simple_get_string_property (MMCallbackInfo *info, const char *name, GError **error)
{
GHashTable *properties = (GHashTable *) mm_callback_info_get_data (info, "simple-connect-properties");
GValue *value;
value = (GValue *) g_hash_table_lookup (properties, name);
if (!value)
return NULL;
if (G_VALUE_HOLDS_STRING (value))
return g_value_get_string (value);
g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
"Invalid property type for '%s': %s (string expected)",
name, G_VALUE_TYPE_NAME (value));
return NULL;
}
static void
simple_state_machine (MMModem *modem, GError *error, gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
const char *str;
SimpleState state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "simple-connect-state"));
gboolean need_pin = FALSE;
if (error) {
if (state == SIMPLE_STATE_CHECK_PIN && g_error_matches (error, MM_MOBILE_ERROR, MM_MOBILE_ERROR_SIM_PIN))
need_pin = TRUE;
else {
info->error = g_error_copy (error);
goto out;
}
}
switch (state) {
case SIMPLE_STATE_BEGIN:
state = SIMPLE_STATE_ENABLE;
mm_modem_enable (modem, TRUE, simple_state_machine, info);
break;
case SIMPLE_STATE_ENABLE:
state = SIMPLE_STATE_CHECK_PIN;
mm_generic_gsm_check_pin (MM_GENERIC_GSM (modem), simple_state_machine, info);
break;
case SIMPLE_STATE_CHECK_PIN:
if (need_pin) {
str = simple_get_string_property (info, "pin", &info->error);
if (str)
mm_modem_gsm_card_send_pin (MM_MODEM_GSM_CARD (modem), str, simple_state_machine, info);
else
info->error = g_error_copy (error);
} else {
str = simple_get_string_property (info, "network_id", &info->error);
state = SIMPLE_STATE_REGISTER;
if (!info->error)
mm_modem_gsm_network_register (MM_MODEM_GSM_NETWORK (modem), str, simple_state_machine, info);
}
break;
case SIMPLE_STATE_REGISTER:
str = simple_get_string_property (info, "apn", &info->error);
if (str) {
state = SIMPLE_STATE_SET_APN;
mm_modem_gsm_network_set_apn (MM_MODEM_GSM_NETWORK (modem), str, simple_state_machine, info);
break;
}
/* Fall through */
case SIMPLE_STATE_SET_APN:
str = simple_get_string_property (info, "number", &info->error);
state = SIMPLE_STATE_CONNECT;
mm_modem_connect (modem, str, simple_state_machine, info);
break;
case SIMPLE_STATE_CONNECT:
state = SIMPLE_STATE_DONE;
break;
case SIMPLE_STATE_DONE:
break;
}
out:
if (info->error || state == SIMPLE_STATE_DONE)
mm_callback_info_schedule (info);
else
mm_callback_info_set_data (info, "simple-connect-state", GUINT_TO_POINTER (state), NULL);
}
static void
simple_connect (MMModemSimple *simple,
GHashTable *properties,
MMModemFn callback,
gpointer user_data)
{
MMCallbackInfo *info;
info = mm_callback_info_new (MM_MODEM (simple), callback, user_data);
mm_callback_info_set_data (info, "simple-connect-properties",
g_hash_table_ref (properties),
(GDestroyNotify) g_hash_table_unref);
/* At least number must be present */
if (!simple_get_string_property (info, "number", &info->error)) {
if (!info->error)
info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Missing number property");
}
simple_state_machine (MM_MODEM (simple), NULL, info);
}
static void
simple_free_gvalue (gpointer data)
{
g_value_unset ((GValue *) data);
g_slice_free (GValue, data);
}
static GValue *
simple_uint_value (guint32 i)
{
GValue *val;
val = g_slice_new0 (GValue);
g_value_init (val, G_TYPE_UINT);
g_value_set_uint (val, i);
return val;
}
static GValue *
simple_string_value (const char *str)
{
GValue *val;
val = g_slice_new0 (GValue);
g_value_init (val, G_TYPE_STRING);
g_value_set_string (val, str);
return val;
}
static void
simple_status_got_signal_quality (MMModem *modem,
guint32 result,
GError *error,
gpointer user_data)
{
if (error)
g_warning ("Error getting signal quality: %s", error->message);
else
g_hash_table_insert ((GHashTable *) user_data, "signal_quality", simple_uint_value (result));
}
static void
simple_status_got_band (MMModem *modem,
guint32 result,
GError *error,
gpointer user_data)
{
/* Ignore band errors since there's no generic implementation for it */
if (!error)
g_hash_table_insert ((GHashTable *) user_data, "band", simple_uint_value (result));
}
static void
simple_status_got_mode (MMModem *modem,
guint32 result,
GError *error,
gpointer user_data)
{
/* Ignore network mode errors since there's no generic implementation for it */
if (!error)
g_hash_table_insert ((GHashTable *) user_data, "network_mode", simple_uint_value (result));
}
static void
simple_status_got_reg_info (MMModemGsmNetwork *modem,
MMModemGsmNetworkRegStatus status,
const char *oper_code,
const char *oper_name,
GError *error,
gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
GHashTable *properties;
if (error)
info->error = g_error_copy (error);
else {
properties = (GHashTable *) mm_callback_info_get_data (info, "simple-get-status");
g_hash_table_insert (properties, "registration_status", simple_uint_value (status));
g_hash_table_insert (properties, "operator_code", simple_string_value (oper_code));
g_hash_table_insert (properties, "operator_name", simple_string_value (oper_name));
}
mm_callback_info_schedule (info);
}
static void
simple_get_status_invoke (MMCallbackInfo *info)
{
MMModemSimpleGetStatusFn callback = (MMModemSimpleGetStatusFn) info->callback;
callback (MM_MODEM_SIMPLE (info->modem),
(GHashTable *) mm_callback_info_get_data (info, "simple-get-status"),
info->error, info->user_data);
}
static void
simple_get_status (MMModemSimple *simple,
MMModemSimpleGetStatusFn callback,
gpointer user_data)
{
MMModemGsmNetwork *gsm;
GHashTable *properties;
MMCallbackInfo *info;
info = mm_callback_info_new_full (MM_MODEM (simple),
simple_get_status_invoke,
G_CALLBACK (callback),
user_data);
properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, simple_free_gvalue);
mm_callback_info_set_data (info, "simple-get-status", properties, (GDestroyNotify) g_hash_table_unref);
gsm = MM_MODEM_GSM_NETWORK (simple);
mm_modem_gsm_network_get_signal_quality (gsm, simple_status_got_signal_quality, properties);
mm_modem_gsm_network_get_band (gsm, simple_status_got_band, properties);
mm_modem_gsm_network_get_mode (gsm, simple_status_got_mode, properties);
mm_modem_gsm_network_get_registration_info (gsm, simple_status_got_reg_info, properties);
}
/*****************************************************************************/
static void
@@ -1110,6 +1358,13 @@ modem_gsm_network_init (MMModemGsmNetwork *class)
class->get_signal_quality = get_signal_quality;
}
static void
modem_simple_init (MMModemSimple *class)
{
class->connect = simple_connect;
class->get_status = simple_get_status;
}
static void
mm_generic_gsm_init (MMGenericGsm *self)
{
@@ -1237,11 +1492,16 @@ mm_generic_gsm_get_type (void)
(GInterfaceInitFunc) modem_gsm_network_init
};
static const GInterfaceInfo modem_simple_info = {
(GInterfaceInitFunc) modem_simple_init
};
generic_gsm_type = g_type_register_static (MM_TYPE_SERIAL, "MMGenericGsm", &generic_gsm_type_info, 0);
g_type_add_interface_static (generic_gsm_type, MM_TYPE_MODEM, &modem_iface_info);
g_type_add_interface_static (generic_gsm_type, MM_TYPE_MODEM_GSM_CARD, &modem_gsm_card_info);
g_type_add_interface_static (generic_gsm_type, MM_TYPE_MODEM_GSM_NETWORK, &modem_gsm_network_info);
g_type_add_interface_static (generic_gsm_type, MM_TYPE_MODEM_SIMPLE, &modem_simple_info);
}
return generic_gsm_type;
+142
View File
@@ -0,0 +1,142 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
#include <dbus/dbus-glib.h>
#include "mm-modem-simple.h"
#include "mm-errors.h"
#include "mm-callback-info.h"
static void impl_modem_simple_connect (MMModemSimple *self, GHashTable *properties, DBusGMethodInvocation *context);
static void impl_modem_simple_get_status (MMModemSimple *self, DBusGMethodInvocation *context);
#include "mm-modem-simple-glue.h"
void
mm_modem_simple_connect (MMModemSimple *self,
GHashTable *properties,
MMModemFn callback,
gpointer user_data)
{
g_return_if_fail (MM_IS_MODEM_SIMPLE (self));
g_return_if_fail (properties != NULL);
if (MM_MODEM_SIMPLE_GET_INTERFACE (self)->connect)
MM_MODEM_SIMPLE_GET_INTERFACE (self)->connect (self, properties, callback, user_data);
else {
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
simple_get_status_invoke (MMCallbackInfo *info)
{
MMModemSimpleGetStatusFn callback = (MMModemSimpleGetStatusFn) info->callback;
callback (MM_MODEM_SIMPLE (info->modem), NULL, info->error, info->user_data);
}
void
mm_modem_simple_get_status (MMModemSimple *self,
MMModemSimpleGetStatusFn callback,
gpointer user_data)
{
g_return_if_fail (MM_IS_MODEM_SIMPLE (self));
if (MM_MODEM_SIMPLE_GET_INTERFACE (self)->get_status)
MM_MODEM_SIMPLE_GET_INTERFACE (self)->get_status (self, callback, user_data);
else {
MMCallbackInfo *info;
info = mm_callback_info_new_full (MM_MODEM (self),
simple_get_status_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
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
impl_modem_simple_connect (MMModemSimple *self,
GHashTable *properties,
DBusGMethodInvocation *context)
{
mm_modem_simple_connect (self, properties, async_call_done, context);
}
static void
get_status_done (MMModem *modem,
GHashTable *properties,
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, properties);
}
static void
impl_modem_simple_get_status (MMModemSimple *self,
DBusGMethodInvocation *context)
{
mm_modem_simple_get_status (self, get_status_done, context);
}
/*****************************************************************************/
static void
mm_modem_simple_init (gpointer g_iface)
{
}
GType
mm_modem_simple_get_type (void)
{
static GType modem_type = 0;
if (!G_UNLIKELY (modem_type)) {
const GTypeInfo modem_info = {
sizeof (MMModemSimple), /* class_size */
mm_modem_simple_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,
"MMModemSimple",
&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_simple_object_info);
}
return modem_type;
}
+46
View File
@@ -0,0 +1,46 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
#ifndef MM_MODEM_SIMPLE_H
#define MM_MODEM_SIMPLE_H
#include <glib-object.h>
#include <mm-modem.h>
#define MM_TYPE_MODEM_SIMPLE (mm_modem_simple_get_type ())
#define MM_MODEM_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM_SIMPLE, MMModemSimple))
#define MM_IS_MODEM_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM_SIMPLE))
#define MM_MODEM_SIMPLE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_MODEM_SIMPLE, MMModemSimple))
typedef struct _MMModemSimple MMModemSimple;
typedef void (*MMModemSimpleGetStatusFn) (MMModemSimple *modem,
GHashTable *properties,
GError *error,
gpointer user_data);
struct _MMModemSimple {
GTypeInterface g_iface;
/* Methods */
void (*connect) (MMModemSimple *self,
GHashTable *properties,
MMModemFn callback,
gpointer user_data);
void (*get_status) (MMModemSimple *self,
MMModemSimpleGetStatusFn callback,
gpointer user_data);
};
GType mm_modem_simple_get_type (void);
void mm_modem_simple_connect (MMModemSimple *self,
GHashTable *properties,
MMModemFn callback,
gpointer user_data);
void mm_modem_simple_get_status (MMModemSimple *self,
MMModemSimpleGetStatusFn callback,
gpointer user_data);
#endif /* MM_MODEM_SIMPLE_H */