diff options
Diffstat (limited to 'src/devices/wwan')
| -rw-r--r-- | src/devices/wwan/libnm-wwan.ver | 1 | ||||
| -rw-r--r-- | src/devices/wwan/meson.build | 14 | ||||
| -rw-r--r-- | src/devices/wwan/nm-device-modem.c | 115 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-broadband.c | 118 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-manager.c | 1 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-ofono.c | 102 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem.c | 232 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem.h | 22 | ||||
| -rw-r--r-- | src/devices/wwan/nm-wwan-factory.c | 1 |
9 files changed, 252 insertions, 354 deletions
diff --git a/src/devices/wwan/libnm-wwan.ver b/src/devices/wwan/libnm-wwan.ver index 70b954c5..ea966afe 100644 --- a/src/devices/wwan/libnm-wwan.ver +++ b/src/devices/wwan/libnm-wwan.ver @@ -6,7 +6,6 @@ global: nm_modem_complete_connection; nm_modem_deactivate; nm_modem_deactivate_async; - nm_modem_deactivate_async_finish; nm_modem_device_state_changed; nm_modem_get_capabilities; nm_modem_get_configured_mtu; diff --git a/src/devices/wwan/meson.build b/src/devices/wwan/meson.build index 5fe6e433..482dc205 100644 --- a/src/devices/wwan/meson.build +++ b/src/devices/wwan/meson.build @@ -1,13 +1,13 @@ sources = files( 'nm-modem-broadband.c', 'nm-modem.c', - 'nm-modem-manager.c' + 'nm-modem-manager.c', ) deps = [ libsystemd_dep, mm_glib_dep, - nm_dep + nm_dep, ] if enable_ofono @@ -25,12 +25,12 @@ libnm_wwan = shared_module( ], link_depends: linker_script, install: true, - install_dir: nm_plugindir + install_dir: nm_plugindir, ) libnm_wwan_dep = declare_dependency( include_directories: include_directories('.'), - link_with: libnm_wwan + link_with: libnm_wwan, ) core_plugins += libnm_wwan @@ -43,7 +43,7 @@ test( sources = files( 'nm-device-modem.c', - 'nm-wwan-factory.c' + 'nm-wwan-factory.c', ) libnm_device_plugin_wwan = shared_module( @@ -55,7 +55,7 @@ libnm_device_plugin_wwan = shared_module( link_depends: linker_script_devices, install: true, install_dir: nm_plugindir, - install_rpath: nm_plugindir + install_rpath: nm_plugindir, ) core_plugins += libnm_device_plugin_wwan @@ -63,7 +63,7 @@ core_plugins += libnm_device_plugin_wwan run_target( 'check-local-devices-wwan', command: [check_exports, libnm_device_plugin_wwan.full_path(), linker_script_devices], - depends: libnm_device_plugin_wwan + depends: libnm_device_plugin_wwan, ) # FIXME: check_so_symbols replacement diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index 8ff931aa..1e316280 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -22,9 +22,8 @@ #include "nm-device-modem.h" -#include <string.h> - #include "nm-modem.h" +#include "nm-ip4-config.h" #include "devices/nm-device-private.h" #include "nm-rfkill-manager.h" #include "settings/nm-settings-connection.h" @@ -61,7 +60,7 @@ struct _NMDeviceModemClass { G_DEFINE_TYPE (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE) -#define NM_DEVICE_MODEM_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceModem, NM_IS_DEVICE_MODEM) +#define NM_DEVICE_MODEM_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceModem, NM_IS_DEVICE_MODEM, NMDevice) /*****************************************************************************/ @@ -85,9 +84,9 @@ ppp_failed (NMModem *modem, case NM_DEVICE_STATE_SECONDARIES: case NM_DEVICE_STATE_ACTIVATED: if (nm_device_activate_ip4_state_in_conf (device)) - nm_device_activate_schedule_ip4_config_timeout (device); + nm_device_activate_schedule_ip_config_timeout (device, AF_INET); else if (nm_device_activate_ip6_state_in_conf (device)) - nm_device_activate_schedule_ip6_config_timeout (device); + nm_device_activate_schedule_ip_config_timeout (device, AF_INET6); else if (nm_device_activate_ip4_state_done (device)) { nm_device_ip_method_failed (device, AF_INET, @@ -213,8 +212,8 @@ modem_ip4_config_result (NMModem *modem, AF_INET, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); } else { - nm_device_set_wwan_ip4_config (device, config); - nm_device_activate_schedule_ip4_config_result (device, NULL); + nm_device_set_dev2_ip_config (device, AF_INET, NM_IP_CONFIG_CAST (config)); + nm_device_activate_schedule_ip_config_result (device, AF_INET, NULL); } } @@ -229,7 +228,7 @@ modem_ip6_config_result (NMModem *modem, NMDevice *device = NM_DEVICE (self); NMActStageReturn ret; NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; - NMIP6Config *ignored = NULL; + gs_unref_object NMIP6Config *ignored = NULL; gboolean got_config = !!config; g_return_if_fail (nm_device_activate_ip6_state_in_conf (device) == TRUE); @@ -244,14 +243,14 @@ modem_ip6_config_result (NMModem *modem, } /* Re-enable IPv6 on the interface */ - nm_device_ipv6_sysctl_set (device, "disable_ipv6", "0"); + nm_device_sysctl_ip_conf_set (device, AF_INET6, "disable_ipv6", "0"); if (config) - nm_device_set_wwan_ip6_config (device, config); + nm_device_set_dev2_ip_config (device, AF_INET6, NM_IP_CONFIG_CAST (config)); if (do_slaac == FALSE) { if (got_config) - nm_device_activate_schedule_ip6_config_result (device); + nm_device_activate_schedule_ip_config_result (device, AF_INET6, NULL); else { _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: SLAAC not requested and no addresses"); nm_device_ip_method_failed (device, @@ -262,15 +261,17 @@ modem_ip6_config_result (NMModem *modem, } /* Start SLAAC now that we have a link-local address from the modem */ - ret = NM_DEVICE_CLASS (nm_device_modem_parent_class)->act_stage3_ip6_config_start (device, &ignored, &failure_reason); - g_assert (ignored == NULL); + ret = NM_DEVICE_CLASS (nm_device_modem_parent_class)->act_stage3_ip_config_start (device, AF_INET6, (gpointer *) &ignored, &failure_reason); + + nm_assert (ignored == NULL); + switch (ret) { case NM_ACT_STAGE_RETURN_FAILURE: nm_device_ip_method_failed (device, AF_INET6, failure_reason); break; case NM_ACT_STAGE_RETURN_IP_FAIL: /* all done */ - nm_device_activate_schedule_ip6_config_result (device); + nm_device_activate_schedule_ip_config_result (device, AF_INET6, NULL); break; case NM_ACT_STAGE_RETURN_POSTPONE: /* let SLAAC run */ @@ -279,7 +280,7 @@ modem_ip6_config_result (NMModem *modem, /* Should never get here since we've assured that the IPv6 method * will either be "auto" or "ignored" when starting IPv6 configuration. */ - g_assert_not_reached (); + nm_assert_not_reached (); } } @@ -303,7 +304,7 @@ ip_ifindex_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data) * internally, and leaving it enabled could allow the kernel's IPv6 * RA handling code to run before NM is ready. */ - nm_device_ipv6_sysctl_set (device, "disable_ipv6", "1"); + nm_device_sysctl_ip_conf_set (device, AF_INET6, "disable_ipv6", "1"); } static void @@ -474,7 +475,7 @@ check_connection_available (NMDevice *device, state = nm_modem_get_state (priv->modem); if (state <= NM_MODEM_STATE_INITIALIZING) { nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "modem not initalized"); + "modem not initialized"); return FALSE; } @@ -509,44 +510,35 @@ deactivate (NMDevice *device) /*****************************************************************************/ -static gboolean -deactivate_async_finish (NMDevice *self, - GAsyncResult *res, - GError **error) -{ - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} - static void -modem_deactivate_async_ready (NMModem *modem, - GAsyncResult *res, - GSimpleAsyncResult *simple) +modem_deactivate_async_cb (NMModem *modem, + GError *error, + gpointer user_data) { - GError *error = NULL; + gs_unref_object NMDevice *self = NULL; + NMDeviceDeactivateCallback callback; + gpointer callback_user_data; - if (!nm_modem_deactivate_async_finish (modem, res, &error)) - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - g_object_unref (simple); + nm_utils_user_data_unpack (user_data, &self, &callback, &callback_user_data); + callback (self, error, callback_user_data); } static void deactivate_async (NMDevice *self, GCancellable *cancellable, - GAsyncReadyCallback callback, + NMDeviceDeactivateCallback callback, gpointer user_data) { - GSimpleAsyncResult *simple; + nm_assert (G_IS_CANCELLABLE (cancellable)); + nm_assert (callback); - simple = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - deactivate_async); - nm_modem_deactivate_async (NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) self)->modem, + nm_modem_deactivate_async (NM_DEVICE_MODEM_GET_PRIVATE (self)->modem, self, cancellable, - (GAsyncReadyCallback) modem_deactivate_async_ready, - simple); + modem_deactivate_async_cb, + nm_utils_user_data_pack (g_object_ref (self), + callback, + user_data)); } /*****************************************************************************/ @@ -579,14 +571,25 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) } static NMActStageReturn -act_stage3_ip4_config_start (NMDevice *device, - NMIP4Config **out_config, - NMDeviceStateReason *out_failure_reason) +act_stage3_ip_config_start (NMDevice *device, + int addr_family, + gpointer *out_config, + NMDeviceStateReason *out_failure_reason) { - return nm_modem_stage3_ip4_config_start (NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device)->modem, - device, - NM_DEVICE_CLASS (nm_device_modem_parent_class), - out_failure_reason); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); + + nm_assert_addr_family (addr_family); + + if (addr_family == AF_INET) { + return nm_modem_stage3_ip4_config_start (priv->modem, + device, + NM_DEVICE_CLASS (nm_device_modem_parent_class), + out_failure_reason); + } else { + return nm_modem_stage3_ip6_config_start (priv->modem, + device, + out_failure_reason); + } } static void @@ -595,16 +598,6 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) nm_modem_ip4_pre_commit (NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device)->modem, device, config); } -static NMActStageReturn -act_stage3_ip6_config_start (NMDevice *device, - NMIP6Config **out_config, - NMDeviceStateReason *out_failure_reason) -{ - return nm_modem_stage3_ip6_config_start (NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device)->modem, - device, - out_failure_reason); -} - static gboolean get_ip_iface_identifier (NMDevice *device, NMUtilsIPv6IfaceId *out_iid) { @@ -831,12 +824,10 @@ nm_device_modem_class_init (NMDeviceModemClass *klass) device_class->check_connection_available = check_connection_available; device_class->complete_connection = complete_connection; device_class->deactivate_async = deactivate_async; - device_class->deactivate_async_finish = deactivate_async_finish; device_class->deactivate = deactivate; device_class->act_stage1_prepare = act_stage1_prepare; device_class->act_stage2_config = act_stage2_config; - device_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; - device_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start; + device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; device_class->ip4_config_pre_commit = ip4_config_pre_commit; device_class->get_enabled = get_enabled; device_class->set_enabled = set_enabled; diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index 04cb8599..1cb549b0 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -22,7 +22,6 @@ #include "nm-modem-broadband.h" -#include <string.h> #include <arpa/inet.h> #include <libmm-glib.h> @@ -254,16 +253,21 @@ get_bearer_ip_method (MMBearerIpConfig *config) static MMSimpleConnectProperties * create_cdma_connect_properties (NMConnection *connection) { - NMSettingCdma *setting; MMSimpleConnectProperties *properties; - const char *str; - setting = nm_connection_get_setting_cdma (connection); properties = mm_simple_connect_properties_new (); - str = nm_setting_cdma_get_number (setting); - if (str) - mm_simple_connect_properties_set_number (properties, str); +#if !MM_CHECK_VERSION (1, 9, 1) + { + NMSettingCdma *setting; + const char *str; + + setting = nm_connection_get_setting_cdma (connection); + str = nm_setting_cdma_get_number (setting); + if (str) + mm_simple_connect_properties_set_number (properties, str); + } +#endif return properties; } @@ -279,11 +283,6 @@ create_gsm_connect_properties (NMConnection *connection) setting = nm_connection_get_setting_gsm (connection); properties = mm_simple_connect_properties_new (); - /* TODO: not needed */ - str = nm_setting_gsm_get_number (setting); - if (str) - mm_simple_connect_properties_set_number (properties, str); - /* Blank APN ("") means the default subscription APN */ str = nm_setting_gsm_get_apn (setting); mm_simple_connect_properties_set_apn (properties, str ?: ""); @@ -693,10 +692,6 @@ complete_connection (NMModem *_self, return FALSE; } - /* TODO: This is not needed */ - if (!nm_setting_gsm_get_number (s_gsm)) - g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL); - nm_utils_complete_generic (NM_PLATFORM_GET, connection, NM_SETTING_GSM_SETTING_NAME, @@ -884,7 +879,7 @@ static_stage3_ip4_done (NMModemBroadband *self) /* Fully fail if invalid IP address retrieved */ address_string = mm_bearer_ip_config_get_address (self->_priv.ipv4_config); if ( !address_string - || !nm_utils_parse_inaddr_bin (AF_INET, address_string, &address_network)) { + || !nm_utils_parse_inaddr_bin (AF_INET, address_string, NULL, &address_network)) { error = g_error_new (NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "(%s) retrieving IP4 configuration failed: invalid address given %s%s%s", @@ -896,7 +891,7 @@ static_stage3_ip4_done (NMModemBroadband *self) /* Missing gateway not a hard failure */ gw_string = mm_bearer_ip_config_get_gateway (self->_priv.ipv4_config); if ( gw_string - && !nm_utils_parse_inaddr_bin (AF_INET, gw_string, &gw)) { + && !nm_utils_parse_inaddr_bin (AF_INET, gw_string, NULL, &gw)) { error = g_error_new (NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "(%s) retrieving IP4 configuration failed: invalid gateway address \"%s\"", @@ -937,7 +932,7 @@ static_stage3_ip4_done (NMModemBroadband *self) /* DNS servers */ dns = mm_bearer_ip_config_get_dns (self->_priv.ipv4_config); for (i = 0; dns && dns[i]; i++) { - if ( nm_utils_parse_inaddr_bin (AF_INET, dns[i], &address_network) + if ( nm_utils_parse_inaddr_bin (AF_INET, dns[i], NULL, &address_network) && address_network > 0) { nm_ip4_config_add_nameserver (config, address_network); _LOGI (" DNS %s", dns[i]); @@ -1098,100 +1093,101 @@ stage3_ip6_config_request (NMModem *modem, NMDeviceStateReason *out_failure_reas typedef struct { NMModemBroadband *self; - GSimpleAsyncResult *result; + _NMModemDisconnectCallback callback; + gpointer callback_user_data; GCancellable *cancellable; gboolean warn; } DisconnectContext; static void -disconnect_context_complete (DisconnectContext *ctx) +disconnect_context_complete (DisconnectContext *ctx, GError *error) { - g_simple_async_result_complete_in_idle (ctx->result); - if (ctx->cancellable) - g_object_unref (ctx->cancellable); - g_object_unref (ctx->result); + if (ctx->callback) + ctx->callback (NM_MODEM (ctx->self), error, ctx->callback_user_data); + nm_g_object_unref (ctx->cancellable); g_object_unref (ctx->self); g_slice_free (DisconnectContext, ctx); } -static gboolean -disconnect_finish (NMModem *self, - GAsyncResult *res, - GError **error) +static void +disconnect_context_complete_on_idle (gpointer user_data, + GCancellable *cancellable) { - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); + DisconnectContext *ctx = user_data; + gs_free_error GError *cancelled_error = NULL; + + g_cancellable_set_error_if_cancelled (cancellable, &cancelled_error); + disconnect_context_complete (ctx, cancelled_error); } static void -simple_disconnect_ready (MMModemSimple *modem_iface, +simple_disconnect_ready (GObject *source_object, GAsyncResult *res, - DisconnectContext *ctx) + gpointer user_data) { + MMModemSimple *modem_iface = MM_MODEM_SIMPLE (source_object); + DisconnectContext *ctx = user_data; GError *error = NULL; if (!mm_modem_simple_disconnect_finish (modem_iface, res, &error)) { - if (ctx->warn && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) { + if ( ctx->warn + && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) { NMModemBroadband *self = ctx->self; _LOGW ("failed to disconnect modem: %s", error->message); } - g_simple_async_result_take_error (ctx->result, error); } - disconnect_context_complete (ctx); + disconnect_context_complete (ctx, error); } static void disconnect (NMModem *modem, gboolean warn, GCancellable *cancellable, - GAsyncReadyCallback callback, + _NMModemDisconnectCallback callback, gpointer user_data) { NMModemBroadband *self = NM_MODEM_BROADBAND (modem); DisconnectContext *ctx; - GError *error = NULL; connect_context_clear (self); - ctx = g_slice_new (DisconnectContext); - ctx->cancellable = NULL; + + ctx = g_slice_new0 (DisconnectContext); ctx->self = g_object_ref (self); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - disconnect); + ctx->cancellable = nm_g_object_ref (cancellable); + ctx->callback = callback; + ctx->callback_user_data = user_data; + /* Don't bother warning on FAILED since the modem is already gone */ ctx->warn = warn; - /* Already cancelled? */ - if (g_cancellable_set_error_if_cancelled (cancellable, &error)) { - g_simple_async_result_take_error (ctx->result, error); - disconnect_context_complete (ctx); - return; - } - - /* If no simple iface, we're done */ - if (!ctx->self->_priv.simple_iface) { - disconnect_context_complete (ctx); + /* Already cancelled or no simple-iface? We are done. */ + if ( !ctx->self->_priv.simple_iface + || g_cancellable_is_cancelled (cancellable)) { + nm_utils_invoke_on_idle (disconnect_context_complete_on_idle, + ctx, + cancellable); return; } _LOGD ("notifying ModemManager about the modem disconnection"); - ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - mm_modem_simple_disconnect (ctx->self->_priv.simple_iface, + mm_modem_simple_disconnect (self->_priv.simple_iface, NULL, /* bearer path; if NULL given ALL get disconnected */ cancellable, - (GAsyncReadyCallback) simple_disconnect_ready, + simple_disconnect_ready, ctx); } /*****************************************************************************/ static void -deactivate_cleanup (NMModem *_self, NMDevice *device) +deactivate_cleanup (NMModem *modem, + NMDevice *device, + gboolean stop_ppp_manager) { - NMModemBroadband *self = NM_MODEM_BROADBAND (_self); + NMModemBroadband *self = NM_MODEM_BROADBAND (modem); /* TODO: cancel SimpleConnect() if any */ @@ -1202,8 +1198,9 @@ deactivate_cleanup (NMModem *_self, NMDevice *device) self->_priv.pin_tries = 0; - /* Chain up parent's */ - NM_MODEM_CLASS (nm_modem_broadband_parent_class)->deactivate_cleanup (_self, device); + NM_MODEM_CLASS (nm_modem_broadband_parent_class)->deactivate_cleanup (modem, + device, + stop_ppp_manager); } /*****************************************************************************/ @@ -1468,7 +1465,6 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass) modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; modem_class->stage3_ip6_config_request = stage3_ip6_config_request; modem_class->disconnect = disconnect; - modem_class->disconnect_finish = disconnect_finish; modem_class->deactivate_cleanup = deactivate_cleanup; modem_class->set_mm_enabled = set_mm_enabled; modem_class->get_user_pass = get_user_pass; diff --git a/src/devices/wwan/nm-modem-manager.c b/src/devices/wwan/nm-modem-manager.c index dfc102f3..fac14d69 100644 --- a/src/devices/wwan/nm-modem-manager.c +++ b/src/devices/wwan/nm-modem-manager.c @@ -24,7 +24,6 @@ #include "nm-modem-manager.h" -#include <string.h> #include <libmm-glib.h> #if HAVE_LIBSYSTEMD diff --git a/src/devices/wwan/nm-modem-ofono.c b/src/devices/wwan/nm-modem-ofono.c index ea668590..78d9a9f0 100644 --- a/src/devices/wwan/nm-modem-ofono.c +++ b/src/devices/wwan/nm-modem-ofono.c @@ -22,8 +22,6 @@ #include "nm-modem-ofono.h" -#include <string.h> - #include "nm-core-internal.h" #include "devices/nm-device-private.h" #include "nm-modem.h" @@ -146,30 +144,36 @@ update_modem_state (NMModemOfono *self) /* Disconnect */ typedef struct { NMModemOfono *self; - GSimpleAsyncResult *result; + _NMModemDisconnectCallback callback; + gpointer callback_user_data; GCancellable *cancellable; gboolean warn; } DisconnectContext; static void -disconnect_context_complete (DisconnectContext *ctx) +disconnect_context_complete (DisconnectContext *ctx, GError *error) { - if (ctx->cancellable) - g_object_unref (ctx->cancellable); - if (ctx->result) { - g_simple_async_result_complete_in_idle (ctx->result); - g_object_unref (ctx->result); - } + if (ctx->callback) + ctx->callback (NM_MODEM (ctx->self), error, ctx->callback_user_data); + nm_g_object_unref (ctx->cancellable); g_object_unref (ctx->self); g_slice_free (DisconnectContext, ctx); } -static gboolean -disconnect_finish (NMModem *self, - GAsyncResult *result, - GError **error) +static void +disconnect_context_complete_on_idle (gpointer user_data, + GCancellable *cancellable) { - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error); + DisconnectContext *ctx = user_data; + gs_free_error GError *error = NULL; + + if (!g_cancellable_set_error_if_cancelled (cancellable, &error)) { + g_set_error_literal (&error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + ("modem is currently not connected")); + } + disconnect_context_complete (ctx, error); } static void @@ -177,16 +181,14 @@ disconnect_done (GObject *source, GAsyncResult *result, gpointer user_data) { - DisconnectContext *ctx = (DisconnectContext*) user_data; + DisconnectContext *ctx = user_data; NMModemOfono *self = ctx->self; gs_free_error GError *error = NULL; gs_unref_variant GVariant *v = NULL; v = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - if (ctx->result) - g_simple_async_result_take_error (ctx->result, g_steal_pointer (&error)); - disconnect_context_complete (ctx); + disconnect_context_complete (ctx, error); return; } @@ -196,21 +198,20 @@ disconnect_done (GObject *source, _LOGD ("modem disconnected"); update_modem_state (self); - disconnect_context_complete (ctx); + disconnect_context_complete (ctx, error); } static void disconnect (NMModem *modem, gboolean warn, GCancellable *cancellable, - GAsyncReadyCallback callback, + _NMModemDisconnectCallback callback, gpointer user_data) { NMModemOfono *self = NM_MODEM_OFONO (modem); NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); DisconnectContext *ctx; NMModemState state = nm_modem_get_state (NM_MODEM (self)); - GError *error = NULL; _LOGD ("warn: %s modem_state: %s", warn ? "TRUE" : "FALSE", @@ -218,37 +219,19 @@ disconnect (NMModem *modem, ctx = g_slice_new0 (DisconnectContext); ctx->self = g_object_ref (self); + ctx->cancellable = nm_g_object_ref (cancellable); ctx->warn = warn; - if (callback) { - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - disconnect); - } - - if (state != NM_MODEM_STATE_CONNECTED) { - if (ctx->result) { - g_set_error_literal (&error, - NM_UTILS_ERROR, - NM_UTILS_ERROR_UNKNOWN, - ("modem is currently not connected")); - g_simple_async_result_take_error (ctx->result, error); - } - disconnect_context_complete (ctx); + ctx->callback = callback; + ctx->callback_user_data = user_data; + + if ( state != NM_MODEM_STATE_CONNECTED + || g_cancellable_is_cancelled (cancellable)) { + nm_utils_invoke_on_idle (disconnect_context_complete_on_idle, + ctx, + cancellable); return; } - if (g_cancellable_set_error_if_cancelled (cancellable, &error)) { - if (ctx->result) - g_simple_async_result_take_error (ctx->result, error); - else - g_clear_error (&error); - disconnect_context_complete (ctx); - return; - } - - ctx->cancellable = nm_g_object_ref (cancellable); - nm_modem_set_state (NM_MODEM (self), NM_MODEM_STATE_DISCONNECTING, nm_modem_state_to_string (NM_MODEM_STATE_DISCONNECTING)); @@ -266,7 +249,9 @@ disconnect (NMModem *modem, } static void -deactivate_cleanup (NMModem *modem, NMDevice *device) +deactivate_cleanup (NMModem *modem, + NMDevice *device, + gboolean stop_ppp_manager) { NMModemOfono *self = NM_MODEM_OFONO (modem); NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); @@ -275,7 +260,9 @@ deactivate_cleanup (NMModem *modem, NMDevice *device) g_clear_object (&priv->ip4_config); - NM_MODEM_CLASS (nm_modem_ofono_parent_class)->deactivate_cleanup (modem, device); + NM_MODEM_CLASS (nm_modem_ofono_parent_class)->deactivate_cleanup (modem, + device, + stop_ppp_manager); } static gboolean @@ -664,7 +651,7 @@ handle_connman_iface (NMModemOfono *self, gboolean found) OFONO_DBUS_INTERFACE_CONNECTION_MANAGER, priv->connman_proxy_cancellable, _connman_proxy_new_cb, - NULL); + self); } } @@ -883,7 +870,7 @@ context_property_changed (GDBusProxy *proxy, goto out; } if ( !s - || !nm_utils_parse_inaddr_bin (AF_INET, s, &address_network)) { + || !nm_utils_parse_inaddr_bin (AF_INET, s, NULL, &address_network)) { _LOGW ("can't convert 'Address' %s to addr", s ?: ""); goto out; } @@ -897,7 +884,7 @@ context_property_changed (GDBusProxy *proxy, goto out; } if ( !s - || !nm_utils_parse_inaddr_bin (AF_INET, s, &address_network)) { + || !nm_utils_parse_inaddr_bin (AF_INET, s, NULL, &address_network)) { _LOGW ("invalid 'Netmask': %s", s ?: ""); goto out; } @@ -911,7 +898,7 @@ context_property_changed (GDBusProxy *proxy, _LOGW ("Settings 'Gateway' missing"); goto out; } - if (!nm_utils_parse_inaddr_bin (AF_INET, s, &gateway_network)) { + if (!nm_utils_parse_inaddr_bin (AF_INET, s, NULL, &gateway_network)) { _LOGW ("invalid 'Gateway': %s", s); goto out; } @@ -938,7 +925,7 @@ context_property_changed (GDBusProxy *proxy, } if (array) { for (iter = array; *iter; iter++) { - if ( nm_utils_parse_inaddr_bin (AF_INET, *iter, &address_network) + if ( nm_utils_parse_inaddr_bin (AF_INET, *iter, NULL, &address_network) && address_network) { _LOGI ("DNS: %s", *iter); nm_ip4_config_add_nameserver (priv->ip4_config, address_network); @@ -958,7 +945,7 @@ context_property_changed (GDBusProxy *proxy, if (g_variant_lookup (v_dict, "MessageProxy", "&s", &s)) { _LOGI ("MessageProxy: %s", s); if ( s - && nm_utils_parse_inaddr_bin (AF_INET, s, &address_network)) { + && nm_utils_parse_inaddr_bin (AF_INET, s, NULL, &address_network)) { nm_modem_get_route_parameters (NM_MODEM (self), &ip4_route_table, &ip4_route_metric, @@ -1319,7 +1306,6 @@ nm_modem_ofono_class_init (NMModemOfonoClass *klass) modem_class->get_capabilities = get_capabilities; modem_class->disconnect = disconnect; - modem_class->disconnect_finish = disconnect_finish; modem_class->deactivate_cleanup = deactivate_cleanup; modem_class->check_connection_compatible_with_modem = check_connection_compatible_with_modem; diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index 59b081e9..2217f2a2 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -24,7 +24,6 @@ #include "nm-modem.h" #include <fcntl.h> -#include <string.h> #include <termios.h> #include <linux/rtnetlink.h> @@ -706,13 +705,13 @@ nm_modem_stage3_ip4_config_start (NMModem *self, nm_modem_set_route_parameters_from_device (self, device); - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + method = nm_utils_get_ip_config_method (connection, AF_INET); /* Only Disabled and Auto methods make sense for WWAN */ - if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) + if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) return NM_ACT_STAGE_RETURN_SUCCESS; - if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) != 0) { + if (!nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { _LOGE ("unhandled WWAN IPv4 method '%s'; will fail", method); NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED); return NM_ACT_STAGE_RETURN_FAILURE; @@ -729,7 +728,7 @@ nm_modem_stage3_ip4_config_start (NMModem *self, break; case NM_MODEM_IP_METHOD_AUTO: _LOGD ("MODEM_IP_METHOD_AUTO"); - ret = device_class->act_stage3_ip4_config_start (device, NULL, out_failure_reason); + ret = device_class->act_stage3_ip_config_start (device, AF_INET, NULL, out_failure_reason); break; default: _LOGI ("IPv4 configuration disabled"); @@ -823,13 +822,13 @@ nm_modem_stage3_ip6_config_start (NMModem *self, nm_modem_set_route_parameters_from_device (self, device); - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + method = nm_utils_get_ip_config_method (connection, AF_INET6); /* Only Ignore and Auto methods make sense for WWAN */ - if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) + if (nm_streq (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) return NM_ACT_STAGE_RETURN_IP_DONE; - if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) != 0) { + if (!nm_streq (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { _LOGW ("unhandled WWAN IPv6 method '%s'; will fail", method); NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); @@ -948,7 +947,7 @@ nm_modem_get_secrets (NMModem *self, FALSE, setting_name, flags, - hint, + NM_MAKE_STRV (hint), modem_secrets_cb, self); g_return_if_fail (priv->secrets_id); @@ -986,8 +985,7 @@ nm_modem_act_stage1_prepare (NMModem *self, setting_name = nm_connection_need_secrets (connection, &hints); if (!setting_name) { - /* Ready to connect */ - g_assert (!hints); + nm_assert (!hints); return NM_MODEM_GET_CLASS (self)->act_stage1_prepare (self, connection, out_failure_reason); } @@ -995,11 +993,14 @@ nm_modem_act_stage1_prepare (NMModem *self, if (priv->secrets_tries++) flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + if (hints) + g_ptr_array_add (hints, NULL); + priv->secrets_id = nm_act_request_get_secrets (req, FALSE, setting_name, flags, - hints ? g_ptr_array_index (hints, 0) : NULL, + hints ? (const char *const*) hints->pdata : NULL, modem_secrets_cb, self); g_return_val_if_fail (priv->secrets_id, NM_ACT_STAGE_RETURN_FAILURE); @@ -1105,7 +1106,9 @@ nm_modem_complete_connection (NMModem *self, /*****************************************************************************/ static void -deactivate_cleanup (NMModem *self, NMDevice *device) +deactivate_cleanup (NMModem *self, + NMDevice *device, + gboolean stop_ppp_manager) { NMModemPrivate *priv; int ifindex; @@ -1126,7 +1129,8 @@ deactivate_cleanup (NMModem *self, NMDevice *device) if (priv->ppp_manager) { g_signal_handlers_disconnect_by_data (priv->ppp_manager, self); - nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL); + if (stop_ppp_manager) + nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL, NULL); g_clear_object (&priv->ppp_manager); } @@ -1157,189 +1161,109 @@ deactivate_cleanup (NMModem *self, NMDevice *device) /*****************************************************************************/ -typedef enum { - DEACTIVATE_CONTEXT_STEP_FIRST, - DEACTIVATE_CONTEXT_STEP_CLEANUP, - DEACTIVATE_CONTEXT_STEP_PPP_MANAGER_STOP, - DEACTIVATE_CONTEXT_STEP_MM_DISCONNECT, - DEACTIVATE_CONTEXT_STEP_LAST -} DeactivateContextStep; - typedef struct { NMModem *self; NMDevice *device; GCancellable *cancellable; - GSimpleAsyncResult *result; - DeactivateContextStep step; - NMPPPManager *ppp_manager; - NMPPPManagerStopHandle *ppp_stop_handle; - gulong ppp_stop_cancellable_id; + NMModemDeactivateCallback callback; + gpointer callback_user_data; } DeactivateContext; static void -deactivate_context_complete (DeactivateContext *ctx) +deactivate_context_complete (DeactivateContext *ctx, GError *error) { - if (ctx->ppp_stop_handle) - nm_ppp_manager_stop_cancel (ctx->ppp_stop_handle); + NMModem *self = ctx->self; - nm_assert (!ctx->ppp_stop_handle); - nm_assert (ctx->ppp_stop_cancellable_id == 0); + _LOGD ("modem deactivation finished %s%s%s", + NM_PRINT_FMT_QUOTED (error, "with failure: ", error->message, "", "successfully")); - if (ctx->ppp_manager) - g_object_unref (ctx->ppp_manager); - if (ctx->cancellable) - g_object_unref (ctx->cancellable); - g_simple_async_result_complete_in_idle (ctx->result); - g_object_unref (ctx->result); + if (ctx->callback) + ctx->callback (ctx->self, error, ctx->callback_user_data); + nm_g_object_unref (ctx->cancellable); g_object_unref (ctx->device); g_object_unref (ctx->self); g_slice_free (DeactivateContext, ctx); } -gboolean -nm_modem_deactivate_async_finish (NMModem *self, - GAsyncResult *res, - GError **error) -{ - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} - -static void deactivate_step (DeactivateContext *ctx); - static void -disconnect_ready (NMModem *self, - GAsyncResult *res, - DeactivateContext *ctx) +_deactivate_call_disconnect_cb (NMModem *self, + GError *error, + gpointer user_data) { - GError *error = NULL; - - if (!NM_MODEM_GET_CLASS (self)->disconnect_finish (self, res, &error)) { - g_simple_async_result_take_error (ctx->result, error); - deactivate_context_complete (ctx); - return; - } - - /* Go on */ - ctx->step++; - deactivate_step (ctx); + deactivate_context_complete (user_data, error); } static void -ppp_manager_stop_ready (NMPPPManager *ppp_manager, - NMPPPManagerStopHandle *handle, - gboolean was_cancelled, - gpointer user_data) +_deactivate_call_disconnect (DeactivateContext *ctx) { - DeactivateContext *ctx = user_data; - - nm_assert (ctx->ppp_stop_handle == handle); - ctx->ppp_stop_handle = NULL; - - if (ctx->ppp_stop_cancellable_id) { - g_cancellable_disconnect (ctx->cancellable, - nm_steal_int (&ctx->ppp_stop_cancellable_id)); - } - - if (was_cancelled) - return; - - ctx->step++; - deactivate_step (ctx); + NM_MODEM_GET_CLASS (ctx->self)->disconnect (ctx->self, + FALSE, + ctx->cancellable, + _deactivate_call_disconnect_cb, + ctx); } static void -ppp_manager_stop_cancelled (GCancellable *cancellable, - gpointer user_data) +_deactivate_ppp_manager_stop_cb (NMPPPManager *ppp_manager, + NMPPPManagerStopHandle *handle, + gboolean was_cancelled, + gpointer user_data) { DeactivateContext *ctx = user_data; - nm_ppp_manager_stop_cancel (ctx->ppp_stop_handle); -} + g_object_unref (ppp_manager); -static void -deactivate_step (DeactivateContext *ctx) -{ - NMModem *self = ctx->self; - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - GError *error = NULL; - - /* Check cancellable in each step */ - if (g_cancellable_set_error_if_cancelled (ctx->cancellable, &error)) { - g_simple_async_result_take_error (ctx->result, error); - deactivate_context_complete (ctx); - return; - } - - switch (ctx->step) { - case DEACTIVATE_CONTEXT_STEP_FIRST: - ctx->step++; - /* fall through */ - case DEACTIVATE_CONTEXT_STEP_CLEANUP: - /* Make sure we keep a ref to the PPP manager if there is one */ - if (priv->ppp_manager) - ctx->ppp_manager = g_object_ref (priv->ppp_manager); - /* Run cleanup */ - NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, ctx->device); - ctx->step++; - /* fall through */ - case DEACTIVATE_CONTEXT_STEP_PPP_MANAGER_STOP: - /* If we have a PPP manager, stop it */ - if (ctx->ppp_manager) { - nm_assert (!ctx->ppp_stop_handle); - if (ctx->cancellable) { - ctx->ppp_stop_cancellable_id = g_cancellable_connect (ctx->cancellable, - G_CALLBACK (ppp_manager_stop_cancelled), - ctx, - NULL); - } - ctx->ppp_stop_handle = nm_ppp_manager_stop (ctx->ppp_manager, - ppp_manager_stop_ready, - ctx); - return; - } - ctx->step++; - /* fall through */ - case DEACTIVATE_CONTEXT_STEP_MM_DISCONNECT: - /* Disconnect asynchronously */ - NM_MODEM_GET_CLASS (self)->disconnect (self, - FALSE, - ctx->cancellable, - (GAsyncReadyCallback) disconnect_ready, - ctx); - return; + if (was_cancelled) { + gs_free_error GError *error = NULL; - case DEACTIVATE_CONTEXT_STEP_LAST: - _LOGD ("modem deactivation finished"); - deactivate_context_complete (ctx); + if (!g_cancellable_set_error_if_cancelled (ctx->cancellable, &error)) + nm_assert_not_reached (); + deactivate_context_complete (ctx, error); return; } - g_assert_not_reached (); + nm_assert (!g_cancellable_is_cancelled (ctx->cancellable)); + _deactivate_call_disconnect (ctx); } void nm_modem_deactivate_async (NMModem *self, NMDevice *device, GCancellable *cancellable, - GAsyncReadyCallback callback, + NMModemDeactivateCallback callback, gpointer user_data) { + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); DeactivateContext *ctx; + NMPPPManager *ppp_manager; + + g_return_if_fail (NM_IS_MODEM (self)); + g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (G_IS_CANCELLABLE (cancellable)); - ctx = g_slice_new0 (DeactivateContext); + ctx = g_slice_new (DeactivateContext); ctx->self = g_object_ref (self); ctx->device = g_object_ref (device); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - nm_modem_deactivate_async); - /* FIXME(shutdown): we always require a cancellable, otherwise we cannot - * do a coordinated shutdown. */ - ctx->cancellable = nm_g_object_ref (cancellable); + ctx->cancellable = g_object_ref (cancellable); + ctx->callback = callback; + ctx->callback_user_data = user_data; + + ppp_manager = nm_g_object_ref (priv->ppp_manager); + + NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, ctx->device, FALSE); + + if (ppp_manager) { + /* If we have a PPP manager, stop it. + * + * Pass on the reference in @ppp_manager. */ + nm_ppp_manager_stop (ppp_manager, + ctx->cancellable, + _deactivate_ppp_manager_stop_cb, + ctx); + return; + } - /* Start */ - ctx->step = DEACTIVATE_CONTEXT_STEP_FIRST; - deactivate_step (ctx); + _deactivate_call_disconnect (ctx); } /*****************************************************************************/ @@ -1348,7 +1272,7 @@ void nm_modem_deactivate (NMModem *self, NMDevice *device) { /* First cleanup */ - NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, device); + NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, device, TRUE); /* Then disconnect without waiting */ NM_MODEM_GET_CLASS (self)->disconnect (self, FALSE, NULL, NULL, NULL); } @@ -1387,7 +1311,7 @@ nm_modem_device_state_changed (NMModem *self, if (new_state == NM_DEVICE_STATE_FAILED || new_state == NM_DEVICE_STATE_DISCONNECTED) warn = FALSE; /* First cleanup */ - NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, NULL); + NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, NULL, TRUE); NM_MODEM_GET_CLASS (self)->disconnect (self, warn, NULL, NULL, NULL); } break; diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h index c73745ce..f7b6bfe9 100644 --- a/src/devices/wwan/nm-modem.h +++ b/src/devices/wwan/nm-modem.h @@ -109,6 +109,10 @@ struct _NMModem { typedef struct _NMModem NMModem; +typedef void (*_NMModemDisconnectCallback) (NMModem *modem, + GError *error, + gpointer user_data); + typedef struct { GObjectClass parent; @@ -149,13 +153,12 @@ typedef struct { void (*disconnect) (NMModem *self, gboolean warn, GCancellable *cancellable, - GAsyncReadyCallback callback, + _NMModemDisconnectCallback callback, gpointer user_data); - gboolean (*disconnect_finish) (NMModem *self, - GAsyncResult *res, - GError **error); - void (*deactivate_cleanup) (NMModem *self, NMDevice *device); + void (*deactivate_cleanup) (NMModem *self, + NMDevice *device, + gboolean stop_ppp_manager); gboolean (*owns_port) (NMModem *self, const char *iface); } NMModemClass; @@ -236,14 +239,15 @@ void nm_modem_get_secrets (NMModem *modem, void nm_modem_deactivate (NMModem *modem, NMDevice *device); +typedef void (*NMModemDeactivateCallback) (NMModem *self, + GError *error, + gpointer user_data); + void nm_modem_deactivate_async (NMModem *self, NMDevice *device, GCancellable *cancellable, - GAsyncReadyCallback callback, + NMModemDeactivateCallback callback, gpointer user_data); -gboolean nm_modem_deactivate_async_finish (NMModem *self, - GAsyncResult *res, - GError **error); void nm_modem_device_state_changed (NMModem *modem, NMDeviceState new_state, diff --git a/src/devices/wwan/nm-wwan-factory.c b/src/devices/wwan/nm-wwan-factory.c index a561b58a..c9ee27ff 100644 --- a/src/devices/wwan/nm-wwan-factory.c +++ b/src/devices/wwan/nm-wwan-factory.c @@ -20,7 +20,6 @@ #include "nm-default.h" -#include <string.h> #include <gmodule.h> #include "devices/nm-device-factory.h" |