Add no_cck parameter for send_action() driver_ops
authorJouni Malinen <j@w1.fi>
Sat, 29 Oct 2011 18:49:46 +0000 (21:49 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 29 Oct 2011 18:49:46 +0000 (21:49 +0300)
This can be used to apply the no-CCK rule conditionally depending on
which frame is being sent. The no-CCK rule applies only for P2P
management frames while SA Query and FT use cases do not have similar
restrictions.

Signed-hostap: Jouni Malinen <j@w1.fi>

src/drivers/driver.h
src/drivers/driver_nl80211.c
src/drivers/driver_test.c
wpa_supplicant/driver_i.h
wpa_supplicant/gas_query.c
wpa_supplicant/offchannel.c
wpa_supplicant/offchannel.h
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant_i.h

index a41d890..4a9be35 100644 (file)
@@ -1862,6 +1862,7 @@ struct wpa_driver_ops {
         * @bssid: BSSID (Address 3)
         * @data: Frame body
         * @data_len: data length in octets
+        @ @no_cck: Whether CCK rates must not be used to transmit this frame
         * Returns: 0 on success, -1 on failure
         *
         * This command can be used to request the driver to transmit an action
@@ -1879,7 +1880,7 @@ struct wpa_driver_ops {
         */
        int (*send_action)(void *priv, unsigned int freq, unsigned int wait,
                           const u8 *dst, const u8 *src, const u8 *bssid,
-                          const u8 *data, size_t data_len);
+                          const u8 *data, size_t data_len, int no_cck);
 
        /**
         * send_action_cancel_wait - Cancel action frame TX wait
index de9d532..f22e847 100644 (file)
@@ -266,7 +266,8 @@ static void nl80211_remove_monitor_interface(
        struct wpa_driver_nl80211_data *drv);
 static int nl80211_send_frame_cmd(struct wpa_driver_nl80211_data *drv,
                                  unsigned int freq, unsigned int wait,
-                                 const u8 *buf, size_t buf_len, u64 *cookie);
+                                 const u8 *buf, size_t buf_len, u64 *cookie,
+                                 int no_cck);
 static int wpa_driver_nl80211_probe_req_report(void *priv, int report);
 
 #ifdef HOSTAPD
@@ -4140,12 +4141,12 @@ static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
                 * of wpa_supplicant.
                 */
                return nl80211_send_frame_cmd(drv, drv->last_mgmt_freq, 0,
-                                             data, data_len, NULL);
+                                             data, data_len, NULL, 1);
        }
 
        if (drv->no_monitor_iface_capab && is_ap_interface(drv->nlmode)) {
                return nl80211_send_frame_cmd(drv, drv->ap_oper_freq, 0,
-                                             data, data_len, NULL);
+                                             data, data_len, NULL, 0);
        }
 
        if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
