| Johannes Berg | 39192c0 | 2008-09-09 14:49:03 +0200 | [diff] [blame] | 1 | /* | 
|  | 2 | * spectrum management | 
|  | 3 | * | 
|  | 4 | * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi> | 
|  | 5 | * Copyright 2002-2005, Instant802 Networks, Inc. | 
|  | 6 | * Copyright 2005-2006, Devicescape Software, Inc. | 
|  | 7 | * Copyright 2006-2007  Jiri Benc <jbenc@suse.cz> | 
|  | 8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 
|  | 9 | * Copyright 2007-2008, Intel Corporation | 
|  | 10 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | 
|  | 11 | * | 
|  | 12 | * This program is free software; you can redistribute it and/or modify | 
|  | 13 | * it under the terms of the GNU General Public License version 2 as | 
|  | 14 | * published by the Free Software Foundation. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #include <linux/ieee80211.h> | 
| Johannes Berg | d323655 | 2009-04-20 14:31:42 +0200 | [diff] [blame] | 18 | #include <net/cfg80211.h> | 
| Johannes Berg | 39192c0 | 2008-09-09 14:49:03 +0200 | [diff] [blame] | 19 | #include <net/mac80211.h> | 
|  | 20 | #include "ieee80211_i.h" | 
|  | 21 | #include "sta_info.h" | 
|  | 22 | #include "wme.h" | 
|  | 23 |  | 
|  | 24 | static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata, | 
|  | 25 | struct ieee80211_msrment_ie *request_ie, | 
|  | 26 | const u8 *da, const u8 *bssid, | 
|  | 27 | u8 dialog_token) | 
|  | 28 | { | 
|  | 29 | struct ieee80211_local *local = sdata->local; | 
|  | 30 | struct sk_buff *skb; | 
|  | 31 | struct ieee80211_mgmt *msr_report; | 
|  | 32 |  | 
|  | 33 | skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom + | 
|  | 34 | sizeof(struct ieee80211_msrment_ie)); | 
| Joe Perches | d15b845 | 2011-08-29 14:17:31 -0700 | [diff] [blame] | 35 | if (!skb) | 
| Johannes Berg | 39192c0 | 2008-09-09 14:49:03 +0200 | [diff] [blame] | 36 | return; | 
| Johannes Berg | 39192c0 | 2008-09-09 14:49:03 +0200 | [diff] [blame] | 37 |  | 
|  | 38 | skb_reserve(skb, local->hw.extra_tx_headroom); | 
|  | 39 | msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24); | 
|  | 40 | memset(msr_report, 0, 24); | 
|  | 41 | memcpy(msr_report->da, da, ETH_ALEN); | 
| Johannes Berg | 47846c9 | 2009-11-25 17:46:19 +0100 | [diff] [blame] | 42 | memcpy(msr_report->sa, sdata->vif.addr, ETH_ALEN); | 
| Johannes Berg | 39192c0 | 2008-09-09 14:49:03 +0200 | [diff] [blame] | 43 | memcpy(msr_report->bssid, bssid, ETH_ALEN); | 
|  | 44 | msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 
|  | 45 | IEEE80211_STYPE_ACTION); | 
|  | 46 |  | 
|  | 47 | skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement)); | 
|  | 48 | msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; | 
|  | 49 | msr_report->u.action.u.measurement.action_code = | 
|  | 50 | WLAN_ACTION_SPCT_MSR_RPRT; | 
|  | 51 | msr_report->u.action.u.measurement.dialog_token = dialog_token; | 
|  | 52 |  | 
|  | 53 | msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT; | 
|  | 54 | msr_report->u.action.u.measurement.length = | 
|  | 55 | sizeof(struct ieee80211_msrment_ie); | 
|  | 56 |  | 
|  | 57 | memset(&msr_report->u.action.u.measurement.msr_elem, 0, | 
|  | 58 | sizeof(struct ieee80211_msrment_ie)); | 
|  | 59 | msr_report->u.action.u.measurement.msr_elem.token = request_ie->token; | 
|  | 60 | msr_report->u.action.u.measurement.msr_elem.mode |= | 
|  | 61 | IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED; | 
|  | 62 | msr_report->u.action.u.measurement.msr_elem.type = request_ie->type; | 
|  | 63 |  | 
| Johannes Berg | 62ae67b | 2009-11-18 18:42:05 +0100 | [diff] [blame] | 64 | ieee80211_tx_skb(sdata, skb); | 
| Johannes Berg | 39192c0 | 2008-09-09 14:49:03 +0200 | [diff] [blame] | 65 | } | 
|  | 66 |  | 
|  | 67 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, | 
|  | 68 | struct ieee80211_mgmt *mgmt, | 
|  | 69 | size_t len) | 
|  | 70 | { | 
|  | 71 | /* | 
|  | 72 | * Ignoring measurement request is spec violation. | 
|  | 73 | * Mandatory measurements must be reported optional | 
|  | 74 | * measurements might be refused or reported incapable | 
|  | 75 | * For now just refuse | 
|  | 76 | * TODO: Answer basic measurement as unmeasured | 
|  | 77 | */ | 
|  | 78 | ieee80211_send_refuse_measurement_request(sdata, | 
|  | 79 | &mgmt->u.action.u.measurement.msr_elem, | 
|  | 80 | mgmt->sa, mgmt->bssid, | 
|  | 81 | mgmt->u.action.u.measurement.dialog_token); | 
|  | 82 | } |