/** @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
};

/**
  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;
  }

  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof (UINT8));
  if (AsciiPassword == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword, PASSWORD_STORAGE_SIZE);
  Status = Supplicant->SetData (
                         Supplicant,
                         EfiSupplicant80211PskPassword,
                         AsciiPassword,
                         (StrLen (Profile->Password) + 1) * sizeof (UINT8)
                         );
  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;
  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;
    }

    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;
}

/**
  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;

  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);
  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;
    }
  }
}
