Browse Source

P2P: Fix Action frame processing if Interworking is enabled

GAS server used the same public_action_cb mechanism as P2P to process
Action frames. This ended up overriding P2P processing of Action frames
while running an AP/GO interface with a build that enables Interworking
(e.g., for Hotspot 2.0) and a driver that uses hostapd for AP mode
SME/MLME. Fix this by adding a separate callback registration for the
GAS server. This should really be cleaned up by supporting arbitrary
number of callback handlers, but for now, this addresses the regression
with a minimal change.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
Jouni Malinen 12 years ago
parent
commit
2d9ffe1e85
3 changed files with 12 additions and 3 deletions
  1. 2 2
      src/ap/gas_serv.c
  2. 3 0
      src/ap/hostapd.h
  3. 7 1
      src/ap/ieee802_11.c

+ 2 - 2
src/ap/gas_serv.c

@@ -1158,8 +1158,8 @@ static void gas_serv_rx_public_action(void *ctx, const u8 *buf, size_t len,
 
 int gas_serv_init(struct hostapd_data *hapd)
 {
-	hapd->public_action_cb = gas_serv_rx_public_action;
-	hapd->public_action_cb_ctx = hapd;
+	hapd->public_action_cb2 = gas_serv_rx_public_action;
+	hapd->public_action_cb2_ctx = hapd;
 	hapd->gas_frag_limit = 1400;
 	if (hapd->conf->gas_frag_limit > 0)
 		hapd->gas_frag_limit = hapd->conf->gas_frag_limit;

+ 3 - 0
src/ap/hostapd.h

@@ -151,6 +151,9 @@ struct hostapd_data {
 	void (*public_action_cb)(void *ctx, const u8 *buf, size_t len,
 				 int freq);
 	void *public_action_cb_ctx;
+	void (*public_action_cb2)(void *ctx, const u8 *buf, size_t len,
+				  int freq);
+	void *public_action_cb2_ctx;
 
 	int (*vendor_action_cb)(void *ctx, const u8 *buf, size_t len,
 				int freq);

+ 7 - 1
src/ap/ieee802_11.c

@@ -1599,8 +1599,14 @@ static void handle_action(struct hostapd_data *hapd,
 			hapd->public_action_cb(hapd->public_action_cb_ctx,
 					       (u8 *) mgmt, len,
 					       hapd->iface->freq);
-			return;
 		}
+		if (hapd->public_action_cb2) {
+			hapd->public_action_cb2(hapd->public_action_cb_ctx,
+						(u8 *) mgmt, len,
+						hapd->iface->freq);
+		}
+		if (hapd->public_action_cb || hapd->public_action_cb2)
+			return;
 		break;
 	case WLAN_ACTION_VENDOR_SPECIFIC:
 		if (hapd->vendor_action_cb) {