void
nm_active_connection_set_state (NMActiveConnection *self,
                                NMActiveConnectionState new_state)
{
	NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
	NMActiveConnectionState old_state;

	if (priv->state == new_state)
		return;

	/* DEACTIVATED is a terminal state */
	if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
		g_return_if_fail (new_state != NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);

	_LOGD ("set state %s (was %s)",
	       state_to_string (new_state),
	       state_to_string (priv->state));

	old_state = priv->state;
	priv->state = new_state;
	priv->state_set = TRUE;
	_notify (self, PROP_STATE);

	check_master_ready (self);

	if (   new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
	    || old_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
		nm_settings_connection_update_timestamp (priv->settings_connection,
		                                         (guint64) time (NULL), TRUE);
	}

	if (priv->device) {
		if (   old_state < NM_ACTIVE_CONNECTION_STATE_ACTIVATED
		    && new_state >= NM_ACTIVE_CONNECTION_STATE_ACTIVATED &&
		    priv->pending_activation_id)
		{
			nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE);
			g_clear_pointer (&priv->pending_activation_id, g_free);
		}
	}

	if (   new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
	    || old_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
		_notify (self, PROP_IP4_CONFIG);
		_notify (self, PROP_DHCP4_CONFIG);
		_notify (self, PROP_IP6_CONFIG);
		_notify (self, PROP_DHCP6_CONFIG);
	}

	if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
		/* Device is no longer relevant when deactivated. So remove it and
		 * emit property change notification so clients re-read the value,
		 * which will be NULL due to conditions in get_property().
		 */
		_device_cleanup (self);
		_notify (self, PROP_DEVICES);
	}
}
void
nm_active_connection_set_assumed (NMActiveConnection *self, gboolean assumed)
{
	NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);

	g_return_if_fail (priv->assumed == FALSE);
	priv->assumed = assumed;

	if (priv->pending_activation_id) {
		nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE);
		g_clear_pointer (&priv->pending_activation_id, g_free);
	}
}
static void
device_added_cb (NMManager *manager, NMDevice *other, gpointer user_data)
{
	NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data);
	NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);

	if (!priv->companion && check_companion (self, other)) {
		nm_device_state_changed (NM_DEVICE (self),
		                         NM_DEVICE_STATE_DISCONNECTED,
		                         NM_DEVICE_STATE_REASON_NONE);
		nm_device_remove_pending_action (NM_DEVICE (self), "waiting for companion", TRUE);
	}
}
static void
_device_cleanup (NMActiveConnection *self)
{
	NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);

	if (priv->device) {
		g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_state_changed), self);
		g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_master_changed), self);
		g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_metered_changed), self);
	}

	if (priv->pending_activation_id) {
		nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE);
		g_clear_pointer (&priv->pending_activation_id, g_free);
	}

	g_clear_object (&priv->device);
}
static void
find_companion (NMDeviceOlpcMesh *self)
{
	NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
	const GSList *list;

	if (priv->companion)
		return;

	nm_device_add_pending_action (NM_DEVICE (self), "waiting for companion", TRUE);

	/* Try to find the companion if it's already known to the NMManager */
	for (list = nm_manager_get_devices (nm_manager_get ()); list ; list = g_slist_next (list)) {
		if (check_companion (self, NM_DEVICE (list->data))) {
			nm_device_queue_state (NM_DEVICE (self),
			                       NM_DEVICE_STATE_DISCONNECTED,
			                       NM_DEVICE_STATE_REASON_NONE);
			nm_device_remove_pending_action (NM_DEVICE (self), "waiting for companion", TRUE);
			break;
		}
	}
}