mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-25 17:59:25 +01:00
ap: Use frame-xchg when sending frames
Convert ap_send_mgmt_frame() to use frame_xchg_start for sending frames, this fixes among other things the ACK-received checks. One side effect is that we're no longer sending Probe Responses with the don't-wait-for-ack flag because frame-xchg doesn't support it, but other AP implementations don't use that flag either. Another side-effect is that we do use the no-cck-rate flag unconditionally, something we may want to fix but would need to add another parameter to frame-xchg.
This commit is contained in:
parent
311e91b944
commit
c51e187462
86
src/ap.c
86
src/ap.c
@ -543,36 +543,20 @@ static void ap_wsc_exit_pbc(struct ap_state *ap)
|
||||
|
||||
static uint32_t ap_send_mgmt_frame(struct ap_state *ap,
|
||||
const struct mmpdu_header *frame,
|
||||
size_t frame_len, bool wait_ack,
|
||||
l_genl_msg_func_t callback,
|
||||
size_t frame_len,
|
||||
frame_xchg_cb_t callback,
|
||||
void *user_data)
|
||||
{
|
||||
struct l_genl_msg *msg;
|
||||
uint32_t ifindex = netdev_get_ifindex(ap->netdev);
|
||||
uint32_t id;
|
||||
uint32_t ch_freq = scan_channel_to_freq(ap->config->channel,
|
||||
SCAN_BAND_2_4_GHZ);
|
||||
uint64_t wdev_id = netdev_get_wdev_id(ap->netdev);
|
||||
struct iovec iov[2];
|
||||
|
||||
msg = l_genl_msg_new_sized(NL80211_CMD_FRAME, 128 + frame_len);
|
||||
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &ifindex);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_WIPHY_FREQ, 4, &ch_freq);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_FRAME, frame_len, frame);
|
||||
if (!wait_ack)
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_DONT_WAIT_FOR_ACK,
|
||||
0, NULL);
|
||||
|
||||
if (ap->config->no_cck_rates)
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_TX_NO_CCK_RATE, 0,
|
||||
NULL);
|
||||
|
||||
|
||||
id = l_genl_family_send(ap->nl80211, msg, callback, user_data, NULL);
|
||||
|
||||
if (!id)
|
||||
l_genl_msg_unref(msg);
|
||||
|
||||
return id;
|
||||
iov[0].iov_base = (void *) frame;
|
||||
iov[0].iov_len = frame_len;
|
||||
iov[1].iov_base = NULL;
|
||||
return frame_xchg_start(wdev_id, iov, ch_freq, 0, 0, 0, 0,
|
||||
callback, user_data, NULL, NULL);
|
||||
}
|
||||
|
||||
static void ap_start_handshake(struct sta_state *sta, bool use_eapol_start)
|
||||
@ -1013,16 +997,19 @@ static bool ap_common_rates(struct l_uintset *ap_rates,
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ap_success_assoc_resp_cb(struct l_genl_msg *msg, void *user_data)
|
||||
static void ap_success_assoc_resp_cb(int err, void *user_data)
|
||||
{
|
||||
struct sta_state *sta = user_data;
|
||||
struct ap_state *ap = sta->ap;
|
||||
|
||||
sta->assoc_resp_cmd_id = 0;
|
||||
|
||||
if (l_genl_msg_get_error(msg) < 0) {
|
||||
l_error("AP (Re)Association Response not sent or not ACKed: %i",
|
||||
l_genl_msg_get_error(msg));
|
||||
if (err) {
|
||||
if (err == -ECOMM)
|
||||
l_error("AP (Re)Association Response received no ACK");
|
||||
else
|
||||
l_error("AP (Re)Association Response not sent %s (%i)",
|
||||
strerror(-err), -err);
|
||||
|
||||
/* If we were in State 3 or 4 go to back to State 2 */
|
||||
if (sta->associated)
|
||||
@ -1038,11 +1025,14 @@ static void ap_success_assoc_resp_cb(struct l_genl_msg *msg, void *user_data)
|
||||
l_info("AP (Re)Association Response ACK received");
|
||||
}
|
||||
|
||||
static void ap_fail_assoc_resp_cb(struct l_genl_msg *msg, void *user_data)
|
||||
static void ap_fail_assoc_resp_cb(int err, void *user_data)
|
||||
{
|
||||
if (l_genl_msg_get_error(msg) < 0)
|
||||
l_error("AP (Re)Association Response with an error status not "
|
||||
"sent or not ACKed: %i", l_genl_msg_get_error(msg));
|
||||
if (err == -ECOMM)
|
||||
l_error("AP (Re)Association Response with an error status "
|
||||
"received no ACK");
|
||||
else if (err)
|
||||
l_error("AP (Re)Association Response with an error status "
|
||||
"not sent: %s (%i)", strerror(-err), -err);
|
||||
else
|
||||
l_info("AP (Re)Association Response with an error status "
|
||||
"delivered OK");
|
||||
@ -1051,7 +1041,7 @@ static void ap_fail_assoc_resp_cb(struct l_genl_msg *msg, void *user_data)
|
||||
static uint32_t ap_assoc_resp(struct ap_state *ap, struct sta_state *sta,
|
||||
const uint8_t *dest,
|
||||
enum mmpdu_reason_code status_code,
|
||||
bool reassoc, l_genl_msg_func_t callback)
|
||||
bool reassoc, frame_xchg_cb_t callback)
|
||||
{
|
||||
const uint8_t *addr = netdev_get_address(ap->netdev);
|
||||
uint8_t mpdu_buf[128];
|
||||
@ -1132,7 +1122,7 @@ static uint32_t ap_assoc_resp(struct ap_state *ap, struct sta_state *sta,
|
||||
|
||||
send_frame:
|
||||
return ap_send_mgmt_frame(ap, mpdu, resp->ies + ies_len - mpdu_buf,
|
||||
true, callback, sta);
|
||||
callback, sta);
|
||||
}
|
||||
|
||||
static int ap_parse_supported_rates(struct ie_tlv_iter *iter,
|
||||
@ -1606,13 +1596,15 @@ static void ap_process_wsc_probe_req(struct ap_state *ap, const uint8_t *from,
|
||||
}
|
||||
}
|
||||
|
||||
static void ap_probe_resp_cb(struct l_genl_msg *msg, void *user_data)
|
||||
static void ap_probe_resp_cb(int err, void *user_data)
|
||||
{
|
||||
if (l_genl_msg_get_error(msg) < 0)
|
||||
l_error("AP Probe Response not sent: %i",
|
||||
l_genl_msg_get_error(msg));
|
||||
if (err == -ECOMM)
|
||||
l_error("AP Probe Response received no ACK");
|
||||
else if (err)
|
||||
l_error("AP Probe Response not sent: %s (%i)",
|
||||
strerror(-err), -err);
|
||||
else
|
||||
l_info("AP Probe Response sent OK");
|
||||
l_info("AP Probe Response delivered OK");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1723,7 +1715,7 @@ static void ap_probe_req_cb(const struct mmpdu_header *hdr, const void *body,
|
||||
hdr->address_2, resp, sizeof(resp));
|
||||
len += ap_build_beacon_pr_tail(ap, true, resp + len);
|
||||
|
||||
ap_send_mgmt_frame(ap, (struct mmpdu_header *) resp, len, false,
|
||||
ap_send_mgmt_frame(ap, (struct mmpdu_header *) resp, len,
|
||||
ap_probe_resp_cb, NULL);
|
||||
}
|
||||
|
||||
@ -1757,11 +1749,13 @@ static void ap_disassoc_cb(const struct mmpdu_header *hdr, const void *body,
|
||||
ap_del_station(sta, L_LE16_TO_CPU(disassoc->reason_code), true);
|
||||
}
|
||||
|
||||
static void ap_auth_reply_cb(struct l_genl_msg *msg, void *user_data)
|
||||
static void ap_auth_reply_cb(int err, void *user_data)
|
||||
{
|
||||
if (l_genl_msg_get_error(msg) < 0)
|
||||
l_error("AP Authentication frame 2 not sent or not ACKed: %i",
|
||||
l_genl_msg_get_error(msg));
|
||||
if (err == -ECOMM)
|
||||
l_error("AP Authentication frame 2 received no ACK");
|
||||
else if (err)
|
||||
l_error("AP Authentication frame 2 not sent: %s (%i)",
|
||||
strerror(-err), -err);
|
||||
else
|
||||
l_info("AP Authentication frame 2 ACKed by STA");
|
||||
}
|
||||
@ -1790,7 +1784,7 @@ static void ap_auth_reply(struct ap_state *ap, const uint8_t *dest,
|
||||
auth->transaction_sequence = L_CPU_TO_LE16(2);
|
||||
auth->status = L_CPU_TO_LE16(status_code);
|
||||
|
||||
ap_send_mgmt_frame(ap, mpdu, (uint8_t *) auth + 6 - mpdu_buf, true,
|
||||
ap_send_mgmt_frame(ap, mpdu, (uint8_t *) auth + 6 - mpdu_buf,
|
||||
ap_auth_reply_cb, NULL);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user