1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552 |
- /** @file
- The Mac Connection2 Protocol adapter functions for WiFi Connection Manager.
- Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "WifiConnectionMgrDxe.h"
- EFI_EAP_TYPE mEapAuthMethod[] = {
- EFI_EAP_TYPE_TTLS,
- EFI_EAP_TYPE_PEAP,
- EFI_EAP_TYPE_EAPTLS
- };
- EFI_EAP_TYPE mEapSecondAuthMethod[] = {
- EFI_EAP_TYPE_MSCHAPV2
- };
- UINT8 mWifiConnectionCount = 0;
- /**
- The callback function for scan operation. This function updates networks
- according to the latest scan result, and trigger UI refresh.
- ASSERT when errors occur in config token.
- @param[in] Event The GetNetworks token receive event.
- @param[in] Context The context of the GetNetworks token.
- **/
- VOID
- EFIAPI
- WifiMgrOnScanFinished (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- EFI_STATUS Status;
- WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;
- WIFI_MGR_DEVICE_DATA *Nic;
- WIFI_MGR_NETWORK_PROFILE *Profile;
- EFI_80211_NETWORK *Network;
- UINTN DataSize;
- EFI_80211_NETWORK_DESCRIPTION *NetworkDescription;
- EFI_80211_GET_NETWORKS_RESULT *Result;
- LIST_ENTRY *Entry;
- UINT8 SecurityType;
- BOOLEAN AKMSuiteSupported;
- BOOLEAN CipherSuiteSupported;
- CHAR8 *AsciiSSId;
- UINTN Index;
- ASSERT (Context != NULL);
- ConfigToken = (WIFI_MGR_MAC_CONFIG_TOKEN *)Context;
- ASSERT (ConfigToken->Nic != NULL);
- ASSERT (ConfigToken->Type == TokenTypeGetNetworksToken);
- //
- // It is the GetNetworks token, set scan state to "ScanFinished"
- //
- ConfigToken->Nic->ScanState = WifiMgrScanFinished;
- ASSERT (ConfigToken->Token.GetNetworksToken != NULL);
- Result = ConfigToken->Token.GetNetworksToken->Result;
- Nic = ConfigToken->Nic;
- //
- // Clean previous result, and update network list according to the scan result
- //
- Nic->AvailableCount = 0;
- NET_LIST_FOR_EACH (Entry, &Nic->ProfileList) {
- Profile = NET_LIST_USER_STRUCT_S (
- Entry,
- WIFI_MGR_NETWORK_PROFILE,
- Link,
- WIFI_MGR_PROFILE_SIGNATURE
- );
- Profile->IsAvailable = FALSE;
- }
- if (Result == NULL) {
- gBS->SignalEvent (Nic->Private->NetworkListRefreshEvent);
- WifiMgrFreeToken (ConfigToken);
- return;
- }
- for (Index = 0; Index < Result->NumOfNetworkDesc; Index++) {
- NetworkDescription = Result->NetworkDesc + Index;
- if (NetworkDescription == NULL) {
- continue;
- }
- Network = &NetworkDescription->Network;
- if ((Network == NULL) || (Network->SSId.SSIdLen == 0)) {
- continue;
- }
- Status = WifiMgrCheckRSN (
- Network->AKMSuite,
- Network->CipherSuite,
- Nic,
- &SecurityType,
- &AKMSuiteSupported,
- &CipherSuiteSupported
- );
- if (EFI_ERROR (Status)) {
- SecurityType = SECURITY_TYPE_UNKNOWN;
- AKMSuiteSupported = FALSE;
- CipherSuiteSupported = FALSE;
- }
- AsciiSSId = (CHAR8 *)AllocateZeroPool (sizeof (CHAR8) * (Network->SSId.SSIdLen + 1));
- if (AsciiSSId == NULL) {
- continue;
- }
- CopyMem (AsciiSSId, (CHAR8 *)Network->SSId.SSId, sizeof (CHAR8) * Network->SSId.SSIdLen);
- *(AsciiSSId + Network->SSId.SSIdLen) = '\0';
- Profile = WifiMgrGetProfileByAsciiSSId (AsciiSSId, SecurityType, &Nic->ProfileList);
- if (Profile == NULL) {
- if (Nic->MaxProfileIndex >= NETWORK_LIST_COUNT_MAX) {
- FreePool (AsciiSSId);
- continue;
- }
- //
- // Create a new profile
- //
- Profile = AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
- if (Profile == NULL) {
- FreePool (AsciiSSId);
- continue;
- }
- Profile->Signature = WIFI_MGR_PROFILE_SIGNATURE;
- Profile->NicIndex = Nic->NicIndex;
- Profile->ProfileIndex = Nic->MaxProfileIndex + 1;
- AsciiStrToUnicodeStrS (AsciiSSId, Profile->SSId, SSID_STORAGE_SIZE);
- InsertTailList (&Nic->ProfileList, &Profile->Link);
- Nic->MaxProfileIndex++;
- }
- FreePool (AsciiSSId);
- //
- // May receive duplicate networks in scan results, check if it has already
- // been processed.
- //
- if (!Profile->IsAvailable) {
- Profile->IsAvailable = TRUE;
- Profile->SecurityType = SecurityType;
- Profile->AKMSuiteSupported = AKMSuiteSupported;
- Profile->CipherSuiteSupported = CipherSuiteSupported;
- Profile->NetworkQuality = NetworkDescription->NetworkQuality;
- Nic->AvailableCount++;
- //
- // Copy BSSType and SSId
- //
- CopyMem (&Profile->Network, Network, sizeof (EFI_80211_NETWORK));
- //
- // Copy AKMSuite list
- //
- if (Network->AKMSuite != NULL) {
- if (Network->AKMSuite->AKMSuiteCount == 0) {
- DataSize = sizeof (EFI_80211_AKM_SUITE_SELECTOR);
- } else {
- DataSize = sizeof (EFI_80211_AKM_SUITE_SELECTOR) + sizeof (EFI_80211_SUITE_SELECTOR)
- * (Network->AKMSuite->AKMSuiteCount - 1);
- }
- Profile->Network.AKMSuite = (EFI_80211_AKM_SUITE_SELECTOR *)AllocateZeroPool (DataSize);
- if (Profile->Network.AKMSuite == NULL) {
- continue;
- }
- CopyMem (Profile->Network.AKMSuite, Network->AKMSuite, DataSize);
- }
- //
- // Copy CipherSuite list
- //
- if (Network->CipherSuite != NULL) {
- if (Network->CipherSuite->CipherSuiteCount == 0) {
- DataSize = sizeof (EFI_80211_CIPHER_SUITE_SELECTOR);
- } else {
- DataSize = sizeof (EFI_80211_CIPHER_SUITE_SELECTOR) + sizeof (EFI_80211_SUITE_SELECTOR)
- * (Network->CipherSuite->CipherSuiteCount - 1);
- }
- Profile->Network.CipherSuite = (EFI_80211_CIPHER_SUITE_SELECTOR *)AllocateZeroPool (DataSize);
- if (Profile->Network.CipherSuite == NULL) {
- continue;
- }
- CopyMem (Profile->Network.CipherSuite, Network->CipherSuite, DataSize);
- }
- } else {
- //
- // A duplicate network, update signal quality
- //
- if (Profile->NetworkQuality < NetworkDescription->NetworkQuality) {
- Profile->NetworkQuality = NetworkDescription->NetworkQuality;
- }
- continue;
- }
- }
- gBS->SignalEvent (Nic->Private->NetworkListRefreshEvent);
- //
- // The current connected network should always be available until disconnection
- // happens in Wifi FW layer, even when it is not in this time's scan result.
- //
- if ((Nic->ConnectState == WifiMgrConnectedToAp) && (Nic->CurrentOperateNetwork != NULL)) {
- if (!Nic->CurrentOperateNetwork->IsAvailable) {
- Nic->CurrentOperateNetwork->IsAvailable = TRUE;
- Nic->AvailableCount++;
- }
- }
- WifiMgrFreeToken (ConfigToken);
- }
- /**
- Start scan operation, and send out a token to collect available networks.
- @param[in] Nic Pointer to the device data of the selected NIC.
- @retval EFI_SUCCESS The operation is completed.
- @retval EFI_ALREADY_STARTED A former scan operation is already ongoing.
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
- @retval Other Errors Return errors when getting networks from low layer.
- **/
- EFI_STATUS
- WifiMgrStartScan (
- IN WIFI_MGR_DEVICE_DATA *Nic
- )
- {
- EFI_STATUS Status;
- EFI_TPL OldTpl;
- WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;
- EFI_80211_GET_NETWORKS_TOKEN *GetNetworksToken;
- UINT32 HiddenSSIdIndex;
- UINT32 HiddenSSIdCount;
- EFI_80211_SSID *HiddenSSIdList;
- WIFI_HIDDEN_NETWORK_DATA *HiddenNetwork;
- LIST_ENTRY *Entry;
- if ((Nic == NULL) || (Nic->Wmp == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- if (Nic->ScanState == WifiMgrScanning) {
- return EFI_ALREADY_STARTED;
- }
- Nic->ScanState = WifiMgrScanning;
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- Status = EFI_SUCCESS;
- HiddenSSIdList = NULL;
- HiddenSSIdCount = Nic->Private->HiddenNetworkCount;
- HiddenSSIdIndex = 0;
- //
- // create a new get network token
- //
- ConfigToken = AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN));
- if (ConfigToken == NULL) {
- gBS->RestoreTPL (OldTpl);
- return EFI_OUT_OF_RESOURCES;
- }
- ConfigToken->Type = TokenTypeGetNetworksToken;
- ConfigToken->Nic = Nic;
- ConfigToken->Token.GetNetworksToken = AllocateZeroPool (sizeof (EFI_80211_GET_NETWORKS_TOKEN));
- if (ConfigToken->Token.GetNetworksToken == NULL) {
- WifiMgrFreeToken (ConfigToken);
- gBS->RestoreTPL (OldTpl);
- return EFI_OUT_OF_RESOURCES;
- }
- GetNetworksToken = ConfigToken->Token.GetNetworksToken;
- //
- // There are some hidden networks to scan, add them into scan list
- //
- if (HiddenSSIdCount > 0) {
- HiddenSSIdList = AllocateZeroPool (HiddenSSIdCount * sizeof (EFI_80211_SSID));
- if (HiddenSSIdList == NULL) {
- WifiMgrFreeToken (ConfigToken);
- gBS->RestoreTPL (OldTpl);
- return EFI_OUT_OF_RESOURCES;
- }
- HiddenSSIdIndex = 0;
- NET_LIST_FOR_EACH (Entry, &Nic->Private->HiddenNetworkList) {
- HiddenNetwork = NET_LIST_USER_STRUCT_S (
- Entry,
- WIFI_HIDDEN_NETWORK_DATA,
- Link,
- WIFI_MGR_HIDDEN_NETWORK_SIGNATURE
- );
- HiddenSSIdList[HiddenSSIdIndex].SSIdLen = (UINT8)StrLen (HiddenNetwork->SSId);
- UnicodeStrToAsciiStrS (
- HiddenNetwork->SSId,
- (CHAR8 *)HiddenSSIdList[HiddenSSIdIndex].SSId,
- SSID_STORAGE_SIZE
- );
- HiddenSSIdIndex++;
- }
- GetNetworksToken->Data = AllocateZeroPool (
- sizeof (EFI_80211_GET_NETWORKS_DATA) +
- (HiddenSSIdCount - 1) * sizeof (EFI_80211_SSID)
- );
- if (GetNetworksToken->Data == NULL) {
- FreePool (HiddenSSIdList);
- WifiMgrFreeToken (ConfigToken);
- gBS->RestoreTPL (OldTpl);
- return EFI_OUT_OF_RESOURCES;
- }
- GetNetworksToken->Data->NumOfSSID = HiddenSSIdCount;
- CopyMem (GetNetworksToken->Data->SSIDList, HiddenSSIdList, HiddenSSIdCount * sizeof (EFI_80211_SSID));
- FreePool (HiddenSSIdList);
- } else {
- GetNetworksToken->Data = AllocateZeroPool (sizeof (EFI_80211_GET_NETWORKS_DATA));
- if (GetNetworksToken->Data == NULL) {
- WifiMgrFreeToken (ConfigToken);
- gBS->RestoreTPL (OldTpl);
- return EFI_OUT_OF_RESOURCES;
- }
- GetNetworksToken->Data->NumOfSSID = 0;
- }
- //
- // Create a handle when scan process ends
- //
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- WifiMgrOnScanFinished,
- ConfigToken,
- &GetNetworksToken->Event
- );
- if (EFI_ERROR (Status)) {
- WifiMgrFreeToken (ConfigToken);
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- //
- // Start scan ...
- //
- Status = Nic->Wmp->GetNetworks (Nic->Wmp, GetNetworksToken);
- if (EFI_ERROR (Status)) {
- Nic->ScanState = WifiMgrScanFinished;
- WifiMgrFreeToken (ConfigToken);
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- gBS->RestoreTPL (OldTpl);
- return EFI_SUCCESS;
- }
- /**
- Configure password to supplicant before connecting to a secured network.
- @param[in] Nic Pointer to the device data of the selected NIC.
- @param[in] Profile The target network to be connected.
- @retval EFI_SUCCESS The operation is completed.
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
- @retval EFI_NOT_FOUND No valid password is found to configure.
- @retval Other Errors Returned errors when setting data to supplicant.
- **/
- EFI_STATUS
- WifiMgrConfigPassword (
- IN WIFI_MGR_DEVICE_DATA *Nic,
- IN WIFI_MGR_NETWORK_PROFILE *Profile
- )
- {
- EFI_STATUS Status;
- EFI_SUPPLICANT_PROTOCOL *Supplicant;
- EFI_80211_SSID SSId;
- UINT8 *AsciiPassword;
- if ((Nic == NULL) || (Nic->Supplicant == NULL) || (Profile == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- Supplicant = Nic->Supplicant;
- //
- // Set SSId to supplicant
- //
- SSId.SSIdLen = Profile->Network.SSId.SSIdLen;
- CopyMem (SSId.SSId, Profile->Network.SSId.SSId, sizeof (Profile->Network.SSId.SSId));
- Status = Supplicant->SetData (
- Supplicant,
- EfiSupplicant80211TargetSSIDName,
- (VOID *)&SSId,
- sizeof (EFI_80211_SSID)
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Set password to supplicant
- //
- if (StrLen (Profile->Password) < PASSWORD_MIN_LEN) {
- return EFI_NOT_FOUND;
- }
- if (StrLen (Profile->Password) >= PASSWORD_STORAGE_SIZE) {
- ASSERT (EFI_INVALID_PARAMETER);
- return EFI_INVALID_PARAMETER;
- }
- AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof (CHAR8));
- if (AsciiPassword == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- Status = UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword, (StrLen (Profile->Password) + 1));
- if (!EFI_ERROR (Status)) {
- Status = Supplicant->SetData (
- Supplicant,
- EfiSupplicant80211PskPassword,
- AsciiPassword,
- (StrLen (Profile->Password) + 1) * sizeof (CHAR8)
- );
- }
- ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *)AsciiPassword) + 1);
- FreePool (AsciiPassword);
- return Status;
- }
- /**
- Conduct EAP configuration to supplicant before connecting to a EAP network.
- Current WiFi Connection Manager only supports three kinds of EAP networks:
- 1). EAP-TLS (Two-Way Authentication is required in our implementation)
- 2). EAP-TTLS/MSCHAPv2 (One-Way Authentication is required in our implementation)
- 3). PEAPv0/MSCHAPv2 (One-Way Authentication is required in our implementation)
- @param[in] Nic Pointer to the device data of the selected NIC.
- @param[in] Profile The target network to be connected.
- @retval EFI_SUCCESS The operation is completed.
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
- @retval EFI_UNSUPPORTED The expected EAP method is not supported.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
- @retval Other Errors Returned errors when setting data to supplicant.
- **/
- EFI_STATUS
- WifiMgrConfigEap (
- IN WIFI_MGR_DEVICE_DATA *Nic,
- IN WIFI_MGR_NETWORK_PROFILE *Profile
- )
- {
- EFI_STATUS Status;
- EDKII_WIFI_PROFILE_SYNC_PROTOCOL *WiFiProfileSyncProtocol;
- EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig;
- EFI_EAP_TYPE EapAuthMethod;
- EFI_EAP_TYPE EapSecondAuthMethod;
- EFI_EAP_TYPE *AuthMethodList;
- CHAR8 *Identity;
- UINTN IdentitySize;
- CHAR16 *Password;
- UINTN PasswordSize;
- UINTN EncryptPasswordLen;
- CHAR8 *AsciiEncryptPassword;
- UINTN AuthMethodListSize;
- UINTN Index;
- if ((Nic == NULL) || (Nic->EapConfig == NULL) || (Profile == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- EapConfig = Nic->EapConfig;
- if (Profile->EapAuthMethod >= EAP_AUTH_METHOD_MAX) {
- return EFI_INVALID_PARAMETER;
- }
- EapAuthMethod = mEapAuthMethod[Profile->EapAuthMethod];
- if (EapAuthMethod != EFI_EAP_TYPE_EAPTLS) {
- if (Profile->EapSecondAuthMethod >= EAP_SEAUTH_METHOD_MAX) {
- return EFI_INVALID_PARAMETER;
- }
- EapSecondAuthMethod = mEapSecondAuthMethod[Profile->EapSecondAuthMethod];
- }
- //
- // The first time to get Supported Auth Method list, return the size.
- //
- AuthMethodListSize = 0;
- AuthMethodList = NULL;
- Status = EapConfig->GetData (
- EapConfig,
- EFI_EAP_TYPE_ATTRIBUTE,
- EfiEapConfigEapSupportedAuthMethod,
- (VOID *)AuthMethodList,
- &AuthMethodListSize
- );
- if (Status == EFI_SUCCESS) {
- //
- // No Supported Eap Auth Method
- //
- return EFI_UNSUPPORTED;
- } else if (Status != EFI_BUFFER_TOO_SMALL) {
- return Status;
- }
- //
- // The second time to get Supported Auth Method list, return the list.
- // In current design, only EAPTLS, TTLS and PEAP are supported
- //
- AuthMethodList = (EFI_EAP_TYPE *)AllocateZeroPool (AuthMethodListSize);
- if (AuthMethodList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- Status = EapConfig->GetData (
- EapConfig,
- EFI_EAP_TYPE_ATTRIBUTE,
- EfiEapConfigEapSupportedAuthMethod,
- (VOID *)AuthMethodList,
- &AuthMethodListSize
- );
- if (EFI_ERROR (Status)) {
- FreePool (AuthMethodList);
- return Status;
- }
- //
- // Check if EapAuthMethod is in supported Auth Method list, if found, skip the loop.
- //
- for (Index = 0; Index < AuthMethodListSize / sizeof (EFI_EAP_TYPE); Index++) {
- if (EapAuthMethod == AuthMethodList[Index]) {
- break;
- }
- }
- if (Index == AuthMethodListSize / sizeof (EFI_EAP_TYPE)) {
- FreePool (AuthMethodList);
- return EFI_UNSUPPORTED;
- }
- FreePool (AuthMethodList);
- //
- // Set Identity to Eap peer, Mandatory field for PEAP and TTLS
- //
- if (StrLen (Profile->EapIdentity) > 0) {
- IdentitySize = sizeof (CHAR8) * (StrLen (Profile->EapIdentity) + 1);
- Identity = AllocateZeroPool (IdentitySize);
- if (Identity == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- Status = gBS->LocateProtocol (&gEdkiiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
- if (!EFI_ERROR (Status)) {
- CopyMem (Identity, &Profile->EapIdentity, IdentitySize);
- } else {
- UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
- }
- Status = EapConfig->SetData (
- EapConfig,
- EFI_EAP_TYPE_IDENTITY,
- EfiEapConfigIdentityString,
- (VOID *)Identity,
- IdentitySize - 1
- );
- if (EFI_ERROR (Status)) {
- FreePool (Identity);
- return Status;
- }
- FreePool (Identity);
- } else {
- if (EapAuthMethod != EFI_EAP_TYPE_EAPTLS) {
- return EFI_INVALID_PARAMETER;
- }
- }
- //
- // Set Auth Method to Eap peer, Mandatory field
- //
- Status = EapConfig->SetData (
- EapConfig,
- EFI_EAP_TYPE_ATTRIBUTE,
- EfiEapConfigEapAuthMethod,
- (VOID *)&EapAuthMethod,
- sizeof (EapAuthMethod)
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if ((EapAuthMethod == EFI_EAP_TYPE_TTLS) || (EapAuthMethod == EFI_EAP_TYPE_PEAP)) {
- Status = EapConfig->SetData (
- EapConfig,
- EapAuthMethod,
- EfiEapConfigEap2ndAuthMethod,
- (VOID *)&EapSecondAuthMethod,
- sizeof (EapSecondAuthMethod)
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Set Password to Eap peer
- //
- if (StrLen (Profile->EapPassword) < PASSWORD_MIN_LEN) {
- DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Error: No Eap Password for Network: %s.\n", Profile->SSId));
- return EFI_INVALID_PARAMETER;
- }
- PasswordSize = sizeof (CHAR16) * (StrLen (Profile->EapPassword) + 1);
- Password = AllocateZeroPool (PasswordSize);
- if (Password == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- StrCpyS (Password, PasswordSize, Profile->EapPassword);
- Status = EapConfig->SetData (
- EapConfig,
- EFI_EAP_TYPE_MSCHAPV2,
- EfiEapConfigEapMSChapV2Password,
- (VOID *)Password,
- PasswordSize
- );
- ZeroMem (Password, PasswordSize);
- FreePool (Password);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // If CA cert is required, set it to Eap peer
- //
- if (Profile->CACertData != NULL) {
- Status = EapConfig->SetData (
- EapConfig,
- EapAuthMethod,
- EfiEapConfigEapTlsCACert,
- Profile->CACertData,
- Profile->CACertSize
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- } else {
- return EFI_INVALID_PARAMETER;
- }
- } else if (EapAuthMethod == EFI_EAP_TYPE_EAPTLS) {
- //
- // Set CA cert to Eap peer
- //
- if (Profile->CACertData == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Status = EapConfig->SetData (
- EapConfig,
- EFI_EAP_TYPE_EAPTLS,
- EfiEapConfigEapTlsCACert,
- Profile->CACertData,
- Profile->CACertSize
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Set Client cert to Eap peer
- //
- if (Profile->ClientCertData == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Status = EapConfig->SetData (
- EapConfig,
- EFI_EAP_TYPE_EAPTLS,
- EfiEapConfigEapTlsClientCert,
- Profile->ClientCertData,
- Profile->ClientCertSize
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Set Private key to Eap peer
- //
- if (Profile->PrivateKeyData == NULL) {
- DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Error: No Private Key for Network: %s.\n", Profile->SSId));
- return EFI_INVALID_PARAMETER;
- }
- Status = EapConfig->SetData (
- EapConfig,
- EFI_EAP_TYPE_EAPTLS,
- EfiEapConfigEapTlsClientPrivateKeyFile,
- Profile->PrivateKeyData,
- Profile->PrivateKeyDataSize
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if (StrLen (Profile->PrivateKeyPassword) > 0) {
- EncryptPasswordLen = StrLen (Profile->PrivateKeyPassword);
- AsciiEncryptPassword = AllocateZeroPool (EncryptPasswordLen + 1);
- if (AsciiEncryptPassword == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- UnicodeStrToAsciiStrS (Profile->PrivateKeyPassword, AsciiEncryptPassword, EncryptPasswordLen + 1);
- Status = EapConfig->SetData (
- EapConfig,
- EFI_EAP_TYPE_EAPTLS,
- EfiEapConfigEapTlsClientPrivateKeyFilePassword,
- (VOID *)AsciiEncryptPassword,
- EncryptPasswordLen + 1
- );
- if (EFI_ERROR (Status)) {
- ZeroMem (AsciiEncryptPassword, EncryptPasswordLen + 1);
- FreePool (AsciiEncryptPassword);
- return Status;
- }
- ZeroMem (AsciiEncryptPassword, EncryptPasswordLen + 1);
- FreePool (AsciiEncryptPassword);
- }
- } else {
- return EFI_INVALID_PARAMETER;
- }
- return EFI_SUCCESS;
- }
- /**
- Get current link state from low layer.
- @param[in] Nic Pointer to the device data of the selected NIC.
- @param[out] LinkState The pointer to buffer to retrieve link state.
- @retval EFI_SUCCESS The operation is completed.
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
- @retval EFI_UNSUPPORTED Adapter information protocol is not supported.
- @retval Other Errors Returned errors when retrieving link state from low layer.
- **/
- EFI_STATUS
- WifiMgrGetLinkState (
- IN WIFI_MGR_DEVICE_DATA *Nic,
- OUT EFI_ADAPTER_INFO_MEDIA_STATE *LinkState
- )
- {
- EFI_STATUS Status;
- EFI_TPL OldTpl;
- UINTN DataSize;
- EFI_ADAPTER_INFO_MEDIA_STATE *UndiState;
- EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
- if ((Nic == NULL) || (LinkState == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- Status = gBS->OpenProtocol (
- Nic->ControllerHandle,
- &gEfiAdapterInformationProtocolGuid,
- (VOID **)&Aip,
- Nic->DriverHandle,
- Nic->ControllerHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- gBS->RestoreTPL (OldTpl);
- return EFI_UNSUPPORTED;
- }
- Status = Aip->GetInformation (
- Aip,
- &gEfiAdapterInfoMediaStateGuid,
- (VOID **)&UndiState,
- &DataSize
- );
- if (EFI_ERROR (Status)) {
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- gBS->RestoreTPL (OldTpl);
- CopyMem (LinkState, UndiState, sizeof (EFI_ADAPTER_INFO_MEDIA_STATE));
- FreePool (UndiState);
- return EFI_SUCCESS;
- }
- /**
- Prepare configuration work before connecting to the target network.
- For WPA2 Personal networks, password should be checked; and for EAP networks, parameters
- are different for different networks.
- @param[in] Nic Pointer to the device data of the selected NIC.
- @param[in] Profile The target network to be connected.
- @retval EFI_SUCCESS The operation is completed.
- @retval EFI_UNSUPPORTED This network is not supported.
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
- **/
- EFI_STATUS
- WifiMgrPrepareConnection (
- IN WIFI_MGR_DEVICE_DATA *Nic,
- IN WIFI_MGR_NETWORK_PROFILE *Profile
- )
- {
- EFI_STATUS Status;
- UINT8 SecurityType;
- BOOLEAN AKMSuiteSupported;
- BOOLEAN CipherSuiteSupported;
- if ((Profile == NULL) || (Nic == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- Status = WifiMgrCheckRSN (
- Profile->Network.AKMSuite,
- Profile->Network.CipherSuite,
- Nic,
- &SecurityType,
- &AKMSuiteSupported,
- &CipherSuiteSupported
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if (AKMSuiteSupported && CipherSuiteSupported) {
- switch (SecurityType) {
- case SECURITY_TYPE_WPA2_PERSONAL:
- case SECURITY_TYPE_WPA3_PERSONAL:
- Status = WifiMgrConfigPassword (Nic, Profile);
- if (EFI_ERROR (Status)) {
- if (Status == EFI_NOT_FOUND) {
- if (Nic->OneTimeConnectRequest) {
- WifiMgrUpdateConnectMessage (Nic, FALSE, L"Connect Failed: Invalid Password!");
- }
- }
- return Status;
- }
- break;
- case SECURITY_TYPE_WPA2_ENTERPRISE:
- case SECURITY_TYPE_WPA3_ENTERPRISE:
- Status = WifiMgrConfigEap (Nic, Profile);
- if (EFI_ERROR (Status)) {
- if (Status == EFI_INVALID_PARAMETER) {
- if (Nic->OneTimeConnectRequest) {
- WifiMgrUpdateConnectMessage (Nic, FALSE, L"Connect Failed: Invalid Configuration!");
- }
- }
- return Status;
- }
- break;
- case SECURITY_TYPE_NONE:
- break;
- default:
- return EFI_UNSUPPORTED;
- }
- } else {
- return EFI_UNSUPPORTED;
- }
- return EFI_SUCCESS;
- }
- /**
- Will reset NiC data, get profile from profile sync driver, and send for
- another connection attempt.This function should not be called more than
- 3 times.
- @param[in] WiFiProfileSyncProtocol The target network profile to connect.
- @retval EFI_SUCCESS The operation is completed.
- @retval other Operation failure.
- **/
- EFI_STATUS
- ConnectionRetry (
- IN EDKII_WIFI_PROFILE_SYNC_PROTOCOL *WiFiProfileSyncProtocol
- )
- {
- EFI_STATUS Status;
- WIFI_MGR_DEVICE_DATA *Nic;
- EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL *Wmp;
- EFI_SUPPLICANT_PROTOCOL *Supplicant;
- EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig;
- Nic = NULL;
- Status = gBS->LocateProtocol (
- &gEfiWiFi2ProtocolGuid,
- NULL,
- (VOID **)&Wmp
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- Status = gBS->LocateProtocol (
- &gEfiSupplicantProtocolGuid,
- NULL,
- (VOID **)&Supplicant
- );
- if (EFI_ERROR (Status)) {
- Supplicant = NULL;
- }
- Status = gBS->LocateProtocol (
- &gEfiEapConfigurationProtocolGuid,
- NULL,
- (VOID **)&EapConfig
- );
- if (EFI_ERROR (Status)) {
- EapConfig = NULL;
- }
- //
- // Initialize Nic device data
- //
- Nic = AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA));
- if (Nic == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
- }
- Nic->Signature = WIFI_MGR_DEVICE_DATA_SIGNATURE;
- Nic->Private = mPrivate;
- Nic->Wmp = Wmp;
- Nic->Supplicant = Supplicant;
- Nic->EapConfig = EapConfig;
- Nic->UserSelectedProfile = NULL;
- Nic->OneTimeScanRequest = FALSE;
- if (Nic->Supplicant != NULL) {
- Status = WifiMgrGetSupportedSuites (Nic);
- }
- if (!EFI_ERROR (Status)) {
- InitializeListHead (&Nic->ProfileList);
- Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
- if (Nic->ConnectPendingNetwork == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to allocate memory for ConnectPendingNetwork\n"));
- goto ERROR;
- }
- Status = WiFiProfileSyncProtocol->GetProfile (Nic->ConnectPendingNetwork, Nic->MacAddress);
- if (!EFI_ERROR (Status) && (Nic->ConnectPendingNetwork != NULL)) {
- Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
- if (!EFI_ERROR (Status)) {
- return Status;
- }
- } else {
- DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get WiFi profile with status %r\n", Status));
- }
- } else {
- DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get Supported suites with status %r\n", Status));
- }
- if (Nic->ConnectPendingNetwork != NULL) {
- if (Nic->ConnectPendingNetwork->Network.AKMSuite != NULL) {
- FreePool (Nic->ConnectPendingNetwork->Network.AKMSuite);
- }
- if (Nic->ConnectPendingNetwork->Network.CipherSuite != NULL) {
- FreePool (Nic->ConnectPendingNetwork->Network.CipherSuite);
- }
- FreePool (Nic->ConnectPendingNetwork);
- }
- ERROR:
- if (Nic->Supplicant != NULL) {
- if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {
- FreePool (Nic->SupportedSuites.SupportedAKMSuites);
- }
- if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {
- FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);
- }
- if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {
- FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);
- }
- }
- FreePool (Nic);
- return Status;
- }
- /**
- The callback function for connect operation.
- ASSERT when errors occur in config token.
- @param[in] Event The Connect token receive event.
- @param[in] Context The context of the connect token.
- **/
- VOID
- EFIAPI
- WifiMgrOnConnectFinished (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- EFI_STATUS Status;
- WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;
- WIFI_MGR_NETWORK_PROFILE *ConnectedProfile;
- UINT8 SecurityType;
- UINT8 SSIdLen;
- CHAR8 *AsciiSSId;
- EDKII_WIFI_PROFILE_SYNC_PROTOCOL *WiFiProfileSyncProtocol;
- ASSERT (Context != NULL);
- ConnectedProfile = NULL;
- ConfigToken = (WIFI_MGR_MAC_CONFIG_TOKEN *)Context;
- ASSERT (ConfigToken->Nic != NULL);
- ConfigToken->Nic->ConnectState = WifiMgrDisconnected;
- ASSERT (ConfigToken->Type == TokenTypeConnectNetworkToken);
- ASSERT (ConfigToken->Token.ConnectNetworkToken != NULL);
- Status = gBS->LocateProtocol (&gEdkiiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
- if (!EFI_ERROR (Status)) {
- WiFiProfileSyncProtocol->SetConnectState (ConfigToken->Token.ConnectNetworkToken->ResultCode);
- if ((mWifiConnectionCount < MAX_WIFI_CONNETION_ATTEMPTS) &&
- (ConfigToken->Token.ConnectNetworkToken->ResultCode != ConnectSuccess))
- {
- mWifiConnectionCount++;
- gBS->CloseEvent (Event);
- Status = ConnectionRetry (WiFiProfileSyncProtocol);
- if (!EFI_ERROR (Status)) {
- return;
- }
- WiFiProfileSyncProtocol->SetConnectState (Status);
- }
- }
- if (ConfigToken->Token.ConnectNetworkToken->Status != EFI_SUCCESS) {
- if (ConfigToken->Nic->OneTimeConnectRequest) {
- //
- // Only update message for user triggered connection
- //
- if (ConfigToken->Token.ConnectNetworkToken->Status == EFI_ACCESS_DENIED) {
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Connect Failed: Permission Denied!");
- } else {
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Connect Failed!");
- }
- ConfigToken->Nic->OneTimeConnectRequest = FALSE;
- }
- ConfigToken->Nic->CurrentOperateNetwork = NULL;
- return;
- }
- if (ConfigToken->Token.ConnectNetworkToken->ResultCode != ConnectSuccess) {
- if (ConfigToken->Nic->OneTimeConnectRequest) {
- if (ConfigToken->Token.ConnectNetworkToken->ResultCode == ConnectFailedReasonUnspecified) {
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Connect Failed: Wrong Password or Unexpected Error!");
- } else {
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Connect Failed!");
- }
- }
- goto Exit;
- }
- if ((ConfigToken->Token.ConnectNetworkToken->Data == NULL) ||
- (ConfigToken->Token.ConnectNetworkToken->Data->Network == NULL))
- {
- //
- // An unexpected error occurs, tell low layer to perform a disconnect
- //
- ConfigToken->Nic->HasDisconnectPendingNetwork = TRUE;
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL);
- goto Exit;
- }
- //
- // A correct connect token received, terminate the connection process
- //
- Status = WifiMgrCheckRSN (
- ConfigToken->Token.ConnectNetworkToken->Data->Network->AKMSuite,
- ConfigToken->Token.ConnectNetworkToken->Data->Network->CipherSuite,
- ConfigToken->Nic,
- &SecurityType,
- NULL,
- NULL
- );
- if (EFI_ERROR (Status)) {
- SecurityType = SECURITY_TYPE_UNKNOWN;
- }
- SSIdLen = ConfigToken->Token.ConnectNetworkToken->Data->Network->SSId.SSIdLen;
- AsciiSSId = (CHAR8 *)AllocateZeroPool (sizeof (CHAR8) * (SSIdLen + 1));
- if (AsciiSSId == NULL) {
- ConfigToken->Nic->HasDisconnectPendingNetwork = TRUE;
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL);
- goto Exit;
- }
- CopyMem (AsciiSSId, ConfigToken->Token.ConnectNetworkToken->Data->Network->SSId.SSId, SSIdLen);
- *(AsciiSSId + SSIdLen) = '\0';
- ConnectedProfile = WifiMgrGetProfileByAsciiSSId (AsciiSSId, SecurityType, &ConfigToken->Nic->ProfileList);
- FreePool (AsciiSSId);
- if (ConnectedProfile == NULL) {
- ConfigToken->Nic->HasDisconnectPendingNetwork = TRUE;
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL);
- goto Exit;
- }
- ConfigToken->Nic->ConnectState = WifiMgrConnectedToAp;
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, TRUE, NULL);
- Exit:
- if (ConfigToken->Nic->ConnectState == WifiMgrDisconnected) {
- ConfigToken->Nic->CurrentOperateNetwork = NULL;
- }
- ConfigToken->Nic->OneTimeConnectRequest = FALSE;
- WifiMgrFreeToken (ConfigToken);
- }
- /**
- Start connect operation, and send out a token to connect to a target network.
- @param[in] Nic Pointer to the device data of the selected NIC.
- @param[in] Profile The target network to be connected.
- @retval EFI_SUCCESS The operation is completed.
- @retval EFI_ALREADY_STARTED Already in "connected" state, need to perform a disconnect
- operation first.
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
- @retval Other Errors Return errors when connecting network on low layer.
- **/
- EFI_STATUS
- WifiMgrConnectToNetwork (
- IN WIFI_MGR_DEVICE_DATA *Nic,
- IN WIFI_MGR_NETWORK_PROFILE *Profile
- )
- {
- EFI_STATUS Status;
- EFI_TPL OldTpl;
- EFI_ADAPTER_INFO_MEDIA_STATE LinkState;
- WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;
- EFI_80211_CONNECT_NETWORK_TOKEN *ConnectToken;
- if ((Nic == NULL) || (Nic->Wmp == NULL) || (Profile == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- Status = WifiMgrGetLinkState (Nic, &LinkState);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if (LinkState.MediaState == EFI_SUCCESS) {
- return EFI_ALREADY_STARTED;
- }
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- Status = WifiMgrPrepareConnection (Nic, Profile);
- if (EFI_ERROR (Status)) {
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- //
- // Create a new connect token
- //
- ConfigToken = AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN));
- if (ConfigToken == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
- ConfigToken->Type = TokenTypeConnectNetworkToken;
- ConfigToken->Nic = Nic;
- ConfigToken->Token.ConnectNetworkToken = AllocateZeroPool (sizeof (EFI_80211_CONNECT_NETWORK_TOKEN));
- if (ConfigToken->Token.ConnectNetworkToken == NULL) {
- goto Exit;
- }
- ConnectToken = ConfigToken->Token.ConnectNetworkToken;
- ConnectToken->Data = AllocateZeroPool (sizeof (EFI_80211_CONNECT_NETWORK_DATA));
- if (ConnectToken->Data == NULL) {
- goto Exit;
- }
- ConnectToken->Data->Network = AllocateZeroPool (sizeof (EFI_80211_NETWORK));
- if (ConnectToken->Data->Network == NULL) {
- goto Exit;
- }
- CopyMem (ConnectToken->Data->Network, &Profile->Network, sizeof (EFI_80211_NETWORK));
- //
- // Add event handle and start to connect
- //
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- WifiMgrOnConnectFinished,
- ConfigToken,
- &ConnectToken->Event
- );
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
- Nic->ConnectState = WifiMgrConnectingToAp;
- Nic->CurrentOperateNetwork = Profile;
- WifiMgrUpdateConnectMessage (Nic, FALSE, NULL);
- //
- // Start Connecting ...
- //
- Status = Nic->Wmp->ConnectNetwork (Nic->Wmp, ConnectToken);
- //
- // Erase secrets after connection is triggered
- //
- WifiMgrCleanProfileSecrets (Profile);
- if (EFI_ERROR (Status)) {
- if (Status == EFI_ALREADY_STARTED) {
- Nic->ConnectState = WifiMgrConnectedToAp;
- WifiMgrUpdateConnectMessage (Nic, TRUE, NULL);
- } else {
- Nic->ConnectState = WifiMgrDisconnected;
- Nic->CurrentOperateNetwork = NULL;
- if (Nic->OneTimeConnectRequest) {
- if (Status == EFI_NOT_FOUND) {
- WifiMgrUpdateConnectMessage (Nic, FALSE, L"Connect Failed: Not Available!");
- } else {
- WifiMgrUpdateConnectMessage (Nic, FALSE, L"Connect Failed: Unexpected Error!");
- }
- }
- }
- goto Exit;
- }
- Exit:
- if (EFI_ERROR (Status)) {
- WifiMgrFreeToken (ConfigToken);
- }
- gBS->RestoreTPL (OldTpl);
- DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] WifiMgrConnectToNetwork: %r\n", Status));
- return Status;
- }
- /**
- The callback function for disconnect operation.
- ASSERT when errors occur in config token.
- @param[in] Event The Disconnect token receive event.
- @param[in] Context The context of the Disconnect token.
- **/
- VOID
- EFIAPI
- WifiMgrOnDisconnectFinished (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;
- ASSERT (Context != NULL);
- ConfigToken = (WIFI_MGR_MAC_CONFIG_TOKEN *)Context;
- ASSERT (ConfigToken->Nic != NULL);
- ASSERT (ConfigToken->Type == TokenTypeDisconnectNetworkToken);
- ASSERT (ConfigToken->Token.DisconnectNetworkToken != NULL);
- if (ConfigToken->Token.DisconnectNetworkToken->Status != EFI_SUCCESS) {
- ConfigToken->Nic->ConnectState = WifiMgrConnectedToAp;
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL);
- ConfigToken->Nic->OneTimeDisconnectRequest = FALSE;
- goto Exit;
- }
- ConfigToken->Nic->ConnectState = WifiMgrDisconnected;
- ConfigToken->Nic->CurrentOperateNetwork = NULL;
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, TRUE, NULL);
- ConfigToken->Nic->OneTimeDisconnectRequest = FALSE;
- //
- // Disconnected network may not be in network list now, trigger a scan again!
- //
- ConfigToken->Nic->OneTimeScanRequest = TRUE;
- Exit:
- WifiMgrFreeToken (ConfigToken);
- return;
- }
- /**
- Start disconnect operation, and send out a token to disconnect from current connected
- network.
- @param[in] Nic Pointer to the device data of the selected NIC.
- @retval EFI_SUCCESS The operation is completed.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
- @retval Other Errors Return errors when disconnecting a network on low layer.
- **/
- EFI_STATUS
- WifiMgrDisconnectToNetwork (
- IN WIFI_MGR_DEVICE_DATA *Nic
- )
- {
- EFI_STATUS Status;
- EFI_TPL OldTpl;
- WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;
- EFI_80211_DISCONNECT_NETWORK_TOKEN *DisconnectToken;
- if (Nic == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- Status = EFI_SUCCESS;
- ConfigToken = AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN));
- if (ConfigToken == NULL) {
- gBS->RestoreTPL (OldTpl);
- return EFI_OUT_OF_RESOURCES;
- }
- ConfigToken->Type = TokenTypeDisconnectNetworkToken;
- ConfigToken->Nic = Nic;
- ConfigToken->Token.DisconnectNetworkToken = AllocateZeroPool (sizeof (EFI_80211_DISCONNECT_NETWORK_TOKEN));
- if (ConfigToken->Token.DisconnectNetworkToken == NULL) {
- WifiMgrFreeToken (ConfigToken);
- gBS->RestoreTPL (OldTpl);
- return EFI_OUT_OF_RESOURCES;
- }
- DisconnectToken = ConfigToken->Token.DisconnectNetworkToken;
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- WifiMgrOnDisconnectFinished,
- ConfigToken,
- &DisconnectToken->Event
- );
- if (EFI_ERROR (Status)) {
- WifiMgrFreeToken (ConfigToken);
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- Nic->ConnectState = WifiMgrDisconnectingToAp;
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL);
- Status = Nic->Wmp->DisconnectNetwork (Nic->Wmp, DisconnectToken);
- if (EFI_ERROR (Status)) {
- if (Status == EFI_NOT_FOUND) {
- Nic->ConnectState = WifiMgrDisconnected;
- Nic->CurrentOperateNetwork = NULL;
- //
- // This network is not in network list now, trigger a scan again!
- //
- Nic->OneTimeScanRequest = TRUE;
- //
- // State has been changed from Connected to Disconnected
- //
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, TRUE, NULL);
- Status = EFI_SUCCESS;
- } else {
- if (Nic->OneTimeDisconnectRequest) {
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Disconnect Failed: Unexpected Error!");
- }
- Nic->ConnectState = WifiMgrConnectedToAp;
- WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL);
- }
- WifiMgrFreeToken (ConfigToken);
- }
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- /**
- The state machine of the connection manager, periodically check the state and
- perform a corresponding operation.
- @param[in] Event The timer event to be triggered.
- @param[in] Context The context of the Nic device data.
- **/
- VOID
- EFIAPI
- WifiMgrOnTimerTick (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- WIFI_MGR_DEVICE_DATA *Nic;
- EFI_STATUS Status;
- EFI_ADAPTER_INFO_MEDIA_STATE LinkState;
- WIFI_MGR_NETWORK_PROFILE *Profile;
- if (Context == NULL) {
- return;
- }
- Nic = (WIFI_MGR_DEVICE_DATA *)Context;
- NET_CHECK_SIGNATURE (Nic, WIFI_MGR_DEVICE_DATA_SIGNATURE);
- Status = WifiMgrGetLinkState (Nic, &LinkState);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Error: Failed to get link state!\n"));
- return;
- }
- if (Nic->LastLinkState.MediaState != LinkState.MediaState) {
- if ((Nic->LastLinkState.MediaState == EFI_SUCCESS) && (LinkState.MediaState == EFI_NO_MEDIA)) {
- Nic->HasDisconnectPendingNetwork = TRUE;
- }
- Nic->LastLinkState.MediaState = LinkState.MediaState;
- }
- Nic->ScanTickTime++;
- if (((Nic->ScanTickTime > WIFI_SCAN_FREQUENCY) || Nic->OneTimeScanRequest) &&
- (Nic->ScanState == WifiMgrScanFinished))
- {
- Nic->OneTimeScanRequest = FALSE;
- Nic->ScanTickTime = 0;
- DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Scan is triggered.\n"));
- WifiMgrStartScan (Nic);
- }
- if ((Nic->AvailableCount > 0) && (Nic->ScanState == WifiMgrScanFinished)) {
- switch (Nic->ConnectState) {
- case WifiMgrDisconnected:
- if (Nic->HasDisconnectPendingNetwork) {
- Nic->HasDisconnectPendingNetwork = FALSE;
- }
- if (Nic->ConnectPendingNetwork != NULL) {
- Profile = Nic->ConnectPendingNetwork;
- Status = WifiMgrConnectToNetwork (Nic, Profile);
- Nic->ConnectPendingNetwork = NULL;
- if (EFI_ERROR (Status)) {
- //
- // Some error happened, don't wait for a return connect token!
- //
- Nic->OneTimeConnectRequest = FALSE;
- }
- }
- break;
- case WifiMgrConnectingToAp:
- break;
- case WifiMgrDisconnectingToAp:
- break;
- case WifiMgrConnectedToAp:
- if ((Nic->ConnectPendingNetwork != NULL) || Nic->HasDisconnectPendingNetwork) {
- Status = WifiMgrDisconnectToNetwork (Nic);
- if (EFI_ERROR (Status)) {
- //
- // Some error happened, don't wait for a return disconnect token!
- //
- Nic->OneTimeDisconnectRequest = FALSE;
- }
- }
- break;
- default:
- break;
- }
- }
- }
|