/** @file
  The Hii 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"

CHAR16  mVendorStorageName[] = L"WIFI_MANAGER_IFR_NVDATA";

HII_VENDOR_DEVICE_PATH  mWifiMgrDxeHiiVendorDevicePath = {
  {
    {
      HARDWARE_DEVICE_PATH,
      HW_VENDOR_DP,
      {
        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
      }
    },
    WIFI_CONNECTION_MANAGER_CONFIG_GUID
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    {
      (UINT8)(END_DEVICE_PATH_LENGTH),
      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
    }
  }
};

//
// HII Config Access Protocol instance
//
GLOBAL_REMOVE_IF_UNREFERENCED
EFI_HII_CONFIG_ACCESS_PROTOCOL  gWifiMgrDxeHiiConfigAccess = {
  WifiMgrDxeHiiConfigAccessExtractConfig,
  WifiMgrDxeHiiConfigAccessRouteConfig,
  WifiMgrDxeHiiConfigAccessCallback
};

CHAR16  *mSecurityType[] = {
  L"OPEN           ",
  L"WPA-Enterprise ",
  L"WPA2-Enterprise",
  L"WPA-Personal   ",
  L"WPA2-Personal  ",
  L"WEP            ",
  L"WPA3-Personal  ",
  L"WPA3-Enterprise",
  L"UnKnown        "
};

CHAR16  *mSignalStrengthBar[] = {
  L"[-----]",
  L"[*----]",
  L"[**---]",
  L"[***--]",
  L"[****-]",
  L"[*****]"
};

#define  RSSI_TO_SIGNAL_STRENGTH_BAR(Rssi)  mSignalStrengthBar[((Rssi + 19)/20)]

#define  NET_LIST_FOR_EACH_FROM_NODE(Entry, Node, ListHead) \
  for(Entry = Node->ForwardLink; Entry != (ListHead); Entry = Entry->ForwardLink)

extern EFI_GUID  gWifiConfigFormSetGuid;

/**
  Create Hii Extend Label OpCode as the start opcode and end opcode.
  The caller is responsible for freeing the OpCode with HiiFreeOpCodeHandle().

  @param[in]  StartLabelNumber   The number of start label.
  @param[out] StartOpCodeHandle  Points to the start opcode handle.
  @param[out] EndOpCodeHandle    Points to the end opcode handle.

  @retval EFI_OUT_OF_RESOURCES   Do not have sufficient resource to finish this
                                 operation.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.
  @retval EFI_SUCCESS            The operation is completed successfully.
  @retval Other Errors           Returned errors when updating the HII form.

**/
EFI_STATUS
WifiMgrCreateOpCode (
  IN  UINT16  StartLabelNumber,
  OUT VOID    **StartOpCodeHandle,
  OUT VOID    **EndOpCodeHandle
  )
{
  EFI_STATUS          Status;
  EFI_IFR_GUID_LABEL  *InternalStartLabel;
  EFI_IFR_GUID_LABEL  *InternalEndLabel;

  if ((StartOpCodeHandle == NULL) || (EndOpCodeHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Status             = EFI_OUT_OF_RESOURCES;
  *StartOpCodeHandle = NULL;
  *EndOpCodeHandle   = NULL;

  //
  // Initialize the container for dynamic opcodes.
  //
  *StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  if (*StartOpCodeHandle == NULL) {
    goto Exit;
  }

  *EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  if (*EndOpCodeHandle == NULL) {
    goto Exit;
  }

  //
  // Create Hii Extend Label OpCode as the start opcode.
  //
  InternalStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
                                               *StartOpCodeHandle,
                                               &gEfiIfrTianoGuid,
                                               NULL,
                                               sizeof (EFI_IFR_GUID_LABEL)
                                               );
  if (InternalStartLabel == NULL) {
    goto Exit;
  }

  InternalStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  InternalStartLabel->Number       = StartLabelNumber;

  //
  // Create Hii Extend Label OpCode as the end opcode.
  //
  InternalEndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
                                             *EndOpCodeHandle,
                                             &gEfiIfrTianoGuid,
                                             NULL,
                                             sizeof (EFI_IFR_GUID_LABEL)
                                             );
  if (InternalEndLabel == NULL) {
    goto Exit;
  }

  InternalEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  InternalEndLabel->Number       = LABEL_END;

  return EFI_SUCCESS;

Exit:

  if (*StartOpCodeHandle != NULL) {
    HiiFreeOpCodeHandle (*StartOpCodeHandle);
  }

  if (*EndOpCodeHandle != NULL) {
    HiiFreeOpCodeHandle (*EndOpCodeHandle);
  }

  return Status;
}

