Re: [OT] Re: [MM] [PATCH v2] iface-modem, novatel-lte: disable network scan in LTE mode

2013-01-04 Thread Aleksander Morgado

> 
>> You cannot mix in the same async method a code execution path using
>> mm_base_modem_at_command() with another one using GSimpleAsyncResult and
>> completion in idle.  When you use mm_base_modem_at_command(), in
>> finish() you're expected to use mm_base_modem_at_command_finish(), like
>> you did. But when you use GSimpleAsyncResult and completion in idle you
>> should use g_simple_async_result_propagate_error() in finish(). The fact
>> that it may work as expected is due to how at_command_finish() is
>> implemented; but you shouldn't rely on that.
>>
>> So you'll need to use GSimpleAsyncResult for both cases, i.e. provide a
>> _ready() GAsyncReadyCallback in mm_base_modem_at_command() to which you
>> pass 'simple' as user_data; and then complete the 'simple' from within
>> the _ready() method. In this way, you can safely call
>> g_simple_async_result_propagate_error() in finish().
> 
> Offtopic, but do you know where this is documented? Any books, online
> docs or api docs to recommend? Is it part of gnome/glibs, or dbus?
> 

If you mean the overall GSimpleAsyncResult behaviour; I guess the
reference is still the GLib/GIO API documentation:
http://developer.gnome.org/gio/unstable/GSimpleAsyncResult.html

But note that for new code, GTask is the new better and cleaner
GSimpleAsyncResult replacement:
http://developer.gnome.org/gio/unstable/GTask.html

There's no manual or tutorial just talking about async GIO functions,
AFAIK, I guess you just end up getting used to it...

-- 
Aleksander
___
networkmanager-list mailing list
networkmanager-list@gnome.org
https://mail.gnome.org/mailman/listinfo/networkmanager-list


[OT] Re: [MM] [PATCH v2] iface-modem,novatel-lte: disable network scan in LTE mode

2013-01-04 Thread Marius Kotsbak
On Jan 4, 2013 12:58 AM, "Aleksander Morgado"  wrote:

> You cannot mix in the same async method a code execution path using
> mm_base_modem_at_command() with another one using GSimpleAsyncResult and
> completion in idle.  When you use mm_base_modem_at_command(), in
> finish() you're expected to use mm_base_modem_at_command_finish(), like
> you did. But when you use GSimpleAsyncResult and completion in idle you
> should use g_simple_async_result_propagate_error() in finish(). The fact
> that it may work as expected is due to how at_command_finish() is
> implemented; but you shouldn't rely on that.
>
> So you'll need to use GSimpleAsyncResult for both cases, i.e. provide a
> _ready() GAsyncReadyCallback in mm_base_modem_at_command() to which you
> pass 'simple' as user_data; and then complete the 'simple' from within
> the _ready() method. In this way, you can safely call
> g_simple_async_result_propagate_error() in finish().

Offtopic, but do you know where this is documented? Any books, online docs
or api docs to recommend? Is it part of gnome/glibs, or dbus?

--
Marius
___
networkmanager-list mailing list
networkmanager-list@gnome.org
https://mail.gnome.org/mailman/listinfo/networkmanager-list


Re: [MM] [PATCH v2] iface-modem, novatel-lte: disable network scan in LTE mode

2013-01-03 Thread Ben Chan
Thanks for the notes.  Submitted patch v3.

- Ben


On Thu, Jan 3, 2013 at 3:58 PM, Aleksander Morgado wrote:

