[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 aleksan...@lanedo.com 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: [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


[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);
+g_object_unref 

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


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 aleksan...@lanedo.comwrote:


  +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