/**
  Display the Nic list contains all available Nics.

  @param[in]  Private            The pointer to the global private data structure.

  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.
  @retval EFI_SUCCESS            The operation is completed successfully.

**/
EFI_STATUS
WifiMgrShowNicList (
  IN  WIFI_MGR_PRIVATE_DATA  *Private
  )
{
  EFI_STATUS            Status;
  CHAR16                MacString[WIFI_MGR_MAX_MAC_STRING_LEN];
  CHAR16                PortString[WIFI_STR_MAX_SIZE];
  EFI_STRING_ID         PortTitleToken;
  EFI_STRING_ID         PortTitleHelpToken;
  WIFI_MGR_DEVICE_DATA  *Nic;
  LIST_ENTRY            *Entry;
  VOID                  *StartOpCodeHandle;
  VOID                  *EndOpCodeHandle;

  if (Private == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Status = WifiMgrCreateOpCode (
             LABEL_MAC_ENTRY,
             &StartOpCodeHandle,
             &EndOpCodeHandle
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  NET_LIST_FOR_EACH (Entry, &Private->NicList) {
    Nic = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_DEVICE_DATA, Link, WIFI_MGR_DEVICE_DATA_SIGNATURE);
    WifiMgrMacAddrToStr (&Nic->MacAddress, sizeof (MacString), MacString);
    UnicodeSPrint (PortString, sizeof (PortString), L"MAC %s", MacString);
    PortTitleToken = HiiSetString (
                       Private->RegisteredHandle,
                       0,
                       PortString,
                       NULL
                       );
    if (PortTitleToken == 0) {
      Status = EFI_INVALID_PARAMETER;
      goto Exit;
    }

    UnicodeSPrint (PortString, sizeof (PortString), L"MAC Address");
    PortTitleHelpToken = HiiSetString (
                           Private->RegisteredHandle,
                           0,
                           PortString,
                           NULL
                           );
    if (PortTitleHelpToken == 0) {
      Status = EFI_INVALID_PARAMETER;
      goto Exit;
    }

    HiiCreateGotoOpCode (
      StartOpCodeHandle,
      FORMID_WIFI_MAINPAGE,
      PortTitleToken,
      PortTitleHelpToken,
      EFI_IFR_FLAG_CALLBACK,
      (UINT16)(KEY_MAC_ENTRY_BASE + Nic->NicIndex)
      );
  }

  Status = HiiUpdateForm (
             Private->RegisteredHandle,       // HII handle
             &gWifiConfigFormSetGuid,         // Formset GUID
             FORMID_MAC_SELECTION,            // Form ID
             StartOpCodeHandle,               // Label for where to insert opcodes
             EndOpCodeHandle                  // Replace data
             );

Exit:

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
  return Status;
}

/**
  Retreive the unicode string of the AKM Suite list of a profile.
  The caller is responsible for freeing the string with FreePool().

  @param[in]  Profile           The network profile contains a AKM suite list.

  @return the unicode string of AKM suite list or "None".

**/
CHAR16 *
WifiMgrGetStrAKMList (
  IN  WIFI_MGR_NETWORK_PROFILE  *Profile
  )
{
  UINT8   Index;
  UINT16  AKMSuiteCount;
  CHAR16  *AKMListDisplay;
  UINTN   Length;

  AKMListDisplay = NULL;
  if ((Profile == NULL) || (Profile->Network.AKMSuite == NULL)) {
    goto Exit;
  }

  AKMSuiteCount = Profile->Network.AKMSuite->AKMSuiteCount;
  if (AKMSuiteCount != 0) {
    //
    // Current AKM Suite is between 1-18
    //
    AKMListDisplay = (CHAR16 *)AllocateZeroPool (sizeof (CHAR16) * (AKMSuiteCount * 3 + 1));
    Length         = 0;
    if (AKMListDisplay != NULL) {
      for (Index = 0; Index < AKMSuiteCount; Index++) {
        //
        // The size of buffer should be 4 CHAR16 for Null-terminated Unicode string.
        //
        UnicodeSPrint (
          AKMListDisplay + Length,
          sizeof (CHAR16) * 4,
          L"%d ",
          Profile->Network.AKMSuite->AKMSuiteList[Index].SuiteType
          );
        Length = StrLen (AKMListDisplay + Length) + Length;
        if (Index == AKMSuiteCount - 1) {
          *(AKMListDisplay + (Length - 1)) = L'\0';
        }
      }
    }
  }

Exit:

  if (AKMListDisplay == NULL) {
    AKMListDisplay = AllocateCopyPool (sizeof (L"None"), L"None");
  }

  return AKMListDisplay;
}

/**
  Retreive the unicode string of the Cipher Suite list of a profile.
  The caller is responsible for freeing the string with FreePool().

  @param[in]  Profile           The network profile contains a Cipher suite list.

  @return the unicode string of Cipher suite list or "None".

**/
CHAR16 *
WifiMgrGetStrCipherList (
  IN  WIFI_MGR_NETWORK_PROFILE  *Profile
  )
{
  UINT8   Index;
  UINT16  CipherSuiteCount;
  CHAR16  *CipherListDisplay;

  CipherListDisplay = NULL;
  if ((Profile == NULL) || (Profile->Network.CipherSuite == NULL)) {
    goto Exit;
  }

  CipherSuiteCount = Profile->Network.CipherSuite->CipherSuiteCount;
  if (CipherSuiteCount != 0) {
    //
    // Current Cipher Suite is between 1-9
    //
    CipherListDisplay = (CHAR16 *)AllocateZeroPool (sizeof (CHAR16) * (CipherSuiteCount * 2 + 1));
    if (CipherListDisplay != NULL) {
      for (Index = 0; Index < CipherSuiteCount; Index++) {
        //
        // The size of buffer should be 3 CHAR16 for Null-terminated Unicode string.
        // The first char is the Cipher Suite number, the second char is ' ', the third char is '\0'.
        //
        UnicodeSPrint (
          CipherListDisplay + (Index * 2),
          sizeof (CHAR16) * 3,
          L"%d ",
          Profile->Network.CipherSuite->CipherSuiteList[Index].SuiteType
          );
        if (Index == CipherSuiteCount - 1) {
          *(CipherListDisplay + (Index * 2 + 1)) = L'\0';
        }
      }
    }
  }

Exit:

  if (CipherListDisplay == NULL) {
    CipherListDisplay = AllocateCopyPool (sizeof (L"None"), L"None");
  }

  return CipherListDisplay;
}

/**
  Refresh the network list display of the current Nic.

  @param[in]   Private           The pointer to the global private data structure.
  @param[out]  IfrNvData         The IFR NV data.

  @retval EFI_SUCCESS            The operation is completed successfully.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
  @retval Other Errors           Returned errors when creating Opcodes or updating the
                                 Hii form.

**/
EFI_STATUS
WifiMgrRefreshNetworkList (
  IN    WIFI_MGR_PRIVATE_DATA    *Private,
  OUT   WIFI_MANAGER_IFR_NVDATA  *IfrNvData
  )
{
  EFI_STATUS                Status;
  EFI_TPL                   OldTpl;
  UINT32                    AvailableCount;
  EFI_STRING_ID             PortPromptToken;
  EFI_STRING_ID             PortTextToken;
  EFI_STRING_ID             PortHelpToken;
  WIFI_MGR_NETWORK_PROFILE  *Profile;
  LIST_ENTRY                *Entry;
  VOID                      *StartOpCodeHandle;
  VOID                      *EndOpCodeHandle;
  CHAR16                    *AKMListDisplay;
  CHAR16                    *CipherListDisplay;
  CHAR16                    PortString[WIFI_STR_MAX_SIZE];
  UINTN                     PortStringSize;
  WIFI_MGR_NETWORK_PROFILE  *ConnectedProfile;

  if (Private->CurrentNic == NULL) {
    return EFI_SUCCESS;
  }

  Status = WifiMgrCreateOpCode (
             LABEL_NETWORK_LIST_ENTRY,
             &StartOpCodeHandle,
             &EndOpCodeHandle
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  OldTpl            = gBS->RaiseTPL (TPL_CALLBACK);
  AvailableCount    = 0;
  PortStringSize    = sizeof (PortString);
  ConnectedProfile  = NULL;
  AKMListDisplay    = NULL;
  CipherListDisplay = NULL;

  if (Private->CurrentNic->ConnectState == WifiMgrConnectedToAp) {
    //
    // Display the current connected network.
    // Find the current operate network under connected status.
    //
    if ((Private->CurrentNic->CurrentOperateNetwork != NULL) &&
        Private->CurrentNic->CurrentOperateNetwork->IsAvailable)
    {
      Profile = Private->CurrentNic->CurrentOperateNetwork;
      AvailableCount++;

      AKMListDisplay = WifiMgrGetStrAKMList (Profile);
      if (AKMListDisplay == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Exit;
      }

      CipherListDisplay = WifiMgrGetStrCipherList (Profile);
      if (CipherListDisplay == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Exit;
      }

      UnicodeSPrint (PortString, PortStringSize, L"%s (Connected)", Profile->SSId);
      PortPromptToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL);

      if (Profile->SecurityType == SECURITY_TYPE_NONE) {
        PortHelpToken = 0;
      } else {
        UnicodeSPrint (PortString, PortStringSize, L"AKMSuite: %s CipherSuite: %s", AKMListDisplay, CipherListDisplay);
        PortHelpToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL);
      }

      FreePool (AKMListDisplay);
      FreePool (CipherListDisplay);
      AKMListDisplay    = NULL;
      CipherListDisplay = NULL;

      HiiCreateGotoOpCode (
        StartOpCodeHandle,
        FORMID_CONNECT_NETWORK,
        PortPromptToken,
        PortHelpToken,
        EFI_IFR_FLAG_CALLBACK,
        (UINT16)(KEY_AVAILABLE_NETWORK_ENTRY_BASE + Profile->ProfileIndex)
        );

      UnicodeSPrint (
        PortString,
        PortStringSize,
        L"%s       %s %s",
        (Profile->SecurityType != SECURITY_TYPE_NONE ? L"Secured" : L"Open   "),
        mSecurityType[Profile->SecurityType],
        RSSI_TO_SIGNAL_STRENGTH_BAR (Profile->NetworkQuality)
        );
      PortTextToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL);

      HiiCreateTextOpCode (
        StartOpCodeHandle,
        PortTextToken,
        0,
        0
        );

      ConnectedProfile = Profile;
    } else {
      Private->CurrentNic->HasDisconnectPendingNetwork = TRUE;
    }
  }

  //
  // Display all supported available networks.
  //
  NET_LIST_FOR_EACH (Entry, &Private->CurrentNic->ProfileList) {
    Profile = NET_LIST_USER_STRUCT_S (
                Entry,
                WIFI_MGR_NETWORK_PROFILE,
                Link,
                WIFI_MGR_PROFILE_SIGNATURE
                );
    if (ConnectedProfile == Profile) {
      continue;
    }

    if (Profile->IsAvailable && Profile->CipherSuiteSupported) {
      AvailableCount++;

      AKMListDisplay = WifiMgrGetStrAKMList (Profile);
      if (AKMListDisplay == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Exit;
      }

      CipherListDisplay = WifiMgrGetStrCipherList (Profile);
      if (CipherListDisplay == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Exit;
      }

      PortPromptToken = HiiSetString (Private->RegisteredHandle, 0, Profile->SSId, NULL);
      if (PortPromptToken == 0) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Exit;
      }

      if (Profile->SecurityType == SECURITY_TYPE_NONE) {
        PortHelpToken = 0;
      } else {
        UnicodeSPrint (
          PortString,
          PortStringSize,
          L"AKMSuite: %s CipherSuite: %s",
          AKMListDisplay,
          CipherListDisplay
          );
        PortHelpToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL);
        if (PortHelpToken == 0) {
          Status = EFI_OUT_OF_RESOURCES;
          goto Exit;
        }
      }

      FreePool (AKMListDisplay);
      FreePool (CipherListDisplay);
      AKMListDisplay    = NULL;
      CipherListDisplay = NULL;

      HiiCreateGotoOpCode (
        StartOpCodeHandle,
        FORMID_CONNECT_NETWORK,
        PortPromptToken,
        PortHelpToken,
        EFI_IFR_FLAG_CALLBACK,
        (UINT16)(KEY_AVAILABLE_NETWORK_ENTRY_BASE + Profile->ProfileIndex)
        );

      UnicodeSPrint (
        PortString,
        PortStringSize,
        L"%s       %s %s",
        (Profile->SecurityType != SECURITY_TYPE_NONE ? L"Secured" : L"Open   "),
        mSecurityType[Profile->SecurityType],
        RSSI_TO_SIGNAL_STRENGTH_BAR (Profile->NetworkQuality)
        );
      PortTextToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL);
      if (PortTextToken == 0) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Exit;
      }

      HiiCreateTextOpCode (
        StartOpCodeHandle,
        PortTextToken,
        0,
        0
        );
    }
  }

  //
  // Display all Unsupported available networks.
  //
  NET_LIST_FOR_EACH (Entry, &Private->CurrentNic->ProfileList) {
    Profile = NET_LIST_USER_STRUCT_S (
                Entry,
                WIFI_MGR_NETWORK_PROFILE,
                Link,
                WIFI_MGR_PROFILE_SIGNATURE
                );
    if (ConnectedProfile == Profile) {
      continue;
    }

    if (Profile->IsAvailable && !Profile->CipherSuiteSupported) {
      AvailableCount++;

      AKMListDisplay = WifiMgrGetStrAKMList (Profile);
      if (AKMListDisplay == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Exit;
      }

      CipherListDisplay = WifiMgrGetStrCipherList (Profile);
      if (CipherListDisplay == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Exit;
      }

      PortPromptToken = HiiSetString (Private->RegisteredHandle, 0, Profile->SSId, NULL);

      if (Profile->AKMSuiteSupported) {
        UnicodeSPrint (
          PortString,
          PortStringSize,
          L"AKMSuite: %s CipherSuite(UnSupported): %s",
          AKMListDisplay,
          CipherListDisplay
          );
      } else {
        UnicodeSPrint (
          PortString,
          PortStringSize,
          L"AKMSuite(UnSupported): %s CipherSuite(UnSupported): %s",
          AKMListDisplay,
          CipherListDisplay
          );
      }

      FreePool (AKMListDisplay);
      FreePool (CipherListDisplay);
      AKMListDisplay    = NULL;
      CipherListDisplay = NULL;

      PortHelpToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL);

      HiiCreateGotoOpCode (
        StartOpCodeHandle,
        FORMID_CONNECT_NETWORK,
        PortPromptToken,
        PortHelpToken,
        EFI_IFR_FLAG_CALLBACK,
        (UINT16)(KEY_AVAILABLE_NETWORK_ENTRY_BASE + Profile->ProfileIndex)
        );

      UnicodeSPrint (
        PortString,
        PortStringSize,
        L"%s       %s %s",
        L"UnSupported",
        mSecurityType[Profile->SecurityType],
        RSSI_TO_SIGNAL_STRENGTH_BAR (Profile->NetworkQuality)
        );
      PortTextToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL);

      HiiCreateTextOpCode (
        StartOpCodeHandle,
        PortTextToken,
        0,
        0
        );
    }
  }

  Status = HiiUpdateForm (
             Private->RegisteredHandle,       // HII handle
             &gWifiConfigFormSetGuid,         // Formset GUID
             FORMID_NETWORK_LIST,             // Form ID
             StartOpCodeHandle,               // Label for where to insert opcodes
             EndOpCodeHandle                  // Replace data
             );

Exit:

  gBS->RestoreTPL (OldTpl);

  if (AKMListDisplay != NULL) {
    FreePool (AKMListDisplay);
  }

  if (CipherListDisplay != NULL) {
    FreePool (CipherListDisplay);
  }

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);

  DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Network List is Refreshed!\n"));
  return Status;
}

/**
  Refresh the hidden network list configured by user.

  @param[in]   Private           The pointer to the global private data structure.

  @retval EFI_SUCCESS            The operation is completed successfully.
  @retval Other Errors           Returned errors when creating Opcodes or updating the
                                 Hii form.
**/
EFI_STATUS
WifiMgrRefreshHiddenList (
  IN    WIFI_MGR_PRIVATE_DATA  *Private
  )
{
  EFI_STATUS                Status;
  EFI_TPL                   OldTpl;
  UINTN                     Index;
  EFI_STRING_ID             StringId;
  VOID                      *StartOpCodeHandle;
  VOID                      *EndOpCodeHandle;
  WIFI_HIDDEN_NETWORK_DATA  *HiddenNetwork;
  LIST_ENTRY                *Entry;

  if (Private == NULL) {
    return EFI_SUCCESS;
  }

  Status = WifiMgrCreateOpCode (
             LABEL_HIDDEN_NETWORK_ENTRY,
             &StartOpCodeHandle,
             &EndOpCodeHandle
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  Index  = 0;

  NET_LIST_FOR_EACH (Entry, &Private->HiddenNetworkList) {
    HiddenNetwork = NET_LIST_USER_STRUCT_S (
                      Entry,
                      WIFI_HIDDEN_NETWORK_DATA,
                      Link,
                      WIFI_MGR_HIDDEN_NETWORK_SIGNATURE
                      );
    StringId = HiiSetString (Private->RegisteredHandle, 0, HiddenNetwork->SSId, NULL);

    HiiCreateCheckBoxOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(KEY_HIDDEN_NETWORK_ENTRY_BASE + Index),
      MANAGER_VARSTORE_ID,
      (UINT16)(HIDDEN_NETWORK_LIST_VAR_OFFSET + Index),
      StringId,
      0,
      0,
      0,
      NULL
      );
    Index++;
  }

  Status = HiiUpdateForm (
             Private->RegisteredHandle,       // HII handle
             &gWifiConfigFormSetGuid,         // Formset GUID
             FORMID_HIDDEN_NETWORK_LIST,      // Form ID
             StartOpCodeHandle,               // Label for where to insert opcodes
             EndOpCodeHandle                  // Replace data
             );

  gBS->RestoreTPL (OldTpl);
  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
  return Status;
}

/**
  Callback function for user to select a Nic.

  @param[in]  Private            The pointer to the global private data structure.
  @param[in]  KeyValue           The key value received from HII input.

  @retval EFI_NOT_FOUND          The corresponding Nic is not found.
  @retval EFI_SUCCESS            The operation is completed successfully.

**/
EFI_STATUS
WifiMgrSelectNic (
  IN     WIFI_MGR_PRIVATE_DATA  *Private,
  IN     EFI_QUESTION_ID        KeyValue
  )
{
  WIFI_MGR_DEVICE_DATA  *Nic;
  UINT32                NicIndex;
  CHAR16                MacString[WIFI_MGR_MAX_MAC_STRING_LEN];

  NicIndex = KeyValue - KEY_MAC_ENTRY_BASE;
  Nic      = WifiMgrGetNicByIndex (Private, NicIndex);
  if (Nic == NULL) {
    return EFI_NOT_FOUND;
  }

  Private->CurrentNic = Nic;

  WifiMgrMacAddrToStr (&Nic->MacAddress, sizeof (MacString), MacString);
  HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_MAC_ADDRESS), MacString, NULL);
  return EFI_SUCCESS;
}

/**
  Restore the NV data to be default.

  @param[in]  Private             The pointer to the global private data structure.
  @param[out] IfrNvData           The IFR NV data.

**/
VOID
WifiMgrCleanUserInput (
  IN  WIFI_MGR_PRIVATE_DATA  *Private
  )
{
  Private->SecurityType        = SECURITY_TYPE_NONE;
  Private->EapAuthMethod       = EAP_AUTH_METHOD_TTLS;
  Private->EapSecondAuthMethod = EAP_SEAUTH_METHOD_MSCHAPV2;
  Private->FileType            = FileTypeMax;
}

/**
  UI handle function when user select a network to connect.

  @param[in]  Private             The pointer to the global private data structure.
  @param[in]  ProfileIndex        The profile index user selected to connect.

  @retval EFI_INVALID_PARAMETER   Nic is null.
  @retval EFI_NOT_FOUND           Profile could not be found.
  @retval EFI_SUCCESS             The operation is completed successfully.

**/
EFI_STATUS
WifiMgrUserSelectProfileToConnect (
  IN     WIFI_MGR_PRIVATE_DATA  *Private,
  IN     UINT32                 ProfileIndex
  )
{
  WIFI_MGR_NETWORK_PROFILE  *Profile;
  WIFI_MGR_DEVICE_DATA      *Nic;

  Nic = Private->CurrentNic;
  if (Nic == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Initialize the connection page
  //
  WifiMgrCleanUserInput (Private);

  Profile = WifiMgrGetProfileByProfileIndex (ProfileIndex, &Nic->ProfileList);
  if (Profile == NULL) {
    return EFI_NOT_FOUND;
  }

  Private->CurrentNic->UserSelectedProfile = Profile;

  return EFI_SUCCESS;
}

/**
  Record password from a HII input string.

  @param[in]  Private             The pointer to the global private data structure.
  @param[in]  StringId            The QuestionId received from HII input.
  @param[in]  StringBuffer        The unicode string buffer to store password.
  @param[in]  StringBufferLen     The len of unicode string buffer.

  @retval EFI_INVALID_PARAMETER   Any input parameter is invalid.
  @retval EFI_NOT_FOUND           The password string is not found or invalid.
  @retval EFI_SUCCESS             The operation is completed successfully.

**/
EFI_STATUS
WifiMgrRecordPassword (
  IN   WIFI_MGR_PRIVATE_DATA  *Private,
  IN   EFI_STRING_ID          StringId,
  IN   CHAR16                 *StringBuffer,
  IN   UINTN                  StringBufferLen
  )
{
  CHAR16  *Password;

  if ((StringId == 0) || (StringBuffer == NULL) || (StringBufferLen <= 0)) {
    return EFI_INVALID_PARAMETER;
  }

  Password = HiiGetString (Private->RegisteredHandle, StringId, NULL);
  if (Password == NULL) {
    return EFI_NOT_FOUND;
  }

  if (StrLen (Password) > StringBufferLen) {
    FreePool (Password);
    return EFI_NOT_FOUND;
  }

  StrnCpyS (StringBuffer, StringBufferLen, Password, StrLen (Password));
  ZeroMem (Password, (StrLen (Password) + 1) * sizeof (CHAR16));
  FreePool (Password);

  //
  // Clean password in string package
  //
  HiiSetString (Private->RegisteredHandle, StringId, L"", NULL);
  return EFI_SUCCESS;
}

/**
  Update connection message on connect configuration page, and trigger related form refresh.

  @param[in]   Nic                        The related Nic for updating message.
  @param[in]   ConnectStateChanged        The tag to tell if the connection state has been changed, only
                                          when the connection changes from "Connected" or "Disconnecting"
                                          to "Disconnected", or from "Disconnected" or "Connecting" to
                                          "Connected", this tag can be set as TRUE.
  @param[in]   ConnectStatusMessage       The message to show on connected status bar, if NULL, will
                                          use default message.

**/
VOID
WifiMgrUpdateConnectMessage (
  IN  WIFI_MGR_DEVICE_DATA  *Nic,
  IN  BOOLEAN               ConnectStateChanged,
  IN  EFI_STRING            ConnectStatusMessage
  )
{
  CHAR16                 ConnectStatusStr[WIFI_STR_MAX_SIZE];
  WIFI_MGR_PRIVATE_DATA  *Private;

  Private = Nic->Private;
  if ((Private == NULL) || (Private->CurrentNic != Nic)) {
    return;
  }

  //
  // Update Connection Status Bar
  //
  if (ConnectStatusMessage != NULL) {
    HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusMessage, NULL);
  } else {
    if (Nic->ConnectState == WifiMgrConnectedToAp) {
      UnicodeSPrint (
        ConnectStatusStr,
        sizeof (ConnectStatusStr),
        L"Connected to %s",
        Nic->CurrentOperateNetwork->SSId
        );
      HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusStr, NULL);
    } else if (Nic->ConnectState == WifiMgrDisconnected) {
      HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), L"Disconnected", NULL);
    } else if (Nic->ConnectState == WifiMgrConnectingToAp) {
      UnicodeSPrint (
        ConnectStatusStr,
        sizeof (ConnectStatusStr),
        L"Connecting to %s ...",
        Nic->CurrentOperateNetwork->SSId
        );
      HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusStr, NULL);
    } else if (Nic->ConnectState == WifiMgrDisconnectingToAp) {
      UnicodeSPrint (
        ConnectStatusStr,
        sizeof (ConnectStatusStr),
        L"Disconnecting from %s ...",
        Nic->CurrentOperateNetwork->SSId
        );
      HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusStr, NULL);
    } else {
      return;
    }
  }

  //
  // Update Connect Button
  //
  if ((Nic->ConnectState == WifiMgrConnectedToAp) && (Nic->UserSelectedProfile == Nic->CurrentOperateNetwork)) {
    HiiSetString (
      Private->RegisteredHandle,
      STRING_TOKEN (STR_CONNECT_NOW),
      L"Disconnect from this Network",
      NULL
      );
  } else {
    HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_NOW), L"Connect to this Network", NULL);
  }

  gBS->SignalEvent (Private->ConnectFormRefreshEvent);

  //
  // Update Main Page and Network List
  //
  if (ConnectStateChanged) {
    if (Nic->ConnectState == WifiMgrConnectedToAp) {
      HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECTION_INFO), L"Connected to", NULL);
      HiiSetString (
        Private->RegisteredHandle,
        STRING_TOKEN (STR_CONNECTED_SSID),
        Nic->CurrentOperateNetwork->SSId,
        NULL
        );
    } else {
      HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECTION_INFO), L"Disconnected", NULL);
      HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECTED_SSID), L"", NULL);
    }

    gBS->SignalEvent (Private->NetworkListRefreshEvent);
    gBS->SignalEvent (Private->MainPageRefreshEvent);
  }
}

/**
  Convert the driver configuration data into the IFR data.

  @param[in]   Private            The pointer to the global private data structure.
  @param[out]  IfrNvData          The IFR NV data.

  @retval EFI_SUCCESS             The operation is completed successfully.

**/
EFI_STATUS
WifiMgrConvertConfigDataToIfrNvData (
  IN   WIFI_MGR_PRIVATE_DATA    *Private,
  OUT  WIFI_MANAGER_IFR_NVDATA  *IfrNvData
  )
{
  //
  // Private shouldn't be NULL here, assert if Private is NULL.
  //
  ASSERT (Private != NULL);

  if (Private->CurrentNic != NULL) {
    IfrNvData->ProfileCount = Private->CurrentNic->AvailableCount;
  } else {
    IfrNvData->ProfileCount = 0;
  }

  return EFI_SUCCESS;
}

/**
  Convert the IFR data into the driver configuration data.

  @param[in]       Private             The pointer to the global private data structure.
  @param[in, out]  IfrNvData           The IFR NV data.

  @retval EFI_SUCCESS                  The operation is completed successfully.

**/
EFI_STATUS
WifiMgrConvertIfrNvDataToConfigData (
  IN     WIFI_MGR_PRIVATE_DATA    *Private,
  IN OUT WIFI_MANAGER_IFR_NVDATA  *IfrNvData
  )
{
  return EFI_SUCCESS;
}

/**
  This function allows the caller to request the current
  configuration for one or more named elements. The resulting
  string is in <ConfigAltResp> format. Any and all alternative
  configuration strings shall also be appended to the end of the
  current configuration string. If they are, they must appear
  after the current configuration. They must contain the same
  routing (GUID, NAME, PATH) as the current configuration string.
  They must have an additional description indicating the type of
  alternative configuration the string represents,
  "ALTCFG=<StringToken>". That <StringToken> (when
  converted from Hex UNICODE to binary) is a reference to a
  string in the associated string pack.

  @param This       Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.

  @param Request    A null-terminated Unicode string in
                    <ConfigRequest> format. Note that this
                    includes the routing information as well as
                    the configurable name / value pairs. It is
                    invalid for this string to be in
                    <MultiConfigRequest> format.
                    If a NULL is passed in for the Request field,
                    all of the settings being abstracted by this function
                    will be returned in the Results field.  In addition,
                    if a ConfigHdr is passed in with no request elements,
                    all of the settings being abstracted for that particular
                    ConfigHdr reference will be returned in the Results Field.

  @param Progress   On return, points to a character in the
                    Request string. Points to the string's null
                    terminator if request was successful. Points
                    to the most recent "&" before the first
                    failing name / value pair (or the beginning
                    of the string if the failure is in the first
                    name / value pair) if the request was not
                    successful.

  @param Results    A null-terminated Unicode string in
                    <MultiConfigAltResp> format which has all values
                    filled in for the names in the Request string.
                    String to be allocated by the called function.

  @retval EFI_SUCCESS             The Results string is filled with the
                                  values corresponding to all requested
                                  names.

  @retval EFI_OUT_OF_RESOURCES    Not enough memory to store the
                                  parts of the results that must be
                                  stored awaiting possible future
                                  protocols.

  @retval EFI_NOT_FOUND           Routing data doesn't match any
                                  known driver. Progress set to the
                                  first character in the routing header.
                                  Note: There is no requirement that the
                                  driver validate the routing data. It
                                  must skip the <ConfigHdr> in order to
                                  process the names.

  @retval EFI_INVALID_PARAMETER   Illegal syntax. Progress set
                                  to most recent "&" before the
                                  error or the beginning of the
                                  string.

  @retval EFI_INVALID_PARAMETER   Unknown name. Progress points
                                  to the & before the name in
                                  question.

**/
EFI_STATUS
EFIAPI
WifiMgrDxeHiiConfigAccessExtractConfig (
  IN CONST  EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN CONST  EFI_STRING                      Request,
  OUT       EFI_STRING                      *Progress,
  OUT       EFI_STRING                      *Results
  )
{
  WIFI_MGR_PRIVATE_DATA    *Private;
  WIFI_MANAGER_IFR_NVDATA  *IfrNvData;
  EFI_STRING               ConfigRequestHdr;
  EFI_STRING               ConfigRequest;
  UINTN                    Size;
  BOOLEAN                  AllocatedRequest;
  UINTN                    BufferSize;
  EFI_STATUS               Status;

  if ((This == NULL) || (Progress == NULL) || (Results == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Request;
  if ((Request != NULL) &&
      !HiiIsConfigHdrMatch (Request, &gWifiConfigFormSetGuid, mVendorStorageName))
  {
    return EFI_NOT_FOUND;
  }

  ConfigRequestHdr = NULL;
  ConfigRequest    = NULL;
  AllocatedRequest = FALSE;
  Size             = 0;

  Private = WIFI_MGR_PRIVATE_DATA_FROM_CONFIG_ACCESS (This);

  BufferSize = sizeof (WIFI_MANAGER_IFR_NVDATA);
  IfrNvData  = AllocateZeroPool (BufferSize);
  if (IfrNvData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  WifiMgrConvertConfigDataToIfrNvData (Private, IfrNvData);

  ConfigRequest = Request;
  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
    //
    // Request has no request element, construct full request string.
    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator.
    //
    ConfigRequestHdr = HiiConstructConfigHdr (
                         &gWifiConfigFormSetGuid,
                         mVendorStorageName,
                         Private->DriverHandle
                         );
    if (ConfigRequestHdr == NULL) {
      FreePool (IfrNvData);
      return EFI_OUT_OF_RESOURCES;
    }

    Size          = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
    ConfigRequest = AllocateZeroPool (Size);
    if (ConfigRequest == NULL) {
      FreePool (IfrNvData);
      FreePool (ConfigRequestHdr);
      return EFI_OUT_OF_RESOURCES;
    }

    AllocatedRequest = TRUE;
    UnicodeSPrint (
      ConfigRequest,
      Size,
      L"%s&OFFSET=0&WIDTH=%016LX",
      ConfigRequestHdr,
      (UINT64)BufferSize
      );
    FreePool (ConfigRequestHdr);
  }

  //
  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
  //
  Status = gHiiConfigRouting->BlockToConfig (
                                gHiiConfigRouting,
                                ConfigRequest,
                                (UINT8 *)IfrNvData,
                                BufferSize,
                                Results,
                                Progress
                                );

  FreePool (IfrNvData);
  //
  // Free the allocated config request string.
  //
  if (AllocatedRequest) {
    FreePool (ConfigRequest);
    ConfigRequest = NULL;
  }

  //
  // Set Progress string to the original request string.
  //
  if (Request == NULL) {
    *Progress = NULL;
  } else if (StrStr (Request, L"OFFSET") == NULL) {
    *Progress = Request + StrLen (Request);
  }

  return Status;
}

/**
  This function applies changes in a driver's configuration.
  Input is a Configuration, which has the routing data for this
  driver followed by name / value configuration pairs. The driver
  must apply those pairs to its configurable storage. If the
  driver's configuration is stored in a linear block of data
  and the driver's name / value pairs are in <BlockConfig>
  format, it may use the ConfigToBlock helper function (above) to
  simplify the job.

  @param This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.

  @param Configuration  A null-terminated Unicode string in
                        <ConfigString> format.

  @param Progress       A pointer to a string filled in with the
                        offset of the most recent '&' before the
                        first failing name / value pair (or the
                        beginn ing of the string if the failure
                        is in the first name / value pair) or
                        the terminating NULL if all was
                        successful.

  @retval EFI_SUCCESS             The results have been distributed or are
                                  awaiting distribution.

  @retval EFI_OUT_OF_RESOURCES    Not enough memory to store the
                                  parts of the results that must be
                                  stored awaiting possible future
                                  protocols.

  @retval EFI_INVALID_PARAMETERS  Passing in a NULL for the
                                  Results parameter would result
                                  in this type of error.

  @retval EFI_NOT_FOUND           Target for the specified routing data
                                  was not found

**/
EFI_STATUS
EFIAPI
WifiMgrDxeHiiConfigAccessRouteConfig (
  IN CONST  EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN CONST  EFI_STRING                      Configuration,
  OUT       EFI_STRING                      *Progress
  )
{
  EFI_STATUS               Status;
  UINTN                    BufferSize;
  WIFI_MGR_PRIVATE_DATA    *Private;
  WIFI_MANAGER_IFR_NVDATA  *IfrNvData;

  if ((Configuration == NULL) || (Progress == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  IfrNvData  = NULL;
  *Progress  = Configuration;
  BufferSize = sizeof (WIFI_MANAGER_IFR_NVDATA);
  Private    = WIFI_MGR_PRIVATE_DATA_FROM_CONFIG_ACCESS (This);

  if (!HiiIsConfigHdrMatch (Configuration, &gWifiConfigFormSetGuid, mVendorStorageName)) {
    return EFI_NOT_FOUND;
  }

  IfrNvData = AllocateZeroPool (BufferSize);
  if (IfrNvData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  WifiMgrConvertConfigDataToIfrNvData (Private, IfrNvData);

  Status = gHiiConfigRouting->ConfigToBlock (
                                gHiiConfigRouting,
                                Configuration,
                                (UINT8 *)IfrNvData,
                                &BufferSize,
                                Progress
                                );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = WifiMgrConvertIfrNvDataToConfigData (Private, IfrNvData);
  ZeroMem (IfrNvData, sizeof (WIFI_MANAGER_IFR_NVDATA));
  FreePool (IfrNvData);

  return Status;
}

/**
  This function is called to provide results data to the driver.
  This data consists of a unique key that is used to identify
  which data is either being passed back or being asked for.

  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param  Action                 Specifies the type of action taken by the browser.
  @param  QuestionId             A unique value which is sent to the original
                                 exporting driver so that it can identify the type
                                 of data to expect. The format of the data tends to
                                 vary based on the opcode that generated the callback.
  @param  Type                   The type of value for the question.
  @param  Value                  A pointer to the data being sent to the original
                                 exporting driver.
  @param  ActionRequest          On return, points to the action requested by the
                                 callback function.

  @retval EFI_SUCCESS            The callback successfully handled the action.
  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
                                 variable and its data.
  @retval EFI_DEVICE_ERROR       The variable could not be saved.
  @retval EFI_UNSUPPORTED        The specified Action is not supported by the
                                 callback.

**/
EFI_STATUS
EFIAPI
WifiMgrDxeHiiConfigAccessCallback (
  IN     CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN     EFI_BROWSER_ACTION                    Action,
  IN     EFI_QUESTION_ID                       QuestionId,
  IN     UINT8                                 Type,
  IN OUT EFI_IFR_TYPE_VALUE                    *Value,
  OUT    EFI_BROWSER_ACTION_REQUEST            *ActionRequest
  )
{
  EFI_STATUS                Status;
  EFI_INPUT_KEY             Key;
  UINTN                     BufferSize;
  WIFI_MGR_PRIVATE_DATA     *Private;
  WIFI_MANAGER_IFR_NVDATA   *IfrNvData;
  EFI_DEVICE_PATH_PROTOCOL  *FilePath;
  WIFI_MGR_NETWORK_PROFILE  *Profile;
  WIFI_MGR_NETWORK_PROFILE  *ProfileToConnect;
  WIFI_HIDDEN_NETWORK_DATA  *HiddenNetwork;
  UINTN                     TempDataSize;
  VOID                      *TempData;
  LIST_ENTRY                *Entry;
  UINT32                    Index;
  UINT32                    RemoveCount;
  CHAR16                    *TempPassword;
  CHAR16                    *ErrorMessage;

  if ((Action != EFI_BROWSER_ACTION_FORM_OPEN) &&
      (Action != EFI_BROWSER_ACTION_FORM_CLOSE) &&
      (Action != EFI_BROWSER_ACTION_CHANGING) &&
      (Action != EFI_BROWSER_ACTION_CHANGED) &&
      (Action != EFI_BROWSER_ACTION_RETRIEVE))
  {
    return EFI_UNSUPPORTED;
  }

  if ((Value == NULL) || (ActionRequest == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Status  = EFI_SUCCESS;
  Private = WIFI_MGR_PRIVATE_DATA_FROM_CONFIG_ACCESS (This);
  if (Private->CurrentNic == NULL) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Retrieve uncommitted data from Browser
  //
  BufferSize = sizeof (WIFI_MANAGER_IFR_NVDATA);
  IfrNvData  = AllocateZeroPool (BufferSize);
  if (IfrNvData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (Action != EFI_BROWSER_ACTION_FORM_OPEN) {
    HiiGetBrowserData (&gWifiConfigFormSetGuid, mVendorStorageName, BufferSize, (UINT8 *)IfrNvData);
  }

  if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
    switch (QuestionId) {
      case KEY_MAC_LIST:

        Status = WifiMgrShowNicList (Private);
        break;

      case KEY_REFRESH_NETWORK_LIST:

        if (Private->CurrentNic->UserSelectedProfile != NULL) {
          Profile = Private->CurrentNic->UserSelectedProfile;

          //
          // Erase secrets since user has left Connection Page
          // Connection Page may direct to Network List Page or Eap Configuration Page,
          // secrets only need to be erased when head to Network List Page
          //
          WifiMgrCleanProfileSecrets (Profile);

          Private->CurrentNic->UserSelectedProfile = NULL;
        }

        break;

      case KEY_ENROLLED_CERT_NAME:

        if (Private->CurrentNic->UserSelectedProfile == NULL) {
          break;
        }

        Profile = Private->CurrentNic->UserSelectedProfile;

        //
        // Enter the key enrollment page
        // For TTLS and PEAP, only CA cert needs to be cared
        //
        if (Private->FileType == FileTypeCACert) {
          if (Profile->CACertData != NULL) {
            HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), Profile->CACertName, NULL);
          } else {
            HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), L"", NULL);
          }
        } else if (Private->FileType == FileTypeClientCert) {
          if (Profile->ClientCertData != NULL) {
            HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), Profile->ClientCertName, NULL);
          } else {
            HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), L"", NULL);
          }
        }

        break;

      case KEY_ENROLLED_PRIVATE_KEY_NAME:

        if (Private->CurrentNic->UserSelectedProfile == NULL) {
          break;
        }

        Profile = Private->CurrentNic->UserSelectedProfile;

        if (Profile->PrivateKeyData != NULL) {
          HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_PRIVATE_KEY_NAME), Profile->PrivateKeyName, NULL);
        } else {
          HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_PRIVATE_KEY_NAME), L"", NULL);
        }

        break;

      default:
        break;
    }
  } else if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {
    switch (QuestionId) {
      case KEY_EAP_ENROLL_CERT_FROM_FILE:

        if (Private->CurrentNic->UserSelectedProfile == NULL) {
          break;
        }

        Profile = Private->CurrentNic->UserSelectedProfile;

        //
        // Enter the network connection configuration page
        // Recovery from restored data
        //
        if (HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_SSID), Profile->SSId, NULL) == 0) {
          return EFI_OUT_OF_RESOURCES;
        }

        IfrNvData->SecurityType = Profile->SecurityType;
        if (HiiSetString (
              Private->RegisteredHandle,
              STRING_TOKEN (STR_SECURITY_TYPE),
              mSecurityType[IfrNvData->SecurityType],
              NULL
              ) == 0)
        {
          return EFI_OUT_OF_RESOURCES;
        }

        if (  (IfrNvData->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE)
           || (IfrNvData->SecurityType == SECURITY_TYPE_WPA3_ENTERPRISE))
        {
          IfrNvData->EapAuthMethod       = Profile->EapAuthMethod;
          IfrNvData->EapSecondAuthMethod = Profile->EapSecondAuthMethod;
          StrCpyS (IfrNvData->EapIdentity, EAP_IDENTITY_SIZE, Profile->EapIdentity);
        }

        break;

      case KEY_CONNECT_ACTION:

        if (Private->CurrentNic->UserSelectedProfile == NULL) {
          break;
        }

        Profile = Private->CurrentNic->UserSelectedProfile;

        //
        // Restore User Config Data for Page recovery
        //
        if ((IfrNvData->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE) ||
            (IfrNvData->SecurityType == SECURITY_TYPE_WPA3_ENTERPRISE))
        {
          Profile->EapAuthMethod       = IfrNvData->EapAuthMethod;
          Profile->EapSecondAuthMethod = IfrNvData->EapSecondAuthMethod;
          StrCpyS (Profile->EapIdentity, EAP_IDENTITY_SIZE, IfrNvData->EapIdentity);
        }

        break;

      default:
        break;
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
    switch (QuestionId) {
      case KEY_NETWORK_LIST:

        //
        // User triggered a scan process.
        //
        Private->CurrentNic->OneTimeScanRequest = TRUE;
        break;

      case KEY_PASSWORD_CONNECT_NETWORK:
      case KEY_EAP_PASSWORD_CONNECT_NETWORK:
      case KEY_PRIVATE_KEY_PASSWORD:

        if (Private->CurrentNic->UserSelectedProfile == NULL) {
          break;
        }

        Profile = Private->CurrentNic->UserSelectedProfile;

        if (QuestionId == KEY_PASSWORD_CONNECT_NETWORK) {
          TempPassword = Profile->Password;
        } else if (QuestionId == KEY_EAP_PASSWORD_CONNECT_NETWORK) {
          TempPassword = Profile->EapPassword;
        } else {
          TempPassword = Profile->PrivateKeyPassword;
        }

        Status = WifiMgrRecordPassword (Private, Value->string, TempPassword, PASSWORD_STORAGE_SIZE);
        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Error: Failed to input password!"));
          break;
        }

        //
        // This password is not a new created password, so no need to confirm.
        //
        Status = EFI_NOT_FOUND;
        break;

      case KEY_CONNECT_ACTION:

        ErrorMessage     = NULL;
        ProfileToConnect = NULL;

        if (Private->CurrentNic->UserSelectedProfile == NULL) {
          break;
        }

        Profile = Private->CurrentNic->UserSelectedProfile;

        if ((Private->CurrentNic->ConnectState == WifiMgrDisconnected) ||
            (Profile != Private->CurrentNic->CurrentOperateNetwork))
        {
          //
          // When this network is not currently connected, pend it to connect.
          //
          if (Profile->AKMSuiteSupported && Profile->CipherSuiteSupported) {
            if ((Profile->SecurityType == SECURITY_TYPE_NONE) ||
                (Profile->SecurityType == SECURITY_TYPE_WPA2_PERSONAL) ||
                (Profile->SecurityType == SECURITY_TYPE_WPA3_PERSONAL))
            {
              //
              // For Open network, connect directly.
              //
              ProfileToConnect = Profile;
            } else if ((Profile->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE) ||
                       (Profile->SecurityType == SECURITY_TYPE_WPA3_ENTERPRISE))
            {
              //
              // For WPA/WPA2-Enterprise network, conduct eap configuration first.
              // Only EAP-TLS, TTLS and PEAP is supported now!
              //
              Profile->EapAuthMethod = IfrNvData->EapAuthMethod;
              StrCpyS (Profile->EapIdentity, EAP_IDENTITY_SIZE, IfrNvData->EapIdentity);

              if ((IfrNvData->EapAuthMethod == EAP_AUTH_METHOD_TTLS) || (IfrNvData->EapAuthMethod == EAP_AUTH_METHOD_PEAP)) {
                Profile->EapSecondAuthMethod = IfrNvData->EapSecondAuthMethod;
                ProfileToConnect             = Profile;
              } else if (IfrNvData->EapAuthMethod == EAP_AUTH_METHOD_TLS) {
                ProfileToConnect = Profile;
              } else {
                ErrorMessage = L"ERROR: Only EAP-TLS, TTLS or PEAP is supported now!";
              }
            } else {
              ErrorMessage = L"ERROR: Can't connect to this network!";
            }
          } else {
            ErrorMessage = L"ERROR: This network is not supported!";
          }

          if (ErrorMessage != NULL) {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              ErrorMessage,
              NULL
              );
          }

          if (ProfileToConnect != NULL) {
            Private->CurrentNic->OneTimeConnectRequest = TRUE;
            Private->CurrentNic->ConnectPendingNetwork = ProfileToConnect;
          }
        } else if (Private->CurrentNic->ConnectState == WifiMgrConnectedToAp) {
          //
          // This network is currently connected, just disconnect from it.
          //
          Private->CurrentNic->OneTimeDisconnectRequest    = TRUE;
          Private->CurrentNic->HasDisconnectPendingNetwork = TRUE;
        }

        break;

      case KEY_ENROLL_CA_CERT_CONNECT_NETWORK:

        Private->FileType = FileTypeCACert;
        break;

      case KEY_ENROLL_CLIENT_CERT_CONNECT_NETWORK:

        Private->FileType = FileTypeClientCert;
        break;

      case KEY_EAP_ENROLL_PRIVATE_KEY_FROM_FILE:

        FilePath = NULL;
        ChooseFile (NULL, NULL, NULL, &FilePath);

        if (FilePath != NULL) {
          UpdatePrivateKeyFromFile (Private, FilePath);
          FreePool (FilePath);
        }

        break;

      case KEY_EAP_ENROLL_CERT_FROM_FILE:

        //
        // User will select a cert file from File Explore
        //
        FilePath = NULL;
        ChooseFile (NULL, NULL, NULL, &FilePath);

        if (FilePath != NULL) {
          UpdateCAFromFile (Private, FilePath);
          FreePool (FilePath);
        }

        break;

      case KEY_SAVE_PRIVATE_KEY_TO_MEM:

        if ((Private->FileContext != NULL) && (Private->FileContext->FHandle != NULL) &&
            (Private->CurrentNic->UserSelectedProfile != NULL))
        {
          //
          // Read Private Key file to Buffer
          //
          Profile = Private->CurrentNic->UserSelectedProfile;
          if (Profile->PrivateKeyData != NULL) {
            ZeroMem (Profile->PrivateKeyData, Profile->PrivateKeyDataSize);
            FreePool (Profile->PrivateKeyData);
            Profile->PrivateKeyData = NULL;
          }

          Status = WifiMgrReadFileToBuffer (
                     Private->FileContext,
                     &TempData,
                     &TempDataSize
                     );
          if (EFI_ERROR (Status)) {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              L"ERROR: Can't read this private key file!",
              NULL
              );
          } else {
            ASSERT (Private->FileContext->FileName != NULL);

            Profile->PrivateKeyData     = TempData;
            Profile->PrivateKeyDataSize = TempDataSize;
            StrCpyS (Profile->PrivateKeyName, WIFI_FILENAME_STR_MAX_SIZE, Private->FileContext->FileName);

            DEBUG ((
              DEBUG_INFO,
              "[WiFi Connection Manager] Private Key: %s has been enrolled! Size: %d\n",
              Profile->PrivateKeyName,
              Profile->PrivateKeyDataSize
              ));
          }
        }

        break;

      case KEY_SAVE_CERT_TO_MEM:

        if ((Private->FileContext != NULL) && (Private->FileContext->FHandle != NULL) &&
            (Private->CurrentNic->UserSelectedProfile != NULL))
        {
          //
          // Read Cert file to Buffer
          //
          Profile = Private->CurrentNic->UserSelectedProfile;

          if (Private->FileType == FileTypeCACert) {
            if (Profile->CACertData != NULL) {
              ZeroMem (Profile->CACertData, Profile->CACertSize);
              FreePool (Profile->CACertData);
              Profile->CACertData = NULL;
            }
          } else if (Private->FileType == FileTypeClientCert) {
            if (Profile->ClientCertData != NULL) {
              ZeroMem (Profile->ClientCertData, Profile->ClientCertSize);
              FreePool (Profile->ClientCertData);
              Profile->ClientCertData = NULL;
            }
          } else {
            break;
          }

          Status = WifiMgrReadFileToBuffer (
                     Private->FileContext,
                     &TempData,
                     &TempDataSize
                     );
          if (EFI_ERROR (Status)) {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              L"ERROR: Can't read this certificate file!",
              NULL
              );
          } else {
            ASSERT (Private->FileContext->FileName != NULL);
            if (Private->FileType == FileTypeCACert) {
              Profile->CACertData = TempData;
              Profile->CACertSize = TempDataSize;
              StrCpyS (Profile->CACertName, WIFI_FILENAME_STR_MAX_SIZE, Private->FileContext->FileName);
              DEBUG ((
                DEBUG_INFO,
                "[WiFi Connection Manager] CA Cert: %s has been enrolled! Size: %d\n",
                Profile->CACertName,
                Profile->CACertSize
                ));
            } else {
              Profile->ClientCertData = TempData;
              Profile->ClientCertSize = TempDataSize;
              StrCpyS (Profile->ClientCertName, WIFI_FILENAME_STR_MAX_SIZE, Private->FileContext->FileName);
              DEBUG ((
                DEBUG_INFO,
                "[WiFi Connection Manager] Client Cert: %s has been enrolled! Size: %d\n",
                Profile->ClientCertName,
                Profile->ClientCertSize
                ));
            }
          }
        }

        break;

      case KEY_ADD_HIDDEN_NETWORK:

        //
        // Add a Hidden Network
        //
        if ((StrLen (IfrNvData->SSId) < SSID_MIN_LEN) ||
            (Private->HiddenNetworkCount >= HIDDEN_NETWORK_LIST_COUNT_MAX))
        {
          Status = EFI_ABORTED;
          break;
        } else {
          //
          // Check if this SSId is already in Hidden Network List
          //
          NET_LIST_FOR_EACH (Entry, &Private->HiddenNetworkList) {
            HiddenNetwork = NET_LIST_USER_STRUCT_S (
                              Entry,
                              WIFI_HIDDEN_NETWORK_DATA,
                              Link,
                              WIFI_MGR_HIDDEN_NETWORK_SIGNATURE
                              );
            if (StrCmp (HiddenNetwork->SSId, IfrNvData->SSId) == 0) {
              Status = EFI_ABORTED;
              break;
            }
          }
        }

        HiddenNetwork = (WIFI_HIDDEN_NETWORK_DATA *)AllocateZeroPool (sizeof (WIFI_HIDDEN_NETWORK_DATA));
        if (HiddenNetwork == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }

        HiddenNetwork->Signature = WIFI_MGR_HIDDEN_NETWORK_SIGNATURE;
        StrCpyS (HiddenNetwork->SSId, SSID_STORAGE_SIZE, IfrNvData->SSId);

        InsertTailList (&Private->HiddenNetworkList, &HiddenNetwork->Link);
        Private->HiddenNetworkCount++;

        WifiMgrRefreshHiddenList (Private);
        break;

      case KEY_REMOVE_HIDDEN_NETWORK:

        //
        // Remove Hidden Networks
        //
        Entry       = GetFirstNode (&Private->HiddenNetworkList);
        RemoveCount = 0;
        for (Index = 0; Index < Private->HiddenNetworkCount; Index++) {
          if (IfrNvData->HiddenNetworkList[Index] != 0) {
            HiddenNetwork = NET_LIST_USER_STRUCT_S (Entry, WIFI_HIDDEN_NETWORK_DATA, Link, WIFI_MGR_HIDDEN_NETWORK_SIGNATURE);
            Entry         = RemoveEntryList (Entry);
            RemoveCount++;

            FreePool (HiddenNetwork);
          } else {
            Entry = GetNextNode (&Private->HiddenNetworkList, Entry);
          }
        }

        Private->HiddenNetworkCount -= RemoveCount;
        WifiMgrRefreshHiddenList (Private);
        break;

      default:

        if ((QuestionId >= KEY_MAC_ENTRY_BASE) && (QuestionId < KEY_MAC_ENTRY_BASE + Private->NicCount)) {
          //
          // User selects a wireless NIC.
          //
          Status = WifiMgrSelectNic (Private, QuestionId);
          if (EFI_ERROR (Status)) {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              L"ERROR: Fail to operate the wireless NIC!",
              NULL
              );
          }
        } else if (Private->CurrentNic != NULL) {
          if ((QuestionId >= KEY_AVAILABLE_NETWORK_ENTRY_BASE) &&
              (QuestionId <= KEY_AVAILABLE_NETWORK_ENTRY_BASE + Private->CurrentNic->MaxProfileIndex))
          {
            Status = WifiMgrUserSelectProfileToConnect (Private, QuestionId - KEY_AVAILABLE_NETWORK_ENTRY_BASE);
            if (!EFI_ERROR (Status)) {
              WifiMgrUpdateConnectMessage (Private->CurrentNic, FALSE, NULL);
            }
          }

          if (EFI_ERROR (Status)) {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              L"ERROR: Fail to operate this profile!",
              NULL
              );
          }

          if (Private->CurrentNic->UserSelectedProfile == NULL) {
            break;
          }

          Profile = Private->CurrentNic->UserSelectedProfile;

          //
          // Enter the network connection configuration page
          // Recovery from restored data
          //
          if (HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_SSID), Profile->SSId, NULL) == 0) {
            return EFI_OUT_OF_RESOURCES;
          }

          IfrNvData->SecurityType = Profile->SecurityType;
          if (HiiSetString (
                Private->RegisteredHandle,
                STRING_TOKEN (STR_SECURITY_TYPE),
                mSecurityType[IfrNvData->SecurityType],
                NULL
                ) == 0)
          {
            return EFI_OUT_OF_RESOURCES;
          }

          if (  (IfrNvData->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE)
             || (IfrNvData->SecurityType == SECURITY_TYPE_WPA3_ENTERPRISE))
          {
            IfrNvData->EapAuthMethod       = Profile->EapAuthMethod;
            IfrNvData->EapSecondAuthMethod = Profile->EapSecondAuthMethod;
            StrCpyS (IfrNvData->EapIdentity, EAP_IDENTITY_SIZE, Profile->EapIdentity);
          }
        }

        break;
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
    switch (QuestionId) {
      case KEY_SAVE_CERT_TO_MEM:
      case KEY_SAVE_PRIVATE_KEY_TO_MEM:

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
        break;

      case KEY_NO_SAVE_CERT_TO_MEM:
      case KEY_NO_SAVE_PRIVATE_KEY_TO_MEM:

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
        break;

      default:

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
        break;
    }
  } else if (Action == EFI_BROWSER_ACTION_RETRIEVE) {
    switch (QuestionId) {
      case KEY_REFRESH_NETWORK_LIST:

        WifiMgrRefreshNetworkList (Private, IfrNvData);
        break;

      default:
        break;
    }
  }

  if (!EFI_ERROR (Status) && (Action != EFI_BROWSER_ACTION_FORM_OPEN)) {
    //
    // Pass changed uncommitted data back to Form Browser.
    //
    BufferSize = sizeof (WIFI_MANAGER_IFR_NVDATA);
    HiiSetBrowserData (&gWifiConfigFormSetGuid, mVendorStorageName, BufferSize, (UINT8 *)IfrNvData, NULL);
  }

  ZeroMem (IfrNvData, sizeof (WIFI_MANAGER_IFR_NVDATA));
  FreePool (IfrNvData);
  return Status;
}

