1 /*************************************************************************
3 * 4F, No. 2 Technology 5th Rd. *
4 * Science-based Industrial Park *
5 * Hsin-chu, Taiwan, R.O.C. *
7 * (c) Copyright 2002, Ralink Technology, Inc. *
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. *
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. *
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. *
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
));
73 ==========================================================================
75 association state machine init, including state transition and timer init
77 S - pointer to the association state machine
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(
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
);
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);
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
);
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
);
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 ==========================================================================
145 Association timeout procedure. After association timeout, this function
146 will be called and it will put a message into the MLME queue
148 Standard timer parameters
149 ==========================================================================
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
);
161 ==========================================================================
163 Reassociation timeout procedure. After reassociation timeout, this
164 function will be called and put a message into the MLME queue
166 Standard timer parameters
167 ==========================================================================
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
);
179 ==========================================================================
181 Disassociation timeout procedure. After disassociation timeout, this
182 function will be called and put a message into the MLME queue
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
);
197 ==========================================================================
199 mlme assoc req handling procedure
201 Adapter - Adapter pointer
202 Elem - MLME Queue Element
204 the station has been authenticated and the following information is stored in the config
206 -# supported rates and their length
207 -# listen interval (Adapter->PortCfg.default_listen_count)
208 -# Transmit power (Adapter->PortCfg.tx_power)
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
)
221 UCHAR SsidIe
= IE_SSID
, RateIe
= IE_SUPP_RATES
,WpaIe
= IE_WPA
, ExtRateIe
= IE_EXT_SUPP_RATES
;
224 USHORT CapabilityInfo
;
225 UCHAR
*OutBuffer
= NULL
;
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
);
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
268 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &SsidIe
, 1);
270 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &pAd
->PortCfg
.SsidLen
, 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);
278 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &pAd
->PortCfg
.SupportedRatesLen
, 1);
280 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, pAd
->PortCfg
.SupportedRates
, pAd
->PortCfg
.SupportedRatesLen
);
281 VarIesOffset
+= pAd
->PortCfg
.SupportedRatesLen
;
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
,
293 1, &pAd
->PortCfg
.SsidLen
,
294 pAd
->PortCfg
.SsidLen
, pAd
->PortCfg
.Ssid
,
296 1, &pAd
->PortCfg
.SupRateLen
,
297 pAd
->PortCfg
.SupRateLen
, pAd
->PortCfg
.SupRate
,
299 if (pAd
->PortCfg
.ExtRateLen
!= 0)
301 MakeOutgoingFrame(OutBuffer
+ FrameLen
, &tmp
,
303 1, &pAd
->PortCfg
.ExtRateLen
,
304 pAd
->PortCfg
.ExtRateLen
, pAd
->PortCfg
.ExtRate
,
309 if ((pAd
->PortCfg
.AuthMode
== Ndis802_11AuthModeWPA
) && (pAd
->PortCfg
.WepStatus
== Ndis802_11Encryption2Enabled
))
311 MakeOutgoingFrame(OutBuffer
+ FrameLen
, &tmp
,
313 1, &CipherSuiteWpaTkipLen
,
314 CipherSuiteWpaTkipLen
, &CipherSuiteWpaTkip
[0],
318 // Add by James 03/06/27
320 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &WpaIe
, 1);
322 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &CipherSuiteWpaTkipLen
, 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
;
336 else if ((pAd
->PortCfg
.AuthMode
== Ndis802_11AuthModeWPA
) && (pAd
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
))
338 MakeOutgoingFrame(OutBuffer
+ FrameLen
, &tmp
,
340 1, &CipherSuiteWpaAesLen
,
341 CipherSuiteWpaAesLen
, &CipherSuiteWpaAes
[0],
345 // Add by James 03/06/27
347 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &WpaIe
, 1);
349 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &CipherSuiteWpaAesLen
, 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
;
362 else if ((pAd
->PortCfg
.AuthMode
== Ndis802_11AuthModeWPAPSK
) && (pAd
->PortCfg
.WepStatus
== Ndis802_11Encryption2Enabled
))
364 MakeOutgoingFrame(OutBuffer
+ FrameLen
, &tmp
,
366 1, &CipherSuiteWpaPskTkipLen
,
367 CipherSuiteWpaPskTkipLen
, &CipherSuiteWpaPskTkip
[0],
371 // Add by James 03/06/27
373 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &WpaIe
, 1);
375 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &CipherSuiteWpaPskTkipLen
, 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
;
388 else if ((pAd
->PortCfg
.AuthMode
== Ndis802_11AuthModeWPAPSK
) && (pAd
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
))
390 MakeOutgoingFrame(OutBuffer
+ FrameLen
, &tmp
,
392 1, &CipherSuiteWpaPskAesLen
,
393 CipherSuiteWpaPskAesLen
, &CipherSuiteWpaPskAes
[0],
397 // Add by James 03/06/27
399 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &WpaIe
, 1);
401 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &CipherSuiteWpaPskAesLen
, 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
;
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
;
425 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
427 RTMPSetTimer(pAd
, &pAd
->Mlme
.AssocAux
.AssocTimer
, Timeout
);
428 pAd
->Mlme
.AssocMachine
.CurrState
= ASSOC_WAIT_RSP
;
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 ==========================================================================
442 mlme reassoc req handling procedure
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
)
459 UCHAR SsidIe
= IE_SSID
, RateIe
= IE_SUPP_RATES
, ExtRateIe
= IE_EXT_SUPP_RATES
;
460 USHORT CapabilityInfo
, ListenIntv
;
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
);
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
,
501 MAC_ADDR_LEN
, &pAd
->PortCfg
.Bssid
,
503 1, &pAd
->PortCfg
.SsidLen
,
504 pAd
->PortCfg
.SsidLen
, pAd
->PortCfg
.Ssid
,
506 1, &pAd
->PortCfg
.SupRateLen
,
507 pAd
->PortCfg
.SupRateLen
, pAd
->PortCfg
.SupRate
,
509 if (pAd
->PortCfg
.ExtRateLen
!= 0)
511 MakeOutgoingFrame(OutBuffer
+ FrameLen
, &tmp
,
513 1, &pAd
->PortCfg
.ExtRateLen
,
514 pAd
->PortCfg
.ExtRateLen
, pAd
->PortCfg
.ExtRate
,
518 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
520 RTMPSetTimer(pAd
, &pAd
->Mlme
.AssocAux
.ReassocTimer
, Timeout
); /* in mSec */
521 pAd
->Mlme
.AssocMachine
.CurrState
= REASSOC_WAIT_RSP
;
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 ==========================================================================
534 Upper layer issues disassoc request
537 ==========================================================================
539 VOID
MlmeDisassocReqAction(
540 IN PRTMP_ADAPTER pAd
,
541 IN MLME_QUEUE_ELEM
*Elem
)
543 MLME_DISASSOC_REQ_STRUCT
*DisassocReq
;
545 CHAR
*OutBuffer
= NULL
;
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
);
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
,
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 ==========================================================================
583 peer sends assoc rsp back
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
;
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
);
617 DBGPRINT(RT_DEBUG_TRACE
, "ASSOC - PeerAssocRspAction() sanity check fail\n");
622 ==========================================================================
624 peer sends reassoc rsp
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
;
636 UCHAR Rates
[MAX_LEN_OF_SUPPORTED_RATES
];
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
);
662 DBGPRINT(RT_DEBUG_TRACE
, "ASSOC - PeerReassocRspAction() sanity check fail\n");
667 ==========================================================================
669 procedures on IEEE 802.11/1999 p.376
671 ==========================================================================
674 IN PRTMP_ADAPTER pAd
,
676 IN USHORT CapabilityInfo
,
680 IN BOOLEAN ExtendedRateIeExist
)
683 UCHAR RateIe
= IE_SUPP_RATES
;
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");
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
720 NdisMoveMemory(pAd
->PortCfg
.ResVarIEs
+ VarIesOffset
, &RateIe
, 1);
722 NdisMoveMemory(pAd
->PortCfg
.ResVarIEs
+ VarIesOffset
, &RatesLen
, 1);
724 NdisMoveMemory(pAd
->PortCfg
.ResVarIEs
+ VarIesOffset
, Rates
, RatesLen
);
725 VarIesOffset
+= RatesLen
;
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
;
739 ==========================================================================
741 left part of IEEE 802.11/1999 p.374
743 Elem - MLME message containing the received frame
744 ==========================================================================
746 VOID
PeerDisassocAction(
747 IN PRTMP_ADAPTER pAd
,
748 IN MLME_QUEUE_ELEM
*Elem
)
753 if(PeerDisassocSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &Addr2
, &Reason
))
755 if (INFRA_ON(pAd
) && MAC_ADDR_EQUAL(&pAd
->PortCfg
.Bssid
, &Addr2
))
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
);
767 DBGPRINT(RT_DEBUG_TRACE
, "ASSOC - PeerDisassocAction() sanity check fail\n");
772 ==========================================================================
774 what the state machine will do after assoc timeout
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 ==========================================================================
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 ==========================================================================
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 ==========================================================================
851 right part of IEEE 802.11/1999 page 374
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 ==========================================================================
859 IN PRTMP_ADAPTER pAd
,
863 CHAR
*OutBuffer
= NULL
;
866 USHORT Reason
= REASON_CLS3ERR
;
868 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
869 if (NStatus
!= NDIS_STATUS_SUCCESS
)
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
,
878 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
880 pAd
->PortCfg
.DisassocReason
= REASON_CLS3ERR
;
881 COPY_MAC_ADDR(&pAd
->PortCfg
.DisassocSta
, pAddr
);