@@ -6743,7 +6744,7 @@ static int cookie_handler(struct nl_msg *msg, void *arg)
 static int nl80211_send_frame_cmd(struct wpa_driver_nl80211_data *drv,
                                  unsigned int freq, unsigned int wait,
                                  const u8 *buf, size_t buf_len,
-                                 u64 *cookie_out)
+                                 u64 *cookie_out, int no_cck)
 {
        struct nl_msg *msg;
        u64 cookie;
@@ -6760,7 +6761,8 @@ static int nl80211_send_frame_cmd(struct wpa_driver_nl80211_data *drv,
        if (wait)
                NLA_PUT_U32(msg, NL80211_ATTR_DURATION, wait);
        NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
-       NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
+       if (no_cck)
+               NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
 
        NLA_PUT(msg, NL80211_ATTR_FRAME, buf_len, buf);
 
@@ -6789,7 +6791,8 @@ static int wpa_driver_nl80211_send_action(void *priv, unsigned int freq,
                                          unsigned int wait_time,
                                          const u8 *dst, const u8 *src,
                                          const u8 *bssid,
-                                         const u8 *data, size_t data_len)
+                                         const u8 *data, size_t data_len,
+                                         int no_cck)
 {
        struct i802_bss *bss = priv;
        struct wpa_driver_nl80211_data *drv = bss->drv;
@@ -6798,7 +6801,7 @@ static int wpa_driver_nl80211_send_action(void *priv, unsigned int freq,
        struct ieee80211_hdr *hdr;
 
        wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
-                  "wait=%d ms)", drv->ifindex, wait_time);
+                  "wait=%d ms no_cck=%d)", drv->ifindex, wait_time, no_cck);
 
        buf = os_zalloc(24 + data_len);
        if (buf == NULL)
@@ -6816,7 +6819,8 @@ static int wpa_driver_nl80211_send_action(void *priv, unsigned int freq,
        else
                ret = nl80211_send_frame_cmd(drv, freq, wait_time, buf,
                                             24 + data_len,
-                                            &drv->send_action_cookie);
+                                            &drv->send_action_cookie,
+                                            no_cck);
 
        os_free(buf);
        return ret;
@@ -7086,7 +7090,7 @@ static int nl80211_send_ft_action(void *priv, u8 action, const u8 *target_ap,
 
        ret = wpa_driver_nl80211_send_action(bss, drv->assoc_freq, 0,
                                             drv->bssid, own_addr, drv->bssid,
-                                            data, data_len);
+                                            data, data_len, 0);
        os_free(data);
 
        return ret;
index 3e8e7a6..4b3d00f 100644 (file)
@@ -116,6 +116,7 @@ struct wpa_driver_test_data {
        u8 pending_action_dst[ETH_ALEN];
        u8 pending_action_bssid[ETH_ALEN];
        unsigned int pending_action_freq;
+       unsigned int pending_action_no_cck;
        unsigned int pending_listen_freq;
        unsigned int pending_listen_duration;
        int pending_p2p_scan;
@@ -2670,7 +2671,8 @@ static int wpa_driver_test_send_action(void *priv, unsigned int freq,
                                       unsigned int wait,
                                       const u8 *dst, const u8 *src,
                                       const u8 *bssid,
-                                      const u8 *data, size_t data_len)
+                                      const u8 *data, size_t data_len,
+                                      int no_cck)
 {
        struct test_driver_bss *dbss = priv;
        struct wpa_driver_test_data *drv = dbss->drv;
@@ -2730,7 +2732,8 @@ static void test_send_action_cb(void *eloop_ctx, void *timeout_ctx)
                                    drv->pending_action_src,
                                    drv->pending_action_bssid,
                                    wpabuf_head(drv->pending_action_tx),
-                                   wpabuf_len(drv->pending_action_tx));
+                                   wpabuf_len(drv->pending_action_tx),
+                                   drv->pending_action_no_cck);
 }
 #endif /* CONFIG_P2P */
 
@@ -3013,6 +3016,7 @@ static int test_send_action(void *ctx, unsigned int freq, const u8 *dst,
        os_memcpy(drv->pending_action_dst, dst, ETH_ALEN);
        os_memcpy(drv->pending_action_bssid, bssid, ETH_ALEN);
        drv->pending_action_freq = freq;
+       drv->pending_action_no_cck = 1;
 
        if (drv->off_channel_freq == freq) {
                /* Already on requested channel; send immediately */
index b5f4393..0363f4d 100644 (file)
@@ -352,12 +352,13 @@ static inline int wpa_drv_send_action(struct wpa_supplicant *wpa_s,
                                      unsigned int wait,
                                      const u8 *dst, const u8 *src,
                                      const u8 *bssid,
-                                     const u8 *data, size_t data_len)
+                                     const u8 *data, size_t data_len,
+                                     int no_cck)
 {
        if (wpa_s->driver->send_action)
                return wpa_s->driver->send_action(wpa_s->drv_priv, freq,
                                                  wait, dst, src, bssid,
-                                                 data, data_len);
+                                                 data, data_len, no_cck);
        return -1;
 }
 
index 1ac185a..3b736da 100644 (file)
@@ -138,7 +138,7 @@ static int gas_query_tx(struct gas_query *gas, struct gas_query_pending *query,
        res = offchannel_send_action(gas->wpa_s, query->freq, query->addr,
                                     gas->wpa_s->own_addr, query->addr,
                                     wpabuf_head(req), wpabuf_len(req), 1000,
-                                    NULL);
+                                    NULL, 0);
        if (res == 0)
                query->offchannel_tx_started = 1;
        return res;
