Example #1
0
static void gas_query_start_cb(struct wpa_radio_work *work, int deinit)
{
	struct gas_query_pending *query = work->ctx;
	struct gas_query *gas = query->gas;
	struct wpa_supplicant *wpa_s = gas->wpa_s;

	if (deinit) {
		if (work->started) {
			gas->work = NULL;
			gas_query_done(gas, query, GAS_QUERY_DELETED_AT_DEINIT);
			return;
		}

		gas_query_free(query, 1);
		return;
	}

	if (wpas_update_random_addr_disassoc(wpa_s) < 0) {
		wpa_msg(wpa_s, MSG_INFO,
			"Failed to assign random MAC address for GAS");
		gas_query_free(query, 1);
		radio_work_done(work);
		return;
	}

	gas->work = work;
	gas_query_tx_initial_req(gas, query);
}
Example #2
0
static void gas_query_start_cb(struct wpa_radio_work *work, int deinit)
{
	struct gas_query_pending *query = work->ctx;
	struct gas_query *gas = query->gas;

	if (deinit) {
		if (work->started) {
			gas->work = NULL;
			gas_query_done(gas, query, GAS_QUERY_DELETED_AT_DEINIT);
			return;
		}

		gas_query_free(query, 1);
		return;
	}

	gas->work = work;

	if (gas_query_tx(gas, query, query->req) < 0) {
		wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to "
			   MACSTR, MAC2STR(query->addr));
		gas_query_free(query, 1);
		return;
	}
	gas->current = query;

	wpa_printf(MSG_DEBUG, "GAS: Starting query timeout for dialog token %u",
		   query->dialog_token);
	eloop_register_timeout(GAS_QUERY_TIMEOUT_PERIOD, 0,
			       gas_query_timeout, gas, query);

}
static void gas_query_start_cb(struct wpa_radio_work *work, int deinit)
{
	struct gas_query_pending *query = work->ctx;
	struct gas_query *gas = query->gas;
	struct wpa_supplicant *wpa_s = gas->wpa_s;

	if (deinit) {
		if (work->started) {
			gas->work = NULL;
			gas_query_done(gas, query, GAS_QUERY_DELETED_AT_DEINIT);
			return;
		}

		gas_query_free(query, 1);
		return;
	}

	if (wpas_update_random_addr_disassoc(wpa_s) < 0) {
		wpa_msg(wpa_s, MSG_INFO,
			"Failed to assign random MAC address for GAS");
		gas_query_free(query, 1);
		radio_work_done(work);
		return;
	}

	gas->work = work;

	if (gas_query_tx(gas, query, query->req) < 0) {
		wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to "
			   MACSTR, MAC2STR(query->addr));
		gas_query_free(query, 1);
		return;
	}
	gas->current = query;

	wpa_printf(MSG_DEBUG, "GAS: Starting query timeout for dialog token %u",
		   query->dialog_token);
	eloop_register_timeout(GAS_QUERY_TIMEOUT_PERIOD, 0,
			       gas_query_timeout, gas, query);

}
Example #4
0
/**
 * gas_query_req - Request a GAS query
 * @gas: GAS query data from gas_query_init()
 * @dst: Destination MAC address for the query
 * @freq: Frequency (in MHz) for the channel on which to send the query
 * @req: GAS query payload (to be freed by gas_query module in case of success
 *	return)
 * @cb: Callback function for reporting GAS query result and response
 * @ctx: Context pointer to use with the @cb call
 * Returns: dialog token (>= 0) on success or -1 on failure
 */
