summaryrefslogtreecommitdiff
path: root/plugins/telit/mm-broadband-modem-telit.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/telit/mm-broadband-modem-telit.c')
-rw-r--r--plugins/telit/mm-broadband-modem-telit.c210
1 files changed, 210 insertions, 0 deletions
diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c
new file mode 100644
index 000000000..5e1dbff06
--- /dev/null
+++ b/plugins/telit/mm-broadband-modem-telit.c
@@ -0,0 +1,210 @@
+/* -*- 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 - 2012 Red Hat, Inc.
+ * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include "ModemManager.h"
+#include "mm-log.h"
+#include "mm-errors-types.h"
+#include "mm-modem-helpers.h"
+#include "mm-base-modem-at.h"
+#include "mm-iface-modem.h"
+#include "mm-broadband-modem-telit.h"
+
+static void iface_modem_init (MMIfaceModem *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMBroadbandModemTelit, mm_broadband_modem_telit, MM_TYPE_BROADBAND_MODEM, 0,
+ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init));
+
+/*****************************************************************************/
+/* Load access technologies (Modem interface) */
+
+static gboolean
+load_access_technologies_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ MMModemAccessTechnology *access_technologies,
+ guint *mask,
+ GError **error)
+{
+ GVariant *result;
+
+ result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
+ if (!result) {
+ if (error)
+ g_assert (*error);
+ return FALSE;
+ }
+
+ *access_technologies = (MMModemAccessTechnology) g_variant_get_uint32 (result);
+ *mask = MM_MODEM_ACCESS_TECHNOLOGY_ANY;
+ return TRUE;
+}
+
+static gboolean
+response_processor_psnt_ignore_at_errors (MMBaseModem *self,
+ gpointer none,
+ const gchar *command,
+ const gchar *response,
+ gboolean last_command,
+ const GError *error,
+ GVariant **result,
+ GError **result_error)
+{
+ const gchar *psnt, *mode;
+
+ if (error) {
+ /* Ignore AT errors (ie, ERROR or CMx ERROR) */
+ if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command)
+ *result_error = g_error_copy (error);
+ return FALSE;
+ }
+
+ psnt = mm_strip_tag (response, "#PSNT:");
+ mode = strchr (psnt, ',');
+ if (mode) {
+ switch (atoi (++mode)) {
+ case 0:
+ *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_GPRS);
+ return TRUE;
+ case 1:
+ *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_EDGE);
+ return TRUE;
+ case 2:
+ *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_UMTS);
+ return TRUE;
+ case 3:
+ *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_HSDPA);
+ return TRUE;
+ default:
+ break;
+ }
+ }
+
+ g_set_error (result_error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Failed to parse #PSNT response: '%s'",
+ response);
+ return FALSE;
+}
+
+static gboolean
+response_processor_service_ignore_at_errors (MMBaseModem *self,
+ gpointer none,
+ const gchar *command,
+ const gchar *response,
+ gboolean last_command,
+ const GError *error,
+ GVariant **result,
+ GError **result_error)
+{
+ const gchar *service, *mode;
+
+ if (error) {
+ /* Ignore AT errors (ie, ERROR or CMx ERROR) */
+ if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command)
+ *result_error = g_error_copy (error);
+ return FALSE;
+ }
+
+ service = mm_strip_tag (response, "+SERVICE:");
+ mode = strchr (service, ',');
+ if (mode) {
+ switch (atoi (++mode)) {
+ case 1:
+ *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_1XRTT);
+ return TRUE;
+ case 2:
+ *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_EVDO0);
+ return TRUE;
+ case 3:
+ *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_EVDOA);
+ return TRUE;
+ default:
+ break;
+ }
+ }
+
+ g_set_error (result_error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Failed to parse +SERVICE response: '%s'",
+ response);
+ return FALSE;
+}
+
+static const MMBaseModemAtCommand access_tech_commands[] = {
+ { "#PSNT?", 3, TRUE, response_processor_psnt_ignore_at_errors },
+ { "+SERVICE?", 3, TRUE, response_processor_service_ignore_at_errors },
+ { NULL }
+};
+
+static void
+load_access_technologies (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ mm_dbg ("loading access technology (Telit)...");
+ mm_base_modem_at_sequence (
+ MM_BASE_MODEM (self),
+ access_tech_commands,
+ NULL, /* response_processor_context */
+ NULL, /* response_processor_context_free */
+ callback,
+ user_data);
+}
+
+/*****************************************************************************/
+
+MMBroadbandModemTelit *
+mm_broadband_modem_telit_new (const gchar *device,
+ const gchar **drivers,
+ const gchar *plugin,
+ guint16 vendor_id,
+ guint16 product_id)
+{
+ return g_object_new (MM_TYPE_BROADBAND_MODEM_TELIT,
+ MM_BASE_MODEM_DEVICE, device,
+ MM_BASE_MODEM_DRIVERS, drivers,
+ MM_BASE_MODEM_PLUGIN, plugin,
+ MM_BASE_MODEM_VENDOR_ID, vendor_id,
+ MM_BASE_MODEM_PRODUCT_ID, product_id,
+ NULL);
+}
+
+static void
+mm_broadband_modem_telit_init (MMBroadbandModemTelit *self)
+{
+}
+
+static void
+iface_modem_init (MMIfaceModem *iface)
+{
+ iface->load_access_technologies = load_access_technologies;
+ iface->load_access_technologies_finish = load_access_technologies_finish;
+}
+
+static void
+mm_broadband_modem_telit_class_init (MMBroadbandModemTelitClass *klass)
+{
+}