static void ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data) { switch (status) { case NM_PPP_STATUS_DISCONNECT: g_signal_emit (NM_MODEM (user_data), signals[PPP_FAILED], 0, NM_DEVICE_STATE_REASON_PPP_DISCONNECT); break; case NM_PPP_STATUS_DEAD: g_signal_emit (NM_MODEM (user_data), signals[PPP_FAILED], 0, NM_DEVICE_STATE_REASON_PPP_FAILED); break; default: break; } }
static void static_stage3_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) { NMModem *self = NM_MODEM (user_data); NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); GValueArray *ret_array = NULL; GError *error = NULL; NMIP4Config *config = NULL; priv->call = NULL; if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_VALUE_ARRAY, &ret_array, G_TYPE_INVALID)) { NMIP4Address *addr; int i; config = nm_ip4_config_new (); addr = nm_ip4_address_new (); nm_ip4_address_set_address (addr, g_value_get_uint (g_value_array_get_nth (ret_array, 0))); nm_ip4_address_set_prefix (addr, 32); nm_ip4_config_take_address (config, addr); for (i = 0; i < ret_array->n_values; i++) { GValue *value = g_value_array_get_nth (ret_array, i); nm_ip4_config_add_nameserver (config, g_value_get_uint (value)); } g_value_array_free (ret_array); } g_signal_emit (self, signals[IP4_CONFIG_RESULT], 0, NULL, config, error); g_clear_error (&error); }
static void real_connection_secrets_updated (NMDevice *dev, NMConnection *connection, GSList *updated_settings, RequestSecretsCaller caller) { NMActRequest *req; gboolean found = FALSE; GSList *iter; if (caller == SECRETS_CALLER_PPP) { NMPPPManager *ppp_manager; NMSettingGsm *s_gsm = NULL; ppp_manager = nm_modem_get_ppp_manager (NM_MODEM (dev)); g_return_if_fail (ppp_manager != NULL); s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM); if (!s_gsm) { /* Shouldn't ever happen */ nm_ppp_manager_update_secrets (ppp_manager, nm_device_get_iface (dev), NULL, NULL, "missing GSM setting; no secrets could be found."); } else { const char *username = nm_setting_gsm_get_username (s_gsm); const char *password = nm_setting_gsm_get_password (s_gsm); nm_ppp_manager_update_secrets (ppp_manager, nm_device_get_iface (dev), username ? username : "", password ? password : "", NULL); } return; } g_return_if_fail (caller == SECRETS_CALLER_GSM); g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH); for (iter = updated_settings; iter; iter = g_slist_next (iter)) { const char *setting_name = (const char *) iter->data; if (!strcmp (setting_name, NM_SETTING_GSM_SETTING_NAME)) found = TRUE; else nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name); } if (!found) return; req = nm_device_get_act_request (dev); g_assert (req); g_return_if_fail (nm_act_request_get_connection (req) == connection); nm_device_activate_schedule_stage1_device_prepare (dev); }
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 */ guint32 bad_dns2 = htonl (0x0A0B0C0E); guint32 good_dns2 = htonl (0x04020202); /* GTE nameserver */ 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); /* 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. * Apparently fixed in ppp-2.4.5 but we've had some reports that this is * not the case. * * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=2e09ef6886bbf00bc5a9a641110f801e372ffde6 * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=f8191bf07df374f119a07910a79217c7618f113e */ num = nm_ip4_config_get_num_nameservers (config); if (num == 2) { gboolean found1 = FALSE, found2 = FALSE; for (i = 0; i < num; i++) { guint32 ns = nm_ip4_config_get_nameserver (config, i); if (ns == bad_dns1) found1 = TRUE; else if (ns == bad_dns2) found2 = TRUE; } /* Be somewhat conservative about substitutions; the "bad" nameservers * could actually be valid in some cases, so only substitute if ppp * returns *only* the two bad nameservers. */ dns_workaround = (found1 && found2); } if (!num || dns_workaround) { nm_log_warn (LOGD_PPP, "compensating for invalid PPP-provided nameservers"); nm_ip4_config_reset_nameservers (config); nm_ip4_config_add_nameserver (config, good_dns1); nm_ip4_config_add_nameserver (config, good_dns2); } g_signal_emit (self, signals[IP4_CONFIG_RESULT], 0, config, NULL); }
static NMActStageReturn real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { NMActRequest *req; NMConnection *connection; const char *setting_name; GPtrArray *hints = NULL; const char *hint1 = NULL, *hint2 = NULL; guint32 tries; req = nm_device_get_act_request (device); g_assert (req); connection = nm_act_request_get_connection (req); g_assert (connection); setting_name = nm_connection_need_secrets (connection, &hints); if (!setting_name) { GHashTable *properties; properties = create_connect_properties (connection); dbus_g_proxy_begin_call_with_timeout (nm_modem_get_proxy (NM_MODEM (device), MM_DBUS_INTERFACE_MODEM_SIMPLE), "Connect", stage1_prepare_done, device, NULL, 120000, DBUS_TYPE_G_MAP_OF_VARIANT, properties, G_TYPE_INVALID); return NM_ACT_STAGE_RETURN_POSTPONE; } if (hints) { if (hints->len > 0) hint1 = g_ptr_array_index (hints, 0); if (hints->len > 1) hint2 = g_ptr_array_index (hints, 1); } nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), GSM_SECRETS_TRIES)); nm_act_request_get_secrets (req, setting_name, tries ? TRUE : FALSE, SECRETS_CALLER_GSM, hint1, hint2); g_object_set_data (G_OBJECT (connection), GSM_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); if (hints) g_ptr_array_free (hints, TRUE); return NM_ACT_STAGE_RETURN_POSTPONE; }
static void do_connect (NMModemGsm *self) { NMModemGsmPrivate *priv = NM_MODEM_GSM_GET_PRIVATE (self); DBusGProxy *proxy; proxy = nm_modem_get_proxy (NM_MODEM (self), MM_DBUS_INTERFACE_MODEM_SIMPLE); dbus_g_proxy_begin_call_with_timeout (proxy, "Connect", stage1_prepare_done, self, NULL, 120000, DBUS_TYPE_G_MAP_OF_VARIANT, priv->connect_properties, G_TYPE_INVALID); }
static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object); switch (prop_id) { case PROP_PATH: g_value_set_string (value, priv->path); break; case PROP_DRIVER: g_value_set_string (value, priv->driver); break; case PROP_CONTROL_PORT: g_value_set_string (value, priv->control_port); break; case PROP_DATA_PORT: g_value_set_string (value, nm_modem_get_data_port (NM_MODEM (object))); break; case PROP_UID: g_value_set_string (value, priv->uid); break; 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); break; case PROP_STATE: g_value_set_enum (value, priv->state); break; case PROP_DEVICE_ID: g_value_set_string (value, priv->device_id); break; 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; case PROP_SIM_OPERATOR_ID: g_value_set_string (value, priv->sim_operator_id); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void set_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { GError *error = NULL; if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { nm_log_warn (LOGD_MB, "failed to enable/disable modem: (%d) %s", error ? error->code : -1, error && error->message ? error->message : "(unknown)"); } /* Update enabled/disabled state again */ query_mm_enabled (NM_MODEM (user_data)); }
static void do_enable (NMModemGsm *self) { DBusGProxy *proxy; g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_MODEM_GSM (self)); proxy = nm_modem_get_proxy (NM_MODEM (self), MM_DBUS_INTERFACE_MODEM); dbus_g_proxy_begin_call_with_timeout (proxy, "Enable", stage1_enable_done, self, NULL, 20000, G_TYPE_BOOLEAN, TRUE, G_TYPE_INVALID); }
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, gpointer user_data) { NMModem *self = NM_MODEM (user_data); NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); if (priv->in_bytes != in_bytes || priv->out_bytes != out_bytes) { priv->in_bytes = in_bytes; priv->out_bytes = out_bytes; g_signal_emit (self, signals[PPP_STATS], 0, in_bytes, out_bytes); } }
/* do_enable() is used as a GSourceFunc, hence the gboolean return */ static gboolean do_enable (NMModemGsm *self) { DBusGProxy *proxy; g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_MODEM_GSM (self), FALSE); NM_MODEM_GSM_GET_PRIVATE (self)->enable_delay_id = 0; proxy = nm_modem_get_proxy (NM_MODEM (self), MM_DBUS_INTERFACE_MODEM); dbus_g_proxy_begin_call_with_timeout (proxy, "Enable", stage1_enable_done, self, NULL, 20000, G_TYPE_BOOLEAN, TRUE, G_TYPE_INVALID); return FALSE; }
static void ask_for_pin (NMModemGsm *self, gboolean always_ask) { NMModemGsmPrivate *priv; guint32 tries = 0; g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_MODEM_GSM (self)); priv = NM_MODEM_GSM_GET_PRIVATE (self); if (!always_ask) tries = priv->pin_tries++; nm_modem_get_secrets (NM_MODEM (self), NM_SETTING_GSM_SETTING_NAME, (tries || always_ask) ? TRUE : FALSE, NM_SETTING_GSM_PIN); }
static void modem_secrets_cb (NMActRequest *req, guint32 call_id, NMConnection *connection, GError *error, gpointer user_data) { NMModem *self = NM_MODEM (user_data); NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); g_return_if_fail (call_id == priv->secrets_id); priv->secrets_id = 0; if (error) nm_log_warn (LOGD_MB, "%s", error->message); g_signal_emit (self, signals[AUTH_RESULT], 0, error); }
static void modem_secrets_cb (NMActRequest *req, NMActRequestGetSecretsCallId call_id, NMSettingsConnection *connection, GError *error, gpointer user_data) { NMModem *self = NM_MODEM (user_data); NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); g_return_if_fail (call_id == priv->secrets_id); priv->secrets_id = NULL; if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; if (error) nm_log_warn (LOGD_MB, "(%s): %s", nm_modem_get_uid (self), error->message); g_signal_emit (self, signals[AUTH_RESULT], 0, error); }
static void get_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { NMModem *self = NM_MODEM (user_data); GError *error = NULL; GValue value = { 0, }; if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_VALUE, &value, G_TYPE_INVALID)) { nm_log_warn (LOGD_MB, "failed get modem enabled state: (%d) %s", error ? error->code : -1, error && error->message ? error->message : "(unknown)"); return; } if (G_VALUE_HOLDS_BOOLEAN (&value)) { update_mm_enabled (self, g_value_get_boolean (&value)); } else nm_log_warn (LOGD_MB, "failed get modem enabled state: unexpected reply type"); g_value_unset (&value); }
static void modem_properties_changed (DBusGProxy *proxy, const char *interface, GHashTable *props, gpointer user_data) { NMModem *self = NM_MODEM (user_data); NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); GValue *value; if (strcmp (interface, MM_DBUS_INTERFACE_MODEM)) return; value = g_hash_table_lookup (props, "Enabled"); if (value && G_VALUE_HOLDS_BOOLEAN (value)) { update_mm_enabled (self, g_value_get_boolean (value)); } value = g_hash_table_lookup (props, "IpMethod"); if (value && G_VALUE_HOLDS_UINT (value)) { priv->ip_method = g_value_get_uint (value); g_object_notify (G_OBJECT (self), NM_MODEM_IP_METHOD); } }
static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object); switch (prop_id) { case PROP_PATH: g_value_set_string (value, priv->path); break; case PROP_CONTROL_PORT: g_value_set_string (value, priv->control_port); break; case PROP_DATA_PORT: g_value_set_string (value, nm_modem_get_data_port (NM_MODEM (object))); break; case PROP_UID: g_value_set_string (value, priv->uid); break; case PROP_IP_METHOD: g_value_set_uint (value, priv->ip_method); break; case PROP_IP_TIMEOUT: g_value_set_uint (value, priv->mm_ip_timeout); break; case PROP_ENABLED: g_value_set_boolean (value, priv->mm_enabled); break; case PROP_CONNECTED: g_value_set_boolean (value, priv->mm_connected); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void handle_enable_pin_required (NMModemGsm *self) { NMModemGsmPrivate *priv = NM_MODEM_GSM_GET_PRIVATE (self); const char *pin = NULL; GValue *value; DBusGProxy *proxy; /* See if we have a PIN already */ value = g_hash_table_lookup (priv->connect_properties, "pin"); if (value && G_VALUE_HOLDS_STRING (value)) pin = g_value_get_string (value); /* If we do, send it */ if (pin) { proxy = nm_modem_get_proxy (NM_MODEM (self), MM_DBUS_INTERFACE_MODEM_GSM_CARD); dbus_g_proxy_begin_call_with_timeout (proxy, "SendPin", stage1_pin_done, self, NULL, 10000, G_TYPE_STRING, pin, G_TYPE_INVALID); } else ask_for_pin (self, FALSE); }
static GObject* constructor (GType type, guint n_construct_params, GObjectConstructParam *construct_params) { GObject *object; NMModemPrivate *priv; DBusGConnection *bus; object = G_OBJECT_CLASS (nm_modem_parent_class)->constructor (type, n_construct_params, construct_params); if (!object) return NULL; priv = NM_MODEM_GET_PRIVATE (object); if (!priv->device) { nm_log_err (LOGD_HW, "modem parent device not provided"); goto err; } if (!priv->device) { nm_log_err (LOGD_HW, "modem command interface not provided"); goto err; } if (!priv->path) { nm_log_err (LOGD_HW, "D-Bus path not provided"); goto err; } bus = nm_dbus_manager_get_connection (priv->dbus_mgr); priv->proxy = dbus_g_proxy_new_for_name (bus, MM_DBUS_SERVICE, priv->path, MM_DBUS_INTERFACE_MODEM); priv->props_proxy = dbus_g_proxy_new_for_name (bus, MM_DBUS_SERVICE, priv->path, DBUS_INTERFACE_PROPERTIES); dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_BOXED, G_TYPE_NONE, G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); dbus_g_proxy_add_signal (priv->props_proxy, "MmPropertiesChanged", G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->props_proxy, "MmPropertiesChanged", G_CALLBACK (modem_properties_changed), object, NULL); query_mm_enabled (NM_MODEM (object)); return object; err: g_object_unref (object); return NULL; }