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