Merge lp:~binli/ubuntu/wily/modemmanager/lp1441095 into lp:ubuntu/wily/modemmanager

Proposed by Bin Li
Status: Merged
Approved by: Mathieu Trudel-Lapierre
Approved revision: 32
Merge reported by: Mathieu Trudel-Lapierre
Merged at revision: not available
Proposed branch: lp:~binli/ubuntu/wily/modemmanager/lp1441095
Merge into: lp:ubuntu/wily/modemmanager
Diff against target: 2001 lines (+1953/-0)
9 files modified
debian/changelog (+6/-0)
debian/patches/dell-mbim-plugin.patch (+569/-0)
debian/patches/mbm-common-library.patch (+46/-0)
debian/patches/new-sierra-legacy-plugin.patch (+291/-0)
debian/patches/novatel-common-library.patch (+47/-0)
debian/patches/novatel-custom-init.patch (+389/-0)
debian/patches/series (+7/-0)
debian/patches/sierra-common-library.patch (+50/-0)
debian/patches/sierra-custom-init.patch (+548/-0)
To merge this branch: bzr merge lp:~binli/ubuntu/wily/modemmanager/lp1441095
Reviewer Review Type Date Requested Status
Bin Li (community) Needs Fixing
Mathieu Trudel-Lapierre Approve
Sebastien Bacher Pending
Review via email: mp+271088@code.launchpad.net

Description of the change

Support the MBIM for Dell.

Cherry picked some patches from git master branch to 1.4.

To post a comment you must log in.
Revision history for this message
Mathieu Trudel-Lapierre (cyphermox) wrote :

Looks fine. I don't have any of these devices, so I can only defer to the testing that was done by Bin Li and upstream developers.

review: Approve
Revision history for this message
Bin Li (binli) wrote :

Mathieu,

 Thanks for your review, I just tested it on trusty with EM7305, we need Taipei team which had the 3G device by hand to verify it, and they found the patches did not work for another new device(EM7455), so please postpone the release for wily.

 And Shih-Yuan Lee <email address hidden> and I will continue to work on it.

Thanks!

review: Needs Fixing
Revision history for this message
Mathieu Trudel-Lapierre (cyphermox) wrote :

