[OT] Re: [MM] [PATCH v2] iface-modem,novatel-lte: disable network scan in LTE mode
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
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
--- 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
+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
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