mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-25 11:55:28 +01:00
2072 lines
66 KiB
C
2072 lines
66 KiB
C
/** @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;
|
|
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);
|
|
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;
|
|
|
|
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) {
|
|
|
|
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) {
|
|
|
|
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;
|
|
}
|
|
|
|
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_CONNECT_ACTION:
|
|
|
|
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_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_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
|
|
);
|
|
}
|
|
}
|
|
|
|
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)) {
|
|
//
|
|
// 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;
|
|
}
|