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

Proposed by Bin Li on 2015-04-13
Status: Superseded
Proposed branch: lp:~binli/ubuntu/trusty/modemmanager/lp1441095
Merge into: lp:ubuntu/trusty/modemmanager
Diff against target: 2001 lines (+1951/-0)
9 files modified
debian/changelog (+6/-0)
debian/patches/dell-mbim-plugin.patch (+566/-0)
debian/patches/mbm-common-library.patch (+49/-0)
debian/patches/new-sierra-legacy-plugin.patch (+295/-0)
debian/patches/novatel-common-library.patch (+51/-0)
debian/patches/novatel-custom-init.patch (+392/-0)
debian/patches/series (+7/-0)
debian/patches/sierra-common-library.patch (+54/-0)
debian/patches/sierra-custom-init.patch (+531/-0)
To merge this branch: bzr merge lp:~binli/ubuntu/trusty/modemmanager/lp1441095
Reviewer Review Type Date Requested Status
Bin Li (community) Resubmit on 2015-09-15
Ubuntu branches 2015-04-13 Pending
Review via email: mp+255935@code.launchpad.net

This proposal has been superseded by a proposal from 2015-09-23.

Description of the change

Support the MBIM for Dell.

dell-mbim-plugin.patch need novatel-custom-init.patch and sierra-custom-init.patch.

It built successfully, but not test it yet.

To post a comment you must log in.
Sebastien Bacher (seb128) wrote :

Thanks but before doing a backport to trusty the issue should be fixed in wily...

Iain Lane (laney) wrote :

said on #ubuntu-desktop

02/09 11:56:37 <Laney> BinLi: hi, I hope you're the right BinLi. Can you look to fix wily for https://code.launchpad.net/~binli/ubuntu/trusty/modemmanager/lp1441095/+merge/255935 per seb128's
                       comment please?
02/09 11:57:45 <Laney> If it's cherry-picks from upstream this can probably go via Debian and maybe cyphermox can help you there

-> Work In Progress - please reset to Needs Review once this is done. Also could you merge the two changelog entries into one please?

Bin Li (binli) wrote :

Iain & seb128,

 Thanks for your reply, this week is holiday in China, I will update it next week.

Bin Li (binli) wrote :

@Iain, @Seb128,

 In trusty, I have finished the patches, I separated the previous patches based on the upstream commit, I merged these together for convenient in first version, I back-ported modemmanager from master branch(1.5) to trusty(1.0), some data structure was changed which I have updated in the backported patches.

 For Wily, we need to backport these patch from master branch(1.5) to 1.4 which is used by wily, I'm still working on it.

 And yes, if it could be cherry-picks from upstream(1.5) to 1.4, it's the best way, could we let cyphermox to help us? Thanks!

Bin Li (binli) wrote :

@Iain, @Seb128,

 I have done for trusty and wily. Thanks!

review: Resubmit
Bin Li (binli) wrote :

Sorry, I just resubmit it to change the status

43. By Bin Li on 2015-09-25

 * Support the MBIM for Dell. (LP: #1441095)

Unmerged revisions

Preview Diff

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