/**
 * wpa_supplicant_dbus_notify_state_change - Send a state change signal
 * @wpa_s: %wpa_supplicant network interface data
 * @new_state: new state wpa_supplicant is entering
 * @old_state: old state wpa_supplicant is leaving
 * Returns: 0 on success, -1 on failure
 *
 * Notify listeners that wpa_supplicant has changed state
 */
void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
					     enum wpa_states new_state,
					     enum wpa_states old_state)
{
	struct wpas_dbus_priv *iface;
	DBusMessage *_signal = NULL;
	const char *new_state_str, *old_state_str;

	if (wpa_s->dbus_path == NULL)
		return; /* Skip signal since D-Bus setup is not yet ready */

	/* Do nothing if the control interface is not turned on */
	if (wpa_s->global == NULL)
		return;
	iface = wpa_s->global->dbus;
	if (iface == NULL)
		return;

	/* Only send signal if state really changed */
	if (new_state == old_state)
		return;

	_signal = dbus_message_new_signal(wpa_s->dbus_path,
					  WPAS_DBUS_IFACE_INTERFACE,
					  "StateChange");
	if (_signal == NULL) {
		wpa_printf(MSG_ERROR,
		           "dbus: wpa_supplicant_dbus_notify_state_change: "
		           "could not create dbus signal; likely out of "
		           "memory");
		return;
	}

	new_state_str = wpa_supplicant_state_txt(new_state);
	old_state_str = wpa_supplicant_state_txt(old_state);
	if (new_state_str == NULL || old_state_str == NULL) {
		wpa_printf(MSG_ERROR,
		           "dbus: wpa_supplicant_dbus_notify_state_change: "
		           "Could not convert state strings");
		goto out;
	}

	if (!dbus_message_append_args(_signal,
	                              DBUS_TYPE_STRING, &new_state_str,
	                              DBUS_TYPE_STRING, &old_state_str,
	                              DBUS_TYPE_INVALID)) {
		wpa_printf(MSG_ERROR,
		           "dbus: wpa_supplicant_dbus_notify_state_change: "
		           "Not enough memory to construct state change "
		           "signal");
		goto out;
	}

	dbus_connection_send(iface->con, _signal, NULL);

out:
	dbus_message_unref(_signal);
}
示例#2
0
/**
 * wpas_dbus_iface_get_state - Get interface state
 * @message: Pointer to incoming dbus message
 * @wpa_s: wpa_supplicant structure for a network interface
 * Returns: A dbus message containing a STRING representing the current
 *          interface state
 *
 * Handler function for "state" method call.
 */
DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
					struct wpa_supplicant *wpa_s)
{
	DBusMessage *reply = NULL;
	const char *str_state;

