diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2011-11-30 13:29:32 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-03-15 14:14:30 +0100 |
commit | 8ecb80b553d8b60ceeaa78af92a7163e9db8f10a (patch) | |
tree | 09bba002613d5e5ef8dfa80a455bf03fa747aa6e /src | |
parent | a92e9c59c1c2a4b2078e02d631b04eced68320be (diff) |
iface-modem-3gpp: handle network scan requests
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-iface-modem-3gpp.c | 124 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.h | 8 |
2 files changed, 131 insertions, 1 deletions
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c index 7ced39ea..d2de6a40 100644 --- a/src/mm-iface-modem-3gpp.c +++ b/src/mm-iface-modem-3gpp.c @@ -22,6 +22,7 @@ #include "mm-iface-modem.h" #include "mm-iface-modem-3gpp.h" #include "mm-base-modem.h" +#include "mm-modem-helpers.h" #include "mm-log.h" typedef struct { @@ -145,12 +146,133 @@ handle_register (MmGdbusModem3gpp *skeleton, return TRUE; } +/*****************************************************************************/ + +static GVariant * +scan_networks_build_result (GList *info_list) +{ + GList *l; + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); + + for (l = info_list; l; l = g_list_next (l)) { + MM3gppNetworkInfo *info = l->data; + + if (!info->operator_code) { + g_warn_if_reached (); + continue; + } + + g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}")); + + g_variant_builder_add (&builder, "{sv}", + "operator-code", g_variant_new_string (info->operator_code)); + g_variant_builder_add (&builder, "{sv}", + "status", g_variant_new_uint32 (info->status)); + g_variant_builder_add (&builder, "{sv}", + "access-tech", g_variant_new_uint32 (info->access_tech)); + if (info->operator_long) + g_variant_builder_add (&builder, "{sv}", + "operator-long", g_variant_new_string (info->operator_long)); + if (info->operator_short) + g_variant_builder_add (&builder, "{sv}", + "operator-short", g_variant_new_string (info->operator_short)); + g_variant_builder_close (&builder); + } + + return g_variant_builder_end (&builder); +} + +static void +scan_networks_ready (MMIfaceModem3gpp *self, + GAsyncResult *res, + DbusCallContext *ctx) +{ + GError *error = NULL; + GList *info_list; + + info_list = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->scan_networks_finish (self, + res, + &error); + if (error) + g_dbus_method_invocation_take_error (ctx->invocation, + error); + else { + GVariant *dict_array; + + dict_array = scan_networks_build_result (info_list); + mm_gdbus_modem3gpp_complete_scan (ctx->skeleton, + ctx->invocation, + dict_array); + g_variant_unref (dict_array); + } + + mm_3gpp_network_info_list_free (info_list); + dbus_call_context_free (ctx); +} + static gboolean handle_scan (MmGdbusModem3gpp *skeleton, GDBusMethodInvocation *invocation, MMIfaceModem3gpp *self) { - return FALSE; /* Currently unhandled */ + + MMModemState modem_state; + + /* If scanning is not implemented, report an error */ + if (!MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->scan_networks || + !MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->scan_networks_finish) { + g_dbus_method_invocation_return_error (invocation, + MM_CORE_ERROR, + MM_CORE_ERROR_UNSUPPORTED, + "Cannot scan networks: operation not supported"); + return TRUE; + } + + modem_state = MM_MODEM_STATE_UNKNOWN; + g_object_get (self, + MM_IFACE_MODEM_STATE, &modem_state, + NULL); + + switch (modem_state) { + case MM_MODEM_STATE_UNKNOWN: + /* We should never have such request in UNKNOWN state */ + g_assert_not_reached (); + break; + + case MM_MODEM_STATE_LOCKED: + g_dbus_method_invocation_return_error (invocation, + MM_CORE_ERROR, + MM_CORE_ERROR_WRONG_STATE, + "Cannot scan networks: device locked"); + break; + + case MM_MODEM_STATE_DISABLED: + case MM_MODEM_STATE_DISABLING: + case MM_MODEM_STATE_ENABLING: + g_dbus_method_invocation_return_error (invocation, + MM_CORE_ERROR, + MM_CORE_ERROR_WRONG_STATE, + "Cannot scan networks: not enabled yet"); + break; + + case MM_MODEM_STATE_ENABLED: + case MM_MODEM_STATE_SEARCHING: + case MM_MODEM_STATE_REGISTERED: + case MM_MODEM_STATE_DISCONNECTING: + case MM_MODEM_STATE_CONNECTING: + case MM_MODEM_STATE_CONNECTED: + MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->scan_networks ( + self, + (GAsyncReadyCallback)scan_networks_ready, + dbus_call_context_new (skeleton, + invocation, + self)); + break; + } + + return TRUE; } /*****************************************************************************/ diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h index a33264f3..9f8a9b63 100644 --- a/src/mm-iface-modem-3gpp.h +++ b/src/mm-iface-modem-3gpp.h @@ -110,6 +110,14 @@ struct _MMIfaceModem3gpp { gchar * (*load_operator_name_finish) (MMIfaceModem3gpp *self, GAsyncResult *res, GError **error); + + /* Scan current networks, expect a GList of MMModem3gppNetworkInfo */ + void (* scan_networks) (MMIfaceModem3gpp *self, + GAsyncReadyCallback callback, + gpointer user_data); + GList * (*scan_networks_finish) (MMIfaceModem3gpp *self, + GAsyncResult *res, + GError **error); }; GType mm_iface_modem_3gpp_get_type (void); |