diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-generic-cdma.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c index a53b7a41..6701e407 100644 --- a/src/mm-generic-cdma.c +++ b/src/mm-generic-cdma.c @@ -5,6 +5,7 @@ #include "mm-generic-cdma.h" #include "mm-modem-cdma.h" +#include "mm-modem-simple.h" #include "mm-errors.h" #include "mm-callback-info.h" #include "mm-serial-parsers.h" @@ -187,6 +188,153 @@ get_signal_quality (MMModemCdma *modem, } /*****************************************************************************/ +/* MMModemSimple interface */ + +typedef enum { + SIMPLE_STATE_BEGIN = 0, + SIMPLE_STATE_ENABLE, + 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")); + + if (error) { + 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: + 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 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_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) +{ + 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); + mm_modem_cdma_get_signal_quality (MM_MODEM_CDMA (simple), simple_status_got_signal_quality, properties); +} + +/*****************************************************************************/ static void modem_init (MMModem *modem_class) @@ -203,6 +351,13 @@ modem_cdma_init (MMModemCdma *cdma_modem_class) } static void +modem_simple_init (MMModemSimple *class) +{ + class->connect = simple_connect; + class->get_status = simple_get_status; +} + +static void mm_generic_cdma_init (MMGenericCdma *self) { mm_serial_set_response_parser (MM_SERIAL (self), @@ -312,10 +467,15 @@ mm_generic_cdma_get_type (void) (GInterfaceInitFunc) modem_cdma_init }; + static const GInterfaceInfo modem_simple_info = { + (GInterfaceInitFunc) modem_simple_init + }; + generic_cdma_type = g_type_register_static (MM_TYPE_SERIAL, "MMGenericCdma", &generic_cdma_type_info, 0); g_type_add_interface_static (generic_cdma_type, MM_TYPE_MODEM, &modem_iface_info); g_type_add_interface_static (generic_cdma_type, MM_TYPE_MODEM_CDMA, &modem_cdma_iface_info); + g_type_add_interface_static (generic_cdma_type, MM_TYPE_MODEM_SIMPLE, &modem_simple_info); } return generic_cdma_type; |