Commit | Line | Data |
---|---|---|
5449c685 FB |
1 | /* |
2 | * Copyright (c) 1996, 2005 VIA Networking Technologies, Inc. | |
3 | * All rights reserved. | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation; either version 2 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License along | |
16 | * with this program; if not, write to the Free Software Foundation, Inc., | |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 | * | |
19 | * | |
20 | * File: IEEE11h.c | |
21 | * | |
22 | * Purpose: | |
23 | * | |
24 | * Functions: | |
25 | * | |
26 | * Revision History: | |
27 | * | |
28 | * Author: Yiching Chen | |
29 | * | |
30 | * Date: Mar. 31, 2005 | |
31 | * | |
32 | */ | |
33 | ||
5449c685 | 34 | #include "ttype.h" |
5449c685 | 35 | #include "tmacro.h" |
5449c685 | 36 | #include "tether.h" |
5449c685 | 37 | #include "IEEE11h.h" |
5449c685 | 38 | #include "device.h" |
5449c685 | 39 | #include "wmgr.h" |
5449c685 | 40 | #include "rxtx.h" |
5449c685 FB |
41 | |
42 | /*--------------------- Static Definitions -------------------------*/ | |
43 | static int msglevel =MSG_LEVEL_INFO; | |
44 | ||
45 | #pragma pack(1) | |
46 | ||
47 | typedef struct _WLAN_FRAME_ACTION { | |
48 | WLAN_80211HDR_A3 Header; | |
49 | BYTE byCategory; | |
50 | BYTE byAction; | |
51 | BYTE abyVars[1]; | |
52 | } WLAN_FRAME_ACTION, *PWLAN_FRAME_ACTION; | |
53 | ||
54 | typedef struct _WLAN_FRAME_MSRREQ { | |
55 | WLAN_80211HDR_A3 Header; | |
56 | BYTE byCategory; | |
57 | BYTE byAction; | |
58 | BYTE byDialogToken; | |
59 | WLAN_IE_MEASURE_REQ sMSRReqEIDs[1]; | |
60 | } WLAN_FRAME_MSRREQ, *PWLAN_FRAME_MSRREQ; | |
61 | ||
62 | typedef struct _WLAN_FRAME_MSRREP { | |
63 | WLAN_80211HDR_A3 Header; | |
64 | BYTE byCategory; | |
65 | BYTE byAction; | |
66 | BYTE byDialogToken; | |
67 | WLAN_IE_MEASURE_REP sMSRRepEIDs[1]; | |
68 | } WLAN_FRAME_MSRREP, *PWLAN_FRAME_MSRREP; | |
69 | ||
70 | typedef struct _WLAN_FRAME_TPCREQ { | |
71 | WLAN_80211HDR_A3 Header; | |
72 | BYTE byCategory; | |
73 | BYTE byAction; | |
74 | BYTE byDialogToken; | |
75 | WLAN_IE_TPC_REQ sTPCReqEIDs; | |
76 | } WLAN_FRAME_TPCREQ, *PWLAN_FRAME_TPCREQ; | |
77 | ||
78 | typedef struct _WLAN_FRAME_TPCREP { | |
79 | WLAN_80211HDR_A3 Header; | |
80 | BYTE byCategory; | |
81 | BYTE byAction; | |
82 | BYTE byDialogToken; | |
83 | WLAN_IE_TPC_REP sTPCRepEIDs; | |
84 | } WLAN_FRAME_TPCREP, *PWLAN_FRAME_TPCREP; | |
85 | ||
86 | #pragma pack() | |
87 | ||
88 | // action field reference ieee 802.11h Table 20e | |
89 | #define ACTION_MSRREQ 0 | |
90 | #define ACTION_MSRREP 1 | |
91 | #define ACTION_TPCREQ 2 | |
92 | #define ACTION_TPCREP 3 | |
93 | #define ACTION_CHSW 4 | |
94 | ||
95 | /*--------------------- Static Classes ----------------------------*/ | |
96 | ||
97 | /*--------------------- Static Variables --------------------------*/ | |
98 | ||
99 | /*--------------------- Static Functions --------------------------*/ | |
100 | static BOOL s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq, UINT uLength) | |
101 | { | |
db6cb903 | 102 | size_t uNumOfEIDs = 0; |
5449c685 FB |
103 | BOOL bResult = TRUE; |
104 | ||
105 | if (uLength <= WLAN_A3FR_MAXLEN) { | |
51b6d9c2 | 106 | memcpy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength); |
5449c685 | 107 | } |
db6cb903 | 108 | uNumOfEIDs = ((uLength - offsetof(WLAN_FRAME_MSRREQ, sMSRReqEIDs))/ (sizeof(WLAN_IE_MEASURE_REQ))); |
5449c685 FB |
109 | pMgmt->pCurrMeasureEIDRep = &(((PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep))->sMSRRepEIDs[0]); |
110 | pMgmt->uLengthOfRepEIDs = 0; | |
111 | bResult = CARDbStartMeasure(pMgmt->pAdapter, | |
112 | ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->sMSRReqEIDs, | |
113 | uNumOfEIDs | |
114 | ); | |
115 | return (bResult); | |
116 | } | |
117 | ||
118 | ||
119 | static BOOL s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, BYTE byRate, BYTE byRSSI) | |
120 | { | |
121 | PWLAN_FRAME_TPCREP pFrame; | |
122 | PSTxMgmtPacket pTxPacket = NULL; | |
123 | ||
124 | ||
125 | pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; | |
126 | memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN); | |
127 | pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket)); | |
128 | ||
129 | pFrame = (PWLAN_FRAME_TPCREP)((PBYTE)pTxPacket + sizeof(STxMgmtPacket)); | |
130 | ||
131 | pFrame->Header.wFrameCtl = ( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | | |
132 | WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) | |
133 | ); | |
134 | ||
51b6d9c2 JL |
135 | memcpy( pFrame->Header.abyAddr1, pTPCReq->Header.abyAddr2, WLAN_ADDR_LEN); |
136 | memcpy( pFrame->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN); | |
137 | memcpy( pFrame->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); | |
5449c685 FB |
138 | |
139 | pFrame->byCategory = 0; | |
140 | pFrame->byAction = 3; | |
141 | pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken; | |
142 | ||
143 | pFrame->sTPCRepEIDs.byElementID = WLAN_EID_TPC_REP; | |
144 | pFrame->sTPCRepEIDs.len = 2; | |
145 | pFrame->sTPCRepEIDs.byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter); | |
146 | switch (byRate) { | |
147 | case RATE_54M: | |
148 | pFrame->sTPCRepEIDs.byLinkMargin = 65 - byRSSI; | |
149 | break; | |
150 | case RATE_48M: | |
151 | pFrame->sTPCRepEIDs.byLinkMargin = 66 - byRSSI; | |
152 | break; | |
153 | case RATE_36M: | |
154 | pFrame->sTPCRepEIDs.byLinkMargin = 70 - byRSSI; | |
155 | break; | |
156 | case RATE_24M: | |
157 | pFrame->sTPCRepEIDs.byLinkMargin = 74 - byRSSI; | |
158 | break; | |
159 | case RATE_18M: | |
160 | pFrame->sTPCRepEIDs.byLinkMargin = 77 - byRSSI; | |
161 | break; | |
162 | case RATE_12M: | |
163 | pFrame->sTPCRepEIDs.byLinkMargin = 79 - byRSSI; | |
164 | break; | |
165 | case RATE_9M: | |
166 | pFrame->sTPCRepEIDs.byLinkMargin = 81 - byRSSI; | |
167 | break; | |
168 | case RATE_6M: | |
169 | default: | |
170 | pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI; | |
171 | break; | |
172 | } | |
173 | ||
174 | pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP); | |
175 | pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) - WLAN_HDR_ADDR3_LEN; | |
176 | if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING) | |
177 | return (FALSE); | |
178 | return (TRUE); | |
179 | // return (CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG, sizeof(WLAN_FRAME_TPCREP))); | |
180 | ||
181 | } | |
182 | ||
183 | ||
184 | /*--------------------- Export Variables --------------------------*/ | |
185 | ||
186 | /*--------------------- Export Functions --------------------------*/ | |
187 | ||
188 | ||
189 | /*+ | |
190 | * | |
191 | * Description: | |
192 | * Handles action management frames. | |
193 | * | |
194 | * Parameters: | |
195 | * In: | |
196 | * pMgmt - Management Object structure | |
197 | * pRxPacket - Received packet | |
198 | * Out: | |
199 | * none | |
200 | * | |
201 | * Return Value: None. | |
202 | * | |
203 | -*/ | |
204 | BOOL | |
205 | IEEE11hbMgrRxAction ( | |
3a215e0f CC |
206 | void *pMgmtHandle, |
207 | void *pRxPacket | |
5449c685 FB |
208 | ) |
209 | { | |
210 | PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; | |
211 | PWLAN_FRAME_ACTION pAction = NULL; | |
212 | UINT uLength = 0; | |
213 | PWLAN_IE_CH_SW pChannelSwitch = NULL; | |
214 | ||
215 | ||
216 | // decode the frame | |
217 | uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen; | |
218 | if (uLength > WLAN_A3FR_MAXLEN) { | |
219 | return (FALSE); | |
220 | } | |
221 | ||
222 | ||
223 | pAction = (PWLAN_FRAME_ACTION) (((PSRxMgmtPacket)pRxPacket)->p80211Header); | |
224 | ||
225 | if (pAction->byCategory == 0) { | |
226 | switch (pAction->byAction) { | |
227 | case ACTION_MSRREQ: | |
228 | return (s_bRxMSRReq(pMgmt, (PWLAN_FRAME_MSRREQ) pAction, uLength)); | |
229 | break; | |
230 | case ACTION_MSRREP: | |
231 | break; | |
232 | case ACTION_TPCREQ: | |
233 | return (s_bRxTPCReq(pMgmt, | |
234 | (PWLAN_FRAME_TPCREQ) pAction, | |
235 | ((PSRxMgmtPacket)pRxPacket)->byRxRate, | |
236 | (BYTE) ((PSRxMgmtPacket)pRxPacket)->uRSSI)); | |
237 | break; | |
238 | case ACTION_TPCREP: | |
239 | break; | |
240 | case ACTION_CHSW: | |
241 | pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars); | |
242 | if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH) && | |
243 | (pChannelSwitch->len == 3)) { | |
244 | // valid element id | |
245 | CARDbChannelSwitch( pMgmt->pAdapter, | |
246 | pChannelSwitch->byMode, | |
247 | CARDbyGetChannelMapping(pMgmt->pAdapter, pChannelSwitch->byChannel, pMgmt->eCurrentPHYMode), | |
248 | pChannelSwitch->byCount | |
249 | ); | |
250 | } | |
251 | break; | |
252 | default: | |
7e809a9b | 253 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Action = %d\n", pAction->byAction); |
5449c685 FB |
254 | break; |
255 | } | |
256 | } else { | |
7e809a9b | 257 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n", pAction->byCategory); |
5449c685 FB |
258 | pAction->byCategory |= 0x80; |
259 | ||
260 | //return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG, uLength)); | |
261 | return (TRUE); | |
262 | } | |
263 | return (TRUE); | |
264 | } | |
265 | ||
266 | ||
267 | BOOL IEEE11hbMSRRepTx ( | |
3a215e0f | 268 | void *pMgmtHandle |
5449c685 FB |
269 | ) |
270 | { | |
271 | PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; | |
272 | PWLAN_FRAME_MSRREP pMSRRep = (PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket)); | |
db6cb903 | 273 | size_t uLength = 0; |
5449c685 FB |
274 | PSTxMgmtPacket pTxPacket = NULL; |
275 | ||
276 | pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep; | |
277 | memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN); | |
278 | pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket)); | |
279 | ||
280 | ||
281 | pMSRRep->Header.wFrameCtl = ( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | | |
282 | WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) | |
283 | ); | |
284 | ||
51b6d9c2 JL |
285 | memcpy( pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN); |
286 | memcpy( pMSRRep->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN); | |
287 | memcpy( pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); | |
5449c685 FB |
288 | |
289 | pMSRRep->byCategory = 0; | |
290 | pMSRRep->byAction = 1; | |
291 | pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken; | |
292 | ||
db6cb903 | 293 | uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP, sMSRRepEIDs); |
5449c685 FB |
294 | |
295 | pTxPacket->cbMPDULen = uLength; | |
296 | pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN; | |
297 | if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING) | |
298 | return (FALSE); | |
299 | return (TRUE); | |
300 | // return (CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG, uLength)); | |
301 | ||
302 | } | |
303 |