This has been merged into wily already.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== removed file '.pc/applied-patches'
2=== modified file 'debian/changelog'
3--- debian/changelog 2015-07-26 20:43:23 +0000
4+++ debian/changelog 2015-09-15 09:59:59 +0000
5@@ -1,3 +1,9 @@
6+modemmanager (1.4.10-2) UNRELEASED; urgency=medium
7+
8+ * Support the MBIM for Dell. (LP: #1441943)
9+
10+ -- Bin Li <bin.li@canonical.com> Tue, 15 Sep 2015 17:39:10 +0800
11+
12 modemmanager (1.4.10-1) unstable; urgency=medium
13
14 * New upstream release.
15
16=== added file 'debian/patches/dell-mbim-plugin.patch'
17--- debian/patches/dell-mbim-plugin.patch 1970-01-01 00:00:00 +0000
18+++ debian/patches/dell-mbim-plugin.patch 2015-09-15 09:59:59 +0000
19@@ -0,0 +1,569 @@
20+commit 93d6e4f102da51e72ecd2fbfcfa096cd2fd2e02e
21+Author: Aleksander Morgado <aleksander@aleksander.es>
22+Date: Fri Feb 6 16:35:52 2015 +0100
23+
24+ dell: new Dell plugin
25+
26+ For Dell-branded Novatel, Sierra and Ericsson modems.
27+
28+ The Novatel plugin will no longer accept every Dell-branded modem, which was
29+ the current situation. Instead, a new Dell plugin will take care of probing for
30+ the correct vendor string, and based on the results create a specific Novatel,
31+ Sierra or Ericsson modem.
32+
33+ In order to properly support this, the Novatel, Sierra and MBM plugins now
34+ export their implementations into non-inst libraries that the Dell plugin will
35+ import.
36+
37+ Also, for now, the Dell plugin doesn't make any difference between e.g. Sierra
38+ or Ericsson MBIM implementations, just a generic MBIM modem is created in both
39+ cases, as that is anyway what the Ericsson MBM and Sierra plugins do already.
40+
41+ https://bugs.freedesktop.org/show_bug.cgi?id=86713
42+
43+Index: modemmanager/plugins/Makefile.am
44+===================================================================
45+--- modemmanager.orig/plugins/Makefile.am
46++++ modemmanager/plugins/Makefile.am
47+@@ -128,6 +128,7 @@ pkglib_LTLIBRARIES = \
48+ libmm-plugin-motorola.la \
49+ libmm-plugin-novatel.la \
50+ libmm-plugin-novatel-lte.la \
51++ libmm-plugin-dell.la \
52+ libmm-plugin-altair-lte.la \
53+ libmm-plugin-samsung.la \
54+ libmm-plugin-option.la \
55+@@ -504,6 +505,14 @@ libmm_plugin_novatel_la_CPPFLAGS = $(PLU
56+ libmm_plugin_novatel_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
57+ libmm_plugin_novatel_la_LIBADD = $(NOVATEL_COMMON_LIBADD_FLAGS)
58+
59++# Dell (e.g. Novatel or Sierra) modem
60++libmm_plugin_dell_la_SOURCES = \
61++ dell/mm-plugin-dell.c \
62++ dell/mm-plugin-dell.h
63++libmm_plugin_dell_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(NOVATEL_COMMON_COMPILER_FLAGS) $(SIERRA_COMMON_COMPILER_FLAGS) $(MBM_COMMON_COMPILER_FLAGS)
64++libmm_plugin_dell_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
65++libmm_plugin_dell_la_LIBADD = $(NOVATEL_COMMON_LIBADD_FLAGS) $(SIERRA_COMMON_LIBADD_FLAGS) $(MBM_COMMON_LIBADD_FLAGS)
66++
67+ # Altair LTE modem
68+ libmm_plugin_altair_lte_la_SOURCES = \
69+ altair/mm-modem-helpers-altair-lte.c \
70+Index: modemmanager/plugins/dell/mm-plugin-dell.c
71+===================================================================
72+--- /dev/null
73++++ modemmanager/plugins/dell/mm-plugin-dell.c
74+@@ -0,0 +1,448 @@
75++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
76++
77++/*
78++ * This program is free software; you can redistribute it and/or
79++ * modify it under the terms of the GNU General Public License as
80++ * published by the Free Software Foundation; either version 2 of the
81++ * License, or (at your option) any later version.
82++ *
83++ * This program is distributed in the hope that it will be useful,
84++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
85++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
86++ * General Public License for more details.
87++ *
88++ * You should have received a copy of the GNU General Public
89++ * License along with this program; if not, write to the
90++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
91++ * Boston, MA 02111-1307, USA.
92++ *
93++ * Copyright (C) 2015 Aleksander Morgado <aleksander@aleksander.es>
94++ */
95++
96++#include <string.h>
97++#include <gmodule.h>
98++
99++#define _LIBMM_INSIDE_MM
100++#include <libmm-glib.h>
101++
102++#include "mm-plugin-dell.h"
103++#include "mm-common-novatel.h"
104++#include "mm-private-boxed-types.h"
105++#include "mm-broadband-modem.h"
106++#include "mm-broadband-modem-novatel.h"
107++#include "mm-common-novatel.h"
108++#include "mm-broadband-modem-sierra.h"
109++#include "mm-common-sierra.h"
110++#include "mm-log.h"
111++
112++#if defined WITH_QMI
113++#include "mm-broadband-modem-qmi.h"
114++#endif
115++
116++#if defined WITH_MBIM
117++#include "mm-broadband-modem-mbim.h"
118++#endif
119++
120++G_DEFINE_TYPE (MMPluginDell, mm_plugin_dell, MM_TYPE_PLUGIN)
121++
122++int mm_plugin_major_version = MM_PLUGIN_MAJOR_VERSION;
123++int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION;
124++
125++#define TAG_DELL_MANUFACTURER "dell-manufacturer"
126++typedef enum {
127++ DELL_MANUFACTURER_UNKNOWN = 0,
128++ DELL_MANUFACTURER_NOVATEL = 1,
129++ DELL_MANUFACTURER_SIERRA = 2,
130++ DELL_MANUFACTURER_ERICSSON = 3
131++} DellManufacturer;
132++
133++/*****************************************************************************/
134++/* Custom init */
135++
136++typedef struct {
137++ MMPortProbe *probe;
138++ MMPortSerialAt *port;
139++ GCancellable *cancellable;
140++ GSimpleAsyncResult *result;
141++ guint gmi_retries;
142++ guint cgmi_retries;
143++ guint ati_retries;
144++} CustomInitContext;
145++
146++static void
147++custom_init_context_complete_and_free (CustomInitContext *ctx)
148++{
149++ g_simple_async_result_complete_in_idle (ctx->result);
150++
151++ if (ctx->cancellable)
152++ g_object_unref (ctx->cancellable);
153++ g_object_unref (ctx->port);
154++ g_object_unref (ctx->probe);
155++ g_object_unref (ctx->result);
156++ g_slice_free (CustomInitContext, ctx);
157++}
158++
159++static gboolean
160++dell_custom_init_finish (MMPortProbe *probe,
161++ GAsyncResult *result,
162++ GError **error)
163++{
164++ return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
165++}
166++
167++static void
168++novatel_custom_init_ready (MMPortProbe *probe,
169++ GAsyncResult *res,
170++ CustomInitContext *ctx)
171++{
172++ GError *error = NULL;
173++
174++ if (!mm_common_novatel_custom_init_finish (probe, res, &error))
175++ g_simple_async_result_take_error (ctx->result, error);
176++ else
177++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
178++ custom_init_context_complete_and_free (ctx);
179++}
180++
181++static void
182++sierra_custom_init_ready (MMPortProbe *probe,
183++ GAsyncResult *res,
184++ CustomInitContext *ctx)
185++{
186++ GError *error = NULL;
187++
188++ if (!mm_common_sierra_custom_init_finish (probe, res, &error))
189++ g_simple_async_result_take_error (ctx->result, error);
190++ else
191++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
192++ custom_init_context_complete_and_free (ctx);
193++}
194++
195++static void custom_init_step (CustomInitContext *ctx);
196++
197++static void
198++custom_init_step_next_command (CustomInitContext *ctx)
199++{
200++ if (ctx->gmi_retries > 0)
201++ ctx->gmi_retries = 0;
202++ else if (ctx->cgmi_retries > 0)
203++ ctx->cgmi_retries = 0;
204++ else if (ctx->ati_retries > 0)
205++ ctx->ati_retries = 0;
206++ custom_init_step (ctx);
207++}
208++
209++static void
210++response_ready (MMPortSerialAt *port,
211++ GAsyncResult *res,
212++ CustomInitContext *ctx)
213++{
214++ const gchar *response;
215++ GError *error = NULL;
216++ gchar *lower;
217++ DellManufacturer manufacturer;
218++
219++ response = mm_port_serial_at_command_finish (port, res, &error);
220++ if (error) {
221++ /* Non-timeout error, jump to next command */
222++ if (!g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) {
223++ mm_dbg ("(Dell) Error probing AT port: %s", error->message);
224++ g_error_free (error);
225++ custom_init_step_next_command (ctx);
226++ return;
227++ }
228++ /* Directly retry same command on timeout */
229++ custom_init_step (ctx);
230++ g_error_free (error);
231++ return;
232++ }
233++
234++ /* Guess manufacturer from response */
235++ lower = g_ascii_strdown (response, -1);
236++ if (strstr (lower, "novatel"))
237++ manufacturer = DELL_MANUFACTURER_NOVATEL;
238++ else if (strstr (lower, "sierra"))
239++ manufacturer = DELL_MANUFACTURER_SIERRA;
240++ else if (strstr (lower, "ericsson"))
241++ manufacturer = DELL_MANUFACTURER_ERICSSON;
242++ else
243++ manufacturer = DELL_MANUFACTURER_UNKNOWN;
244++ g_free (lower);
245++
246++ /* Tag based on manufacturer */
247++ if (manufacturer != DELL_MANUFACTURER_UNKNOWN) {
248++ g_object_set_data (G_OBJECT (ctx->probe), TAG_DELL_MANUFACTURER, GUINT_TO_POINTER (manufacturer));
249++
250++ /* Run additional custom init, if needed */
251++
252++ if (manufacturer == DELL_MANUFACTURER_NOVATEL) {
253++ mm_common_novatel_custom_init (ctx->probe,
254++ ctx->port,
255++ ctx->cancellable,
256++ (GAsyncReadyCallback) novatel_custom_init_ready,
257++ ctx);
258++ return;
259++ }
260++
261++ if (manufacturer == DELL_MANUFACTURER_SIERRA) {
262++ mm_common_sierra_custom_init (ctx->probe,
263++ ctx->port,
264++ ctx->cancellable,
265++ (GAsyncReadyCallback) sierra_custom_init_ready,
266++ ctx);
267++ return;
268++ }
269++
270++ /* Finish custom_init */
271++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
272++ custom_init_context_complete_and_free (ctx);
273++ return;
274++ }
275++
276++ /* If we got a response, but we didn't get an expected string, try with next command */
277++ custom_init_step_next_command (ctx);
278++}
279++
280++static void
281++custom_init_step (CustomInitContext *ctx)
282++{
283++ /* If cancelled, end */
284++ if (g_cancellable_is_cancelled (ctx->cancellable)) {
285++ mm_dbg ("(Dell) no need to keep on running custom init in (%s)",
286++ mm_port_get_device (MM_PORT (ctx->port)));
287++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
288++ custom_init_context_complete_and_free (ctx);
289++ return;
290++ }
291++
292++#if defined WITH_QMI
293++ /* If device has a QMI port, don't run anything else, as we don't care */
294++ if (mm_port_probe_list_has_qmi_port (mm_device_peek_port_probe_list (mm_port_probe_peek_device (ctx->probe)))) {
295++ mm_dbg ("(Dell) no need to run custom init in (%s): device has QMI port",
296++ mm_port_get_device (MM_PORT (ctx->port)));
297++ mm_port_probe_set_result_at (ctx->probe, FALSE);
298++ mm_port_probe_set_result_qcdm (ctx->probe, FALSE);
299++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
300++ custom_init_context_complete_and_free (ctx);
301++ return;
302++ }
303++#endif
304++
305++#if defined WITH_MBIM
306++ /* If device has a MBIM port, don't run anything else, as we don't care */
307++ if (mm_port_probe_list_has_mbim_port (mm_device_peek_port_probe_list (mm_port_probe_peek_device (ctx->probe)))) {
308++ mm_dbg ("(Dell) no need to run custom init in (%s): device has MBIM port",
309++ mm_port_get_device (MM_PORT (ctx->port)));
310++ mm_port_probe_set_result_at (ctx->probe, FALSE);
311++ mm_port_probe_set_result_qcdm (ctx->probe, FALSE);
312++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
313++ custom_init_context_complete_and_free (ctx);
314++ return;
315++ }
316++#endif
317++
318++ if (ctx->gmi_retries > 0) {
319++ ctx->gmi_retries--;
320++ mm_port_serial_at_command (ctx->port,
321++ "AT+GMI",
322++ 3,
323++ FALSE, /* raw */
324++ FALSE, /* allow_cached */
325++ ctx->cancellable,
326++ (GAsyncReadyCallback)response_ready,
327++ ctx);
328++ return;
329++ }
330++
331++ if (ctx->cgmi_retries > 0) {
332++ ctx->cgmi_retries--;
333++ mm_port_serial_at_command (ctx->port,
334++ "AT+CGMI",
335++ 3,
336++ FALSE, /* raw */
337++ FALSE, /* allow_cached */
338++ ctx->cancellable,
339++ (GAsyncReadyCallback)response_ready,
340++ ctx);
341++ return;
342++ }
343++
344++ if (ctx->ati_retries > 0) {
345++ ctx->ati_retries--;
346++ /* Note: in Ericsson devices, ATI3 seems to reply the vendor string */
347++ mm_port_serial_at_command (ctx->port,
348++ "ATI1I2I3",
349++ 3,
350++ FALSE, /* raw */
351++ FALSE, /* allow_cached */
352++ ctx->cancellable,
353++ (GAsyncReadyCallback)response_ready,
354++ ctx);
355++ return;
356++ }
357++
358++ /* Finish custom_init */
359++ mm_dbg ("(Dell) couldn't flip secondary port to AT in (%s): all retries consumed",
360++ mm_port_get_device (MM_PORT (ctx->port)));
361++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
362++ custom_init_context_complete_and_free (ctx);
363++}
364++
365++static void
366++dell_custom_init (MMPortProbe *probe,
367++ MMPortSerialAt *port,
368++ GCancellable *cancellable,
369++ GAsyncReadyCallback callback,
370++ gpointer user_data)
371++{
372++ CustomInitContext *ctx;
373++
374++ ctx = g_slice_new (CustomInitContext);
375++ ctx->result = g_simple_async_result_new (G_OBJECT (probe),
376++ callback,
377++ user_data,
378++ dell_custom_init);
379++ ctx->probe = g_object_ref (probe);
380++ ctx->port = g_object_ref (port);
381++ ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
382++ ctx->gmi_retries = 3;
383++ ctx->ati_retries = 3;
384++
385++ custom_init_step (ctx);
386++}
387++
388++/*****************************************************************************/
389++
390++static gboolean
391++port_probe_list_has_manufacturer_port (GList *probes,
392++ DellManufacturer manufacturer)
393++{
394++ GList *l;
395++
396++ for (l = probes; l; l = g_list_next (l)) {
397++ if (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (l->data), TAG_DELL_MANUFACTURER)) == manufacturer)
398++ return TRUE;
399++ }
400++ return FALSE;
401++}
402++
403++static MMBaseModem *
404++create_modem (MMPlugin *self,
405++ const gchar *sysfs_path,
406++ const gchar **drivers,
407++ guint16 vendor,
408++ guint16 product,
409++ GList *probes,
410++ GError **error)
411++{
412++ /* Note: at this point we don't make any difference between different
413++ * Dell-branded QMI or MBIM modems; they may come from Novatel, Ericsson or
414++ * Sierra. */
415++
416++#if defined WITH_QMI
417++ if (mm_port_probe_list_has_qmi_port (probes)) {
418++ mm_dbg ("QMI-powered Dell-branded modem found...");
419++ return MM_BASE_MODEM (mm_broadband_modem_qmi_new (sysfs_path,
420++ drivers,
421++ mm_plugin_get_name (self),
422++ vendor,
423++ product));
424++ }
425++#endif
426++
427++#if defined WITH_MBIM
428++ if (mm_port_probe_list_has_mbim_port (probes)) {
429++ mm_dbg ("MBIM-powered Dell-branded modem found...");
430++ return MM_BASE_MODEM (mm_broadband_modem_mbim_new (sysfs_path,
431++ drivers,
432++ mm_plugin_get_name (self),
433++ vendor,
434++ product));
435++ }
436++#endif
437++
438++ if (port_probe_list_has_manufacturer_port (probes, DELL_MANUFACTURER_NOVATEL)) {
439++ mm_dbg ("Novatel-powered Dell-branded modem found...");
440++ return MM_BASE_MODEM (mm_broadband_modem_novatel_new (sysfs_path,
441++ drivers,
442++ mm_plugin_get_name (self),
443++ vendor,
444++ product));
445++ }
446++
447++ if (port_probe_list_has_manufacturer_port (probes, DELL_MANUFACTURER_SIERRA)) {
448++ mm_dbg ("Sierra-powered Dell-branded modem found...");
449++ return MM_BASE_MODEM (mm_broadband_modem_sierra_new (sysfs_path,
450++ drivers,
451++ mm_plugin_get_name (self),
452++ vendor,
453++ product));
454++ }
455++
456++ mm_dbg ("Dell-branded generic modem found...");
457++ return MM_BASE_MODEM (mm_broadband_modem_new (sysfs_path,
458++ drivers,
459++ mm_plugin_get_name (self),
460++ vendor,
461++ product));
462++}
463++
464++/*****************************************************************************/
465++
466++static gboolean
467++grab_port (MMPlugin *self,
468++ MMBaseModem *modem,
469++ MMPortProbe *probe,
470++ GError **error)
471++{
472++ /* Only Sierra needs custom grab port, due to the port type hints */
473++ if (MM_IS_BROADBAND_MODEM_SIERRA (modem))
474++ return mm_common_sierra_grab_port (self, modem, probe, error);
475++
476++ return mm_base_modem_grab_port (modem,
477++ mm_port_probe_get_port_subsys (probe),
478++ mm_port_probe_get_port_name (probe),
479++ mm_port_probe_get_parent_path (probe),
480++ mm_port_probe_get_port_type (probe),
481++ MM_PORT_SERIAL_AT_FLAG_NONE,
482++ error);
483++}
484++
485++/*****************************************************************************/
486++
487++G_MODULE_EXPORT MMPlugin *
488++mm_plugin_create (void)
489++{
490++ static const gchar *subsystems[] = { "tty", "net", "usb", NULL };
491++ static const guint16 vendors[] = { 0x413c, 0 };
492++ static const MMAsyncMethod custom_init = {
493++ .async = G_CALLBACK (dell_custom_init),
494++ .finish = G_CALLBACK (dell_custom_init_finish),
495++ };
496++
497++ return MM_PLUGIN (
498++ g_object_new (MM_TYPE_PLUGIN_DELL,
499++ MM_PLUGIN_NAME, "Dell",
500++ MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
501++ MM_PLUGIN_ALLOWED_VENDOR_IDS, vendors,
502++ MM_PLUGIN_ALLOWED_AT, TRUE,
503++ MM_PLUGIN_CUSTOM_INIT, &custom_init,
504++ MM_PLUGIN_ALLOWED_QCDM, TRUE,
505++ MM_PLUGIN_ALLOWED_QMI, TRUE,
506++ MM_PLUGIN_ALLOWED_MBIM, TRUE,
507++ NULL));
508++}
509++
510++static void
511++mm_plugin_dell_init (MMPluginDell *self)
512++{
513++}
514++
515++static void
516++mm_plugin_dell_class_init (MMPluginDellClass *klass)
517++{
518++ MMPluginClass *plugin_class = MM_PLUGIN_CLASS (klass);
519++
520++ plugin_class->create_modem = create_modem;
521++ plugin_class->grab_port = grab_port;
522++}
523+Index: modemmanager/plugins/dell/mm-plugin-dell.h
524+===================================================================
525+--- /dev/null
526++++ modemmanager/plugins/dell/mm-plugin-dell.h
527+@@ -0,0 +1,46 @@
528++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
529++
530++/*
531++ * This program is free software; you can redistribute it and/or
532++ * modify it under the terms of the GNU General Public License as
533++ * published by the Free Software Foundation; either version 2 of the
534++ * License, or (at your option) any later version.
535++ *
536++ * This program is distributed in the hope that it will be useful,
537++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
538++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
539++ * General Public License for more details.
540++ *
541++ * You should have received a copy of the GNU General Public
542++ * License along with this program; if not, write to the
543++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
544++ * Boston, MA 02111-1307, USA.
545++ *
546++ * Copyright (C) 2015 Aleksander Morgado <aleksander@aleksander.es>
547++ */
548++
549++#ifndef MM_PLUGIN_DELL_H
550++#define MM_PLUGIN_DELL_H
551++
552++#include "mm-plugin.h"
553++
554++#define MM_TYPE_PLUGIN_DELL (mm_plugin_dell_get_type ())
555++#define MM_PLUGIN_DELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_PLUGIN_DELL, MMPluginDell))
556++#define MM_PLUGIN_DELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_PLUGIN_DELL, MMPluginDellClass))
557++#define MM_IS_PLUGIN_DELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_PLUGIN_DELL))
558++#define MM_IS_PLUGIN_DELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_PLUGIN_DELL))
559++#define MM_PLUGIN_DELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN_DELL, MMPluginDellClass))
560++
561++typedef struct {
562++ MMPlugin parent;
563++} MMPluginDell;
564++
565++typedef struct {
566++ MMPluginClass parent;
567++} MMPluginDellClass;
568++
569++GType mm_plugin_dell_get_type (void);
570++
571++G_MODULE_EXPORT MMPlugin *mm_plugin_create (void);
572++
573++#endif /* MM_PLUGIN_DELL_H */
574+Index: modemmanager/plugins/novatel/mm-plugin-novatel.c
575+===================================================================
576+--- modemmanager.orig/plugins/novatel/mm-plugin-novatel.c
577++++ modemmanager/plugins/novatel/mm-plugin-novatel.c
578+@@ -90,9 +90,7 @@ G_MODULE_EXPORT MMPlugin *
579+ mm_plugin_create (void)
580+ {
581+ static const gchar *subsystems[] = { "tty", "net", "usb", NULL };
582+- static const guint16 vendors[] = { 0x1410, /* Novatel */
583+- 0x413c, /* Dell */
584+- 0 };
585++ static const guint16 vendors[] = { 0x1410, 0 };
586+ static const mm_uint16_pair forbidden_products[] = { { 0x1410, 0x9010 }, /* Novatel E362 */
587+ { 0, 0 } };
588+ static const MMAsyncMethod custom_init = {
589
590=== added file 'debian/patches/mbm-common-library.patch'
591--- debian/patches/mbm-common-library.patch 1970-01-01 00:00:00 +0000
592+++ debian/patches/mbm-common-library.patch 2015-09-15 09:59:59 +0000
593@@ -0,0 +1,46 @@
594+commit 5a268430c4c89e21d977403ec764c59b86498af8
595+Author: Aleksander Morgado <aleksander@aleksander.es>
596+Date: Fri Feb 6 17:11:52 2015 +0100
597+
598+ mbm: build a common non-inst library with the core Ericsson modem support
599+
600+Index: modemmanager/plugins/Makefile.am
601+===================================================================
602+--- modemmanager.orig/plugins/Makefile.am
603++++ modemmanager/plugins/Makefile.am
604+@@ -212,10 +212,9 @@ test_modem_helpers_huawei_LDADD = \
605+ $(top_builddir)/src/libmodem-helpers.la
606+ test_modem_helpers_huawei_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
607+
608+-# MBM
609+-libmm_plugin_mbm_la_SOURCES = \
610+- mbm/mm-plugin-mbm.c \
611+- mbm/mm-plugin-mbm.h \
612++# Common Mbm modem support library
613++noinst_LTLIBRARIES += libmm-utils-mbm.la
614++libmm_utils_mbm_la_SOURCES = \
615+ mbm/mm-broadband-modem-mbm.c \
616+ mbm/mm-broadband-modem-mbm.h \
617+ mbm/mm-broadband-bearer-mbm.c \
618+@@ -224,8 +223,20 @@ libmm_plugin_mbm_la_SOURCES = \
619+ mbm/mm-modem-helpers-mbm.h \
620+ mbm/mm-sim-mbm.c \
621+ mbm/mm-sim-mbm.h
622+-libmm_plugin_mbm_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
623++libmm_utils_mbm_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
624++libmm_utils_mbm_la_LIBADD = $(GUDEV_LIBS) $(MM_LIBS)
625++
626++MBM_COMMON_COMPILER_FLAGS = -I$(top_srcdir)/plugins/mbm
627++MBM_COMMON_LIBADD_FLAGS = $(builddir)/libmm-utils-mbm.la
628++
629++# MBM
630++libmm_plugin_mbm_la_SOURCES = \
631++ mbm/mm-plugin-mbm.c \
632++ mbm/mm-plugin-mbm.h
633++libmm_plugin_mbm_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(MBM_COMMON_COMPILER_FLAGS)
634+ libmm_plugin_mbm_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
635++libmm_plugin_mbm_la_LIBADD = $(MBM_COMMON_LIBADD_FLAGS)
636++
637+ udevrules_DATA += mbm/77-mm-ericsson-mbm.rules
638+
639+ noinst_PROGRAMS += test-modem-helpers-mbm
640
641=== added file 'debian/patches/new-sierra-legacy-plugin.patch'
642--- debian/patches/new-sierra-legacy-plugin.patch 1970-01-01 00:00:00 +0000
643+++ debian/patches/new-sierra-legacy-plugin.patch 2015-09-15 09:59:59 +0000
644@@ -0,0 +1,291 @@
645+commit 6bbc4c1746c9e7c48e12dcb1e1986f1e16327161
646+Author: Aleksander Morgado <aleksander@aleksander.es>
647+Date: Fri Feb 6 20:02:20 2015 +0100
648+
649+ sierra: move all the legacy Sierra support to a new 'sierra-legacy' plugin
650+
651+ In short:
652+
653+ * The 'sierra-legacy' plugin will handle all the old AT based modems,
654+ including the DirectIP ones. This plugin is filtered by driver ('sierra' or
655+ 'sierra_net') and forbidden-drivers ('qmi_wwan' and 'cdc_mbim'). This plugin
656+ should also grab HP and AT&T branded models if they are handled by the
657+ proper kernel driver.
658+
659+ * The 'sierra' plugin will only handle QMI or MBIM based Sierra modems, which
660+ are really all the new ones. This plugin is filtered by VID (0x1199) and
661+ driver (qmi_wwan and cdc_mbim).
662+
663+ For this separation to work, the 'sierra' and 'sierra_net' plugins need to be
664+ complementary to each other.
665+
666+Index: modemmanager/plugins/Makefile.am
667+===================================================================
668+--- modemmanager.orig/plugins/Makefile.am
669++++ modemmanager/plugins/Makefile.am
670+@@ -142,6 +142,7 @@ pkglib_LTLIBRARIES = \
671+ libmm-plugin-pantech.la \
672+ libmm-plugin-zte.la \
673+ libmm-plugin-sierra.la \
674++ libmm-plugin-sierra-legacy.la \
675+ libmm-plugin-mbm.la \
676+ libmm-plugin-via.la \
677+ libmm-plugin-telit.la \
678+@@ -291,15 +292,22 @@ libmm_utils_sierra_la_LIBADD = $(GUDEV_L
679+ SIERRA_COMMON_COMPILER_FLAGS = -I$(top_srcdir)/plugins/sierra
680+ SIERRA_COMMON_LIBADD_FLAGS = $(builddir)/libmm-utils-sierra.la
681+
682+-# Sierra
683++# Sierra (new QMI or MBIM modems)
684+ libmm_plugin_sierra_la_SOURCES = \
685+ sierra/mm-plugin-sierra.c \
686+- sierra/mm-plugin-sierra.h \
687++ sierra/mm-plugin-sierra.h
688++libmm_plugin_sierra_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
689++libmm_plugin_sierra_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
690++
691++# Sierra (legacy)
692++libmm_plugin_sierra_legacy_la_SOURCES = \
693++ sierra/mm-plugin-sierra-legacy.c \
694++ sierra/mm-plugin-sierra-legacy.h \
695+ sierra/mm-broadband-modem-sierra-icera.c \
696+ sierra/mm-broadband-modem-sierra-icera.h
697+-libmm_plugin_sierra_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(ICERA_COMMON_COMPILER_FLAGS) $(SIERRA_COMMON_COMPILER_FLAGS)
698+-libmm_plugin_sierra_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
699+-libmm_plugin_sierra_la_LIBADD = $(ICERA_COMMON_LIBADD_FLAGS) $(SIERRA_COMMON_LIBADD_FLAGS)
700++libmm_plugin_sierra_legacy_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(ICERA_COMMON_COMPILER_FLAGS) $(SIERRA_COMMON_COMPILER_FLAGS)
701++libmm_plugin_sierra_legacy_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
702++libmm_plugin_sierra_legacy_la_LIBADD = $(ICERA_COMMON_LIBADD_FLAGS) $(SIERRA_COMMON_LIBADD_FLAGS)
703+
704+ # Wavecom (Sierra Airlink)
705+ libmm_plugin_wavecom_la_SOURCES = \
706+Index: modemmanager/plugins/sierra/mm-plugin-sierra-legacy.c
707+===================================================================
708+--- /dev/null
709++++ modemmanager/plugins/sierra/mm-plugin-sierra-legacy.c
710+@@ -0,0 +1,99 @@
711++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
712++/*
713++ * This program is free software; you can redistribute it and/or modify
714++ * it under the terms of the GNU General Public License as published by
715++ * the Free Software Foundation; either version 2 of the License, or
716++ * (at your option) any later version.
717++ *
718++ * This program is distributed in the hope that it will be useful,
719++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
720++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
721++ * GNU General Public License for more details:
722++ *
723++ * Copyright (C) 2008 - 2009 Novell, Inc.
724++ * Copyright (C) 2009 - 2012 Red Hat, Inc.
725++ * Copyright (C) 2012 Lanedo GmbH
726++ * Copyright (C) 2015 Aleksander Morgado <aleksander@aleksander.es>
727++ */
728++
729++#include <stdlib.h>
730++#include <gmodule.h>
731++
732++#define _LIBMM_INSIDE_MM
733++#include <libmm-glib.h>
734++
735++#include "mm-log.h"
736++#include "mm-plugin-sierra-legacy.h"
737++#include "mm-common-sierra.h"
738++#include "mm-broadband-modem-sierra.h"
739++#include "mm-broadband-modem-sierra-icera.h"
740++
741++G_DEFINE_TYPE (MMPluginSierraLegacy, mm_plugin_sierra_legacy, MM_TYPE_PLUGIN)
742++
743++int mm_plugin_major_version = MM_PLUGIN_MAJOR_VERSION;
744++int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION;
745++
746++/*****************************************************************************/
747++
748++static MMBaseModem *
749++create_modem (MMPlugin *self,
750++ const gchar *sysfs_path,
751++ const gchar **drivers,
752++ guint16 vendor,
753++ guint16 product,
754++ GList *probes,
755++ GError **error)
756++{
757++ if (mm_common_sierra_port_probe_list_is_icera (probes))
758++ return MM_BASE_MODEM (mm_broadband_modem_sierra_icera_new (sysfs_path,
759++ drivers,
760++ mm_plugin_get_name (self),
761++ vendor,
762++ product));
763++
764++ return MM_BASE_MODEM (mm_broadband_modem_sierra_new (sysfs_path,
765++ drivers,
766++ mm_plugin_get_name (self),
767++ vendor,
768++ product));
769++}
770++
771++/*****************************************************************************/
772++
773++G_MODULE_EXPORT MMPlugin *
774++mm_plugin_create (void)
775++{
776++ static const gchar *subsystems[] = { "tty", "net", NULL };
777++ static const gchar *drivers[] = { "sierra", "sierra_net", NULL };
778++ static const gchar *forbidden_drivers[] = { "qmi_wwan", "cdc_mbim", NULL };
779++ static const MMAsyncMethod custom_init = {
780++ .async = G_CALLBACK (mm_common_sierra_custom_init),
781++ .finish = G_CALLBACK (mm_common_sierra_custom_init_finish),
782++ };
783++
784++ return MM_PLUGIN (
785++ g_object_new (MM_TYPE_PLUGIN_SIERRA_LEGACY,
786++ MM_PLUGIN_NAME, "Sierra (legacy)",
787++ MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
788++ MM_PLUGIN_ALLOWED_DRIVERS, drivers,
789++ MM_PLUGIN_FORBIDDEN_DRIVERS, forbidden_drivers,
790++ MM_PLUGIN_ALLOWED_AT, TRUE,
791++ MM_PLUGIN_CUSTOM_INIT, &custom_init,
792++ MM_PLUGIN_ICERA_PROBE, TRUE,
793++ MM_PLUGIN_REMOVE_ECHO, FALSE,
794++ NULL));
795++}
796++
797++static void
798++mm_plugin_sierra_legacy_init (MMPluginSierraLegacy *self)
799++{
800++}
801++
802++static void
803++mm_plugin_sierra_legacy_class_init (MMPluginSierraLegacyClass *klass)
804++{
805++ MMPluginClass *plugin_class = MM_PLUGIN_CLASS (klass);
806++
807++ plugin_class->create_modem = create_modem;
808++ plugin_class->grab_port = mm_common_sierra_grab_port;
809++}
810+Index: modemmanager/plugins/sierra/mm-plugin-sierra-legacy.h
811+===================================================================
812+--- /dev/null
813++++ modemmanager/plugins/sierra/mm-plugin-sierra-legacy.h
814+@@ -0,0 +1,40 @@
815++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
816++/*
817++ * This program is free software; you can redistribute it and/or modify
818++ * it under the terms of the GNU General Public License as published by
819++ * the Free Software Foundation; either version 2 of the License, or
820++ * (at your option) any later version.
821++ *
822++ * This program is distributed in the hope that it will be useful,
823++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
824++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
825++ * GNU General Public License for more details:
826++ *
827++ * Copyright (C) 2015 Aleksander Morgado <aleksander@aleksander.es>
828++ */
829++
830++#ifndef MM_PLUGIN_SIERRA_LEGACY_H
831++#define MM_PLUGIN_SIERRA_LEGACY_H
832++
833++#include "mm-plugin.h"
834++
835++#define MM_TYPE_PLUGIN_SIERRA_LEGACY (mm_plugin_sierra_legacy_get_type ())
836++#define MM_PLUGIN_SIERRA_LEGACY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_PLUGIN_SIERRA_LEGACY, MMPluginSierraLegacy))
837++#define MM_PLUGIN_SIERRA_LEGACY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_PLUGIN_SIERRA_LEGACY, MMPluginSierraLegacyClass))
838++#define MM_IS_PLUGIN_SIERRA_LEGACY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_PLUGIN_SIERRA_LEGACY))
839++#define MM_IS_PLUGIN_SIERRA_LEGACY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_PLUGIN_SIERRA_LEGACY))
840++#define MM_PLUGIN_SIERRA_LEGACY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN_SIERRA_LEGACY, MMPluginSierraLegacyClass))
841++
842++typedef struct {
843++ MMPlugin parent;
844++} MMPluginSierraLegacy;
845++
846++typedef struct {
847++ MMPluginClass parent;
848++} MMPluginSierraLegacyClass;
849++
850++GType mm_plugin_sierra_legacy_get_type (void);
851++
852++G_MODULE_EXPORT MMPlugin *mm_plugin_create (void);
853++
854++#endif /* MM_PLUGIN_SIERRA_LEGACY_H */
855+Index: modemmanager/plugins/sierra/mm-plugin-sierra.c
856+===================================================================
857+--- modemmanager.orig/plugins/sierra/mm-plugin-sierra.c
858++++ modemmanager/plugins/sierra/mm-plugin-sierra.c
859+@@ -13,6 +13,7 @@
860+ * Copyright (C) 2008 - 2009 Novell, Inc.
861+ * Copyright (C) 2009 - 2012 Red Hat, Inc.
862+ * Copyright (C) 2012 Lanedo GmbH
863++ * Copyright (C) 2015 Aleksander Morgado <aleksander@aleksander.es>
864+ */
865+
866+ #include <stdlib.h>
867+@@ -23,9 +24,6 @@
868+
869+ #include "mm-log.h"
870+ #include "mm-plugin-sierra.h"
871+-#include "mm-common-sierra.h"
872+-#include "mm-broadband-modem-sierra.h"
873+-#include "mm-broadband-modem-sierra-icera.h"
874+
875+ #if defined WITH_QMI
876+ #include "mm-broadband-modem-qmi.h"
877+@@ -73,18 +71,12 @@ create_modem (MMPlugin *self,
878+ }
879+ #endif
880+
881+- if (mm_common_sierra_port_probe_list_is_icera (probes))
882+- return MM_BASE_MODEM (mm_broadband_modem_sierra_icera_new (sysfs_path,
883+- drivers,
884+- mm_plugin_get_name (self),
885+- vendor,
886+- product));
887+-
888+- return MM_BASE_MODEM (mm_broadband_modem_sierra_new (sysfs_path,
889+- drivers,
890+- mm_plugin_get_name (self),
891+- vendor,
892+- product));
893++ /* Fallback to default modem in the worst case */
894++ return MM_BASE_MODEM (mm_broadband_modem_new (sysfs_path,
895++ drivers,
896++ mm_plugin_get_name (self),
897++ vendor,
898++ product));
899+ }
900+
901+ /*****************************************************************************/
902+@@ -93,24 +85,19 @@ G_MODULE_EXPORT MMPlugin *
903+ mm_plugin_create (void)
904+ {
905+ static const gchar *subsystems[] = { "tty", "net", "usb", NULL };
906+- static const gchar *drivers[] = { "sierra", "sierra_net", NULL };
907+- static const MMAsyncMethod custom_init = {
908+- .async = G_CALLBACK (mm_common_sierra_custom_init),
909+- .finish = G_CALLBACK (mm_common_sierra_custom_init_finish),
910+- };
911++ static const guint16 vendor_ids[] = { 0x1199, 0 };
912++ static const gchar *drivers[] = { "qmi_wwan", "cdc_mbim", NULL };
913+
914+ return MM_PLUGIN (
915+ g_object_new (MM_TYPE_PLUGIN_SIERRA,
916+ MM_PLUGIN_NAME, "Sierra",
917+ MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
918++ MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
919+ MM_PLUGIN_ALLOWED_DRIVERS, drivers,
920+ MM_PLUGIN_ALLOWED_AT, TRUE,
921+ MM_PLUGIN_ALLOWED_QCDM, TRUE,
922+ MM_PLUGIN_ALLOWED_QMI, TRUE,
923+ MM_PLUGIN_ALLOWED_MBIM, TRUE,
924+- MM_PLUGIN_CUSTOM_INIT, &custom_init,
925+- MM_PLUGIN_ICERA_PROBE, TRUE,
926+- MM_PLUGIN_REMOVE_ECHO, FALSE,
927+ NULL));
928+ }
929+
930+@@ -125,5 +112,4 @@ mm_plugin_sierra_class_init (MMPluginSie
931+ MMPluginClass *plugin_class = MM_PLUGIN_CLASS (klass);
932+
933+ plugin_class->create_modem = create_modem;
934+- plugin_class->grab_port = mm_common_sierra_grab_port;
935+ }
936
937=== added file 'debian/patches/novatel-common-library.patch'
938--- debian/patches/novatel-common-library.patch 1970-01-01 00:00:00 +0000
939+++ debian/patches/novatel-common-library.patch 2015-09-15 09:59:59 +0000
940@@ -0,0 +1,47 @@
941+commit 60a17df4c78d7bd9f27ca1425dba6c53298fd3d3
942+Author: Aleksander Morgado <aleksander@aleksander.es>
943+Date: Fri Feb 6 15:55:18 2015 +0100
944+
945+ novatel: build a common non-inst library with the core Novatel modem support
946+
947+Index: modemmanager/plugins/Makefile.am
948+===================================================================
949+--- modemmanager.orig/plugins/Makefile.am
950++++ modemmanager/plugins/Makefile.am
951+@@ -442,6 +442,19 @@ libmm_plugin_iridium_la_SOURCES = \
952+ libmm_plugin_iridium_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
953+ libmm_plugin_iridium_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
954+
955++# Common Novatel modem support library
956++noinst_LTLIBRARIES += libmm-utils-novatel.la
957++libmm_utils_novatel_la_SOURCES = \
958++ novatel/mm-common-novatel.c \
959++ novatel/mm-common-novatel.h \
960++ novatel/mm-broadband-modem-novatel.c \
961++ novatel/mm-broadband-modem-novatel.h
962++libmm_utils_novatel_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
963++libmm_utils_novatel_la_LIBADD = $(GUDEV_LIBS) $(MM_LIBS)
964++
965++NOVATEL_COMMON_COMPILER_FLAGS = -I$(top_srcdir)/plugins/novatel
966++NOVATEL_COMMON_LIBADD_FLAGS = $(builddir)/libmm-utils-novatel.la
967++
968+ # Novatel LTE modem
969+ libmm_plugin_novatel_lte_la_SOURCES = \
970+ novatel/mm-plugin-novatel-lte.c \
971+@@ -458,13 +471,10 @@ libmm_plugin_novatel_lte_la_LDFLAGS = $(
972+ # Novatel non-LTE modem
973+ libmm_plugin_novatel_la_SOURCES = \
974+ novatel/mm-plugin-novatel.c \
975+- novatel/mm-plugin-novatel.h \
976+- novatel/mm-common-novatel.c \
977+- novatel/mm-common-novatel.h \
978+- novatel/mm-broadband-modem-novatel.c \
979+- novatel/mm-broadband-modem-novatel.h
980+-libmm_plugin_novatel_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
981++ novatel/mm-plugin-novatel.h
982++libmm_plugin_novatel_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(NOVATEL_COMMON_COMPILER_FLAGS)
983+ libmm_plugin_novatel_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
984++libmm_plugin_novatel_la_LIBADD = $(NOVATEL_COMMON_LIBADD_FLAGS)
985+
986+ # Altair LTE modem
987+ libmm_plugin_altair_lte_la_SOURCES = \
988
989=== added file 'debian/patches/novatel-custom-init.patch'
990--- debian/patches/novatel-custom-init.patch 1970-01-01 00:00:00 +0000
991+++ debian/patches/novatel-custom-init.patch 2015-09-15 09:59:59 +0000
992@@ -0,0 +1,389 @@
993+commit 7c929b5cf19ca6fd3ed8c5667efc026df13046a1
994+Author: Aleksander Morgado <aleksander@aleksander.es>
995+Date: Fri Feb 6 15:30:50 2015 +0100
996+
997+ novatel: move custom init method to separate source files
998+
999+Index: modemmanager/plugins/Makefile.am
1000+===================================================================
1001+--- modemmanager.orig/plugins/Makefile.am
1002++++ modemmanager/plugins/Makefile.am
1003+@@ -459,6 +459,8 @@ libmm_plugin_novatel_lte_la_LDFLAGS = $(
1004+ libmm_plugin_novatel_la_SOURCES = \
1005+ novatel/mm-plugin-novatel.c \
1006+ novatel/mm-plugin-novatel.h \
1007++ novatel/mm-common-novatel.c \
1008++ novatel/mm-common-novatel.h \
1009+ novatel/mm-broadband-modem-novatel.c \
1010+ novatel/mm-broadband-modem-novatel.h
1011+ libmm_plugin_novatel_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
1012+Index: modemmanager/plugins/novatel/mm-common-novatel.c
1013+===================================================================
1014+--- /dev/null
1015++++ modemmanager/plugins/novatel/mm-common-novatel.c
1016+@@ -0,0 +1,158 @@
1017++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
1018++/*
1019++ * This program is free software; you can redistribute it and/or modify
1020++ * it under the terms of the GNU General Public License as published by
1021++ * the Free Software Foundation; either version 2 of the License, or
1022++ * (at your option) any later version.
1023++ *
1024++ * This program is distributed in the hope that it will be useful,
1025++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1026++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1027++ * GNU General Public License for more details:
1028++ *
1029++ * Copyright (C) 2015 Aleksander Morgado <aleksander@aleksander.es>
1030++ */
1031++
1032++#include "mm-common-novatel.h"
1033++#include "mm-log.h"
1034++
1035++/*****************************************************************************/
1036++/* Custom init */
1037++
1038++typedef struct {
1039++ MMPortProbe *probe;
1040++ MMPortSerialAt *port;
1041++ GCancellable *cancellable;
1042++ GSimpleAsyncResult *result;
1043++ guint nwdmat_retries;
1044++ guint wait_time;
1045++} CustomInitContext;
1046++
1047++static void
1048++custom_init_context_complete_and_free (CustomInitContext *ctx)
1049++{
1050++ g_simple_async_result_complete_in_idle (ctx->result);
1051++
1052++ if (ctx->cancellable)
1053++ g_object_unref (ctx->cancellable);
1054++ g_object_unref (ctx->port);
1055++ g_object_unref (ctx->probe);
1056++ g_object_unref (ctx->result);
1057++ g_slice_free (CustomInitContext, ctx);
1058++}
1059++
1060++gboolean
1061++mm_common_novatel_custom_init_finish (MMPortProbe *probe,
1062++ GAsyncResult *result,
1063++ GError **error)
1064++{
1065++ return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
1066++}
1067++
1068++static void custom_init_step (CustomInitContext *ctx);
1069++
1070++static void
1071++nwdmat_ready (MMPortSerialAt *port,
1072++ GAsyncResult *res,
1073++ CustomInitContext *ctx)
1074++{
1075++ const gchar *response;
1076++ GError *error = NULL;
1077++
1078++ response = mm_port_serial_at_command_finish (port, res, &error);
1079++ if (error) {
1080++ if (g_error_matches (error,
1081++ MM_SERIAL_ERROR,
1082++ MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) {
1083++ custom_init_step (ctx);
1084++ goto out;
1085++ }
1086++
1087++ mm_dbg ("(Novatel) Error flipping secondary ports to AT mode: %s", error->message);
1088++ }
1089++
1090++ /* Finish custom_init */
1091++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1092++ custom_init_context_complete_and_free (ctx);
1093++
1094++out:
1095++ if (error)
1096++ g_error_free (error);
1097++}
1098++
1099++static gboolean
1100++custom_init_wait_cb (CustomInitContext *ctx)
1101++{
1102++ custom_init_step (ctx);
1103++ return FALSE;
1104++}
1105++
1106++static void
1107++custom_init_step (CustomInitContext *ctx)
1108++{
1109++ /* If cancelled, end */
1110++ if (g_cancellable_is_cancelled (ctx->cancellable)) {
1111++ mm_dbg ("(Novatel) no need to keep on running custom init in (%s)",
1112++ mm_port_get_device (MM_PORT (ctx->port)));
1113++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1114++ custom_init_context_complete_and_free (ctx);
1115++ return;
1116++ }
1117++
1118++ /* If device has a QMI port, don't run $NWDMAT */
1119++ if (mm_port_probe_list_has_qmi_port (mm_device_peek_port_probe_list (mm_port_probe_peek_device (ctx->probe)))) {
1120++ mm_dbg ("(Novatel) no need to run custom init in (%s): device has QMI port",
1121++ mm_port_get_device (MM_PORT (ctx->port)));
1122++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1123++ custom_init_context_complete_and_free (ctx);
1124++ return;
1125++ }
1126++
1127++ if (ctx->wait_time > 0) {
1128++ ctx->wait_time--;
1129++ g_timeout_add_seconds (1, (GSourceFunc)custom_init_wait_cb, ctx);
1130++ return;
1131++ }
1132++
1133++ if (ctx->nwdmat_retries > 0) {
1134++ ctx->nwdmat_retries--;
1135++ mm_port_serial_at_command (ctx->port,
1136++ "$NWDMAT=1",
1137++ 3,
1138++ FALSE, /* raw */
1139++ FALSE, /* allow_cached */
1140++ ctx->cancellable,
1141++ (GAsyncReadyCallback)nwdmat_ready,
1142++ ctx);
1143++ return;
1144++ }
1145++
1146++ /* Finish custom_init */
1147++ mm_dbg ("(Novatel) couldn't flip secondary port to AT in (%s): all retries consumed",
1148++ mm_port_get_device (MM_PORT (ctx->port)));
1149++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1150++ custom_init_context_complete_and_free (ctx);
1151++}
1152++
1153++void
1154++mm_common_novatel_custom_init (MMPortProbe *probe,
1155++ MMPortSerialAt *port,
1156++ GCancellable *cancellable,
1157++ GAsyncReadyCallback callback,
1158++ gpointer user_data)
1159++{
1160++ CustomInitContext *ctx;
1161++
1162++ ctx = g_slice_new (CustomInitContext);
1163++ ctx->result = g_simple_async_result_new (G_OBJECT (probe),
1164++ callback,
1165++ user_data,
1166++ mm_common_novatel_custom_init);
1167++ ctx->probe = g_object_ref (probe);
1168++ ctx->port = g_object_ref (port);
1169++ ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1170++ ctx->nwdmat_retries = 3;
1171++ ctx->wait_time = 2;
1172++
1173++ custom_init_step (ctx);
1174++}
1175+Index: modemmanager/plugins/novatel/mm-common-novatel.h
1176+===================================================================
1177+--- /dev/null
1178++++ modemmanager/plugins/novatel/mm-common-novatel.h
1179+@@ -0,0 +1,31 @@
1180++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
1181++/*
1182++ * This program is free software; you can redistribute it and/or modify
1183++ * it under the terms of the GNU General Public License as published by
1184++ * the Free Software Foundation; either version 2 of the License, or
1185++ * (at your option) any later version.
1186++ *
1187++ * This program is distributed in the hope that it will be useful,
1188++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1189++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1190++ * GNU General Public License for more details:
1191++ *
1192++ * Copyright (C) 2015 Aleksander Morgado <aleksander@aleksander.es>
1193++ */
1194++
1195++#ifndef MM_COMMON_NOVATEL_H
1196++#define MM_COMMON_NOVATEL_H
1197++
1198++#include "glib.h"
1199++#include "mm-plugin.h"
1200++
1201++void mm_common_novatel_custom_init (MMPortProbe *probe,
1202++ MMPortSerialAt *port,
1203++ GCancellable *cancellable,
1204++ GAsyncReadyCallback callback,
1205++ gpointer user_data);
1206++gboolean mm_common_novatel_custom_init_finish (MMPortProbe *probe,
1207++ GAsyncResult *result,
1208++ GError **error);
1209++
1210++#endif /* MM_COMMON_NOVATEL_H */
1211+Index: modemmanager/plugins/novatel/mm-plugin-novatel.c
1212+===================================================================
1213+--- modemmanager.orig/plugins/novatel/mm-plugin-novatel.c
1214++++ modemmanager/plugins/novatel/mm-plugin-novatel.c
1215+@@ -28,6 +28,7 @@
1216+ #include <libmm-glib.h>
1217+
1218+ #include "mm-plugin-novatel.h"
1219++#include "mm-common-novatel.h"
1220+ #include "mm-private-boxed-types.h"
1221+ #include "mm-broadband-modem-novatel.h"
1222+ #include "mm-log.h"
1223+@@ -55,147 +56,6 @@ static const MMPortProbeAtCommand custom
1224+ };
1225+
1226+ /*****************************************************************************/
1227+-/* Custom init */
1228+-
1229+-typedef struct {
1230+- MMPortProbe *probe;
1231+- MMPortSerialAt *port;
1232+- GCancellable *cancellable;
1233+- GSimpleAsyncResult *result;
1234+- guint nwdmat_retries;
1235+- guint wait_time;
1236+-} CustomInitContext;
1237+-
1238+-static void
1239+-custom_init_context_complete_and_free (CustomInitContext *ctx)
1240+-{
1241+- g_simple_async_result_complete_in_idle (ctx->result);
1242+-
1243+- if (ctx->cancellable)
1244+- g_object_unref (ctx->cancellable);
1245+- g_object_unref (ctx->port);
1246+- g_object_unref (ctx->probe);
1247+- g_object_unref (ctx->result);
1248+- g_slice_free (CustomInitContext, ctx);
1249+-}
1250+-
1251+-static gboolean
1252+-novatel_custom_init_finish (MMPortProbe *probe,
1253+- GAsyncResult *result,
1254+- GError **error)
1255+-{
1256+- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
1257+-}
1258+-
1259+-static void custom_init_step (CustomInitContext *ctx);
1260+-
1261+-static void
1262+-nwdmat_ready (MMPortSerialAt *port,
1263+- GAsyncResult *res,
1264+- CustomInitContext *ctx)
1265+-{
1266+- const gchar *response;
1267+- GError *error = NULL;
1268+-
1269+- response = mm_port_serial_at_command_finish (port, res, &error);
1270+- if (error) {
1271+- if (g_error_matches (error,
1272+- MM_SERIAL_ERROR,
1273+- MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) {
1274+- custom_init_step (ctx);
1275+- goto out;
1276+- }
1277+-
1278+- mm_dbg ("(Novatel) Error flipping secondary ports to AT mode: %s", error->message);
1279+- }
1280+-
1281+- /* Finish custom_init */
1282+- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1283+- custom_init_context_complete_and_free (ctx);
1284+-
1285+-out:
1286+- if (error)
1287+- g_error_free (error);
1288+-}
1289+-
1290+-static gboolean
1291+-custom_init_wait_cb (CustomInitContext *ctx)
1292+-{
1293+- custom_init_step (ctx);
1294+- return FALSE;
1295+-}
1296+-
1297+-static void
1298+-custom_init_step (CustomInitContext *ctx)
1299+-{
1300+- /* If cancelled, end */
1301+- if (g_cancellable_is_cancelled (ctx->cancellable)) {
1302+- mm_dbg ("(Novatel) no need to keep on running custom init in (%s)",
1303+- mm_port_get_device (MM_PORT (ctx->port)));
1304+- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1305+- custom_init_context_complete_and_free (ctx);
1306+- return;
1307+- }
1308+-
1309+- /* If device has a QMI port, don't run $NWDMAT */
1310+- if (mm_port_probe_list_has_qmi_port (mm_device_peek_port_probe_list (mm_port_probe_peek_device (ctx->probe)))) {
1311+- mm_dbg ("(Novatel) no need to run custom init in (%s): device has QMI port",
1312+- mm_port_get_device (MM_PORT (ctx->port)));
1313+- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1314+- custom_init_context_complete_and_free (ctx);
1315+- return;
1316+- }
1317+-
1318+- if (ctx->wait_time > 0) {
1319+- ctx->wait_time--;
1320+- g_timeout_add_seconds (1, (GSourceFunc)custom_init_wait_cb, ctx);
1321+- return;
1322+- }
1323+-
1324+- if (ctx->nwdmat_retries > 0) {
1325+- ctx->nwdmat_retries--;
1326+- mm_port_serial_at_command (ctx->port,
1327+- "$NWDMAT=1",
1328+- 3,
1329+- FALSE, /* raw */
1330+- FALSE, /* allow_cached */
1331+- ctx->cancellable,
1332+- (GAsyncReadyCallback)nwdmat_ready,
1333+- ctx);
1334+- return;
1335+- }
1336+-
1337+- /* Finish custom_init */
1338+- mm_dbg ("(Novatel) couldn't flip secondary port to AT in (%s): all retries consumed",
1339+- mm_port_get_device (MM_PORT (ctx->port)));
1340+- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1341+- custom_init_context_complete_and_free (ctx);
1342+-}
1343+-
1344+-static void
1345+-novatel_custom_init (MMPortProbe *probe,
1346+- MMPortSerialAt *port,
1347+- GCancellable *cancellable,
1348+- GAsyncReadyCallback callback,
1349+- gpointer user_data)
1350+-{
1351+- CustomInitContext *ctx;
1352+-
1353+- ctx = g_slice_new (CustomInitContext);
1354+- ctx->result = g_simple_async_result_new (G_OBJECT (probe),
1355+- callback,
1356+- user_data,
1357+- novatel_custom_init);
1358+- ctx->probe = g_object_ref (probe);
1359+- ctx->port = g_object_ref (port);
1360+- ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1361+- ctx->nwdmat_retries = 3;
1362+- ctx->wait_time = 2;
1363+-
1364+- custom_init_step (ctx);
1365+-}
1366+-
1367+-/*****************************************************************************/
1368+
1369+ static MMBaseModem *
1370+ create_modem (MMPlugin *self,
1371+@@ -236,8 +96,8 @@ mm_plugin_create (void)
1372+ static const mm_uint16_pair forbidden_products[] = { { 0x1410, 0x9010 }, /* Novatel E362 */
1373+ { 0, 0 } };
1374+ static const MMAsyncMethod custom_init = {
1375+- .async = G_CALLBACK (novatel_custom_init),
1376+- .finish = G_CALLBACK (novatel_custom_init_finish),
1377++ .async = G_CALLBACK (mm_common_novatel_custom_init),
1378++ .finish = G_CALLBACK (mm_common_novatel_custom_init_finish),
1379+ };
1380+
1381+ return MM_PLUGIN (
1382
1383=== modified file 'debian/patches/series'
1384--- debian/patches/series 2015-05-08 01:44:53 +0000
1385+++ debian/patches/series 2015-09-15 09:59:59 +0000
1386@@ -0,0 +1,7 @@
1387+novatel-custom-init.patch
1388+novatel-common-library.patch
1389+sierra-common-library.patch
1390+mbm-common-library.patch
1391+sierra-custom-init.patch
1392+new-sierra-legacy-plugin.patch
1393+dell-mbim-plugin.patch
1394
1395=== added file 'debian/patches/sierra-common-library.patch'
1396--- debian/patches/sierra-common-library.patch 1970-01-01 00:00:00 +0000
1397+++ debian/patches/sierra-common-library.patch 2015-09-15 09:59:59 +0000
1398@@ -0,0 +1,50 @@
1399+commit 299280166301d00c2b0e2b8868a96013388b2a3f
1400+Author: Aleksander Morgado <aleksander@aleksander.es>
1401+Date: Fri Feb 6 16:51:13 2015 +0100
1402+
1403+ sierra: build a common non-inst library with the core Sierra modem support
1404+
1405+Index: modemmanager/plugins/Makefile.am
1406+===================================================================
1407+--- modemmanager.orig/plugins/Makefile.am
1408++++ modemmanager/plugins/Makefile.am
1409+@@ -263,10 +263,9 @@ libmm_plugin_hso_la_SOURCES = \
1410+ libmm_plugin_hso_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
1411+ libmm_plugin_hso_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
1412+
1413+-# Sierra
1414+-libmm_plugin_sierra_la_SOURCES = \
1415+- sierra/mm-plugin-sierra.c \
1416+- sierra/mm-plugin-sierra.h \
1417++# Common Sierra modem support library
1418++noinst_LTLIBRARIES += libmm-utils-sierra.la
1419++libmm_utils_sierra_la_SOURCES = \
1420+ sierra/mm-common-sierra.c \
1421+ sierra/mm-common-sierra.h \
1422+ sierra/mm-sim-sierra.c \
1423+@@ -274,12 +273,22 @@ libmm_plugin_sierra_la_SOURCES = \
1424+ sierra/mm-broadband-bearer-sierra.c \
1425+ sierra/mm-broadband-bearer-sierra.h \
1426+ sierra/mm-broadband-modem-sierra.c \
1427+- sierra/mm-broadband-modem-sierra.h \
1428++ sierra/mm-broadband-modem-sierra.h
1429++libmm_utils_sierra_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
1430++libmm_utils_sierra_la_LIBADD = $(GUDEV_LIBS) $(MM_LIBS)
1431++
1432++SIERRA_COMMON_COMPILER_FLAGS = -I$(top_srcdir)/plugins/sierra
1433++SIERRA_COMMON_LIBADD_FLAGS = $(builddir)/libmm-utils-sierra.la
1434++
1435++# Sierra
1436++libmm_plugin_sierra_la_SOURCES = \
1437++ sierra/mm-plugin-sierra.c \
1438++ sierra/mm-plugin-sierra.h \
1439+ sierra/mm-broadband-modem-sierra-icera.c \
1440+ sierra/mm-broadband-modem-sierra-icera.h
1441+-libmm_plugin_sierra_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(ICERA_COMMON_COMPILER_FLAGS)
1442++libmm_plugin_sierra_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(ICERA_COMMON_COMPILER_FLAGS) $(SIERRA_COMMON_COMPILER_FLAGS)
1443+ libmm_plugin_sierra_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
1444+-libmm_plugin_sierra_la_LIBADD = $(ICERA_COMMON_LIBADD_FLAGS)
1445++libmm_plugin_sierra_la_LIBADD = $(ICERA_COMMON_LIBADD_FLAGS) $(SIERRA_COMMON_LIBADD_FLAGS)
1446+
1447+ # Wavecom (Sierra Airlink)
1448+ libmm_plugin_wavecom_la_SOURCES = \
1449
1450=== added file 'debian/patches/sierra-custom-init.patch'
1451--- debian/patches/sierra-custom-init.patch 1970-01-01 00:00:00 +0000
1452+++ debian/patches/sierra-custom-init.patch 2015-09-15 09:59:59 +0000
1453@@ -0,0 +1,548 @@
1454+commit b1159453998e6dc89ba31a803c4c3886c8da0605
1455+Author: Aleksander Morgado <aleksander@aleksander.es>
1456+Date: Fri Feb 6 17:29:56 2015 +0100
1457+
1458+ sierra: move custom init and port grabbing methods to separate source files
1459+
1460+diff --git a/plugins/sierra/mm-common-sierra.c b/plugins/sierra/mm-common-sierra.c
1461+index 82a5d7b..e712093 100644
1462+--- a/plugins/sierra/mm-common-sierra.c
1463++++ b/plugins/sierra/mm-common-sierra.c
1464+@@ -15,6 +15,9 @@
1465+ * Copyright (C) 2012 Lanedo GmbH
1466+ */
1467+
1468++#include <stdlib.h>
1469++#include <string.h>
1470++
1471+ #include "mm-common-sierra.h"
1472+ #include "mm-base-modem-at.h"
1473+ #include "mm-log.h"
1474+@@ -24,6 +27,220 @@
1475+ static MMIfaceModem *iface_modem_parent;
1476+
1477+ /*****************************************************************************/
1478++/* Custom init and port type hints */
1479++
1480++#define TAG_SIERRA_APP_PORT "sierra-app-port"
1481++#define TAG_SIERRA_APP1_PPP_OK "sierra-app1-ppp-ok"
1482++
1483++gboolean
1484++mm_common_sierra_grab_port (MMPlugin *self,
1485++ MMBaseModem *modem,
1486++ MMPortProbe *probe,
1487++ GError **error)
1488++{
1489++ MMPortSerialAtFlag pflags = MM_PORT_SERIAL_AT_FLAG_NONE;
1490++ MMPortType ptype;
1491++
1492++ ptype = mm_port_probe_get_port_type (probe);
1493++
1494++ /* Is it a GSM secondary port? */
1495++ if (g_object_get_data (G_OBJECT (probe), TAG_SIERRA_APP_PORT)) {
1496++ if (g_object_get_data (G_OBJECT (probe), TAG_SIERRA_APP1_PPP_OK))
1497++ pflags = MM_PORT_SERIAL_AT_FLAG_PPP;
1498++ else
1499++ pflags = MM_PORT_SERIAL_AT_FLAG_SECONDARY;
1500++ } else if (ptype == MM_PORT_TYPE_AT)
1501++ pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY;
1502++
1503++ return mm_base_modem_grab_port (modem,
1504++ mm_port_probe_get_port_subsys (probe),
1505++ mm_port_probe_get_port_name (probe),
1506++ mm_port_probe_get_parent_path (probe),
1507++ ptype,
1508++ pflags,
1509++ error);
1510++}
1511++
1512++gboolean
1513++mm_common_sierra_port_probe_list_is_icera (GList *probes)
1514++{
1515++ GList *l;
1516++
1517++ for (l = probes; l; l = g_list_next (l)) {
1518++ /* Only assume the Icera probing check is valid IF the port is not
1519++ * secondary. This will skip the stupid ports which reply OK to every
1520++ * AT command, even the one we use to check for Icera support */
1521++ if (mm_port_probe_is_icera (MM_PORT_PROBE (l->data)) &&
1522++ !g_object_get_data (G_OBJECT (l->data), TAG_SIERRA_APP_PORT))
1523++ return TRUE;
1524++ }
1525++
1526++ return FALSE;
1527++}
1528++
1529++typedef struct {
1530++ MMPortProbe *probe;
1531++ MMPortSerialAt *port;
1532++ GCancellable *cancellable;
1533++ GSimpleAsyncResult *result;
1534++ guint retries;
1535++} SierraCustomInitContext;
1536++
1537++static void
1538++sierra_custom_init_context_complete_and_free (SierraCustomInitContext *ctx)
1539++{
1540++ g_simple_async_result_complete_in_idle (ctx->result);
1541++
1542++ if (ctx->cancellable)
1543++ g_object_unref (ctx->cancellable);
1544++ g_object_unref (ctx->port);
1545++ g_object_unref (ctx->probe);
1546++ g_object_unref (ctx->result);
1547++ g_slice_free (SierraCustomInitContext, ctx);
1548++}
1549++
1550++gboolean
1551++mm_common_sierra_custom_init_finish (MMPortProbe *probe,
1552++ GAsyncResult *result,
1553++ GError **error)
1554++{
1555++ return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
1556++}
1557++
1558++static void sierra_custom_init_step (SierraCustomInitContext *ctx);
1559++
1560++static void
1561++gcap_ready (MMPortSerialAt *port,
1562++ GAsyncResult *res,
1563++ SierraCustomInitContext *ctx)
1564++{
1565++ const gchar *response;
1566++ GError *error = NULL;
1567++
1568++ response = mm_port_serial_at_command_finish (port, res, &error);
1569++ if (error) {
1570++ /* If consumed all tries and the last error was a timeout, assume the
1571++ * port is not AT */
1572++ if (ctx->retries == 0 &&
1573++ g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) {
1574++ mm_port_probe_set_result_at (ctx->probe, FALSE);
1575++ }
1576++ /* If reported a hard parse error, this port is definitely not an AT
1577++ * port, skip trying. */
1578++ else if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_PARSE_FAILED)) {
1579++ mm_port_probe_set_result_at (ctx->probe, FALSE);
1580++ ctx->retries = 0;
1581++ }
1582++ /* Some Icera-based devices (eg, USB305) have an AT-style port that
1583++ * replies to everything with ERROR, so tag as unsupported; sometimes
1584++ * the real AT ports do this too, so let a retry tag the port as
1585++ * supported if it responds correctly later. */
1586++ else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN)) {
1587++ mm_port_probe_set_result_at (ctx->probe, FALSE);
1588++ }
1589++
1590++ /* Just retry... */
1591++ sierra_custom_init_step (ctx);
1592++ goto out;
1593++ }
1594++
1595++ /* A valid reply to ATI tells us this is an AT port already */
1596++ mm_port_probe_set_result_at (ctx->probe, TRUE);
1597++
1598++ /* Sierra APPx ports have limited AT command parsers that just reply with
1599++ * "OK" to most commands. These can sometimes be used for PPP while the
1600++ * main port is used for status and control, but older modems tend to crash
1601++ * or fail PPP. So we whitelist modems that are known to allow PPP on the
1602++ * secondary APP ports.
1603++ */
1604++ if (strstr (response, "APP1")) {
1605++ g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP_PORT, GUINT_TO_POINTER (TRUE));
1606++
1607++ /* PPP-on-APP1-port whitelist */
1608++ if (strstr (response, "C885") ||
1609++ strstr (response, "USB 306") ||
1610++ strstr (response, "MC8790"))
1611++ g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP1_PPP_OK, GUINT_TO_POINTER (TRUE));
1612++
1613++ /* For debugging: let users figure out if their device supports PPP
1614++ * on the APP1 port or not.
1615++ */
1616++ if (getenv ("MM_SIERRA_APP1_PPP_OK")) {
1617++ mm_dbg ("Sierra: APP1 PPP OK '%s'", response);
1618++ g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP1_PPP_OK, GUINT_TO_POINTER (TRUE));
1619++ }
1620++ } else if (strstr (response, "APP2") ||
1621++ strstr (response, "APP3") ||
1622++ strstr (response, "APP4")) {
1623++ /* Additional APP ports don't support most AT commands, so they cannot
1624++ * be used as the primary port.
1625++ */
1626++ g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP_PORT, GUINT_TO_POINTER (TRUE));
1627++ }
1628++
1629++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1630++ sierra_custom_init_context_complete_and_free (ctx);
1631++
1632++out:
1633++ if (error)
1634++ g_error_free (error);
1635++}
1636++
1637++static void
1638++sierra_custom_init_step (SierraCustomInitContext *ctx)
1639++{
1640++ /* If cancelled, end */
1641++ if (g_cancellable_is_cancelled (ctx->cancellable)) {
1642++ mm_dbg ("(Sierra) no need to keep on running custom init in '%s'",
1643++ mm_port_get_device (MM_PORT (ctx->port)));
1644++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1645++ sierra_custom_init_context_complete_and_free (ctx);
1646++ return;
1647++ }
1648++
1649++ if (ctx->retries == 0) {
1650++ mm_dbg ("(Sierra) Couldn't get port type hints from '%s'",
1651++ mm_port_get_device (MM_PORT (ctx->port)));
1652++ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1653++ sierra_custom_init_context_complete_and_free (ctx);
1654++ return;
1655++ }
1656++
1657++ ctx->retries--;
1658++ mm_port_serial_at_command (
1659++ ctx->port,
1660++ "ATI",
1661++ 3,
1662++ FALSE, /* raw */
1663++ FALSE, /* allow_cached */
1664++ ctx->cancellable,
1665++ (GAsyncReadyCallback)gcap_ready,
1666++ ctx);
1667++}
1668++
1669++void
1670++mm_common_sierra_custom_init (MMPortProbe *probe,
1671++ MMPortSerialAt *port,
1672++ GCancellable *cancellable,
1673++ GAsyncReadyCallback callback,
1674++ gpointer user_data)
1675++{
1676++ SierraCustomInitContext *ctx;
1677++
1678++ ctx = g_slice_new (SierraCustomInitContext);
1679++ ctx->result = g_simple_async_result_new (G_OBJECT (probe),
1680++ callback,
1681++ user_data,
1682++ mm_common_sierra_custom_init);
1683++ ctx->probe = g_object_ref (probe);
1684++ ctx->port = g_object_ref (port);
1685++ ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1686++ ctx->retries = 3;
1687++
1688++ sierra_custom_init_step (ctx);
1689++}
1690++
1691++/*****************************************************************************/
1692+ /* Modem power up (Modem interface) */
1693+
1694+ gboolean
1695+diff --git a/plugins/sierra/mm-common-sierra.h b/plugins/sierra/mm-common-sierra.h
1696+index ec206d2..22471c0 100644
1697+--- a/plugins/sierra/mm-common-sierra.h
1698++++ b/plugins/sierra/mm-common-sierra.h
1699+@@ -18,10 +18,27 @@
1700+ #ifndef MM_COMMON_SIERRA_H
1701+ #define MM_COMMON_SIERRA_H
1702+
1703++#include "mm-plugin.h"
1704+ #include "mm-broadband-modem.h"
1705+ #include "mm-iface-modem.h"
1706+ #include "mm-base-sim.h"
1707+
1708++gboolean mm_common_sierra_grab_port (MMPlugin *self,
1709++ MMBaseModem *modem,
1710++ MMPortProbe *probe,
1711++ GError **error);
1712++
1713++gboolean mm_common_sierra_port_probe_list_is_icera (GList *probes);
1714++
1715++void mm_common_sierra_custom_init (MMPortProbe *probe,
1716++ MMPortSerialAt *port,
1717++ GCancellable *cancellable,
1718++ GAsyncReadyCallback callback,
1719++ gpointer user_data);
1720++gboolean mm_common_sierra_custom_init_finish (MMPortProbe *probe,
1721++ GAsyncResult *result,
1722++ GError **error);
1723++
1724+ void mm_common_sierra_load_power_state (MMIfaceModem *self,
1725+ GAsyncReadyCallback callback,
1726+ gpointer user_data);
1727+diff --git a/plugins/sierra/mm-plugin-sierra.c b/plugins/sierra/mm-plugin-sierra.c
1728+index 96f657a..665b61c 100644
1729+--- a/plugins/sierra/mm-plugin-sierra.c
1730++++ b/plugins/sierra/mm-plugin-sierra.c
1731+@@ -15,7 +15,6 @@
1732+ * Copyright (C) 2012 Lanedo GmbH
1733+ */
1734+
1735+-#include <string.h>
1736+ #include <stdlib.h>
1737+ #include <gmodule.h>
1738+
1739+@@ -24,6 +23,7 @@
1740+
1741+ #include "mm-log.h"
1742+ #include "mm-plugin-sierra.h"
1743++#include "mm-common-sierra.h"
1744+ #include "mm-broadband-modem-sierra.h"
1745+ #include "mm-broadband-modem-sierra-icera.h"
1746+
1747+@@ -41,191 +41,6 @@ int mm_plugin_major_version = MM_PLUGIN_MAJOR_VERSION;
1748+ int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION;
1749+
1750+ /*****************************************************************************/
1751+-/* Custom init */
1752+-
1753+-#define TAG_SIERRA_APP_PORT "sierra-app-port"
1754+-#define TAG_SIERRA_APP1_PPP_OK "sierra-app1-ppp-ok"
1755+-
1756+-typedef struct {
1757+- MMPortProbe *probe;
1758+- MMPortSerialAt *port;
1759+- GCancellable *cancellable;
1760+- GSimpleAsyncResult *result;
1761+- guint retries;
1762+-} SierraCustomInitContext;
1763+-
1764+-static void
1765+-sierra_custom_init_context_complete_and_free (SierraCustomInitContext *ctx)
1766+-{
1767+- g_simple_async_result_complete_in_idle (ctx->result);
1768+-
1769+- if (ctx->cancellable)
1770+- g_object_unref (ctx->cancellable);
1771+- g_object_unref (ctx->port);
1772+- g_object_unref (ctx->probe);
1773+- g_object_unref (ctx->result);
1774+- g_slice_free (SierraCustomInitContext, ctx);
1775+-}
1776+-
1777+-static gboolean
1778+-sierra_custom_init_finish (MMPortProbe *probe,
1779+- GAsyncResult *result,
1780+- GError **error)
1781+-{
1782+- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
1783+-}
1784+-
1785+-static void sierra_custom_init_step (SierraCustomInitContext *ctx);
1786+-
1787+-static void
1788+-gcap_ready (MMPortSerialAt *port,
1789+- GAsyncResult *res,
1790+- SierraCustomInitContext *ctx)
1791+-{
1792+- const gchar *response;
1793+- GError *error = NULL;
1794+-
1795+- response = mm_port_serial_at_command_finish (port, res, &error);
1796+- if (error) {
1797+- /* If consumed all tries and the last error was a timeout, assume the
1798+- * port is not AT */
1799+- if (ctx->retries == 0 &&
1800+- g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) {
1801+- mm_port_probe_set_result_at (ctx->probe, FALSE);
1802+- }
1803+- /* If reported a hard parse error, this port is definitely not an AT
1804+- * port, skip trying. */
1805+- else if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_PARSE_FAILED)) {
1806+- mm_port_probe_set_result_at (ctx->probe, FALSE);
1807+- ctx->retries = 0;
1808+- }
1809+- /* Some Icera-based devices (eg, USB305) have an AT-style port that
1810+- * replies to everything with ERROR, so tag as unsupported; sometimes
1811+- * the real AT ports do this too, so let a retry tag the port as
1812+- * supported if it responds correctly later. */
1813+- else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN)) {
1814+- mm_port_probe_set_result_at (ctx->probe, FALSE);
1815+- }
1816+-
1817+- /* Just retry... */
1818+- sierra_custom_init_step (ctx);
1819+- goto out;
1820+- }
1821+-
1822+- /* A valid reply to ATI tells us this is an AT port already */
1823+- mm_port_probe_set_result_at (ctx->probe, TRUE);
1824+-
1825+- /* Sierra APPx ports have limited AT command parsers that just reply with
1826+- * "OK" to most commands. These can sometimes be used for PPP while the
1827+- * main port is used for status and control, but older modems tend to crash
1828+- * or fail PPP. So we whitelist modems that are known to allow PPP on the
1829+- * secondary APP ports.
1830+- */
1831+- if (strstr (response, "APP1")) {
1832+- g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP_PORT, GUINT_TO_POINTER (TRUE));
1833+-
1834+- /* PPP-on-APP1-port whitelist */
1835+- if (strstr (response, "C885") ||
1836+- strstr (response, "USB 306") ||
1837+- strstr (response, "MC8790"))
1838+- g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP1_PPP_OK, GUINT_TO_POINTER (TRUE));
1839+-
1840+- /* For debugging: let users figure out if their device supports PPP
1841+- * on the APP1 port or not.
1842+- */
1843+- if (getenv ("MM_SIERRA_APP1_PPP_OK")) {
1844+- mm_dbg ("Sierra: APP1 PPP OK '%s'", response);
1845+- g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP1_PPP_OK, GUINT_TO_POINTER (TRUE));
1846+- }
1847+- } else if (strstr (response, "APP2") ||
1848+- strstr (response, "APP3") ||
1849+- strstr (response, "APP4")) {
1850+- /* Additional APP ports don't support most AT commands, so they cannot
1851+- * be used as the primary port.
1852+- */
1853+- g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP_PORT, GUINT_TO_POINTER (TRUE));
1854+- }
1855+-
1856+- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1857+- sierra_custom_init_context_complete_and_free (ctx);
1858+-
1859+-out:
1860+- if (error)
1861+- g_error_free (error);
1862+-}
1863+-
1864+-static void
1865+-sierra_custom_init_step (SierraCustomInitContext *ctx)
1866+-{
1867+- /* If cancelled, end */
1868+- if (g_cancellable_is_cancelled (ctx->cancellable)) {
1869+- mm_dbg ("(Sierra) no need to keep on running custom init in '%s'",
1870+- mm_port_get_device (MM_PORT (ctx->port)));
1871+- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1872+- sierra_custom_init_context_complete_and_free (ctx);
1873+- return;
1874+- }
1875+-
1876+- if (ctx->retries == 0) {
1877+- mm_dbg ("(Sierra) Couldn't get port type hints from '%s'",
1878+- mm_port_get_device (MM_PORT (ctx->port)));
1879+- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
1880+- sierra_custom_init_context_complete_and_free (ctx);
1881+- return;
1882+- }
1883+-
1884+- ctx->retries--;
1885+- mm_port_serial_at_command (
1886+- ctx->port,
1887+- "ATI",
1888+- 3,
1889+- FALSE, /* raw */
1890+- FALSE, /* allow_cached */
1891+- ctx->cancellable,
1892+- (GAsyncReadyCallback)gcap_ready,
1893+- ctx);
1894+-}
1895+-
1896+-static void
1897+-sierra_custom_init (MMPortProbe *probe,
1898+- MMPortSerialAt *port,
1899+- GCancellable *cancellable,
1900+- GAsyncReadyCallback callback,
1901+- gpointer user_data)
1902+-{
1903+- SierraCustomInitContext *ctx;
1904+-
1905+- ctx = g_slice_new (SierraCustomInitContext);
1906+- ctx->result = g_simple_async_result_new (G_OBJECT (probe),
1907+- callback,
1908+- user_data,
1909+- sierra_custom_init);
1910+- ctx->probe = g_object_ref (probe);
1911+- ctx->port = g_object_ref (port);
1912+- ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1913+- ctx->retries = 3;
1914+-
1915+- sierra_custom_init_step (ctx);
1916+-}
1917+-
1918+-/*****************************************************************************/
1919+-
1920+-static gboolean
1921+-sierra_port_probe_list_is_icera (GList *probes)
1922+-{
1923+- GList *l;
1924+-
1925+- for (l = probes; l; l = g_list_next (l)) {
1926+- /* Only assume the Icera probing check is valid IF the port is not
1927+- * secondary. This will skip the stupid ports which reply OK to every
1928+- * AT command, even the one we use to check for Icera support */
1929+- if (mm_port_probe_is_icera (MM_PORT_PROBE (l->data)) &&
1930+- !g_object_get_data (G_OBJECT (l->data), TAG_SIERRA_APP_PORT))
1931+- return TRUE;
1932+- }
1933+-
1934+- return FALSE;
1935+-}
1936+
1937+ static MMBaseModem *
1938+ create_modem (MMPlugin *self,
1939+@@ -258,7 +73,7 @@ create_modem (MMPlugin *self,
1940+ }
1941+ #endif
1942+
1943+- if (sierra_port_probe_list_is_icera (probes))
1944++ if (mm_common_sierra_port_probe_list_is_icera (probes))
1945+ return MM_BASE_MODEM (mm_broadband_modem_sierra_icera_new (sysfs_path,
1946+ drivers,
1947+ mm_plugin_get_name (self),
1948+@@ -272,35 +87,6 @@ create_modem (MMPlugin *self,
1949+ product));
1950+ }
1951+
1952+-static gboolean
1953+-grab_port (MMPlugin *self,
1954+- MMBaseModem *modem,
1955+- MMPortProbe *probe,
1956+- GError **error)
1957+-{
1958+- MMPortSerialAtFlag pflags = MM_PORT_SERIAL_AT_FLAG_NONE;
1959+- MMPortType ptype;
1960+-
1961+- ptype = mm_port_probe_get_port_type (probe);
1962+-
1963+- /* Is it a GSM secondary port? */
1964+- if (g_object_get_data (G_OBJECT (probe), TAG_SIERRA_APP_PORT)) {
1965+- if (g_object_get_data (G_OBJECT (probe), TAG_SIERRA_APP1_PPP_OK))
1966+- pflags = MM_PORT_SERIAL_AT_FLAG_PPP;
1967+- else
1968+- pflags = MM_PORT_SERIAL_AT_FLAG_SECONDARY;
1969+- } else if (ptype == MM_PORT_TYPE_AT)
1970+- pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY;
1971+-
1972+- return mm_base_modem_grab_port (modem,
1973+- mm_port_probe_get_port_subsys (probe),
1974+- mm_port_probe_get_port_name (probe),
1975+- mm_port_probe_get_parent_path (probe),
1976+- ptype,
1977+- pflags,
1978+- error);
1979+-}
1980+-
1981+ /*****************************************************************************/
1982+
1983+ G_MODULE_EXPORT MMPlugin *
1984+@@ -309,8 +95,8 @@ mm_plugin_create (void)
1985+ static const gchar *subsystems[] = { "tty", "net", "usb", NULL };
1986+ static const gchar *drivers[] = { "sierra", "sierra_net", NULL };
1987+ static const MMAsyncMethod custom_init = {
1988+- .async = G_CALLBACK (sierra_custom_init),
1989+- .finish = G_CALLBACK (sierra_custom_init_finish),
1990++ .async = G_CALLBACK (mm_common_sierra_custom_init),
1991++ .finish = G_CALLBACK (mm_common_sierra_custom_init_finish),
1992+ };
1993+
1994+ return MM_PLUGIN (
1995+@@ -339,5 +125,5 @@ mm_plugin_sierra_class_init (MMPluginSierraClass *klass)
1996+ MMPluginClass *plugin_class = MM_PLUGIN_CLASS (klass);
1997+
1998+ plugin_class->create_modem = create_modem;
1999+- plugin_class->grab_port = grab_port;
2000++ plugin_class->grab_port = mm_common_sierra_grab_port;
2001+ }

Subscribers

People subscribed via source and target branches

to all changes: