/** @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) {
    Status = gBS->LocateProtocol (&gEdkiiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
    if (!EFI_ERROR (Status)) {
      //
      // Max size of EapIdentity ::= sizeof (CHAR16) * sizeof (Profile->EapIdentity) ::= 2 * EAP_IDENTITY_SIZE
      //
      IdentitySize = sizeof (CHAR8) * (AsciiStrnLenS ((CHAR8 *)Profile->EapIdentity, sizeof (CHAR16) * sizeof (Profile->EapIdentity)) + 1);
    } else {
      IdentitySize = sizeof (CHAR8) * (StrLen (Profile->EapIdentity) + 1);
    }

    Identity = AllocateZeroPool (IdentitySize);
    if (Identity == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    if (!EFI_ERROR (Status)) {
      //
      // The size of Identity from Username may equal
      // to the max size of EapIdentity(EAP_IDENTITY_SIZE*2=128 bytes),
      // so here only valid characters except NULL characters are copied.
      //
      CopyMem (Identity, &Profile->EapIdentity, IdentitySize - 1);
    } 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->ConnectState != WifiMgrConnectedToAp)) ||
       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;
    }
  }
}
