MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / wireless / rtlink.org / assoc.c
blob519b07e573f0a209e39f0b79bb83f98c5dc27d55
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 * (c) Copyright 2002, Ralink Technology, Inc.
8 * All rights reserved. Ralink's source code is an unpublished work and the
9 * use of a copyright notice does not imply otherwise. This source code
10 * contains confidential trade secret material of Ralink Tech. Any attemp
11 * or participation in deciphering, decoding, reverse engineering or in any
12 * way altering the source code is stricitly prohibited, unless the prior
13 * written consent of Ralink Technology, Inc. is obtained.
14 ****************************************************************************/
16 #include "rt_config.h"
18 UCHAR CipherSuiteWpaTkip[] = {
19 0x00, 0x50, 0xf2, 0x01, // oui
20 0x01, 0x00, // Version
21 0x00, 0x50, 0xf2, 0x02, // Multicast
22 0x01, 0x00, // Number of unicast
23 0x00, 0x50, 0xf2, 0x02, // unicast
24 0x01, 0x00, // number of authentication method
25 0x00, 0x50, 0xf2, 0x01 // authentication
27 UCHAR CipherSuiteWpaTkipLen = (sizeof(CipherSuiteWpaTkip) / sizeof(UCHAR));
29 UCHAR CipherSuiteWpaAes[] = {
30 0x00, 0x50, 0xf2, 0x01, // oui
31 0x01, 0x00, // Version
32 0x00, 0x50, 0xf2, 0x04, // Multicast
33 0x01, 0x00, // Number of unicast
34 0x00, 0x50, 0xf2, 0x04, // unicast
35 0x01, 0x00, // number of authentication method
36 0x00, 0x50, 0xf2, 0x01 // authentication
38 UCHAR CipherSuiteWpaAesLen = (sizeof(CipherSuiteWpaAes) / sizeof(UCHAR));
40 UCHAR CipherSuiteWpaPskTkip[] = {
41 0x00, 0x50, 0xf2, 0x01, // oui
42 0x01, 0x00, // Version
43 0x00, 0x50, 0xf2, 0x02, // Multicast
44 0x01, 0x00, // Number of unicast
45 0x00, 0x50, 0xf2, 0x02, // unicast
46 0x01, 0x00, // number of authentication method
47 0x00, 0x50, 0xf2, 0x02 // authentication
49 UCHAR CipherSuiteWpaPskTkipLen = (sizeof(CipherSuiteWpaPskTkip) / sizeof(UCHAR));
51 UCHAR CipherSuiteWpaPskAes[] = {
52 0x00, 0x50, 0xf2, 0x01, // oui
53 0x01, 0x00, // Version
54 0x00, 0x50, 0xf2, 0x04, // Multicast
55 0x01, 0x00, // Number of unicast
56 0x00, 0x50, 0xf2, 0x04, // unicast
57 0x01, 0x00, // number of authentication method
58 0x00, 0x50, 0xf2, 0x02 // authentication
60 UCHAR CipherSuiteWpaPskAesLen = (sizeof(CipherSuiteWpaPskAes) / sizeof(UCHAR));
62 /*
63 ==========================================================================
64 Description:
65 association state machine init, including state transition and timer init
66 Parameters:
67 S - pointer to the association state machine
68 Note:
69 The state machine looks like the following
71 ASSOC_IDLE ASSOC_WAIT_RSP REASSOC_WAIT_RSP DISASSOC_WAIT_RSP
72 MT2_MLME_ASSOC_REQ mlme_assoc_req_action invalid_state_when_assoc invalid_state_when_assoc invalid_state_when_assoc
73 MT2_MLME_REASSOC_REQ mlme_reassoc_req_action invalid_state_when_reassoc invalid_state_when_reassoc invalid_state_when_reassoc
74 MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action mlme_disassoc_req_action mlme_disassoc_req_action mlme_disassoc_req_action
75 MT2_PEER_DISASSOC_REQ peer_disassoc_action peer_disassoc_action peer_disassoc_action peer_disassoc_action
76 MT2_PEER_ASSOC_REQ drop drop drop drop
77 MT2_PEER_ASSOC_RSP drop peer_assoc_rsp_action drop drop
78 MT2_PEER_REASSOC_REQ drop drop drop drop
79 MT2_PEER_REASSOC_RSP drop drop peer_reassoc_rsp_action drop
80 MT2_CLS3ERR cls3err_action cls3err_action cls3err_action cls3err_action
81 MT2_ASSOC_TIMEOUT timer_nop assoc_timeout_action timer_nop timer_nop
82 MT2_REASSOC_TIMEOUT timer_nop timer_nop reassoc_timeout_action timer_nop
83 MT2_DISASSOC_TIMEOUT timer_nop timer_nop timer_nop disassoc_timeout_action
84 ==========================================================================
86 VOID AssocStateMachineInit(
87 IN PRTMP_ADAPTER pAd,
88 IN STATE_MACHINE *S,
89 OUT STATE_MACHINE_FUNC Trans[])
91 StateMachineInit(S, (STATE_MACHINE_FUNC*)Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG, (STATE_MACHINE_FUNC)Drop, ASSOC_IDLE, ASSOC_MACHINE_BASE);
93 // first column
94 StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)MlmeAssocReqAction);
95 StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)MlmeReassocReqAction);
96 StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)MlmeDisassocReqAction);
97 StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
98 // StateMachineSetAction(S, ASSOC_IDLE, MT2_CLS3ERR, (STATE_MACHINE_FUNC)Cls3errAction);
100 // second column
101 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
102 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
103 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
104 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
105 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
106 // StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_CLS3ERR, (STATE_MACHINE_FUNC)Cls3errAction);
107 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT, (STATE_MACHINE_FUNC)AssocTimeoutAction);
109 // third column
110 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
111 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
112 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
113 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
114 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
115 // StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_CLS3ERR, (STATE_MACHINE_FUNC)Cls3errAction);
116 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT, (STATE_MACHINE_FUNC)ReassocTimeoutAction);
118 // fourth column
119 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
120 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
121 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
122 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
123 // StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_CLS3ERR, (STATE_MACHINE_FUNC)Cls3errAction);
124 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT, (STATE_MACHINE_FUNC)DisassocTimeoutAction);
126 // initialize the timer
127 RTMPInitTimer(pAd, &pAd->Mlme.AssocAux.AssocTimer, AssocTimeout);
128 RTMPInitTimer(pAd, &pAd->Mlme.AssocAux.ReassocTimer, ReassocTimeout);
129 RTMPInitTimer(pAd, &pAd->Mlme.AssocAux.DisassocTimer, DisassocTimeout);
133 ==========================================================================
134 Description:
135 Association timeout procedure. After association timeout, this function
136 will be called and it will put a message into the MLME queue
137 Parameters:
138 Standard timer parameters
139 ==========================================================================
141 VOID AssocTimeout(
142 IN unsigned long data)
144 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)data;
145 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - enqueue MT2_ASSOC_TIMEOUT \n");
146 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL);
147 MlmeHandler(pAd);
151 ==========================================================================
152 Description:
153 Reassociation timeout procedure. After reassociation timeout, this
154 function will be called and put a message into the MLME queue
155 Parameters:
156 Standard timer parameters
157 ==========================================================================
159 VOID ReassocTimeout(
160 IN unsigned long data)
162 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)data;
163 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - enqueue MT2_REASSOC_TIMEOUT \n");
164 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL);
165 MlmeHandler(pAd);
169 ==========================================================================
170 Description:
171 Disassociation timeout procedure. After disassociation timeout, this
172 function will be called and put a message into the MLME queue
173 Parameters:
174 Standard timer parameters
175 ==========================================================================
177 VOID DisassocTimeout(
178 IN unsigned long data)
180 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)data;
181 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - enqueue MT2_DISASSOC_TIMEOUT \n");
182 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL);
183 MlmeHandler(pAd);
187 ==========================================================================
188 Description:
189 mlme assoc req handling procedure
190 Parameters:
191 Adapter - Adapter pointer
192 Elem - MLME Queue Element
193 Pre:
194 the station has been authenticated and the following information is stored in the config
195 -# SSID
196 -# supported rates and their length
197 -# listen interval (Adapter->PortCfg.default_listen_count)
198 -# Transmit power (Adapter->PortCfg.tx_power)
199 Post :
200 -# An association request frame is generated and sent to the air
201 -# Association timer starts
202 -# Association state -> ASSOC_WAIT_RSP
203 ==========================================================================
205 VOID MlmeAssocReqAction(
206 IN PRTMP_ADAPTER pAd,
207 IN MLME_QUEUE_ELEM *Elem)
209 MACADDR ApAddr;
210 MACHDR AssocHdr;
211 UCHAR SsidIe = IE_SSID, RateIe = IE_SUPP_RATES,WpaIe = IE_WPA, ExtRateIe = IE_EXT_SUPP_RATES;
212 USHORT ListenIntv;
213 ULONG Timeout;
214 USHORT CapabilityInfo;
215 UCHAR *OutBuffer = NULL;
216 NDIS_STATUS NStatus;
217 ULONG FrameLen = 0;
218 ULONG tmp;
219 UCHAR VarIesOffset;
221 // Block all authentication request durning WPA block period
222 if (pAd->PortCfg.bBlockAssoc == TRUE)
224 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Block Assoc request durning WPA block period!\n");
225 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
226 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, MLME_STATE_MACHINE_REJECT);
228 // check sanity first
229 else if (MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, &ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
231 RTMPCancelTimer(&pAd->Mlme.AssocAux.AssocTimer);
232 COPY_MAC_ADDR(&pAd->Mlme.AssocAux.Addr, &ApAddr);
233 // Mask out unnecessary capability information
234 CapabilityInfo &= SUPPORTED_CAPABILITY_INFO; // pAd->PortCfg.SupportedCapabilityInfo;
235 pAd->Mlme.AssocAux.CapabilityInfo = CapabilityInfo;
236 pAd->Mlme.AssocAux.ListenIntv = ListenIntv;
238 NStatus = MlmeAllocateMemory(pAd, (PVOID)&OutBuffer); //Get an unused nonpaged memory
239 if (NStatus != NDIS_STATUS_SUCCESS)
241 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - MlmeAssocReqAction() allocate memory failed \n");
242 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
243 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, MLME_FAIL_NO_RESOURCE);
244 return;
247 // Add by James 03/06/27
248 pAd->PortCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); //+ sizeof(NDIS_802_11_FIXED_IEs); // Filled in assoc request
249 pAd->PortCfg.AssocInfo.AvailableRequestFixedIEs =
250 NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_LISTENINTERVAL | NDIS_802_11_AI_REQFI_CURRENTAPADDRESS;
251 pAd->PortCfg.AssocInfo.RequestFixedIEs.Capabilities = CapabilityInfo;
252 pAd->PortCfg.AssocInfo.RequestFixedIEs.ListenInterval = ListenIntv;
253 NdisMoveMemory(pAd->PortCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, &AssocHdr, sizeof(NDIS_802_11_MAC_ADDRESS));
254 pAd->PortCfg.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); // No request Variables IEs
256 // First add SSID
257 VarIesOffset = 0;
258 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &SsidIe, 1);
259 VarIesOffset += 1;
260 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &pAd->PortCfg.SsidLen, 1);
261 VarIesOffset += 1;
262 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, pAd->PortCfg.Ssid, pAd->PortCfg.SsidLen);
263 VarIesOffset += pAd->PortCfg.SsidLen;
265 // Second add Supported rates
266 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &RateIe, 1);
267 VarIesOffset += 1;
268 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &pAd->PortCfg.SupportedRatesLen, 1);
269 VarIesOffset += 1;
270 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, pAd->PortCfg.SupportedRates, pAd->PortCfg.SupportedRatesLen);
271 VarIesOffset += pAd->PortCfg.SupportedRatesLen;
272 // End Add by James
274 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Send ASSOC request...\n");
275 MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, &ApAddr, &ApAddr);
277 // Build basic frame first
278 MakeOutgoingFrame(OutBuffer, &FrameLen,
279 sizeof(MACHDR), &AssocHdr,
280 2, &CapabilityInfo,
281 2, &ListenIntv,
282 1, &SsidIe,
283 1, &pAd->PortCfg.SsidLen,
284 pAd->PortCfg.SsidLen, pAd->PortCfg.Ssid,
285 1, &RateIe,
286 1, &pAd->PortCfg.SupRateLen,
287 pAd->PortCfg.SupRateLen, pAd->PortCfg.SupRate,
288 END_OF_ARGS);
289 if (pAd->PortCfg.ExtRateLen != 0)
291 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp, 1, &ExtRateIe, 1, &pAd->PortCfg.ExtRateLen, pAd->PortCfg.ExtRateLen, pAd->PortCfg.ExtRate, END_OF_ARGS);
292 FrameLen += tmp;
295 if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA) && (pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled)) {
296 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp, 1, &WpaIe, 1, &CipherSuiteWpaTkipLen, CipherSuiteWpaTkipLen, &CipherSuiteWpaTkip[0], END_OF_ARGS);
297 FrameLen += tmp;
299 // Add by James 03/06/27
300 // Third add RSN
301 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &WpaIe, 1);
302 VarIesOffset += 1;
303 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &CipherSuiteWpaTkipLen, 1);
304 VarIesOffset += 1;
305 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, CipherSuiteWpaTkip, CipherSuiteWpaTkipLen);
306 VarIesOffset += CipherSuiteWpaTkipLen;
308 // Set Variable IEs Length
309 pAd->PortCfg.ReqVarIELen = VarIesOffset;
310 pAd->PortCfg.AssocInfo.RequestIELength = VarIesOffset;
312 // OffsetResponseIEs follow ReqVarIE
313 pAd->PortCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->PortCfg.ReqVarIELen;
314 // End Add by James
317 else if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA) && (pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled))
319 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp, 1, &WpaIe, 1, &CipherSuiteWpaAesLen, CipherSuiteWpaAesLen, &CipherSuiteWpaAes[0], END_OF_ARGS);
320 FrameLen += tmp;
322 // Add by James 03/06/27
323 // Third add RSN
324 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &WpaIe, 1);
325 VarIesOffset += 1;
326 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &CipherSuiteWpaAesLen, 1);
327 VarIesOffset += 1;
328 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, CipherSuiteWpaAes, CipherSuiteWpaAesLen);
329 VarIesOffset += CipherSuiteWpaAesLen;
331 // Set Variable IEs Length
332 pAd->PortCfg.ReqVarIELen = VarIesOffset;
333 pAd->PortCfg.AssocInfo.RequestIELength = VarIesOffset;
335 // OffsetResponseIEs follow ReqVarIE
336 pAd->PortCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->PortCfg.ReqVarIELen;
337 // End Add by James
339 else if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK) && (pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled))
341 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp, 1, &WpaIe, 1, &CipherSuiteWpaPskTkipLen, CipherSuiteWpaPskTkipLen, &CipherSuiteWpaPskTkip[0], END_OF_ARGS);
342 FrameLen += tmp;
344 // Add by James 03/06/27
345 // Third add RSN
346 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &WpaIe, 1);
347 VarIesOffset += 1;
348 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &CipherSuiteWpaPskTkipLen, 1);
349 VarIesOffset += 1;
350 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, CipherSuiteWpaPskTkip, CipherSuiteWpaPskTkipLen);
351 VarIesOffset += CipherSuiteWpaPskTkipLen;
353 // Set Variable IEs Length
354 pAd->PortCfg.ReqVarIELen = VarIesOffset;
355 pAd->PortCfg.AssocInfo.RequestIELength = VarIesOffset;
357 // OffsetResponseIEs follow ReqVarIE
358 pAd->PortCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->PortCfg.ReqVarIELen;
359 // End Add by James
361 else if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK) && (pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled))
363 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp, 1, &WpaIe, 1, &CipherSuiteWpaPskAesLen, CipherSuiteWpaPskAesLen, &CipherSuiteWpaPskAes[0], END_OF_ARGS);
364 FrameLen += tmp;
366 // Add by James 03/06/27
367 // Third add RSN
368 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &WpaIe, 1);
369 VarIesOffset += 1;
370 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, &CipherSuiteWpaPskAesLen, 1);
371 VarIesOffset += 1;
372 NdisMoveMemory(pAd->PortCfg.ReqVarIEs + VarIesOffset, CipherSuiteWpaPskAes, CipherSuiteWpaPskAesLen);
373 VarIesOffset += CipherSuiteWpaPskAesLen;
375 // Set Variable IEs Length
376 pAd->PortCfg.ReqVarIELen = VarIesOffset;
377 pAd->PortCfg.AssocInfo.RequestIELength = VarIesOffset;
379 // OffsetResponseIEs follow ReqVarIE
380 pAd->PortCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->PortCfg.ReqVarIELen;
381 // End Add by James
382 } else {
383 // Add by James 03/06/27
384 // Set Variable IEs Length
385 pAd->PortCfg.ReqVarIELen = VarIesOffset;
386 pAd->PortCfg.AssocInfo.RequestIELength = VarIesOffset;
388 // OffsetResponseIEs follow ReqVarIE
389 pAd->PortCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->PortCfg.ReqVarIELen;
390 // End Add by James
392 MiniportMMRequest(pAd, OutBuffer, FrameLen);
393 RTMPSetTimer(pAd, &pAd->Mlme.AssocAux.AssocTimer, Timeout);
394 pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP;
395 } else {
396 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - MlmeAssocReqAction() sanity check failed. BUG!!!!!! \n");
397 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
398 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, MLME_INVALID_FORMAT);
404 ==========================================================================
405 Description:
406 mlme reassoc req handling procedure
407 Parameters:
408 Elem -
409 Pre:
410 -# SSID (Adapter->PortCfg.ssid[])
411 -# BSSID (AP address, Adapter->PortCfg.bssid)
412 -# Supported rates (Adapter->PortCfg.supported_rates[])
413 -# Supported rates length (Adapter->PortCfg.supported_rates_len)
414 -# Tx power (Adapter->PortCfg.tx_power)
415 ==========================================================================
417 VOID MlmeReassocReqAction(
418 IN PRTMP_ADAPTER pAd,
419 IN MLME_QUEUE_ELEM *Elem)
421 MACADDR ApAddr;
422 MACHDR ReassocHdr;
423 UCHAR SsidIe = IE_SSID, RateIe = IE_SUPP_RATES, ExtRateIe = IE_EXT_SUPP_RATES;
424 USHORT CapabilityInfo, ListenIntv;
425 ULONG Timeout;
426 ULONG FrameLen = 0;
427 NDIS_STATUS NStatus;
428 ULONG tmp;
429 UCHAR *OutBuffer = NULL;
431 // Block all authentication request durning WPA block period
432 if (pAd->PortCfg.bBlockAssoc == TRUE)
434 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Block ReAssoc request durning WPA block period!\n");
435 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
436 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, MLME_STATE_MACHINE_REJECT);
438 // the parameters are the same as the association
439 else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, &ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
441 RTMPCancelTimer(&pAd->Mlme.AssocAux.ReassocTimer);
443 NStatus = MlmeAllocateMemory(pAd, (PVOID)&OutBuffer); //Get an unused nonpaged memory
444 if(NStatus != NDIS_STATUS_SUCCESS)
446 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - MlmeReassocReqAction() allocate memory failed \n");
447 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
448 MlmeCntlConfirm(pAd, MT2_REASSOC_CONF, MLME_FAIL_NO_RESOURCE);
449 return;
452 // Mask out unnecessary capability information
453 CapabilityInfo &= SUPPORTED_CAPABILITY_INFO; // pAd->PortCfg.SupportedCapabilityInfo;
454 pAd->Mlme.AssocAux.CapabilityInfo = CapabilityInfo;
455 COPY_MAC_ADDR(&pAd->Mlme.AssocAux.Addr, &ApAddr);
456 pAd->Mlme.AssocAux.ListenIntv = ListenIntv;
458 // make frame, use bssid as the AP address??
459 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Send RE-ASSOC request...\n");
460 MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0, &ApAddr, &ApAddr);
461 MakeOutgoingFrame(OutBuffer, &FrameLen,
462 sizeof(MACHDR), &ReassocHdr,
463 2, &CapabilityInfo,
464 2, &ListenIntv,
465 MAC_ADDR_LEN, &pAd->PortCfg.Bssid,
466 1, &SsidIe,
467 1, &pAd->PortCfg.SsidLen,
468 pAd->PortCfg.SsidLen, pAd->PortCfg.Ssid,
469 1, &RateIe,
470 1, &pAd->PortCfg.SupRateLen,
471 pAd->PortCfg.SupRateLen, pAd->PortCfg.SupRate,
472 END_OF_ARGS);
473 if (pAd->PortCfg.ExtRateLen != 0)
475 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp, 1, &ExtRateIe, 1, &pAd->PortCfg.ExtRateLen, pAd->PortCfg.ExtRateLen, pAd->PortCfg.ExtRate, END_OF_ARGS);
476 FrameLen += tmp;
478 MiniportMMRequest(pAd, OutBuffer, FrameLen);
480 RTMPSetTimer(pAd, &pAd->Mlme.AssocAux.ReassocTimer, Timeout); /* in mSec */
481 pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP;
482 } else {
483 DBGPRINT(RT_DEBUG_TRACE,"ASSOC - MlmeReassocReqAction() sanity check failed. BUG!!!! \n");
484 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
485 MlmeCntlConfirm(pAd, MT2_REASSOC_CONF, MLME_INVALID_FORMAT);
490 ==========================================================================
491 Description:
492 Upper layer issues disassoc request
493 Parameters:
494 Elem -
495 ==========================================================================
497 VOID MlmeDisassocReqAction(
498 IN PRTMP_ADAPTER pAd,
499 IN MLME_QUEUE_ELEM *Elem)
501 MLME_DISASSOC_REQ_STRUCT *DisassocReq;
502 MACHDR DisassocHdr;
503 CHAR *OutBuffer = NULL;
504 ULONG FrameLen = 0;
505 NDIS_STATUS NStatus;
506 ULONG Timeout = 0;
508 // skip sanity check
509 DisassocReq = (MLME_DISASSOC_REQ_STRUCT *)(Elem->Msg);
511 NStatus = MlmeAllocateMemory(pAd, (PVOID)&OutBuffer); //Get an unused nonpaged memory
512 if (NStatus != NDIS_STATUS_SUCCESS)
514 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - MlmeDisassocReqAction() allocate memory failed\n");
515 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
516 MlmeCntlConfirm(pAd, MT2_DISASSOC_CONF, MLME_FAIL_NO_RESOURCE);
517 return;
520 RTMPCancelTimer(&pAd->Mlme.AssocAux.DisassocTimer);
522 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Send DISASSOC request\n");
523 MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, &pAd->PortCfg.Bssid, &pAd->PortCfg.Bssid);
524 MakeOutgoingFrame(OutBuffer, &FrameLen,
525 sizeof(MACHDR), &DisassocHdr,
526 2, &DisassocReq->Reason,
527 END_OF_ARGS);
528 MiniportMMRequest(pAd, OutBuffer, FrameLen);
529 NdisZeroMemory(&(pAd->PortCfg.Bssid), MAC_ADDR_LEN);
531 pAd->PortCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING;
532 COPY_MAC_ADDR(&pAd->PortCfg.DisassocSta, &DisassocReq->Addr);
534 RTMPSetTimer(pAd, &pAd->Mlme.AssocAux.DisassocTimer, Timeout); /* in mSec */
535 pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP;
539 ==========================================================================
540 Description:
541 peer sends assoc rsp back
542 Parameters:
543 Elme - MLME message containing the received frame
544 ==========================================================================
546 VOID PeerAssocRspAction(
547 IN PRTMP_ADAPTER pAd,
548 IN MLME_QUEUE_ELEM *Elem)
550 USHORT CapabilityInfo, Status, Aid;
551 UCHAR Rates[MAX_LEN_OF_SUPPORTED_RATES], RatesLen;
552 MACADDR Addr2;
553 BOOLEAN ExtendedRateIeExist;
555 if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, &Addr2, &CapabilityInfo, &Status, &Aid, Rates, &RatesLen, &ExtendedRateIeExist))
557 // The frame is for me ?
558 if(MAC_ADDR_EQUAL(&Addr2, &pAd->Mlme.AssocAux.Addr))
560 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status);
561 RTMPCancelTimer(&pAd->Mlme.AssocAux.AssocTimer);
562 if(Status == MLME_SUCCESS)
564 // go to procedure listed on page 376
565 // Mask out unnecessary capability information
566 CapabilityInfo &= SUPPORTED_CAPABILITY_INFO; // pAd->PortCfg.SupportedCapabilityInfo;
567 AssocPostProc(pAd, &Addr2, CapabilityInfo, Aid, Rates, RatesLen, ExtendedRateIeExist);
569 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
570 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, Status);
573 else
575 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - PeerAssocRspAction() sanity check fail\n");
580 ==========================================================================
581 Description:
582 peer sends reassoc rsp
583 Parametrs:
584 Elem - MLME message cntaining the received frame
585 ==========================================================================
587 VOID PeerReassocRspAction(
588 IN PRTMP_ADAPTER pAd,
589 IN MLME_QUEUE_ELEM *Elem)
591 USHORT CapabilityInfo;
592 USHORT Status;
593 USHORT Aid;
594 UCHAR Rates[MAX_LEN_OF_SUPPORTED_RATES];
595 UCHAR RatesLen;
596 MACADDR Addr2;
597 BOOLEAN ExtendedRateIeExist;
599 if(PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, &Addr2, &CapabilityInfo, &Status, &Aid, Rates, &RatesLen, &ExtendedRateIeExist))
601 if(MAC_ADDR_EQUAL(&Addr2, &pAd->Mlme.AssocAux.Addr)) // The frame is for me ?
603 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - receive REASSOC_RSP to me (status=%d)\n", Status);
604 RTMPCancelTimer(&pAd->Mlme.AssocAux.ReassocTimer);
606 if(Status == MLME_SUCCESS)
608 // Mask out unnecessary capability information
609 CapabilityInfo &= SUPPORTED_CAPABILITY_INFO; // pAd->PortCfg.SupportedCapabilityInfo;
610 // go to procedure listed on page 376
611 AssocPostProc(pAd, &Addr2, CapabilityInfo, Aid, Rates, RatesLen, ExtendedRateIeExist);
614 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
615 MlmeCntlConfirm(pAd, MT2_REASSOC_CONF, Status);
618 else
620 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - PeerReassocRspAction() sanity check fail\n");
625 ==========================================================================
626 Description:
627 procedures on IEEE 802.11/1999 p.376
628 Parametrs:
629 ==========================================================================
631 VOID AssocPostProc(
632 IN PRTMP_ADAPTER pAd,
633 IN PMACADDR Addr2,
634 IN USHORT CapabilityInfo,
635 IN USHORT Aid,
636 IN UCHAR Rates[],
637 IN UCHAR RatesLen,
638 IN BOOLEAN ExtendedRateIeExist)
640 ULONG Idx;
641 UCHAR RateIe = IE_SUPP_RATES;
642 UCHAR VarIesOffset;
644 // 2003/12/11 - skip the following because experiment show that we can not
645 // trust the "privacy" bit in AssocRsp. We can only trust "Privacy" bit specified in
646 // BEACON and ProbeRsp.
647 // pAd->PortCfg.PrivacyInvoked = CAP_IS_PRIVACY_ON(CapabilityInfo);
649 pAd->PortCfg.Aid = Aid;
650 NdisMoveMemory(pAd->PortCfg.SupportedRates, Rates, RatesLen);
651 pAd->PortCfg.SupportedRatesLen = RatesLen;
652 COPY_MAC_ADDR(&pAd->PortCfg.Bssid, Addr2);
653 AsicSetBssid(pAd, &pAd->PortCfg.Bssid);
655 // set listen interval
656 pAd->PortCfg.DefaultListenCount = pAd->Mlme.AssocAux.ListenIntv;
657 // pAd->PortCfg.CurrListenCount = pAd->Mlme.AssocAux.ListenIntv;
659 // Set New WPA information
660 Idx = BssTableSearch(&pAd->PortCfg.BssTab, Addr2);
661 if (Idx == BSS_NOT_FOUND)
663 DBGPRINT(RT_DEBUG_ERROR, "ASSOC - Can't find BSS after receiving Assoc response\n");
665 else
667 // Mod by James to fix OID_802_11_ASSOCIATION_INFORMATION
668 pAd->PortCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); //+ sizeof(NDIS_802_11_FIXED_IEs); // Filled in assoc request
669 pAd->PortCfg.AssocInfo.AvailableResponseFixedIEs =
670 NDIS_802_11_AI_RESFI_CAPABILITIES | NDIS_802_11_AI_RESFI_STATUSCODE | NDIS_802_11_AI_RESFI_ASSOCIATIONID;
671 pAd->PortCfg.AssocInfo.ResponseFixedIEs.Capabilities = CapabilityInfo;
672 pAd->PortCfg.AssocInfo.ResponseFixedIEs.StatusCode = MLME_SUCCESS; // Should be success, add failed later
673 pAd->PortCfg.AssocInfo.ResponseFixedIEs.AssociationId = Aid;
675 // Copy BSS VarIEs to PortCfg associnfo structure.
676 // First add Supported rates
677 VarIesOffset = 0;
678 NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, &RateIe, 1);
679 VarIesOffset += 1;
680 NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, &RatesLen, 1);
681 VarIesOffset += 1;
682 NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, Rates, RatesLen);
683 VarIesOffset += RatesLen;
685 // Second add RSN
686 NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, pAd->PortCfg.BssTab.BssEntry[Idx].VarIEs, pAd->PortCfg.BssTab.BssEntry[Idx].VarIELen);
687 VarIesOffset += pAd->PortCfg.BssTab.BssEntry[Idx].VarIELen;
689 // Set Variable IEs Length
690 pAd->PortCfg.ResVarIELen = VarIesOffset;
691 pAd->PortCfg.AssocInfo.ResponseIELength = VarIesOffset;
692 // End Mod by James
697 ==========================================================================
698 Description:
699 left part of IEEE 802.11/1999 p.374
700 Parameters:
701 Elem - MLME message containing the received frame
702 ==========================================================================
704 VOID PeerDisassocAction(
705 IN PRTMP_ADAPTER pAd,
706 IN MLME_QUEUE_ELEM *Elem)
708 MACADDR Addr2;
709 USHORT Reason;
711 if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, &Addr2, &Reason))
713 if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(&pAd->PortCfg.Bssid, &Addr2))
715 LinkDown(pAd);
716 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
718 pAd->RalinkCounters.BeenDisassociatedCount ++;
719 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Disassociated by AP, Auto Recovery attempt #%d\n", pAd->RalinkCounters.BeenDisassociatedCount);
720 MlmeAutoReconnectLastSSID(pAd);
723 else
725 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - PeerDisassocAction() sanity check fail\n");
730 ==========================================================================
731 Description:
732 what the state machine will do after assoc timeout
733 Parameters:
734 Elme -
735 ==========================================================================
737 VOID AssocTimeoutAction(
738 IN PRTMP_ADAPTER pAd,
739 IN MLME_QUEUE_ELEM *Elem)
741 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - AssocTimeoutAction\n");
742 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
743 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, MLME_REJ_TIMEOUT);
747 ==========================================================================
748 Description:
749 what the state machine will do after reassoc timeout
750 ==========================================================================
752 VOID ReassocTimeoutAction(
753 IN PRTMP_ADAPTER pAd,
754 IN MLME_QUEUE_ELEM *Elem)
756 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - ReassocTimeoutAction\n");
757 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
758 MlmeCntlConfirm(pAd, MT2_REASSOC_CONF, MLME_REJ_TIMEOUT);
762 ==========================================================================
763 Description:
764 what the state machine will do after disassoc timeout
765 ==========================================================================
767 VOID DisassocTimeoutAction(
768 IN PRTMP_ADAPTER pAd,
769 IN MLME_QUEUE_ELEM *Elem)
771 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - DisassocTimeoutAction\n");
772 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
773 MlmeCntlConfirm(pAd, MT2_DISASSOC_CONF, MLME_SUCCESS);
776 VOID InvalidStateWhenAssoc(
777 IN PRTMP_ADAPTER pAd,
778 IN MLME_QUEUE_ELEM *Elem)
780 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - InvalidStateWhenAssoc(state=%d), reset ASSOC state machine\n",
781 pAd->Mlme.AssocMachine.CurrState);
782 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
783 MlmeCntlConfirm(pAd, MT2_ASSOC_CONF, MLME_STATE_MACHINE_REJECT);
786 VOID InvalidStateWhenReassoc(
787 IN PRTMP_ADAPTER pAd,
788 IN MLME_QUEUE_ELEM *Elem)
790 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - InvalidStateWhenReassoc(state=%d), reset ASSOC state machine\n",
791 pAd->Mlme.AssocMachine.CurrState);
792 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
793 MlmeCntlConfirm(pAd, MT2_REASSOC_CONF, MLME_STATE_MACHINE_REJECT);
796 VOID InvalidStateWhenDisassociate(
797 IN PRTMP_ADAPTER pAd,
798 IN MLME_QUEUE_ELEM *Elem)
800 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - InvalidStateWhenDisassoc(state=%d), reset ASSOC state machine\n",
801 pAd->Mlme.AssocMachine.CurrState);
802 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
803 MlmeCntlConfirm(pAd, MT2_DISASSOC_CONF, MLME_STATE_MACHINE_REJECT);
807 ==========================================================================
808 Description:
809 right part of IEEE 802.11/1999 page 374
810 Note:
811 This event should never cause ASSOC state machine perform state
812 transition, and has no relationship with CNTL machine. So we separate
813 this routine as a service outside of ASSOC state transition table.
814 ==========================================================================
816 VOID Cls3errAction(
817 IN PRTMP_ADAPTER pAd,
818 IN PMACADDR pAddr)
820 MACHDR DisassocHdr;
821 CHAR *OutBuffer = NULL;
822 ULONG FrameLen = 0;
823 NDIS_STATUS NStatus;
824 USHORT Reason = REASON_CLS3ERR;
826 NStatus = MlmeAllocateMemory(pAd, (PVOID)&OutBuffer); //Get an unused nonpaged memory
827 if (NStatus != NDIS_STATUS_SUCCESS)
828 return;
830 DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Class 3 Error, Send DISASSOC frame\n");
831 MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, &pAd->PortCfg.Bssid);
832 MakeOutgoingFrame(OutBuffer, &FrameLen,
833 sizeof(MACHDR), &DisassocHdr,
834 2, &Reason,
835 END_OF_ARGS);
836 MiniportMMRequest(pAd, OutBuffer, FrameLen);
838 pAd->PortCfg.DisassocReason = REASON_CLS3ERR;
839 COPY_MAC_ADDR(&pAd->PortCfg.DisassocSta, pAddr);