>
> > +static GList *
> > +scan_networks_finish (MMIfaceModem3gpp *self,
> > +  GAsyncResult *res,
> > +  GError **error)
> > +{
> > +const gchar *result;
> > +
> > +result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self),
> res, error);
> > +if (!result)
> > +return NULL;
> > +
> > +return mm_3gpp_parse_cops_test_response (result, error);
> > +}
> > +
> > +static void
> > +scan_networks (MMIfaceModem3gpp *self,
> > +   GAsyncReadyCallback callback,
> > +   gpointer user_data)
> > +{
> > +MMModemAccessTechnology access_tech;
> > +
> > +mm_dbg ("scanning for networks (Novatel LTE)...");
> > +
> > +access_tech = mm_iface_modem_get_access_technologies
> (MM_IFACE_MODEM (self));
> > +/* The Novatel LTE modem does not properly support AT+COPS=? in LTE
> mode.
> > + * Thus, do not try to scan networks when the current access
> technologies
> > + * include LTE.
> > + */
> > +if (access_tech & MM_MODEM_ACCESS_TECHNOLOGY_LTE) {
> > +GSimpleAsyncResult *simple;
> > +gchar *access_tech_string;
> > +
> > +access_tech_string =
> mm_modem_access_technology_build_string_from_mask (access_tech);
> > +mm_warn ("Couldn't scan for networks with access technologies:
> %s", access_tech_string);
> > +simple = g_simple_async_result_new (G_OBJECT (self),
> > +callback,
> > +user_data,
> > +scan_networks);
> > +g_simple_async_result_set_error (simple,
> > + MM_CORE_ERROR,
> > + MM_CORE_ERROR_UNSUPPORTED,
> > + "Couldn't scan for networks
> with access technologies: %s",
> > + access_tech_string);
> > +g_simple_async_result_complete_in_idle (simple);
> > +g_object_unref (simple);
> > +g_free (access_tech_string);
> > +return;
> > +}
> > +
> > +mm_base_modem_at_command (MM_BASE_MODEM (self),
> > +  "+COPS=?",
> > +  120,
> > +  FALSE,
> > +  callback,
> > +  user_data);
> > +}
>
> You cannot mix in the same async method a code execution path using
> mm_base_modem_at_command() with another one using GSimpleAsyncResult and
> completion in idle.  When you use mm_base_modem_at_command(), in
> finish() you're expected to use mm_base_modem_at_command_finish(), like
> you did. But when you use GSimpleAsyncResult and completion in idle you
> should use g_simple_async_result_propagate_error() in finish(). The fact
> that it may work as expected is due to how at_command_finish() is
> implemented; but you shouldn't rely on that.
>
> So you'll need to use GSimpleAsyncResult for both cases, i.e. provide a
> _ready() GAsyncReadyCallback in mm_base_modem_at_command() to which you
> pass 'simple' as user_data; and then complete the 'simple' from within
> the _ready() method. In this way, you can safely call
> g_simple_async_result_propagate_error() in finish().
>
> See for example:
>
> http://cgit.freedesktop.org/ModemManager/ModemManager/tree/plugins/simtech/mm-broadband-modem-simtech.c#n416
>
> And btw, a hint for when you just always need to report an error in idle
> in the async method (avoids the need to create a GSimpleAsyncResult
> yourself):
>
> http://developer.gnome.org/gio/unstable/GSimpleAsyncResult.html#g-simple-async-report-error-in-idle
>
> --
> Aleksander
>
___
networkmanager-list mailing list
networkmanager-list@gnome.org
https://mail.gnome.org/mailman/listinfo/networkmanager-list


Re: [MM] [PATCH v2] iface-modem,novatel-lte: disable network scan in LTE mode

2013-01-03 Thread Aleksander Morgado

> +static GList *
> +scan_networks_finish (MMIfaceModem3gpp *self,
> +  GAsyncResult *res,
> +  GError **error)
> +{
> +const gchar *result;
> +
> +result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, 
> error);
> +if (!result)
> +return NULL;
> +
> +return mm_3gpp_parse_cops_test_response (result, error);
> +}
> +
> +static void
> +scan_networks (MMIfaceModem3gpp *self,
> +   GAsyncReadyCallback callback,
> +   gpointer user_data)
> +{
> +MMModemAccessTechnology access_tech;
> +
> +mm_dbg ("scanning for networks (Novatel LTE)...");
> +
> +access_tech = mm_iface_modem_get_access_technologies (MM_IFACE_MODEM 
> (self));
> +/* The Novatel LTE modem does not properly support AT+COPS=? in LTE mode.
> + * Thus, do not try to scan networks when the current access technologies
> + * include LTE.
> + */
> +if (access_tech & MM_MODEM_ACCESS_TECHNOLOGY_LTE) {
> +GSimpleAsyncResult *simple;
> +gchar *access_tech_string;
> +
> +access_tech_string = 
> mm_modem_access_technology_build_string_from_mask (access_tech);
> +mm_warn ("Couldn't scan for networks with access technologies: %s", 
> access_tech_string);
> +simple = g_simple_async_result_new (G_OBJECT (self),
> +callback,
> +user_data,
> +scan_networks);
> +g_simple_async_result_set_error (simple,
> + MM_CORE_ERROR,
> + MM_CORE_ERROR_UNSUPPORTED,
> + "Couldn't scan for networks with 
> access technologies: %s",
> + access_tech_string);
> +g_simple_async_result_complete_in_idle (simple);
> +g_object_unref (simple);
> +g_free (access_tech_string);
> +return;
> +}
> +
> +mm_base_modem_at_command (MM_BASE_MODEM (self),
> +  "+COPS=?",
> +  120,
> +  FALSE,
> +  callback,
> +  user_data);
> +}

You cannot mix in the same async method a code execution path using
mm_base_modem_at_command() with another one using GSimpleAsyncResult and
completion in idle.  When you use mm_base_modem_at_command(), in
finish() you're expected to use mm_base_modem_at_command_finish(), like
you did. But when you use GSimpleAsyncResult and completion in idle you
should use g_simple_async_result_propagate_error() in finish(). The fact
that it may work as expected is due to how at_command_finish() is
implemented; but you shouldn't rely on that.

So you'll need to use GSimpleAsyncResult for both cases, i.e. provide a
_ready() GAsyncReadyCallback in mm_base_modem_at_command() to which you
pass 'simple' as user_data; and then complete the 'simple' from within
the _ready() method. In this way, you can safely call
g_simple_async_result_propagate_error() in finish().

See for example:
http://cgit.freedesktop.org/ModemManager/ModemManager/tree/plugins/simtech/mm-broadband-modem-simtech.c#n416

And btw, a hint for when you just always need to report an error in idle
in the async method (avoids the need to create a GSimpleAsyncResult
yourself):
http://developer.gnome.org/gio/unstable/GSimpleAsyncResult.html#g-simple-async-report-error-in-idle

-- 
Aleksander
___
networkmanager-list mailing list
networkmanager-list@gnome.org
https://mail.gnome.org/mailman/listinfo/networkmanager-list


[MM] [PATCH v2] iface-modem, novatel-lte: disable network scan in LTE mode

2013-01-03 Thread Ben Chan
---
 plugins/novatel/mm-broadband-modem-novatel-lte.c |   72 +-
 src/mm-iface-modem.c |   20 ++
 src/mm-iface-modem.h |3 +
 3 files changed, 94 insertions(+), 1 deletions(-)

diff --git a/plugins/novatel/mm-broadband-modem-novatel-lte.c 
b/plugins/novatel/mm-broadband-modem-novatel-lte.c
index 249a4a1..d667182 100644
--- a/plugins/novatel/mm-broadband-modem-novatel-lte.c
+++ b/plugins/novatel/mm-broadband-modem-novatel-lte.c
@@ -29,15 +29,18 @@
 #include "mm-sim-novatel-lte.h"
 #include "mm-errors-types.h"
 #include "mm-iface-modem.h"
+#include "mm-iface-modem-3gpp.h"
 #include "mm-iface-modem-messaging.h"
 #include "mm-log.h"
 #include "mm-modem-helpers.h"
 #include "mm-serial-parsers.h"
 
 static void iface_modem_init (MMIfaceModem *iface);
+static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
 
 G_DEFINE_TYPE_EXTENDED (MMBroadbandModemNovatelLte, 
mm_broadband_modem_novatel_lte, MM_TYPE_BROADBAND_MODEM, 0,
-G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, 
iface_modem_init));
+G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, 
iface_modem_init)
+G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, 
iface_modem_3gpp_init));
 
 /*/
 /* Create Bearer (Modem interface) */
@@ -519,6 +522,66 @@ reset (MMIfaceModem *self,
 }
 
 /*/
+/* Scan networks (3GPP interface) */
+
+static GList *
+scan_networks_finish (MMIfaceModem3gpp *self,
+  GAsyncResult *res,
+  GError **error)
+{
+const gchar *result;
+
+result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, 
error);
+if (!result)
+return NULL;
+
+return mm_3gpp_parse_cops_test_response (result, error);
+}
+
+static void
+scan_networks (MMIfaceModem3gpp *self,
+   GAsyncReadyCallback callback,
+   gpointer user_data)
+{
+MMModemAccessTechnology access_tech;
+
+mm_dbg ("scanning for networks (Novatel LTE)...");
+
+access_tech = mm_iface_modem_get_access_technologies (MM_IFACE_MODEM 
(self));
+/* The Novatel LTE modem does not properly support AT+COPS=? in LTE mode.
+ * Thus, do not try to scan networks when the current access technologies
+ * include LTE.
+ */
+if (access_tech & MM_MODEM_ACCESS_TECHNOLOGY_LTE) {
+GSimpleAsyncResult *simple;
+gchar *access_tech_string;
+
+access_tech_string = mm_modem_access_technology_build_string_from_mask 
(access_tech);
+mm_warn ("Couldn't scan for networks with access technologies: %s", 
access_tech_string);
+simple = g_simple_async_result_new (G_OBJECT (self),
+callback,
+user_data,
+scan_networks);
+g_simple_async_result_set_error (simple,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_UNSUPPORTED,
+ "Couldn't scan for networks with 
access technologies: %s",
+ access_tech_string);
+g_simple_async_result_complete_in_idle (simple);
+g_object_unref (simple);
+g_free (access_tech_string);
+return;
+}
+
+mm_base_modem_at_command (MM_BASE_MODEM (self),
+  "+COPS=?",
+  120,
+  FALSE,
+  callback,
+  user_data);
+}
+
+/*/
 
 MMBroadbandModemNovatelLte *
 mm_broadband_modem_novatel_lte_new (const gchar *device,
@@ -564,6 +627,13 @@ iface_modem_init (MMIfaceModem *iface)
 }
 
 static void
+iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
+{
+iface->scan_networks = scan_networks;
+iface->scan_networks_finish = scan_networks_finish;
+}
+
+static void
 mm_broadband_modem_novatel_lte_class_init (MMBroadbandModemNovatelLteClass 
*klass)
 {
 }
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index d25b03d..e94bc42 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -3930,6 +3930,26 @@ mm_iface_modem_shutdown (MMIfaceModem *self)
 
 /*/
 
+MMModemAccessTechnology
+mm_iface_modem_get_access_technologies (MMIfaceModem *self)
+{
+MMModemAccessTechnology access_tech = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
+MmGdbusModem *skeleton;
+
+g_object_get (self,
+  MM_IFACE_MODEM_DBUS_SKELETON, &skeleton,
+  NULL);
+
+if (skeleton) {
+access_tech = mm_gdbus_modem_get_access_technologies (skeleton);
+