MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / wireless / rtlink / assoc.c
blob108f27070b11068cd0756580d52159bfcb0096eb
1 /*************************************************************************
2 * Ralink Tech Inc. *
3 * 4F, No. 2 Technology 5th Rd. *
4 * Science-based Industrial Park *
5 * Hsin-chu, Taiwan, R.O.C. *
6 * *
7 * (c) Copyright 2002, Ralink Technology, Inc. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23 * *
24 ************************************************************************/
26 #include "rt_config.h"
28 UCHAR CipherSuiteWpaTkip[] = {
29 0x00, 0x50, 0xf2, 0x01, // oui
30 0x01, 0x00, // Version
31 0x00, 0x50, 0xf2, 0x02, // Multicast
32 0x01, 0x00, // Number of unicast
33 0x00, 0x50, 0xf2, 0x02, // unicast
34 0x01, 0x00, // number of authentication method
35 0x00, 0x50, 0xf2, 0x01 // authentication
37 UCHAR CipherSuiteWpaTkipLen = (sizeof(CipherSuiteWpaTkip) / sizeof(UCHAR));
39 UCHAR CipherSuiteWpaAes[] = {
40 0x00, 0x50, 0xf2, 0x01, // oui
41 0x01, 0x00, // Version
42 0x00, 0x50, 0xf2, 0x04, // Multicast
43 0x01, 0x00, // Number of unicast
44 0x00, 0x50, 0xf2, 0x04, // unicast
45 0x01, 0x00, // number of authentication method
46 0x00, 0x50, 0xf2, 0x01 // authentication
48 UCHAR CipherSuiteWpaAesLen = (sizeof(CipherSuiteWpaAes) / sizeof(UCHAR));
50 UCHAR CipherSuiteWpaPskTkip[] = {
51 0x00, 0x50, 0xf2, 0x01, // oui
52 0x01, 0x00, // Version
53 0x00, 0x50, 0xf2, 0x02, // Multicast
54 0x01, 0x00, // Number of unicast
55 0x00, 0x50, 0xf2, 0x02, // unicast
56 0x01, 0x00, // number of authentication method
57 0x00, 0x50, 0xf2, 0x02 // authentication
59 UCHAR CipherSuiteWpaPskTkipLen = (sizeof(CipherSuiteWpaPskTkip) / sizeof(UCHAR));
61 UCHAR CipherSuiteWpaPskAes[] = {
62 0x00, 0x50, 0xf2, 0x01, // oui
63 0x01, 0x00, // Version
64 0x00, 0x50, 0xf2, 0x04, // Multicast
65 0x01, 0x00, // Number of unicast
66 0x00, 0x50, 0xf2, 0x04, // unicast
67 0x01, 0x00, // number of authentication method
68 0x00, 0x50, 0xf2, 0x02 // authentication
70 UCHAR CipherSuiteWpaPskAesLen = (sizeof(CipherSuiteWpaPskAes) / sizeof(UCHAR));
72 /*
73 ==========================================================================
74 Description:
75 association state machine init, including state transition and timer init
76 Parameters:
77 S - pointer to the association state machine
78 Note:
79 The state machine looks like the following
81 ASSOC_IDLE ASSOC_WAIT_RSP REASSOC_WAIT_RSP DISASSOC_WAIT_RSP
82 MT2_MLME_ASSOC_REQ mlme_assoc_req_action invalid_state_when_assoc invalid_state_when_assoc invalid_state_when_assoc
83 MT2_MLME_REASSOC_REQ mlme_reassoc_req_action invalid_state_when_reassoc invalid_state_when_reassoc invalid_state_when_reassoc
84 MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action mlme_disassoc_req_action mlme_disassoc_req_action mlme_disassoc_req_action
85 MT2_PEER_DISASSOC_REQ peer_disassoc_action peer_disassoc_action peer_disassoc_action peer_disassoc_action
86 MT2_PEER_ASSOC_REQ drop drop drop drop
87 MT2_PEER_ASSOC_RSP drop peer_assoc_rsp_action drop drop
88 MT2_PEER_REASSOC_REQ drop drop drop drop
89 MT2_PEER_REASSOC_RSP drop drop peer_reassoc_rsp_action drop
90 MT2_CLS3ERR cls3err_action cls3err_action cls3err_action cls3err_action
91 MT2_ASSOC_TIMEOUT timer_nop assoc_timeout_action timer_nop timer_nop
92 MT2_REASSOC_TIMEOUT timer_nop timer_nop reassoc_timeout_action timer_nop
93 MT2_DISASSOC_TIMEOUT timer_nop timer_nop timer_nop disassoc_timeout_action
94 ==========================================================================
96 VOID AssocStateMachineInit(
97 IN PRTMP_ADAPTER pAd,
98 IN STATE_MACHINE *S,
99 OUT STATE_MACHINE_FUNC Trans[])
101 StateMachineInit(S, (STATE_MACHINE_FUNC*)Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG, (STATE_MACHINE_FUNC)Drop, ASSOC_IDLE, ASSOC_MACHINE_BASE);
103 // first column
104 StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)MlmeAssocReqAction);
105 StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)MlmeReassocReqAction);
106 StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)MlmeDisassocReqAction);
107 StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
108 // StateMachineSetAction(S, ASSOC_IDLE, MT2_CLS3ERR, (STATE_MACHINE_FUNC)Cls3errAction);
110 // second column
111 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
112 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
113 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
114 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
115 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
116 // StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_CLS3ERR, (STATE_MACHINE_FUNC)Cls3errAction);
117 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT, (STATE_MACHINE_FUNC)AssocTimeoutAction);
119 // third column
120 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
121 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
122 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
123 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
124 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
125 // StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_CLS3ERR, (STATE_MACHINE_FUNC)Cls3errAction);
126 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT, (STATE_MACHINE_FUNC)ReassocTimeoutAction);
128 // fourth column
129 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
130 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
131 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
132 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
133 // StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_CLS3ERR, (STATE_MACHINE_FUNC)Cls3errAction);
134 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT, (STATE_MACHINE_FUNC)DisassocTimeoutAction);
136 // initialize the timer
137 RTMPInitTimer(pAd, &pAd->Mlme.AssocAux.AssocTimer, AssocTimeout);
138 RTMPInitTimer(pAd, &pAd->Mlme.AssocAux.ReassocTimer, ReassocTimeout);
139 RTMPInitTimer(pAd, &pAd->Mlme.AssocAux.DisassocTimer, DisassocTimeout);
143 ==========================================================================
144 Description:
145 Association timeout procedure. After association timeout, this function
146 will be called and it will put a message into the MLME queue
147 Parameters:
148 Standard timer parameters
149 ==========================================================================
151 VOID AssocTimeout(
152 IN unsigned long data)
154 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)data;
155 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - enqueue MT2_ASSOC_TIMEOUT \n");
156 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL);
157 MlmeHandler(pAd);
161 ==========================================================================
162 Description:
163 Reassociation timeout procedure. After reassociation timeout, this
164 function will be called and put a message into the MLME queue
165 Parameters:
166 Standard timer parameters
167 ==========================================================================
169 VOID ReassocTimeout(
170 IN unsigned long data)
172 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)data;
173 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - enqueue MT2_REASSOC_TIMEOUT \n");
174 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL);
175 MlmeHandler(pAd);
179 ==========================================================================
180 Description:
181 Disassociation timeout procedure. After disassociation timeout, this
182 function will be called and put a message into the MLME queue
183 Parameters:
184 Standard timer parameters
185 ==========================================================================
187 VOID DisassocTimeout(
188 IN unsigned long data)
190 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)data;
191 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - enqueue MT2_DISASSOC_TIMEOUT \n");
192 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL);
193 MlmeHandler(pAd);
197 ==========================================================================
198 Description:
199 mlme assoc req handling procedure
200 Parameters:
201 Adapter - Adapter pointer
202 Elem - MLME Queue Element
203 Pre:
204 the station has been authenticated and the following information is stored in the config
205 -# SSID
206 -# supported rates and their length
207 -# listen interval (Adapter->PortCfg.default_listen_count)
208 -# Transmit power (Adapter->PortCfg.tx_power)
209 Post :
210 -# An association request frame is generated and sent to the air
211 -# Association timer starts
212 -# Association state -> ASSOC_WAIT_RSP
213 ==========================================================================
215 VOID MlmeAssocReqAction(
216 IN PRTMP_ADAPTER pAd,
217 IN MLME_QUEUE_ELEM *Elem)
219 MACADDR ApAddr;
220 MACHDR AssocHdr;
221 UCHAR SsidIe = IE_SSID, RateIe = IE_SUPP_RATES,WpaIe = IE_WPA, ExtRateIe = IE_EXT_SUPP_RATES;
222 USHORT ListenIntv;
223 ULONG Timeout;
224 USHORT CapabilityInfo;
225 UCHAR *OutBuffer = NULL;
226 NDIS_STATUS NStatus;
227 ULONG FrameLen = 0;
228 ULONG tmp;
229 UCHAR VarIesOffset;
231 // Block all authentication request durning WPA block period
232 if (pAd->PortCfg.bBlockAssoc == TRUE)
234 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Block Assoc request durning WPA block period!\n");
235 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
236 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, MLME_STATE_MACHINE_REJECT);
238 // check sanity first
239 else if (MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, &ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
241 RTMPCancelTimer(&pAd->Mlme.AssocAux.AssocTimer);
242 COPY_MAC_ADDR(&pAd->Mlme.AssocAux.Addr, &ApAddr);
243 // Mask out unnecessary capability information
244 CapabilityInfo &= SUPPORTED_CAPABILITY_INFO; // pAd->PortCfg.SupportedCapabilityInfo;
245 pAd->Mlme.AssocAux.CapabilityInfo = CapabilityInfo;
246 pAd->Mlme.AssocAux.ListenIntv = ListenIntv;
248 NStatus = MlmeAllocateMemory(pAd, (PVOID)&OutBuffer); //Get an unused nonpaged memory
249 if (NStatus != NDIS_STATUS_SUCCESS)
251 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - MlmeAssocReqAction() allocate memory failed \n");
252 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
253 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, MLME_FAIL_NO_RESOURCE);
254 return;
257 // Add by James 03/06/27
258 pAd->PortCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); //+ sizeof(NDIS_802_11_FIXED_IEs); // Filled in assoc request
259 pAd->PortCfg.AssocInfo.AvailableRequestFixedIEs =
260 NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_LISTENINTERVAL | NDIS_802_11_AI_REQFI_CURRENTAPADDRESS;
261 pAd->PortCfg.AssocInfo.RequestFixedIEs.Capabilities = CapabilityInfo;
262 pAd->PortCfg.AssocInfo.RequestFixedIEs.ListenInterval = ListenIntv;
263 NdisMoveMemory(pAd->PortCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, &AssocHdr, sizeof(NDIS_802_11_MAC_ADDRESS));
264 pAd->PortCfg.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); // No request Variables IEs
266 // First add SSID
267 VarIesOffset = 0;
268 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &SsidIe, 1);
269 VarIesOffset += 1;
270 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &pAd->PortCfg.SsidLen, 1);
271 VarIesOffset += 1;
272 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, pAd->PortCfg.Ssid, pAd->PortCfg.SsidLen);
273 VarIesOffset += pAd->PortCfg.SsidLen;
275 // Second add Supported rates
276 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &RateIe, 1);
277 VarIesOffset += 1;
278 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &pAd->PortCfg.SupportedRatesLen, 1);
279 VarIesOffset += 1;
280 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, pAd->PortCfg.SupportedRates, pAd->PortCfg.SupportedRatesLen);
281 VarIesOffset += pAd->PortCfg.SupportedRatesLen;
282 // End Add by James
284 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Send ASSOC request...\n");
285 MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, &ApAddr, &ApAddr);
287 // Build basic frame first
288 MakeOutgoingFrame(OutBuffer, &FrameLen,
289 sizeof(MACHDR), &AssocHdr,
290 2, &CapabilityInfo,
291 2, &ListenIntv,
292 1, &SsidIe,
293 1, &pAd->PortCfg.SsidLen,
294 pAd->PortCfg.SsidLen, pAd->PortCfg.Ssid,
295 1, &RateIe,
296 1, &pAd->PortCfg.SupRateLen,
297 pAd->PortCfg.SupRateLen, pAd->PortCfg.SupRate,
298 END_OF_ARGS);
299 if (pAd->PortCfg.ExtRateLen != 0)
301 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp,
302 1, &ExtRateIe,
303 1, &pAd->PortCfg.ExtRateLen,
304 pAd->PortCfg.ExtRateLen, pAd->PortCfg.ExtRate,
305 END_OF_ARGS);
306 FrameLen += tmp;
309 if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA) && (pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled))
311 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp,
312 1, &WpaIe,
313 1, &CipherSuiteWpaTkipLen,
314 CipherSuiteWpaTkipLen, &CipherSuiteWpaTkip[0],
315 END_OF_ARGS);
316 FrameLen += tmp;
318 // Add by James 03/06/27
319 // Third add RSN
320 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &WpaIe, 1);
321 VarIesOffset += 1;
322 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &CipherSuiteWpaTkipLen, 1);
323 VarIesOffset += 1;
324 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, CipherSuiteWpaTkip, CipherSuiteWpaTkipLen);
325 VarIesOffset += CipherSuiteWpaTkipLen;
327 // Set Variable IEs Length
328 pAd->PortCfg.ReqVarIELen = VarIesOffset;
329 pAd->PortCfg.AssocInfo.RequestIELength = VarIesOffset;
331 // OffsetResponseIEs follow ReqVarIE
332 pAd->PortCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->PortCfg.ReqVarIELen;
333 // End Add by James
336 else if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA) && (pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled))
338 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp,
339 1, &WpaIe,
340 1, &CipherSuiteWpaAesLen,
341 CipherSuiteWpaAesLen, &CipherSuiteWpaAes[0],
342 END_OF_ARGS);
343 FrameLen += tmp;
345 // Add by James 03/06/27
346 // Third add RSN
347 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &WpaIe, 1);
348 VarIesOffset += 1;
349 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &CipherSuiteWpaAesLen, 1);
350 VarIesOffset += 1;
351 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, CipherSuiteWpaAes, CipherSuiteWpaAesLen);
352 VarIesOffset += CipherSuiteWpaAesLen;
354 // Set Variable IEs Length
355 pAd->PortCfg.ReqVarIELen = VarIesOffset;
356 pAd->PortCfg.AssocInfo.RequestIELength = VarIesOffset;
358 // OffsetResponseIEs follow ReqVarIE
359 pAd->PortCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->PortCfg.ReqVarIELen;
360 // End Add by James
362 else if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK) && (pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled))
364 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp,
365 1, &WpaIe,
366 1, &CipherSuiteWpaPskTkipLen,
367 CipherSuiteWpaPskTkipLen, &CipherSuiteWpaPskTkip[0],
368 END_OF_ARGS);
369 FrameLen += tmp;
371 // Add by James 03/06/27
372 // Third add RSN
373 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &WpaIe, 1);
374 VarIesOffset += 1;
375 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &CipherSuiteWpaPskTkipLen, 1);
376 VarIesOffset += 1;
377 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, CipherSuiteWpaPskTkip, CipherSuiteWpaPskTkipLen);
378 VarIesOffset += CipherSuiteWpaPskTkipLen;
380 // Set Variable IEs Length
381 pAd->PortCfg.ReqVarIELen = VarIesOffset;
382 pAd->PortCfg.AssocInfo.RequestIELength = VarIesOffset;
384 // OffsetResponseIEs follow ReqVarIE
385 pAd->PortCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->PortCfg.ReqVarIELen;
386 // End Add by James
388 else if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK) && (pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled))
390 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp,
391 1, &WpaIe,
392 1, &CipherSuiteWpaPskAesLen,
393 CipherSuiteWpaPskAesLen, &CipherSuiteWpaPskAes[0],
394 END_OF_ARGS);
395 FrameLen += tmp;
397 // Add by James 03/06/27
398 // Third add RSN
399 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &WpaIe, 1);
400 VarIesOffset += 1;
401 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &CipherSuiteWpaPskAesLen, 1);
402 VarIesOffset += 1;
403 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, CipherSuiteWpaPskAes, CipherSuiteWpaPskAesLen);
404 VarIesOffset += CipherSuiteWpaPskAesLen;
406 // Set Variable IEs Length
407 pAd->PortCfg.ReqVarIELen = VarIesOffset;
408 pAd->PortCfg.AssocInfo.RequestIELength = VarIesOffset;
410 // OffsetResponseIEs follow ReqVarIE
411 pAd->PortCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->PortCfg.ReqVarIELen;
412 // End Add by James
414 else
416 // Add by James 03/06/27
417 // Set Variable IEs Length
418 pAd->PortCfg.ReqVarIELen = VarIesOffset;
419 pAd->PortCfg.AssocInfo.RequestIELength = VarIesOffset;
421 // OffsetResponseIEs follow ReqVarIE
422 pAd->PortCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->PortCfg.ReqVarIELen;
423 // End Add by James
425 MiniportMMRequest(pAd, OutBuffer, FrameLen);
427 RTMPSetTimer(pAd, &pAd->Mlme.AssocAux.AssocTimer, Timeout);
428 pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP;
430 else
432 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - MlmeAssocReqAction() sanity check failed. BUG!!!!!! \n");
433 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
434 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, MLME_INVALID_FORMAT);
440 ==========================================================================
441 Description:
442 mlme reassoc req handling procedure
443 Parameters:
444 Elem -
445 Pre:
446 -# SSID (Adapter->PortCfg.ssid[])
447 -# BSSID (AP address, Adapter->PortCfg.bssid)
448 -# Supported rates (Adapter->PortCfg.supported_rates[])
449 -# Supported rates length (Adapter->PortCfg.supported_rates_len)
450 -# Tx power (Adapter->PortCfg.tx_power)
451 ==========================================================================
453 VOID MlmeReassocReqAction(
454 IN PRTMP_ADAPTER pAd,
455 IN MLME_QUEUE_ELEM *Elem)
457 MACADDR ApAddr;
458 MACHDR ReassocHdr;
459 UCHAR SsidIe = IE_SSID, RateIe = IE_SUPP_RATES, ExtRateIe = IE_EXT_SUPP_RATES;
460 USHORT CapabilityInfo, ListenIntv;
461 ULONG Timeout;
462 ULONG FrameLen = 0;
463 NDIS_STATUS NStatus;
464 ULONG tmp;
465 UCHAR *OutBuffer = NULL;
467 // Block all authentication request durning WPA block period
468 if (pAd->PortCfg.bBlockAssoc == TRUE)
470 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Block ReAssoc request durning WPA block period!\n");
471 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
472 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, MLME_STATE_MACHINE_REJECT);
474 // the parameters are the same as the association
475 else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, &ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
477 RTMPCancelTimer(&pAd->Mlme.AssocAux.ReassocTimer);
479 NStatus = MlmeAllocateMemory(pAd, (PVOID)&OutBuffer); //Get an unused nonpaged memory
480 if(NStatus != NDIS_STATUS_SUCCESS)
482 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - MlmeReassocReqAction() allocate memory failed \n");
483 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
484 MlmeCntlConfirm(pAd, MT2_REASSOC_CONF, MLME_FAIL_NO_RESOURCE);
485 return;
488 // Mask out unnecessary capability information
489 CapabilityInfo &= SUPPORTED_CAPABILITY_INFO; // pAd->PortCfg.SupportedCapabilityInfo;
490 pAd->Mlme.AssocAux.CapabilityInfo = CapabilityInfo;
491 COPY_MAC_ADDR(&pAd->Mlme.AssocAux.Addr, &ApAddr);
492 pAd->Mlme.AssocAux.ListenIntv = ListenIntv;
494 // make frame, use bssid as the AP address??
495 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Send RE-ASSOC request...\n");
496 MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0, &ApAddr, &ApAddr);
497 MakeOutgoingFrame(OutBuffer, &FrameLen,
498 sizeof(MACHDR), &ReassocHdr,
499 2, &CapabilityInfo,
500 2, &ListenIntv,
501 MAC_ADDR_LEN, &pAd->PortCfg.Bssid,
502 1, &SsidIe,
503 1, &pAd->PortCfg.SsidLen,
504 pAd->PortCfg.SsidLen, pAd->PortCfg.Ssid,
505 1, &RateIe,
506 1, &pAd->PortCfg.SupRateLen,
507 pAd->PortCfg.SupRateLen, pAd->PortCfg.SupRate,
508 END_OF_ARGS);
509 if (pAd->PortCfg.ExtRateLen != 0)
511 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp,
512 1, &ExtRateIe,
513 1, &pAd->PortCfg.ExtRateLen,
514 pAd->PortCfg.ExtRateLen, pAd->PortCfg.ExtRate,
515 END_OF_ARGS);
516 FrameLen += tmp;
518 MiniportMMRequest(pAd, OutBuffer, FrameLen);
520 RTMPSetTimer(pAd, &pAd->Mlme.AssocAux.ReassocTimer, Timeout); /* in mSec */
521 pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP;
523 else
525 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - MlmeReassocReqAction() sanity check failed. BUG!!!! \n");
526 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
527 MlmeCntlConfirm(pAd, MT2_REASSOC_CONF, MLME_INVALID_FORMAT);
532 ==========================================================================
533 Description:
534 Upper layer issues disassoc request
535 Parameters:
536 Elem -
537 ==========================================================================
539 VOID MlmeDisassocReqAction(
540 IN PRTMP_ADAPTER pAd,
541 IN MLME_QUEUE_ELEM *Elem)
543 MLME_DISASSOC_REQ_STRUCT *DisassocReq;
544 MACHDR DisassocHdr;
545 CHAR *OutBuffer = NULL;
546 ULONG FrameLen = 0;
547 NDIS_STATUS NStatus;
548 ULONG Timeout = 0;
550 // skip sanity check
551 DisassocReq = (MLME_DISASSOC_REQ_STRUCT *)(Elem->Msg);
553 NStatus = MlmeAllocateMemory(pAd, (PVOID)&OutBuffer); //Get an unused nonpaged memory
554 if (NStatus != NDIS_STATUS_SUCCESS)
556 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - MlmeDisassocReqAction() allocate memory failed\n");
557 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
558 MlmeCntlConfirm(pAd, MT2_DISASSOC_CONF, MLME_FAIL_NO_RESOURCE);
559 return;
562 RTMPCancelTimer(&pAd->Mlme.AssocAux.DisassocTimer);
564 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Send DISASSOC request\n");
565 MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, &pAd->PortCfg.Bssid, &pAd->PortCfg.Bssid);
566 MakeOutgoingFrame(OutBuffer, &FrameLen,
567 sizeof(MACHDR), &DisassocHdr,
568 2, &DisassocReq->Reason,
569 END_OF_ARGS);
570 MiniportMMRequest(pAd, OutBuffer, FrameLen);
571 NdisZeroMemory(&(pAd->PortCfg.Bssid), MAC_ADDR_LEN);
573 pAd->PortCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING;
574 COPY_MAC_ADDR(&pAd->PortCfg.DisassocSta, &DisassocReq->Addr);
576 RTMPSetTimer(pAd, &pAd->Mlme.AssocAux.DisassocTimer, Timeout); /* in mSec */
577 pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP;
581 ==========================================================================
582 Description:
583 peer sends assoc rsp back
584 Parameters:
585 Elme - MLME message containing the received frame
586 ==========================================================================
588 VOID PeerAssocRspAction(
589 IN PRTMP_ADAPTER pAd,
590 IN MLME_QUEUE_ELEM *Elem)
592 USHORT CapabilityInfo, Status, Aid;
593 UCHAR Rates[MAX_LEN_OF_SUPPORTED_RATES], RatesLen;
594 MACADDR Addr2;
595 BOOLEAN ExtendedRateIeExist;
597 if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, &Addr2, &CapabilityInfo, &Status, &Aid, Rates, &RatesLen, &ExtendedRateIeExist))
599 // The frame is for me ?
600 if(MAC_ADDR_EQUAL(&Addr2, &pAd->Mlme.AssocAux.Addr))
602 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status);
603 RTMPCancelTimer(&pAd->Mlme.AssocAux.AssocTimer);
604 if(Status == MLME_SUCCESS)
606 // go to procedure listed on page 376
607 // Mask out unnecessary capability information
608 CapabilityInfo &= SUPPORTED_CAPABILITY_INFO; // pAd->PortCfg.SupportedCapabilityInfo;
609 AssocPostProc(pAd, &Addr2, CapabilityInfo, Aid, Rates, RatesLen, ExtendedRateIeExist);
611 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
612 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, Status);
615 else
617 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - PeerAssocRspAction() sanity check fail\n");
622 ==========================================================================
623 Description:
624 peer sends reassoc rsp
625 Parametrs:
626 Elem - MLME message cntaining the received frame
627 ==========================================================================
629 VOID PeerReassocRspAction(
630 IN PRTMP_ADAPTER pAd,
631 IN MLME_QUEUE_ELEM *Elem)
633 USHORT CapabilityInfo;
634 USHORT Status;
635 USHORT Aid;
636 UCHAR Rates[MAX_LEN_OF_SUPPORTED_RATES];
637 UCHAR RatesLen;
638 MACADDR Addr2;
639 BOOLEAN ExtendedRateIeExist;
641 if(PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, &Addr2, &CapabilityInfo, &Status, &Aid, Rates, &RatesLen, &ExtendedRateIeExist))
643 if(MAC_ADDR_EQUAL(&Addr2, &pAd->Mlme.AssocAux.Addr)) // The frame is for me ?
645 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - receive REASSOC_RSP to me (status=%d)\n", Status);
646 RTMPCancelTimer(&pAd->Mlme.AssocAux.ReassocTimer);
648 if(Status == MLME_SUCCESS)
650 // Mask out unnecessary capability information
651 CapabilityInfo &= SUPPORTED_CAPABILITY_INFO; // pAd->PortCfg.SupportedCapabilityInfo;
652 // go to procedure listed on page 376
653 AssocPostProc(pAd, &Addr2, CapabilityInfo, Aid, Rates, RatesLen, ExtendedRateIeExist);
656 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
657 MlmeCntlConfirm(pAd, MT2_REASSOC_CONF, Status);
660 else
662 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - PeerReassocRspAction() sanity check fail\n");
667 ==========================================================================
668 Description:
669 procedures on IEEE 802.11/1999 p.376
670 Parametrs:
671 ==========================================================================
673 VOID AssocPostProc(
674 IN PRTMP_ADAPTER pAd,
675 IN PMACADDR Addr2,
676 IN USHORT CapabilityInfo,
677 IN USHORT Aid,
678 IN UCHAR Rates[],
679 IN UCHAR RatesLen,
680 IN BOOLEAN ExtendedRateIeExist)
682 ULONG Idx;
683 UCHAR RateIe = IE_SUPP_RATES;
684 UCHAR VarIesOffset;
686 // 2003/12/11 - skip the following because experiment show that we can not
687 // trust the "privacy" bit in AssocRsp. We can only trust "Privacy" bit specified in
688 // BEACON and ProbeRsp.
689 // pAd->PortCfg.PrivacyInvoked = CAP_IS_PRIVACY_ON(CapabilityInfo);
691 pAd->PortCfg.Aid = Aid;
692 NdisMoveMemory(pAd->PortCfg.SupportedRates, Rates, RatesLen);
693 pAd->PortCfg.SupportedRatesLen = RatesLen;
694 COPY_MAC_ADDR(&pAd->PortCfg.Bssid, Addr2);
695 AsicSetBssid(pAd, &pAd->PortCfg.Bssid);
697 // set listen interval
698 pAd->PortCfg.DefaultListenCount = pAd->Mlme.AssocAux.ListenIntv;
699 // pAd->PortCfg.CurrListenCount = pAd->Mlme.AssocAux.ListenIntv;
701 // Set New WPA information
702 Idx = BssTableSearch(&pAd->PortCfg.BssTab, Addr2);
703 if (Idx == BSS_NOT_FOUND)
705 DBGPRINT(RT_DEBUG_ERROR, "ASSOC - Can't find BSS after receiving Assoc response\n");
707 else
709 // Mod by James to fix OID_802_11_ASSOCIATION_INFORMATION
710 pAd->PortCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); //+ sizeof(NDIS_802_11_FIXED_IEs); // Filled in assoc request
711 pAd->PortCfg.AssocInfo.AvailableResponseFixedIEs =
712 NDIS_802_11_AI_RESFI_CAPABILITIES | NDIS_802_11_AI_RESFI_STATUSCODE | NDIS_802_11_AI_RESFI_ASSOCIATIONID;
713 pAd->PortCfg.AssocInfo.ResponseFixedIEs.Capabilities = CapabilityInfo;
714 pAd->PortCfg.AssocInfo.ResponseFixedIEs.StatusCode = MLME_SUCCESS; // Should be success, add failed later
715 pAd->PortCfg.AssocInfo.ResponseFixedIEs.AssociationId = Aid;
717 // Copy BSS VarIEs to PortCfg associnfo structure.
718 // First add Supported rates
719 VarIesOffset = 0;
720 NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, &RateIe, 1);
721 VarIesOffset += 1;
722 NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, &RatesLen, 1);
723 VarIesOffset += 1;
724 NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, Rates, RatesLen);
725 VarIesOffset += RatesLen;
727 // Second add RSN
728 NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, pAd->PortCfg.BssTab.BssEntry[Idx].VarIEs, pAd->PortCfg.BssTab.BssEntry[Idx].VarIELen);
729 VarIesOffset += pAd->PortCfg.BssTab.BssEntry[Idx].VarIELen;
731 // Set Variable IEs Length
732 pAd->PortCfg.ResVarIELen = VarIesOffset;
733 pAd->PortCfg.AssocInfo.ResponseIELength = VarIesOffset;
734 // End Mod by James
739 ==========================================================================
740 Description:
741 left part of IEEE 802.11/1999 p.374
742 Parameters:
743 Elem - MLME message containing the received frame
744 ==========================================================================
746 VOID PeerDisassocAction(
747 IN PRTMP_ADAPTER pAd,
748 IN MLME_QUEUE_ELEM *Elem)
750 MACADDR Addr2;
751 USHORT Reason;
753 if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, &Addr2, &Reason))
755 if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(&pAd->PortCfg.Bssid, &Addr2))
757 LinkDown(pAd);
758 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
760 pAd->RalinkCounters.BeenDisassociatedCount ++;
761 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Disassociated by AP, Auto Recovery attempt #%d\n", pAd->RalinkCounters.BeenDisassociatedCount);
762 MlmeAutoReconnectLastSSID(pAd);
765 else
767 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - PeerDisassocAction() sanity check fail\n");
772 ==========================================================================
773 Description:
774 what the state machine will do after assoc timeout
775 Parameters:
776 Elme -
777 ==========================================================================
779 VOID AssocTimeoutAction(
780 IN PRTMP_ADAPTER pAd,
781 IN MLME_QUEUE_ELEM *Elem)
783 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - AssocTimeoutAction\n");
784 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
785 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, MLME_REJ_TIMEOUT);
789 ==========================================================================
790 Description:
791 what the state machine will do after reassoc timeout
792 ==========================================================================
794 VOID ReassocTimeoutAction(
795 IN PRTMP_ADAPTER pAd,
796 IN MLME_QUEUE_ELEM *Elem)
798 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - ReassocTimeoutAction\n");
799 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
800 MlmeCntlConfirm(pAd, MT2_REASSOC_CONF, MLME_REJ_TIMEOUT);
804 ==========================================================================
805 Description:
806 what the state machine will do after disassoc timeout
807 ==========================================================================
809 VOID DisassocTimeoutAction(
810 IN PRTMP_ADAPTER pAd,
811 IN MLME_QUEUE_ELEM *Elem)
813 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - DisassocTimeoutAction\n");
814 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
815 MlmeCntlConfirm(pAd, MT2_DISASSOC_CONF, MLME_SUCCESS);
818 VOID InvalidStateWhenAssoc(
819 IN PRTMP_ADAPTER pAd,
820 IN MLME_QUEUE_ELEM *Elem)
822 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - InvalidStateWhenAssoc(state=%d), reset ASSOC state machine\n",
823 pAd->Mlme.AssocMachine.CurrState);
824 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
825 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, MLME_STATE_MACHINE_REJECT);
828 VOID InvalidStateWhenReassoc(
829 IN PRTMP_ADAPTER pAd,
830 IN MLME_QUEUE_ELEM *Elem)
832 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - InvalidStateWhenReassoc(state=%d), reset ASSOC state machine\n",
833 pAd->Mlme.AssocMachine.CurrState);
834 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
835 MlmeCntlConfirm(pAd, MT2_REASSOC_CONF, MLME_STATE_MACHINE_REJECT);
838 VOID InvalidStateWhenDisassociate(
839 IN PRTMP_ADAPTER pAd,
840 IN MLME_QUEUE_ELEM *Elem)
842 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - InvalidStateWhenDisassoc(state=%d), reset ASSOC state machine\n",
843 pAd->Mlme.AssocMachine.CurrState);
844 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
845 MlmeCntlConfirm(pAd, MT2_DISASSOC_CONF, MLME_STATE_MACHINE_REJECT);
849 ==========================================================================
850 Description:
851 right part of IEEE 802.11/1999 page 374
852 Note:
853 This event should never cause ASSOC state machine perform state
854 transition, and has no relationship with CNTL machine. So we separate
855 this routine as a service outside of ASSOC state transition table.
856 ==========================================================================
858 VOID Cls3errAction(
859 IN PRTMP_ADAPTER pAd,
860 IN PMACADDR pAddr)
862 MACHDR DisassocHdr;
863 CHAR *OutBuffer = NULL;
864 ULONG FrameLen = 0;
865 NDIS_STATUS NStatus;
866 USHORT Reason = REASON_CLS3ERR;
868 NStatus = MlmeAllocateMemory(pAd, (PVOID)&OutBuffer); //Get an unused nonpaged memory
869 if (NStatus != NDIS_STATUS_SUCCESS)
870 return;
872 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Class 3 Error, Send DISASSOC frame\n");
873 MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, &pAd->PortCfg.Bssid);
874 MakeOutgoingFrame(OutBuffer, &FrameLen,
875 sizeof(MACHDR), &DisassocHdr,
876 2, &Reason,
877 END_OF_ARGS);
878 MiniportMMRequest(pAd, OutBuffer, FrameLen);
880 pAd->PortCfg.DisassocReason = REASON_CLS3ERR;
881 COPY_MAC_ADDR(&pAd->PortCfg.DisassocSta, pAddr);