static gboolean
update_availability (NMDeviceWimax *self, gboolean old_available)
{
	NMDevice *device = NM_DEVICE (self);
	NMDeviceState state;
	gboolean new_available, changed = FALSE;

	new_available = nm_device_is_available (device);
	if (new_available == old_available)
		return FALSE;

	state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self));
	if (state == NM_DEVICE_STATE_UNAVAILABLE) {
		if (new_available == TRUE) {
			nm_device_state_changed (device,
			                         NM_DEVICE_STATE_DISCONNECTED,
			                         NM_DEVICE_STATE_REASON_NONE);
			changed = TRUE;
		}
	} else if (state >= NM_DEVICE_STATE_DISCONNECTED) {
		if (new_available == FALSE) {
			nm_device_state_changed (device,
			                         NM_DEVICE_STATE_UNAVAILABLE,
			                         NM_DEVICE_STATE_REASON_NONE);
			changed = TRUE;
		}
	}

	return changed;
}
static void
modem_ip4_config_result (NMModem *self,
                         const char *iface,
                         NMIP4Config *config,
                         GError *error,
                         gpointer user_data)
{
	NMDevice *device = NM_DEVICE (user_data);
	NMDeviceState state;

	state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
	g_return_if_fail (state == NM_DEVICE_STATE_IP_CONFIG);

	if (error) {
		nm_log_warn (LOGD_MB | LOGD_IP4, "retrieving IP4 configuration failed: (%d) %s",
		             error ? error->code : -1,
		             error && error->message ? error->message : "(unknown)");

		nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
	} else {
		if (iface)
			nm_device_set_ip_iface (device, iface);

		nm_device_activate_schedule_stage4_ip4_config_get (device);
	}
}
예제 #3
0
static void
schedule_activate_check (NMPolicy *policy, NMDevice *device, guint delay_seconds)
{
	ActivateData *data;
	GSList *iter;
	NMDeviceState state;

	if (nm_manager_get_state (policy->manager) == NM_STATE_ASLEEP)
		return;

	state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
	if (state < NM_DEVICE_STATE_DISCONNECTED)
		return;

	if (!nm_device_autoconnect_allowed (device))
		return;

	for (iter = policy->pending_activation_checks; iter; iter = g_slist_next (iter)) {
		/* Only one pending activation check at a time */
		if (((ActivateData *) iter->data)->device == device)
			return;
	}

	data = g_malloc0 (sizeof (ActivateData));
	g_return_if_fail (data != NULL);

	data->policy = policy;
	data->device = g_object_ref (device);
	data->id = delay_seconds ? g_timeout_add_seconds (delay_seconds, auto_activate_device, data) : g_idle_add (auto_activate_device, data);
	policy->pending_activation_checks = g_slist_append (policy->pending_activation_checks, data);
}
예제 #4
0
static void
modem_prepare_result (NMModem *modem,
                      gboolean success,
                      NMDeviceStateReason reason,
                      gpointer user_data)
{
	NMDevice *device = NM_DEVICE (user_data);
	NMDeviceState state;

	state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
	g_return_if_fail (state == NM_DEVICE_STATE_CONFIG || state == NM_DEVICE_STATE_NEED_AUTH);

	if (success) {
		NMActRequest *req;
		NMActStageReturn ret;
		NMDeviceStateReason stage2_reason = NM_DEVICE_STATE_REASON_NONE;

		req = nm_device_get_act_request (device);
		g_assert (req);

		ret = nm_modem_act_stage2_config (modem, req, &stage2_reason);
		switch (ret) {
		case NM_ACT_STAGE_RETURN_POSTPONE:
			break;
		case NM_ACT_STAGE_RETURN_SUCCESS:
			nm_device_activate_schedule_stage3_ip_config_start (device);
			break;
		case NM_ACT_STAGE_RETURN_FAILURE:
		default:
			nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, stage2_reason);
			break;
		}
	} else
		nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
}
static void
modem_prepare_result (NMModem *modem,
                      gboolean success,
                      NMDeviceStateReason reason,
                      gpointer user_data)
{
	NMDevice *device = NM_DEVICE (user_data);
	NMDeviceState state;

	state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
	g_return_if_fail (state == NM_DEVICE_STATE_PREPARE);

	if (success)
		nm_device_activate_schedule_stage2_device_config (device);
	else
		nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
}
static void
wmx_connect_result_cb (struct wmxsdk *wmxsdk,
                       WIMAX_API_NETWORK_CONNECTION_RESP result,
                       void *user_data)
{
	NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
	NMDeviceState state;

	state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self));
	if (IS_ACTIVATING_STATE (state)) {
		priv->connect_failed = (result == WIMAX_API_CONNECTION_SUCCESS);
		/* Wait for the state change so we can get the reason code; we
		 * cache the connect failure so we don't have to wait for the
		 * activation timeout.
		 */
	}
}
static void
wmx_media_status_cb (struct wmxsdk *wmxsdk,
                     WIMAX_API_MEDIA_STATUS new_status,
                     void *user_data)
{
	NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
	NMDeviceState state;
	const char *iface;

	iface = nm_device_get_iface (NM_DEVICE (self));
	state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self));

	nm_log_dbg (LOGD_WIMAX, "(%s): media status change to %s",
	            iface, iwmx_sdk_media_status_to_str (new_status));

	/* We only care about media events while activated */
	if (state != NM_DEVICE_STATE_ACTIVATED)
		return;

	clear_link_timeout (self);

	switch (new_status) {
	case WIMAX_API_MEDIA_STATUS_LINK_UP:
		break;
	case WIMAX_API_MEDIA_STATUS_LINK_DOWN:
		nm_log_dbg (LOGD_WIMAX, "(%s): starting link timeout", iface);
		priv->link_timeout_id = g_timeout_add (15, link_timeout_cb, self);
		break;
	case WIMAX_API_MEDIA_STATUS_LINK_RENEW:
		nm_log_dbg (LOGD_WIMAX, "(%s): renewing DHCP lease", iface);
		if (!nm_device_dhcp4_renew (NM_DEVICE (self), TRUE)) {
			nm_device_state_changed (NM_DEVICE (self),
			                         NM_DEVICE_STATE_FAILED,
			                         NM_DEVICE_STATE_REASON_DHCP_FAILED);
		}
		break;
	default:
		nm_log_err (LOGD_WIMAX, "(%s): unhandled media status %d", iface, new_status);
		break;
	}
}
static void
real_set_enabled (NMDeviceInterface *device, gboolean enabled)
{
	NMDeviceModem *self = NM_DEVICE_MODEM (device);
	NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self);
	NMDeviceState state;

	if (priv->modem) {
		nm_modem_set_mm_enabled (priv->modem, enabled);

		if (enabled == FALSE) {
			state = nm_device_interface_get_state (device);
			if (state == NM_DEVICE_STATE_ACTIVATED) {
				nm_device_state_changed (NM_DEVICE (device),
				                         NM_DEVICE_STATE_DISCONNECTED,
				                         NM_DEVICE_STATE_REASON_NONE);
			}
		}
	}
}
static void
ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
{
	NMDevice *device = NM_DEVICE (user_data);

	switch (nm_device_interface_get_state (NM_DEVICE_INTERFACE (device))) {
	case NM_DEVICE_STATE_PREPARE:
	case NM_DEVICE_STATE_CONFIG:
	case NM_DEVICE_STATE_NEED_AUTH:
	case NM_DEVICE_STATE_ACTIVATED:
		nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
		break;
	case NM_DEVICE_STATE_IP_CONFIG:
		if (nm_device_ip_config_should_fail (device, FALSE)) {
			nm_device_state_changed (device,
			                         NM_DEVICE_STATE_FAILED,
			                         NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
		}
		break;
	default:
		break;
	}
}
static void
wmx_state_change_cb (struct wmxsdk *wmxsdk,
                     WIMAX_API_DEVICE_STATUS new_status,
                     WIMAX_API_DEVICE_STATUS old_status,
                     WIMAX_API_STATUS_REASON reason,
                     void *user_data)
{
	NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
	NMDeviceState state;
	const char *iface;
	gboolean old_available = FALSE;
	const char *nsp_name = NULL;

	if (new_status == old_status)
		return;

	iface = nm_device_get_iface (NM_DEVICE (self));
	state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self));
	old_available = nm_device_is_available (NM_DEVICE (self));

	priv->status = new_status;
	if (priv->current_nsp)
		nsp_name = nm_wimax_nsp_get_name (priv->current_nsp);

	nm_log_dbg (LOGD_WIMAX, "(%s): wimax state change %s -> %s (reason %d)",
	            iface,
	            iwmx_sdk_dev_status_to_str (old_status),
	            iwmx_sdk_dev_status_to_str (new_status),
	            reason);

	switch (new_status) {
	case WIMAX_API_DEVICE_STATUS_UnInitialized:
	case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
	case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
	case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
		if (priv->wimaxd_enabled) {
			priv->wimaxd_enabled = FALSE;
			if (update_availability (self, old_available))
				return;
		}
		break;
	case WIMAX_API_DEVICE_STATUS_Connecting:
	case WIMAX_API_DEVICE_STATUS_Data_Connected:
		/* If for some reason we're initially connected, force a disconnect here */
		if (state < NM_DEVICE_STATE_DISCONNECTED)
			force_disconnect (self, wmxsdk);
		/* Fall through */
	case WIMAX_API_DEVICE_STATUS_Ready:
	case WIMAX_API_DEVICE_STATUS_Scanning:
		if (priv->wimaxd_enabled == FALSE) {
			priv->wimaxd_enabled = TRUE;
			if (update_availability (self, old_available))
				return;
		}
		break;
	default:
		nm_log_warn (LOGD_WIMAX, "(%s): unhandled WiMAX device state %d",
		             iface, new_status);
		break;
	}

	/* Handle activation success and failure */
	if (IS_ACTIVATING_STATE (state)) {
	    if (new_status == WIMAX_API_DEVICE_STATUS_Data_Connected) {
			/* Success */
			clear_activation_timeout (self);

			nm_log_info (LOGD_WIMAX, "(%s): connected to '%s'",
			             iface, nsp_name);
			nm_device_activate_schedule_stage3_ip_config_start (NM_DEVICE (self));
			return;
		}

		if (priv->connect_failed) {
			/* Connection attempt failed */
			nm_log_info (LOGD_WIMAX, "(%s): connection to '%s' failed: (%d) %s",
			             iface, nsp_name, reason, iwmx_sdk_reason_to_str (reason));
			nm_device_state_changed (NM_DEVICE (self),
			                         NM_DEVICE_STATE_FAILED,
			                         NM_DEVICE_STATE_REASON_CONFIG_FAILED);
			return;
		}
	}

	/* Handle disconnection */
	if (state == NM_DEVICE_STATE_ACTIVATED) {
		if (   old_status == WIMAX_API_DEVICE_STATUS_Data_Connected
			&& new_status < WIMAX_API_DEVICE_STATUS_Connecting) {

			nm_log_info (LOGD_WIMAX, "(%s): disconnected from '%s': (%d) %s",
				         iface, nsp_name, reason, iwmx_sdk_reason_to_str (reason));

			nm_device_state_changed (NM_DEVICE (self),
				                     NM_DEVICE_STATE_FAILED,
				                     NM_DEVICE_STATE_REASON_CONFIG_FAILED);
		}
	}
}
예제 #11
0
gboolean
nm_device_bt_modem_added (NMDeviceBt *self,
                          NMModem *modem,
                          const char *driver)
{
	NMDeviceBtPrivate *priv;
	const char *modem_iface;
	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_iface = nm_modem_get_iface (modem);
	g_return_val_if_fail (modem_iface != NULL, FALSE);

	if (!priv->rfcomm_iface)
		return FALSE;

	base = g_path_get_basename (priv->rfcomm_iface);
	if (strcmp (base, modem_iface)) {
		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_interface_get_state (NM_DEVICE_INTERFACE (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_NEED_AUTH, G_CALLBACK (modem_need_auth), 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;
}