mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-30 21:20:10 +01:00
merge: various WWAN fixes
This commit is contained in:
commit
255cc3f707
7 changed files with 163 additions and 118 deletions
|
|
@ -423,7 +423,15 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
|
|||
static void
|
||||
modem_auth_requested (NMModem *modem, gpointer user_data)
|
||||
{
|
||||
nm_device_state_changed (NM_DEVICE (user_data),
|
||||
NMDevice *device = NM_DEVICE (user_data);
|
||||
|
||||
/* Auth requests (PIN, PAP/CHAP passwords, etc) only get handled
|
||||
* during activation.
|
||||
*/
|
||||
if (!nm_device_is_activating (device))
|
||||
return;
|
||||
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_NEED_AUTH,
|
||||
NM_DEVICE_STATE_REASON_NONE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,7 +113,15 @@ modem_prepare_result (NMModem *modem,
|
|||
static void
|
||||
modem_auth_requested (NMModem *modem, gpointer user_data)
|
||||
{
|
||||
nm_device_state_changed (NM_DEVICE (user_data),
|
||||
NMDevice *device = NM_DEVICE (user_data);
|
||||
|
||||
/* Auth requests (PIN, PAP/CHAP passwords, etc) only get handled
|
||||
* during activation.
|
||||
*/
|
||||
if (!nm_device_is_activating (device))
|
||||
return;
|
||||
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_NEED_AUTH,
|
||||
NM_DEVICE_STATE_REASON_NONE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,6 +124,20 @@ get_capabilities (NMModem *_self,
|
|||
*current_caps = (NMDeviceModemCapabilities) mm_modem_get_current_capabilities (self->priv->modem_iface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
owns_port (NMModem *_self, const char *iface)
|
||||
{
|
||||
NMModemBroadband *self = NM_MODEM_BROADBAND (_self);
|
||||
const MMModemPortInfo *ports = NULL;
|
||||
guint n_ports = 0, i;
|
||||
gboolean owns = FALSE;
|
||||
|
||||
mm_modem_peek_ports (self->priv->modem_iface, &ports, &n_ports);
|
||||
for (i = 0; i < n_ports && !owns; i++)
|
||||
owns = (g_strcmp0 (iface, ports[i].name) == 0);
|
||||
return owns;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -296,48 +310,35 @@ create_gsm_connect_properties (NMConnection *connection)
|
|||
|
||||
static NMActStageReturn
|
||||
act_stage1_prepare (NMModem *_self,
|
||||
NMActRequest *req,
|
||||
GPtrArray **out_hints,
|
||||
const char **out_setting_name,
|
||||
NMConnection *connection,
|
||||
NMDeviceStateReason *reason)
|
||||
{
|
||||
NMModemBroadband *self = NM_MODEM_BROADBAND (_self);
|
||||
NMConnection *connection;
|
||||
MMModemCapability caps;
|
||||
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
g_clear_object (&self->priv->connect_properties);
|
||||
|
||||
*out_setting_name = nm_connection_need_secrets (connection, out_hints);
|
||||
if (!*out_setting_name) {
|
||||
MMModemCapability caps;
|
||||
|
||||
caps = mm_modem_get_current_capabilities (self->priv->modem_iface);
|
||||
|
||||
g_clear_object (&self->priv->connect_properties);
|
||||
|
||||
if (MODEM_CAPS_3GPP (caps))
|
||||
self->priv->connect_properties = create_gsm_connect_properties (connection);
|
||||
else if (MODEM_CAPS_3GPP2 (caps))
|
||||
self->priv->connect_properties = create_cdma_connect_properties (connection);
|
||||
else {
|
||||
nm_log_warn (LOGD_MB, "(%s) not a mobile broadband modem",
|
||||
nm_modem_get_uid (NM_MODEM (self)));
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
if (!self->priv->simple_iface)
|
||||
self->priv->simple_iface = mm_object_get_modem_simple (self->priv->modem_object);
|
||||
|
||||
g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (self->priv->simple_iface), MODEM_CONNECT_TIMEOUT_SECS * 1000);
|
||||
mm_modem_simple_connect (self->priv->simple_iface,
|
||||
self->priv->connect_properties,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)connect_ready,
|
||||
g_object_ref (self));
|
||||
} else {
|
||||
/* NMModem will handle requesting secrets... */
|
||||
caps = mm_modem_get_current_capabilities (self->priv->modem_iface);
|
||||
if (MODEM_CAPS_3GPP (caps))
|
||||
self->priv->connect_properties = create_gsm_connect_properties (connection);
|
||||
else if (MODEM_CAPS_3GPP2 (caps))
|
||||
self->priv->connect_properties = create_cdma_connect_properties (connection);
|
||||
else {
|
||||
nm_log_warn (LOGD_MB, "(%s) not a mobile broadband modem",
|
||||
nm_modem_get_uid (NM_MODEM (self)));
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
if (!self->priv->simple_iface)
|
||||
self->priv->simple_iface = mm_object_get_modem_simple (self->priv->modem_object);
|
||||
|
||||
g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (self->priv->simple_iface), MODEM_CONNECT_TIMEOUT_SECS * 1000);
|
||||
mm_modem_simple_connect (self->priv->simple_iface,
|
||||
self->priv->connect_properties,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)connect_ready,
|
||||
g_object_ref (self));
|
||||
|
||||
return NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
}
|
||||
|
||||
|
|
@ -614,14 +615,16 @@ static gboolean
|
|||
ip_string_to_network_address (const gchar *str,
|
||||
guint32 *out)
|
||||
{
|
||||
guint32 addr;
|
||||
guint32 addr = 0;
|
||||
gboolean success = FALSE;
|
||||
|
||||
/* IP address */
|
||||
if (inet_pton (AF_INET, str, &addr) <= 0)
|
||||
return FALSE;
|
||||
if (!str || inet_pton (AF_INET, str, &addr) != 1)
|
||||
addr = 0;
|
||||
else
|
||||
success = TRUE;
|
||||
|
||||
*out = (guint32)addr;
|
||||
return TRUE;
|
||||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -630,7 +633,9 @@ static_stage3_done (NMModemBroadband *self)
|
|||
GError *error = NULL;
|
||||
NMIP4Config *config = NULL;
|
||||
const gchar *address_string;
|
||||
const gchar *gw_string;
|
||||
guint32 address_network;
|
||||
guint32 gw;
|
||||
NMPlatformIP4Address address;
|
||||
const gchar **dns;
|
||||
guint i;
|
||||
|
|
@ -651,6 +656,10 @@ static_stage3_done (NMModemBroadband *self)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* Missing gateway not a hard failure */
|
||||
gw_string = mm_bearer_ip_config_get_gateway (self->priv->ipv4_config);
|
||||
ip_string_to_network_address (gw_string, &gw);
|
||||
|
||||
config = nm_ip4_config_new ();
|
||||
|
||||
memset (&address, 0, sizeof (address));
|
||||
|
|
@ -659,9 +668,12 @@ static_stage3_done (NMModemBroadband *self)
|
|||
address.source = NM_PLATFORM_SOURCE_WWAN;
|
||||
nm_ip4_config_add_address (config, &address);
|
||||
|
||||
nm_log_info (LOGD_MB, " address %s/%d",
|
||||
mm_bearer_ip_config_get_address (self->priv->ipv4_config),
|
||||
mm_bearer_ip_config_get_prefix (self->priv->ipv4_config));
|
||||
nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen);
|
||||
|
||||
if (gw) {
|
||||
nm_ip4_config_set_gateway (config, gw);
|
||||
nm_log_info (LOGD_MB, " gateway %s", gw_string);
|
||||
}
|
||||
|
||||
/* DNS servers */
|
||||
dns = mm_bearer_ip_config_get_dns (self->priv->ipv4_config);
|
||||
|
|
@ -929,6 +941,7 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass)
|
|||
modem_class->check_connection_compatible = check_connection_compatible;
|
||||
modem_class->complete_connection = complete_connection;
|
||||
modem_class->act_stage1_prepare = act_stage1_prepare;
|
||||
modem_class->owns_port = owns_port;
|
||||
|
||||
/* Properties */
|
||||
g_object_class_install_property
|
||||
|
|
|
|||
|
|
@ -538,33 +538,21 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
|||
|
||||
static NMActStageReturn
|
||||
act_stage1_prepare (NMModem *modem,
|
||||
NMActRequest *req,
|
||||
GPtrArray **out_hints,
|
||||
const char **out_setting_name,
|
||||
NMConnection *connection,
|
||||
NMDeviceStateReason *reason)
|
||||
{
|
||||
NMModemOld *self = NM_MODEM_OLD (modem);
|
||||
NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self);
|
||||
NMConnection *connection;
|
||||
gboolean enabled = nm_modem_get_mm_enabled (modem);
|
||||
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
if (priv->connect_properties)
|
||||
g_hash_table_destroy (priv->connect_properties);
|
||||
priv->connect_properties = create_connect_properties (connection);
|
||||
|
||||
*out_setting_name = nm_connection_need_secrets (connection, out_hints);
|
||||
if (!*out_setting_name) {
|
||||
gboolean enabled = nm_modem_get_mm_enabled (modem);
|
||||
|
||||
if (priv->connect_properties)
|
||||
g_hash_table_destroy (priv->connect_properties);
|
||||
priv->connect_properties = create_connect_properties (connection);
|
||||
|
||||
if (enabled)
|
||||
do_connect (self);
|
||||
else
|
||||
do_enable (self);
|
||||
} else {
|
||||
/* NMModem will handle requesting secrets... */
|
||||
}
|
||||
if (enabled)
|
||||
do_connect (self);
|
||||
else
|
||||
do_enable (self);
|
||||
|
||||
return NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -416,9 +416,7 @@ nm_modem_get_secrets (NMModem *self,
|
|||
|
||||
static NMActStageReturn
|
||||
act_stage1_prepare (NMModem *modem,
|
||||
NMActRequest *req,
|
||||
GPtrArray **out_hints,
|
||||
const char **out_setting_name,
|
||||
NMConnection *connection,
|
||||
NMDeviceStateReason *reason)
|
||||
{
|
||||
*reason = NM_DEVICE_STATE_REASON_UNKNOWN;
|
||||
|
|
@ -435,37 +433,43 @@ nm_modem_act_stage1_prepare (NMModem *self,
|
|||
GPtrArray *hints = NULL;
|
||||
const char *setting_name = NULL;
|
||||
NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION;
|
||||
NMConnection *connection;
|
||||
|
||||
if (priv->act_request)
|
||||
g_object_unref (priv->act_request);
|
||||
priv->act_request = g_object_ref (req);
|
||||
|
||||
ret = NM_MODEM_GET_CLASS (self)->act_stage1_prepare (self,
|
||||
req,
|
||||
&hints,
|
||||
&setting_name,
|
||||
reason);
|
||||
if ((ret == NM_ACT_STAGE_RETURN_POSTPONE) && setting_name) {
|
||||
if (priv->secrets_tries++)
|
||||
flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
|
||||
priv->secrets_id = nm_act_request_get_secrets (req,
|
||||
setting_name,
|
||||
flags,
|
||||
hints ? g_ptr_array_index (hints, 0) : NULL,
|
||||
modem_secrets_cb,
|
||||
self);
|
||||
if (priv->secrets_id)
|
||||
g_signal_emit (self, signals[AUTH_REQUESTED], 0);
|
||||
else {
|
||||
*reason = NM_DEVICE_STATE_REASON_NO_SECRETS;
|
||||
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
if (hints)
|
||||
g_ptr_array_free (hints, TRUE);
|
||||
setting_name = nm_connection_need_secrets (connection, &hints);
|
||||
if (!setting_name) {
|
||||
/* Ready to connect */
|
||||
g_assert (!hints);
|
||||
return NM_MODEM_GET_CLASS (self)->act_stage1_prepare (self, connection, reason);
|
||||
}
|
||||
|
||||
/* Secrets required... */
|
||||
if (priv->secrets_tries++)
|
||||
flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
|
||||
priv->secrets_id = nm_act_request_get_secrets (req,
|
||||
setting_name,
|
||||
flags,
|
||||
hints ? g_ptr_array_index (hints, 0) : NULL,
|
||||
modem_secrets_cb,
|
||||
self);
|
||||
if (priv->secrets_id) {
|
||||
g_signal_emit (self, signals[AUTH_REQUESTED], 0);
|
||||
ret = NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
} else {
|
||||
*reason = NM_DEVICE_STATE_REASON_NO_SECRETS;
|
||||
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
if (hints)
|
||||
g_ptr_array_free (hints, TRUE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -581,27 +585,21 @@ nm_modem_device_state_changed (NMModem *self,
|
|||
|
||||
g_return_if_fail (NM_IS_MODEM (self));
|
||||
|
||||
if (old_state >= NM_DEVICE_STATE_PREPARE && old_state <= NM_DEVICE_STATE_ACTIVATED)
|
||||
if (old_state >= NM_DEVICE_STATE_PREPARE && old_state <= NM_DEVICE_STATE_DEACTIVATING)
|
||||
was_connected = TRUE;
|
||||
|
||||
priv = NM_MODEM_GET_PRIVATE (self);
|
||||
|
||||
/* Make sure we don't leave the serial device open */
|
||||
switch (new_state) {
|
||||
case NM_DEVICE_STATE_NEED_AUTH:
|
||||
if (priv->ppp_manager)
|
||||
break;
|
||||
/* else fall through */
|
||||
case NM_DEVICE_STATE_UNMANAGED:
|
||||
case NM_DEVICE_STATE_UNAVAILABLE:
|
||||
case NM_DEVICE_STATE_FAILED:
|
||||
case NM_DEVICE_STATE_DISCONNECTED:
|
||||
if (new_state != NM_DEVICE_STATE_NEED_AUTH) {
|
||||
if (priv->act_request) {
|
||||
cancel_get_secrets (self);
|
||||
g_object_unref (priv->act_request);
|
||||
priv->act_request = NULL;
|
||||
}
|
||||
case NM_DEVICE_STATE_FAILED:
|
||||
if (priv->act_request) {
|
||||
cancel_get_secrets (self);
|
||||
g_object_unref (priv->act_request);
|
||||
priv->act_request = NULL;
|
||||
}
|
||||
|
||||
if (was_connected) {
|
||||
|
|
@ -663,6 +661,27 @@ nm_modem_get_data_port (NMModem *self)
|
|||
NM_MODEM_GET_PRIVATE (self)->ppp_iface : NM_MODEM_GET_PRIVATE (self)->data_port;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_modem_owns_port (NMModem *self, const char *iface)
|
||||
{
|
||||
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
|
||||
|
||||
g_return_val_if_fail (iface != NULL, FALSE);
|
||||
|
||||
if (NM_MODEM_GET_CLASS (self)->owns_port)
|
||||
return NM_MODEM_GET_CLASS (self)->owns_port (self, iface);
|
||||
|
||||
/* Fall back to data/control ports */
|
||||
if (priv->ppp_iface && (strcmp (priv->ppp_iface, iface) == 0))
|
||||
return TRUE;
|
||||
if (priv->data_port && (strcmp (priv->data_port, iface) == 0))
|
||||
return TRUE;
|
||||
if (priv->control_port && (strcmp (priv->control_port, iface) == 0))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -95,9 +95,7 @@ typedef struct {
|
|||
GError **error);
|
||||
|
||||
NMActStageReturn (*act_stage1_prepare) (NMModem *modem,
|
||||
NMActRequest *req,
|
||||
GPtrArray **out_hints,
|
||||
const char **out_setting_name,
|
||||
NMConnection *connection,
|
||||
NMDeviceStateReason *reason);
|
||||
|
||||
NMActStageReturn (*static_stage3_ip4_config_start) (NMModem *self,
|
||||
|
|
@ -110,6 +108,8 @@ typedef struct {
|
|||
|
||||
void (*deactivate) (NMModem *self, NMDevice *device);
|
||||
|
||||
gboolean (*owns_port) (NMModem *self, const char *iface);
|
||||
|
||||
/* Signals */
|
||||
void (*ppp_stats) (NMModem *self, guint32 in_bytes, guint32 out_bytes);
|
||||
void (*ppp_failed) (NMModem *self, NMDeviceStateReason reason);
|
||||
|
|
@ -129,6 +129,8 @@ const char *nm_modem_get_control_port (NMModem *modem);
|
|||
const char *nm_modem_get_data_port (NMModem *modem);
|
||||
const char *nm_modem_get_driver (NMModem *modem);
|
||||
|
||||
gboolean nm_modem_owns_port (NMModem *modem, const char *iface);
|
||||
|
||||
void nm_modem_get_capabilities (NMModem *self,
|
||||
NMDeviceModemCapabilities *modem_caps,
|
||||
NMDeviceModemCapabilities *current_caps);
|
||||
|
|
|
|||
|
|
@ -550,19 +550,22 @@ modem_added (NMModemManager *modem_manager,
|
|||
{
|
||||
NMManager *self = NM_MANAGER (user_data);
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
NMDevice *replace_device, *device = NULL;
|
||||
NMDevice *device = NULL;
|
||||
const char *modem_iface;
|
||||
GSList *iter;
|
||||
GSList *iter, *remove = NULL;
|
||||
|
||||
/* Don't rely only on the data port; use the control port if available */
|
||||
modem_iface = nm_modem_get_data_port (modem);
|
||||
if (!modem_iface)
|
||||
modem_iface = nm_modem_get_control_port (modem);
|
||||
g_return_if_fail (modem_iface);
|
||||
|
||||
replace_device = find_device_by_ip_iface (NM_MANAGER (user_data), modem_iface);
|
||||
if (replace_device)
|
||||
remove_device (NM_MANAGER (user_data), replace_device, FALSE);
|
||||
/* Remove ethernet devices that are actually owned by the modem, since
|
||||
* they cannot be used as normal ethernet.
|
||||
*/
|
||||
for (iter = priv->devices; iter; iter = iter->next) {
|
||||
if (nm_device_get_device_type (iter->data) == NM_DEVICE_TYPE_ETHERNET) {
|
||||
if (nm_modem_owns_port (modem, nm_device_get_ip_iface (iter->data)))
|
||||
remove = g_slist_prepend (remove, iter->data);
|
||||
}
|
||||
}
|
||||
for (iter = remove; iter; iter = iter->next)
|
||||
remove_device (self, NM_DEVICE (iter->data), FALSE);
|
||||
g_slist_free (remove);
|
||||
|
||||
/* Give Bluetooth DUN devices first chance to claim the modem */
|
||||
for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
|
||||
|
|
@ -577,6 +580,10 @@ modem_added (NMModemManager *modem_manager,
|
|||
* by the Bluetooth code during the connection process.
|
||||
*/
|
||||
if (driver && !strcmp (driver, "bluetooth")) {
|
||||
modem_iface = nm_modem_get_data_port (modem);
|
||||
if (!modem_iface)
|
||||
modem_iface = nm_modem_get_control_port (modem);
|
||||
|
||||
nm_log_info (LOGD_MB, "ignoring modem '%s' (no associated Bluetooth device)", modem_iface);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue