|
1 /* |
|
2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Implementation of the WlanDot11AuthenticatePending class |
|
15 * |
|
16 */ |
|
17 |
|
18 /* |
|
19 * %version: 38 % |
|
20 */ |
|
21 |
|
22 #include "config.h" |
|
23 #include "UmacDot11AuthenticatePending.h" |
|
24 #include "UmacContextImpl.h" |
|
25 |
|
26 #ifndef NDEBUG |
|
27 const TUint8 WlanDot11AuthenticatePending::iStateName |
|
28 [ESTATEMAX][KMaxStateStringLength] = |
|
29 { |
|
30 {"EINIT"}, |
|
31 {"ETXAUTHFRAME"}, |
|
32 {"EWAIT4AUTHRESPONSE"}, |
|
33 {"EWAIT4PUSHPACKET"}, |
|
34 {"ECONTINUEDOT11TRAVERSE"} |
|
35 }; |
|
36 |
|
37 const TUint8 WlanDot11AuthenticatePending::iEventName |
|
38 [EEVENTMAX][KMaxEventStringLength] = |
|
39 { |
|
40 {"ESTATEENTRY"}, {"ECONTINUE"}, {"ERXAUTHRESPONSE"}, |
|
41 {"ETX_AUTHFRAME_XFER"}, {"ETX_SCHEDULER_FULL"}, |
|
42 {"ETIMEOUT"}, {"EPUSHPACKET"} |
|
43 }; |
|
44 #endif |
|
45 // ================= MEMBER FUNCTIONS ======================= |
|
46 |
|
47 // ----------------------------------------------------------------------------- |
|
48 // |
|
49 // ----------------------------------------------------------------------------- |
|
50 // |
|
51 void WlanDot11AuthenticatePending::Entry( |
|
52 WlanContextImpl& aCtxImpl ) |
|
53 { |
|
54 OsTracePrint( KUmacProtocolState | KUmacAuth, |
|
55 (TUint8*)("UMAC * execute dot11 authenticate")); |
|
56 |
|
57 if ( aCtxImpl.WsaCmdActive() ) |
|
58 { |
|
59 // sanity checking code |
|
60 OsAssert( (TUint8*)("UMAC * panic"), (TUint8*)(WLAN_FILE), __LINE__ ); |
|
61 } |
|
62 |
|
63 // no need to do event dispatching as this |
|
64 // thing is triggered by the user and |
|
65 // is executed synchronously as we only do OID completion |
|
66 // at the end of authenticate + association process |
|
67 // for the same reason we don't execute any asynchronous WHA commands |
|
68 // from here so authetication protocol does not include multiple |
|
69 // this object entry method executions |
|
70 |
|
71 if ( iState == EINIT ) |
|
72 { |
|
73 // this is the start of the the FSM actions |
|
74 Fsm( aCtxImpl, ESTATEENTRY ); |
|
75 } |
|
76 else |
|
77 { |
|
78 // implementation error see comment block above why |
|
79 #ifndef NDEBUG |
|
80 OsTracePrint( KErrorLevel, (TUint8*)("state:")); |
|
81 OsTracePrint( KErrorLevel, iStateName[iState] ); |
|
82 #endif |
|
83 OsAssert( (TUint8*)("UMAC * panic"), (TUint8*)(WLAN_FILE), __LINE__ ); |
|
84 } |
|
85 } |
|
86 |
|
87 // ----------------------------------------------------------------------------- |
|
88 // |
|
89 // ----------------------------------------------------------------------------- |
|
90 // |
|
91 void WlanDot11AuthenticatePending::Exit( |
|
92 WlanContextImpl& /*aCtxImpl*/ ) |
|
93 { |
|
94 // we are departing this dot11state to another dot11state, |
|
95 // which means we are either: |
|
96 // 1) proceeding to WlanDot11AssociationPending state |
|
97 // in case of authentication success |
|
98 // 2) proceeding to WlanDot11Idle state |
|
99 // in case of authentication failure |
|
100 // we simple reset our local FSM for the next time... |
|
101 iState = EINIT; |
|
102 } |
|
103 |
|
104 // ----------------------------------------------------------------------------- |
|
105 // |
|
106 // ----------------------------------------------------------------------------- |
|
107 // |
|
108 void WlanDot11AuthenticatePending::StateEntryActions( |
|
109 WlanContextImpl& aCtxImpl ) |
|
110 { |
|
111 iFlags = 0; |
|
112 |
|
113 if ( aCtxImpl.HtSupportedByNw() ) |
|
114 { |
|
115 aCtxImpl.GetHtAuthenticationFrame().ResetSeqNmbr(); |
|
116 aCtxImpl.GetHtAuthenticationFrame().ClearWepBit(); |
|
117 } |
|
118 else |
|
119 { |
|
120 aCtxImpl.GetAuthenticationFrame().ResetSeqNmbr(); |
|
121 aCtxImpl.GetAuthenticationFrame().ClearWepBit(); |
|
122 } |
|
123 |
|
124 aCtxImpl.ResetAuthSeqNmbrExpected(); |
|
125 |
|
126 // its up to our sub states to fill this block |
|
127 OnSetAlgorithmNumber( aCtxImpl ); |
|
128 } |
|
129 |
|
130 // ----------------------------------------------------------------------------- |
|
131 // Start authentication frame response timer |
|
132 // ----------------------------------------------------------------------------- |
|
133 // |
|
134 void WlanDot11AuthenticatePending::StartAuthenticationFrameResponseTimer( |
|
135 WlanContextImpl& aCtxImpl ) |
|
136 { |
|
137 // start authentication frame response timeout timer |
|
138 const TUint32 timeout( dot11AuthenticationResponseTimeOut * KTU ); |
|
139 |
|
140 OsTracePrint( KUmacAuth, ( |
|
141 TUint8*)("UMAC: WlanDot11AuthenticatePending::StartAuthenticationFrameResponseTimer:timeout in microseconds: %d"), |
|
142 timeout ); |
|
143 |
|
144 aCtxImpl.iUmac.RegisterTimeout( timeout ); |
|
145 } |
|
146 |
|
147 // ----------------------------------------------------------------------------- |
|
148 // Send authenticate seq.number 1 message |
|
149 // ----------------------------------------------------------------------------- |
|
150 // |
|
151 TBool WlanDot11AuthenticatePending::SendAuthSeqNbr1Frame( |
|
152 WlanContextImpl& aCtxImpl ) const |
|
153 { |
|
154 OsTracePrint( KUmacAuth, (TUint8*) |
|
155 ("UMAC: WlanDot11AuthenticatePending::SendAuthSeqNbr1Frame") ); |
|
156 |
|
157 TBool status ( EFalse ); |
|
158 |
|
159 // client doesn't have to take care of the tx buffer header space |
|
160 // as the method below does that by itself |
|
161 TUint8* start_of_frame = aCtxImpl.TxBuffer( ETrue ); |
|
162 |
|
163 if ( start_of_frame ) |
|
164 { |
|
165 TUint32 frameLength ( 0 ); |
|
166 |
|
167 if ( aCtxImpl.HtSupportedByNw() && aCtxImpl.QosEnabled() ) |
|
168 { |
|
169 OsTracePrint( KUmacAuth, (TUint8*) |
|
170 ("UMAC: Algorithm number: %d"), |
|
171 aCtxImpl.GetHtAuthenticationFrame().GetAlgorithmNumber()); |
|
172 OsTracePrint( KUmacAuth, (TUint8*) |
|
173 ("UMAC: Sequence number: %d"), |
|
174 aCtxImpl.GetHtAuthenticationFrame().GetSeqNmbr()); |
|
175 OsTracePrint( KUmacAuth, (TUint8*) |
|
176 ("UMAC: Status code: %d"), |
|
177 aCtxImpl.GetHtAuthenticationFrame().GetStatusCode()); |
|
178 |
|
179 frameLength = sizeof( SHtAuthenticationFrame ); |
|
180 |
|
181 os_memcpy( |
|
182 start_of_frame, |
|
183 &(aCtxImpl.GetHtAuthenticationFrame()), |
|
184 frameLength ); |
|
185 } |
|
186 else |
|
187 { |
|
188 OsTracePrint( KUmacAuth, (TUint8*) |
|
189 ("UMAC: Algorithm number: %d"), |
|
190 aCtxImpl.GetAuthenticationFrame().GetAlgorithmNumber()); |
|
191 OsTracePrint( KUmacAuth, (TUint8*) |
|
192 ("UMAC: Sequence number: %d"), |
|
193 aCtxImpl.GetAuthenticationFrame().GetSeqNmbr()); |
|
194 OsTracePrint( KUmacAuth, (TUint8*) |
|
195 ("UMAC: Status code: %d"), |
|
196 aCtxImpl.GetAuthenticationFrame().GetStatusCode()); |
|
197 |
|
198 frameLength = sizeof( SAuthenticationFrame ); |
|
199 |
|
200 os_memcpy( |
|
201 start_of_frame, |
|
202 &(aCtxImpl.GetAuthenticationFrame()), |
|
203 frameLength ); |
|
204 } |
|
205 |
|
206 // trace the frame critter |
|
207 OsTracePrint( KUmacAuth, (TUint8*)("UMAC: dot11 authenticate frame tx:"), |
|
208 *(reinterpret_cast<const Sdot11MacHeader*>(start_of_frame)) ); |
|
209 |
|
210 const WHA::TQueueId queue_id |
|
211 = QueueId( aCtxImpl, start_of_frame ); |
|
212 |
|
213 // push the frame to packet scheduler for transmission |
|
214 status = aCtxImpl.PushPacketToPacketScheduler( |
|
215 start_of_frame, |
|
216 frameLength, |
|
217 queue_id, |
|
218 E802Dot11FrameTypeAuthSeqNmbr1, |
|
219 NULL, |
|
220 EFalse, |
|
221 EFalse, |
|
222 ETrue ); |
|
223 |
|
224 if ( !status ) |
|
225 { |
|
226 // as we came here we did get an internal Tx buffer for the frame |
|
227 // but packet push to scheduler failed. In this case we need cancel |
|
228 // the internal Tx buffer reservation as we will request it again |
|
229 // when the Packet Scheduler is again ready for packet push |
|
230 aCtxImpl.MarkInternalTxBufFree(); |
|
231 } |
|
232 } |
|
233 else |
|
234 { |
|
235 // we didn't get a Tx buffer. EFalse will be returned |
|
236 // to indicate that |
|
237 OsTracePrint( KUmacAuth, (TUint8*) |
|
238 ("UMAC: WlanDot11AuthenticatePending::SendAuthSeqNbr1Frame: no internal Tx buffer available") ); |
|
239 } |
|
240 |
|
241 return status; |
|
242 } |
|
243 |
|
244 // ----------------------------------------------------------------------------- |
|
245 // completion method called when packet has been xferred to the WLAN device |
|
246 // ----------------------------------------------------------------------------- |
|
247 // |
|
248 void WlanDot11AuthenticatePending::OnPacketTransferComplete( |
|
249 WlanContextImpl& aCtxImpl, |
|
250 TUint32 aPacketId, |
|
251 TDataBuffer* aMetaHeader ) |
|
252 { |
|
253 OsTracePrint( KUmacAuth, (TUint8*) |
|
254 ("UMAC: WlanDot11AuthenticatePending::OnPacketTransferComplete")); |
|
255 |
|
256 if ( aPacketId == E802Dot11FrameTypeData ) |
|
257 { |
|
258 OnTxProtocolStackDataComplete( aCtxImpl, aMetaHeader ); |
|
259 } |
|
260 else if ( aPacketId == E802Dot11FrameTypeDataEapol || |
|
261 aPacketId == E802Dot11FrameTypeManagementAction || |
|
262 aPacketId == E802Dot11FrameTypeTestFrame ) |
|
263 { |
|
264 OnMgmtPathWriteComplete( aCtxImpl ); |
|
265 } |
|
266 else |
|
267 { |
|
268 // this frame Tx request didn't come from above us (i.e. neither |
|
269 // through the user data nor the management data API) but is |
|
270 // related to a frame Tx we have done internally. So we need to mark |
|
271 // the internal Tx buffer free again |
|
272 aCtxImpl.MarkInternalTxBufFree(); |
|
273 } |
|
274 |
|
275 if ( aPacketId == E802Dot11FrameTypeAuthSeqNmbr1 |
|
276 || aPacketId == E802Dot11FrameTypeAuthSeqNmbr3 ) |
|
277 { |
|
278 // authenticate tx message has been xferred to the WLAN device |
|
279 |
|
280 // so feed an event critter to the fsm |
|
281 Fsm( aCtxImpl, ETX_AUTHFRAME_XFER ); |
|
282 } |
|
283 } |
|
284 |
|
285 // ----------------------------------------------------------------------------- |
|
286 // |
|
287 // ----------------------------------------------------------------------------- |
|
288 // |
|
289 TBool WlanDot11AuthenticatePending::ResolveAuthMessage( |
|
290 WlanContextImpl& aCtxImpl, |
|
291 TUint16 aAuthModeDesired, |
|
292 const void* aFrame, |
|
293 TUint32 aFlags ) |
|
294 { |
|
295 TBool ret( EFalse ); |
|
296 const SAuthenticationFixedFields* auth_fields = |
|
297 HtcFieldPresent( aCtxImpl, aFrame, aFlags ) ? |
|
298 reinterpret_cast<const SAuthenticationFixedFields*> |
|
299 (reinterpret_cast<const TUint8*>(aFrame) + |
|
300 sizeof( SHtManagementFrameHeader )) : |
|
301 reinterpret_cast<const SAuthenticationFixedFields*> |
|
302 (reinterpret_cast<const TUint8*>(aFrame) + |
|
303 sizeof( SManagementFrameHeader )); |
|
304 |
|
305 OsTracePrint( KUmacAuth, (TUint8*) |
|
306 ("UMAC: WlanDot11AuthenticatePending::ResolveAuthMessage: auth message sequence number expected: %d"), |
|
307 aCtxImpl.GetAuthSeqNmbrExpected() ); |
|
308 OsTracePrint( KUmacAuth, (TUint8*) |
|
309 ("UMAC: WlanDot11AuthenticatePending::ResolveAuthMessage: auth message sequence number: %d"), |
|
310 auth_fields->SequenceNumber() ); |
|
311 OsTracePrint( KUmacAuth, (TUint8*) |
|
312 ("UMAC: WlanDot11AuthenticatePending::ResolveAuthMessage: algorithm number expected: %d"), |
|
313 aAuthModeDesired ); |
|
314 OsTracePrint( KUmacAuth, (TUint8*) |
|
315 ("UMAC: WlanDot11AuthenticatePending::ResolveAuthMessage: algorithm number: %d"), |
|
316 auth_fields->AlgorithmNumber() ); |
|
317 OsTracePrint( KUmacAuth, (TUint8*) |
|
318 ("UMAC: WlanDot11AuthenticatePending::ResolveAuthMessage: status code: %d"), |
|
319 auth_fields->StatusCode() ); |
|
320 |
|
321 if ( // is desired mode authentication |
|
322 ( auth_fields->AlgorithmNumber() == aAuthModeDesired ) |
|
323 // AND is authentication transaction sequence number expected |
|
324 && ( auth_fields->SequenceNumber() == aCtxImpl.GetAuthSeqNmbrExpected() ) |
|
325 // AND the status code is successful |
|
326 && ( auth_fields->StatusCode() == E802Dot11StatusSuccess )) |
|
327 { |
|
328 ret = ETrue; |
|
329 } |
|
330 |
|
331 return ret; |
|
332 } |
|
333 |
|
334 // ----------------------------------------------------------------------------- |
|
335 // |
|
336 // ----------------------------------------------------------------------------- |
|
337 // |
|
338 void WlanDot11AuthenticatePending::ChangeInternalState( |
|
339 WlanContextImpl& aCtxImpl, |
|
340 TState aNewState ) |
|
341 { |
|
342 iState = aNewState; |
|
343 Fsm( aCtxImpl, ESTATEENTRY ); |
|
344 } |
|
345 |
|
346 // ----------------------------------------------------------------------------- |
|
347 // |
|
348 // ----------------------------------------------------------------------------- |
|
349 // |
|
350 void WlanDot11AuthenticatePending::Fsm( |
|
351 WlanContextImpl& aCtxImpl, |
|
352 TEvent aEvent ) |
|
353 { |
|
354 OsTracePrint( KUmacAuth, |
|
355 (TUint8*)("UMAC * dot11-authenticatepending * FSM EVENT") ); |
|
356 #ifndef NDEBUG |
|
357 OsTracePrint( KUmacAuth, (TUint8*)("event:")); |
|
358 OsTracePrint( KUmacAuth, iEventName[aEvent] ); |
|
359 OsTracePrint( KUmacAuth, (TUint8*)("state:")); |
|
360 OsTracePrint( KUmacAuth, iStateName[iState] ); |
|
361 #endif |
|
362 |
|
363 switch ( aEvent ) |
|
364 { |
|
365 case ESTATEENTRY: |
|
366 OnStateEntryEvent( aCtxImpl ); |
|
367 break; |
|
368 case ECONTINUE: |
|
369 OnContinueEvent( aCtxImpl ); |
|
370 break; |
|
371 case ERXAUTHRESPONSE: |
|
372 OnRxAuthResponseEvent( aCtxImpl ); |
|
373 break; |
|
374 case ETX_AUTHFRAME_XFER: |
|
375 OnTxAuthFrameXferEvent( aCtxImpl ); |
|
376 break; |
|
377 case ETX_SCHEDULER_FULL: |
|
378 OnTxSchedulerFullEvent( aCtxImpl ); |
|
379 break; |
|
380 case ETIMEOUT: |
|
381 OnTimeoutEvent( aCtxImpl ); |
|
382 break; |
|
383 case EPUSHPACKET: |
|
384 OnPushPacketEvent( aCtxImpl ); |
|
385 break; |
|
386 default: |
|
387 // cath internal FSM programming error |
|
388 #ifndef NDEBUG |
|
389 OsTracePrint( KErrorLevel, (TUint8*)("event:")); |
|
390 OsTracePrint( KErrorLevel, iEventName[aEvent] ); |
|
391 #endif |
|
392 OsAssert( (TUint8*)("* UMAC * panic"), |
|
393 (TUint8*)(WLAN_FILE), __LINE__ ); |
|
394 break; |
|
395 } |
|
396 } |
|
397 |
|
398 // ----------------------------------------------------------------------------- |
|
399 // Handler for generic continue event. |
|
400 // ----------------------------------------------------------------------------- |
|
401 // |
|
402 void WlanDot11AuthenticatePending::OnContinueEvent( |
|
403 WlanContextImpl& aCtxImpl ) |
|
404 { |
|
405 switch ( iState ) |
|
406 { |
|
407 case EINIT: |
|
408 ChangeInternalState( aCtxImpl, ETXAUTHFRAME ); |
|
409 break; |
|
410 default: |
|
411 // catch internal FSM programming error |
|
412 #ifndef NDEBUG |
|
413 OsTracePrint( KErrorLevel, (TUint8*)("state:")); |
|
414 OsTracePrint( KErrorLevel, iStateName[iState] ); |
|
415 #endif |
|
416 OsAssert( (TUint8*)("* UMAC * panic"), |
|
417 (TUint8*)(WLAN_FILE), __LINE__ ); |
|
418 break; |
|
419 } |
|
420 } |
|
421 |
|
422 // ----------------------------------------------------------------------------- |
|
423 // Handler for authentication response timeout event. |
|
424 // ----------------------------------------------------------------------------- |
|
425 // |
|
426 void WlanDot11AuthenticatePending::OnTimeoutEvent( |
|
427 WlanContextImpl& aCtxImpl ) |
|
428 { |
|
429 // set completion code |
|
430 // as dot11idle state does the OID completion |
|
431 aCtxImpl.iStates.iIdleState.Set( KErrTimedOut ); |
|
432 // authentication was not successful |
|
433 iFlags &= ~KAuthSuccess; |
|
434 ChangeInternalState( aCtxImpl, ECONTINUEDOT11TRAVERSE ); |
|
435 } |
|
436 |
|
437 // ----------------------------------------------------------------------------- |
|
438 // Handler for push packet to packet scheduler possible event |
|
439 // ----------------------------------------------------------------------------- |
|
440 // |
|
441 void WlanDot11AuthenticatePending::OnPushPacketEvent( |
|
442 WlanContextImpl& aCtxImpl ) |
|
443 { |
|
444 if ( iState == EWAIT4PUSHPACKET ) |
|
445 { |
|
446 ChangeInternalState( aCtxImpl, ETXAUTHFRAME ); |
|
447 } |
|
448 } |
|
449 |
|
450 // ----------------------------------------------------------------------------- |
|
451 // Handler for authenticate request frame |
|
452 // has been xferred to the WLAN device event |
|
453 // ----------------------------------------------------------------------------- |
|
454 // |
|
455 void WlanDot11AuthenticatePending::OnTxAuthFrameXferEvent( |
|
456 WlanContextImpl& aCtxImpl ) |
|
457 { |
|
458 // change state |
|
459 ChangeInternalState( aCtxImpl, EWAIT4AUTHRESPONSE ); |
|
460 } |
|
461 |
|
462 // ----------------------------------------------------------------------------- |
|
463 // Handler for scheduler full event upon trying to tx dot11-authenticate frame |
|
464 // ----------------------------------------------------------------------------- |
|
465 // |
|
466 void WlanDot11AuthenticatePending::OnTxSchedulerFullEvent( |
|
467 WlanContextImpl& aCtxImpl ) |
|
468 { |
|
469 // change state |
|
470 OsTracePrint( KWarningLevel | KUmacAuth, (TUint8*) |
|
471 ("UMAC: packet scheduler full during authentication process") ); |
|
472 |
|
473 ChangeInternalState( aCtxImpl, EWAIT4PUSHPACKET ); |
|
474 } |
|
475 |
|
476 // ----------------------------------------------------------------------------- |
|
477 // continue dot11 protocol statemachine traversal |
|
478 // ----------------------------------------------------------------------------- |
|
479 // |
|
480 void WlanDot11AuthenticatePending::ContinueDot11StateTraversal( |
|
481 WlanContextImpl& aCtxImpl ) |
|
482 { |
|
483 if ( iFlags & KAuthSuccess ) |
|
484 { |
|
485 // authentication was a success |
|
486 // so we proceed to reassociation state - if this happens to be a |
|
487 // roaming case - or to association state |
|
488 // |
|
489 if ( aCtxImpl.Reassociate() ) |
|
490 { |
|
491 ChangeState( aCtxImpl, |
|
492 *this, // prev state |
|
493 aCtxImpl.iStates.iReassociationPendingState // next state |
|
494 ); |
|
495 } |
|
496 else |
|
497 { |
|
498 ChangeState( aCtxImpl, |
|
499 *this, // prev state |
|
500 aCtxImpl.iStates.iAssociationPendingState // next state |
|
501 ); |
|
502 } |
|
503 } |
|
504 else |
|
505 { |
|
506 // authentication was a failure |
|
507 // either due AP denial or by timeout |
|
508 // the reason does not really intrest us here |
|
509 // as the procedure is the same... |
|
510 ChangeState( aCtxImpl, |
|
511 *this, // prev state |
|
512 aCtxImpl.iStates.iIdleState // next state |
|
513 ); |
|
514 } |
|
515 } |
|
516 |
|
517 // ----------------------------------------------------------------------------- |
|
518 // |
|
519 // ----------------------------------------------------------------------------- |
|
520 // |
|
521 TBool WlanDot11AuthenticatePending::OnTimeout( |
|
522 WlanContextImpl& aCtxImpl ) |
|
523 { |
|
524 TBool stateChange ( ETrue ); |
|
525 |
|
526 switch ( iState ) |
|
527 { |
|
528 case EWAIT4AUTHRESPONSE: |
|
529 // authentication response timeout |
|
530 |
|
531 OsTracePrint( KWarningLevel | KUmacAssoc, (TUint8*) |
|
532 ("UMAC: WlanDot11AuthenticatePending::OnTimeout: authentication resp. timeout => authenication failed!") ); |
|
533 |
|
534 Fsm( aCtxImpl, ETIMEOUT ); |
|
535 |
|
536 // in this case we return ETrue, i.e. signal the caller that a |
|
537 // state change occurred |
|
538 |
|
539 break; |
|
540 default: |
|
541 // a timeout occurred when we weren't expecting it (yet). This |
|
542 // means that a timeout callback had already been registered when |
|
543 // we tried to cancel this timer the previous time (regarding |
|
544 // the previous authentication frame). So this callback is not |
|
545 // relevant and can be ignored. |
|
546 |
|
547 OsTracePrint( KWarningLevel | KUmacAssoc, (TUint8*) |
|
548 ("UMAC: WlanDot11AuthenticatePending::OnTimeout: irrelevant timeout; ignored") ); |
|
549 |
|
550 // Signal the caller that no state change occurred |
|
551 stateChange = EFalse; |
|
552 } |
|
553 |
|
554 return stateChange; |
|
555 } |
|
556 |
|
557 // ----------------------------------------------------------------------------- |
|
558 // |
|
559 // ----------------------------------------------------------------------------- |
|
560 // |
|
561 void WlanDot11AuthenticatePending::ReceivePacket( |
|
562 WlanContextImpl& aCtxImpl, |
|
563 WHA::TStatus aStatus, |
|
564 const void* aFrame, |
|
565 TUint16 aLength, |
|
566 WHA::TRate /*aRate*/, |
|
567 WHA::TRcpi aRcpi, |
|
568 WHA::TChannelNumber /*aChannel*/, |
|
569 TUint8* aBuffer, |
|
570 TUint32 aFlags ) |
|
571 { |
|
572 OsTracePrint( KUmacAuth, (TUint8*) |
|
573 ("UMAC: dot11-authenticatepending::ReceivePacket()") ); |
|
574 |
|
575 if ( aStatus == WHA::KSuccess ) |
|
576 { |
|
577 // receive success |
|
578 const Sdot11MacHeader* dot11_hdr( |
|
579 static_cast<const Sdot11MacHeader*>(aFrame) ); |
|
580 |
|
581 // we accept only frames with ToDS bit cleared |
|
582 if ( dot11_hdr->IsToDsBitSet() ) |
|
583 { |
|
584 OsTracePrint( KWarningLevel | KUmacAuth, |
|
585 (TUint8*)("UMAC: authenticating to BSS:") ); |
|
586 OsTracePrint( KWarningLevel | KUmacAuth, |
|
587 (TUint8*)("UMAC: rx-frame: ToDs bit set, discard frame") ); |
|
588 |
|
589 // release the Rx buffer & abort |
|
590 aCtxImpl.iUmac.MarkRxBufFree( aBuffer ); |
|
591 return; |
|
592 } |
|
593 |
|
594 const TBool class2_frame( IsClass2Frame( dot11_hdr->iFrameControl.iType ) ); |
|
595 const TBool class3_frame( IsClass3Frame( dot11_hdr->iFrameControl.iType ) ); |
|
596 const TBool unicast_addr( !IsGroupBitSet( dot11_hdr->iAddress1 ) ); |
|
597 |
|
598 if ( class2_frame && unicast_addr ) |
|
599 { |
|
600 OsTracePrint( KWarningLevel | KUmacAuth, |
|
601 (TUint8*)("UMAC: authenticating to BSS:") ); |
|
602 OsTracePrint( KWarningLevel | KUmacAuth, |
|
603 (TUint8*)("rx class2 frame with unicast DA address") ); |
|
604 |
|
605 // class 2 frame rx and unicast address in address1 field |
|
606 // That's not the frame we are expecting. |
|
607 // Note that we release the Rx buffer at the end of this method |
|
608 |
|
609 if ( !Authenticated() ) |
|
610 { |
|
611 // we do not have a valid authentication with the |
|
612 // BSS where the frame came |
|
613 OsTracePrint( KWarningLevel | KUmacAuth, |
|
614 (TUint8*)("TxDeauthenticate") ); |
|
615 if ( !TxDeauthenticate( |
|
616 aCtxImpl, |
|
617 E802Dot11ReasonClass2FrameWhenNotAuth ) ) |
|
618 { |
|
619 // frame was not sent because either packet scheduler was |
|
620 // full or because we didn't get a Tx buffer. In any case |
|
621 // we won't try to send it again. |
|
622 } |
|
623 } |
|
624 } |
|
625 else if ( class3_frame && unicast_addr ) |
|
626 { |
|
627 OsTracePrint( KWarningLevel | KUmacAuth, |
|
628 (TUint8*)("UMAC: authenticating to BSS:") ); |
|
629 OsTracePrint( KWarningLevel | KUmacAuth, |
|
630 (TUint8*)("rx class3 frame with unicast DA address") ); |
|
631 |
|
632 // class 3 frame rx and unicast address in address1 field |
|
633 // That's not the frame we are expecting |
|
634 // Note that we release the Rx buffer at the end of this method |
|
635 |
|
636 if ( !Authenticated() ) |
|
637 { |
|
638 // we do not have a valid authentication with the |
|
639 // BSS where the frame came |
|
640 OsTracePrint( KWarningLevel | KUmacAuth, |
|
641 (TUint8*)("TxDeauthenticate") ); |
|
642 if ( !TxDeauthenticate( |
|
643 aCtxImpl, |
|
644 E802Dot11ReasonClass3FrameWhenNotAssoc ) ) |
|
645 { |
|
646 // frame was not sent because either packet scheduler was |
|
647 // full or because we didn't get a Tx buffer. In any case |
|
648 // we won't try to send it again. |
|
649 } |
|
650 } |
|
651 else |
|
652 { |
|
653 // we do have a valid authentication with the |
|
654 // STA that sent the frame |
|
655 OsTracePrint( KWarningLevel | KUmacAuth, |
|
656 (TUint8*)("UMAC: TxDisassociate") ); |
|
657 |
|
658 // set the BSSID of the existing network; and the DA |
|
659 if ( aCtxImpl.HtSupportedByNw() ) |
|
660 { |
|
661 (aCtxImpl.GetHtDisassociationFrame()).iHeader.iBSSID = |
|
662 aCtxImpl.GetBssId(); |
|
663 (aCtxImpl.GetHtDisassociationFrame()).iHeader.iDA = |
|
664 aCtxImpl.GetBssId(); |
|
665 } |
|
666 else |
|
667 { |
|
668 (aCtxImpl.GetDisassociationFrame()).iHeader.iBSSID = |
|
669 aCtxImpl.GetBssId(); |
|
670 (aCtxImpl.GetDisassociationFrame()).iHeader.iDA = |
|
671 aCtxImpl.GetBssId(); |
|
672 } |
|
673 if ( !TxDisassociate( |
|
674 aCtxImpl, |
|
675 E802Dot11ReasonClass3FrameWhenNotAssoc ) ) |
|
676 { |
|
677 // frame was not sent because either packet scheduler was |
|
678 // full or because we didn't get a Tx buffer. In any case |
|
679 // we won't try to send it again. |
|
680 } |
|
681 } |
|
682 } |
|
683 else |
|
684 { |
|
685 // default handler |
|
686 OnReceiveFrameSuccess( |
|
687 aCtxImpl, |
|
688 aFrame, |
|
689 aLength, |
|
690 aRcpi, |
|
691 aFlags, |
|
692 aBuffer ); |
|
693 } |
|
694 } |
|
695 else // aStatus == WHA::KSuccess |
|
696 { |
|
697 // receive failed, so no action here |
|
698 } |
|
699 |
|
700 // release the Rx buffer |
|
701 aCtxImpl.iUmac.MarkRxBufFree( aBuffer ); |
|
702 } |
|
703 |
|
704 // ----------------------------------------------------------------------------- |
|
705 // packet sceduler notification that a packet push is guaranteed to succeed |
|
706 // ----------------------------------------------------------------------------- |
|
707 // |
|
708 void WlanDot11AuthenticatePending::OnPacketPushPossible( |
|
709 WlanContextImpl& aCtxImpl ) |
|
710 { |
|
711 // feed a critter to the fsm |
|
712 Fsm( aCtxImpl, EPUSHPACKET ); |
|
713 } |