2 The Mac Connection2 Protocol adapter functions for WiFi Connection Manager.
4 Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "WifiConnectionMgrDxe.h"
12 EFI_EAP_TYPE mEapAuthMethod
[] = {
18 EFI_EAP_TYPE mEapSecondAuthMethod
[] = {
22 UINT8 mWifiConnectionCount
= 0;
25 The callback function for scan operation. This function updates networks
26 according to the latest scan result, and trigger UI refresh.
28 ASSERT when errors occur in config token.
30 @param[in] Event The GetNetworks token receive event.
31 @param[in] Context The context of the GetNetworks token.
36 WifiMgrOnScanFinished (
42 WIFI_MGR_MAC_CONFIG_TOKEN
*ConfigToken
;
43 WIFI_MGR_DEVICE_DATA
*Nic
;
44 WIFI_MGR_NETWORK_PROFILE
*Profile
;
45 EFI_80211_NETWORK
*Network
;
47 EFI_80211_NETWORK_DESCRIPTION
*NetworkDescription
;
48 EFI_80211_GET_NETWORKS_RESULT
*Result
;
51 BOOLEAN AKMSuiteSupported
;
52 BOOLEAN CipherSuiteSupported
;
56 ASSERT (Context
!= NULL
);
58 ConfigToken
= (WIFI_MGR_MAC_CONFIG_TOKEN
*)Context
;
59 ASSERT (ConfigToken
->Nic
!= NULL
);
60 ASSERT (ConfigToken
->Type
== TokenTypeGetNetworksToken
);
63 // It is the GetNetworks token, set scan state to "ScanFinished"
65 ConfigToken
->Nic
->ScanState
= WifiMgrScanFinished
;
67 ASSERT (ConfigToken
->Token
.GetNetworksToken
!= NULL
);
68 Result
= ConfigToken
->Token
.GetNetworksToken
->Result
;
69 Nic
= ConfigToken
->Nic
;
72 // Clean previous result, and update network list according to the scan result
74 Nic
->AvailableCount
= 0;
76 NET_LIST_FOR_EACH (Entry
, &Nic
->ProfileList
) {
77 Profile
= NET_LIST_USER_STRUCT_S (
79 WIFI_MGR_NETWORK_PROFILE
,
81 WIFI_MGR_PROFILE_SIGNATURE
83 Profile
->IsAvailable
= FALSE
;
87 gBS
->SignalEvent (Nic
->Private
->NetworkListRefreshEvent
);
88 WifiMgrFreeToken (ConfigToken
);
92 for (Index
= 0; Index
< Result
->NumOfNetworkDesc
; Index
++) {
93 NetworkDescription
= Result
->NetworkDesc
+ Index
;
94 if (NetworkDescription
== NULL
) {
98 Network
= &NetworkDescription
->Network
;
99 if ((Network
== NULL
) || (Network
->SSId
.SSIdLen
== 0)) {
103 Status
= WifiMgrCheckRSN (
105 Network
->CipherSuite
,
109 &CipherSuiteSupported
111 if (EFI_ERROR (Status
)) {
112 SecurityType
= SECURITY_TYPE_UNKNOWN
;
113 AKMSuiteSupported
= FALSE
;
114 CipherSuiteSupported
= FALSE
;
117 AsciiSSId
= (CHAR8
*)AllocateZeroPool (sizeof (CHAR8
) * (Network
->SSId
.SSIdLen
+ 1));
118 if (AsciiSSId
== NULL
) {
122 CopyMem (AsciiSSId
, (CHAR8
*)Network
->SSId
.SSId
, sizeof (CHAR8
) * Network
->SSId
.SSIdLen
);
123 *(AsciiSSId
+ Network
->SSId
.SSIdLen
) = '\0';
125 Profile
= WifiMgrGetProfileByAsciiSSId (AsciiSSId
, SecurityType
, &Nic
->ProfileList
);
126 if (Profile
== NULL
) {
127 if (Nic
->MaxProfileIndex
>= NETWORK_LIST_COUNT_MAX
) {
128 FreePool (AsciiSSId
);
133 // Create a new profile
135 Profile
= AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE
));
136 if (Profile
== NULL
) {
137 FreePool (AsciiSSId
);
141 Profile
->Signature
= WIFI_MGR_PROFILE_SIGNATURE
;
142 Profile
->NicIndex
= Nic
->NicIndex
;
143 Profile
->ProfileIndex
= Nic
->MaxProfileIndex
+ 1;
144 AsciiStrToUnicodeStrS (AsciiSSId
, Profile
->SSId
, SSID_STORAGE_SIZE
);
145 InsertTailList (&Nic
->ProfileList
, &Profile
->Link
);
146 Nic
->MaxProfileIndex
++;
149 FreePool (AsciiSSId
);
152 // May receive duplicate networks in scan results, check if it has already
155 if (!Profile
->IsAvailable
) {
156 Profile
->IsAvailable
= TRUE
;
157 Profile
->SecurityType
= SecurityType
;
158 Profile
->AKMSuiteSupported
= AKMSuiteSupported
;
159 Profile
->CipherSuiteSupported
= CipherSuiteSupported
;
160 Profile
->NetworkQuality
= NetworkDescription
->NetworkQuality
;
161 Nic
->AvailableCount
++;
164 // Copy BSSType and SSId
166 CopyMem (&Profile
->Network
, Network
, sizeof (EFI_80211_NETWORK
));
169 // Copy AKMSuite list
171 if (Network
->AKMSuite
!= NULL
) {
172 if (Network
->AKMSuite
->AKMSuiteCount
== 0) {
173 DataSize
= sizeof (EFI_80211_AKM_SUITE_SELECTOR
);
175 DataSize
= sizeof (EFI_80211_AKM_SUITE_SELECTOR
) + sizeof (EFI_80211_SUITE_SELECTOR
)
176 * (Network
->AKMSuite
->AKMSuiteCount
- 1);
179 Profile
->Network
.AKMSuite
= (EFI_80211_AKM_SUITE_SELECTOR
*)AllocateZeroPool (DataSize
);
180 if (Profile
->Network
.AKMSuite
== NULL
) {
184 CopyMem (Profile
->Network
.AKMSuite
, Network
->AKMSuite
, DataSize
);
188 // Copy CipherSuite list
190 if (Network
->CipherSuite
!= NULL
) {
191 if (Network
->CipherSuite
->CipherSuiteCount
== 0) {
192 DataSize
= sizeof (EFI_80211_CIPHER_SUITE_SELECTOR
);
194 DataSize
= sizeof (EFI_80211_CIPHER_SUITE_SELECTOR
) + sizeof (EFI_80211_SUITE_SELECTOR
)
195 * (Network
->CipherSuite
->CipherSuiteCount
- 1);
198 Profile
->Network
.CipherSuite
= (EFI_80211_CIPHER_SUITE_SELECTOR
*)AllocateZeroPool (DataSize
);
199 if (Profile
->Network
.CipherSuite
== NULL
) {
203 CopyMem (Profile
->Network
.CipherSuite
, Network
->CipherSuite
, DataSize
);
207 // A duplicate network, update signal quality
209 if (Profile
->NetworkQuality
< NetworkDescription
->NetworkQuality
) {
210 Profile
->NetworkQuality
= NetworkDescription
->NetworkQuality
;
217 gBS
->SignalEvent (Nic
->Private
->NetworkListRefreshEvent
);
220 // The current connected network should always be available until disconnection
221 // happens in Wifi FW layer, even when it is not in this time's scan result.
223 if ((Nic
->ConnectState
== WifiMgrConnectedToAp
) && (Nic
->CurrentOperateNetwork
!= NULL
)) {
224 if (!Nic
->CurrentOperateNetwork
->IsAvailable
) {
225 Nic
->CurrentOperateNetwork
->IsAvailable
= TRUE
;
226 Nic
->AvailableCount
++;
230 WifiMgrFreeToken (ConfigToken
);
234 Start scan operation, and send out a token to collect available networks.
236 @param[in] Nic Pointer to the device data of the selected NIC.
238 @retval EFI_SUCCESS The operation is completed.
239 @retval EFI_ALREADY_STARTED A former scan operation is already ongoing.
240 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
241 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
242 @retval Other Errors Return errors when getting networks from low layer.
247 IN WIFI_MGR_DEVICE_DATA
*Nic
252 WIFI_MGR_MAC_CONFIG_TOKEN
*ConfigToken
;
253 EFI_80211_GET_NETWORKS_TOKEN
*GetNetworksToken
;
254 UINT32 HiddenSSIdIndex
;
255 UINT32 HiddenSSIdCount
;
256 EFI_80211_SSID
*HiddenSSIdList
;
257 WIFI_HIDDEN_NETWORK_DATA
*HiddenNetwork
;
260 if ((Nic
== NULL
) || (Nic
->Wmp
== NULL
)) {
261 return EFI_INVALID_PARAMETER
;
264 if (Nic
->ScanState
== WifiMgrScanning
) {
265 return EFI_ALREADY_STARTED
;
268 Nic
->ScanState
= WifiMgrScanning
;
269 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
270 Status
= EFI_SUCCESS
;
271 HiddenSSIdList
= NULL
;
272 HiddenSSIdCount
= Nic
->Private
->HiddenNetworkCount
;
276 // create a new get network token
278 ConfigToken
= AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN
));
279 if (ConfigToken
== NULL
) {
280 gBS
->RestoreTPL (OldTpl
);
281 return EFI_OUT_OF_RESOURCES
;
284 ConfigToken
->Type
= TokenTypeGetNetworksToken
;
285 ConfigToken
->Nic
= Nic
;
286 ConfigToken
->Token
.GetNetworksToken
= AllocateZeroPool (sizeof (EFI_80211_GET_NETWORKS_TOKEN
));
287 if (ConfigToken
->Token
.GetNetworksToken
== NULL
) {
288 WifiMgrFreeToken (ConfigToken
);
289 gBS
->RestoreTPL (OldTpl
);
290 return EFI_OUT_OF_RESOURCES
;
293 GetNetworksToken
= ConfigToken
->Token
.GetNetworksToken
;
296 // There are some hidden networks to scan, add them into scan list
298 if (HiddenSSIdCount
> 0) {
299 HiddenSSIdList
= AllocateZeroPool (HiddenSSIdCount
* sizeof (EFI_80211_SSID
));
300 if (HiddenSSIdList
== NULL
) {
301 WifiMgrFreeToken (ConfigToken
);
302 gBS
->RestoreTPL (OldTpl
);
303 return EFI_OUT_OF_RESOURCES
;
307 NET_LIST_FOR_EACH (Entry
, &Nic
->Private
->HiddenNetworkList
) {
308 HiddenNetwork
= NET_LIST_USER_STRUCT_S (
310 WIFI_HIDDEN_NETWORK_DATA
,
312 WIFI_MGR_HIDDEN_NETWORK_SIGNATURE
314 HiddenSSIdList
[HiddenSSIdIndex
].SSIdLen
= (UINT8
)StrLen (HiddenNetwork
->SSId
);
315 UnicodeStrToAsciiStrS (
317 (CHAR8
*)HiddenSSIdList
[HiddenSSIdIndex
].SSId
,
322 GetNetworksToken
->Data
= AllocateZeroPool (
323 sizeof (EFI_80211_GET_NETWORKS_DATA
) +
324 (HiddenSSIdCount
- 1) * sizeof (EFI_80211_SSID
)
326 if (GetNetworksToken
->Data
== NULL
) {
327 FreePool (HiddenSSIdList
);
328 WifiMgrFreeToken (ConfigToken
);
329 gBS
->RestoreTPL (OldTpl
);
330 return EFI_OUT_OF_RESOURCES
;
333 GetNetworksToken
->Data
->NumOfSSID
= HiddenSSIdCount
;
334 CopyMem (GetNetworksToken
->Data
->SSIDList
, HiddenSSIdList
, HiddenSSIdCount
* sizeof (EFI_80211_SSID
));
335 FreePool (HiddenSSIdList
);
337 GetNetworksToken
->Data
= AllocateZeroPool (sizeof (EFI_80211_GET_NETWORKS_DATA
));
338 if (GetNetworksToken
->Data
== NULL
) {
339 WifiMgrFreeToken (ConfigToken
);
340 gBS
->RestoreTPL (OldTpl
);
341 return EFI_OUT_OF_RESOURCES
;
344 GetNetworksToken
->Data
->NumOfSSID
= 0;
348 // Create a handle when scan process ends
350 Status
= gBS
->CreateEvent (
353 WifiMgrOnScanFinished
,
355 &GetNetworksToken
->Event
357 if (EFI_ERROR (Status
)) {
358 WifiMgrFreeToken (ConfigToken
);
359 gBS
->RestoreTPL (OldTpl
);
366 Status
= Nic
->Wmp
->GetNetworks (Nic
->Wmp
, GetNetworksToken
);
367 if (EFI_ERROR (Status
)) {
368 Nic
->ScanState
= WifiMgrScanFinished
;
369 WifiMgrFreeToken (ConfigToken
);
370 gBS
->RestoreTPL (OldTpl
);
374 gBS
->RestoreTPL (OldTpl
);
379 Configure password to supplicant before connecting to a secured network.
381 @param[in] Nic Pointer to the device data of the selected NIC.
382 @param[in] Profile The target network to be connected.
384 @retval EFI_SUCCESS The operation is completed.
385 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
386 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
387 @retval EFI_NOT_FOUND No valid password is found to configure.
388 @retval Other Errors Returned errors when setting data to supplicant.
392 WifiMgrConfigPassword (
393 IN WIFI_MGR_DEVICE_DATA
*Nic
,
394 IN WIFI_MGR_NETWORK_PROFILE
*Profile
398 EFI_SUPPLICANT_PROTOCOL
*Supplicant
;
400 UINT8
*AsciiPassword
;
402 if ((Nic
== NULL
) || (Nic
->Supplicant
== NULL
) || (Profile
== NULL
)) {
403 return EFI_INVALID_PARAMETER
;
406 Supplicant
= Nic
->Supplicant
;
408 // Set SSId to supplicant
410 SSId
.SSIdLen
= Profile
->Network
.SSId
.SSIdLen
;
411 CopyMem (SSId
.SSId
, Profile
->Network
.SSId
.SSId
, sizeof (Profile
->Network
.SSId
.SSId
));
412 Status
= Supplicant
->SetData (
414 EfiSupplicant80211TargetSSIDName
,
416 sizeof (EFI_80211_SSID
)
418 if (EFI_ERROR (Status
)) {
423 // Set password to supplicant
425 if (StrLen (Profile
->Password
) < PASSWORD_MIN_LEN
) {
426 return EFI_NOT_FOUND
;
429 if (StrLen (Profile
->Password
) >= PASSWORD_STORAGE_SIZE
) {
430 ASSERT (EFI_INVALID_PARAMETER
);
431 return EFI_INVALID_PARAMETER
;
434 AsciiPassword
= AllocateZeroPool ((StrLen (Profile
->Password
) + 1) * sizeof (CHAR8
));
435 if (AsciiPassword
== NULL
) {
436 return EFI_OUT_OF_RESOURCES
;
439 Status
= UnicodeStrToAsciiStrS (Profile
->Password
, (CHAR8
*)AsciiPassword
, (StrLen (Profile
->Password
) + 1));
440 if (!EFI_ERROR (Status
)) {
441 Status
= Supplicant
->SetData (
443 EfiSupplicant80211PskPassword
,
445 (StrLen (Profile
->Password
) + 1) * sizeof (CHAR8
)
449 ZeroMem (AsciiPassword
, AsciiStrLen ((CHAR8
*)AsciiPassword
) + 1);
450 FreePool (AsciiPassword
);
456 Conduct EAP configuration to supplicant before connecting to a EAP network.
457 Current WiFi Connection Manager only supports three kinds of EAP networks:
458 1). EAP-TLS (Two-Way Authentication is required in our implementation)
459 2). EAP-TTLS/MSCHAPv2 (One-Way Authentication is required in our implementation)
460 3). PEAPv0/MSCHAPv2 (One-Way Authentication is required in our implementation)
462 @param[in] Nic Pointer to the device data of the selected NIC.
463 @param[in] Profile The target network to be connected.
465 @retval EFI_SUCCESS The operation is completed.
466 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
467 @retval EFI_UNSUPPORTED The expected EAP method is not supported.
468 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
469 @retval Other Errors Returned errors when setting data to supplicant.
474 IN WIFI_MGR_DEVICE_DATA
*Nic
,
475 IN WIFI_MGR_NETWORK_PROFILE
*Profile
479 EDKII_WIFI_PROFILE_SYNC_PROTOCOL
*WiFiProfileSyncProtocol
;
480 EFI_EAP_CONFIGURATION_PROTOCOL
*EapConfig
;
481 EFI_EAP_TYPE EapAuthMethod
;
482 EFI_EAP_TYPE EapSecondAuthMethod
;
483 EFI_EAP_TYPE
*AuthMethodList
;
488 UINTN EncryptPasswordLen
;
489 CHAR8
*AsciiEncryptPassword
;
490 UINTN AuthMethodListSize
;
493 if ((Nic
== NULL
) || (Nic
->EapConfig
== NULL
) || (Profile
== NULL
)) {
494 return EFI_INVALID_PARAMETER
;
497 EapConfig
= Nic
->EapConfig
;
499 if (Profile
->EapAuthMethod
>= EAP_AUTH_METHOD_MAX
) {
500 return EFI_INVALID_PARAMETER
;
503 EapAuthMethod
= mEapAuthMethod
[Profile
->EapAuthMethod
];
505 if (EapAuthMethod
!= EFI_EAP_TYPE_EAPTLS
) {
506 if (Profile
->EapSecondAuthMethod
>= EAP_SEAUTH_METHOD_MAX
) {
507 return EFI_INVALID_PARAMETER
;
510 EapSecondAuthMethod
= mEapSecondAuthMethod
[Profile
->EapSecondAuthMethod
];
514 // The first time to get Supported Auth Method list, return the size.
516 AuthMethodListSize
= 0;
517 AuthMethodList
= NULL
;
518 Status
= EapConfig
->GetData (
520 EFI_EAP_TYPE_ATTRIBUTE
,
521 EfiEapConfigEapSupportedAuthMethod
,
522 (VOID
*)AuthMethodList
,
525 if (Status
== EFI_SUCCESS
) {
527 // No Supported Eap Auth Method
529 return EFI_UNSUPPORTED
;
530 } else if (Status
!= EFI_BUFFER_TOO_SMALL
) {
535 // The second time to get Supported Auth Method list, return the list.
536 // In current design, only EAPTLS, TTLS and PEAP are supported
538 AuthMethodList
= (EFI_EAP_TYPE
*)AllocateZeroPool (AuthMethodListSize
);
539 if (AuthMethodList
== NULL
) {
540 return EFI_OUT_OF_RESOURCES
;
543 Status
= EapConfig
->GetData (
545 EFI_EAP_TYPE_ATTRIBUTE
,
546 EfiEapConfigEapSupportedAuthMethod
,
547 (VOID
*)AuthMethodList
,
550 if (EFI_ERROR (Status
)) {
551 FreePool (AuthMethodList
);
556 // Check if EapAuthMethod is in supported Auth Method list, if found, skip the loop.
558 for (Index
= 0; Index
< AuthMethodListSize
/ sizeof (EFI_EAP_TYPE
); Index
++) {
559 if (EapAuthMethod
== AuthMethodList
[Index
]) {
564 if (Index
== AuthMethodListSize
/ sizeof (EFI_EAP_TYPE
)) {
565 FreePool (AuthMethodList
);
566 return EFI_UNSUPPORTED
;
569 FreePool (AuthMethodList
);
572 // Set Identity to Eap peer, Mandatory field for PEAP and TTLS
574 if (StrLen (Profile
->EapIdentity
) > 0) {
575 IdentitySize
= sizeof (CHAR8
) * (StrLen (Profile
->EapIdentity
) + 1);
576 Identity
= AllocateZeroPool (IdentitySize
);
577 if (Identity
== NULL
) {
578 return EFI_OUT_OF_RESOURCES
;
581 Status
= gBS
->LocateProtocol (&gEdkiiWiFiProfileSyncProtocolGuid
, NULL
, (VOID
**)&WiFiProfileSyncProtocol
);
582 if (!EFI_ERROR (Status
)) {
583 CopyMem (Identity
, &Profile
->EapIdentity
, IdentitySize
);
585 UnicodeStrToAsciiStrS (Profile
->EapIdentity
, Identity
, IdentitySize
);
588 Status
= EapConfig
->SetData (
590 EFI_EAP_TYPE_IDENTITY
,
591 EfiEapConfigIdentityString
,
595 if (EFI_ERROR (Status
)) {
602 if (EapAuthMethod
!= EFI_EAP_TYPE_EAPTLS
) {
603 return EFI_INVALID_PARAMETER
;
608 // Set Auth Method to Eap peer, Mandatory field
610 Status
= EapConfig
->SetData (
612 EFI_EAP_TYPE_ATTRIBUTE
,
613 EfiEapConfigEapAuthMethod
,
614 (VOID
*)&EapAuthMethod
,
615 sizeof (EapAuthMethod
)
617 if (EFI_ERROR (Status
)) {
621 if ((EapAuthMethod
== EFI_EAP_TYPE_TTLS
) || (EapAuthMethod
== EFI_EAP_TYPE_PEAP
)) {
622 Status
= EapConfig
->SetData (
625 EfiEapConfigEap2ndAuthMethod
,
626 (VOID
*)&EapSecondAuthMethod
,
627 sizeof (EapSecondAuthMethod
)
629 if (EFI_ERROR (Status
)) {
634 // Set Password to Eap peer
636 if (StrLen (Profile
->EapPassword
) < PASSWORD_MIN_LEN
) {
637 DEBUG ((DEBUG_ERROR
, "[WiFi Connection Manager] Error: No Eap Password for Network: %s.\n", Profile
->SSId
));
638 return EFI_INVALID_PARAMETER
;
641 PasswordSize
= sizeof (CHAR16
) * (StrLen (Profile
->EapPassword
) + 1);
642 Password
= AllocateZeroPool (PasswordSize
);
643 if (Password
== NULL
) {
644 return EFI_OUT_OF_RESOURCES
;
647 StrCpyS (Password
, PasswordSize
, Profile
->EapPassword
);
648 Status
= EapConfig
->SetData (
650 EFI_EAP_TYPE_MSCHAPV2
,
651 EfiEapConfigEapMSChapV2Password
,
655 ZeroMem (Password
, PasswordSize
);
657 if (EFI_ERROR (Status
)) {
662 // If CA cert is required, set it to Eap peer
664 if (Profile
->CACertData
!= NULL
) {
665 Status
= EapConfig
->SetData (
668 EfiEapConfigEapTlsCACert
,
672 if (EFI_ERROR (Status
)) {
676 return EFI_INVALID_PARAMETER
;
678 } else if (EapAuthMethod
== EFI_EAP_TYPE_EAPTLS
) {
680 // Set CA cert to Eap peer
682 if (Profile
->CACertData
== NULL
) {
683 return EFI_INVALID_PARAMETER
;
686 Status
= EapConfig
->SetData (
689 EfiEapConfigEapTlsCACert
,
693 if (EFI_ERROR (Status
)) {
698 // Set Client cert to Eap peer
700 if (Profile
->ClientCertData
== NULL
) {
701 return EFI_INVALID_PARAMETER
;
704 Status
= EapConfig
->SetData (
707 EfiEapConfigEapTlsClientCert
,
708 Profile
->ClientCertData
,
709 Profile
->ClientCertSize
711 if (EFI_ERROR (Status
)) {
716 // Set Private key to Eap peer
718 if (Profile
->PrivateKeyData
== NULL
) {
719 DEBUG ((DEBUG_ERROR
, "[WiFi Connection Manager] Error: No Private Key for Network: %s.\n", Profile
->SSId
));
720 return EFI_INVALID_PARAMETER
;
723 Status
= EapConfig
->SetData (
726 EfiEapConfigEapTlsClientPrivateKeyFile
,
727 Profile
->PrivateKeyData
,
728 Profile
->PrivateKeyDataSize
730 if (EFI_ERROR (Status
)) {
734 if (StrLen (Profile
->PrivateKeyPassword
) > 0) {
735 EncryptPasswordLen
= StrLen (Profile
->PrivateKeyPassword
);
736 AsciiEncryptPassword
= AllocateZeroPool (EncryptPasswordLen
+ 1);
737 if (AsciiEncryptPassword
== NULL
) {
738 return EFI_OUT_OF_RESOURCES
;
741 UnicodeStrToAsciiStrS (Profile
->PrivateKeyPassword
, AsciiEncryptPassword
, EncryptPasswordLen
+ 1);
742 Status
= EapConfig
->SetData (
745 EfiEapConfigEapTlsClientPrivateKeyFilePassword
,
746 (VOID
*)AsciiEncryptPassword
,
747 EncryptPasswordLen
+ 1
749 if (EFI_ERROR (Status
)) {
750 ZeroMem (AsciiEncryptPassword
, EncryptPasswordLen
+ 1);
751 FreePool (AsciiEncryptPassword
);
755 ZeroMem (AsciiEncryptPassword
, EncryptPasswordLen
+ 1);
756 FreePool (AsciiEncryptPassword
);
759 return EFI_INVALID_PARAMETER
;
766 Get current link state from low layer.
768 @param[in] Nic Pointer to the device data of the selected NIC.
769 @param[out] LinkState The pointer to buffer to retrieve link state.
771 @retval EFI_SUCCESS The operation is completed.
772 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
773 @retval EFI_UNSUPPORTED Adapter information protocol is not supported.
774 @retval Other Errors Returned errors when retrieving link state from low layer.
778 WifiMgrGetLinkState (
779 IN WIFI_MGR_DEVICE_DATA
*Nic
,
780 OUT EFI_ADAPTER_INFO_MEDIA_STATE
*LinkState
786 EFI_ADAPTER_INFO_MEDIA_STATE
*UndiState
;
787 EFI_ADAPTER_INFORMATION_PROTOCOL
*Aip
;
789 if ((Nic
== NULL
) || (LinkState
== NULL
)) {
790 return EFI_INVALID_PARAMETER
;
793 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
794 Status
= gBS
->OpenProtocol (
795 Nic
->ControllerHandle
,
796 &gEfiAdapterInformationProtocolGuid
,
799 Nic
->ControllerHandle
,
800 EFI_OPEN_PROTOCOL_GET_PROTOCOL
802 if (EFI_ERROR (Status
)) {
803 gBS
->RestoreTPL (OldTpl
);
804 return EFI_UNSUPPORTED
;
807 Status
= Aip
->GetInformation (
809 &gEfiAdapterInfoMediaStateGuid
,
813 if (EFI_ERROR (Status
)) {
814 gBS
->RestoreTPL (OldTpl
);
818 gBS
->RestoreTPL (OldTpl
);
820 CopyMem (LinkState
, UndiState
, sizeof (EFI_ADAPTER_INFO_MEDIA_STATE
));
821 FreePool (UndiState
);
826 Prepare configuration work before connecting to the target network.
827 For WPA2 Personal networks, password should be checked; and for EAP networks, parameters
828 are different for different networks.
830 @param[in] Nic Pointer to the device data of the selected NIC.
831 @param[in] Profile The target network to be connected.
833 @retval EFI_SUCCESS The operation is completed.
834 @retval EFI_UNSUPPORTED This network is not supported.
835 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
839 WifiMgrPrepareConnection (
840 IN WIFI_MGR_DEVICE_DATA
*Nic
,
841 IN WIFI_MGR_NETWORK_PROFILE
*Profile
846 BOOLEAN AKMSuiteSupported
;
847 BOOLEAN CipherSuiteSupported
;
849 if ((Profile
== NULL
) || (Nic
== NULL
)) {
850 return EFI_INVALID_PARAMETER
;
853 Status
= WifiMgrCheckRSN (
854 Profile
->Network
.AKMSuite
,
855 Profile
->Network
.CipherSuite
,
859 &CipherSuiteSupported
861 if (EFI_ERROR (Status
)) {
865 if (AKMSuiteSupported
&& CipherSuiteSupported
) {
866 switch (SecurityType
) {
867 case SECURITY_TYPE_WPA2_PERSONAL
:
868 case SECURITY_TYPE_WPA3_PERSONAL
:
870 Status
= WifiMgrConfigPassword (Nic
, Profile
);
871 if (EFI_ERROR (Status
)) {
872 if (Status
== EFI_NOT_FOUND
) {
873 if (Nic
->OneTimeConnectRequest
) {
874 WifiMgrUpdateConnectMessage (Nic
, FALSE
, L
"Connect Failed: Invalid Password!");
883 case SECURITY_TYPE_WPA2_ENTERPRISE
:
884 case SECURITY_TYPE_WPA3_ENTERPRISE
:
886 Status
= WifiMgrConfigEap (Nic
, Profile
);
887 if (EFI_ERROR (Status
)) {
888 if (Status
== EFI_INVALID_PARAMETER
) {
889 if (Nic
->OneTimeConnectRequest
) {
890 WifiMgrUpdateConnectMessage (Nic
, FALSE
, L
"Connect Failed: Invalid Configuration!");
899 case SECURITY_TYPE_NONE
:
903 return EFI_UNSUPPORTED
;
906 return EFI_UNSUPPORTED
;
913 Will reset NiC data, get profile from profile sync driver, and send for
914 another connection attempt.This function should not be called more than
917 @param[in] WiFiProfileSyncProtocol The target network profile to connect.
919 @retval EFI_SUCCESS The operation is completed.
920 @retval other Operation failure.
925 IN EDKII_WIFI_PROFILE_SYNC_PROTOCOL
*WiFiProfileSyncProtocol
929 WIFI_MGR_DEVICE_DATA
*Nic
;
930 EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL
*Wmp
;
931 EFI_SUPPLICANT_PROTOCOL
*Supplicant
;
932 EFI_EAP_CONFIGURATION_PROTOCOL
*EapConfig
;
936 Status
= gBS
->LocateProtocol (
937 &gEfiWiFi2ProtocolGuid
,
941 if (EFI_ERROR (Status
)) {
945 Status
= gBS
->LocateProtocol (
946 &gEfiSupplicantProtocolGuid
,
950 if (EFI_ERROR (Status
)) {
954 Status
= gBS
->LocateProtocol (
955 &gEfiEapConfigurationProtocolGuid
,
959 if (EFI_ERROR (Status
)) {
964 // Initialize Nic device data
966 Nic
= AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA
));
968 Status
= EFI_OUT_OF_RESOURCES
;
972 Nic
->Signature
= WIFI_MGR_DEVICE_DATA_SIGNATURE
;
973 Nic
->Private
= mPrivate
;
975 Nic
->Supplicant
= Supplicant
;
976 Nic
->EapConfig
= EapConfig
;
977 Nic
->UserSelectedProfile
= NULL
;
978 Nic
->OneTimeScanRequest
= FALSE
;
980 if (Nic
->Supplicant
!= NULL
) {
981 Status
= WifiMgrGetSupportedSuites (Nic
);
984 if (!EFI_ERROR (Status
)) {
985 InitializeListHead (&Nic
->ProfileList
);
987 Nic
->ConnectPendingNetwork
= (WIFI_MGR_NETWORK_PROFILE
*)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE
));
988 if (Nic
->ConnectPendingNetwork
== NULL
) {
989 Status
= EFI_OUT_OF_RESOURCES
;
990 DEBUG ((DEBUG_ERROR
, "[WiFi Connection Manager] Failed to allocate memory for ConnectPendingNetwork\n"));
994 Status
= WiFiProfileSyncProtocol
->GetProfile (Nic
->ConnectPendingNetwork
, Nic
->MacAddress
);
995 if (!EFI_ERROR (Status
) && (Nic
->ConnectPendingNetwork
!= NULL
)) {
996 Status
= WifiMgrConnectToNetwork (Nic
, Nic
->ConnectPendingNetwork
);
997 if (!EFI_ERROR (Status
)) {
1001 DEBUG ((DEBUG_ERROR
, "[WiFi Connection Manager] Failed to get WiFi profile with status %r\n", Status
));
1004 DEBUG ((DEBUG_ERROR
, "[WiFi Connection Manager] Failed to get Supported suites with status %r\n", Status
));
1007 if (Nic
->ConnectPendingNetwork
!= NULL
) {
1008 if (Nic
->ConnectPendingNetwork
->Network
.AKMSuite
!= NULL
) {
1009 FreePool (Nic
->ConnectPendingNetwork
->Network
.AKMSuite
);
1012 if (Nic
->ConnectPendingNetwork
->Network
.CipherSuite
!= NULL
) {
1013 FreePool (Nic
->ConnectPendingNetwork
->Network
.CipherSuite
);
1016 FreePool (Nic
->ConnectPendingNetwork
);
1020 if (Nic
->Supplicant
!= NULL
) {
1021 if (Nic
->SupportedSuites
.SupportedAKMSuites
!= NULL
) {
1022 FreePool (Nic
->SupportedSuites
.SupportedAKMSuites
);
1025 if (Nic
->SupportedSuites
.SupportedSwCipherSuites
!= NULL
) {
1026 FreePool (Nic
->SupportedSuites
.SupportedSwCipherSuites
);
1029 if (Nic
->SupportedSuites
.SupportedHwCipherSuites
!= NULL
) {
1030 FreePool (Nic
->SupportedSuites
.SupportedHwCipherSuites
);
1040 The callback function for connect operation.
1042 ASSERT when errors occur in config token.
1044 @param[in] Event The Connect token receive event.
1045 @param[in] Context The context of the connect token.
1050 WifiMgrOnConnectFinished (
1056 WIFI_MGR_MAC_CONFIG_TOKEN
*ConfigToken
;
1057 WIFI_MGR_NETWORK_PROFILE
*ConnectedProfile
;
1061 EDKII_WIFI_PROFILE_SYNC_PROTOCOL
*WiFiProfileSyncProtocol
;
1063 ASSERT (Context
!= NULL
);
1065 ConnectedProfile
= NULL
;
1066 ConfigToken
= (WIFI_MGR_MAC_CONFIG_TOKEN
*)Context
;
1067 ASSERT (ConfigToken
->Nic
!= NULL
);
1069 ConfigToken
->Nic
->ConnectState
= WifiMgrDisconnected
;
1070 ASSERT (ConfigToken
->Type
== TokenTypeConnectNetworkToken
);
1072 ASSERT (ConfigToken
->Token
.ConnectNetworkToken
!= NULL
);
1074 Status
= gBS
->LocateProtocol (&gEdkiiWiFiProfileSyncProtocolGuid
, NULL
, (VOID
**)&WiFiProfileSyncProtocol
);
1075 if (!EFI_ERROR (Status
)) {
1076 WiFiProfileSyncProtocol
->SetConnectState (ConfigToken
->Token
.ConnectNetworkToken
->ResultCode
);
1077 if ((mWifiConnectionCount
< MAX_WIFI_CONNETION_ATTEMPTS
) &&
1078 (ConfigToken
->Token
.ConnectNetworkToken
->ResultCode
!= ConnectSuccess
))
1080 mWifiConnectionCount
++;
1081 gBS
->CloseEvent (Event
);
1082 Status
= ConnectionRetry (WiFiProfileSyncProtocol
);
1083 if (!EFI_ERROR (Status
)) {
1087 WiFiProfileSyncProtocol
->SetConnectState (Status
);
1091 if (ConfigToken
->Token
.ConnectNetworkToken
->Status
!= EFI_SUCCESS
) {
1092 if (ConfigToken
->Nic
->OneTimeConnectRequest
) {
1094 // Only update message for user triggered connection
1096 if (ConfigToken
->Token
.ConnectNetworkToken
->Status
== EFI_ACCESS_DENIED
) {
1097 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, FALSE
, L
"Connect Failed: Permission Denied!");
1099 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, FALSE
, L
"Connect Failed!");
1102 ConfigToken
->Nic
->OneTimeConnectRequest
= FALSE
;
1105 ConfigToken
->Nic
->CurrentOperateNetwork
= NULL
;
1109 if (ConfigToken
->Token
.ConnectNetworkToken
->ResultCode
!= ConnectSuccess
) {
1110 if (ConfigToken
->Nic
->OneTimeConnectRequest
) {
1111 if (ConfigToken
->Token
.ConnectNetworkToken
->ResultCode
== ConnectFailedReasonUnspecified
) {
1112 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, FALSE
, L
"Connect Failed: Wrong Password or Unexpected Error!");
1114 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, FALSE
, L
"Connect Failed!");
1121 if ((ConfigToken
->Token
.ConnectNetworkToken
->Data
== NULL
) ||
1122 (ConfigToken
->Token
.ConnectNetworkToken
->Data
->Network
== NULL
))
1125 // An unexpected error occurs, tell low layer to perform a disconnect
1127 ConfigToken
->Nic
->HasDisconnectPendingNetwork
= TRUE
;
1128 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, FALSE
, NULL
);
1133 // A correct connect token received, terminate the connection process
1135 Status
= WifiMgrCheckRSN (
1136 ConfigToken
->Token
.ConnectNetworkToken
->Data
->Network
->AKMSuite
,
1137 ConfigToken
->Token
.ConnectNetworkToken
->Data
->Network
->CipherSuite
,
1143 if (EFI_ERROR (Status
)) {
1144 SecurityType
= SECURITY_TYPE_UNKNOWN
;
1147 SSIdLen
= ConfigToken
->Token
.ConnectNetworkToken
->Data
->Network
->SSId
.SSIdLen
;
1148 AsciiSSId
= (CHAR8
*)AllocateZeroPool (sizeof (CHAR8
) * (SSIdLen
+ 1));
1149 if (AsciiSSId
== NULL
) {
1150 ConfigToken
->Nic
->HasDisconnectPendingNetwork
= TRUE
;
1151 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, FALSE
, NULL
);
1155 CopyMem (AsciiSSId
, ConfigToken
->Token
.ConnectNetworkToken
->Data
->Network
->SSId
.SSId
, SSIdLen
);
1156 *(AsciiSSId
+ SSIdLen
) = '\0';
1158 ConnectedProfile
= WifiMgrGetProfileByAsciiSSId (AsciiSSId
, SecurityType
, &ConfigToken
->Nic
->ProfileList
);
1159 FreePool (AsciiSSId
);
1160 if (ConnectedProfile
== NULL
) {
1161 ConfigToken
->Nic
->HasDisconnectPendingNetwork
= TRUE
;
1162 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, FALSE
, NULL
);
1166 ConfigToken
->Nic
->ConnectState
= WifiMgrConnectedToAp
;
1167 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, TRUE
, NULL
);
1171 if (ConfigToken
->Nic
->ConnectState
== WifiMgrDisconnected
) {
1172 ConfigToken
->Nic
->CurrentOperateNetwork
= NULL
;
1175 ConfigToken
->Nic
->OneTimeConnectRequest
= FALSE
;
1176 WifiMgrFreeToken (ConfigToken
);
1180 Start connect operation, and send out a token to connect to a target network.
1182 @param[in] Nic Pointer to the device data of the selected NIC.
1183 @param[in] Profile The target network to be connected.
1185 @retval EFI_SUCCESS The operation is completed.
1186 @retval EFI_ALREADY_STARTED Already in "connected" state, need to perform a disconnect
1188 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
1189 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1190 @retval Other Errors Return errors when connecting network on low layer.
1194 WifiMgrConnectToNetwork (
1195 IN WIFI_MGR_DEVICE_DATA
*Nic
,
1196 IN WIFI_MGR_NETWORK_PROFILE
*Profile
1201 EFI_ADAPTER_INFO_MEDIA_STATE LinkState
;
1202 WIFI_MGR_MAC_CONFIG_TOKEN
*ConfigToken
;
1203 EFI_80211_CONNECT_NETWORK_TOKEN
*ConnectToken
;
1205 if ((Nic
== NULL
) || (Nic
->Wmp
== NULL
) || (Profile
== NULL
)) {
1206 return EFI_INVALID_PARAMETER
;
1209 Status
= WifiMgrGetLinkState (Nic
, &LinkState
);
1210 if (EFI_ERROR (Status
)) {
1214 if (LinkState
.MediaState
== EFI_SUCCESS
) {
1215 return EFI_ALREADY_STARTED
;
1218 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1219 Status
= WifiMgrPrepareConnection (Nic
, Profile
);
1220 if (EFI_ERROR (Status
)) {
1221 gBS
->RestoreTPL (OldTpl
);
1226 // Create a new connect token
1228 ConfigToken
= AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN
));
1229 if (ConfigToken
== NULL
) {
1230 Status
= EFI_OUT_OF_RESOURCES
;
1234 ConfigToken
->Type
= TokenTypeConnectNetworkToken
;
1235 ConfigToken
->Nic
= Nic
;
1236 ConfigToken
->Token
.ConnectNetworkToken
= AllocateZeroPool (sizeof (EFI_80211_CONNECT_NETWORK_TOKEN
));
1237 if (ConfigToken
->Token
.ConnectNetworkToken
== NULL
) {
1241 ConnectToken
= ConfigToken
->Token
.ConnectNetworkToken
;
1242 ConnectToken
->Data
= AllocateZeroPool (sizeof (EFI_80211_CONNECT_NETWORK_DATA
));
1243 if (ConnectToken
->Data
== NULL
) {
1247 ConnectToken
->Data
->Network
= AllocateZeroPool (sizeof (EFI_80211_NETWORK
));
1248 if (ConnectToken
->Data
->Network
== NULL
) {
1252 CopyMem (ConnectToken
->Data
->Network
, &Profile
->Network
, sizeof (EFI_80211_NETWORK
));
1255 // Add event handle and start to connect
1257 Status
= gBS
->CreateEvent (
1260 WifiMgrOnConnectFinished
,
1262 &ConnectToken
->Event
1264 if (EFI_ERROR (Status
)) {
1268 Nic
->ConnectState
= WifiMgrConnectingToAp
;
1269 Nic
->CurrentOperateNetwork
= Profile
;
1270 WifiMgrUpdateConnectMessage (Nic
, FALSE
, NULL
);
1273 // Start Connecting ...
1275 Status
= Nic
->Wmp
->ConnectNetwork (Nic
->Wmp
, ConnectToken
);
1278 // Erase secrets after connection is triggered
1280 WifiMgrCleanProfileSecrets (Profile
);
1282 if (EFI_ERROR (Status
)) {
1283 if (Status
== EFI_ALREADY_STARTED
) {
1284 Nic
->ConnectState
= WifiMgrConnectedToAp
;
1285 WifiMgrUpdateConnectMessage (Nic
, TRUE
, NULL
);
1287 Nic
->ConnectState
= WifiMgrDisconnected
;
1288 Nic
->CurrentOperateNetwork
= NULL
;
1290 if (Nic
->OneTimeConnectRequest
) {
1291 if (Status
== EFI_NOT_FOUND
) {
1292 WifiMgrUpdateConnectMessage (Nic
, FALSE
, L
"Connect Failed: Not Available!");
1294 WifiMgrUpdateConnectMessage (Nic
, FALSE
, L
"Connect Failed: Unexpected Error!");
1304 if (EFI_ERROR (Status
)) {
1305 WifiMgrFreeToken (ConfigToken
);
1308 gBS
->RestoreTPL (OldTpl
);
1310 DEBUG ((DEBUG_INFO
, "[WiFi Connection Manager] WifiMgrConnectToNetwork: %r\n", Status
));
1315 The callback function for disconnect operation.
1317 ASSERT when errors occur in config token.
1319 @param[in] Event The Disconnect token receive event.
1320 @param[in] Context The context of the Disconnect token.
1325 WifiMgrOnDisconnectFinished (
1330 WIFI_MGR_MAC_CONFIG_TOKEN
*ConfigToken
;
1332 ASSERT (Context
!= NULL
);
1334 ConfigToken
= (WIFI_MGR_MAC_CONFIG_TOKEN
*)Context
;
1335 ASSERT (ConfigToken
->Nic
!= NULL
);
1336 ASSERT (ConfigToken
->Type
== TokenTypeDisconnectNetworkToken
);
1338 ASSERT (ConfigToken
->Token
.DisconnectNetworkToken
!= NULL
);
1339 if (ConfigToken
->Token
.DisconnectNetworkToken
->Status
!= EFI_SUCCESS
) {
1340 ConfigToken
->Nic
->ConnectState
= WifiMgrConnectedToAp
;
1341 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, FALSE
, NULL
);
1342 ConfigToken
->Nic
->OneTimeDisconnectRequest
= FALSE
;
1346 ConfigToken
->Nic
->ConnectState
= WifiMgrDisconnected
;
1347 ConfigToken
->Nic
->CurrentOperateNetwork
= NULL
;
1348 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, TRUE
, NULL
);
1349 ConfigToken
->Nic
->OneTimeDisconnectRequest
= FALSE
;
1352 // Disconnected network may not be in network list now, trigger a scan again!
1354 ConfigToken
->Nic
->OneTimeScanRequest
= TRUE
;
1357 WifiMgrFreeToken (ConfigToken
);
1362 Start disconnect operation, and send out a token to disconnect from current connected
1365 @param[in] Nic Pointer to the device data of the selected NIC.
1367 @retval EFI_SUCCESS The operation is completed.
1368 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1369 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
1370 @retval Other Errors Return errors when disconnecting a network on low layer.
1374 WifiMgrDisconnectToNetwork (
1375 IN WIFI_MGR_DEVICE_DATA
*Nic
1380 WIFI_MGR_MAC_CONFIG_TOKEN
*ConfigToken
;
1381 EFI_80211_DISCONNECT_NETWORK_TOKEN
*DisconnectToken
;
1384 return EFI_INVALID_PARAMETER
;
1387 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1388 Status
= EFI_SUCCESS
;
1389 ConfigToken
= AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN
));
1390 if (ConfigToken
== NULL
) {
1391 gBS
->RestoreTPL (OldTpl
);
1392 return EFI_OUT_OF_RESOURCES
;
1395 ConfigToken
->Type
= TokenTypeDisconnectNetworkToken
;
1396 ConfigToken
->Nic
= Nic
;
1397 ConfigToken
->Token
.DisconnectNetworkToken
= AllocateZeroPool (sizeof (EFI_80211_DISCONNECT_NETWORK_TOKEN
));
1398 if (ConfigToken
->Token
.DisconnectNetworkToken
== NULL
) {
1399 WifiMgrFreeToken (ConfigToken
);
1400 gBS
->RestoreTPL (OldTpl
);
1401 return EFI_OUT_OF_RESOURCES
;
1404 DisconnectToken
= ConfigToken
->Token
.DisconnectNetworkToken
;
1406 Status
= gBS
->CreateEvent (
1409 WifiMgrOnDisconnectFinished
,
1411 &DisconnectToken
->Event
1413 if (EFI_ERROR (Status
)) {
1414 WifiMgrFreeToken (ConfigToken
);
1415 gBS
->RestoreTPL (OldTpl
);
1419 Nic
->ConnectState
= WifiMgrDisconnectingToAp
;
1420 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, FALSE
, NULL
);
1422 Status
= Nic
->Wmp
->DisconnectNetwork (Nic
->Wmp
, DisconnectToken
);
1423 if (EFI_ERROR (Status
)) {
1424 if (Status
== EFI_NOT_FOUND
) {
1425 Nic
->ConnectState
= WifiMgrDisconnected
;
1426 Nic
->CurrentOperateNetwork
= NULL
;
1429 // This network is not in network list now, trigger a scan again!
1431 Nic
->OneTimeScanRequest
= TRUE
;
1434 // State has been changed from Connected to Disconnected
1436 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, TRUE
, NULL
);
1437 Status
= EFI_SUCCESS
;
1439 if (Nic
->OneTimeDisconnectRequest
) {
1440 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, FALSE
, L
"Disconnect Failed: Unexpected Error!");
1443 Nic
->ConnectState
= WifiMgrConnectedToAp
;
1444 WifiMgrUpdateConnectMessage (ConfigToken
->Nic
, FALSE
, NULL
);
1447 WifiMgrFreeToken (ConfigToken
);
1450 gBS
->RestoreTPL (OldTpl
);
1455 The state machine of the connection manager, periodically check the state and
1456 perform a corresponding operation.
1458 @param[in] Event The timer event to be triggered.
1459 @param[in] Context The context of the Nic device data.
1464 WifiMgrOnTimerTick (
1469 WIFI_MGR_DEVICE_DATA
*Nic
;
1471 EFI_ADAPTER_INFO_MEDIA_STATE LinkState
;
1472 WIFI_MGR_NETWORK_PROFILE
*Profile
;
1474 if (Context
== NULL
) {
1478 Nic
= (WIFI_MGR_DEVICE_DATA
*)Context
;
1479 NET_CHECK_SIGNATURE (Nic
, WIFI_MGR_DEVICE_DATA_SIGNATURE
);
1481 Status
= WifiMgrGetLinkState (Nic
, &LinkState
);
1482 if (EFI_ERROR (Status
)) {
1483 DEBUG ((DEBUG_INFO
, "[WiFi Connection Manager] Error: Failed to get link state!\n"));
1487 if (Nic
->LastLinkState
.MediaState
!= LinkState
.MediaState
) {
1488 if ((Nic
->LastLinkState
.MediaState
== EFI_SUCCESS
) && (LinkState
.MediaState
== EFI_NO_MEDIA
)) {
1489 Nic
->HasDisconnectPendingNetwork
= TRUE
;
1492 Nic
->LastLinkState
.MediaState
= LinkState
.MediaState
;
1495 Nic
->ScanTickTime
++;
1496 if (((Nic
->ScanTickTime
> WIFI_SCAN_FREQUENCY
) || Nic
->OneTimeScanRequest
) &&
1497 (Nic
->ScanState
== WifiMgrScanFinished
))
1499 Nic
->OneTimeScanRequest
= FALSE
;
1500 Nic
->ScanTickTime
= 0;
1502 DEBUG ((DEBUG_INFO
, "[WiFi Connection Manager] Scan is triggered.\n"));
1503 WifiMgrStartScan (Nic
);
1506 if ((Nic
->AvailableCount
> 0) && (Nic
->ScanState
== WifiMgrScanFinished
)) {
1507 switch (Nic
->ConnectState
) {
1508 case WifiMgrDisconnected
:
1510 if (Nic
->HasDisconnectPendingNetwork
) {
1511 Nic
->HasDisconnectPendingNetwork
= FALSE
;
1514 if (Nic
->ConnectPendingNetwork
!= NULL
) {
1515 Profile
= Nic
->ConnectPendingNetwork
;
1516 Status
= WifiMgrConnectToNetwork (Nic
, Profile
);
1517 Nic
->ConnectPendingNetwork
= NULL
;
1518 if (EFI_ERROR (Status
)) {
1520 // Some error happened, don't wait for a return connect token!
1522 Nic
->OneTimeConnectRequest
= FALSE
;
1528 case WifiMgrConnectingToAp
:
1531 case WifiMgrDisconnectingToAp
:
1534 case WifiMgrConnectedToAp
:
1536 if ((Nic
->ConnectPendingNetwork
!= NULL
) || Nic
->HasDisconnectPendingNetwork
) {
1537 Status
= WifiMgrDisconnectToNetwork (Nic
);
1538 if (EFI_ERROR (Status
)) {
1540 // Some error happened, don't wait for a return disconnect token!
1542 Nic
->OneTimeDisconnectRequest
= FALSE
;