1 /****************************************************************************
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
));
63 ==========================================================================
65 association state machine init, including state transition and timer init
67 S - pointer to the association state machine
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(
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
);
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);
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
);
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
);
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 ==========================================================================
135 Association timeout procedure. After association timeout, this function
136 will be called and it will put a message into the MLME queue
138 Standard timer parameters
139 ==========================================================================
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
);
151 ==========================================================================
153 Reassociation timeout procedure. After reassociation timeout, this
154 function will be called and put a message into the MLME queue
156 Standard timer parameters
157 ==========================================================================
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
);
169 ==========================================================================
171 Disassociation timeout procedure. After disassociation timeout, this
172 function will be called and put a message into the MLME queue
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
);
187 ==========================================================================
189 mlme assoc req handling procedure
191 Adapter - Adapter pointer
192 Elem - MLME Queue Element
194 the station has been authenticated and the following information is stored in the config
196 -# supported rates and their length
197 -# listen interval (Adapter->PortCfg.default_listen_count)
198 -# Transmit power (Adapter->PortCfg.tx_power)
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
)
211 UCHAR SsidIe
= IE_SSID
, RateIe
= IE_SUPP_RATES
,WpaIe
= IE_WPA
, ExtRateIe
= IE_EXT_SUPP_RATES
;
214 USHORT CapabilityInfo
;
215 UCHAR
*OutBuffer
= NULL
;
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
);
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
258 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &SsidIe
, 1);
260 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &pAd
->PortCfg
.SsidLen
, 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);
268 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &pAd
->PortCfg
.SupportedRatesLen
, 1);
270 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, pAd
->PortCfg
.SupportedRates
, pAd
->PortCfg
.SupportedRatesLen
);
271 VarIesOffset
+= pAd
->PortCfg
.SupportedRatesLen
;
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
,
283 1, &pAd
->PortCfg
.SsidLen
,
284 pAd
->PortCfg
.SsidLen
, pAd
->PortCfg
.Ssid
,
286 1, &pAd
->PortCfg
.SupRateLen
,
287 pAd
->PortCfg
.SupRateLen
, pAd
->PortCfg
.SupRate
,
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
);
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
);
299 // Add by James 03/06/27
301 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &WpaIe
, 1);
303 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &CipherSuiteWpaTkipLen
, 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
;
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
);
322 // Add by James 03/06/27
324 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &WpaIe
, 1);
326 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &CipherSuiteWpaAesLen
, 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
;
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
);
344 // Add by James 03/06/27
346 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &WpaIe
, 1);
348 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &CipherSuiteWpaPskTkipLen
, 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
;
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
);
366 // Add by James 03/06/27
368 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &WpaIe
, 1);
370 NdisMoveMemory(pAd
->PortCfg
.ReqVarIEs
+ VarIesOffset
, &CipherSuiteWpaPskAesLen
, 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
;
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
;
392 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
393 RTMPSetTimer(pAd
, &pAd
->Mlme
.AssocAux
.AssocTimer
, Timeout
);
394 pAd
->Mlme
.AssocMachine
.CurrState
= ASSOC_WAIT_RSP
;
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 ==========================================================================
406 mlme reassoc req handling procedure
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
)
423 UCHAR SsidIe
= IE_SSID
, RateIe
= IE_SUPP_RATES
, ExtRateIe
= IE_EXT_SUPP_RATES
;
424 USHORT CapabilityInfo
, ListenIntv
;
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
);
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
,
465 MAC_ADDR_LEN
, &pAd
->PortCfg
.Bssid
,
467 1, &pAd
->PortCfg
.SsidLen
,
468 pAd
->PortCfg
.SsidLen
, pAd
->PortCfg
.Ssid
,
470 1, &pAd
->PortCfg
.SupRateLen
,
471 pAd
->PortCfg
.SupRateLen
, pAd
->PortCfg
.SupRate
,
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
);
478 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
480 RTMPSetTimer(pAd
, &pAd
->Mlme
.AssocAux
.ReassocTimer
, Timeout
); /* in mSec */
481 pAd
->Mlme
.AssocMachine
.CurrState
= REASSOC_WAIT_RSP
;
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 ==========================================================================
492 Upper layer issues disassoc request
495 ==========================================================================
497 VOID
MlmeDisassocReqAction(
498 IN PRTMP_ADAPTER pAd
,
499 IN MLME_QUEUE_ELEM
*Elem
)
501 MLME_DISASSOC_REQ_STRUCT
*DisassocReq
;
503 CHAR
*OutBuffer
= NULL
;
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
);
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
,
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 ==========================================================================
541 peer sends assoc rsp back
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
;
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
);
575 DBGPRINT(RT_DEBUG_TRACE
, "ASSOC - PeerAssocRspAction() sanity check fail\n");
580 ==========================================================================
582 peer sends reassoc rsp
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
;
594 UCHAR Rates
[MAX_LEN_OF_SUPPORTED_RATES
];
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
);
620 DBGPRINT(RT_DEBUG_TRACE
, "ASSOC - PeerReassocRspAction() sanity check fail\n");
625 ==========================================================================
627 procedures on IEEE 802.11/1999 p.376
629 ==========================================================================
632 IN PRTMP_ADAPTER pAd
,
634 IN USHORT CapabilityInfo
,
638 IN BOOLEAN ExtendedRateIeExist
)
641 UCHAR RateIe
= IE_SUPP_RATES
;
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");
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
678 NdisMoveMemory(pAd
->PortCfg
.ResVarIEs
+ VarIesOffset
, &RateIe
, 1);
680 NdisMoveMemory(pAd
->PortCfg
.ResVarIEs
+ VarIesOffset
, &RatesLen
, 1);
682 NdisMoveMemory(pAd
->PortCfg
.ResVarIEs
+ VarIesOffset
, Rates
, RatesLen
);
683 VarIesOffset
+= RatesLen
;
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
;
697 ==========================================================================
699 left part of IEEE 802.11/1999 p.374
701 Elem - MLME message containing the received frame
702 ==========================================================================
704 VOID
PeerDisassocAction(
705 IN PRTMP_ADAPTER pAd
,
706 IN MLME_QUEUE_ELEM
*Elem
)
711 if(PeerDisassocSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &Addr2
, &Reason
))
713 if (INFRA_ON(pAd
) && MAC_ADDR_EQUAL(&pAd
->PortCfg
.Bssid
, &Addr2
))
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
);
725 DBGPRINT(RT_DEBUG_TRACE
, "ASSOC - PeerDisassocAction() sanity check fail\n");
730 ==========================================================================
732 what the state machine will do after assoc timeout
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 ==========================================================================
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 ==========================================================================
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 ==========================================================================
809 right part of IEEE 802.11/1999 page 374
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 ==========================================================================
817 IN PRTMP_ADAPTER pAd
,
821 CHAR
*OutBuffer
= NULL
;
824 USHORT Reason
= REASON_CLS3ERR
;
826 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
827 if (NStatus
!= NDIS_STATUS_SUCCESS
)
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
,
836 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
838 pAd
->PortCfg
.DisassocReason
= REASON_CLS3ERR
;
839 COPY_MAC_ADDR(&pAd
->PortCfg
.DisassocSta
, pAddr
);