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> 18 #include <net/cfg80211.h> 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)); 35 36 if (!skb) { 37 printk(KERN_ERR "%s: failed to allocate buffer for " 38 "measurement report frame\n", sdata->dev->name); 39 return; 40 } 41 42 skb_reserve(skb, local->hw.extra_tx_headroom); 43 msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24); 44 memset(msr_report, 0, 24); 45 memcpy(msr_report->da, da, ETH_ALEN); 46 memcpy(msr_report->sa, sdata->dev->dev_addr, ETH_ALEN); 47 memcpy(msr_report->bssid, bssid, ETH_ALEN); 48 msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 49 IEEE80211_STYPE_ACTION); 50 51 skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement)); 52 msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; 53 msr_report->u.action.u.measurement.action_code = 54 WLAN_ACTION_SPCT_MSR_RPRT; 55 msr_report->u.action.u.measurement.dialog_token = dialog_token; 56 57 msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT; 58 msr_report->u.action.u.measurement.length = 59 sizeof(struct ieee80211_msrment_ie); 60 61 memset(&msr_report->u.action.u.measurement.msr_elem, 0, 62 sizeof(struct ieee80211_msrment_ie)); 63 msr_report->u.action.u.measurement.msr_elem.token = request_ie->token; 64 msr_report->u.action.u.measurement.msr_elem.mode |= 65 IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED; 66 msr_report->u.action.u.measurement.msr_elem.type = request_ie->type; 67 68 ieee80211_tx_skb(sdata, skb); 69 } 70 71 void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, 72 struct ieee80211_mgmt *mgmt, 73 size_t len) 74 { 75 /* 76 * Ignoring measurement request is spec violation. 77 * Mandatory measurements must be reported optional 78 * measurements might be refused or reported incapable 79 * For now just refuse 80 * TODO: Answer basic measurement as unmeasured 81 */ 82 ieee80211_send_refuse_measurement_request(sdata, 83 &mgmt->u.action.u.measurement.msr_elem, 84 mgmt->sa, mgmt->bssid, 85 mgmt->u.action.u.measurement.dialog_token); 86 } 87