index 8f8ef3a..790f14a 100644 (file)
@@ -120,7 +120,8 @@ static void wpas_send_action_cb(void *eloop_ctx, void *timeout_ctx)
                                  wpa_s->pending_action_src,
                                  wpa_s->pending_action_bssid,
                                  wpabuf_head(wpa_s->pending_action_tx),
-                                 wpabuf_len(wpa_s->pending_action_tx));
+                                 wpabuf_len(wpa_s->pending_action_tx),
+                                 wpa_s->pending_action_no_cck);
        if (res) {
                wpa_printf(MSG_DEBUG, "Off-channel: Failed to send the "
                           "pending Action frame");
@@ -177,7 +178,8 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq,
                                         const u8 *src, const u8 *bssid,
                                         const u8 *data, size_t data_len,
                                         enum offchannel_send_action_result
-                                        result))
+                                        result),
+                          int no_cck)
 {
        wpa_printf(MSG_DEBUG, "Off-channel: Send action frame: freq=%d dst="
                   MACSTR " src=" MACSTR " bssid=" MACSTR " len=%d",
@@ -204,6 +206,7 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq,
        os_memcpy(wpa_s->pending_action_dst, dst, ETH_ALEN);
        os_memcpy(wpa_s->pending_action_bssid, bssid, ETH_ALEN);
        wpa_s->pending_action_freq = freq;
+       wpa_s->pending_action_no_cck = no_cck;
 
        if (freq != 0 && wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) {
                struct wpa_supplicant *iface;
@@ -212,12 +215,13 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq,
                                              wpa_s->pending_action_src);
                wpa_s->action_tx_wait_time = wait_time;
 
-               return wpa_drv_send_action(iface, wpa_s->pending_action_freq,
-                                       wait_time, wpa_s->pending_action_dst,
-                                       wpa_s->pending_action_src,
-                                       wpa_s->pending_action_bssid,
-                                       wpabuf_head(wpa_s->pending_action_tx),
-                                       wpabuf_len(wpa_s->pending_action_tx));
+               return wpa_drv_send_action(
+                       iface, wpa_s->pending_action_freq,
+                       wait_time, wpa_s->pending_action_dst,
+                       wpa_s->pending_action_src, wpa_s->pending_action_bssid,
+                       wpabuf_head(wpa_s->pending_action_tx),
+                       wpabuf_len(wpa_s->pending_action_tx),
+                       wpa_s->pending_action_no_cck);
        }
 
        if (freq) {
index 90f79c1..60e0d03 100644 (file)
@@ -24,7 +24,8 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq,
                                         const u8 *src, const u8 *bssid,
                                         const u8 *data, size_t data_len,
                                         enum offchannel_send_action_result
-                                        result));
+                                        result),
+                          int no_cck);
 void offchannel_send_action_done(struct wpa_supplicant *wpa_s);
 void offchannel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
                                     unsigned int freq, unsigned int duration);
index 929d2fd..3eeb61e 100644 (file)
@@ -593,7 +593,7 @@ static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst,
        struct wpa_supplicant *wpa_s = ctx;
        return offchannel_send_action(wpa_s, freq, dst, src, bssid, buf, len,
                                      wait_time,
-                                     wpas_p2p_send_action_tx_status);
+                                     wpas_p2p_send_action_tx_status, 1);
 }
 
 
index cba8444..da689d2 100644 (file)
@@ -647,7 +647,7 @@ static void sme_send_sa_query_req(struct wpa_supplicant *wpa_s,
        os_memcpy(req + 2, trans_id, WLAN_SA_QUERY_TR_ID_LEN);
        if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
                                wpa_s->own_addr, wpa_s->bssid,
-                               req, sizeof(req)) < 0)
+                               req, sizeof(req), 0) < 0)
                wpa_msg(wpa_s, MSG_INFO, "SME: Failed to send SA Query "
                        "Request");
 }
index a11db03..3e6e5dd 100644 (file)
@@ -406,6 +406,7 @@ struct wpa_supplicant {
        u8 pending_action_dst[ETH_ALEN];
        u8 pending_action_bssid[ETH_ALEN];
        unsigned int pending_action_freq;
+       int pending_action_no_cck;
        int pending_action_without_roc;
        void (*pending_action_tx_status_cb)(struct wpa_supplicant *wpa_s,
                                            unsigned int freq, const u8 *dst,