| 
									
										
										
										
											2008-09-09 14:49:03 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * spectrum management | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi> | 
					
						
							|  |  |  |  * Copyright 2002-2005, Instant802 Networks, Inc. | 
					
						
							|  |  |  |  * Copyright 2005-2006, Devicescape Software, Inc. | 
					
						
							|  |  |  |  * Copyright 2006-2007  Jiri Benc <jbenc@suse.cz> | 
					
						
							|  |  |  |  * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 
					
						
							|  |  |  |  * Copyright 2007-2008, Intel Corporation | 
					
						
							|  |  |  |  * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License version 2 as | 
					
						
							|  |  |  |  * published by the Free Software Foundation. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/ieee80211.h>
 | 
					
						
							| 
									
										
										
										
											2009-04-20 14:31:42 +02:00
										 |  |  | #include <net/cfg80211.h>
 | 
					
						
							| 
									
										
										
										
											2008-09-09 14:49:03 +02:00
										 |  |  | #include <net/mac80211.h>
 | 
					
						
							|  |  |  | #include "ieee80211_i.h"
 | 
					
						
							|  |  |  | #include "sta_info.h"
 | 
					
						
							|  |  |  | #include "wme.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata, | 
					
						
							|  |  |  | 					struct ieee80211_msrment_ie *request_ie, | 
					
						
							|  |  |  | 					const u8 *da, const u8 *bssid, | 
					
						
							|  |  |  | 					u8 dialog_token) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ieee80211_local *local = sdata->local; | 
					
						
							|  |  |  | 	struct sk_buff *skb; | 
					
						
							|  |  |  | 	struct ieee80211_mgmt *msr_report; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom + | 
					
						
							|  |  |  | 				sizeof(struct ieee80211_msrment_ie)); | 
					
						
							| 
									
										
										
										
											2011-08-29 14:17:31 -07:00
										 |  |  | 	if (!skb) | 
					
						
							| 
									
										
										
										
											2008-09-09 14:49:03 +02:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	skb_reserve(skb, local->hw.extra_tx_headroom); | 
					
						
							|  |  |  | 	msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24); | 
					
						
							|  |  |  | 	memset(msr_report, 0, 24); | 
					
						
							|  |  |  | 	memcpy(msr_report->da, da, ETH_ALEN); | 
					
						
							| 
									
										
										
										
											2009-11-25 17:46:19 +01:00
										 |  |  | 	memcpy(msr_report->sa, sdata->vif.addr, ETH_ALEN); | 
					
						
							| 
									
										
										
										
											2008-09-09 14:49:03 +02:00
										 |  |  | 	memcpy(msr_report->bssid, bssid, ETH_ALEN); | 
					
						
							|  |  |  | 	msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 
					
						
							|  |  |  | 						IEEE80211_STYPE_ACTION); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement)); | 
					
						
							|  |  |  | 	msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; | 
					
						
							|  |  |  | 	msr_report->u.action.u.measurement.action_code = | 
					
						
							|  |  |  | 				WLAN_ACTION_SPCT_MSR_RPRT; | 
					
						
							|  |  |  | 	msr_report->u.action.u.measurement.dialog_token = dialog_token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT; | 
					
						
							|  |  |  | 	msr_report->u.action.u.measurement.length = | 
					
						
							|  |  |  | 			sizeof(struct ieee80211_msrment_ie); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memset(&msr_report->u.action.u.measurement.msr_elem, 0, | 
					
						
							|  |  |  | 		sizeof(struct ieee80211_msrment_ie)); | 
					
						
							|  |  |  | 	msr_report->u.action.u.measurement.msr_elem.token = request_ie->token; | 
					
						
							|  |  |  | 	msr_report->u.action.u.measurement.msr_elem.mode |= | 
					
						
							|  |  |  | 			IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED; | 
					
						
							|  |  |  | 	msr_report->u.action.u.measurement.msr_elem.type = request_ie->type; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-18 18:42:05 +01:00
										 |  |  | 	ieee80211_tx_skb(sdata, skb); | 
					
						
							| 
									
										
										
										
											2008-09-09 14:49:03 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, | 
					
						
							|  |  |  | 				       struct ieee80211_mgmt *mgmt, | 
					
						
							|  |  |  | 				       size_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Ignoring measurement request is spec violation. | 
					
						
							|  |  |  | 	 * Mandatory measurements must be reported optional | 
					
						
							|  |  |  | 	 * measurements might be refused or reported incapable | 
					
						
							|  |  |  | 	 * For now just refuse | 
					
						
							|  |  |  | 	 * TODO: Answer basic measurement as unmeasured | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	ieee80211_send_refuse_measurement_request(sdata, | 
					
						
							|  |  |  | 			&mgmt->u.action.u.measurement.msr_elem, | 
					
						
							|  |  |  | 			mgmt->sa, mgmt->bssid, | 
					
						
							|  |  |  | 			mgmt->u.action.u.measurement.dialog_token); | 
					
						
							|  |  |  | } |