	reply = dbus_message_new_method_return(message);
	if (reply != NULL) {
		str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
		dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_state,
					 DBUS_TYPE_INVALID);
	}

	return reply;
}
示例#3
0
void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
			    struct wpa_bss *selected,
			    struct wpa_ssid *ssid)
{
	if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
		wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
			"PBC session overlap");
		wpa_supplicant_req_new_scan(wpa_s, 10, 0);
		return;
	}

	/*
	 * Do not trigger new association unless the BSSID has changed or if
	 * reassociation is requested. If we are in process of associating with
	 * the selected BSSID, do not trigger new attempt.
	 */
	if (wpa_s->reassociate ||
	    (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
	     ((wpa_s->wpa_state != WPA_ASSOCIATING &&
	       wpa_s->wpa_state != WPA_AUTHENTICATING) ||
	      os_memcmp(selected->bssid, wpa_s->pending_bssid, ETH_ALEN) !=
	      0))) {
		if (wpa_supplicant_scard_init(wpa_s, ssid)) {
			wpa_supplicant_req_new_scan(wpa_s, 10, 0);
			return;
		}
		wpa_msg(wpa_s, MSG_DEBUG, "Request association: "
			"reassociate: %d  selected: "MACSTR "  bssid: " MACSTR
			"  pending: " MACSTR "  wpa_state: %s",
			wpa_s->reassociate, MAC2STR(selected->bssid),
			MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
			wpa_supplicant_state_txt(wpa_s->wpa_state));
		wpa_supplicant_associate(wpa_s, selected, ssid);
	} else {
		wpa_printf(MSG_DEBUG, "Already associated with the selected "
			   "AP");
	}
}
示例#4
0
static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
					    const char *params,
					    char *buf, size_t buflen)
{
	char *pos, *end, tmp[30];
	int res, verbose, ret;

	verbose = os_strcmp(params, "-VERBOSE") == 0;
	pos = buf;
	end = buf + buflen;
	if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
		struct wpa_ssid *ssid = wpa_s->current_ssid;
		ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
				  MAC2STR(wpa_s->bssid));
		if (ret < 0 || ret >= end - pos)
			return pos - buf;
		pos += ret;
		if (ssid) {
			u8 *_ssid = ssid->ssid;
			size_t ssid_len = ssid->ssid_len;
			u8 ssid_buf[MAX_SSID_LEN];
			if (ssid_len == 0) {
				int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
				if (_res < 0)
					ssid_len = 0;
				else
					ssid_len = _res;
				_ssid = ssid_buf;
			}
			ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
					  wpa_ssid_txt(_ssid, ssid_len),
					  ssid->id);
			if (ret < 0 || ret >= end - pos)
				return pos - buf;
			pos += ret;

			if (ssid->id_str) {
				ret = os_snprintf(pos, end - pos,
						  "id_str=%s\n",
						  ssid->id_str);
				if (ret < 0 || ret >= end - pos)
					return pos - buf;
				pos += ret;
			}
		}

		pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
	}
	ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
			  wpa_supplicant_state_txt(wpa_s->wpa_state));
	if (ret < 0 || ret >= end - pos)
		return pos - buf;
	pos += ret;

	if (wpa_s->l2 &&
	    l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
		ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
		if (ret < 0 || ret >= end - pos)
			return pos - buf;
		pos += ret;
	}

	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
	    wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
		res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,
					  verbose);
		if (res >= 0)
			pos += res;
	}

	res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
	if (res >= 0)
		pos += res;

	return pos - buf;
}
示例#5
0
/**
 * wpa_supplicant_dbus_notify_state_change - Send a state change signal
 * @wpa_s: %wpa_supplicant network interface data
 * @new_state: new state wpa_supplicant is entering
 * @old_state: old state wpa_supplicant is leaving
 * Returns: 0 on success, -1 on failure
 *
 * Notify listeners that wpa_supplicant has changed state
 */
void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
					     wpa_states new_state,
					     wpa_states old_state)
{
	struct ctrl_iface_dbus_priv *iface;
	DBusMessage *_signal = NULL;
	const char *path;
	const char *new_state_str, *old_state_str;

	/* Do nothing if the control interface is not turned on */
	if (wpa_s->global == NULL)
		return;
	iface = wpa_s->global->dbus_ctrl_iface;
	if (iface == NULL)
		return;

	/* Only send signal if state really changed */
	if (new_state == old_state)
		return;

	path = wpa_supplicant_get_dbus_path(wpa_s);
	if (path == NULL) {
		perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
		       "interface didn't have a dbus path");
		wpa_printf(MSG_ERROR,
		           "wpa_supplicant_dbus_notify_state_change[dbus]: "
		           "interface didn't have a dbus path; can't send "
		           "signal.");
		return;
	}
	_signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE,
					  "StateChange");
	if (_signal == NULL) {
		perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
		       "couldn't create dbus signal; likely out of memory");
		wpa_printf(MSG_ERROR,
		           "wpa_supplicant_dbus_notify_state_change[dbus]: "
		           "couldn't create dbus signal; likely out of "
		           "memory.");
		return;
	}

	new_state_str = wpa_supplicant_state_txt(new_state);
	old_state_str = wpa_supplicant_state_txt(old_state);
	if (new_state_str == NULL || old_state_str == NULL) {
		perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
		       "couldn't convert state strings");
		wpa_printf(MSG_ERROR,
		           "wpa_supplicant_dbus_notify_state_change[dbus]: "
		           "couldn't convert state strings.");
		goto out;
	}

	if (!dbus_message_append_args(_signal,
	                              DBUS_TYPE_STRING, &new_state_str,
	                              DBUS_TYPE_STRING, &old_state_str,
	                              DBUS_TYPE_INVALID)) {
		perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
		       "not enough memory to construct state change signal.");
		wpa_printf(MSG_ERROR,
		           "wpa_supplicant_dbus_notify_state_change[dbus]: "
		           "not enough memory to construct state change "
		           "signal.");
		goto out;
	}

	dbus_connection_send(iface->con, _signal, NULL);

out:
	dbus_message_unref(_signal);
}