/**
  Initialize the WiFi configuration form.

  @param[in]  Private             The pointer to the global private data structure.

  @retval EFI_SUCCESS             The configuration form is initialized.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
  @retval EFI_INVALID_PARAMETER   Any input parameter is invalid.
  @retval Other Erros             Returned Errors when installing protocols.

**/
EFI_STATUS
WifiMgrDxeConfigFormInit (
  WIFI_MGR_PRIVATE_DATA  *Private
  )
{
  EFI_STATUS  Status;

  if (Private == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private->ConfigAccess.ExtractConfig = WifiMgrDxeHiiConfigAccessExtractConfig;
  Private->ConfigAccess.RouteConfig   = WifiMgrDxeHiiConfigAccessRouteConfig;
  Private->ConfigAccess.Callback      = WifiMgrDxeHiiConfigAccessCallback;

  //
  // Install Device Path Protocol and Config Access protocol to driver handle.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Private->DriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  &mWifiMgrDxeHiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &Private->ConfigAccess,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Publish our HII data.
  //
  Private->RegisteredHandle = HiiAddPackages (
                                &gWifiConfigFormSetGuid,
                                Private->DriverHandle,
                                WifiConnectionManagerDxeStrings,
                                WifiConnectionManagerDxeBin,
                                NULL
                                );
  if (Private->RegisteredHandle == NULL) {
    gBS->UninstallMultipleProtocolInterfaces (
           Private->DriverHandle,
           &gEfiDevicePathProtocolGuid,
           &mWifiMgrDxeHiiVendorDevicePath,
           &gEfiHiiConfigAccessProtocolGuid,
           &Private->ConfigAccess,
           NULL
           );
    return EFI_OUT_OF_RESOURCES;
  }

  Private->FileContext = AllocateZeroPool (sizeof (WIFI_MGR_FILE_CONTEXT));
  if (Private->FileContext == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  Unload the WiFi configuration form.

  @param[in]  Private             The pointer to the global private data structure.

  @retval EFI_SUCCESS             The configuration form is unloaded successfully.
  @retval EFI_INVALID_PARAMETER   Any input parameter is invalid.
  @retval Other Errors            Returned Erros when uninstalling protocols.

**/
EFI_STATUS
WifiMgrDxeConfigFormUnload (
  WIFI_MGR_PRIVATE_DATA  *Private
  )
{
  EFI_STATUS  Status;

  if (Private == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Private->FileContext != NULL) {
    if (Private->FileContext->FHandle != NULL) {
      Private->FileContext->FHandle->Close (Private->FileContext->FHandle);
    }

    if (Private->FileContext->FileName != NULL) {
      FreePool (Private->FileContext->FileName);
    }

    FreePool (Private->FileContext);
  }

  HiiRemovePackages (Private->RegisteredHandle);

  Status = gBS->UninstallMultipleProtocolInterfaces (
                  Private->DriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  &mWifiMgrDxeHiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &Private->ConfigAccess,
                  NULL
                  );

  return Status;
}
