diff options
-rw-r--r-- | plugins/Makefile.am | 2 | ||||
-rw-r--r-- | plugins/ublox/mm-broadband-bearer-ublox.c | 177 | ||||
-rw-r--r-- | plugins/ublox/mm-broadband-bearer-ublox.h | 63 | ||||
-rw-r--r-- | plugins/ublox/mm-broadband-modem-ublox.c | 49 |
4 files changed, 289 insertions, 2 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 51432ce2..d977b5ff 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -912,6 +912,8 @@ pkglib_LTLIBRARIES += libmm-plugin-ublox.la libmm_plugin_ublox_la_SOURCES = \ ublox/mm-plugin-ublox.c \ ublox/mm-plugin-ublox.h \ + ublox/mm-broadband-bearer-ublox.h \ + ublox/mm-broadband-bearer-ublox.c \ ublox/mm-broadband-modem-ublox.h \ ublox/mm-broadband-modem-ublox.c \ $(NULL) diff --git a/plugins/ublox/mm-broadband-bearer-ublox.c b/plugins/ublox/mm-broadband-bearer-ublox.c new file mode 100644 index 00000000..310af714 --- /dev/null +++ b/plugins/ublox/mm-broadband-bearer-ublox.c @@ -0,0 +1,177 @@ +/* -*- 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) 2016 Aleksander Morgado <aleksander@aleksander.es> + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <ctype.h> +#include <arpa/inet.h> + +#include <ModemManager.h> +#define _LIBMM_INSIDE_MM +#include <libmm-glib.h> + +#include "mm-broadband-bearer-ublox.h" +#include "mm-base-modem-at.h" +#include "mm-log.h" +#include "mm-ublox-enums-types.h" +#include "mm-modem-helpers-ublox.h" + +G_DEFINE_TYPE (MMBroadbandBearerUblox, mm_broadband_bearer_ublox, MM_TYPE_BROADBAND_BEARER) + +enum { + PROP_0, + PROP_USB_PROFILE, + PROP_NETWORKING_MODE, + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + +struct _MMBroadbandBearerUbloxPrivate { + MMUbloxUsbProfile profile; + MMUbloxNetworkingMode mode; +}; + +/*****************************************************************************/ + +MMBaseBearer * +mm_broadband_bearer_ublox_new_finish (GAsyncResult *res, + GError **error) +{ + GObject *source; + GObject *bearer; + + source = g_async_result_get_source_object (res); + bearer = g_async_initable_new_finish (G_ASYNC_INITABLE (source), res, error); + g_object_unref (source); + + if (!bearer) + return NULL; + + /* Only export valid bearers */ + mm_base_bearer_export (MM_BASE_BEARER (bearer)); + + return MM_BASE_BEARER (bearer); +} + +void +mm_broadband_bearer_ublox_new (MMBroadbandModem *modem, + MMUbloxUsbProfile profile, + MMUbloxNetworkingMode mode, + MMBearerProperties *config, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_async_initable_new_async ( + MM_TYPE_BROADBAND_BEARER_UBLOX, + G_PRIORITY_DEFAULT, + cancellable, + callback, + user_data, + MM_BASE_BEARER_MODEM, modem, + MM_BASE_BEARER_CONFIG, config, + MM_BROADBAND_BEARER_UBLOX_USB_PROFILE, profile, + MM_BROADBAND_BEARER_UBLOX_NETWORKING_MODE, mode, + NULL); +} + +static void +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MMBroadbandBearerUblox *self = MM_BROADBAND_BEARER_UBLOX (object); + + switch (prop_id) { + case PROP_USB_PROFILE: + self->priv->profile = g_value_get_enum (value); + break; + case PROP_NETWORKING_MODE: + self->priv->mode = g_value_get_enum (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MMBroadbandBearerUblox *self = MM_BROADBAND_BEARER_UBLOX (object); + + switch (prop_id) { + case PROP_USB_PROFILE: + g_value_set_enum (value, self->priv->profile); + break; + case PROP_NETWORKING_MODE: + g_value_set_enum (value, self->priv->mode); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +mm_broadband_bearer_ublox_init (MMBroadbandBearerUblox *self) +{ + /* Initialize private data */ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + MM_TYPE_BROADBAND_BEARER_UBLOX, + MMBroadbandBearerUbloxPrivate); + + /* Defaults */ + self->priv->profile = MM_UBLOX_USB_PROFILE_UNKNOWN; + self->priv->mode = MM_UBLOX_NETWORKING_MODE_UNKNOWN; +} + +static void +mm_broadband_bearer_ublox_class_init (MMBroadbandBearerUbloxClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (MMBroadbandBearerUbloxPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + + properties[PROP_USB_PROFILE] = + g_param_spec_enum (MM_BROADBAND_BEARER_UBLOX_USB_PROFILE, + "USB profile", + "USB profile in use", + MM_TYPE_UBLOX_USB_PROFILE, + MM_UBLOX_USB_PROFILE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_USB_PROFILE, properties[PROP_USB_PROFILE]); + + properties[PROP_NETWORKING_MODE] = + g_param_spec_enum (MM_BROADBAND_BEARER_UBLOX_NETWORKING_MODE, + "Networking mode", + "Networking mode in use", + MM_TYPE_UBLOX_NETWORKING_MODE, + MM_UBLOX_NETWORKING_MODE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_NETWORKING_MODE, properties[PROP_NETWORKING_MODE]); +} diff --git a/plugins/ublox/mm-broadband-bearer-ublox.h b/plugins/ublox/mm-broadband-bearer-ublox.h new file mode 100644 index 00000000..36c26894 --- /dev/null +++ b/plugins/ublox/mm-broadband-bearer-ublox.h @@ -0,0 +1,63 @@ +/* -*- 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) 2016 Aleksander Morgado <aleksander@aleksander.es> + */ + +#ifndef MM_BROADBAND_BEARER_UBLOX_H +#define MM_BROADBAND_BEARER_UBLOX_H + +#include <glib.h> +#include <glib-object.h> + +#define _LIBMM_INSIDE_MM +#include <libmm-glib.h> + +#include "mm-broadband-bearer.h" +#include "mm-modem-helpers-ublox.h" + +#define MM_TYPE_BROADBAND_BEARER_UBLOX (mm_broadband_bearer_ublox_get_type ()) +#define MM_BROADBAND_BEARER_UBLOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BROADBAND_BEARER_UBLOX, MMBroadbandBearerUblox)) +#define MM_BROADBAND_BEARER_UBLOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_BROADBAND_BEARER_UBLOX, MMBroadbandBearerUbloxClass)) +#define MM_IS_BROADBAND_BEARER_UBLOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_BROADBAND_BEARER_UBLOX)) +#define MM_IS_BROADBAND_BEARER_UBLOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_BROADBAND_BEARER_UBLOX)) +#define MM_BROADBAND_BEARER_UBLOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BROADBAND_BEARER_UBLOX, MMBroadbandBearerUbloxClass)) + +#define MM_BROADBAND_BEARER_UBLOX_USB_PROFILE "broadband-bearer-ublox-usb-profile" +#define MM_BROADBAND_BEARER_UBLOX_NETWORKING_MODE "broadband-bearer-ublox-networking-mode" + +typedef struct _MMBroadbandBearerUblox MMBroadbandBearerUblox; +typedef struct _MMBroadbandBearerUbloxClass MMBroadbandBearerUbloxClass; +typedef struct _MMBroadbandBearerUbloxPrivate MMBroadbandBearerUbloxPrivate; + +struct _MMBroadbandBearerUblox { + MMBroadbandBearer parent; + MMBroadbandBearerUbloxPrivate *priv; +}; + +struct _MMBroadbandBearerUbloxClass { + MMBroadbandBearerClass parent; +}; + +GType mm_broadband_bearer_ublox_get_type (void); + +void mm_broadband_bearer_ublox_new (MMBroadbandModem *modem, + MMUbloxUsbProfile profile, + MMUbloxNetworkingMode mode, + MMBearerProperties *config, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +MMBaseBearer *mm_broadband_bearer_ublox_new_finish (GAsyncResult *res, + GError **error); + +#endif /* MM_BROADBAND_BEARER_UBLOX_H */ diff --git a/plugins/ublox/mm-broadband-modem-ublox.c b/plugins/ublox/mm-broadband-modem-ublox.c index c71daa7d..7d392faa 100644 --- a/plugins/ublox/mm-broadband-modem-ublox.c +++ b/plugins/ublox/mm-broadband-modem-ublox.c @@ -27,6 +27,7 @@ #include "mm-base-modem-at.h" #include "mm-broadband-bearer.h" #include "mm-broadband-modem-ublox.h" +#include "mm-broadband-bearer-ublox.h" #include "mm-modem-helpers-ublox.h" #include "mm-ublox-enums-types.h" @@ -106,6 +107,29 @@ broadband_bearer_new_ready (GObject *source, } static void +broadband_bearer_ublox_new_ready (GObject *source, + GAsyncResult *res, + GTask *task) +{ + CreateBearerContext *ctx; + GError *error = NULL; + + ctx = (CreateBearerContext *) g_task_get_task_data (task); + + g_assert (!ctx->bearer); + ctx->bearer = mm_broadband_bearer_ublox_new_finish (res, &error); + if (!ctx->bearer) { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + mm_dbg ("u-blox: new u-blox broadband bearer created at DBus path '%s'", mm_base_bearer_get_path (ctx->bearer)); + ctx->step++; + create_bearer_step (task); +} + +static void mode_check_ready (MMBaseModem *self, GAsyncResult *res, GTask *task) @@ -207,8 +231,29 @@ create_bearer_step (GTask *task) /* fall down */ case CREATE_BEARER_STEP_CREATE_BEARER: - /* For now, we just create a MMBroadbandBearer */ - mm_dbg ("u-blox: creating generic broadband bearer in u-blox modem..."); + /* If we have a net interface, we'll create a u-blox bearer, unless for + * any reason we have the back-compatible profile selected, or if we don't + * know the mode to use. */ + if ((ctx->self->priv->profile == MM_UBLOX_USB_PROFILE_ECM || ctx->self->priv->profile == MM_UBLOX_USB_PROFILE_RNDIS) && + (ctx->self->priv->mode == MM_UBLOX_NETWORKING_MODE_BRIDGE || ctx->self->priv->mode == MM_UBLOX_NETWORKING_MODE_ROUTER) && + mm_base_modem_peek_best_data_port (MM_BASE_MODEM (ctx->self), MM_PORT_TYPE_NET)) { + mm_dbg ("u-blox: creating u-blox broadband bearer (%s profile, %s mode)...", + mm_ublox_usb_profile_get_string (ctx->self->priv->profile), + mm_ublox_networking_mode_get_string (ctx->self->priv->mode)); + mm_broadband_bearer_ublox_new ( + MM_BROADBAND_MODEM (ctx->self), + ctx->self->priv->profile, + ctx->self->priv->mode, + ctx->properties, + NULL, /* cancellable */ + (GAsyncReadyCallback) broadband_bearer_ublox_new_ready, + task); + return; + } + + /* If usb profile is back-compatible already, or if there is no NET port + * available, create default generic bearer */ + mm_dbg ("u-blox: creating generic broadband bearer..."); mm_broadband_bearer_new (MM_BROADBAND_MODEM (ctx->self), ctx->properties, NULL, /* cancellable */ |