From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.88; helo=mga01.intel.com; envelope-from=fan.wang@intel.com; receiver=edk2-devel@lists.01.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 69EC6208AE342 for ; Thu, 14 Feb 2019 19:07:54 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Feb 2019 19:07:53 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,371,1544515200"; d="scan'208";a="115089495" Received: from fanwang2-hp.ccr.corp.intel.com ([10.239.9.3]) by orsmga007.jf.intel.com with ESMTP; 14 Feb 2019 19:07:46 -0800 From: Wang Fan To: edk2-devel@lists.01.org Cc: Ye Ting , Fu Siyuan , Wu Jiaxin Date: Fri, 15 Feb 2019 11:07:39 +0800 Message-Id: <20190215030739.6816-1-fan.wang@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 Subject: [Patch] NetworkPkg: Add WiFi Connection Manager to NetworkPkg X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Feb 2019 03:07:54 -0000 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1492 Add WiFi Connection Manager in NetworkPkg to provide UI for users to scan networks, connect or disconnect to networks. This connection manager won't include the UNDI driver, supplicant driver, or other device specific drivers and is therefor not a complete solution stack for UEFI Wi-Fi, users can seek help for Wireless card vendors. Cc: Ye Ting Cc: Fu Siyuan Cc: Wu Jiaxin Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Wang Fan --- NetworkPkg/NetworkPkg.dsc | 1 + NetworkPkg/WifiConnectionManagerDxe/EapContext.h | 28 + .../WifiConnectionManagerDxe.inf | 88 + .../WifiConnectionManagerDxe.vfr | 353 ++++ .../WifiConnectionManagerDxeStrings.uni | 109 ++ .../WifiConnectionMgrComponentName.c | 191 ++ .../WifiConnectionMgrComponentName.h | 99 + .../WifiConnectionMgrConfig.h | 74 + .../WifiConnectionMgrConfigHii.h | 41 + .../WifiConnectionMgrConfigNVDataStruct.h | 157 ++ .../WifiConnectionMgrDriver.c | 717 ++++++++ .../WifiConnectionMgrDriverBinding.h | 148 ++ .../WifiConnectionMgrDxe.h | 344 ++++ .../WifiConnectionMgrFileUtil.c | 308 ++++ .../WifiConnectionMgrFileUtil.h | 77 + .../WifiConnectionMgrHiiConfigAccess.c | 1918 ++++++++++++++++++++ .../WifiConnectionMgrHiiConfigAccess.h | 228 +++ .../WifiConnectionMgrImpl.c | 1409 ++++++++++++++ .../WifiConnectionMgrImpl.h | 123 ++ .../WifiConnectionMgrMisc.c | 784 ++++++++ .../WifiConnectionMgrMisc.h | 279 +++ 21 files changed, 7476 insertions(+) create mode 100644 NetworkPkg/WifiConnectionManagerDxe/EapContext.h create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.vfr create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxeStrings.uni create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.c create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.h create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfig.h create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigHii.h create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriverBinding.h create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.c create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.h create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.h create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.h create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c create mode 100644 NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.h diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc index b543caa08f..b17df46542 100644 --- a/NetworkPkg/NetworkPkg.dsc +++ b/NetworkPkg/NetworkPkg.dsc @@ -114,10 +114,11 @@ NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf NetworkPkg/DnsDxe/DnsDxe.inf NetworkPkg/HttpDxe/HttpDxe.inf NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf NetworkPkg/HttpBootDxe/HttpBootDxe.inf + NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf NetworkPkg/Application/IpsecConfig/IpSecConfig.inf NetworkPkg/Application/VConfig/VConfig.inf [Components.IA32, Components.X64] diff --git a/NetworkPkg/WifiConnectionManagerDxe/EapContext.h b/NetworkPkg/WifiConnectionManagerDxe/EapContext.h new file mode 100644 index 0000000000..b8a474cd2b --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/EapContext.h @@ -0,0 +1,28 @@ +/** @file + Eap configuration data structure definitions for EAP connections. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __EFI_WIFI_EAP_CONTEXT_H__ +#define __EFI_WIFI_EAP_CONTEXT_H__ + +typedef struct { + + BOOLEAN IsEncrypted; + CHAR16 EncryptPassword[PASSWORD_STORAGE_SIZE]; + UINTN KeySize; + UINT8 KeyData[1]; + +} EFI_EAP_PRIVATE_KEY; + +#endif diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf new file mode 100644 index 0000000000..f673428292 --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf @@ -0,0 +1,88 @@ +## @file +# WiFi Connection Manager. +# +# This module is an example of how to make use of UEFI WiFi connection capabilities. +# User can scan, connect and diconnect to networks through UI operations. +# +# Supported networks include: +# 1). Open Network +# 2). WPA2 Personal Network +# 3). EAP Networks (EAP-TLS, EAP-TTLS/MSCHAPv2 and PEAPv0/MSCHAPv2) +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = WifiConnectionManagerDxe + FILE_GUID = c6df98f2-5ec0-4a94-8c11-9a9828ef03f2 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 0.1 + ENTRY_POINT = WifiMgrDxeDriverEntryPoint + UNLOAD_IMAGE = WifiMgrDxeUnload + +[Sources] + WifiConnectionMgrDxe.h + WifiConnectionMgrDriverBinding.h + WifiConnectionMgrConfig.h + WifiConnectionMgrMisc.h + WifiConnectionMgrImpl.h + WifiConnectionMgrConfigNVDataStruct.h + WifiConnectionMgrHiiConfigAccess.h + WifiConnectionMgrComponentName.h + WifiConnectionMgrFileUtil.h + WifiConnectionMgrDriver.c + WifiConnectionMgrComponentName.c + WifiConnectionMgrMisc.c + WifiConnectionMgrHiiConfigAccess.c + WifiConnectionMgrImpl.c + WifiConnectionMgrFileUtil.c + WifiConnectionManagerDxeStrings.uni + WifiConnectionManagerDxe.vfr + EapContext.h + WifiConnectionMgrConfigHii.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + NetworkPkg/NetworkPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + MemoryAllocationLib + BaseMemoryLib + BaseLib + UefiLib + DevicePathLib + DebugLib + HiiLib + PrintLib + UefiHiiServicesLib + NetLib + FileExplorerLib + +[Protocols] + gEfiHiiConfigAccessProtocolGuid ## PRODUCES + gEfiWiFi2ProtocolGuid ## TO_START + gEfiAdapterInformationProtocolGuid ## SOMETIMES_CONSUMES + gEfiSupplicantProtocolGuid ## SOMETIMES_CONSUMES + gEfiEapConfigurationProtocolGuid ## SOMETIMES_CONSUMES + +[Guids] + gEfiIfrTianoGuid ## CONSUMES ## GUID (Extended IFR Guid Opcode) + gEfiAdapterInfoMediaStateGuid ## SOMETIMES_CONSUMES ## GUID # Indicate the current media state status + +[Depex] + gEfiHiiConfigRoutingProtocolGuid AND + gEfiRealTimeClockArchProtocolGuid diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.vfr b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.vfr new file mode 100644 index 0000000000..2674372b11 --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.vfr @@ -0,0 +1,353 @@ +/** @file + Vfr files used in WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "WifiConnectionMgrConfigNVDataStruct.h" + +#define EFI_NETWORK_DEVICE_CLASS 0x04 + +formset + guid = WIFI_CONFIG_FORM_SET_GUID, + title = STRING_TOKEN(STR_WIFI_MGR_FORM_TITLE), + help = STRING_TOKEN(STR_WIFI_MGR_FORM_HELP), + class = EFI_NETWORK_DEVICE_CLASS, + subclass = 0x03, + + varstore WIFI_MANAGER_IFR_NVDATA, + varid = MANAGER_VARSTORE_ID, + name = WIFI_MANAGER_IFR_NVDATA, + guid = WIFI_CONFIG_FORM_SET_GUID; + + form formid = FORMID_MAC_SELECTION, + title = STRING_TOKEN(STR_WIFI_MAC_FORM_TITLE); + + suppressif TRUE; + text + help = STRING_TOKEN(STR_NULL_STRING), + text = STRING_TOKEN(STR_NULL_STRING), + flags = INTERACTIVE, + key = KEY_MAC_LIST; + endif; + + label LABEL_MAC_ENTRY; + label LABEL_END; + endform; + + form formid = FORMID_WIFI_MAINPAGE, + title = STRING_TOKEN(STR_NETWORK_MANAGEMENT_TITLE); + + text + help = STRING_TOKEN(STR_MAC_ADDRESS_HELP), // Help string + text = STRING_TOKEN(STR_MAC_ADDRESS_TITLE), // Prompt string + text = STRING_TOKEN(STR_MAC_ADDRESS); // TextTwo + + text + help = STRING_TOKEN(STR_NULL_STRING), // Help string + text = STRING_TOKEN(STR_CONNECTION_INFO), // Prompt string + text = STRING_TOKEN(STR_CONNECTED_SSID); // TextTwo; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + goto FORMID_NETWORK_LIST, + prompt = STRING_TOKEN(STR_NETWORK_LIST), + help = STRING_TOKEN(STR_NETWORK_LIST_HELP), + flags = INTERACTIVE, + key = KEY_NETWORK_LIST; + + goto FORMID_WIFI_SETTINGS, + prompt = STRING_TOKEN(STR_WIFI_SETTINGS), + help = STRING_TOKEN(STR_WIFI_SETTINGS_HELP), + flags = INTERACTIVE, + key = KEY_WIFI_SETTINGS; + + action + questionid = KEY_REFRESH_TITLE_CONNECTION_STATUS, + prompt = STRING_TOKEN(STR_NULL_STRING), + help = STRING_TOKEN(STR_NULL_STRING), + flags = INTERACTIVE, + config = STRING_TOKEN(STR_NULL_STRING), + refreshguid = WIFI_CONFIG_MAIN_FORM_REFRESH_GUID, + endaction; + + endform; + + form formid = FORMID_NETWORK_LIST, + title = STRING_TOKEN(STR_NETWORK_LIST); + + numeric varid = WIFI_MANAGER_IFR_NVDATA.ProfileCount, + prompt = STRING_TOKEN(STR_REFRESH_NETWORK_COUNT), + help = STRING_TOKEN(STR_REFRESH_NETWORK_COUNT_HELP), + flags = INTERACTIVE | READ_ONLY, + key = KEY_REFRESH_NETWORK_LIST, + minimum = 0, + maximum = 0xffffffff, + step = 0, + default = 0, + refreshguid = WIFI_CONFIG_NETWORK_LIST_REFRESH_GUID, + endnumeric; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + label LABEL_NETWORK_LIST_ENTRY; + label LABEL_END; + endform; + + form formid = FORMID_CONNECT_NETWORK, + title = STRING_TOKEN(STR_NETWORK_CONFIGURATION); + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + text + help = STRING_TOKEN(STR_CONNECT_STATUS_TITLE_HELP), // Help string + text = STRING_TOKEN(STR_CONNECT_STATUS_TITLE), // Prompt string + text = STRING_TOKEN(STR_CONNECT_STATUS); // TextTwo + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + text + help = STRING_TOKEN(STR_SSID_HELP), // Help string + text = STRING_TOKEN(STR_SSID_TITLE), // Prompt string + text = STRING_TOKEN(STR_SSID); // TextTwo + + text + help = STRING_TOKEN(STR_SECURITY_TYPE_HELP), // Help string + text = STRING_TOKEN(STR_SECURITY_TYPE_TITLE), // Prompt string + text = STRING_TOKEN(STR_SECURITY_TYPE); // TextTwo + + + suppressif NOT ideqval WIFI_MANAGER_IFR_NVDATA.SecurityType == SECURITY_TYPE_WPA2_PERSONAL; + password varid = WIFI_MANAGER_IFR_NVDATA.Password, + prompt = STRING_TOKEN(STR_PASSWORD), + help = STRING_TOKEN(STR_PASSWORD_HELP), + flags = INTERACTIVE, + key = KEY_PASSWORD_CONNECT_NETWORK, + minsize = PASSWORD_MIN_LEN, + maxsize = PASSWORD_MAX_LEN, + endpassword; + endif; + + suppressif NOT ideqval WIFI_MANAGER_IFR_NVDATA.SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE; + + oneof varid = WIFI_MANAGER_IFR_NVDATA.EapAuthMethod, + questionid = KEY_EAP_AUTH_METHOD_CONNECT_NETWORK, + prompt = STRING_TOKEN(STR_EAP_AUTH_METHOD), + help = STRING_TOKEN(STR_EAP_AUTH_METHOD_HELP), + flags = INTERACTIVE, + option text = STRING_TOKEN(STR_EAP_AUTH_METHOD_TTLS), value = EAP_AUTH_METHOD_TTLS, flags = DEFAULT; + option text = STRING_TOKEN(STR_EAP_AUTH_METHOD_PEAP), value = EAP_AUTH_METHOD_PEAP, flags = 0; + option text = STRING_TOKEN(STR_EAP_AUTH_METHOD_TLS), value = EAP_AUTH_METHOD_TLS, flags = 0; + endoneof; + + suppressif NOT ideqvallist WIFI_MANAGER_IFR_NVDATA.EapAuthMethod == EAP_AUTH_METHOD_TLS + EAP_AUTH_METHOD_TTLS + EAP_AUTH_METHOD_PEAP; + + goto FORMID_ENROLL_CERT, + prompt = STRING_TOKEN(STR_EAP_ENROLL_CA_CERT), + help = STRING_TOKEN(STR_EAP_ENROLL_CA_CERT_HELP), + flags = INTERACTIVE, + key = KEY_ENROLL_CA_CERT_CONNECT_NETWORK; + + suppressif NOT ideqval WIFI_MANAGER_IFR_NVDATA.EapAuthMethod == EAP_AUTH_METHOD_TLS; + + goto FORMID_ENROLL_CERT, + prompt = STRING_TOKEN(STR_EAP_ENROLL_CLIENT_CERT), + help = STRING_TOKEN(STR_EAP_ENROLL_CLIENT_CERT_HELP), + flags = INTERACTIVE, + key = KEY_ENROLL_CLIENT_CERT_CONNECT_NETWORK; + + goto FORMID_ENROLL_PRIVATE_KEY, + prompt = STRING_TOKEN(STR_EAP_ENROLL_CLIENT_KEY), + help = STRING_TOKEN(STR_EAP_ENROLL_CLIENT_KEY_HELP), + flags = INTERACTIVE, + key = KEY_ENROLL_PRIVATE_KEY_CONNECT_NETWORK; + + endif; + + suppressif NOT ideqvallist WIFI_MANAGER_IFR_NVDATA.EapAuthMethod == EAP_AUTH_METHOD_TTLS + EAP_AUTH_METHOD_PEAP; + + oneof varid = WIFI_MANAGER_IFR_NVDATA.EapSecondAuthMethod, + questionid = KEY_EAP_SEAUTH_METHOD_CONNECT_NETWORK, + prompt = STRING_TOKEN(STR_EAP_SEAUTH_METHOD), + help = STRING_TOKEN(STR_EAP_SEAUTH_METHOD_HELP), + flags = INTERACTIVE, + option text = STRING_TOKEN(STR_EAP_SEAUTH_METHOD_MSCHAPV2), value = EAP_SEAUTH_METHOD_MSCHAPV2, flags = DEFAULT; + endoneof; + endif; + + string varid = WIFI_MANAGER_IFR_NVDATA.EapIdentity, + prompt = STRING_TOKEN(STR_EAP_IDENTITY), + help = STRING_TOKEN(STR_EAP_IDENTITY_HELP), + flags = INTERACTIVE, + key = KEY_EAP_IDENTITY_CONNECT_NETWORK, + minsize = 6, + maxsize = EAP_IDENTITY_LEN, + endstring; + + suppressif NOT ideqvallist WIFI_MANAGER_IFR_NVDATA.EapAuthMethod == EAP_AUTH_METHOD_TTLS + EAP_AUTH_METHOD_PEAP; + + password varid = WIFI_MANAGER_IFR_NVDATA.EapPassword, + prompt = STRING_TOKEN(STR_EAP_PASSWORD), + help = STRING_TOKEN(STR_EAP_PASSWORD_HELP), + flags = INTERACTIVE, + key = KEY_EAP_PASSWORD_CONNECT_NETWORK, + minsize = 0, + maxsize = PASSWORD_MAX_LEN, + endpassword; + endif; + endif; + endif; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + text + help = STRING_TOKEN(STR_CONNECT_NOW_HELP), + text = STRING_TOKEN(STR_CONNECT_NOW), + flags = INTERACTIVE, + key = KEY_CONNECT_ACTION; + + action + questionid = KEY_REFRESH_CONNECT_CONFIGURATION, + prompt = STRING_TOKEN(STR_NULL_STRING), + help = STRING_TOKEN(STR_NULL_STRING), + flags = INTERACTIVE, + config = STRING_TOKEN(STR_NULL_STRING), + refreshguid = WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID, + endaction; + + endform; + + form formid = FORMID_ENROLL_CERT, + title = STRING_TOKEN(STR_EAP_ENROLL_CERT); + + goto FORMID_ENROLL_CERT, + prompt = STRING_TOKEN(STR_EAP_ENROLL_CERT_FROM_FILE), + help = STRING_TOKEN(STR_EAP_ENROLL_CERT_FROM_FILE_HELP), + flags = INTERACTIVE, + key = KEY_EAP_ENROLL_CERT_FROM_FILE; + + text + help = STRING_TOKEN(STR_NULL_STRING), + text = STRING_TOKEN(STR_EAP_ENROLLED_CERT_NAME), + flags = INTERACTIVE, + key = KEY_ENROLLED_CERT_NAME; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + text + help = STRING_TOKEN(STR_SAVE_EXIT_HELP), + text = STRING_TOKEN(STR_SAVE_EXIT), + flags = INTERACTIVE, + key = KEY_SAVE_CERT_TO_MEM; + + text + help = STRING_TOKEN(STR_NO_SAVE_EXIT_HELP), + text = STRING_TOKEN(STR_NO_SAVE_EXIT), + flags = INTERACTIVE, + key = KEY_NO_SAVE_CERT_TO_MEM; + + endform; + + form formid = FORMID_ENROLL_PRIVATE_KEY, + title = STRING_TOKEN(STR_EAP_ENROLL_CLIENT_KEY); + + goto FORMID_ENROLL_PRIVATE_KEY, + prompt = STRING_TOKEN(STR_EAP_ENROLL_KEY_FROM_FILE), + help = STRING_TOKEN(STR_EAP_ENROLL_KEY_FROM_FILE_HELP), + flags = INTERACTIVE, + key = KEY_EAP_ENROLL_PRIVATE_KEY_FROM_FILE; + + text + help = STRING_TOKEN(STR_NULL_STRING), + text = STRING_TOKEN(STR_EAP_ENROLLED_PRIVATE_KEY_NAME), + flags = INTERACTIVE, + key = KEY_ENROLLED_PRIVATE_KEY_NAME; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + password varid = WIFI_MANAGER_IFR_NVDATA.PrivateKeyPassword, + prompt = STRING_TOKEN(STR_EAP_CLIENT_KEY_PASSWORD), + help = STRING_TOKEN(STR_NULL_STRING), + flags = INTERACTIVE, + key = KEY_PRIVATE_KEY_PASSWORD, + minsize = 0, + maxsize = PASSWORD_MAX_LEN, + endpassword; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + text + help = STRING_TOKEN(STR_SAVE_EXIT_HELP), + text = STRING_TOKEN(STR_SAVE_EXIT), + flags = INTERACTIVE, + key = KEY_SAVE_PRIVATE_KEY_TO_MEM; + + text + help = STRING_TOKEN(STR_NO_SAVE_EXIT_HELP), + text = STRING_TOKEN(STR_NO_SAVE_EXIT), + flags = INTERACTIVE, + key = KEY_NO_SAVE_PRIVATE_KEY_TO_MEM; + + endform; + + form formid = FORMID_WIFI_SETTINGS, + title = STRING_TOKEN(STR_WIFI_SETTINGS_FORM_TITLE); + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + goto FORMID_HIDDEN_NETWORK_LIST, + prompt = STRING_TOKEN(STR_HIDDEN_NETWORK), + help = STRING_TOKEN(STR_HIDDEN_NETWORK_HELP), + flags = INTERACTIVE, + key = KEY_HIDDEN_NETWORK; + + endform; + + form formid = FORMID_HIDDEN_NETWORK_LIST, + title = STRING_TOKEN(STR_HIDDEN_NETWORK_FORM_TITLE); + + string + varid = WIFI_MANAGER_IFR_NVDATA.SSId, + prompt = STRING_TOKEN(STR_SSID_TITLE), + help = STRING_TOKEN(STR_SSID_HELP), + flags = INTERACTIVE, + minsize = SSID_MIN_LEN, + maxsize = SSID_MAX_LEN, + endstring; + + text + help = STRING_TOKEN(STR_ADD_HIDDEN_NETWORK_HELP), + text = STRING_TOKEN(STR_ADD_HIDDEN_NETWORK), + flags = INTERACTIVE, + key = KEY_ADD_HIDDEN_NETWORK; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + subtitle text = STRING_TOKEN(STR_HIDDEN_NETWORK_LIST); + + label LABEL_HIDDEN_NETWORK_ENTRY; + label LABEL_END; + + text + help = STRING_TOKEN(STR_REMOVE_HIDDEN_NETWORK_HELP), + text = STRING_TOKEN(STR_REMOVE_HIDDEN_NETWORK), + flags = INTERACTIVE, + key = KEY_REMOVE_HIDDEN_NETWORK; + + endform; + +endformset; diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxeStrings.uni b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxeStrings.uni new file mode 100644 index 0000000000..00078cb849 --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxeStrings.uni @@ -0,0 +1,109 @@ +// /** @file +// String definitions for WiFi Connection Manager Forms. +// +// Copyright (c) 2019, Intel Corporation. All rights reserved.
+// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// **/ + +#langdef en-US "English" + +#string STR_WIFI_MGR_FORM_TITLE #language en-US "Wi-Fi Configuration" +#string STR_WIFI_MGR_FORM_HELP #language en-US "Configure the Wi-Fi parameters." + +#string STR_WIFI_MAC_FORM_TITLE #language en-US "MAC Selection" +#string STR_WIFI_MAC_FORM_HELP #language en-US "Select a Nic" + +#string STR_MAC_ADDRESS_TITLE #language en-US "MAC Address" +#string STR_MAC_ADDRESS #language en-US "88-88-88-88-88-87" +#string STR_MAC_ADDRESS_HELP #language en-US "MAC Address" +#string STR_CONNECTION_INFO #language en-US "Disconnected" +#string STR_CONNECTED_SSID #language en-US "" +#string STR_NULL_STRING #language en-US "" + +#string STR_NETWORK_MANAGEMENT_TITLE #language en-US "Wi-Fi Network Management" +#string STR_NETWORK_LIST #language en-US "Wi-Fi Network List" +#string STR_NETWORK_LIST_HELP #language en-US "Available Network List" +#string STR_NETWORK_CONFIGURATION #language en-US "Wi-Fi Network Configuration" + +#string STR_SSID_TITLE #language en-US "SSID" +#string STR_SSID #language en-US "" +#string STR_SSID_HELP #language en-US "SSID Length: 1 - 32 characters" +#string STR_SECURITY_TYPE_TITLE #language en-US "Security" +#string STR_SECURITY_TYPE #language en-US "" +#string STR_SECURITY_TYPE_HELP #language en-US "Network Security Type" + +#string STR_EAP_AUTH_METHOD #language en-US "EAP Authentication Method" +#string STR_EAP_AUTH_METHOD_HELP #language en-US "EAP Authentication Method" +#string STR_EAP_SEAUTH_METHOD #language en-US "EAP Second Authentication Method" +#string STR_EAP_SEAUTH_METHOD_HELP #language en-US "EAP Second Authentication Method" +#string STR_SECURITY_NONE #language en-US "Open" +#string STR_SECURITY_WEP #language en-US "WEP" +#string STR_SECURITY_WPA_PERSONAL #language en-US "WPA-Personal" +#string STR_SECURITY_WPA_ENTERPRISE #language en-US "WPA-Enterprise" +#string STR_SECURITY_WPA2_PERSONAL #language en-US "WPA2-Personal" +#string STR_SECURITY_WPA2_ENTERPRISE #language en-US "WPA2-Enterprise" +#string STR_SECURITY_UNKNOWN #language en-US "Unknown" +#string STR_EAP_AUTH_METHOD_TLS #language en-US "EAPTLS" +#string STR_EAP_AUTH_METHOD_TTLS #language en-US "TTLS" +#string STR_EAP_AUTH_METHOD_PEAP #language en-US "PEAP" +#string STR_EAP_SEAUTH_METHOD_MSCHAPV2 #language en-US "MSCHAPv2" +#string STR_EAP_SEAUTH_METHOD_GTC #language en-US "GTC" + +#string STR_PASSWORD #language en-US "Password" +#string STR_PASSWORD_HELP #language en-US "Password Length: 8 - 63 characters" +#string STR_CONNECT_STATUS_TITLE #language en-US "Connection Status:" +#string STR_CONNECT_STATUS_TITLE_HELP #language en-US "" +#string STR_CONNECT_STATUS #language en-US "" +#string STR_CONNECT_STATUS_HELP #language en-US "" + +#string STR_CONNECT_NOW #language en-US "Connect to network now" +#string STR_CONNECT_NOW_HELP #language en-US "" +#string STR_DISCONNECT_NOW #language en-US "Disconnect from this network" +#string STR_DISCONNECT_NOW_HELP #language en-US "" +#string STR_REFRESH_NETWORK_COUNT #language en-US "Number of Networks" +#string STR_REFRESH_NETWORK_COUNT_HELP #language en-US "The number of current available networks around" + +#string STR_EAP_IDENTITY #language en-US "Identity" +#string STR_EAP_IDENTITY_HELP #language en-US "It is used to query the identity of the peer." +#string STR_EAP_PASSWORD #language en-US "EAP Password" +#string STR_EAP_PASSWORD_HELP #language en-US "Password Length: 1 - 63 characters" + +#string STR_SAVE_EXIT #language en-US "Commit Changes and Exit" +#string STR_SAVE_EXIT_HELP #language en-US "" +#string STR_NO_SAVE_EXIT #language en-US "Discard Changes and Exit" +#string STR_NO_SAVE_EXIT_HELP #language en-US "" + +#string STR_EAP_ENROLL_CERT #language en-US "Enroll Certificate" +#string STR_EAP_ENROLL_CA_CERT #language en-US "Enroll CA Cert" +#string STR_EAP_ENROLL_CA_CERT_HELP #language en-US "" +#string STR_EAP_ENROLL_CLIENT_CERT #language en-US "Enroll Client Cert" +#string STR_EAP_ENROLL_CLIENT_CERT_HELP #language en-US "" +#string STR_EAP_ENROLL_CLIENT_KEY #language en-US "Enroll Client Private Key" +#string STR_EAP_ENROLL_CLIENT_KEY_HELP #language en-US "" +#string STR_EAP_ENROLL_CERT_FROM_FILE #language en-US "Enroll Cert Using File" +#string STR_EAP_ENROLL_CERT_FROM_FILE_HELP #language en-US "" +#string STR_EAP_ENROLL_KEY_FROM_FILE #language en-US "Enroll Private Key Using File" +#string STR_EAP_ENROLL_KEY_FROM_FILE_HELP #language en-US "" +#string STR_EAP_CLIENT_KEY_PASSWORD #language en-US "Client Private Key Password" +#string STR_EAP_ENROLLED_CERT_NAME #language en-US "" +#string STR_EAP_ENROLLED_PRIVATE_KEY_NAME #language en-US "" + +#string STR_WIFI_SETTINGS_FORM_TITLE #language en-US "Wi-Fi Settings" +#string STR_WIFI_SETTINGS #language en-US "Wi-Fi Settings" +#string STR_WIFI_SETTINGS_HELP #language en-US "" + +#string STR_HIDDEN_NETWORK_FORM_TITLE #language en-US "Hidden Network Configuration" +#string STR_HIDDEN_NETWORK #language en-US "Hidden Network Configuration" +#string STR_HIDDEN_NETWORK_HELP #language en-US "" +#string STR_ADD_HIDDEN_NETWORK_HELP #language en-US "Hidden Network List won't be saved in Storage, they will be cleaned after Reset!" +#string STR_ADD_HIDDEN_NETWORK #language en-US "Add Hidden Network" +#string STR_HIDDEN_NETWORK_LIST #language en-US "Hidden Network List" +#string STR_REMOVE_HIDDEN_NETWORK_HELP #language en-US "" +#string STR_REMOVE_HIDDEN_NETWORK #language en-US "Remove Hidden Network" \ No newline at end of file diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.c new file mode 100644 index 0000000000..36c38d3a3c --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.c @@ -0,0 +1,191 @@ +/** @file + UEFI Component Name(2) protocol implementation for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "WifiConnectionMgrDxe.h" + +extern EFI_GUID mEfiWifiMgrPrivateGuid; + +/// +/// Component Name Protocol instance +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_COMPONENT_NAME_PROTOCOL gWifiMgrDxeComponentName = { + (EFI_COMPONENT_NAME_GET_DRIVER_NAME) WifiMgrDxeComponentNameGetDriverName, + (EFI_COMPONENT_NAME_GET_CONTROLLER_NAME) WifiMgrDxeComponentNameGetControllerName, + "eng" +}; + +/// +/// Component Name 2 Protocol instance +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_COMPONENT_NAME2_PROTOCOL gWifiMgrDxeComponentName2 = { + WifiMgrDxeComponentNameGetDriverName, + WifiMgrDxeComponentNameGetControllerName, + "en" +}; + +/// +/// Table of driver names +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_UNICODE_STRING_TABLE mWifiMgrDxeDriverNameTable[] = { + { + "eng;en", + L"WifiConnectionManagerDxe" + }, + { + NULL, + NULL + } +}; + +/// +/// Table of controller names +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_UNICODE_STRING_TABLE mWifiMgrDxeControllerNameTable[] = { + { + "eng;en", + L"WifiConnectionManagerDxe Controller" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param Language A pointer to a three-character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME2_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mWifiMgrDxeDriverNameTable, + DriverName, + (BOOLEAN)(This != &gWifiMgrDxeComponentName2) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language, from the point of view of the driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME2_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + WIFI_MGR_PRIVATE_PROTOCOL *WifiMgrPrivate; + + // + // ChildHandle must be NULL for a Device Driver + // + if (ControllerHandle == NULL || ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // + // Check Controller's handle + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &mEfiWifiMgrPrivateGuid, + (VOID **) &WifiMgrPrivate, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mWifiMgrDxeControllerNameTable, + ControllerName, + (BOOLEAN)(This != &gWifiMgrDxeComponentName2) + ); +} diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.h new file mode 100644 index 0000000000..f69e682950 --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.h @@ -0,0 +1,99 @@ +/** @file + UEFI Component Name(2) protocol implementation for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __EFI_WIFI_COMPONENT_NAME__ +#define __EFI_WIFI_COMPONENT_NAME__ + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param Language A pointer to a three-character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME2_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language, from the point of view of the driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME2_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +#endif diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfig.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfig.h new file mode 100644 index 0000000000..f179fbc4ef --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfig.h @@ -0,0 +1,74 @@ +/** @file + Define network structure used by the WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _WIFI_MGR_CONFIG_H_ +#define _WIFI_MGR_CONFIG_H_ + +#include "WifiConnectionMgrConfigNVDataStruct.h" + +extern UINT8 WifiConnectionManagerDxeBin[]; +extern UINT8 WifiConnectionManagerDxeStrings[]; + +typedef struct { + UINT32 Signature; + + // + // Link to the current profile list in NIC device data (WIFI_MGR_DEVICE_DATA) + // + LIST_ENTRY Link; + + UINT32 NicIndex; + UINT32 ProfileIndex; // The unique identifier for network profile, starts from 1 + CHAR16 SSId[SSID_STORAGE_SIZE]; + CHAR16 Password[PASSWORD_STORAGE_SIZE]; + + UINT8 SecurityType; + UINT8 EapAuthMethod; + + CHAR16 CACertName[WIFI_FILENAME_STR_MAX_SIZE]; + VOID *CACertData; + UINTN CACertSize; + CHAR16 ClientCertName[WIFI_FILENAME_STR_MAX_SIZE]; + VOID *ClientCertData; + UINTN ClientCertSize; + CHAR16 PrivateKeyName[WIFI_FILENAME_STR_MAX_SIZE]; + VOID *PrivateKeyData; + UINTN PrivateKeyDataSize; + CHAR16 PrivateKeyPassword[PASSWORD_STORAGE_SIZE]; //Password to protect private key file + CHAR16 EapIdentity[EAP_IDENTITY_SIZE]; + CHAR16 EapPassword[PASSWORD_STORAGE_SIZE]; + UINT8 EapSecondAuthMethod; + + BOOLEAN AKMSuiteSupported; + BOOLEAN CipherSuiteSupported; + BOOLEAN IsAvailable; + EFI_80211_NETWORK Network; + UINT8 NetworkQuality; + EFI_STRING_ID TitleToken; +} WIFI_MGR_NETWORK_PROFILE; + +#define WIFI_MGR_PROFILE_SIGNATURE SIGNATURE_32 ('W','M','N','P') + +#pragma pack(1) +/// +/// HII specific Vendor Device Path definition. +/// +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} HII_VENDOR_DEVICE_PATH; +#pragma pack() + +#endif diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigHii.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigHii.h new file mode 100644 index 0000000000..99b7fa2083 --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigHii.h @@ -0,0 +1,41 @@ +/** @file + GUIDs used as HII FormSet and HII Package list GUID in WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __WIFI_CONFIG_HII_GUID_H__ +#define __WIFI_CONFIG_HII_GUID_H__ + +// {3441803E-5A88-4941-82F0-858A1085276C} +#define WIFI_CONFIG_FORM_SET_GUID \ + { \ + 0x3441803e, 0x5a88, 0x4941, { 0x82, 0xf0, 0x85, 0x8a, 0x10, 0x85, 0x27, 0x6c } \ + } + +// {36AF7790-0C2F-4055-9D3D-DB72A44953CB} +#define WIFI_CONFIG_NETWORK_LIST_REFRESH_GUID \ + { \ + 0xc5f3c7f9, 0xfb9d, 0x49f1, { 0xbe, 0x67, 0x8b, 0xad, 0x20, 0xa7, 0xc6, 0xac } \ + } + +#define WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID \ + { \ + 0xe5faf2b2, 0x5ecc, 0x44ac, { 0x91, 0x75, 0xfb, 0x78, 0xb2, 0x8a, 0x59, 0x6c } \ + } + +#define WIFI_CONFIG_MAIN_FORM_REFRESH_GUID \ + { \ + 0xde609972, 0xcbcc, 0x4e82, { 0x8b, 0x3e, 0x6a, 0xc5, 0xcf, 0x56, 0x73, 0x8d } \ + } + +#endif diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h new file mode 100644 index 0000000000..2581e080e3 --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h @@ -0,0 +1,157 @@ +/** @file + Define IFR NVData structures used by the WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _WIFI_NVDATASTRUC_H_ +#define _WIFI_NVDATASTRUC_H_ + +#include "WifiConnectionMgrConfigHii.h" + +#define MANAGER_VARSTORE_ID 0x0802 + +#define WIFI_STR_MAX_SIZE 224 +#define WIFI_FILENAME_STR_MAX_SIZE 224 +#define WIFI_MGR_MAX_MAC_STRING_LEN 96 + +#define SSID_MIN_LEN 1 +#define SSID_MAX_LEN 32 +#define SSID_STORAGE_SIZE 33 + +#define PASSWORD_MIN_LEN 8 +#define PASSWORD_MAX_LEN 63 +#define PASSWORD_STORAGE_SIZE 64 + +#define EAP_IDENTITY_LEN 63 +#define EAP_IDENTITY_SIZE 64 + +#define FORMID_NONE_FORM 0 +#define FORMID_MAC_SELECTION 1 +#define FORMID_WIFI_MAINPAGE 2 +#define FORMID_NETWORK_LIST 3 +#define FORMID_CONNECT_NETWORK 4 +#define FORMID_ENROLL_CERT 5 +#define FORMID_CA_LIST 6 +#define FORMID_ENROLL_PRIVATE_KEY 7 +#define FORMID_PRIVATE_KEY_LIST 8 +#define FORMID_WIFI_SETTINGS 9 +#define FORMID_HIDDEN_NETWORK_LIST 10 + +// +// Mac List Form Key +// +#define KEY_MAC_LIST 0x100 + +// +// Main Form Key +// +#define KEY_REFRESH_TITLE_CONNECTION_STATUS 0x101 + +// +// Network List Form Key +// +#define KEY_NETWORK_LIST 0x102 +#define KEY_REFRESH_NETWORK_LIST 0x103 +#define KEY_WIFI_SETTINGS 0x104 + +// +// Connect Network Form Key +// +#define KEY_PASSWORD_CONNECT_NETWORK 0x201 +#define KEY_CONNECT_ACTION 0x202 +#define KEY_REFRESH_CONNECT_CONFIGURATION 0x203 +#define KEY_EAP_AUTH_METHOD_CONNECT_NETWORK 0x204 +#define KEY_EAP_SEAUTH_METHOD_CONNECT_NETWORK 0x205 +#define KEY_ENROLL_CA_CERT_CONNECT_NETWORK 0x206 +#define KEY_ENROLL_CLIENT_CERT_CONNECT_NETWORK 0x207 +#define KEY_ENROLL_PRIVATE_KEY_CONNECT_NETWORK 0x208 +#define KEY_EAP_IDENTITY_CONNECT_NETWORK 0x209 +#define KEY_EAP_PASSWORD_CONNECT_NETWORK 0x210 + +// +//Cert Form And Private Key Form +// +#define KEY_EAP_ENROLL_CERT_FROM_FILE 0x301 +#define KEY_EAP_ENROLL_PRIVATE_KEY_FROM_FILE 0x302 +#define KEY_SAVE_CERT_TO_MEM 0x303 +#define KEY_NO_SAVE_CERT_TO_MEM 0x304 +#define KEY_SAVE_PRIVATE_KEY_TO_MEM 0x305 +#define KEY_NO_SAVE_PRIVATE_KEY_TO_MEM 0x306 +#define KEY_PRIVATE_KEY_PASSWORD 0x307 +#define KEY_ENROLLED_CERT_NAME 0x308 +#define KEY_ENROLLED_PRIVATE_KEY_NAME 0x309 + +// +// Hidden Network Configuration Form +// +#define KEY_HIDDEN_NETWORK 0x401 +#define KEY_ADD_HIDDEN_NETWORK 0x402 +#define KEY_REMOVE_HIDDEN_NETWORK 0x403 + +// +// Dynamic Lists +// +#define MAC_LIST_COUNT_MAX 255 +#define LABEL_MAC_ENTRY 0x1000 +#define KEY_MAC_ENTRY_BASE 0x1100 + +#define NETWORK_LIST_COUNT_MAX 4095 +#define LABEL_NETWORK_LIST_ENTRY 0x2000 +#define KEY_AVAILABLE_NETWORK_ENTRY_BASE 0x3000 + +#define HIDDEN_NETWORK_LIST_COUNT_MAX 255 +#define LABEL_HIDDEN_NETWORK_ENTRY 0x4000 +#define KEY_HIDDEN_NETWORK_ENTRY_BASE 0x4100 + +#define LABEL_END 0xffff + +// +// Network Security Type +// +#define SECURITY_TYPE_NONE 0 +#define SECURITY_TYPE_WPA_ENTERPRISE 1 +#define SECURITY_TYPE_WPA2_ENTERPRISE 2 +#define SECURITY_TYPE_WPA_PERSONAL 3 +#define SECURITY_TYPE_WPA2_PERSONAL 4 +#define SECURITY_TYPE_WEP 5 +#define SECURITY_TYPE_UNKNOWN 6 +#define SECURITY_TYPE_MAX 7 + +#define EAP_AUTH_METHOD_TTLS 0 +#define EAP_AUTH_METHOD_PEAP 1 +#define EAP_AUTH_METHOD_TLS 2 +#define EAP_AUTH_METHOD_MAX 3 + +#define EAP_SEAUTH_METHOD_MSCHAPV2 0 +#define EAP_SEAUTH_METHOD_MAX 1 + +#define HIDDEN_NETWORK_LIST_VAR_OFFSET ((UINT16) OFFSET_OF (WIFI_MANAGER_IFR_NVDATA, HiddenNetworkList)) + +#pragma pack(1) +typedef struct _WIFI_MANAGER_IFR_NVDATA { + + UINT32 ProfileCount; + CHAR16 SSId[SSID_STORAGE_SIZE]; + CHAR16 Password[PASSWORD_STORAGE_SIZE]; + CHAR16 PrivateKeyPassword[PASSWORD_STORAGE_SIZE]; + CHAR16 EapIdentity[EAP_IDENTITY_SIZE]; + CHAR16 EapPassword[PASSWORD_STORAGE_SIZE]; + UINT8 SecurityType; + UINT8 EapAuthMethod; + UINT8 EapSecondAuthMethod; + UINT8 HiddenNetworkList[HIDDEN_NETWORK_LIST_COUNT_MAX]; + +} WIFI_MANAGER_IFR_NVDATA; +#pragma pack() + +#endif diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c new file mode 100644 index 0000000000..0abd95b4c6 --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c @@ -0,0 +1,717 @@ +/** @file + The driver binding protocol for the WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "WifiConnectionMgrDxe.h" + +/// +/// Driver Binding Protocol instance +/// +EFI_DRIVER_BINDING_PROTOCOL gWifiMgrDxeDriverBinding = { + WifiMgrDxeDriverBindingSupported, + WifiMgrDxeDriverBindingStart, + WifiMgrDxeDriverBindingStop, + WIFI_MGR_DXE_VERSION, + NULL, + NULL +}; + +// +//The private global data for WiFi Connection Manager +// +WIFI_MGR_PRIVATE_DATA *mPrivate = NULL; + +// +//The private guid to identify WiFi Connection Manager +// +EFI_GUID mEfiWifiMgrPrivateGuid = EFI_WIFIMGR_PRIVATE_GUID; + +// +//The Hii config guids +// +EFI_GUID gWifiConfigFormSetGuid = WIFI_CONFIG_FORM_SET_GUID; +EFI_GUID gWifiConfigNetworkListRefreshGuid = WIFI_CONFIG_NETWORK_LIST_REFRESH_GUID; +EFI_GUID gWifiConfigConnectFormRefreshGuid = WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID; +EFI_GUID gWifiConfigMainFormRefreshGuid = WIFI_CONFIG_MAIN_FORM_REFRESH_GUID; + +/** + Tests to see if this driver supports a given controller. If a child device is provided, + it further tests to see if this driver supports creating a handle for the specified child device. + + This function checks to see if the driver specified by This supports the device specified by + ControllerHandle. Drivers will typically use the device path attached to + ControllerHandle and/or the services from the bus I/O abstraction attached to + ControllerHandle to determine if the driver supports ControllerHandle. This function + may be called many times during platform initialization. In order to reduce boot times, the tests + performed by this function must be very small, and take as little time as possible to execute. This + function must not change the state of any hardware devices, and this function must be aware that the + device specified by ControllerHandle may already be managed by the same driver or a + different driver. This function must match its calls to AllocatePages() with FreePages(), + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). + Because ControllerHandle may have been previously started by the same driver, if a protocol is + already in the opened state, then it must not be closed with CloseProtocol(). This is required + to guarantee the state of ControllerHandle is not modified by this function. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to test. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For bus drivers, if this parameter is not NULL, then + the bus driver must determine if the bus controller specified + by ControllerHandle and the child controller specified + by RemainingDevicePath are both supported by this + bus driver. + + @retval EFI_SUCCESS The device specified by ControllerHandle and + RemainingDevicePath is supported by the driver specified by This. + @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by the driver + specified by This. + @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by a different + driver or an application that requires exclusive access. + Currently not implemented. + @retval EFI_UNSUPPORTED The device specified by ControllerHandle and + RemainingDevicePath is not supported by the driver specified by This. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + EFI_STATUS Status; + + Status = gBS->OpenProtocol ( + ControllerHandle, + &mEfiWifiMgrPrivateGuid, + NULL, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + return EFI_ALREADY_STARTED; + } + + // + // Test for the wireless MAC connection 2 protocol + // + return gBS->OpenProtocol ( + ControllerHandle, + &gEfiWiFi2ProtocolGuid, + NULL, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); +} + +/** + Starts a device controller or a bus controller. + + The Start() function is designed to be invoked from the EFI boot service ConnectController(). + As a result, much of the error checking on the parameters to Start() has been moved into this + common boot service. It is legal to call Start() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE. + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned + EFI_DEVICE_PATH_PROTOCOL. + 3. Prior to calling Start(), the Supported() function for the driver specified by This must + have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to start. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For a bus driver, if this parameter is NULL, then handles + for all the children of Controller are created by this driver. + If this parameter is not NULL and the first Device Path Node is + not the End of Device Path Node, then only the handle for the + child device specified by the first Device Path Node of + RemainingDevicePath is created by this driver. + If the first Device Path Node of RemainingDevicePath is + the End of Device Path Node, no child handle is created by this + driver. + + @retval EFI_SUCCESS The device was started. + @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others The driver failded to start the device. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + UINTN AddressSize; + WIFI_MGR_DEVICE_DATA *Nic; + EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL *Wmp; + EFI_ADAPTER_INFORMATION_PROTOCOL *Aip; + EFI_SUPPLICANT_PROTOCOL *Supplicant; + EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig; + + Nic = NULL; + + // + //Open Protocols + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiWiFi2ProtocolGuid, + (VOID**) &Wmp, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiAdapterInformationProtocolGuid, + (VOID**) &Aip, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + Aip = NULL; + } + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiSupplicantProtocolGuid, + (VOID**) &Supplicant, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + Supplicant = NULL; + } + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiEapConfigurationProtocolGuid, + (VOID**) &EapConfig, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + EapConfig = NULL; + } + + // + //Initialize Nic device data + // + Nic = AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA)); + if (Nic == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR1; + } + Nic->Signature = WIFI_MGR_DEVICE_DATA_SIGNATURE; + Nic->DriverHandle = This->DriverBindingHandle; + Nic->ControllerHandle = ControllerHandle; + Nic->Private = mPrivate; + Nic->Wmp = Wmp; + Nic->Aip = Aip; + Nic->Supplicant = Supplicant; + Nic->EapConfig = EapConfig; + Nic->UserSelectedProfile = NULL; + Nic->OneTimeScanRequest = FALSE; + Nic->ScanTickTime = WIFI_SCAN_FREQUENCY; //Initialize the first scan + + if (Nic->Supplicant != NULL) { + WifiMgrGetSupportedSuites(Nic); + } + + InitializeListHead (&Nic->ProfileList); + InitializeListHead (&Nic->TokenList); + + // + // Record the MAC address of the incoming NIC. + // + Status = NetLibGetMacAddress ( + ControllerHandle, + (EFI_MAC_ADDRESS*) &Nic->MacAddress, + &AddressSize + ); + if (EFI_ERROR (Status)) { + goto ERROR2; + } + + // + // Create and start the timer for the status check + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL | EVT_TIMER, + TPL_CALLBACK, + WifiMgrOnTimerTick, + Nic, + &Nic->TickTimer + ); + if (EFI_ERROR (Status)) { + goto ERROR2; + } + + Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS(500)); + if (EFI_ERROR (Status)) { + goto ERROR3; + } + + Nic->ConnectState = WifiMgrDisconnected; + Nic->ScanState = WifiMgrScanFinished; + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + InsertTailList (&mPrivate->NicList, &Nic->Link); + Nic->NicIndex = mPrivate->NicCount ++; + mPrivate->CurrentNic = Nic; + gBS->RestoreTPL (OldTpl); + + Status = gBS->InstallProtocolInterface ( + &ControllerHandle, + &mEfiWifiMgrPrivateGuid, + EFI_NATIVE_INTERFACE, + &Nic->WifiMgrIdentifier + ); + if (EFI_ERROR (Status)) { + goto ERROR4; + } + + return EFI_SUCCESS; + +ERROR4: + + gBS->SetTimer (Nic->TickTimer, TimerCancel, 0); + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + RemoveEntryList (&Nic->Link); + mPrivate->NicCount--; + gBS->RestoreTPL (OldTpl); + +ERROR3: + + gBS->CloseEvent (Nic->TickTimer); + +ERROR2: + + if (Nic->Supplicant != NULL) { + if (Nic->SupportedSuites.SupportedAKMSuites != NULL) { + FreePool (Nic->SupportedSuites.SupportedAKMSuites); + } + if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) { + FreePool (Nic->SupportedSuites.SupportedSwCipherSuites); + } + if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) { + FreePool (Nic->SupportedSuites.SupportedHwCipherSuites); + } + } + FreePool (Nic); + +ERROR1: + + if (Aip != NULL) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiAdapterInformationProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + } + + if (Supplicant != NULL) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiSupplicantProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + } + + if (EapConfig != NULL) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiEapConfigurationProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + } + + gBS->CloseProtocol ( + ControllerHandle, + &gEfiWiFi2ProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + + return Status; +} + +/** + Stops a device controller or a bus controller. + + The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). + As a result, much of the error checking on the parameters to Stop() has been moved + into this common boot service. It is legal to call Stop() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this + same driver's Start() function. + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid + EFI_HANDLE. In addition, all of these handles must have been created in this driver's + Start() function, and the Start() function must have called OpenProtocol() on + ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle A handle to the device being stopped. The handle must + support a bus specific I/O protocol for the driver + to use to stop the device. + @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval EFI_SUCCESS The device was stopped. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + WIFI_MGR_PRIVATE_PROTOCOL *WifiMgrIdentifier; + WIFI_MGR_DEVICE_DATA *Nic; + + Status = gBS->OpenProtocol ( + ControllerHandle, + &mEfiWifiMgrPrivateGuid, + (VOID **) &WifiMgrIdentifier, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + Nic = WIFI_MGR_DEVICE_DATA_FROM_IDENTIFIER (WifiMgrIdentifier); + if (Nic == NULL) { + return EFI_DEVICE_ERROR; + } + + // + //Close Protocols + // + Status = gBS->UninstallProtocolInterface ( + ControllerHandle, + &mEfiWifiMgrPrivateGuid, + &Nic->WifiMgrIdentifier + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->CloseProtocol ( + ControllerHandle, + &gEfiWiFi2ProtocolGuid, + Nic->DriverHandle, + Nic->ControllerHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Nic->Supplicant != NULL) { + Status = gBS->CloseProtocol ( + ControllerHandle, + &gEfiSupplicantProtocolGuid, + Nic->DriverHandle, + Nic->ControllerHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + if (Nic->EapConfig != NULL) { + Status = gBS->CloseProtocol ( + ControllerHandle, + &gEfiEapConfigurationProtocolGuid, + Nic->DriverHandle, + Nic->ControllerHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + Status = gBS->CloseProtocol ( + ControllerHandle, + &gEfiAdapterInformationProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + //Free List + // + WifiMgrFreeProfileList (&Nic->ProfileList); + WifiMgrFreeTokenList (&Nic->TokenList); + + // + // Close Event + // + gBS->CloseEvent (Nic->TickTimer); + + // + // Remove this Nic from Nic list + // + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + RemoveEntryList (&Nic->Link); + mPrivate->NicCount--; + gBS->RestoreTPL (OldTpl); + + if (Nic->Supplicant != NULL) { + if (Nic->SupportedSuites.SupportedAKMSuites != NULL) { + FreePool (Nic->SupportedSuites.SupportedAKMSuites); + } + if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) { + FreePool (Nic->SupportedSuites.SupportedSwCipherSuites); + } + if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) { + FreePool (Nic->SupportedSuites.SupportedHwCipherSuites); + } + } + FreePool (Nic); + + DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Device Controller has been Disconnected!\n")); + return EFI_SUCCESS; +} + +/** + Unload Wi-Fi Connection Manager driver. + + @param ImageHandle Handle that identifies the image to be unloaded. + + @retval EFI_SUCCESS The driver is unloaded. + @retval Others An unexpected error occurred. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + UINTN NumberOfHandles; + EFI_HANDLE *Handles; + UINTN Index; + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &mEfiWifiMgrPrivateGuid, + NULL, + &NumberOfHandles, + &Handles + ); + if (!EFI_ERROR (Status)) { + + for (Index = 0; Index < NumberOfHandles; Index ++) { + Status = gBS->DisconnectController ( + Handles[Index], + gWifiMgrDxeDriverBinding.DriverBindingHandle, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + } + + Status = WifiMgrDxeConfigFormUnload (mPrivate); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->UninstallMultipleProtocolInterfaces ( + ImageHandle, + &gEfiDriverBindingProtocolGuid, + &gWifiMgrDxeDriverBinding, + &gEfiComponentNameProtocolGuid, + &gWifiMgrDxeComponentName, + &gEfiComponentName2ProtocolGuid, + &gWifiMgrDxeComponentName2, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + gBS->CloseEvent (mPrivate->MainPageRefreshEvent); + gBS->CloseEvent (mPrivate->ConnectFormRefreshEvent); + gBS->CloseEvent (mPrivate->NetworkListRefreshEvent); + + WifiMgrFreeHiddenList (&mPrivate->HiddenNetworkList); + FreePool (mPrivate); + return EFI_SUCCESS; +} + +/** + This is the declaration of an EFI image entry point. This entry point is + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including + both device drivers and bus drivers. + + @param ImageHandle The firmware allocated handle for the UEFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others An unexpected error occurred. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gWifiMgrDxeDriverBinding, + ImageHandle, + &gWifiMgrDxeComponentName, + &gWifiMgrDxeComponentName2 + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Initialize the global private data structure. + // + mPrivate = AllocateZeroPool (sizeof (WIFI_MGR_PRIVATE_DATA)); + if (mPrivate == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR1; + } + mPrivate->Signature = WIFI_MGR_PRIVATE_DATA_SIGNATURE; + mPrivate->DriverHandle = ImageHandle; + InitializeListHead (&mPrivate->NicList); + mPrivate->NicCount = 0; + InitializeListHead (&mPrivate->HiddenNetworkList); + mPrivate->HiddenNetworkCount = 0; + + // + //Create events for page refresh + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + WifiMgrInternalEmptyFunction, + NULL, + &gWifiConfigNetworkListRefreshGuid, + &mPrivate->NetworkListRefreshEvent + ); + if (EFI_ERROR (Status)) { + goto ERROR2; + } + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + WifiMgrInternalEmptyFunction, + NULL, + &gWifiConfigConnectFormRefreshGuid, + &mPrivate->ConnectFormRefreshEvent + ); + if (EFI_ERROR (Status)) { + goto ERROR3; + } + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + WifiMgrInternalEmptyFunction, + NULL, + &gWifiConfigMainFormRefreshGuid, + &mPrivate->MainPageRefreshEvent + ); + if (EFI_ERROR (Status)) { + goto ERROR4; + } + + Status = WifiMgrDxeConfigFormInit (mPrivate); + if (EFI_ERROR (Status)) { + goto ERROR5; + } + + return Status; + +ERROR5: + gBS->CloseEvent (mPrivate->MainPageRefreshEvent); + +ERROR4: + gBS->CloseEvent (mPrivate->ConnectFormRefreshEvent); + +ERROR3: + gBS->CloseEvent (mPrivate->NetworkListRefreshEvent); + +ERROR2: + if (mPrivate != NULL) { + FreePool (mPrivate); + mPrivate = NULL; + } + +ERROR1: + gBS->UninstallMultipleProtocolInterfaces ( + ImageHandle, + &gEfiDriverBindingProtocolGuid, + &gWifiMgrDxeDriverBinding, + &gEfiComponentNameProtocolGuid, + &gWifiMgrDxeComponentName, + &gEfiComponentName2ProtocolGuid, + &gWifiMgrDxeComponentName2, + NULL + ); + + return Status; +} diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriverBinding.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriverBinding.h new file mode 100644 index 0000000000..e557d67d66 --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriverBinding.h @@ -0,0 +1,148 @@ +/** @file + The driver binding protocol for the WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __EFI_WIFI_DRIVER_BINDING__ +#define __EFI_WIFI_DRIVER_BINDING__ + +/** + Tests to see if this driver supports a given controller. If a child device is provided, + it further tests to see if this driver supports creating a handle for the specified child device. + + This function checks to see if the driver specified by This supports the device specified by + ControllerHandle. Drivers will typically use the device path attached to + ControllerHandle and/or the services from the bus I/O abstraction attached to + ControllerHandle to determine if the driver supports ControllerHandle. This function + may be called many times during platform initialization. In order to reduce boot times, the tests + performed by this function must be very small, and take as little time as possible to execute. This + function must not change the state of any hardware devices, and this function must be aware that the + device specified by ControllerHandle may already be managed by the same driver or a + different driver. This function must match its calls to AllocatePages() with FreePages(), + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). + Because ControllerHandle may have been previously started by the same driver, if a protocol is + already in the opened state, then it must not be closed with CloseProtocol(). This is required + to guarantee the state of ControllerHandle is not modified by this function. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to test. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For bus drivers, if this parameter is not NULL, then + the bus driver must determine if the bus controller specified + by ControllerHandle and the child controller specified + by RemainingDevicePath are both supported by this + bus driver. + + @retval EFI_SUCCESS The device specified by ControllerHandle and + RemainingDevicePath is supported by the driver specified by This. + @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by the driver + specified by This. + @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by a different + driver or an application that requires exclusive access. + Currently not implemented. + @retval EFI_UNSUPPORTED The device specified by ControllerHandle and + RemainingDevicePath is not supported by the driver specified by This. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +/** + Starts a device controller or a bus controller. + + The Start() function is designed to be invoked from the EFI boot service ConnectController(). + As a result, much of the error checking on the parameters to Start() has been moved into this + common boot service. It is legal to call Start() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE. + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned + EFI_DEVICE_PATH_PROTOCOL. + 3. Prior to calling Start(), the Supported() function for the driver specified by This must + have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to start. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For a bus driver, if this parameter is NULL, then handles + for all the children of Controller are created by this driver. + If this parameter is not NULL and the first Device Path Node is + not the End of Device Path Node, then only the handle for the + child device specified by the first Device Path Node of + RemainingDevicePath is created by this driver. + If the first Device Path Node of RemainingDevicePath is + the End of Device Path Node, no child handle is created by this + driver. + + @retval EFI_SUCCESS The device was started. + @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others The driver failded to start the device. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +/** + Stops a device controller or a bus controller. + + The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). + As a result, much of the error checking on the parameters to Stop() has been moved + into this common boot service. It is legal to call Stop() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this + same driver's Start() function. + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid + EFI_HANDLE. In addition, all of these handles must have been created in this driver's + Start() function, and the Start() function must have called OpenProtocol() on + ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle A handle to the device being stopped. The handle must + support a bus specific I/O protocol for the driver + to use to stop the device. + @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval EFI_SUCCESS The device was stopped. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ); + +#endif diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h new file mode 100644 index 0000000000..c12dfcca88 --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h @@ -0,0 +1,344 @@ +/** @file + The miscellaneous structure definitions for WiFi connection driver. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __EFI_WIFI_MGR_DXE_H__ +#define __EFI_WIFI_MGR_DXE_H__ + +#include + +// +// Libraries +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// UEFI Driver Model Protocols +// +#include +#include +#include +#include +#include + +// +// Consumed Protocols +// +#include +#include +#include +#include +#include +#include + +// +// Produced Protocols +// +#include + +// +// Guids +// +#include +#include + +// +// NvData struct definition +// +#include "WifiConnectionMgrConfigNVDataStruct.h" +#include "WifiConnectionMgrConfig.h" +#include "EapContext.h" +#include "WifiConnectionMgrConfigHii.h" + +// +// Driver Version +// +#define WIFI_MGR_DXE_VERSION 0xb + +//--------------------- + +#pragma pack (1) + +#define OUI_IEEE_80211I 0xAC0F00 + +typedef enum { + Ieee80211PairwiseCipherSuiteUseGroupCipherSuite = 0, + Ieee80211PairwiseCipherSuiteWEP40 = 1, + Ieee80211PairwiseCipherSuiteTKIP = 2, + Ieee80211PairwiseCipherSuiteCCMP = 4, + Ieee80211PairwiseCipherSuiteWEP104 = 5, + Ieee80211PairwiseCipherSuiteBIP = 6, + //... +} IEEE_80211_PAIRWISE_CIPHER_SUITE; + +#define IEEE_80211_PAIRWISE_CIPHER_SUITE_USE_GROUP (OUI_IEEE_80211I | (Ieee80211PairwiseCipherSuiteUseGroupCipherSuite << 24)) +#define IEEE_80211_PAIRWISE_CIPHER_SUITE_WEP40 (OUI_IEEE_80211I | (Ieee80211PairwiseCipherSuiteWEP40 << 24)) +#define IEEE_80211_PAIRWISE_CIPHER_SUITE_TKIP (OUI_IEEE_80211I | (Ieee80211PairwiseCipherSuiteTKIP << 24)) +#define IEEE_80211_PAIRWISE_CIPHER_SUITE_CCMP (OUI_IEEE_80211I | (Ieee80211PairwiseCipherSuiteCCMP << 24)) +#define IEEE_80211_PAIRWISE_CIPHER_SUITE_WEP104 (OUI_IEEE_80211I | (Ieee80211PairwiseCipherSuiteWEP104 << 24)) +#define IEEE_80211_PAIRWISE_CIPHER_SUITE_BIP (OUI_IEEE_80211I | (Ieee80211PairwiseCipherSuiteBIP << 24)) + +typedef enum { + Ieee80211AkmSuite8021XOrPMKSA = 1, + Ieee80211AkmSuitePSK = 2, + Ieee80211AkmSuite8021XOrPMKSASHA256 = 5, + Ieee80211AkmSuitePSKSHA256 = 6 + //... +} IEEE_80211_AKM_SUITE; + +#define IEEE_80211_AKM_SUITE_8021X_OR_PMKSA (OUI_IEEE_80211I | (Ieee80211AkmSuite8021XOrPMKSA << 24)) +#define IEEE_80211_AKM_SUITE_PSK (OUI_IEEE_80211I | (Ieee80211AkmSuitePSK << 24)) +#define IEEE_80211_AKM_SUITE_8021X_OR_PMKSA_SHA256 (OUI_IEEE_80211I | (Ieee80211AkmSuite8021XOrPMKSASHA256 << 24)) +#define IEEE_80211_AKM_SUITE_PSK_SHA256 (OUI_IEEE_80211I | (Ieee80211AkmSuitePSKSHA256 << 24)) + +//------------------------------ + +#pragma pack () + +// +// Protocol instances +// +extern EFI_DRIVER_BINDING_PROTOCOL gWifiMgrDxeDriverBinding; +extern EFI_COMPONENT_NAME2_PROTOCOL gWifiMgrDxeComponentName2; +extern EFI_COMPONENT_NAME_PROTOCOL gWifiMgrDxeComponentName; +extern EFI_HII_CONFIG_ACCESS_PROTOCOL gWifiMgrDxeHiiConfigAccess; + +// +// Private Context Data Structure +// +typedef enum { + WifiMgrDisconnected, + WifiMgrConnectingToAp, + WifiMgrConnectedToAp, + WifiMgrDisconnectingToAp, + WifiMgrConnectStateMaximum +} WIFI_MGR_CONNECT_STATE; + +typedef enum { + WifiMgrScanFinished, + WifiMgrScanning, + WifiMgrScanStateMaximum +} WIFI_MGR_SCAN_STATE; + +#define WIFI_SCAN_FREQUENCY 30 + +typedef struct _WIFI_MGR_SUPPORTED_SUITES { + EFI_80211_AKM_SUITE_SELECTOR *SupportedAKMSuites; + EFI_80211_CIPHER_SUITE_SELECTOR *SupportedSwCipherSuites; + EFI_80211_CIPHER_SUITE_SELECTOR *SupportedHwCipherSuites; +} WIFI_MGR_SUPPORTED_SUITES; + +#define EFI_WIFIMGR_PRIVATE_GUID \ + { \ + 0x99b7c019, 0x4789, 0x4829, { 0xa7, 0xbd, 0x0d, 0x4b, 0xaa, 0x62, 0x28, 0x72 } \ + } + +typedef struct _WIFI_MGR_PRIVATE_DATA WIFI_MGR_PRIVATE_DATA; + +typedef struct _WIFI_MGR_PRIVATE_PROTOCOL { + UINT32 Reserved; +} WIFI_MGR_PRIVATE_PROTOCOL; + +typedef struct _WIFI_MGR_FILE_CONTEXT { + EFI_FILE_HANDLE FHandle; + UINT16 *FileName; +} WIFI_MGR_FILE_CONTEXT; + +typedef enum { + FileTypeCACert, + FileTypeClientCert, + FileTypeMax +} WIFI_MGR_FILE_TYPE; + +typedef struct { + UINT32 Signature; + EFI_HANDLE DriverHandle; + EFI_HANDLE ControllerHandle; + EFI_EVENT TickTimer; + WIFI_MGR_PRIVATE_DATA *Private; + + // + // Pointers to consumed protocols + // + EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL *Wmp; + EFI_ADAPTER_INFORMATION_PROTOCOL *Aip; + EFI_SUPPLICANT_PROTOCOL *Supplicant; + EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig; + + // + // Produced protocols + // + WIFI_MGR_PRIVATE_PROTOCOL WifiMgrIdentifier; + + // + // Private functions and data fields + // + LIST_ENTRY Link; // Link to the NicList in global private data structure. + UINT32 NicIndex; + EFI_80211_MAC_ADDRESS MacAddress; + WIFI_MGR_SUPPORTED_SUITES SupportedSuites; + EFI_ADAPTER_INFO_MEDIA_STATE LastLinkState; + + // + // The network is currently connected, connecting or disconnecting. + // Only one network can be operated at one time. + // + WIFI_MGR_NETWORK_PROFILE *CurrentOperateNetwork; + WIFI_MGR_NETWORK_PROFILE *ConnectPendingNetwork; + BOOLEAN HasDisconnectPendingNetwork; + + // + //Profile related data fields + // + LIST_ENTRY ProfileList; // List of WIFI_MGR_NETWORK_PROFILE + UINT32 AvailableCount; + UINT32 MaxProfileIndex; + WIFI_MGR_NETWORK_PROFILE *UserSelectedProfile; + + // + // Data fields for Hii functionlity + // + LIST_ENTRY TokenList; // List of WIFI_MGR_MAC_CONFIG_TOKEN + BOOLEAN OneTimeScanRequest; + BOOLEAN OneTimeConnectRequest; + BOOLEAN OneTimeDisconnectRequest; + WIFI_MGR_SCAN_STATE ScanState; + UINTN ScanTickTime; + WIFI_MGR_CONNECT_STATE ConnectState; + BOOLEAN ConnectStateChanged; +} WIFI_MGR_DEVICE_DATA; + +#define WIFI_MGR_DEVICE_DATA_SIGNATURE SIGNATURE_32 ('W','M','D','D') + +#define WIFI_MGR_DEVICE_DATA_FROM_IDENTIFIER(Identifier) \ + CR ( \ + Identifier, \ + WIFI_MGR_DEVICE_DATA, \ + WifiMgrIdentifier, \ + WIFI_MGR_DEVICE_DATA_SIGNATURE \ + ) + +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + CHAR16 SSId[SSID_STORAGE_SIZE]; +} WIFI_HIDDEN_NETWORK_DATA; + +#define WIFI_MGR_HIDDEN_NETWORK_SIGNATURE SIGNATURE_32 ('W','M','H','N') + +#define WIFI_MGR_HIDDEN_NETWORK_FROM_IDENTIFIER(Identifier) \ + CR ( \ + Identifier, \ + WIFI_HIDDEN_NETWORK_DATA, \ + WifiMgrIdentifier, \ + WIFI_MGR_HIDDEN_NETWORK_SIGNATURE \ + ) + +// +// Global private data struct +// +struct _WIFI_MGR_PRIVATE_DATA { + + UINT32 Signature; + EFI_HANDLE DriverHandle; + EFI_HII_HANDLE RegisteredHandle; + EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; + + UINT32 NicCount; + LIST_ENTRY NicList; + WIFI_MGR_DEVICE_DATA *CurrentNic; + + // + // Data fields for Hii functionlity + // + EFI_EVENT NetworkListRefreshEvent; // Event to refresh the network list form + EFI_EVENT ConnectFormRefreshEvent; // Event to refresh the connect form + EFI_EVENT MainPageRefreshEvent; // Event to refresh the main page + + // + //User Input Record + // + UINT8 SecurityType; + UINT8 EapAuthMethod; + UINT8 EapSecondAuthMethod; + CHAR16 EapIdentity[EAP_IDENTITY_SIZE]; + + WIFI_MGR_FILE_CONTEXT *FileContext; + WIFI_MGR_FILE_TYPE FileType; + + UINT32 HiddenNetworkCount; + LIST_ENTRY HiddenNetworkList; +}; + +#define WIFI_MGR_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('W','M','P','D') + +#define WIFI_MGR_PRIVATE_DATA_FROM_CONFIG_ACCESS(This) \ + CR ( \ + This, \ + WIFI_MGR_PRIVATE_DATA, \ + ConfigAccess, \ + WIFI_MGR_PRIVATE_DATA_SIGNATURE \ + ) +extern WIFI_MGR_PRIVATE_DATA *mPrivate; + +typedef enum { + TokenTypeGetNetworksToken, + TokenTypeConnectNetworkToken, + TokenTypeDisconnectNetworkToken, + TokenTypeMax, +} WIFI_MGR_MAC_CONFIG_TOKEN_TYPE; + +typedef union { + EFI_80211_GET_NETWORKS_TOKEN *GetNetworksToken; + EFI_80211_CONNECT_NETWORK_TOKEN *ConnectNetworkToken; + EFI_80211_DISCONNECT_NETWORK_TOKEN *DisconnectNetworkToken; +} MAC_CONNECTION2_ADAPTER_TOKEN; + +typedef struct { + UINT32 Signature; + WIFI_MGR_MAC_CONFIG_TOKEN_TYPE Type; + // + // Link to the TokenList in device data structure. + // + LIST_ENTRY Link; + WIFI_MGR_DEVICE_DATA *Nic; + + MAC_CONNECTION2_ADAPTER_TOKEN Token; +} WIFI_MGR_MAC_CONFIG_TOKEN; + +#define WIFI_MGR_MAC_CONFIG_TOKEN_SIGNATURE SIGNATURE_32 ('W','M','C','T') + +// +// Include files with function prototypes +// +#include "WifiConnectionMgrDriverBinding.h" +#include "WifiConnectionMgrImpl.h" +#include "WifiConnectionMgrComponentName.h" +#include "WifiConnectionMgrHiiConfigAccess.h" +#include "WifiConnectionMgrMisc.h" +#include "WifiConnectionMgrFileUtil.h" + +#endif diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.c new file mode 100644 index 0000000000..6db1626f2d --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.c @@ -0,0 +1,308 @@ +/** @file + The file operation functions for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "WifiConnectionMgrFileUtil.h" + +CHAR16* mDerPemEncodedSuffix[] = { + L".cer", + L".der", + L".crt", + L".pem", + NULL +}; + +/** + This code checks if the FileSuffix is one of the possible DER/PEM-encoded certificate suffix. + + @param[in] FileSuffix The suffix of the input certificate file + + @retval TRUE It's a DER/PEM-encoded certificate. + @retval FALSE It's NOT a DER/PEM-encoded certificate. + +**/ +BOOLEAN +IsDerPemEncodeCertificate ( + IN CONST CHAR16 *FileSuffix +) +{ + UINTN Index; + for (Index = 0; mDerPemEncodedSuffix[Index] != NULL; Index++) { + if (StrCmp (FileSuffix, mDerPemEncodedSuffix[Index]) == 0) { + return TRUE; + } + } + return FALSE; +} + +/** + Read file content into BufferPtr, the size of the allocate buffer + is *FileSize plus AddtionAllocateSize. + + @param[in] FileHandle The file to be read. + @param[in, out] BufferPtr Pointers to the pointer of allocated buffer. + @param[out] FileSize Size of input file + @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated. + In case the buffer need to contain others besides the file content. + + @retval EFI_SUCCESS The file was read into the buffer. + @retval EFI_INVALID_PARAMETER A parameter was invalid. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval others Unexpected error. + +**/ +EFI_STATUS +ReadFileContent ( + IN EFI_FILE_HANDLE FileHandle, + IN OUT VOID **BufferPtr, + OUT UINTN *FileSize, + IN UINTN AddtionAllocateSize + ) +{ + UINTN BufferSize; + UINT64 SourceFileSize; + VOID *Buffer; + EFI_STATUS Status; + + if ((FileHandle == NULL) || (FileSize == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Buffer = NULL; + + // + // Get the file size + // + Status = FileHandle->SetPosition (FileHandle, (UINT64) -1); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + Status = FileHandle->GetPosition (FileHandle, &SourceFileSize); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + Status = FileHandle->SetPosition (FileHandle, 0); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + BufferSize = (UINTN) SourceFileSize + AddtionAllocateSize; + Buffer = AllocateZeroPool(BufferSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + BufferSize = (UINTN) SourceFileSize; + *FileSize = BufferSize; + + Status = FileHandle->Read (FileHandle, &BufferSize, Buffer); + if (EFI_ERROR (Status) || BufferSize != *FileSize) { + FreePool (Buffer); + Buffer = NULL; + Status = EFI_BAD_BUFFER_SIZE; + goto ON_EXIT; + } + +ON_EXIT: + + *BufferPtr = Buffer; + return Status; +} + +/** + This function converts an input device structure to a Unicode string. + + @param[in] DevPath A pointer to the device path structure. + + @return A new allocated Unicode string that represents the device path. + +**/ +CHAR16 * +EFIAPI +DevicePathToStr ( + IN EFI_DEVICE_PATH_PROTOCOL *DevPath + ) +{ + return ConvertDevicePathToText ( + DevPath, + FALSE, + TRUE + ); +} + +/** + Extract filename from device path. The returned buffer is allocated using AllocateCopyPool. + The caller is responsible for freeing the allocated buffer using FreePool(). If return NULL + means not enough memory resource. + + @param DevicePath Device path. + + @retval NULL Not enough memory resourece for AllocateCopyPool. + @retval Other A new allocated string that represents the file name. + +**/ +CHAR16 * +ExtractFileNameFromDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + CHAR16 *String; + CHAR16 *MatchString; + CHAR16 *LastMatch; + CHAR16 *FileName; + UINTN Length; + + ASSERT(DevicePath != NULL); + + String = DevicePathToStr(DevicePath); + if (String == NULL) { + return NULL; + } + MatchString = String; + LastMatch = String; + FileName = NULL; + + while(MatchString != NULL){ + LastMatch = MatchString + 1; + MatchString = StrStr(LastMatch,L"\\"); + } + + Length = StrLen(LastMatch); + FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch); + if (FileName != NULL) { + *(FileName + Length) = 0; + } + + FreePool(String); + + return FileName; +} + +/** + Update the form base on the selected file. + + @param[in] Private The pointer to the global private data structure. + @param[in] FilePath Point to the file path. + @param[in] FormId The form needs to display. + + @retval TRUE Exit caller function. + @retval FALSE Not exit caller function. + +**/ +BOOLEAN +UpdatePage( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN EFI_FORM_ID FormId + ) +{ + CHAR16 *FileName; + EFI_STATUS Status; + + FileName = NULL; + + if (FilePath != NULL) { + FileName = ExtractFileNameFromDevicePath(FilePath); + } + if (FileName == NULL) { + // + // FileName = NULL has two cases: + // 1. FilePath == NULL, not select file. + // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource. + // In these two case, no need to update the form, and exit the caller function. + // + return TRUE; + } + + // + // Close the previous file handle before open a new one. + // + if (Private->FileContext->FHandle != NULL) { + Private->FileContext->FHandle->Close (Private->FileContext->FHandle); + } + Private->FileContext->FHandle = NULL; + + Status = EfiOpenFileByDevicePath ( + &FilePath, + &Private->FileContext->FHandle, + EFI_FILE_MODE_READ, + 0 + ); + if (EFI_ERROR (Status)) { + if (FormId == FORMID_ENROLL_CERT) { + HiiSetString (Private->RegisteredHandle, + STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), L"", NULL); + } else if (FormId == FORMID_ENROLL_PRIVATE_KEY){ + HiiSetString (Private->RegisteredHandle, + STRING_TOKEN (STR_EAP_ENROLLED_PRIVATE_KEY_NAME), L"", NULL); + } + } else { + + if (Private->FileContext->FileName != NULL) { + FreePool (Private->FileContext->FileName); + } + Private->FileContext->FileName = FileName; + + if (FormId == FORMID_ENROLL_CERT) { + HiiSetString (Private->RegisteredHandle, + STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), FileName, NULL); + } else if (FormId == FORMID_ENROLL_PRIVATE_KEY){ + HiiSetString (Private->RegisteredHandle, + STRING_TOKEN (STR_EAP_ENROLLED_PRIVATE_KEY_NAME), FileName, NULL); + } + } + + return TRUE; +} + +/** + Update the CA form base on the input file path info. + + @param[in] Private The pointer to the global private data structure. + @param[in] FilePath Point to the file path. + + @retval TRUE Exit caller function. + @retval FALSE Not exit caller function. + +**/ +BOOLEAN +UpdateCAFromFile ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath + ) +{ + return UpdatePage(Private, FilePath, FORMID_ENROLL_CERT); +} + +/** + Update the Private Key form base on the input file path info. + + @param[in] Private The pointer to the global private data structure. + @param[in] FilePath Point to the file path. + + @retval TRUE Exit caller function. + @retval FALSE Not exit caller function. + +**/ +BOOLEAN +UpdatePrivateKeyFromFile ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath + ) +{ + return UpdatePage(Private, FilePath, FORMID_ENROLL_PRIVATE_KEY); +} + diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.h new file mode 100644 index 0000000000..5426a5f45d --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.h @@ -0,0 +1,77 @@ +/** @file + The file operation functions for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __EFI_WIFI_MGR_FILE_UTIL__ +#define __EFI_WIFI_MGR_FILE_UTIL__ + +#include "WifiConnectionMgrDxe.h" + +/** + Read file content into BufferPtr, the size of the allocate buffer + is *FileSize plus AddtionAllocateSize. + + @param[in] FileHandle The file to be read. + @param[in, out] BufferPtr Pointers to the pointer of allocated buffer. + @param[out] FileSize Size of input file + @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated. + In case the buffer need to contain others besides the file content. + + @retval EFI_SUCCESS The file was read into the buffer. + @retval EFI_INVALID_PARAMETER A parameter was invalid. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval others Unexpected error. + +**/ +EFI_STATUS +ReadFileContent ( + IN EFI_FILE_HANDLE FileHandle, + IN OUT VOID **BufferPtr, + OUT UINTN *FileSize, + IN UINTN AddtionAllocateSize + ); + +/** + Update the CA cert base on the input file path info. + + @param[in] Private The pointer to the global private data structure. + @param[in] FilePath Point to the file path. + + @retval TRUE Exit caller function. + @retval FALSE Not exit caller function. + +**/ +BOOLEAN +UpdateCAFromFile ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath + ); + +/** + Update the Private Key base on the input file path info. + + @param[in] Private The pointer to the global private data structure. + @param[in] FilePath Point to the file path. + + @retval TRUE Exit caller function. + @retval FALSE Not exit caller function. + +**/ +BOOLEAN +UpdatePrivateKeyFromFile ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath + ); + +#endif diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c new file mode 100644 index 0000000000..69f335263b --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c @@ -0,0 +1,1918 @@ +/** @file + The Hii functions for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#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_CONFIG_FORM_SET_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"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; + + 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-9 + // + AKMListDisplay = (CHAR16 *) AllocateZeroPool(sizeof (CHAR16) * AKMSuiteCount * 2); + if (AKMListDisplay != NULL) { + for (Index = 0; Index < AKMSuiteCount; Index ++) { + UnicodeSPrint ( + AKMListDisplay + (Index * 2), + sizeof (CHAR16) * 2, + L"%d ", + Profile->Network.AKMSuite->AKMSuiteList[Index].SuiteType + ); + if (Index == AKMSuiteCount - 1) { + *(AKMListDisplay + (Index * 2 + 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); + if (CipherListDisplay != NULL) { + for (Index = 0; Index < CipherSuiteCount; Index ++) { + UnicodeSPrint ( + CipherListDisplay + (Index * 2), + sizeof (CHAR16) * 2, + 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); + + 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); + + 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); + + 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); + + return EFI_SUCCESS; +} + +/** + 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 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=". That (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 + 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 + 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 + 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 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 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 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 + 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 + 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); + 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 + // + 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->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) { + + 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) { + + // + // For Open network, connect directly. + // + ProfileToConnect = Profile; + + } else if (Profile->SecurityType == SECURITY_TYPE_WPA2_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); + } + + 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); + } + } else if (Private->FileType == FileTypeClientCert) { + if (Profile->ClientCertData != NULL) { + + ZeroMem (Profile->ClientCertData, Profile->ClientCertSize); + FreePool (Profile->ClientCertData); + } + } 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, 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); + } + + 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; +} diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.h new file mode 100644 index 0000000000..cee8010e17 --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.h @@ -0,0 +1,228 @@ +/** @file + The Hii functions for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __EFI_WIFI_MGR_HII_CONFIG_ACCESS__ +#define __EFI_WIFI_MGR_HII_CONFIG_ACCESS__ + +/** + This function allows the caller to request the current + configuration for one or more named elements. The resulting + string is in 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=". That (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 + 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 + 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 + 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 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 + ); + +/** + 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 + 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 + 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 + ); + +/** + 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 + ); + +/** + 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 Other Erros Returned errors when installing protocols. + +**/ +EFI_STATUS +WifiMgrDxeConfigFormInit ( + WIFI_MGR_PRIVATE_DATA *Private + ); + +/** + 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 Other Errors Returned Erros when uninstalling protocols. + +**/ +EFI_STATUS +WifiMgrDxeConfigFormUnload ( + WIFI_MGR_PRIVATE_DATA *Private + ); + +/** + 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 + ); + +#endif diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c new file mode 100644 index 0000000000..a8b458f85f --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c @@ -0,0 +1,1409 @@ +/** @file + The Mac Connection2 Protocol adapter functions for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "WifiConnectionMgrDxe.h" + +EFI_EAP_TYPE mEapAuthMethod[] = { + EFI_EAP_TYPE_TTLS, + EFI_EAP_TYPE_PEAP, + EFI_EAP_TYPE_EAPTLS +}; + +EFI_EAP_TYPE mEapSecondAuthMethod[] = { + EFI_EAP_TYPE_MSCHAPV2 +}; + +/** + The callback function for scan operation. This function updates networks + according to the latest scan result, and trigger UI refresh. + + @param[in] Event The GetNetworks token receive event. + @param[in] Context The context of the GetNetworks token. + +**/ +VOID +EFIAPI +WifiMgrOnScanFinished ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken; + WIFI_MGR_DEVICE_DATA *Nic; + WIFI_MGR_NETWORK_PROFILE *Profile; + EFI_80211_NETWORK *Network; + UINTN DataSize; + EFI_80211_NETWORK_DESCRIPTION *NetworkDescription; + EFI_80211_GET_NETWORKS_RESULT *Result; + LIST_ENTRY *Entry; + UINT8 SecurityType; + BOOLEAN AKMSuiteSupported; + BOOLEAN CipherSuiteSupported; + CHAR8 *AsciiSSId; + UINTN Index; + + if (Context == NULL) { + return; + } + + ConfigToken = (WIFI_MGR_MAC_CONFIG_TOKEN *) Context; + if (ConfigToken->Nic == NULL) { + WifiMgrFreeToken(ConfigToken); + return; + } + + if (ConfigToken->Signature != WIFI_MGR_MAC_CONFIG_TOKEN_SIGNATURE || + ConfigToken->Type != TokenTypeGetNetworksToken) { + + WifiMgrFreeToken(ConfigToken); + return; + } + + // + // It is the GetNetworks token, set scan state to "ScanFinished" + // + ConfigToken->Nic->ScanState = WifiMgrScanFinished; + + if (ConfigToken->Token.GetNetworksToken == NULL || + ConfigToken->Token.GetNetworksToken->Result == NULL) { + + WifiMgrFreeToken(ConfigToken); + return; + } + + Result = ConfigToken->Token.GetNetworksToken->Result; + Nic = ConfigToken->Nic; + + // + // Clean previous result, and update network list according to the scan result + // + Nic->AvailableCount = 0; + + NET_LIST_FOR_EACH (Entry, &Nic->ProfileList) { + Profile = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_NETWORK_PROFILE, + Link, WIFI_MGR_PROFILE_SIGNATURE); + Profile->IsAvailable = FALSE; + } + + if (Result == NULL) { + gBS->SignalEvent (Nic->Private->NetworkListRefreshEvent); + WifiMgrFreeToken(ConfigToken); + return; + } + + for (Index = 0; Index < Result->NumOfNetworkDesc; Index ++) { + + NetworkDescription = Result->NetworkDesc + Index; + if (NetworkDescription == NULL) { + continue; + } + + Network = &NetworkDescription->Network; + if (Network == NULL || Network->SSId.SSIdLen == 0) { + continue; + } + + Status = WifiMgrCheckRSN ( + Network->AKMSuite, + Network->CipherSuite, + Nic, + &SecurityType, + &AKMSuiteSupported, + &CipherSuiteSupported + ); + if (EFI_ERROR (Status)) { + + SecurityType = SECURITY_TYPE_UNKNOWN; + AKMSuiteSupported = FALSE; + CipherSuiteSupported = FALSE; + } + + AsciiSSId = (CHAR8*) AllocateZeroPool(sizeof (CHAR8) * (Network->SSId.SSIdLen + 1)); + if (AsciiSSId == NULL) { + continue; + } + CopyMem(AsciiSSId, (CHAR8 *) Network->SSId.SSId, sizeof (CHAR8) * Network->SSId.SSIdLen); + *(AsciiSSId + Network->SSId.SSIdLen) = '\0'; + + Profile = WifiMgrGetProfileByAsciiSSId (AsciiSSId, SecurityType, &Nic->ProfileList); + if (Profile == NULL) { + + if (Nic->MaxProfileIndex >= NETWORK_LIST_COUNT_MAX) { + FreePool (AsciiSSId); + continue; + } + + // + // Create a new profile + // + Profile = AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE)); + if (Profile == NULL) { + FreePool (AsciiSSId); + continue; + } + Profile->Signature = WIFI_MGR_PROFILE_SIGNATURE; + Profile->NicIndex = Nic->NicIndex; + Profile->ProfileIndex = Nic->MaxProfileIndex + 1; + AsciiStrToUnicodeStrS (AsciiSSId, Profile->SSId, SSID_STORAGE_SIZE); + InsertTailList (&Nic->ProfileList, &Profile->Link); + Nic->MaxProfileIndex ++; + } + FreePool (AsciiSSId); + + // + //May receive duplicate networks in scan results, check if it has already + //been processed. + // + if (!Profile->IsAvailable) { + + Profile->IsAvailable = TRUE; + Profile->SecurityType = SecurityType; + Profile->AKMSuiteSupported = AKMSuiteSupported; + Profile->CipherSuiteSupported = CipherSuiteSupported; + Profile->NetworkQuality = NetworkDescription->NetworkQuality; + Nic->AvailableCount ++; + + // + //Copy BSSType and SSId + // + CopyMem(&Profile->Network, Network, sizeof (EFI_80211_NETWORK)); + + // + //Copy AKMSuite list + // + if (Network->AKMSuite != NULL) { + + if (Network->AKMSuite->AKMSuiteCount == 0) { + DataSize = sizeof (EFI_80211_AKM_SUITE_SELECTOR); + } else { + DataSize = sizeof (EFI_80211_AKM_SUITE_SELECTOR) + sizeof (EFI_80211_SUITE_SELECTOR) + * (Network->AKMSuite->AKMSuiteCount - 1); + } + Profile->Network.AKMSuite = (EFI_80211_AKM_SUITE_SELECTOR *) AllocateZeroPool (DataSize); + if (Profile->Network.AKMSuite == NULL) { + continue; + } + CopyMem (Profile->Network.AKMSuite, Network->AKMSuite, DataSize); + } + + // + //Copy CipherSuite list + // + if (Network->CipherSuite != NULL) { + + if (Network->CipherSuite->CipherSuiteCount == 0) { + DataSize = sizeof (EFI_80211_CIPHER_SUITE_SELECTOR); + } else { + DataSize = sizeof (EFI_80211_CIPHER_SUITE_SELECTOR) + sizeof (EFI_80211_SUITE_SELECTOR) + * (Network->CipherSuite->CipherSuiteCount - 1); + } + Profile->Network.CipherSuite = (EFI_80211_CIPHER_SUITE_SELECTOR *) AllocateZeroPool (DataSize); + if (Profile->Network.CipherSuite == NULL) { + continue; + } + CopyMem (Profile->Network.CipherSuite, Network->CipherSuite, DataSize); + } + } else { + // + // A duplicate network, update signal quality + // + if (Profile->NetworkQuality < NetworkDescription->NetworkQuality) { + Profile->NetworkQuality = NetworkDescription->NetworkQuality; + } + continue; + } + } + + FreePool (Result); + gBS->SignalEvent (Nic->Private->NetworkListRefreshEvent); + + // + // The current connected network should always be available until disconnection + // happens in Wifi FW layer, even when it is not in this time's scan result. + // + if (Nic->ConnectState == WifiMgrConnectedToAp && Nic->CurrentOperateNetwork != NULL) { + if (!Nic->CurrentOperateNetwork->IsAvailable) { + Nic->CurrentOperateNetwork->IsAvailable = TRUE; + Nic->AvailableCount ++; + } + } + + WifiMgrFreeToken(ConfigToken); +} + +/** + Start scan operation, and send out a token to collect available networks. + + @param[in] Nic Pointer to the device data of the selected NIC. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_ALREADY_STARTED A former scan operation is already ongoing. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Return errors when getting networks from low layer. + +**/ +EFI_STATUS +WifiMgrStartScan ( + IN WIFI_MGR_DEVICE_DATA *Nic + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken; + EFI_80211_GET_NETWORKS_TOKEN *GetNetworksToken; + UINT32 HiddenSSIdIndex; + UINT32 HiddenSSIdCount; + EFI_80211_SSID *HiddenSSIdList; + WIFI_HIDDEN_NETWORK_DATA *HiddenNetwork; + LIST_ENTRY *Entry; + + if (Nic == NULL || Nic->Wmp == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Nic->ScanState == WifiMgrScanning) { + return EFI_ALREADY_STARTED; + } + + Nic->ScanState = WifiMgrScanning; + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + Status = EFI_SUCCESS; + HiddenSSIdList = NULL; + HiddenSSIdCount = Nic->Private->HiddenNetworkCount; + HiddenSSIdIndex = 0; + + // + //create a new get network token + // + ConfigToken = AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN)); + if (ConfigToken == NULL) { + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + InsertTailList (&Nic->TokenList, &ConfigToken->Link); + + ConfigToken->Signature = WIFI_MGR_MAC_CONFIG_TOKEN_SIGNATURE; + ConfigToken->Type = TokenTypeGetNetworksToken; + ConfigToken->Nic = Nic; + ConfigToken->Token.GetNetworksToken = AllocateZeroPool (sizeof (EFI_80211_GET_NETWORKS_TOKEN)); + if (ConfigToken->Token.GetNetworksToken == NULL) { + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + GetNetworksToken = ConfigToken->Token.GetNetworksToken; + + // + // There are some hidden networks to scan, add them into scan list + // + if (HiddenSSIdCount > 0) { + HiddenSSIdList = AllocateZeroPool(HiddenSSIdCount * sizeof (EFI_80211_SSID)); + if (HiddenSSIdList == NULL) { + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + + HiddenSSIdIndex = 0; + NET_LIST_FOR_EACH (Entry, &Nic->Private->HiddenNetworkList) { + + HiddenNetwork = NET_LIST_USER_STRUCT_S (Entry, WIFI_HIDDEN_NETWORK_DATA, + Link, WIFI_MGR_HIDDEN_NETWORK_SIGNATURE); + HiddenSSIdList[HiddenSSIdIndex].SSIdLen = (UINT8) StrLen (HiddenNetwork->SSId); + UnicodeStrToAsciiStrS(HiddenNetwork->SSId, + (CHAR8 *) HiddenSSIdList[HiddenSSIdIndex].SSId, SSID_STORAGE_SIZE); + HiddenSSIdIndex ++; + } + GetNetworksToken->Data = AllocateZeroPool (sizeof (EFI_80211_GET_NETWORKS_DATA) + + (HiddenSSIdCount - 1) * sizeof (EFI_80211_SSID)); + if (GetNetworksToken->Data == NULL) { + FreePool (HiddenSSIdList); + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + GetNetworksToken->Data->NumOfSSID = HiddenSSIdCount; + CopyMem(GetNetworksToken->Data->SSIDList, HiddenSSIdList, HiddenSSIdCount * sizeof (EFI_80211_SSID)); + FreePool(HiddenSSIdList); + } else { + + GetNetworksToken->Data = AllocateZeroPool (sizeof (EFI_80211_GET_NETWORKS_DATA)); + if (GetNetworksToken->Data == NULL) { + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + + GetNetworksToken->Data->NumOfSSID = 0; + } + + // + //Create a handle when scan process ends + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + WifiMgrOnScanFinished, + ConfigToken, + &GetNetworksToken->Event + ); + if (EFI_ERROR (Status)) { + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return Status; + } + + // + //Start scan ... + // + Status = Nic->Wmp->GetNetworks (Nic->Wmp, GetNetworksToken); + if (EFI_ERROR (Status)) { + Nic->ScanState = WifiMgrScanFinished; + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return Status; + } + + gBS->RestoreTPL (OldTpl); + return EFI_SUCCESS; +} + +/** + Configure password to supplicant before connecting to a secured network. + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[in] Profile The target network to be connected. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval EFI_NOT_FOUND No valid password is found to configure. + @retval Other Errors Returned errors when setting data to supplicant. + +**/ +EFI_STATUS +WifiMgrConfigPassword ( + IN WIFI_MGR_DEVICE_DATA *Nic, + IN WIFI_MGR_NETWORK_PROFILE *Profile + ) +{ + EFI_STATUS Status; + EFI_SUPPLICANT_PROTOCOL *Supplicant; + EFI_80211_SSID SSId; + UINT8 *AsciiPassword; + + if (Nic == NULL || Nic->Supplicant == NULL || Profile == NULL) { + return EFI_INVALID_PARAMETER; + } + Supplicant = Nic->Supplicant; + // + //Set SSId to supplicant + // + SSId.SSIdLen = Profile->Network.SSId.SSIdLen; + CopyMem(SSId.SSId, Profile->Network.SSId.SSId, sizeof (Profile->Network.SSId.SSId)); + Status = Supplicant->SetData(Supplicant,EfiSupplicant80211TargetSSIDName, + (VOID *)&SSId, sizeof(EFI_80211_SSID)); + if (EFI_ERROR(Status)) { + return Status; + } + + // + //Set password to supplicant + // + if (StrLen (Profile->Password) < PASSWORD_MIN_LEN) { + return EFI_NOT_FOUND; + } + AsciiPassword = AllocateZeroPool ((StrLen(Profile->Password) + 1) * sizeof (UINT8)); + if (AsciiPassword == NULL) { + return EFI_OUT_OF_RESOURCES; + } + UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *) AsciiPassword, PASSWORD_STORAGE_SIZE); + Status = Supplicant->SetData (Supplicant, EfiSupplicant80211PskPassword, + AsciiPassword, (StrLen(Profile->Password) + 1) * sizeof (UINT8)); + ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *) AsciiPassword) + 1); + FreePool(AsciiPassword); + + return Status; +} + +/** + Conduct EAP configuration to supplicant before connecting to a EAP network. + Current WiFi Connection Manager only supports three kinds of EAP networks: + 1). EAP-TLS (Two-Way Authentication is required in our implementation) + 2). EAP-TTLS/MSCHAPv2 (One-Way Authentication is required in our implementation) + 3). PEAPv0/MSCHAPv2 (One-Way Authentication is required in our implementation) + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[in] Profile The target network to be connected. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_UNSUPPORTED The expected EAP method is not supported. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Returned errors when setting data to supplicant. + +**/ +EFI_STATUS +WifiMgrConfigEap ( + IN WIFI_MGR_DEVICE_DATA *Nic, + IN WIFI_MGR_NETWORK_PROFILE *Profile + ) +{ + EFI_STATUS Status; + EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig; + EFI_EAP_TYPE EapAuthMethod; + EFI_EAP_TYPE EapSecondAuthMethod; + EFI_EAP_TYPE *AuthMethodList; + CHAR8 *Identity; + UINTN IdentitySize; + CHAR16 *Password; + UINTN PasswordSize; + UINTN EncryptPasswordLen; + CHAR8 *AsciiEncryptPassword; + UINTN AuthMethodListSize; + UINTN Index; + + if (Nic == NULL || Nic->EapConfig == NULL || Profile == NULL) { + return EFI_INVALID_PARAMETER; + } + EapConfig = Nic->EapConfig; + + if (Profile->EapAuthMethod >= EAP_AUTH_METHOD_MAX) { + return EFI_INVALID_PARAMETER; + } + EapAuthMethod = mEapAuthMethod[Profile->EapAuthMethod]; + + if (EapAuthMethod != EFI_EAP_TYPE_EAPTLS) { + if (Profile->EapSecondAuthMethod >= EAP_SEAUTH_METHOD_MAX) { + return EFI_INVALID_PARAMETER; + } + EapSecondAuthMethod = mEapSecondAuthMethod[Profile->EapSecondAuthMethod]; + } + + // + //The first time to get Supported Auth Method list, return the size. + // + AuthMethodListSize = 0; + AuthMethodList = NULL; + Status = EapConfig->GetData (EapConfig, EFI_EAP_TYPE_ATTRIBUTE, EfiEapConfigEapSupportedAuthMethod, + (VOID *) AuthMethodList, &AuthMethodListSize); + if (Status == EFI_SUCCESS) { + // + //No Supported Eap Auth Method + // + return EFI_UNSUPPORTED; + } else if (Status != EFI_BUFFER_TOO_SMALL) { + return Status; + } + + // + // The second time to get Supported Auth Method list, return the list. + // In current design, only EAPTLS, TTLS and PEAP are supported + // + AuthMethodList = (EFI_EAP_TYPE *) AllocateZeroPool(AuthMethodListSize); + if (AuthMethodList == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = EapConfig->GetData (EapConfig, EFI_EAP_TYPE_ATTRIBUTE, EfiEapConfigEapSupportedAuthMethod, + (VOID *) AuthMethodList, &AuthMethodListSize); + if (EFI_ERROR (Status)) { + FreePool (AuthMethodList); + return Status; + } + + // + //Check if EapAuthMethod is in supported Auth Method list, if found, skip the loop. + // + for (Index = 0; Index < AuthMethodListSize / sizeof (EFI_EAP_TYPE); Index ++) { + if (EapAuthMethod == AuthMethodList[Index]) { + break; + } + } + if (Index == AuthMethodListSize / sizeof (EFI_EAP_TYPE)) { + FreePool (AuthMethodList); + return EFI_UNSUPPORTED; + } + FreePool (AuthMethodList); + + // + // Set Identity to Eap peer, Mandatory field for PEAP and TTLS + // + if (StrLen (Profile->EapIdentity) > 0) { + + IdentitySize = sizeof(CHAR8) * (StrLen(Profile->EapIdentity) + 1); + Identity = AllocateZeroPool (IdentitySize); + if (Identity == NULL) { + return EFI_OUT_OF_RESOURCES; + } + UnicodeStrToAsciiStrS(Profile->EapIdentity, Identity, IdentitySize); + Status = EapConfig->SetData (EapConfig, EFI_EAP_TYPE_IDENTITY, EfiEapConfigIdentityString, + (VOID *) Identity, IdentitySize - 1); + if (EFI_ERROR(Status)) { + FreePool (Identity); + return Status; + } + FreePool (Identity); + } else { + if (EapAuthMethod != EFI_EAP_TYPE_EAPTLS) { + return EFI_INVALID_PARAMETER; + } + } + + // + //Set Auth Method to Eap peer, Mandatory field + // + Status = EapConfig->SetData (EapConfig, EFI_EAP_TYPE_ATTRIBUTE, EfiEapConfigEapAuthMethod, + (VOID *) &EapAuthMethod, sizeof (EapAuthMethod)); + if (EFI_ERROR(Status)) { + return Status; + } + + if (EapAuthMethod == EFI_EAP_TYPE_TTLS || EapAuthMethod == EFI_EAP_TYPE_PEAP) { + + Status = EapConfig->SetData (EapConfig, EapAuthMethod, EfiEapConfigEap2ndAuthMethod, + (VOID *) &EapSecondAuthMethod, sizeof (EapSecondAuthMethod)); + if (EFI_ERROR(Status)) { + return Status; + } + + // + // Set Password to Eap peer + // + if (StrLen (Profile->EapPassword) < PASSWORD_MIN_LEN) { + + DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Error: No Eap Password for Network: %s.\n", Profile->SSId)); + return EFI_INVALID_PARAMETER; + } + + PasswordSize = sizeof (CHAR16) * (StrLen (Profile->EapPassword) + 1); + Password = AllocateZeroPool (PasswordSize); + if (Password == NULL) { + return EFI_OUT_OF_RESOURCES; + } + StrCpyS (Password, PasswordSize, Profile->EapPassword);; + Status = EapConfig->SetData (EapConfig, EFI_EAP_TYPE_MSCHAPV2, EfiEapConfigEapMSChapV2Password, + (VOID *) Password, PasswordSize); + ZeroMem (Password, PasswordSize); + FreePool (Password); + if (EFI_ERROR (Status)) { + return Status; + } + + // + //If CA cert is required, set it to Eap peer + // + if (Profile->CACertData != NULL) { + + Status = EapConfig->SetData (EapConfig, EapAuthMethod, EfiEapConfigEapTlsCACert, + Profile->CACertData, Profile->CACertSize); + if (EFI_ERROR(Status)) { + return Status; + } + } else { + return EFI_INVALID_PARAMETER; + } + } else if (EapAuthMethod == EFI_EAP_TYPE_EAPTLS) { + + // + //Set CA cert to Eap peer + // + if (Profile->CACertData == NULL) { + return EFI_INVALID_PARAMETER; + } + Status = EapConfig->SetData (EapConfig, EFI_EAP_TYPE_EAPTLS, EfiEapConfigEapTlsCACert, + Profile->CACertData, Profile->CACertSize); + if (EFI_ERROR(Status)) { + return Status; + } + + // + //Set Client cert to Eap peer + // + if (Profile->ClientCertData == NULL) { + return EFI_INVALID_PARAMETER; + } + Status = EapConfig->SetData (EapConfig, EFI_EAP_TYPE_EAPTLS, EfiEapConfigEapTlsClientCert, + Profile->ClientCertData, Profile->ClientCertSize); + if (EFI_ERROR(Status)) { + return Status; + } + + // + //Set Private key to Eap peer + // + if (Profile->PrivateKeyData == NULL) { + + DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Error: No Private Key for Network: %s.\n", Profile->SSId)); + return EFI_INVALID_PARAMETER; + } + + Status = EapConfig->SetData (EapConfig, EFI_EAP_TYPE_EAPTLS, EfiEapConfigEapTlsClientPrivateKeyFile, + Profile->PrivateKeyData, Profile->PrivateKeyDataSize); + if (EFI_ERROR(Status)) { + return Status; + } + + if (StrLen (Profile->PrivateKeyPassword) > 0) { + + EncryptPasswordLen = StrLen (Profile->PrivateKeyPassword); + AsciiEncryptPassword = AllocateZeroPool(EncryptPasswordLen + 1); + if (AsciiEncryptPassword == NULL) { + return EFI_OUT_OF_RESOURCES; + } + UnicodeStrToAsciiStrS(Profile->PrivateKeyPassword, AsciiEncryptPassword, EncryptPasswordLen + 1); + Status = EapConfig->SetData(EapConfig, EFI_EAP_TYPE_EAPTLS, + EfiEapConfigEapTlsClientPrivateKeyFilePassword, + (VOID *) AsciiEncryptPassword, EncryptPasswordLen + 1); + if (EFI_ERROR(Status)) { + + ZeroMem (AsciiEncryptPassword, EncryptPasswordLen + 1); + FreePool (AsciiEncryptPassword); + return Status; + } + + ZeroMem (AsciiEncryptPassword, EncryptPasswordLen + 1); + FreePool (AsciiEncryptPassword); + } + } else { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +/** + Get current link state from low layer. + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[out] LinkState The pointer to buffer to retrieve link state. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_UNSUPPORTED Adapter information protocol is not supported. + @retval Other Errors Returned errors when retrieving link state from low layer. + +**/ +EFI_STATUS +WifiMgrGetLinkState ( + IN WIFI_MGR_DEVICE_DATA *Nic, + OUT EFI_ADAPTER_INFO_MEDIA_STATE *LinkState + ) +{ + EFI_STATUS Status; + UINTN DataSize; + EFI_ADAPTER_INFO_MEDIA_STATE *UndiState; + EFI_ADAPTER_INFORMATION_PROTOCOL *Aip; + + if (Nic == NULL || LinkState == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Nic->Aip == NULL) { + return EFI_UNSUPPORTED; + } + + Aip = Nic->Aip; + Status = Aip->GetInformation( + Aip, + &gEfiAdapterInfoMediaStateGuid, + (VOID **) &UndiState, + &DataSize + ); + if (EFI_ERROR (Status)) { + return Status; + } + + CopyMem (LinkState, UndiState, sizeof (EFI_ADAPTER_INFO_MEDIA_STATE)); + FreePool (UndiState); + return EFI_SUCCESS; +} + +/** + Update connection message on connect configuration page, and trigger related form refresh. + + @param[in] Private The pointer to the global private data structure. + @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_PRIVATE_DATA *Private, + IN BOOLEAN ConnectStateChanged, + IN EFI_STRING ConnectStatusMessage + ) +{ + CHAR16 ConnectStatusStr[WIFI_STR_MAX_SIZE]; + + if (Private == NULL) { + return; + } + + // + // Update Connection Status Bar + // + if (ConnectStatusMessage != NULL) { + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusMessage, NULL); + } else { + if (Private->CurrentNic->ConnectState == WifiMgrConnectedToAp) { + + UnicodeSPrint (ConnectStatusStr, sizeof (ConnectStatusStr), L"Connected to %s", + Private->CurrentNic->CurrentOperateNetwork->SSId); + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusStr, NULL); + } else if (Private->CurrentNic->ConnectState == WifiMgrDisconnected) { + + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), L"Disconnected", NULL); + } else if (Private->CurrentNic->ConnectState == WifiMgrConnectingToAp) { + + UnicodeSPrint (ConnectStatusStr, sizeof (ConnectStatusStr), L"Connecting to %s ...", + Private->CurrentNic->CurrentOperateNetwork->SSId); + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusStr, NULL); + } else if (Private->CurrentNic->ConnectState == WifiMgrDisconnectingToAp) { + + UnicodeSPrint (ConnectStatusStr, sizeof (ConnectStatusStr), L"Disconnecting from %s ...", + Private->CurrentNic->CurrentOperateNetwork->SSId); + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusStr, NULL); + } else { + return; + } + } + + // + // Update Connect Button + // + if (Private->CurrentNic->ConnectState == WifiMgrConnectedToAp && + Private->CurrentNic->UserSelectedProfile == Private->CurrentNic->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 (Private->CurrentNic->ConnectState == WifiMgrConnectedToAp) { + + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECTION_INFO), L"Connected to", NULL); + HiiSetString (Private->RegisteredHandle, + STRING_TOKEN (STR_CONNECTED_SSID), Private->CurrentNic->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); + } +} + +/** + Prepare configuration work before connecting to the target network. + For WPA2 Personal networks, password should be checked; and for EAP networks, parameters + are different for different networks. + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[in] Profile The target network to be connected. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_UNSUPPORTED This network is not supported. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +EFI_STATUS +WifiMgrPrepareConnection ( + IN WIFI_MGR_DEVICE_DATA *Nic, + IN WIFI_MGR_NETWORK_PROFILE *Profile + ) +{ + EFI_STATUS Status; + UINT8 SecurityType; + BOOLEAN AKMSuiteSupported; + BOOLEAN CipherSuiteSupported; + + if (Profile == NULL || Nic == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = WifiMgrCheckRSN (Profile->Network.AKMSuite, Profile->Network.CipherSuite, + Nic, &SecurityType, &AKMSuiteSupported, &CipherSuiteSupported); + if (EFI_ERROR (Status)) { + return Status; + } + + if (AKMSuiteSupported && CipherSuiteSupported) { + switch (SecurityType) { + case SECURITY_TYPE_WPA2_PERSONAL: + + Status = WifiMgrConfigPassword (Nic, Profile); + if (EFI_ERROR (Status)) { + if (Status == EFI_NOT_FOUND) { + if (Nic->OneTimeConnectRequest) { + WifiMgrUpdateConnectMessage (Nic->Private, FALSE, L"Connect Failed: Invalid Password!"); + } + } + return Status; + } + break; + + case SECURITY_TYPE_WPA2_ENTERPRISE: + + Status = WifiMgrConfigEap (Nic, Profile); + if (EFI_ERROR (Status)) { + if (Status == EFI_INVALID_PARAMETER) { + if (Nic->OneTimeConnectRequest) { + WifiMgrUpdateConnectMessage (Nic->Private, FALSE, L"Connect Failed: Invalid Configuration!"); + } + } + return Status; + } + break; + + case SECURITY_TYPE_NONE: + break; + + default: + return EFI_UNSUPPORTED; + } + } else { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +/** + The callback function for connect operation. + + @param[in] Event The Connect token receive event. + @param[in] Context The context of the connect token. + +**/ +VOID +EFIAPI +WifiMgrOnConnectFinished ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + WIFI_MGR_PRIVATE_DATA *Private; + WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken; + WIFI_MGR_NETWORK_PROFILE *ConnectedProfile; + UINT8 SecurityType; + UINT8 SSIdLen; + CHAR8 *AsciiSSId; + + if (Context == NULL) { + return; + } + ConnectedProfile = NULL; + ConfigToken = (WIFI_MGR_MAC_CONFIG_TOKEN*) Context; + if (ConfigToken->Nic == NULL || ConfigToken->Nic->Private == NULL) { + return; + } + Private = ConfigToken->Nic->Private; + + ConfigToken->Nic->ConnectState = WifiMgrDisconnected; + + if (ConfigToken->Signature != WIFI_MGR_MAC_CONFIG_TOKEN_SIGNATURE || + ConfigToken->Type != TokenTypeConnectNetworkToken || + ConfigToken->Token.ConnectNetworkToken == NULL) { + + WifiMgrUpdateConnectMessage (Private, FALSE, NULL); + ConfigToken->Nic->OneTimeConnectRequest = FALSE; + ConfigToken->Nic->CurrentOperateNetwork = NULL; + return; + } + + if (ConfigToken->Token.ConnectNetworkToken->Status != EFI_SUCCESS) { + + if (ConfigToken->Nic->OneTimeConnectRequest) { + // + // Only update message for user triggered connection + // + if (ConfigToken->Token.ConnectNetworkToken->Status == EFI_ACCESS_DENIED) { + + WifiMgrUpdateConnectMessage (Private, FALSE, L"Connect Failed: Permission Denied!"); + } else { + WifiMgrUpdateConnectMessage (Private, FALSE, L"Connect Failed!"); + } + ConfigToken->Nic->OneTimeConnectRequest = FALSE; + } + ConfigToken->Nic->CurrentOperateNetwork = NULL; + return; + } + + if (ConfigToken->Token.ConnectNetworkToken->ResultCode != ConnectSuccess) { + + if (ConfigToken->Nic->OneTimeConnectRequest) { + + if (ConfigToken->Token.ConnectNetworkToken->ResultCode == ConnectFailedReasonUnspecified) { + WifiMgrUpdateConnectMessage (Private, FALSE, L"Connect Failed: Wrong Password or Unexpected Error!"); + } else { + WifiMgrUpdateConnectMessage (Private, FALSE, L"Connect Failed!"); + } + } + goto Exit; + } + + if (ConfigToken->Token.ConnectNetworkToken->Data == NULL || + ConfigToken->Token.ConnectNetworkToken->Data->Network == NULL) { + + // + // An unexpected error occurs, tell low layer to perform a disconnect + // + ConfigToken->Nic->HasDisconnectPendingNetwork = TRUE; + WifiMgrUpdateConnectMessage (Private, FALSE, NULL); + goto Exit; + } + + // + // A correct connect token received, terminate the connection process + // + Status = WifiMgrCheckRSN(ConfigToken->Token.ConnectNetworkToken->Data->Network->AKMSuite, + ConfigToken->Token.ConnectNetworkToken->Data->Network->CipherSuite, + ConfigToken->Nic, &SecurityType, NULL, NULL); + if (EFI_ERROR(Status)) { + SecurityType = SECURITY_TYPE_UNKNOWN; + } + + SSIdLen = ConfigToken->Token.ConnectNetworkToken->Data->Network->SSId.SSIdLen; + AsciiSSId = (CHAR8*) AllocateZeroPool(sizeof (CHAR8) * (SSIdLen + 1)); + if (AsciiSSId == NULL) { + ConfigToken->Nic->HasDisconnectPendingNetwork = TRUE; + WifiMgrUpdateConnectMessage (Private, FALSE, NULL); + goto Exit; + } + + CopyMem(AsciiSSId, ConfigToken->Token.ConnectNetworkToken->Data->Network->SSId.SSId, SSIdLen); + *(AsciiSSId + SSIdLen) = '\0'; + + ConnectedProfile = WifiMgrGetProfileByAsciiSSId(AsciiSSId, SecurityType, &ConfigToken->Nic->ProfileList); + FreePool(AsciiSSId); + if (ConnectedProfile == NULL) { + ConfigToken->Nic->HasDisconnectPendingNetwork = TRUE; + WifiMgrUpdateConnectMessage (Private, FALSE, NULL); + goto Exit; + } + + ConfigToken->Nic->ConnectState = WifiMgrConnectedToAp; + WifiMgrUpdateConnectMessage (Private, TRUE, NULL); + +Exit: + + if (ConfigToken->Nic->ConnectState == WifiMgrDisconnected) { + ConfigToken->Nic->CurrentOperateNetwork = NULL; + } + ConfigToken->Nic->OneTimeConnectRequest = FALSE; + WifiMgrFreeToken(ConfigToken); +} + +/** + Start connect operation, and send out a token to connect to a target network. + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[in] Profile The target network to be connected. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_ALREADY_STARTED Already in "connected" state, need to perform a disconnect + operation first. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Return errors when connecting network on low layer. + +**/ +EFI_STATUS +WifiMgrConnectToNetwork ( + IN WIFI_MGR_DEVICE_DATA *Nic, + IN WIFI_MGR_NETWORK_PROFILE *Profile + ) +{ + EFI_STATUS Status; + WIFI_MGR_PRIVATE_DATA *Private; + EFI_TPL OldTpl; + EFI_ADAPTER_INFO_MEDIA_STATE LinkState; + WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken; + EFI_80211_CONNECT_NETWORK_TOKEN *ConnectToken; + + if (Nic == NULL || Nic->Wmp == NULL || Profile == NULL || Nic->Private == NULL) { + return EFI_INVALID_PARAMETER; + } + Private = Nic->Private; + + Status = WifiMgrGetLinkState (Nic, &LinkState); + if (EFI_ERROR (Status)) { + return Status; + } + if (LinkState.MediaState == EFI_SUCCESS) { + return EFI_ALREADY_STARTED; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + Status = WifiMgrPrepareConnection (Nic, Profile); + if (EFI_ERROR (Status)) { + gBS->RestoreTPL (OldTpl); + return Status; + } + + // + // Create a new connect token + // + ConfigToken = AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN)); + if (ConfigToken == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + InsertTailList (&Nic->TokenList, &ConfigToken->Link); + + ConfigToken->Signature = WIFI_MGR_MAC_CONFIG_TOKEN_SIGNATURE; + ConfigToken->Type = TokenTypeConnectNetworkToken; + ConfigToken->Nic = Nic; + ConfigToken->Token.ConnectNetworkToken = AllocateZeroPool (sizeof (EFI_80211_CONNECT_NETWORK_TOKEN)); + if (ConfigToken->Token.ConnectNetworkToken == NULL) { + goto Exit; + } + + ConnectToken = ConfigToken->Token.ConnectNetworkToken; + ConnectToken->Data = AllocateZeroPool (sizeof (EFI_80211_CONNECT_NETWORK_DATA)); + if (ConnectToken->Data == NULL) { + goto Exit; + } + + ConnectToken->Data->Network = AllocateZeroPool (sizeof (EFI_80211_NETWORK)); + if (ConnectToken->Data->Network == NULL) { + goto Exit; + } + CopyMem(ConnectToken->Data->Network, &Profile->Network, sizeof (EFI_80211_NETWORK)); + + // + // Add event handle and start to connect + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + WifiMgrOnConnectFinished, + ConfigToken, + &ConnectToken->Event + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + Nic->ConnectState = WifiMgrConnectingToAp; + Nic->CurrentOperateNetwork = Profile; + WifiMgrUpdateConnectMessage (Private, FALSE, NULL); + + // + //Start Connecting ... + // + Status = Nic->Wmp->ConnectNetwork (Nic->Wmp, ConnectToken); + + // + // Erase secrets after connection is triggered + // + WifiMgrCleanProfileSecrets (Profile); + + if (EFI_ERROR (Status)) { + if (Status == EFI_ALREADY_STARTED) { + Nic->ConnectState = WifiMgrConnectedToAp; + WifiMgrUpdateConnectMessage (Private, TRUE, NULL); + } else { + + Nic->ConnectState = WifiMgrDisconnected; + Nic->CurrentOperateNetwork = NULL; + + if (Nic->OneTimeConnectRequest) { + if (Status == EFI_NOT_FOUND) { + WifiMgrUpdateConnectMessage (Private, FALSE, L"Connect Failed: Not Available!"); + } else { + WifiMgrUpdateConnectMessage (Private, FALSE, L"Connect Failed: Unexpected Error!"); + } + } + } + goto Exit; + } + +Exit: + + if (EFI_ERROR (Status)) { + WifiMgrFreeToken (ConfigToken); + } + gBS->RestoreTPL (OldTpl); + + DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] WifiMgrConnectToNetwork: %r\n", Status)); + return Status; +} + +/** + The callback function for disconnect operation. + + @param[in] Event The Disconnect token receive event. + @param[in] Context The context of the Disconnect token. + +**/ +VOID +EFIAPI +WifiMgrOnDisconnectFinished ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken; + + if (Context == NULL) { + return; + } + + ConfigToken = (WIFI_MGR_MAC_CONFIG_TOKEN*) Context; + if (ConfigToken->Nic == NULL) { + return; + } + + if (ConfigToken->Signature != WIFI_MGR_MAC_CONFIG_TOKEN_SIGNATURE || + ConfigToken->Type != TokenTypeDisconnectNetworkToken) { + ConfigToken->Nic->ConnectState = WifiMgrConnectedToAp; + WifiMgrUpdateConnectMessage (ConfigToken->Nic->Private, FALSE, NULL); + ConfigToken->Nic->OneTimeDisconnectRequest = FALSE; + return; + } + + if (ConfigToken->Token.DisconnectNetworkToken->Status != EFI_SUCCESS) { + ConfigToken->Nic->ConnectState = WifiMgrConnectedToAp; + WifiMgrUpdateConnectMessage (ConfigToken->Nic->Private, FALSE, NULL); + ConfigToken->Nic->OneTimeDisconnectRequest = FALSE; + goto Exit; + } + + ConfigToken->Nic->ConnectState = WifiMgrDisconnected; + ConfigToken->Nic->CurrentOperateNetwork = NULL; + WifiMgrUpdateConnectMessage (ConfigToken->Nic->Private, TRUE, NULL); + ConfigToken->Nic->OneTimeDisconnectRequest = FALSE; + + // + // Disconnected network may not be in network list now, trigger a scan again! + // + ConfigToken->Nic->OneTimeScanRequest = TRUE; + + Exit: + WifiMgrFreeToken(ConfigToken); + return; +} + +/** + Start disconnect operation, and send out a token to disconnect from current connected + network. + + @param[in] Nic Pointer to the device data of the selected NIC. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval Other Errors Return errors when disconnecting a network on low layer. + +**/ +EFI_STATUS +WifiMgrDisconnectToNetwork ( + IN WIFI_MGR_DEVICE_DATA *Nic + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken; + EFI_80211_DISCONNECT_NETWORK_TOKEN *DisconnectToken; + + if (Nic == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + Status = EFI_SUCCESS; + ConfigToken = AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN)); + if (ConfigToken == NULL) { + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + InsertTailList (&Nic->TokenList, &ConfigToken->Link); + + ConfigToken->Signature = WIFI_MGR_MAC_CONFIG_TOKEN_SIGNATURE; + ConfigToken->Type = TokenTypeDisconnectNetworkToken; + ConfigToken->Nic = Nic; + ConfigToken->Token.DisconnectNetworkToken = AllocateZeroPool (sizeof (EFI_80211_DISCONNECT_NETWORK_TOKEN)); + if (ConfigToken->Token.DisconnectNetworkToken == NULL) { + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + + DisconnectToken = ConfigToken->Token.DisconnectNetworkToken; + + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + WifiMgrOnDisconnectFinished, + ConfigToken, + &DisconnectToken->Event + ); + if (EFI_ERROR (Status)) { + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return Status; + } + + Nic->ConnectState = WifiMgrDisconnectingToAp; + WifiMgrUpdateConnectMessage (ConfigToken->Nic->Private, FALSE, NULL); + + Status = Nic->Wmp->DisconnectNetwork (Nic->Wmp, DisconnectToken); + if (EFI_ERROR (Status)) { + if (Status == EFI_NOT_FOUND) { + + Nic->ConnectState = WifiMgrDisconnected; + Nic->CurrentOperateNetwork = NULL; + + // + // This network is not in network list now, trigger a scan again! + // + Nic->OneTimeScanRequest = TRUE; + + // + // State has been changed from Connected to Disconnected + // + WifiMgrUpdateConnectMessage (ConfigToken->Nic->Private, TRUE, NULL); + Status = EFI_SUCCESS; + } else { + if (Nic->OneTimeDisconnectRequest) { + + WifiMgrUpdateConnectMessage (ConfigToken->Nic->Private, FALSE, L"Disconnect Failed: Unexpected Error!"); + } + + Nic->ConnectState = WifiMgrConnectedToAp; + WifiMgrUpdateConnectMessage (ConfigToken->Nic->Private, FALSE, NULL); + } + WifiMgrFreeToken(ConfigToken); + } + + gBS->RestoreTPL (OldTpl); + return Status; +} + +/** + The state machine of the connection manager, periodically check the state and + perform a corresponding operation. + + @param[in] Event The timer event to be triggered. + @param[in] Context The context of the Nic device data. + +**/ +VOID +EFIAPI +WifiMgrOnTimerTick ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + WIFI_MGR_DEVICE_DATA *Nic; + EFI_STATUS Status; + EFI_ADAPTER_INFO_MEDIA_STATE LinkState; + WIFI_MGR_NETWORK_PROFILE *Profile; + + if (Context == NULL) { + return; + } + + Nic = (WIFI_MGR_DEVICE_DATA*) Context; + NET_CHECK_SIGNATURE (Nic, WIFI_MGR_DEVICE_DATA_SIGNATURE); + + Status = WifiMgrGetLinkState (Nic, &LinkState); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Error: Failed to get link state!\n")); + return; + } + + if (Nic->LastLinkState.MediaState != LinkState.MediaState) { + if (Nic->LastLinkState.MediaState == EFI_SUCCESS && LinkState.MediaState == EFI_NO_MEDIA) { + Nic->HasDisconnectPendingNetwork = TRUE; + } + Nic->LastLinkState.MediaState = LinkState.MediaState; + } + + Nic->ScanTickTime ++; + if ((Nic->ScanTickTime > WIFI_SCAN_FREQUENCY || Nic->OneTimeScanRequest) && + Nic->ScanState == WifiMgrScanFinished) { + + Nic->OneTimeScanRequest = FALSE; + Nic->ScanTickTime = 0; + + DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Scan is triggered.\n")); + WifiMgrStartScan (Nic); + } + + if (Nic->AvailableCount > 0 && Nic->ScanState == WifiMgrScanFinished) { + + switch (Nic->ConnectState) { + case WifiMgrDisconnected: + + if (Nic->HasDisconnectPendingNetwork) { + Nic->HasDisconnectPendingNetwork = FALSE; + } + + if (Nic->ConnectPendingNetwork != NULL) { + + Profile = Nic->ConnectPendingNetwork; + Status = WifiMgrConnectToNetwork(Nic, Profile); + Nic->ConnectPendingNetwork = NULL; + if (EFI_ERROR (Status)) { + // + // Some error happened, don't wait for a return connect token! + // + Nic->OneTimeConnectRequest = FALSE; + } + } + break; + + case WifiMgrConnectingToAp: + break; + + case WifiMgrDisconnectingToAp: + break; + + case WifiMgrConnectedToAp: + + if (Nic->ConnectPendingNetwork != NULL || Nic->HasDisconnectPendingNetwork) { + + Status = WifiMgrDisconnectToNetwork(Nic); + if (EFI_ERROR (Status)) { + // + // Some error happened, don't wait for a return disconnect token! + // + Nic->OneTimeDisconnectRequest = FALSE; + } + } + break; + + default: + break; + } + } +} diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.h new file mode 100644 index 0000000000..d38c391bbf --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.h @@ -0,0 +1,123 @@ +/** @file + The Mac Connection2 Protocol adapter functions for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __EFI_WIFI_IMPL__ +#define __EFI_WIFI_IMPL__ + +/** + Start scan operation, and send out a token to collect available networks. + + @param[in] Nic Pointer to the device data of the selected NIC. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_ALREADY_STARTED A former scan operation is already ongoing. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Return errors when getting networks from low layer. + +**/ +EFI_STATUS +WifiMgrStartScan ( + IN WIFI_MGR_DEVICE_DATA *Nic + ); + +/** + Get current link state from low layer. + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[out] LinkState The pointer to buffer to retrieve link state. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_UNSUPPORTED Adapter information protocol is not supported. + @retval Other Errors Returned errors when retrieving link state from low layer. + +**/ +EFI_STATUS +WifiMgrGetLinkState ( + IN WIFI_MGR_DEVICE_DATA *Nic, + OUT EFI_ADAPTER_INFO_MEDIA_STATE *LinkState + ); + +/** + Update connection message on connect configuration page, and trigger related form refresh. + + @param[in] Private The pointer to the global private data structure. + @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_PRIVATE_DATA *Private, + IN BOOLEAN ConnectStateChanged, + IN EFI_STRING ConnectStatusMessage + ); + +/** + Start connect operation, and send out a token to connect to a target network. + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[in] Profile The target network to be connected. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_ALREADY_STARTED Already in "connected" state, need to perform a disconnect + operation first. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Return errors when connecting network on low layer. + +**/ +EFI_STATUS +WifiMgrConnectToNetwork ( + IN WIFI_MGR_DEVICE_DATA *Nic, + IN WIFI_MGR_NETWORK_PROFILE *Profile + ); + +/** + Start disconnect operation, and send out a token to disconnect from current connected + network. + + @param[in] Nic Pointer to the device data of the selected NIC. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Return errors when disconnecting a network on low layer. + +**/ +EFI_STATUS +WifiMgrDisconnectToNetwork ( + IN WIFI_MGR_DEVICE_DATA *Nic + ); + +/** + The state machine of the connection manager, periodically check the state and + perform a corresponding operation. + + @param[in] Event The timer event to be triggered. + @param[in] Context The context of the Nic device data. + +**/ +VOID +EFIAPI +WifiMgrOnTimerTick ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +#endif diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c new file mode 100644 index 0000000000..3562734040 --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c @@ -0,0 +1,784 @@ +/** @file + The Miscellaneous Routines for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "WifiConnectionMgrDxe.h" + +/** + Empty function for event process function. + + @param Event The Event need to be process + @param Context The context of the event. + +**/ +VOID +EFIAPI +WifiMgrInternalEmptyFunction ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + return; +} + +/** + Convert the mac address into a hexadecimal encoded ":" seperated string. + + @param[in] Mac The mac address. + @param[in] StrSize The size, in bytes, of the output buffer specified by Str. + @param[out] Str The storage to return the mac string. + +**/ +VOID +WifiMgrMacAddrToStr ( + IN EFI_80211_MAC_ADDRESS *Mac, + IN UINT32 StrSize, + OUT CHAR16 *Str + ) +{ + if (Mac == NULL || Str == NULL) { + return; + } + + UnicodeSPrint ( + Str, + StrSize, + L"%02X:%02X:%02X:%02X:%02X:%02X", + Mac->Addr[0], Mac->Addr[1], Mac->Addr[2], + Mac->Addr[3], Mac->Addr[4], Mac->Addr[5] + ); +} + +/** + Read private key file to buffer. + + @param[in] FileContext The file context of private key file. + @param[out] PrivateKeyDataAddr The buffer address to restore private key file, should be + freed by caller. + @param[out] PrivateKeyDataSize The size of read private key file. + + @retval EFI_SUCCESS Successfully read the private key file. + @retval EFI_INVALID_PARAMETER One or more of the parameters is invalid. + +**/ +EFI_STATUS +WifiMgrReadFileToBuffer ( + IN WIFI_MGR_FILE_CONTEXT *FileContext, + OUT VOID **DataAddr, + OUT UINTN *DataSize + ) +{ + EFI_STATUS Status; + + if (FileContext != NULL && FileContext->FHandle != NULL) { + + Status = ReadFileContent ( + FileContext->FHandle, + DataAddr, + DataSize, + 0 + ); + + if (FileContext->FHandle != NULL) { + FileContext->FHandle->Close (FileContext->FHandle); + } + FileContext->FHandle = NULL; + return Status; + } + + return EFI_INVALID_PARAMETER; +} + +/** + Get the Nic data by the NicIndex. + + @param[in] Private The pointer to the global private data structure. + @param[in] NicIndex The index indicates the position of wireless NIC. + + @return Pointer to the Nic data, or NULL if not found. + +**/ +WIFI_MGR_DEVICE_DATA * +WifiMgrGetNicByIndex ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN UINT32 NicIndex + ) +{ + LIST_ENTRY *Entry; + WIFI_MGR_DEVICE_DATA *Nic; + + if (Private == NULL) { + return NULL; + } + + NET_LIST_FOR_EACH (Entry, &Private->NicList) { + Nic = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_DEVICE_DATA, + Link, WIFI_MGR_DEVICE_DATA_SIGNATURE); + if (Nic->NicIndex == NicIndex) { + return Nic; + } + } + + return NULL; +} + +/** + Find a network profile through its' SSId and securit type, and the SSId is an unicode string. + + @param[in] SSId The target network's SSId. + @param[in] SecurityType The target network's security type. + @param[in] ProfileList The profile list on a Nic. + + @return Pointer to a network profile, or NULL if not found. + +**/ +WIFI_MGR_NETWORK_PROFILE * +WifiMgrGetProfileByUnicodeSSId ( + IN CHAR16 *SSId, + IN UINT8 SecurityType, + IN LIST_ENTRY *ProfileList + ) +{ + LIST_ENTRY *Entry; + WIFI_MGR_NETWORK_PROFILE *Profile; + + if (SSId == NULL || ProfileList == NULL) { + return NULL; + } + + NET_LIST_FOR_EACH (Entry, ProfileList) { + Profile = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_NETWORK_PROFILE, + Link, WIFI_MGR_PROFILE_SIGNATURE); + if (StrCmp (SSId, Profile->SSId) == 0 && SecurityType == Profile->SecurityType) { + return Profile; + } + } + + return NULL; +} + +/** + Find a network profile through its' SSId and securit type, and the SSId is an ascii string. + + @param[in] SSId The target network's SSId. + @param[in] SecurityType The target network's security type. + @param[in] ProfileList The profile list on a Nic. + + @return Pointer to a network profile, or NULL if not found. + +**/ +WIFI_MGR_NETWORK_PROFILE * +WifiMgrGetProfileByAsciiSSId ( + IN CHAR8 *SSId, + IN UINT8 SecurityType, + IN LIST_ENTRY *ProfileList + ) +{ + CHAR16 SSIdUniCode[SSID_STORAGE_SIZE]; + + if (SSId == NULL) { + return NULL; + } + if (AsciiStrToUnicodeStrS (SSId, SSIdUniCode, SSID_STORAGE_SIZE) != RETURN_SUCCESS) { + return NULL; + } + + return WifiMgrGetProfileByUnicodeSSId (SSIdUniCode, SecurityType, ProfileList); +} + +/** + Find a network profile through its' profile index. + + @param[in] ProfileIndex The target network's profile index. + @param[in] ProfileList The profile list on a Nic. + + @return Pointer to a network profile, or NULL if not found. + +**/ +WIFI_MGR_NETWORK_PROFILE * +WifiMgrGetProfileByProfileIndex ( + IN UINT32 ProfileIndex, + IN LIST_ENTRY *ProfileList + ) +{ + WIFI_MGR_NETWORK_PROFILE *Profile; + LIST_ENTRY *Entry; + + if (ProfileList == NULL) { + return NULL; + } + NET_LIST_FOR_EACH (Entry, ProfileList) { + Profile = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_NETWORK_PROFILE, + Link, WIFI_MGR_PROFILE_SIGNATURE); + if (Profile->ProfileIndex == ProfileIndex) { + return Profile; + } + } + return NULL; +} + +/** + To test if the AKMSuite is in supported AKMSuite list. + + @param[in] SupportedAKMSuiteCount The count of the supported AKMSuites. + @param[in] SupportedAKMSuiteList The supported AKMSuite list. + @param[in] AKMSuite The AKMSuite to be tested. + + @return True if this AKMSuite is supported, or False if not. + +**/ +BOOLEAN +WifiMgrSupportAKMSuite ( + IN UINT16 SupportedAKMSuiteCount, + IN UINT32 *SupportedAKMSuiteList, + IN UINT32 *AKMSuite + ) +{ + UINT16 Index; + + if (AKMSuite == NULL || SupportedAKMSuiteList == NULL || + SupportedAKMSuiteCount == 0) { + return FALSE; + } + + for (Index = 0; Index < SupportedAKMSuiteCount; Index ++) { + if (SupportedAKMSuiteList[Index] == *AKMSuite) { + return TRUE; + } + } + + return FALSE; +} + +/** + To check if the CipherSuite is in supported CipherSuite list. + + @param[in] SupportedCipherSuiteCount The count of the supported CipherSuites. + @param[in] SupportedCipherSuiteList The supported CipherSuite list. + @param[in] CipherSuite The CipherSuite to be tested. + + @return True if this CipherSuite is supported, or False if not. + +**/ +BOOLEAN +WifiMgrSupportCipherSuite ( + IN UINT16 SupportedCipherSuiteCount, + IN UINT32 *SupportedCipherSuiteList, + IN UINT32 *CipherSuite + ) +{ + UINT16 Index; + + if (CipherSuite == NULL || SupportedCipherSuiteCount == 0 || + SupportedCipherSuiteList == NULL) { + return FALSE; + } + + for (Index = 0; Index < SupportedCipherSuiteCount; Index ++) { + if (SupportedCipherSuiteList[Index] == *CipherSuite) { + return TRUE; + } + } + + return FALSE; +} + +/** + Check an AKM suite list and a Cipher suite list to see if one or more AKM suites or Cipher suites + are supported and find the matchable security type. + + @param[in] AKMList The target AKM suite list to be checked. + @param[in] CipherList The target Cipher suite list to be checked + @param[in] Nic The Nic to operate, contains the supported AKMSuite list + and supported CipherSuite list + @param[out] SecurityType To identify a security type from the AKM suite list and + Cipher suite list + @param[out] AKMSuiteSupported To identify if this security type is supported. If it is + NULL, overcome this field + @param[out] CipherSuiteSupported To identify if this security type is supported. If it is + NULL, overcome this field + + @retval EFI_SUCCESS This operation has completed successfully. + @retval EFI_INVALID_PARAMETER No Nic found or the suite list is null. + +**/ +EFI_STATUS +WifiMgrCheckRSN ( + IN EFI_80211_AKM_SUITE_SELECTOR *AKMList, + IN EFI_80211_CIPHER_SUITE_SELECTOR *CipherList, + IN WIFI_MGR_DEVICE_DATA *Nic, + OUT UINT8 *SecurityType, + OUT BOOLEAN *AKMSuiteSupported, + OUT BOOLEAN *CipherSuiteSupported + ) +{ + EFI_80211_AKM_SUITE_SELECTOR *SupportedAKMSuites; + EFI_80211_CIPHER_SUITE_SELECTOR *SupportedSwCipherSuites; + EFI_80211_CIPHER_SUITE_SELECTOR *SupportedHwCipherSuites; + EFI_80211_SUITE_SELECTOR *AKMSuite; + EFI_80211_SUITE_SELECTOR *CipherSuite; + UINT16 AKMIndex; + UINT16 CipherIndex; + + if (Nic == NULL || AKMList == NULL || CipherList == NULL|| SecurityType == NULL) { + return EFI_INVALID_PARAMETER; + } + + SupportedAKMSuites = Nic->SupportedSuites.SupportedAKMSuites; + SupportedSwCipherSuites = Nic->SupportedSuites.SupportedSwCipherSuites; + SupportedHwCipherSuites = Nic->SupportedSuites.SupportedHwCipherSuites; + + *SecurityType = SECURITY_TYPE_UNKNOWN; + if (AKMSuiteSupported != NULL && CipherSuiteSupported != NULL) { + *AKMSuiteSupported = FALSE; + *CipherSuiteSupported = FALSE; + } + + if (AKMList->AKMSuiteCount == 0) { + if (CipherList->CipherSuiteCount == 0) { + *SecurityType = SECURITY_TYPE_NONE; + if (AKMSuiteSupported != NULL && CipherSuiteSupported != NULL) { + *AKMSuiteSupported = TRUE; + *CipherSuiteSupported = TRUE; + } + } + + return EFI_SUCCESS; + } + + for (AKMIndex = 0; AKMIndex < AKMList->AKMSuiteCount; AKMIndex ++) { + + AKMSuite = AKMList->AKMSuiteList + AKMIndex; + if (WifiMgrSupportAKMSuite(SupportedAKMSuites->AKMSuiteCount, + (UINT32*) SupportedAKMSuites->AKMSuiteList, (UINT32*) AKMSuite)) { + + if (AKMSuiteSupported != NULL && CipherSuiteSupported != NULL) { + *AKMSuiteSupported = TRUE; + } + for (CipherIndex = 0; CipherIndex < CipherList->CipherSuiteCount; CipherIndex ++) { + + CipherSuite = CipherList->CipherSuiteList + CipherIndex; + + if (SupportedSwCipherSuites != NULL) { + + if (WifiMgrSupportCipherSuite(SupportedSwCipherSuites->CipherSuiteCount, + (UINT32*) SupportedSwCipherSuites->CipherSuiteList, (UINT32*) CipherSuite)) { + + *SecurityType = WifiMgrGetSecurityType ((UINT32*) AKMSuite, (UINT32*) CipherSuite); + + if (*SecurityType != SECURITY_TYPE_UNKNOWN) { + + if (AKMSuiteSupported != NULL && CipherSuiteSupported != NULL) { + *CipherSuiteSupported = TRUE; + } + return EFI_SUCCESS; + } + } + } + + if (SupportedHwCipherSuites != NULL) { + + if (WifiMgrSupportCipherSuite(SupportedHwCipherSuites->CipherSuiteCount, + (UINT32*) SupportedHwCipherSuites->CipherSuiteList, (UINT32*) CipherSuite)) { + + *SecurityType = WifiMgrGetSecurityType ((UINT32*) AKMSuite, (UINT32*) CipherSuite); + + if (*SecurityType != SECURITY_TYPE_UNKNOWN) { + + if (AKMSuiteSupported != NULL && CipherSuiteSupported != NULL) { + *CipherSuiteSupported = TRUE; + } + return EFI_SUCCESS; + } + } + } + } + } + } + + *SecurityType = WifiMgrGetSecurityType ((UINT32*) AKMList->AKMSuiteList, + (UINT32*) CipherList->CipherSuiteList); + + return EFI_SUCCESS; +} + +/** + Get the security type for a certain AKMSuite and CipherSuite. + + @param[in] AKMSuite An certain AKMSuite. + @param[in] CipherSuite An certain CipherSuite. + + @return a security type if found, or SECURITY_TYPE_UNKNOWN. + +**/ +UINT8 +WifiMgrGetSecurityType ( + IN UINT32 *AKMSuite, + IN UINT32 *CipherSuite + ) +{ + if (CipherSuite == NULL) { + + if (AKMSuite == NULL) { + return SECURITY_TYPE_NONE; + } else { + return SECURITY_TYPE_UNKNOWN; + } + } else if (*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_USE_GROUP) { + + if (AKMSuite == NULL) { + return SECURITY_TYPE_NONE; + } else { + return SECURITY_TYPE_UNKNOWN; + } + } else if (*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_WEP40 || + *CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_WEP104) { + + return SECURITY_TYPE_WEP; + } else if (*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_CCMP) { + + if (AKMSuite == NULL) { + return SECURITY_TYPE_UNKNOWN; + } + + if (*AKMSuite == IEEE_80211_AKM_SUITE_8021X_OR_PMKSA || + *AKMSuite == IEEE_80211_AKM_SUITE_8021X_OR_PMKSA_SHA256) { + + return SECURITY_TYPE_WPA2_ENTERPRISE; + } else if (*AKMSuite == IEEE_80211_AKM_SUITE_PSK || + *AKMSuite == IEEE_80211_AKM_SUITE_PSK_SHA256){ + + return SECURITY_TYPE_WPA2_PERSONAL; + }else { + return SECURITY_TYPE_UNKNOWN; + } + } else if (*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_TKIP) { + + if (AKMSuite == NULL) { + return SECURITY_TYPE_UNKNOWN; + } + + if (*AKMSuite == IEEE_80211_AKM_SUITE_8021X_OR_PMKSA || + *AKMSuite == IEEE_80211_AKM_SUITE_8021X_OR_PMKSA_SHA256) { + + return SECURITY_TYPE_WPA_ENTERPRISE; + } else if (*AKMSuite == IEEE_80211_AKM_SUITE_PSK || + *AKMSuite == IEEE_80211_AKM_SUITE_PSK_SHA256){ + + return SECURITY_TYPE_WPA_PERSONAL; + }else { + return SECURITY_TYPE_UNKNOWN; + } + } else { + return SECURITY_TYPE_UNKNOWN; + } +} + +/** + Get supported AKMSuites and CipherSuites from supplicant for a Nic. + + @param[in] Nic The Nic to operate. + + @retval EFI_SUCCESS Get the supported suite list successfully. + @retval EFI_INVALID_PARAMETER No Nic found or supplicant is NULL. + +**/ +EFI_STATUS +WifiMgrGetSupportedSuites ( + IN WIFI_MGR_DEVICE_DATA *Nic + ) +{ + EFI_STATUS Status; + EFI_SUPPLICANT_PROTOCOL *Supplicant; + EFI_80211_AKM_SUITE_SELECTOR *SupportedAKMSuites; + EFI_80211_CIPHER_SUITE_SELECTOR *SupportedSwCipherSuites; + EFI_80211_CIPHER_SUITE_SELECTOR *SupportedHwCipherSuites; + UINTN DataSize; + + SupportedAKMSuites = NULL; + SupportedSwCipherSuites = NULL; + SupportedHwCipherSuites = NULL; + + if (Nic == NULL || Nic->Supplicant == NULL) { + return EFI_INVALID_PARAMETER; + } + + Supplicant = Nic->Supplicant; + + DataSize = 0; + Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedAKMSuites, NULL, &DataSize); + if (Status == EFI_BUFFER_TOO_SMALL && DataSize > 0) { + + SupportedAKMSuites = AllocateZeroPool(DataSize); + if (SupportedAKMSuites == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedAKMSuites, + (UINT8 *) SupportedAKMSuites, &DataSize); + if (!EFI_ERROR (Status)) { + Nic->SupportedSuites.SupportedAKMSuites = SupportedAKMSuites; + } else { + FreePool (SupportedAKMSuites); + } + } else { + SupportedAKMSuites = NULL; + } + + DataSize = 0; + Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedSoftwareCipherSuites, NULL, &DataSize); + if (Status == EFI_BUFFER_TOO_SMALL && DataSize > 0) { + + + SupportedSwCipherSuites = AllocateZeroPool(DataSize); + if (SupportedSwCipherSuites == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedSoftwareCipherSuites, + (UINT8 *) SupportedSwCipherSuites, &DataSize); + if (!EFI_ERROR (Status)) { + Nic->SupportedSuites.SupportedSwCipherSuites = SupportedSwCipherSuites; + } else { + FreePool (SupportedSwCipherSuites); + } + } else { + SupportedSwCipherSuites = NULL; + } + + DataSize = 0; + Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedHardwareCipherSuites, NULL, &DataSize); + if (Status == EFI_BUFFER_TOO_SMALL && DataSize > 0) { + + SupportedHwCipherSuites = AllocateZeroPool(DataSize); + if (SupportedHwCipherSuites == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedHardwareCipherSuites, + (UINT8 *) SupportedHwCipherSuites, &DataSize); + if (!EFI_ERROR (Status)) { + Nic->SupportedSuites.SupportedHwCipherSuites = SupportedHwCipherSuites; + } else { + FreePool (SupportedHwCipherSuites); + } + } else { + SupportedHwCipherSuites = NULL; + } + + return EFI_SUCCESS; +} + +/** + Clean secrets from a network profile. + + @param[in] Profile The profile to be cleanned. + +**/ +VOID +WifiMgrCleanProfileSecrets ( + IN WIFI_MGR_NETWORK_PROFILE *Profile + ) +{ + ZeroMem (Profile->Password, sizeof (CHAR16) * PASSWORD_STORAGE_SIZE); + ZeroMem (Profile->EapPassword, sizeof (CHAR16) * PASSWORD_STORAGE_SIZE); + ZeroMem (Profile->PrivateKeyPassword, sizeof (CHAR16) * PASSWORD_STORAGE_SIZE); + + if (Profile->CACertData != NULL) { + + ZeroMem (Profile->CACertData, Profile->CACertSize); + FreePool (Profile->CACertData); + } + Profile->CACertData = NULL; + Profile->CACertSize = 0; + + if (Profile->ClientCertData != NULL) { + + ZeroMem (Profile->ClientCertData, Profile->ClientCertSize); + FreePool (Profile->ClientCertData); + } + Profile->ClientCertData = NULL; + Profile->ClientCertSize = 0; + + if (Profile->PrivateKeyData != NULL) { + + ZeroMem (Profile->PrivateKeyData, Profile->PrivateKeyDataSize); + FreePool (Profile->PrivateKeyData); + } + Profile->PrivateKeyData = NULL; + Profile->PrivateKeyDataSize = 0; +} + +/** + Free all network profiles in a profile list. + + @param[in] ProfileList The profile list to be freed. + +**/ +VOID +WifiMgrFreeProfileList ( + IN LIST_ENTRY *ProfileList + ) +{ + WIFI_MGR_NETWORK_PROFILE *Profile; + LIST_ENTRY *Entry; + LIST_ENTRY *NextEntry; + + if (ProfileList == NULL) { + return; + } + + NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, ProfileList) { + + Profile = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_NETWORK_PROFILE, + Link, WIFI_MGR_PROFILE_SIGNATURE); + + WifiMgrCleanProfileSecrets (Profile); + + if (Profile->Network.AKMSuite != NULL) { + FreePool(Profile->Network.AKMSuite); + } + + if (Profile->Network.CipherSuite != NULL) { + FreePool(Profile->Network.CipherSuite); + } + + FreePool (Profile); + } +} + +/** + Free user configured hidden network list. + + @param[in] HiddenList The hidden network list to be freed. + +**/ +VOID +WifiMgrFreeHiddenList ( + IN LIST_ENTRY *HiddenList + ) +{ + WIFI_HIDDEN_NETWORK_DATA *HiddenNetwork; + LIST_ENTRY *Entry; + LIST_ENTRY *NextEntry; + + if (HiddenList == NULL) { + return; + } + + NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, HiddenList) { + + HiddenNetwork = NET_LIST_USER_STRUCT_S (Entry, WIFI_HIDDEN_NETWORK_DATA, + Link, WIFI_MGR_HIDDEN_NETWORK_SIGNATURE); + FreePool (HiddenNetwork); + } +} + + +/** + Free the resources of a config token. + + @param[in] ConfigToken The config token to be freed. +**/ +VOID +WifiMgrFreeToken ( + IN WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken + ) +{ + EFI_80211_GET_NETWORKS_RESULT *Result; + + if (ConfigToken == NULL) { + return; + } + + switch (ConfigToken->Type) { + + case TokenTypeGetNetworksToken: + + RemoveEntryList (&ConfigToken->Link); + + if (ConfigToken->Token.GetNetworksToken != NULL) { + + gBS->CloseEvent (ConfigToken->Token.GetNetworksToken->Event); + if (ConfigToken->Token.GetNetworksToken->Data != NULL) { + FreePool(ConfigToken->Token.GetNetworksToken->Data); + } + + Result = ConfigToken->Token.GetNetworksToken->Result; + if (Result != NULL) { + FreePool (Result); + } + + FreePool(ConfigToken->Token.GetNetworksToken); + } + + FreePool (ConfigToken); + break; + + case TokenTypeConnectNetworkToken: + + RemoveEntryList (&ConfigToken->Link); + + if (ConfigToken->Token.ConnectNetworkToken != NULL) { + + gBS->CloseEvent (ConfigToken->Token.ConnectNetworkToken->Event); + if (ConfigToken->Token.ConnectNetworkToken->Data != NULL) { + FreePool(ConfigToken->Token.ConnectNetworkToken->Data); + } + FreePool(ConfigToken->Token.ConnectNetworkToken); + } + FreePool (ConfigToken); + break; + + case TokenTypeDisconnectNetworkToken: + + RemoveEntryList (&ConfigToken->Link); + + if (ConfigToken->Token.DisconnectNetworkToken != NULL) { + + FreePool(ConfigToken->Token.DisconnectNetworkToken); + } + + FreePool (ConfigToken); + break; + + default : + break; + } +} + +/** + Free all tokens in a token list. + + @param[in] TokenList The token list to be freed. + +**/ +VOID +WifiMgrFreeTokenList ( + IN LIST_ENTRY *TokenList + ) +{ + WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken; + LIST_ENTRY *Entry; + LIST_ENTRY *NextEntry; + + if (TokenList == NULL) { + return; + } + + NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, TokenList) { + + ConfigToken = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_MAC_CONFIG_TOKEN, + Link, WIFI_MGR_MAC_CONFIG_TOKEN_SIGNATURE); + WifiMgrFreeToken (ConfigToken); + } +} + diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.h new file mode 100644 index 0000000000..10e170fde0 --- /dev/null +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.h @@ -0,0 +1,279 @@ +/** @file + The Miscellaneous Routines for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __EFI_WIFI_MGR_MISC_H__ +#define __EFI_WIFI_MGR_MISC_H__ + +/** + Empty function for event process function. + + @param[in] Event The Event needs to be processed + @param[in] Context The context of the event + +**/ +VOID +EFIAPI +WifiMgrInternalEmptyFunction ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Convert the mac address into a hexadecimal encoded ":" seperated string. + + @param[in] Mac The mac address + @param[in] StrSize The size, in bytes, of the output buffer specified by Str + @param[out] Str The storage to return the mac string + +**/ +VOID +WifiMgrMacAddrToStr ( + IN EFI_80211_MAC_ADDRESS *Mac, + IN UINT32 StrSize, + OUT CHAR16 *Str + ); + +/** + Read private key file to buffer. + + @param[in] FileContext The file context of private key file. + @param[out] PrivateKeyDataAddr The buffer address to restore private key file, should be + freed by caller. + @param[out] PrivateKeyDataSize The size of read private key file. + + @retval EFI_SUCCESS Successfully read the private key file. + @retval EFI_INVALID_PARAMETER One or more of the parameters is invalid. + +**/ +EFI_STATUS +WifiMgrReadFileToBuffer ( + IN WIFI_MGR_FILE_CONTEXT *FileContext, + OUT VOID **PrivateKeyDataAddr, + OUT UINTN *PrivateKeyDataSize + ); + + +/** + Get the Nic data by the NicIndex. + + @param[in] Private The pointer to the global private data structure. + @param[in] NicIndex The index indicates the position of wireless NIC. + + @return Pointer to the Nic data, or NULL if not found. + +**/ +WIFI_MGR_DEVICE_DATA * +WifiMgrGetNicByIndex ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN UINT32 NicIndex + ); + +/** + Find a network profile through its' SSId and securit type, and the SSId is an unicode string. + + @param[in] SSId The target network's SSId. + @param[in] SecurityType The target network's security type. + @param[in] ProfileList The profile list on a Nic. + + @return Pointer to a network profile, or NULL if not found. + +**/ +WIFI_MGR_NETWORK_PROFILE * +WifiMgrGetProfileByUnicodeSSId ( + IN CHAR16 *SSId, + IN UINT8 SecurityType, + IN LIST_ENTRY *ProfileList + ); + +/** + Find a network profile through its' SSId and securit type, and the SSId is an ascii string. + + @param[in] SSId The target network's SSId. + @param[in] SecurityType The target network's security type. + @param[in] ProfileList The profile list on a Nic. + + @return Pointer to a network profile, or NULL if not found. + +**/ +WIFI_MGR_NETWORK_PROFILE * +WifiMgrGetProfileByAsciiSSId ( + IN CHAR8 *SSId, + IN UINT8 SecurityType, + IN LIST_ENTRY *ProfileList + ); + +/** + Find a network profile through its' profile index. + + @param[in] ProfileIndex The target network's profile index. + @param[in] ProfileList The profile list on a Nic. + + @return Pointer to a network profile, or NULL if not found. + +**/ +WIFI_MGR_NETWORK_PROFILE * +WifiMgrGetProfileByProfileIndex ( + IN UINT32 ProfileIndex, + IN LIST_ENTRY *ProfileList + ); + +/** + To test if the AKMSuite is in supported AKMSuite list. + + @param[in] SupportedAKMSuiteCount The count of the supported AKMSuites. + @param[in] SupportedAKMSuiteList The supported AKMSuite list. + @param[in] AKMSuite The AKMSuite to be tested. + + @return True if this AKMSuite is supported, or False if not. + +**/ +BOOLEAN +WifiMgrSupportAKMSuite ( + IN UINT16 SupportedAKMSuiteCount, + IN UINT32 *SupportedAKMSuiteList, + IN UINT32 *AKMSuite + ); + +/** + To check if the CipherSuite is in supported CipherSuite list. + + @param[in] SupportedCipherSuiteCount The count of the supported CipherSuites. + @param[in] SupportedCipherSuiteList The supported CipherSuite list. + @param[in] CipherSuite The CipherSuite to be tested. + + @return True if this CipherSuite is supported, or False if not. + +**/ +BOOLEAN +WifiMgrSupportCipherSuite ( + IN UINT16 SupportedCipherSuiteCount, + IN UINT32 *SupportedCipherSuiteList, + IN UINT32 *CipherSuite + ); + +/** + Check an AKM suite list and a Cipher suite list to see if one or more AKM suites or Cipher suites + are supported and find the matchable security type. + + @param[in] AKMList The target AKM suite list to be checked. + @param[in] CipherList The target Cipher suite list to be checked + @param[in] Nic The Nic to operate, contains the supported AKMSuite list + and supported CipherSuite list + @param[out] SecurityType To identify a security type from the AKM suite list and + Cipher suite list + @param[out] AKMSuiteSupported To identify if this security type is supported. If it is + NULL, overcome this field + @param[out] CipherSuiteSupported To identify if this security type is supported. If it is + NULL, overcome this field + + @retval EFI_SUCCESS This operation has completed successfully. + @retval EFI_INVALID_PARAMETER No Nic found or the suite list is null. + +**/ +EFI_STATUS +WifiMgrCheckRSN ( + IN EFI_80211_AKM_SUITE_SELECTOR *AKMList, + IN EFI_80211_CIPHER_SUITE_SELECTOR *CipherList, + IN WIFI_MGR_DEVICE_DATA *Nic, + OUT UINT8 *SecurityType, + OUT BOOLEAN *AKMSuiteSupported, + OUT BOOLEAN *CipherSuiteSupported + ); + +/** + To get the security type for a certain AKMSuite and CipherSuite. + + @param[in] AKMSuite An certain AKMSuite. + @param[in] CipherSuite An certain CipherSuite. + + @return a security type if found, or SECURITY_TYPE_UNKNOWN. + +**/ +UINT8 +WifiMgrGetSecurityType ( + IN UINT32 *AKMSuite, + IN UINT32 *CipherSuite + ); + +/** + Get supported AKMSuites and CipherSuites from supplicant. + + @param[in] Nic The Nic to operate. + + @retval EFI_SUCCESS Get the supported suite list successfully. + @retval EFI_INVALID_PARAMETER No Nic found or supplicant is NULL. + +**/ +EFI_STATUS +WifiMgrGetSupportedSuites ( + IN WIFI_MGR_DEVICE_DATA *Nic + ); + +/** + Clean secrets from a network profile. + + @param[in] Profile The profile to be cleanned. + +**/ +VOID +WifiMgrCleanProfileSecrets ( + IN WIFI_MGR_NETWORK_PROFILE *Profile + ); + +/** + Free all network profiles in a profile list. + + @param[in] ProfileList The profile list to be freed. + +**/ +VOID +WifiMgrFreeProfileList ( + IN LIST_ENTRY *ProfileList + ); + +/** + Free user configured hidden network list. + + @param[in] HiddenList The hidden network list to be freed. + +**/ +VOID +WifiMgrFreeHiddenList ( + IN LIST_ENTRY *HiddenList + ); + +/** + Free the resources of a config token. + + @param[in] ConfigToken The config token to be freed. + +**/ +VOID +WifiMgrFreeToken ( + IN WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken + ); + +/** + Free all tokens in a token list. + + @param[in] TokenList The token list to be freed. + +**/ +VOID +WifiMgrFreeTokenList ( + IN LIST_ENTRY *TokenList + ); + +#endif -- 2.16.2.windows.1