int gas_query_req(struct gas_query *gas, const u8 *dst, int freq,
		  struct wpabuf *req,
		  void (*cb)(void *ctx, const u8 *dst, u8 dialog_token,
			     enum gas_query_result result,
			     const struct wpabuf *adv_proto,
			     const struct wpabuf *resp, u16 status_code),
		  void *ctx)
{
	struct gas_query_pending *query;
	int dialog_token;
	static int next_start = 0;

	if (wpabuf_len(req) < 3)
		return -1;

	for (dialog_token = 0; dialog_token < 256; dialog_token++) {
		if (gas_query_dialog_token_available(
			    gas, dst, (next_start + dialog_token) % 256))
			break;
	}
	if (dialog_token == 256)
		return -1; /* Too many pending queries */
	dialog_token = (next_start + dialog_token) % 256;
	next_start = (dialog_token + 1) % 256;

	query = os_zalloc(sizeof(*query));
	if (query == NULL)
		return -1;

	query->gas = gas;
	os_memcpy(query->addr, dst, ETH_ALEN);
	query->dialog_token = dialog_token;
	query->freq = freq;
	query->cb = cb;
	query->ctx = ctx;
	query->req = req;
	dl_list_add(&gas->pending, &query->list);

	*(wpabuf_mhead_u8(req) + 2) = dialog_token;

	wpa_msg(gas->wpa_s, MSG_INFO, GAS_QUERY_START "addr=" MACSTR
		" dialog_token=%u freq=%d",
		MAC2STR(query->addr), query->dialog_token, query->freq);

	if (radio_add_work(gas->wpa_s, freq, "gas-query", 0, gas_query_start_cb,
			   query) < 0) {
		gas_query_free(query, 1);
		return -1;
	}

	return dialog_token;
}
Example #5
0
/**
 * gas_query_req - Request a GAS query
 * @gas: GAS query data from gas_query_init()
 * @dst: Destination MAC address for the query
 * @freq: Frequency (in MHz) for the channel on which to send the query
 * @req: GAS query payload (to be freed by gas_query module in case of success
 *	return)
 * @cb: Callback function for reporting GAS query result and response
 * @ctx: Context pointer to use with the @cb call
 * Returns: dialog token (>= 0) on success or -1 on failure
 */
int gas_query_req(struct gas_query *gas, const u8 *dst, int freq,
		  struct wpabuf *req,
		  void (*cb)(void *ctx, const u8 *dst, u8 dialog_token,
			     enum gas_query_result result,
			     const struct wpabuf *adv_proto,
			     const struct wpabuf *resp, u16 status_code),
		  void *ctx)
{
	struct gas_query_pending *query;
	int dialog_token;

	if (wpabuf_len(req) < 3)
		return -1;

	dialog_token = gas_query_new_dialog_token(gas, dst);
	if (dialog_token < 0)
		return -1;

	query = os_zalloc(sizeof(*query));
	if (query == NULL)
		return -1;

	query->gas = gas;
	os_memcpy(query->addr, dst, ETH_ALEN);
	query->dialog_token = dialog_token;
	query->freq = freq;
	query->cb = cb;
	query->ctx = ctx;
	query->req = req;
	dl_list_add(&gas->pending, &query->list);

	*(wpabuf_mhead_u8(req) + 2) = dialog_token;

	wpa_msg(gas->wpa_s, MSG_INFO, GAS_QUERY_START "addr=" MACSTR
		" dialog_token=%u freq=%d",
		MAC2STR(query->addr), query->dialog_token, query->freq);

	if (radio_add_work(gas->wpa_s, freq, "gas-query", 0, gas_query_start_cb,
			   query) < 0) {
		query->req = NULL; /* caller will free this in error case */
		gas_query_free(query, 1);
		return -1;
	}

	return dialog_token;
}
Example #6
0
static void gas_query_tx_initial_req(struct gas_query *gas,
				     struct gas_query_pending *query)
{
	if (gas_query_tx(gas, query, query->req,
			 GAS_QUERY_WAIT_TIME_INITIAL) < 0) {
		wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to "
			   MACSTR, MAC2STR(query->addr));
		gas_query_free(query, 1);
		return;
	}
	gas->current = query;

	wpa_printf(MSG_DEBUG, "GAS: Starting query timeout for dialog token %u",
		   query->dialog_token);
	eloop_register_timeout(GAS_QUERY_TIMEOUT_PERIOD, 0,
			       gas_query_timeout, gas, query);
}
Example #7
0
static void gas_query_done(struct gas_query *gas,
			   struct gas_query_pending *query,
			   enum gas_query_result result)
{
	wpa_msg(gas->wpa_s, MSG_INFO, GAS_QUERY_DONE "addr=" MACSTR
		" dialog_token=%u freq=%d status_code=%u result=%s",
		MAC2STR(query->addr), query->dialog_token, query->freq,
		query->status_code, gas_result_txt(result));
	if (gas->current == query)
		gas->current = NULL;
	if (query->offchannel_tx_started)
		offchannel_send_action_done(gas->wpa_s);
	eloop_cancel_timeout(gas_query_tx_comeback_timeout, gas, query);
	eloop_cancel_timeout(gas_query_timeout, gas, query);
	dl_list_del(&query->list);
	query->cb(query->ctx, query->addr, query->dialog_token, result,
		  query->adv_proto, query->resp, query->status_code);
	gas_query_free(query, 0);
}