static void
modem_added_cb (NMModemManager *manager,
                NMModem *modem,
                gpointer user_data)
{
	NMWwanFactory *self = NM_WWAN_FACTORY (user_data);
	NMDevice *device;
	const char *driver, *port;

	/* Do nothing if the modem was consumed by some other plugin */
	if (nm_device_factory_emit_component_added (NM_DEVICE_FACTORY (self), G_OBJECT (modem)))
		return;

	driver = nm_modem_get_driver (modem);

	/* If it was a Bluetooth modem and no bluetooth device claimed it, ignore
	 * it.  The rfcomm port (and thus the modem) gets created automatically
	 * by the Bluetooth code during the connection process.
	 */
	if (driver && strstr (driver, "bluetooth")) {
		port = nm_modem_get_data_port (modem);
		if (!port)
			port = nm_modem_get_control_port (modem);
		nm_log_info (LOGD_MB, "ignoring modem '%s' (no associated Bluetooth device)", port);
		return;
	}

	/* Make the new modem device */
	device = nm_device_modem_new (modem);
	g_assert (device);
	g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, device);
	g_object_unref (device);
}
gboolean
nm_device_bt_modem_added (NMDeviceBt *self,
                          NMModem *modem,
                          const char *driver)
{
    NMDeviceBtPrivate *priv;
    const gchar *modem_data_port;
    const gchar *modem_control_port;
    char *base;
    NMDeviceState state;
    NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;

    g_return_val_if_fail (self != NULL, FALSE);
    g_return_val_if_fail (NM_IS_DEVICE_BT (self), FALSE);
    g_return_val_if_fail (modem != NULL, FALSE);
    g_return_val_if_fail (NM_IS_MODEM (modem), FALSE);

    priv = NM_DEVICE_BT_GET_PRIVATE (self);
    modem_data_port = nm_modem_get_data_port (modem);
    modem_control_port = nm_modem_get_control_port (modem);
    g_return_val_if_fail (modem_data_port != NULL || modem_control_port != NULL, FALSE);

    if (!priv->rfcomm_iface)
        return FALSE;

    base = g_path_get_basename (priv->rfcomm_iface);
    if (g_strcmp0 (base, modem_data_port) && g_strcmp0 (base, modem_control_port)) {
        g_free (base);
        return FALSE;
    }
    g_free (base);

    /* Got the modem */
    if (priv->timeout_id) {
        g_source_remove (priv->timeout_id);
        priv->timeout_id = 0;
    }

    /* Can only accept the modem in stage2, but since the interface matched
     * what we were expecting, don't let anything else claim the modem either.
     */
    state = nm_device_get_state (NM_DEVICE (self));
    if (state != NM_DEVICE_STATE_CONFIG) {
        nm_log_warn (LOGD_BT | LOGD_MB,
                     "(%s): modem found but device not in correct state (%d)",
                     nm_device_get_iface (NM_DEVICE (self)),
                     nm_device_get_state (NM_DEVICE (self)));
        return TRUE;
    }

    nm_log_info (LOGD_BT | LOGD_MB,
                 "Activation (%s/bluetooth) Stage 2 of 5 (Device Configure) modem found.",
                 nm_device_get_iface (NM_DEVICE (self)));

    if (priv->modem) {
        g_warn_if_reached ();
        g_object_unref (priv->modem);
    }

    priv->modem = g_object_ref (modem);
    g_signal_connect (modem, NM_MODEM_PPP_STATS, G_CALLBACK (ppp_stats), self);
    g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self);
    g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self);
    g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self);
    g_signal_connect (modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK (modem_auth_requested), self);
    g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self);

    /* In the old ModemManager the data port is known from the very beginning;
     * while in the new ModemManager the data port is set afterwards when the bearer gets
     * created */
    if (modem_data_port)
        nm_device_set_ip_iface (NM_DEVICE (self), modem_data_port);
    g_signal_connect (modem, "notify::" NM_MODEM_DATA_PORT, G_CALLBACK (data_port_changed_cb), self);

    /* Kick off the modem connection */
    if (!modem_stage1 (self, modem, &reason))
        nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, reason);

    return TRUE;
}