Browse Source

atheros: Generate EVENT_TX_STATUS events for management frames

This is needed for DPP functionality.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Ashok Kumar Ponnaiah 7 years ago
parent
commit
3d9dd4b772
1 changed files with 43 additions and 0 deletions
  1. 43 0
      src/drivers/driver_atheros.c

+ 43 - 0
src/drivers/driver_atheros.c

@@ -1352,6 +1352,40 @@ atheros_wireless_event_wireless_custom(struct atheros_driver_data *drv,
 	}
 }
 
+
+static void send_action_cb_event(struct atheros_driver_data *drv,
+				 char *data, size_t data_len)
+{
+	union wpa_event_data event;
+	struct ieee80211_send_action_cb *sa;
+	const struct ieee80211_hdr *hdr;
+	u16 fc;
+
+	if (data_len < sizeof(*sa) + 24) {
+		wpa_printf(MSG_DEBUG,
+			   "athr: Too short event message (data_len=%d sizeof(*sa)=%d)",
+			   (int) data_len, (int) sizeof(*sa));
+		wpa_hexdump(MSG_DEBUG, "athr: Short event message",
+			    data, data_len);
+		return;
+	}
+
+	sa = (struct ieee80211_send_action_cb *) data;
+
+	hdr = (const struct ieee80211_hdr *) (sa + 1);
+	fc = le_to_host16(hdr->frame_control);
+
+	os_memset(&event, 0, sizeof(event));
+	event.tx_status.type = WLAN_FC_GET_TYPE(fc);
+	event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
+	event.tx_status.dst = sa->dst_addr;
+	event.tx_status.data = (const u8 *) hdr;
+	event.tx_status.data_len = data_len - sizeof(*sa);
+	event.tx_status.ack = sa->ack;
+	wpa_supplicant_event(drv->hapd, EVENT_TX_STATUS, &event);
+}
+
+
 /*
 * Handle size of data problem. WEXT only allows data of 256 bytes for custom
 * events, and p2p data can be much bigger. So the athr driver sends a small
@@ -1416,6 +1450,11 @@ static void fetch_pending_big_events(struct atheros_driver_data *drv)
 						     &event);
 				continue;
 			}
+		} else if (frame_type == IEEE80211_EV_P2P_SEND_ACTION_CB) {
+			wpa_printf(MSG_DEBUG,
+				   "%s: ACTION_CB frame_type=%u len=%zu",
+				   __func__, frame_type, data_len);
+			send_action_cb_event(drv, (void *) mgmt, data_len);
 		} else {
 			wpa_printf(MSG_DEBUG, "athr: %s unknown type %d",
 				   __func__, frame_type);
@@ -1429,6 +1468,10 @@ atheros_wireless_event_atheros_custom(struct atheros_driver_data *drv,
 				      int opcode, char *buf, int len)
 {
 	switch (opcode) {
+	case IEEE80211_EV_P2P_SEND_ACTION_CB:
+		wpa_printf(MSG_DEBUG, "WEXT: EV_P2P_SEND_ACTION_CB");
+		fetch_pending_big_events(drv);
+		break;
 	case IEEE80211_EV_RX_MGMT:
 		wpa_printf(MSG_DEBUG, "WEXT: EV_RX_MGMT");
 		fetch_pending_big_events(drv);