diff options
| author | Michael Biebl <biebl@debian.org> | 2015-01-22 00:29:39 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2015-01-22 00:29:39 +0100 |
| commit | 2c032d8f1c6292c1338a615e6ec40252889ba85c (patch) | |
| tree | 1f77182220b2b0264288ba4a476ab47e5bc48716 /src/devices/wwan/nm-modem.c | |
| parent | 33491bc4279481db8ae47213e34a6d695a0e8830 (diff) | |
Imported Upstream version 1.0.0 upstream/1.0.0
Diffstat (limited to 'src/devices/wwan/nm-modem.c')
| -rw-r--r-- | src/devices/wwan/nm-modem.c | 482 |
1 files changed, 378 insertions, 104 deletions
diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index fd3b4a36..ba1db8a4 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -19,6 +19,8 @@ * Copyright (C) 2009 Novell, Inc. */ +#include "config.h" + #include <string.h> #include "nm-modem.h" #include "nm-platform.h" @@ -42,11 +44,13 @@ enum { PROP_PATH, PROP_UID, PROP_DRIVER, - PROP_IP_METHOD, + PROP_IP4_METHOD, + PROP_IP6_METHOD, PROP_IP_TIMEOUT, PROP_STATE, PROP_DEVICE_ID, PROP_SIM_ID, + PROP_IP_TYPES, LAST_PROP }; @@ -58,11 +62,14 @@ typedef struct { char *control_port; char *data_port; char *ppp_iface; - guint32 ip_method; + NMModemIPMethod ip4_method; + NMModemIPMethod ip6_method; + NMUtilsIPv6IfaceId iid; NMModemState state; NMModemState prev_state; /* revert to this state if enable/disable fails */ char *device_id; char *sim_id; + NMModemIPType ip_types; NMPPPManager *ppp_manager; @@ -82,6 +89,7 @@ enum { PPP_FAILED, PREPARE_RESULT, IP4_CONFIG_RESULT, + IP6_CONFIG_RESULT, AUTH_REQUESTED, AUTH_RESULT, REMOVED, @@ -94,17 +102,6 @@ static guint signals[LAST_SIGNAL] = { 0 }; /*****************************************************************************/ - -GQuark -nm_modem_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-modem-error"); - return quark; -} - -/*****************************************************************************/ /* State/enabled/connected */ static const char *state_table[] = { @@ -126,7 +123,7 @@ static const char *state_table[] = { const char * nm_modem_state_to_string (NMModemState state) { - if (state >= 0 && state < G_N_ELEMENTS (state_table)) + if ((gsize) state < G_N_ELEMENTS (state_table)) return state_table[state]; return NULL; } @@ -218,6 +215,102 @@ nm_modem_emit_removed (NMModem *self) g_signal_emit (self, signals[REMOVED], 0); } +NMModemIPType +nm_modem_get_supported_ip_types (NMModem *self) +{ + return NM_MODEM_GET_PRIVATE (self)->ip_types; +} + +/** + * nm_modem_get_connection_ip_type: + * @self: the #NMModem + * @connection: the #NMConnection to determine IP type to use + * + * Given a modem and a connection, determine which NMModemIpType to use + * when connecting. + * + * Returns: a single %NMModemIpType value + */ +NMModemIPType +nm_modem_get_connection_ip_type (NMModem *self, + NMConnection *connection, + GError **error) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + NMSettingIPConfig *s_ip4, *s_ip6; + const char *method; + gboolean ip4 = TRUE, ip6 = TRUE; + gboolean ip4_may_fail = TRUE, ip6_may_fail = TRUE; + + s_ip4 = nm_connection_get_setting_ip4_config (connection); + if (s_ip4) { + method = nm_setting_ip_config_get_method (s_ip4); + if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) + ip4 = FALSE; + ip4_may_fail = nm_setting_ip_config_get_may_fail (s_ip4); + } + + s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (s_ip6) { + method = nm_setting_ip_config_get_method (s_ip6); + if (g_strcmp0 (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) + ip6 = FALSE; + ip6_may_fail = nm_setting_ip_config_get_may_fail (s_ip6); + } + + if (ip4 && !ip6) { + if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV4)) { + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested IPv4 but IPv4 is " + "unsuported by the modem."); + return NM_MODEM_IP_TYPE_UNKNOWN; + } + return NM_MODEM_IP_TYPE_IPV4; + } + + if (ip6 && !ip4) { + if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV6)) { + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested IPv6 but IPv6 is " + "unsuported by the modem."); + return NM_MODEM_IP_TYPE_UNKNOWN; + } + return NM_MODEM_IP_TYPE_IPV6; + } + + if (ip4 && ip6) { + /* Modem supports dual-stack */ + if (priv->ip_types & NM_MODEM_IP_TYPE_IPV4V6) + return NM_MODEM_IP_TYPE_IPV4V6; + + /* Both IPv4 and IPv6 requested, but modem doesn't support dual-stack; + * if one method is marked "may-fail" then use the other. + */ + if (ip6_may_fail) + return NM_MODEM_IP_TYPE_IPV4; + else if (ip4_may_fail) + return NM_MODEM_IP_TYPE_IPV6; + + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested both IPv4 and IPv6 " + "but dual-stack addressing is unsupported " + "by the modem."); + return NM_MODEM_IP_TYPE_UNKNOWN; + } + + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection specified no IP configuration!"); + return NM_MODEM_IP_TYPE_UNKNOWN; +} + /*****************************************************************************/ /* IP method PPP */ @@ -237,13 +330,24 @@ ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_ } static void +set_data_port (NMModem *self, const char *new_data_port) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + + if (g_strcmp0 (priv->data_port, new_data_port) != 0) { + g_free (priv->data_port); + priv->data_port = g_strdup (new_data_port); + g_object_notify (G_OBJECT (self), NM_MODEM_DATA_PORT); + } +} + +static void ppp_ip4_config (NMPPPManager *ppp_manager, const char *iface, NMIP4Config *config, gpointer user_data) { NMModem *self = NM_MODEM (user_data); - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); guint32 i, num; guint32 bad_dns1 = htonl (0x0A0B0C0D); guint32 good_dns1 = htonl (0x04020201); /* GTE nameserver */ @@ -252,9 +356,7 @@ ppp_ip4_config (NMPPPManager *ppp_manager, gboolean dns_workaround = FALSE; /* Notify about the new data port to use */ - g_free (priv->ppp_iface); - priv->ppp_iface = g_strdup (iface); - g_object_notify (G_OBJECT (self), NM_MODEM_DATA_PORT); + set_data_port (self, iface); /* Work around a PPP bug (#1732) which causes many mobile broadband * providers to return 10.11.12.13 and 10.11.12.14 for the DNS servers. @@ -296,6 +398,23 @@ ppp_ip4_config (NMPPPManager *ppp_manager, } static void +ppp_ip6_config (NMPPPManager *ppp_manager, + const char *iface, + const NMUtilsIPv6IfaceId *iid, + NMIP6Config *config, + gpointer user_data) +{ + NMModem *self = NM_MODEM (user_data); + + /* Notify about the new data port to use */ + set_data_port (self, iface); + + NM_MODEM_GET_PRIVATE (self)->iid = *iid; + + nm_modem_emit_ip6_config_result (self, config, NULL); +} + +static void ppp_stats (NMPPPManager *ppp_manager, guint32 in_bytes, guint32 out_bytes, @@ -313,20 +432,27 @@ ppp_stats (NMPPPManager *ppp_manager, } static NMActStageReturn -ppp_stage3_ip4_config_start (NMModem *self, - NMActRequest *req, - NMDeviceStateReason *reason) +ppp_stage3_ip_config_start (NMModem *self, + NMActRequest *req, + NMDeviceStateReason *reason) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); const char *ppp_name = NULL; GError *error = NULL; NMActStageReturn ret; - guint ip_timeout = 20; + guint ip_timeout = 30; g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + /* If we're already running PPP don't restart it; for example, if both + * IPv4 and IPv6 are requested, IPv4 gets started first, but we use the + * same pppd for both v4 and v6. + */ + if (priv->ppp_manager) + return NM_ACT_STAGE_RETURN_POSTPONE; + if (NM_MODEM_GET_CLASS (self)->get_user_pass) { NMConnection *connection = nm_act_request_get_connection (req); @@ -336,7 +462,7 @@ ppp_stage3_ip4_config_start (NMModem *self, } /* Check if ModemManager requested a specific IP timeout to be used. If 0 reported, - * use the default one (20s) */ + * use the default one (30s) */ if (priv->mm_ip_timeout > 0) { nm_log_info (LOGD_PPP, "using modem-specified IP timeout: %u seconds", priv->mm_ip_timeout); @@ -351,6 +477,9 @@ ppp_stage3_ip4_config_start (NMModem *self, g_signal_connect (priv->ppp_manager, "ip4-config", G_CALLBACK (ppp_ip4_config), self); + g_signal_connect (priv->ppp_manager, "ip6-config", + G_CALLBACK (ppp_ip6_config), + self); g_signal_connect (priv->ppp_manager, "stats", G_CALLBACK (ppp_stats), self); @@ -382,6 +511,8 @@ nm_modem_stage3_ip4_config_start (NMModem *self, { NMModemPrivate *priv; NMActRequest *req; + NMConnection *connection; + const char *method; NMActStageReturn ret; g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); @@ -391,21 +522,36 @@ nm_modem_stage3_ip4_config_start (NMModem *self, req = nm_device_get_act_request (device); g_assert (req); + connection = nm_act_request_get_connection (req); + g_assert (connection); + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + + /* Only Disabled and Auto methods make sense for WWAN */ + if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) + return NM_ACT_STAGE_RETURN_STOP; + + if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) != 0) { + nm_log_warn (LOGD_MB | LOGD_IP4, + "(%s): unhandled WWAN IPv4 method '%s'; will fail", + nm_modem_get_uid (self), method); + *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + return NM_ACT_STAGE_RETURN_FAILURE; + } priv = NM_MODEM_GET_PRIVATE (self); - switch (priv->ip_method) { - case MM_MODEM_IP_METHOD_PPP: - ret = ppp_stage3_ip4_config_start (self, req, reason); + switch (priv->ip4_method) { + case NM_MODEM_IP_METHOD_PPP: + ret = ppp_stage3_ip_config_start (self, req, reason); break; - case MM_MODEM_IP_METHOD_STATIC: + case NM_MODEM_IP_METHOD_STATIC: ret = NM_MODEM_GET_CLASS (self)->static_stage3_ip4_config_start (self, req, reason); break; - case MM_MODEM_IP_METHOD_DHCP: + case NM_MODEM_IP_METHOD_AUTO: ret = device_class->act_stage3_ip4_config_start (device, NULL, reason); break; default: - nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method); - ret = NM_ACT_STAGE_RETURN_FAILURE; + nm_log_info (LOGD_MB, "(%s): IPv4 configuration disabled", nm_modem_get_uid (self)); + ret = NM_ACT_STAGE_RETURN_STOP; break; } @@ -423,8 +569,8 @@ nm_modem_ip4_pre_commit (NMModem *modem, * not point-to-point) and IP config has a /32 prefix, then we assume that * ARP will be pointless and we turn it off. */ - if ( priv->ip_method == MM_MODEM_IP_METHOD_STATIC - || priv->ip_method == MM_MODEM_IP_METHOD_DHCP) { + if ( priv->ip4_method == NM_MODEM_IP_METHOD_STATIC + || priv->ip4_method == NM_MODEM_IP_METHOD_AUTO) { const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, 0); g_assert (address); @@ -435,15 +581,100 @@ nm_modem_ip4_pre_commit (NMModem *modem, /*****************************************************************************/ +void +nm_modem_emit_ip6_config_result (NMModem *self, + NMIP6Config *config, + GError *error) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + guint i, num; + gboolean do_slaac = TRUE; + + if (error) { + g_signal_emit (self, signals[IP6_CONFIG_RESULT], 0, NULL, FALSE, error); + return; + } + + if (config) { + /* If the IPv6 configuration only included a Link-Local address, then + * we have to run SLAAC to get the full IPv6 configuration. + */ + num = nm_ip6_config_get_num_addresses (config); + g_assert (num > 0); + for (i = 0; i < num; i++) { + const NMPlatformIP6Address * addr = nm_ip6_config_get_address (config, i); + + if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) { + if (!priv->iid.id) + priv->iid.id = ((guint64 *)(&addr->address.s6_addr))[1]; + } else + do_slaac = FALSE; + } + } + g_assert (config || do_slaac); + + g_signal_emit (self, signals[IP6_CONFIG_RESULT], 0, config, do_slaac, NULL); +} + +static NMActStageReturn +stage3_ip6_config_request (NMModem *self, NMDeviceStateReason *reason) +{ + *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + return NM_ACT_STAGE_RETURN_FAILURE; +} + NMActStageReturn nm_modem_stage3_ip6_config_start (NMModem *self, - NMDevice *device, - NMDeviceClass *device_class, + NMActRequest *req, NMDeviceStateReason *reason) { - /* FIXME: We don't support IPv6 on modems quite yet... */ - nm_device_activate_schedule_ip6_config_timeout (device); - return NM_ACT_STAGE_RETURN_POSTPONE; + NMModemPrivate *priv; + NMActStageReturn ret; + NMConnection *connection; + const char *method; + + g_return_val_if_fail (self != NULL, NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + connection = nm_act_request_get_connection (req); + g_assert (connection); + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + + /* Only Ignore and Auto methods make sense for WWAN */ + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) + return NM_ACT_STAGE_RETURN_STOP; + + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) != 0) { + nm_log_warn (LOGD_MB | LOGD_IP6, + "(%s): unhandled WWAN IPv6 method '%s'; will fail", + nm_modem_get_uid (self), method); + *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + priv = NM_MODEM_GET_PRIVATE (self); + switch (priv->ip6_method) { + case NM_MODEM_IP_METHOD_PPP: + ret = ppp_stage3_ip_config_start (self, req, reason); + break; + case NM_MODEM_IP_METHOD_STATIC: + case NM_MODEM_IP_METHOD_AUTO: + /* Both static and DHCP/Auto retrieve a base IP config from the modem + * which in the static case is the full config, and the DHCP/Auto case + * is just the IPv6LL address to use for SLAAC. + */ + ret = NM_MODEM_GET_CLASS (self)->stage3_ip6_config_request (self, reason); + break; + default: + nm_log_info (LOGD_MB, "(%s): IPv6 configuration disabled", nm_modem_get_uid (self)); + ret = NM_ACT_STAGE_RETURN_STOP; + break; + } + + return ret; } /*****************************************************************************/ @@ -486,12 +717,12 @@ nm_modem_get_secrets (NMModem *self, const char *hint) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; cancel_get_secrets (self); if (request_new) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_request, setting_name, flags, @@ -524,7 +755,7 @@ nm_modem_act_stage1_prepare (NMModem *self, NMActStageReturn ret; GPtrArray *hints = NULL; const char *setting_name = NULL; - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; NMConnection *connection; if (priv->act_request) @@ -543,7 +774,7 @@ nm_modem_act_stage1_prepare (NMModem *self, /* Secrets required... */ if (priv->secrets_tries++) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (req, setting_name, @@ -633,22 +864,19 @@ deactivate (NMModem *self, NMDevice *device) priv->ppp_manager = NULL; } - switch (priv->ip_method) { - case MM_MODEM_IP_METHOD_PPP: - break; - case MM_MODEM_IP_METHOD_STATIC: - case MM_MODEM_IP_METHOD_DHCP: + if (priv->ip4_method == NM_MODEM_IP_METHOD_STATIC || + priv->ip4_method == NM_MODEM_IP_METHOD_AUTO || + priv->ip6_method == NM_MODEM_IP_METHOD_STATIC || + priv->ip6_method == NM_MODEM_IP_METHOD_AUTO) { ifindex = nm_device_get_ip_ifindex (device); if (ifindex > 0) { nm_platform_route_flush (ifindex); nm_platform_address_flush (ifindex); nm_platform_link_set_down (ifindex); } - break; - default: - nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method); - break; } + priv->ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; + priv->ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; g_free (priv->ppp_iface); priv->ppp_iface = NULL; @@ -772,6 +1000,15 @@ nm_modem_owns_port (NMModem *self, const char *iface) return FALSE; } +gboolean +nm_modem_get_iid (NMModem *self, NMUtilsIPv6IfaceId *out_iid) +{ + g_return_val_if_fail (NM_IS_MODEM (self), FALSE); + + *out_iid = NM_MODEM_GET_PRIVATE (self)->iid; + return TRUE; +} + /*****************************************************************************/ void @@ -846,8 +1083,11 @@ get_property (GObject *object, guint prop_id, case PROP_UID: g_value_set_string (value, priv->uid); break; - case PROP_IP_METHOD: - g_value_set_uint (value, priv->ip_method); + case PROP_IP4_METHOD: + g_value_set_uint (value, priv->ip4_method); + break; + case PROP_IP6_METHOD: + g_value_set_uint (value, priv->ip6_method); break; case PROP_IP_TIMEOUT: g_value_set_uint (value, priv->mm_ip_timeout); @@ -861,6 +1101,9 @@ get_property (GObject *object, guint prop_id, case PROP_SIM_ID: g_value_set_string (value, priv->sim_id); break; + case PROP_IP_TYPES: + g_value_set_uint (value, priv->ip_types); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -892,8 +1135,11 @@ set_property (GObject *object, guint prop_id, /* Construct only */ priv->uid = g_value_dup_string (value); break; - case PROP_IP_METHOD: - priv->ip_method = g_value_get_uint (value); + case PROP_IP4_METHOD: + priv->ip4_method = g_value_get_uint (value); + break; + case PROP_IP6_METHOD: + priv->ip6_method = g_value_get_uint (value); break; case PROP_IP_TIMEOUT: priv->mm_ip_timeout = g_value_get_uint (value); @@ -909,6 +1155,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->sim_id); priv->sim_id = g_value_dup_string (value); break; + case PROP_IP_TYPES: + priv->ip_types = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -959,92 +1208,100 @@ nm_modem_class_init (NMModemClass *klass) object_class->finalize = finalize; klass->act_stage1_prepare = act_stage1_prepare; + klass->stage3_ip6_config_request = stage3_ip6_config_request; klass->deactivate = deactivate; /* Properties */ g_object_class_install_property (object_class, PROP_UID, - g_param_spec_string (NM_MODEM_UID, - "UID", - "Modem unique ID", + g_param_spec_string (NM_MODEM_UID, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_PATH, - g_param_spec_string (NM_MODEM_PATH, - "DBus path", - "DBus path", + g_param_spec_string (NM_MODEM_PATH, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DRIVER, - g_param_spec_string (NM_MODEM_DRIVER, - "Driver", - "Driver", + g_param_spec_string (NM_MODEM_DRIVER, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CONTROL_PORT, - g_param_spec_string (NM_MODEM_CONTROL_PORT, - "Control port", - "The port controlling the modem", + g_param_spec_string (NM_MODEM_CONTROL_PORT, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DATA_PORT, - g_param_spec_string (NM_MODEM_DATA_PORT, - "Data port", - "The port to connect to", + g_param_spec_string (NM_MODEM_DATA_PORT, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property - (object_class, PROP_IP_METHOD, - g_param_spec_uint (NM_MODEM_IP_METHOD, - "IP method", - "IP method", - MM_MODEM_IP_METHOD_PPP, - MM_MODEM_IP_METHOD_DHCP, - MM_MODEM_IP_METHOD_PPP, - G_PARAM_READWRITE)); + (object_class, PROP_IP4_METHOD, + g_param_spec_uint (NM_MODEM_IP4_METHOD, "", "", + NM_MODEM_IP_METHOD_UNKNOWN, + NM_MODEM_IP_METHOD_AUTO, + NM_MODEM_IP_METHOD_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_IP6_METHOD, + g_param_spec_uint (NM_MODEM_IP6_METHOD, "", "", + NM_MODEM_IP_METHOD_UNKNOWN, + NM_MODEM_IP_METHOD_AUTO, + NM_MODEM_IP_METHOD_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IP_TIMEOUT, - g_param_spec_uint (NM_MODEM_IP_TIMEOUT, - "IP timeout", - "IP timeout", + g_param_spec_uint (NM_MODEM_IP_TIMEOUT, "", "", 0, 360, 20, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_enum (NM_MODEM_STATE, - "State", - "State", - NM_TYPE_MODEM_STATE, - NM_MODEM_STATE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_enum (NM_MODEM_STATE, "", "", + NM_TYPE_MODEM_STATE, + NM_MODEM_STATE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DEVICE_ID, - g_param_spec_string (NM_MODEM_DEVICE_ID, - "DeviceId", - "Device ID", + g_param_spec_string (NM_MODEM_DEVICE_ID, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SIM_ID, - g_param_spec_string (NM_MODEM_SIM_ID, - "SimId", - "Sim ID", + g_param_spec_string (NM_MODEM_SIM_ID, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_IP_TYPES, + g_param_spec_uint (NM_MODEM_IP_TYPES, + "IP Types", + "Supported IP types", + 0, G_MAXUINT32, NM_MODEM_IP_TYPE_IPV4, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); /* Signals */ @@ -1073,6 +1330,27 @@ nm_modem_class_init (NMModemClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_POINTER); + /** + * NMModem::ip6-config-result: + * @modem: the #NMModem on which the signal is emitted + * @config: the #NMIP6Config to apply to the modem's data port + * @do_slaac: %TRUE if IPv6 SLAAC should be started + * @error: a #GError if any error occurred during IP configuration + * + * This signal is emitted when IPv6 configuration has completed or failed. + * If @error is set the configuration failed. If @config is set, then + * the details should be applied to the data port before any further + * configuration (like SLAAC) is done. @do_slaac indicates whether SLAAC + * should be started after applying @config to the data port. + */ + signals[IP6_CONFIG_RESULT] = + g_signal_new (NM_MODEM_IP6_CONFIG_RESULT, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMModemClass, ip6_config_result), + NULL, NULL, NULL, + G_TYPE_NONE, 3, G_TYPE_OBJECT, G_TYPE_BOOLEAN, G_TYPE_POINTER); + signals[PREPARE_RESULT] = g_signal_new (NM_MODEM_PREPARE_RESULT, G_OBJECT_CLASS_TYPE (object_class), @@ -1112,8 +1390,4 @@ nm_modem_class_init (NMModemClass *klass) G_STRUCT_OFFSET (NMModemClass, state_changed), NULL, NULL, NULL, G_TYPE_NONE, 2, NM_TYPE_MODEM_STATE, NM_TYPE_MODEM_STATE); - - dbus_g_error_domain_register (NM_MODEM_ERROR, - NM_DBUS_INTERFACE_DEVICE_MODEM, - NM_TYPE_MODEM_ERROR); } |