]>
Commit | Line | Data |
---|---|---|
90b24889 WF |
1 | /** @file\r |
2 | The Mac Connection2 Protocol adapter functions for WiFi Connection Manager.\r | |
3 | \r | |
e1eef3a8 | 4 | Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>\r |
90b24889 | 5 | \r |
ecf98fbc | 6 | SPDX-License-Identifier: BSD-2-Clause-Patent\r |
90b24889 WF |
7 | \r |
8 | **/\r | |
9 | \r | |
10 | #include "WifiConnectionMgrDxe.h"\r | |
11 | \r | |
d1050b9d | 12 | EFI_EAP_TYPE mEapAuthMethod[] = {\r |
90b24889 WF |
13 | EFI_EAP_TYPE_TTLS,\r |
14 | EFI_EAP_TYPE_PEAP,\r | |
15 | EFI_EAP_TYPE_EAPTLS\r | |
16 | };\r | |
17 | \r | |
d1050b9d | 18 | EFI_EAP_TYPE mEapSecondAuthMethod[] = {\r |
90b24889 WF |
19 | EFI_EAP_TYPE_MSCHAPV2\r |
20 | };\r | |
21 | \r | |
fe405f08 ZCW |
22 | UINT8 mWifiConnectionCount = 0;\r |
23 | \r | |
90b24889 WF |
24 | /**\r |
25 | The callback function for scan operation. This function updates networks\r | |
26 | according to the latest scan result, and trigger UI refresh.\r | |
27 | \r | |
28 | ASSERT when errors occur in config token.\r | |
29 | \r | |
30 | @param[in] Event The GetNetworks token receive event.\r | |
31 | @param[in] Context The context of the GetNetworks token.\r | |
32 | \r | |
33 | **/\r | |
34 | VOID\r | |
35 | EFIAPI\r | |
36 | WifiMgrOnScanFinished (\r | |
d1050b9d MK |
37 | IN EFI_EVENT Event,\r |
38 | IN VOID *Context\r | |
90b24889 WF |
39 | )\r |
40 | {\r | |
d1050b9d MK |
41 | EFI_STATUS Status;\r |
42 | WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;\r | |
43 | WIFI_MGR_DEVICE_DATA *Nic;\r | |
44 | WIFI_MGR_NETWORK_PROFILE *Profile;\r | |
45 | EFI_80211_NETWORK *Network;\r | |
46 | UINTN DataSize;\r | |
47 | EFI_80211_NETWORK_DESCRIPTION *NetworkDescription;\r | |
48 | EFI_80211_GET_NETWORKS_RESULT *Result;\r | |
49 | LIST_ENTRY *Entry;\r | |
50 | UINT8 SecurityType;\r | |
51 | BOOLEAN AKMSuiteSupported;\r | |
52 | BOOLEAN CipherSuiteSupported;\r | |
53 | CHAR8 *AsciiSSId;\r | |
54 | UINTN Index;\r | |
90b24889 WF |
55 | \r |
56 | ASSERT (Context != NULL);\r | |
57 | \r | |
d1050b9d | 58 | ConfigToken = (WIFI_MGR_MAC_CONFIG_TOKEN *)Context;\r |
90b24889 WF |
59 | ASSERT (ConfigToken->Nic != NULL);\r |
60 | ASSERT (ConfigToken->Type == TokenTypeGetNetworksToken);\r | |
61 | \r | |
62 | //\r | |
63 | // It is the GetNetworks token, set scan state to "ScanFinished"\r | |
64 | //\r | |
65 | ConfigToken->Nic->ScanState = WifiMgrScanFinished;\r | |
66 | \r | |
67 | ASSERT (ConfigToken->Token.GetNetworksToken != NULL);\r | |
68 | Result = ConfigToken->Token.GetNetworksToken->Result;\r | |
69 | Nic = ConfigToken->Nic;\r | |
70 | \r | |
71 | //\r | |
72 | // Clean previous result, and update network list according to the scan result\r | |
73 | //\r | |
d1050b9d | 74 | Nic->AvailableCount = 0;\r |
90b24889 WF |
75 | \r |
76 | NET_LIST_FOR_EACH (Entry, &Nic->ProfileList) {\r | |
d1050b9d MK |
77 | Profile = NET_LIST_USER_STRUCT_S (\r |
78 | Entry,\r | |
79 | WIFI_MGR_NETWORK_PROFILE,\r | |
80 | Link,\r | |
81 | WIFI_MGR_PROFILE_SIGNATURE\r | |
82 | );\r | |
90b24889 WF |
83 | Profile->IsAvailable = FALSE;\r |
84 | }\r | |
85 | \r | |
86 | if (Result == NULL) {\r | |
87 | gBS->SignalEvent (Nic->Private->NetworkListRefreshEvent);\r | |
d1050b9d | 88 | WifiMgrFreeToken (ConfigToken);\r |
90b24889 WF |
89 | return;\r |
90 | }\r | |
91 | \r | |
d1050b9d | 92 | for (Index = 0; Index < Result->NumOfNetworkDesc; Index++) {\r |
90b24889 WF |
93 | NetworkDescription = Result->NetworkDesc + Index;\r |
94 | if (NetworkDescription == NULL) {\r | |
95 | continue;\r | |
96 | }\r | |
97 | \r | |
98 | Network = &NetworkDescription->Network;\r | |
d1050b9d | 99 | if ((Network == NULL) || (Network->SSId.SSIdLen == 0)) {\r |
90b24889 WF |
100 | continue;\r |
101 | }\r | |
102 | \r | |
103 | Status = WifiMgrCheckRSN (\r | |
104 | Network->AKMSuite,\r | |
105 | Network->CipherSuite,\r | |
106 | Nic,\r | |
107 | &SecurityType,\r | |
108 | &AKMSuiteSupported,\r | |
109 | &CipherSuiteSupported\r | |
110 | );\r | |
111 | if (EFI_ERROR (Status)) {\r | |
d1050b9d MK |
112 | SecurityType = SECURITY_TYPE_UNKNOWN;\r |
113 | AKMSuiteSupported = FALSE;\r | |
114 | CipherSuiteSupported = FALSE;\r | |
90b24889 WF |
115 | }\r |
116 | \r | |
d1050b9d | 117 | AsciiSSId = (CHAR8 *)AllocateZeroPool (sizeof (CHAR8) * (Network->SSId.SSIdLen + 1));\r |
90b24889 WF |
118 | if (AsciiSSId == NULL) {\r |
119 | continue;\r | |
120 | }\r | |
d1050b9d MK |
121 | \r |
122 | CopyMem (AsciiSSId, (CHAR8 *)Network->SSId.SSId, sizeof (CHAR8) * Network->SSId.SSIdLen);\r | |
90b24889 WF |
123 | *(AsciiSSId + Network->SSId.SSIdLen) = '\0';\r |
124 | \r | |
125 | Profile = WifiMgrGetProfileByAsciiSSId (AsciiSSId, SecurityType, &Nic->ProfileList);\r | |
126 | if (Profile == NULL) {\r | |
90b24889 WF |
127 | if (Nic->MaxProfileIndex >= NETWORK_LIST_COUNT_MAX) {\r |
128 | FreePool (AsciiSSId);\r | |
129 | continue;\r | |
130 | }\r | |
131 | \r | |
132 | //\r | |
133 | // Create a new profile\r | |
134 | //\r | |
135 | Profile = AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));\r | |
136 | if (Profile == NULL) {\r | |
137 | FreePool (AsciiSSId);\r | |
138 | continue;\r | |
139 | }\r | |
d1050b9d | 140 | \r |
90b24889 WF |
141 | Profile->Signature = WIFI_MGR_PROFILE_SIGNATURE;\r |
142 | Profile->NicIndex = Nic->NicIndex;\r | |
143 | Profile->ProfileIndex = Nic->MaxProfileIndex + 1;\r | |
144 | AsciiStrToUnicodeStrS (AsciiSSId, Profile->SSId, SSID_STORAGE_SIZE);\r | |
145 | InsertTailList (&Nic->ProfileList, &Profile->Link);\r | |
d1050b9d | 146 | Nic->MaxProfileIndex++;\r |
90b24889 | 147 | }\r |
d1050b9d | 148 | \r |
90b24889 WF |
149 | FreePool (AsciiSSId);\r |
150 | \r | |
151 | //\r | |
d1050b9d MK |
152 | // May receive duplicate networks in scan results, check if it has already\r |
153 | // been processed.\r | |
90b24889 WF |
154 | //\r |
155 | if (!Profile->IsAvailable) {\r | |
90b24889 WF |
156 | Profile->IsAvailable = TRUE;\r |
157 | Profile->SecurityType = SecurityType;\r | |
158 | Profile->AKMSuiteSupported = AKMSuiteSupported;\r | |
159 | Profile->CipherSuiteSupported = CipherSuiteSupported;\r | |
160 | Profile->NetworkQuality = NetworkDescription->NetworkQuality;\r | |
d1050b9d | 161 | Nic->AvailableCount++;\r |
90b24889 WF |
162 | \r |
163 | //\r | |
d1050b9d | 164 | // Copy BSSType and SSId\r |
90b24889 | 165 | //\r |
d1050b9d | 166 | CopyMem (&Profile->Network, Network, sizeof (EFI_80211_NETWORK));\r |
90b24889 WF |
167 | \r |
168 | //\r | |
d1050b9d | 169 | // Copy AKMSuite list\r |
90b24889 WF |
170 | //\r |
171 | if (Network->AKMSuite != NULL) {\r | |
90b24889 WF |
172 | if (Network->AKMSuite->AKMSuiteCount == 0) {\r |
173 | DataSize = sizeof (EFI_80211_AKM_SUITE_SELECTOR);\r | |
174 | } else {\r | |
175 | DataSize = sizeof (EFI_80211_AKM_SUITE_SELECTOR) + sizeof (EFI_80211_SUITE_SELECTOR)\r | |
d1050b9d | 176 | * (Network->AKMSuite->AKMSuiteCount - 1);\r |
90b24889 | 177 | }\r |
d1050b9d MK |
178 | \r |
179 | Profile->Network.AKMSuite = (EFI_80211_AKM_SUITE_SELECTOR *)AllocateZeroPool (DataSize);\r | |
90b24889 WF |
180 | if (Profile->Network.AKMSuite == NULL) {\r |
181 | continue;\r | |
182 | }\r | |
d1050b9d | 183 | \r |
90b24889 WF |
184 | CopyMem (Profile->Network.AKMSuite, Network->AKMSuite, DataSize);\r |
185 | }\r | |
186 | \r | |
187 | //\r | |
d1050b9d | 188 | // Copy CipherSuite list\r |
90b24889 WF |
189 | //\r |
190 | if (Network->CipherSuite != NULL) {\r | |
90b24889 WF |
191 | if (Network->CipherSuite->CipherSuiteCount == 0) {\r |
192 | DataSize = sizeof (EFI_80211_CIPHER_SUITE_SELECTOR);\r | |
193 | } else {\r | |
194 | DataSize = sizeof (EFI_80211_CIPHER_SUITE_SELECTOR) + sizeof (EFI_80211_SUITE_SELECTOR)\r | |
d1050b9d | 195 | * (Network->CipherSuite->CipherSuiteCount - 1);\r |
90b24889 | 196 | }\r |
d1050b9d MK |
197 | \r |
198 | Profile->Network.CipherSuite = (EFI_80211_CIPHER_SUITE_SELECTOR *)AllocateZeroPool (DataSize);\r | |
90b24889 WF |
199 | if (Profile->Network.CipherSuite == NULL) {\r |
200 | continue;\r | |
201 | }\r | |
d1050b9d | 202 | \r |
90b24889 WF |
203 | CopyMem (Profile->Network.CipherSuite, Network->CipherSuite, DataSize);\r |
204 | }\r | |
205 | } else {\r | |
206 | //\r | |
207 | // A duplicate network, update signal quality\r | |
208 | //\r | |
209 | if (Profile->NetworkQuality < NetworkDescription->NetworkQuality) {\r | |
210 | Profile->NetworkQuality = NetworkDescription->NetworkQuality;\r | |
211 | }\r | |
d1050b9d | 212 | \r |
90b24889 WF |
213 | continue;\r |
214 | }\r | |
215 | }\r | |
216 | \r | |
90b24889 WF |
217 | gBS->SignalEvent (Nic->Private->NetworkListRefreshEvent);\r |
218 | \r | |
219 | //\r | |
220 | // The current connected network should always be available until disconnection\r | |
221 | // happens in Wifi FW layer, even when it is not in this time's scan result.\r | |
222 | //\r | |
d1050b9d | 223 | if ((Nic->ConnectState == WifiMgrConnectedToAp) && (Nic->CurrentOperateNetwork != NULL)) {\r |
90b24889 WF |
224 | if (!Nic->CurrentOperateNetwork->IsAvailable) {\r |
225 | Nic->CurrentOperateNetwork->IsAvailable = TRUE;\r | |
d1050b9d | 226 | Nic->AvailableCount++;\r |
90b24889 WF |
227 | }\r |
228 | }\r | |
229 | \r | |
d1050b9d | 230 | WifiMgrFreeToken (ConfigToken);\r |
90b24889 WF |
231 | }\r |
232 | \r | |
233 | /**\r | |
234 | Start scan operation, and send out a token to collect available networks.\r | |
235 | \r | |
236 | @param[in] Nic Pointer to the device data of the selected NIC.\r | |
237 | \r | |
238 | @retval EFI_SUCCESS The operation is completed.\r | |
239 | @retval EFI_ALREADY_STARTED A former scan operation is already ongoing.\r | |
240 | @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r | |
241 | @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r | |
242 | @retval Other Errors Return errors when getting networks from low layer.\r | |
243 | \r | |
244 | **/\r | |
245 | EFI_STATUS\r | |
246 | WifiMgrStartScan (\r | |
d1050b9d | 247 | IN WIFI_MGR_DEVICE_DATA *Nic\r |
90b24889 WF |
248 | )\r |
249 | {\r | |
d1050b9d MK |
250 | EFI_STATUS Status;\r |
251 | EFI_TPL OldTpl;\r | |
252 | WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;\r | |
253 | EFI_80211_GET_NETWORKS_TOKEN *GetNetworksToken;\r | |
254 | UINT32 HiddenSSIdIndex;\r | |
255 | UINT32 HiddenSSIdCount;\r | |
256 | EFI_80211_SSID *HiddenSSIdList;\r | |
257 | WIFI_HIDDEN_NETWORK_DATA *HiddenNetwork;\r | |
258 | LIST_ENTRY *Entry;\r | |
259 | \r | |
260 | if ((Nic == NULL) || (Nic->Wmp == NULL)) {\r | |
90b24889 WF |
261 | return EFI_INVALID_PARAMETER;\r |
262 | }\r | |
263 | \r | |
264 | if (Nic->ScanState == WifiMgrScanning) {\r | |
265 | return EFI_ALREADY_STARTED;\r | |
266 | }\r | |
267 | \r | |
268 | Nic->ScanState = WifiMgrScanning;\r | |
269 | OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r | |
270 | Status = EFI_SUCCESS;\r | |
271 | HiddenSSIdList = NULL;\r | |
272 | HiddenSSIdCount = Nic->Private->HiddenNetworkCount;\r | |
273 | HiddenSSIdIndex = 0;\r | |
274 | \r | |
275 | //\r | |
d1050b9d | 276 | // create a new get network token\r |
90b24889 | 277 | //\r |
d1050b9d | 278 | ConfigToken = AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN));\r |
90b24889 WF |
279 | if (ConfigToken == NULL) {\r |
280 | gBS->RestoreTPL (OldTpl);\r | |
281 | return EFI_OUT_OF_RESOURCES;\r | |
282 | }\r | |
283 | \r | |
d1050b9d MK |
284 | ConfigToken->Type = TokenTypeGetNetworksToken;\r |
285 | ConfigToken->Nic = Nic;\r | |
90b24889 WF |
286 | ConfigToken->Token.GetNetworksToken = AllocateZeroPool (sizeof (EFI_80211_GET_NETWORKS_TOKEN));\r |
287 | if (ConfigToken->Token.GetNetworksToken == NULL) {\r | |
d1050b9d | 288 | WifiMgrFreeToken (ConfigToken);\r |
90b24889 WF |
289 | gBS->RestoreTPL (OldTpl);\r |
290 | return EFI_OUT_OF_RESOURCES;\r | |
291 | }\r | |
d1050b9d | 292 | \r |
90b24889 WF |
293 | GetNetworksToken = ConfigToken->Token.GetNetworksToken;\r |
294 | \r | |
295 | //\r | |
296 | // There are some hidden networks to scan, add them into scan list\r | |
297 | //\r | |
298 | if (HiddenSSIdCount > 0) {\r | |
d1050b9d | 299 | HiddenSSIdList = AllocateZeroPool (HiddenSSIdCount * sizeof (EFI_80211_SSID));\r |
90b24889 | 300 | if (HiddenSSIdList == NULL) {\r |
d1050b9d | 301 | WifiMgrFreeToken (ConfigToken);\r |
90b24889 WF |
302 | gBS->RestoreTPL (OldTpl);\r |
303 | return EFI_OUT_OF_RESOURCES;\r | |
304 | }\r | |
305 | \r | |
306 | HiddenSSIdIndex = 0;\r | |
307 | NET_LIST_FOR_EACH (Entry, &Nic->Private->HiddenNetworkList) {\r | |
d1050b9d MK |
308 | HiddenNetwork = NET_LIST_USER_STRUCT_S (\r |
309 | Entry,\r | |
310 | WIFI_HIDDEN_NETWORK_DATA,\r | |
311 | Link,\r | |
312 | WIFI_MGR_HIDDEN_NETWORK_SIGNATURE\r | |
313 | );\r | |
314 | HiddenSSIdList[HiddenSSIdIndex].SSIdLen = (UINT8)StrLen (HiddenNetwork->SSId);\r | |
315 | UnicodeStrToAsciiStrS (\r | |
316 | HiddenNetwork->SSId,\r | |
317 | (CHAR8 *)HiddenSSIdList[HiddenSSIdIndex].SSId,\r | |
318 | SSID_STORAGE_SIZE\r | |
319 | );\r | |
320 | HiddenSSIdIndex++;\r | |
90b24889 | 321 | }\r |
d1050b9d MK |
322 | GetNetworksToken->Data = AllocateZeroPool (\r |
323 | sizeof (EFI_80211_GET_NETWORKS_DATA) +\r | |
324 | (HiddenSSIdCount - 1) * sizeof (EFI_80211_SSID)\r | |
325 | );\r | |
90b24889 WF |
326 | if (GetNetworksToken->Data == NULL) {\r |
327 | FreePool (HiddenSSIdList);\r | |
d1050b9d | 328 | WifiMgrFreeToken (ConfigToken);\r |
90b24889 WF |
329 | gBS->RestoreTPL (OldTpl);\r |
330 | return EFI_OUT_OF_RESOURCES;\r | |
331 | }\r | |
d1050b9d | 332 | \r |
90b24889 | 333 | GetNetworksToken->Data->NumOfSSID = HiddenSSIdCount;\r |
d1050b9d MK |
334 | CopyMem (GetNetworksToken->Data->SSIDList, HiddenSSIdList, HiddenSSIdCount * sizeof (EFI_80211_SSID));\r |
335 | FreePool (HiddenSSIdList);\r | |
90b24889 | 336 | } else {\r |
90b24889 WF |
337 | GetNetworksToken->Data = AllocateZeroPool (sizeof (EFI_80211_GET_NETWORKS_DATA));\r |
338 | if (GetNetworksToken->Data == NULL) {\r | |
d1050b9d | 339 | WifiMgrFreeToken (ConfigToken);\r |
90b24889 WF |
340 | gBS->RestoreTPL (OldTpl);\r |
341 | return EFI_OUT_OF_RESOURCES;\r | |
342 | }\r | |
343 | \r | |
344 | GetNetworksToken->Data->NumOfSSID = 0;\r | |
345 | }\r | |
346 | \r | |
347 | //\r | |
d1050b9d | 348 | // Create a handle when scan process ends\r |
90b24889 WF |
349 | //\r |
350 | Status = gBS->CreateEvent (\r | |
351 | EVT_NOTIFY_SIGNAL,\r | |
352 | TPL_CALLBACK,\r | |
353 | WifiMgrOnScanFinished,\r | |
354 | ConfigToken,\r | |
355 | &GetNetworksToken->Event\r | |
356 | );\r | |
357 | if (EFI_ERROR (Status)) {\r | |
d1050b9d | 358 | WifiMgrFreeToken (ConfigToken);\r |
90b24889 WF |
359 | gBS->RestoreTPL (OldTpl);\r |
360 | return Status;\r | |
361 | }\r | |
362 | \r | |
363 | //\r | |
d1050b9d | 364 | // Start scan ...\r |
90b24889 WF |
365 | //\r |
366 | Status = Nic->Wmp->GetNetworks (Nic->Wmp, GetNetworksToken);\r | |
367 | if (EFI_ERROR (Status)) {\r | |
d1050b9d MK |
368 | Nic->ScanState = WifiMgrScanFinished;\r |
369 | WifiMgrFreeToken (ConfigToken);\r | |
90b24889 WF |
370 | gBS->RestoreTPL (OldTpl);\r |
371 | return Status;\r | |
372 | }\r | |
373 | \r | |
374 | gBS->RestoreTPL (OldTpl);\r | |
375 | return EFI_SUCCESS;\r | |
376 | }\r | |
377 | \r | |
378 | /**\r | |
379 | Configure password to supplicant before connecting to a secured network.\r | |
380 | \r | |
381 | @param[in] Nic Pointer to the device data of the selected NIC.\r | |
382 | @param[in] Profile The target network to be connected.\r | |
383 | \r | |
384 | @retval EFI_SUCCESS The operation is completed.\r | |
385 | @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r | |
386 | @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r | |
387 | @retval EFI_NOT_FOUND No valid password is found to configure.\r | |
388 | @retval Other Errors Returned errors when setting data to supplicant.\r | |
389 | \r | |
390 | **/\r | |
391 | EFI_STATUS\r | |
392 | WifiMgrConfigPassword (\r | |
d1050b9d MK |
393 | IN WIFI_MGR_DEVICE_DATA *Nic,\r |
394 | IN WIFI_MGR_NETWORK_PROFILE *Profile\r | |
90b24889 WF |
395 | )\r |
396 | {\r | |
d1050b9d MK |
397 | EFI_STATUS Status;\r |
398 | EFI_SUPPLICANT_PROTOCOL *Supplicant;\r | |
399 | EFI_80211_SSID SSId;\r | |
400 | UINT8 *AsciiPassword;\r | |
90b24889 | 401 | \r |
d1050b9d | 402 | if ((Nic == NULL) || (Nic->Supplicant == NULL) || (Profile == NULL)) {\r |
90b24889 WF |
403 | return EFI_INVALID_PARAMETER;\r |
404 | }\r | |
d1050b9d | 405 | \r |
90b24889 WF |
406 | Supplicant = Nic->Supplicant;\r |
407 | //\r | |
d1050b9d | 408 | // Set SSId to supplicant\r |
90b24889 WF |
409 | //\r |
410 | SSId.SSIdLen = Profile->Network.SSId.SSIdLen;\r | |
d1050b9d MK |
411 | CopyMem (SSId.SSId, Profile->Network.SSId.SSId, sizeof (Profile->Network.SSId.SSId));\r |
412 | Status = Supplicant->SetData (\r | |
413 | Supplicant,\r | |
414 | EfiSupplicant80211TargetSSIDName,\r | |
415 | (VOID *)&SSId,\r | |
416 | sizeof (EFI_80211_SSID)\r | |
417 | );\r | |
418 | if (EFI_ERROR (Status)) {\r | |
90b24889 WF |
419 | return Status;\r |
420 | }\r | |
421 | \r | |
422 | //\r | |
d1050b9d | 423 | // Set password to supplicant\r |
90b24889 WF |
424 | //\r |
425 | if (StrLen (Profile->Password) < PASSWORD_MIN_LEN) {\r | |
426 | return EFI_NOT_FOUND;\r | |
427 | }\r | |
d1050b9d | 428 | \r |
fe405f08 ZCW |
429 | if (StrLen (Profile->Password) >= PASSWORD_STORAGE_SIZE) {\r |
430 | ASSERT (EFI_INVALID_PARAMETER);\r | |
431 | return EFI_INVALID_PARAMETER;\r | |
432 | }\r | |
433 | \r | |
434 | AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof (CHAR8));\r | |
90b24889 WF |
435 | if (AsciiPassword == NULL) {\r |
436 | return EFI_OUT_OF_RESOURCES;\r | |
437 | }\r | |
d1050b9d | 438 | \r |
fe405f08 ZCW |
439 | Status = UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword, (StrLen (Profile->Password) + 1));\r |
440 | if (!EFI_ERROR (Status)) {\r | |
441 | Status = Supplicant->SetData (\r | |
442 | Supplicant,\r | |
443 | EfiSupplicant80211PskPassword,\r | |
444 | AsciiPassword,\r | |
445 | (StrLen (Profile->Password) + 1) * sizeof (CHAR8)\r | |
446 | );\r | |
447 | }\r | |
448 | \r | |
d1050b9d MK |
449 | ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *)AsciiPassword) + 1);\r |
450 | FreePool (AsciiPassword);\r | |
90b24889 WF |
451 | \r |
452 | return Status;\r | |
453 | }\r | |
454 | \r | |
455 | /**\r | |
456 | Conduct EAP configuration to supplicant before connecting to a EAP network.\r | |
457 | Current WiFi Connection Manager only supports three kinds of EAP networks:\r | |
458 | 1). EAP-TLS (Two-Way Authentication is required in our implementation)\r | |
459 | 2). EAP-TTLS/MSCHAPv2 (One-Way Authentication is required in our implementation)\r | |
460 | 3). PEAPv0/MSCHAPv2 (One-Way Authentication is required in our implementation)\r | |
461 | \r | |
462 | @param[in] Nic Pointer to the device data of the selected NIC.\r | |
463 | @param[in] Profile The target network to be connected.\r | |
464 | \r | |
465 | @retval EFI_SUCCESS The operation is completed.\r | |
466 | @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r | |
467 | @retval EFI_UNSUPPORTED The expected EAP method is not supported.\r | |
468 | @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r | |
469 | @retval Other Errors Returned errors when setting data to supplicant.\r | |
470 | \r | |
471 | **/\r | |
472 | EFI_STATUS\r | |
473 | WifiMgrConfigEap (\r | |
d1050b9d MK |
474 | IN WIFI_MGR_DEVICE_DATA *Nic,\r |
475 | IN WIFI_MGR_NETWORK_PROFILE *Profile\r | |
90b24889 WF |
476 | )\r |
477 | {\r | |
fe405f08 ZCW |
478 | EFI_STATUS Status;\r |
479 | EDKII_WIFI_PROFILE_SYNC_PROTOCOL *WiFiProfileSyncProtocol;\r | |
480 | EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig;\r | |
481 | EFI_EAP_TYPE EapAuthMethod;\r | |
482 | EFI_EAP_TYPE EapSecondAuthMethod;\r | |
483 | EFI_EAP_TYPE *AuthMethodList;\r | |
484 | CHAR8 *Identity;\r | |
485 | UINTN IdentitySize;\r | |
486 | CHAR16 *Password;\r | |
487 | UINTN PasswordSize;\r | |
488 | UINTN EncryptPasswordLen;\r | |
489 | CHAR8 *AsciiEncryptPassword;\r | |
490 | UINTN AuthMethodListSize;\r | |
491 | UINTN Index;\r | |
d1050b9d MK |
492 | \r |
493 | if ((Nic == NULL) || (Nic->EapConfig == NULL) || (Profile == NULL)) {\r | |
90b24889 WF |
494 | return EFI_INVALID_PARAMETER;\r |
495 | }\r | |
d1050b9d | 496 | \r |
90b24889 WF |
497 | EapConfig = Nic->EapConfig;\r |
498 | \r | |
499 | if (Profile->EapAuthMethod >= EAP_AUTH_METHOD_MAX) {\r | |
500 | return EFI_INVALID_PARAMETER;\r | |
501 | }\r | |
d1050b9d | 502 | \r |
90b24889 WF |
503 | EapAuthMethod = mEapAuthMethod[Profile->EapAuthMethod];\r |
504 | \r | |
505 | if (EapAuthMethod != EFI_EAP_TYPE_EAPTLS) {\r | |
506 | if (Profile->EapSecondAuthMethod >= EAP_SEAUTH_METHOD_MAX) {\r | |
507 | return EFI_INVALID_PARAMETER;\r | |
508 | }\r | |
d1050b9d | 509 | \r |
90b24889 WF |
510 | EapSecondAuthMethod = mEapSecondAuthMethod[Profile->EapSecondAuthMethod];\r |
511 | }\r | |
512 | \r | |
513 | //\r | |
d1050b9d | 514 | // The first time to get Supported Auth Method list, return the size.\r |
90b24889 | 515 | //\r |
d1050b9d MK |
516 | AuthMethodListSize = 0;\r |
517 | AuthMethodList = NULL;\r | |
518 | Status = EapConfig->GetData (\r | |
519 | EapConfig,\r | |
520 | EFI_EAP_TYPE_ATTRIBUTE,\r | |
521 | EfiEapConfigEapSupportedAuthMethod,\r | |
522 | (VOID *)AuthMethodList,\r | |
523 | &AuthMethodListSize\r | |
524 | );\r | |
90b24889 WF |
525 | if (Status == EFI_SUCCESS) {\r |
526 | //\r | |
d1050b9d | 527 | // No Supported Eap Auth Method\r |
90b24889 WF |
528 | //\r |
529 | return EFI_UNSUPPORTED;\r | |
530 | } else if (Status != EFI_BUFFER_TOO_SMALL) {\r | |
531 | return Status;\r | |
532 | }\r | |
533 | \r | |
534 | //\r | |
535 | // The second time to get Supported Auth Method list, return the list.\r | |
536 | // In current design, only EAPTLS, TTLS and PEAP are supported\r | |
537 | //\r | |
d1050b9d | 538 | AuthMethodList = (EFI_EAP_TYPE *)AllocateZeroPool (AuthMethodListSize);\r |
90b24889 WF |
539 | if (AuthMethodList == NULL) {\r |
540 | return EFI_OUT_OF_RESOURCES;\r | |
541 | }\r | |
d1050b9d MK |
542 | \r |
543 | Status = EapConfig->GetData (\r | |
544 | EapConfig,\r | |
545 | EFI_EAP_TYPE_ATTRIBUTE,\r | |
546 | EfiEapConfigEapSupportedAuthMethod,\r | |
547 | (VOID *)AuthMethodList,\r | |
548 | &AuthMethodListSize\r | |
549 | );\r | |
90b24889 WF |
550 | if (EFI_ERROR (Status)) {\r |
551 | FreePool (AuthMethodList);\r | |
552 | return Status;\r | |
553 | }\r | |
554 | \r | |
555 | //\r | |
d1050b9d | 556 | // Check if EapAuthMethod is in supported Auth Method list, if found, skip the loop.\r |
90b24889 | 557 | //\r |
d1050b9d | 558 | for (Index = 0; Index < AuthMethodListSize / sizeof (EFI_EAP_TYPE); Index++) {\r |
90b24889 WF |
559 | if (EapAuthMethod == AuthMethodList[Index]) {\r |
560 | break;\r | |
561 | }\r | |
562 | }\r | |
d1050b9d | 563 | \r |
90b24889 WF |
564 | if (Index == AuthMethodListSize / sizeof (EFI_EAP_TYPE)) {\r |
565 | FreePool (AuthMethodList);\r | |
566 | return EFI_UNSUPPORTED;\r | |
567 | }\r | |
d1050b9d | 568 | \r |
90b24889 WF |
569 | FreePool (AuthMethodList);\r |
570 | \r | |
571 | //\r | |
572 | // Set Identity to Eap peer, Mandatory field for PEAP and TTLS\r | |
573 | //\r | |
574 | if (StrLen (Profile->EapIdentity) > 0) {\r | |
d1050b9d MK |
575 | IdentitySize = sizeof (CHAR8) * (StrLen (Profile->EapIdentity) + 1);\r |
576 | Identity = AllocateZeroPool (IdentitySize);\r | |
90b24889 WF |
577 | if (Identity == NULL) {\r |
578 | return EFI_OUT_OF_RESOURCES;\r | |
579 | }\r | |
d1050b9d | 580 | \r |
fe405f08 ZCW |
581 | Status = gBS->LocateProtocol (&gEdkiiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);\r |
582 | if (!EFI_ERROR (Status)) {\r | |
583 | CopyMem (Identity, &Profile->EapIdentity, IdentitySize);\r | |
584 | } else {\r | |
585 | UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);\r | |
586 | }\r | |
587 | \r | |
d1050b9d MK |
588 | Status = EapConfig->SetData (\r |
589 | EapConfig,\r | |
590 | EFI_EAP_TYPE_IDENTITY,\r | |
591 | EfiEapConfigIdentityString,\r | |
592 | (VOID *)Identity,\r | |
593 | IdentitySize - 1\r | |
594 | );\r | |
595 | if (EFI_ERROR (Status)) {\r | |
90b24889 WF |
596 | FreePool (Identity);\r |
597 | return Status;\r | |
598 | }\r | |
d1050b9d | 599 | \r |
90b24889 WF |
600 | FreePool (Identity);\r |
601 | } else {\r | |
602 | if (EapAuthMethod != EFI_EAP_TYPE_EAPTLS) {\r | |
603 | return EFI_INVALID_PARAMETER;\r | |
604 | }\r | |
605 | }\r | |
606 | \r | |
607 | //\r | |
d1050b9d | 608 | // Set Auth Method to Eap peer, Mandatory field\r |
90b24889 | 609 | //\r |
d1050b9d MK |
610 | Status = EapConfig->SetData (\r |
611 | EapConfig,\r | |
612 | EFI_EAP_TYPE_ATTRIBUTE,\r | |
613 | EfiEapConfigEapAuthMethod,\r | |
614 | (VOID *)&EapAuthMethod,\r | |
615 | sizeof (EapAuthMethod)\r | |
616 | );\r | |
617 | if (EFI_ERROR (Status)) {\r | |
90b24889 WF |
618 | return Status;\r |
619 | }\r | |
620 | \r | |
d1050b9d MK |
621 | if ((EapAuthMethod == EFI_EAP_TYPE_TTLS) || (EapAuthMethod == EFI_EAP_TYPE_PEAP)) {\r |
622 | Status = EapConfig->SetData (\r | |
623 | EapConfig,\r | |
624 | EapAuthMethod,\r | |
625 | EfiEapConfigEap2ndAuthMethod,\r | |
626 | (VOID *)&EapSecondAuthMethod,\r | |
627 | sizeof (EapSecondAuthMethod)\r | |
628 | );\r | |
629 | if (EFI_ERROR (Status)) {\r | |
90b24889 WF |
630 | return Status;\r |
631 | }\r | |
632 | \r | |
633 | //\r | |
634 | // Set Password to Eap peer\r | |
635 | //\r | |
636 | if (StrLen (Profile->EapPassword) < PASSWORD_MIN_LEN) {\r | |
90b24889 WF |
637 | DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Error: No Eap Password for Network: %s.\n", Profile->SSId));\r |
638 | return EFI_INVALID_PARAMETER;\r | |
639 | }\r | |
640 | \r | |
641 | PasswordSize = sizeof (CHAR16) * (StrLen (Profile->EapPassword) + 1);\r | |
d1050b9d | 642 | Password = AllocateZeroPool (PasswordSize);\r |
90b24889 WF |
643 | if (Password == NULL) {\r |
644 | return EFI_OUT_OF_RESOURCES;\r | |
645 | }\r | |
d1050b9d MK |
646 | \r |
647 | StrCpyS (Password, PasswordSize, Profile->EapPassword);\r | |
648 | Status = EapConfig->SetData (\r | |
649 | EapConfig,\r | |
650 | EFI_EAP_TYPE_MSCHAPV2,\r | |
651 | EfiEapConfigEapMSChapV2Password,\r | |
652 | (VOID *)Password,\r | |
653 | PasswordSize\r | |
654 | );\r | |
90b24889 WF |
655 | ZeroMem (Password, PasswordSize);\r |
656 | FreePool (Password);\r | |
657 | if (EFI_ERROR (Status)) {\r | |
658 | return Status;\r | |
659 | }\r | |
660 | \r | |
661 | //\r | |
d1050b9d | 662 | // If CA cert is required, set it to Eap peer\r |
90b24889 WF |
663 | //\r |
664 | if (Profile->CACertData != NULL) {\r | |
d1050b9d MK |
665 | Status = EapConfig->SetData (\r |
666 | EapConfig,\r | |
667 | EapAuthMethod,\r | |
668 | EfiEapConfigEapTlsCACert,\r | |
669 | Profile->CACertData,\r | |
670 | Profile->CACertSize\r | |
671 | );\r | |
672 | if (EFI_ERROR (Status)) {\r | |
90b24889 WF |
673 | return Status;\r |
674 | }\r | |
675 | } else {\r | |
676 | return EFI_INVALID_PARAMETER;\r | |
677 | }\r | |
678 | } else if (EapAuthMethod == EFI_EAP_TYPE_EAPTLS) {\r | |
90b24889 | 679 | //\r |
d1050b9d | 680 | // Set CA cert to Eap peer\r |
90b24889 WF |
681 | //\r |
682 | if (Profile->CACertData == NULL) {\r | |
683 | return EFI_INVALID_PARAMETER;\r | |
684 | }\r | |
d1050b9d MK |
685 | \r |
686 | Status = EapConfig->SetData (\r | |
687 | EapConfig,\r | |
688 | EFI_EAP_TYPE_EAPTLS,\r | |
689 | EfiEapConfigEapTlsCACert,\r | |
690 | Profile->CACertData,\r | |
691 | Profile->CACertSize\r | |
692 | );\r | |
693 | if (EFI_ERROR (Status)) {\r | |
90b24889 WF |
694 | return Status;\r |
695 | }\r | |
696 | \r | |
697 | //\r | |
d1050b9d | 698 | // Set Client cert to Eap peer\r |
90b24889 WF |
699 | //\r |
700 | if (Profile->ClientCertData == NULL) {\r | |
701 | return EFI_INVALID_PARAMETER;\r | |
702 | }\r | |
d1050b9d MK |
703 | \r |
704 | Status = EapConfig->SetData (\r | |
705 | EapConfig,\r | |
706 | EFI_EAP_TYPE_EAPTLS,\r | |
707 | EfiEapConfigEapTlsClientCert,\r | |
708 | Profile->ClientCertData,\r | |
709 | Profile->ClientCertSize\r | |
710 | );\r | |
711 | if (EFI_ERROR (Status)) {\r | |
90b24889 WF |
712 | return Status;\r |
713 | }\r | |
714 | \r | |
715 | //\r | |
d1050b9d | 716 | // Set Private key to Eap peer\r |
90b24889 WF |
717 | //\r |
718 | if (Profile->PrivateKeyData == NULL) {\r | |
90b24889 WF |
719 | DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Error: No Private Key for Network: %s.\n", Profile->SSId));\r |
720 | return EFI_INVALID_PARAMETER;\r | |
721 | }\r | |
722 | \r | |
d1050b9d MK |
723 | Status = EapConfig->SetData (\r |
724 | EapConfig,\r | |
725 | EFI_EAP_TYPE_EAPTLS,\r | |
726 | EfiEapConfigEapTlsClientPrivateKeyFile,\r | |
727 | Profile->PrivateKeyData,\r | |
728 | Profile->PrivateKeyDataSize\r | |
729 | );\r | |
730 | if (EFI_ERROR (Status)) {\r | |
90b24889 WF |
731 | return Status;\r |
732 | }\r | |
733 | \r | |
734 | if (StrLen (Profile->PrivateKeyPassword) > 0) {\r | |
d1050b9d MK |
735 | EncryptPasswordLen = StrLen (Profile->PrivateKeyPassword);\r |
736 | AsciiEncryptPassword = AllocateZeroPool (EncryptPasswordLen + 1);\r | |
90b24889 WF |
737 | if (AsciiEncryptPassword == NULL) {\r |
738 | return EFI_OUT_OF_RESOURCES;\r | |
739 | }\r | |
90b24889 | 740 | \r |
d1050b9d MK |
741 | UnicodeStrToAsciiStrS (Profile->PrivateKeyPassword, AsciiEncryptPassword, EncryptPasswordLen + 1);\r |
742 | Status = EapConfig->SetData (\r | |
743 | EapConfig,\r | |
744 | EFI_EAP_TYPE_EAPTLS,\r | |
745 | EfiEapConfigEapTlsClientPrivateKeyFilePassword,\r | |
746 | (VOID *)AsciiEncryptPassword,\r | |
747 | EncryptPasswordLen + 1\r | |
748 | );\r | |
749 | if (EFI_ERROR (Status)) {\r | |
90b24889 WF |
750 | ZeroMem (AsciiEncryptPassword, EncryptPasswordLen + 1);\r |
751 | FreePool (AsciiEncryptPassword);\r | |
752 | return Status;\r | |
753 | }\r | |
754 | \r | |
755 | ZeroMem (AsciiEncryptPassword, EncryptPasswordLen + 1);\r | |
756 | FreePool (AsciiEncryptPassword);\r | |
757 | }\r | |
758 | } else {\r | |
759 | return EFI_INVALID_PARAMETER;\r | |
760 | }\r | |
761 | \r | |
762 | return EFI_SUCCESS;\r | |
763 | }\r | |
764 | \r | |
765 | /**\r | |
766 | Get current link state from low layer.\r | |
767 | \r | |
768 | @param[in] Nic Pointer to the device data of the selected NIC.\r | |
769 | @param[out] LinkState The pointer to buffer to retrieve link state.\r | |
770 | \r | |
771 | @retval EFI_SUCCESS The operation is completed.\r | |
772 | @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r | |
773 | @retval EFI_UNSUPPORTED Adapter information protocol is not supported.\r | |
774 | @retval Other Errors Returned errors when retrieving link state from low layer.\r | |
775 | \r | |
776 | **/\r | |
777 | EFI_STATUS\r | |
778 | WifiMgrGetLinkState (\r | |
d1050b9d MK |
779 | IN WIFI_MGR_DEVICE_DATA *Nic,\r |
780 | OUT EFI_ADAPTER_INFO_MEDIA_STATE *LinkState\r | |
90b24889 WF |
781 | )\r |
782 | {\r | |
d1050b9d MK |
783 | EFI_STATUS Status;\r |
784 | EFI_TPL OldTpl;\r | |
785 | UINTN DataSize;\r | |
786 | EFI_ADAPTER_INFO_MEDIA_STATE *UndiState;\r | |
787 | EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;\r | |
90b24889 | 788 | \r |
d1050b9d | 789 | if ((Nic == NULL) || (LinkState == NULL)) {\r |
90b24889 WF |
790 | return EFI_INVALID_PARAMETER;\r |
791 | }\r | |
792 | \r | |
793 | OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r | |
794 | Status = gBS->OpenProtocol (\r | |
795 | Nic->ControllerHandle,\r | |
796 | &gEfiAdapterInformationProtocolGuid,\r | |
d1050b9d | 797 | (VOID **)&Aip,\r |
90b24889 WF |
798 | Nic->DriverHandle,\r |
799 | Nic->ControllerHandle,\r | |
800 | EFI_OPEN_PROTOCOL_GET_PROTOCOL\r | |
801 | );\r | |
802 | if (EFI_ERROR (Status)) {\r | |
803 | gBS->RestoreTPL (OldTpl);\r | |
804 | return EFI_UNSUPPORTED;\r | |
805 | }\r | |
806 | \r | |
d1050b9d | 807 | Status = Aip->GetInformation (\r |
90b24889 WF |
808 | Aip,\r |
809 | &gEfiAdapterInfoMediaStateGuid,\r | |
d1050b9d | 810 | (VOID **)&UndiState,\r |
90b24889 WF |
811 | &DataSize\r |
812 | );\r | |
813 | if (EFI_ERROR (Status)) {\r | |
814 | gBS->RestoreTPL (OldTpl);\r | |
815 | return Status;\r | |
816 | }\r | |
d1050b9d | 817 | \r |
90b24889 WF |
818 | gBS->RestoreTPL (OldTpl);\r |
819 | \r | |
820 | CopyMem (LinkState, UndiState, sizeof (EFI_ADAPTER_INFO_MEDIA_STATE));\r | |
821 | FreePool (UndiState);\r | |
822 | return EFI_SUCCESS;\r | |
823 | }\r | |
824 | \r | |
825 | /**\r | |
826 | Prepare configuration work before connecting to the target network.\r | |
827 | For WPA2 Personal networks, password should be checked; and for EAP networks, parameters\r | |
828 | are different for different networks.\r | |
829 | \r | |
830 | @param[in] Nic Pointer to the device data of the selected NIC.\r | |
831 | @param[in] Profile The target network to be connected.\r | |
832 | \r | |
833 | @retval EFI_SUCCESS The operation is completed.\r | |
834 | @retval EFI_UNSUPPORTED This network is not supported.\r | |
835 | @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r | |
836 | \r | |
837 | **/\r | |
838 | EFI_STATUS\r | |
839 | WifiMgrPrepareConnection (\r | |
d1050b9d MK |
840 | IN WIFI_MGR_DEVICE_DATA *Nic,\r |
841 | IN WIFI_MGR_NETWORK_PROFILE *Profile\r | |
90b24889 WF |
842 | )\r |
843 | {\r | |
d1050b9d MK |
844 | EFI_STATUS Status;\r |
845 | UINT8 SecurityType;\r | |
846 | BOOLEAN AKMSuiteSupported;\r | |
847 | BOOLEAN CipherSuiteSupported;\r | |
90b24889 | 848 | \r |
d1050b9d | 849 | if ((Profile == NULL) || (Nic == NULL)) {\r |
90b24889 WF |
850 | return EFI_INVALID_PARAMETER;\r |
851 | }\r | |
852 | \r | |
d1050b9d MK |
853 | Status = WifiMgrCheckRSN (\r |
854 | Profile->Network.AKMSuite,\r | |
855 | Profile->Network.CipherSuite,\r | |
856 | Nic,\r | |
857 | &SecurityType,\r | |
858 | &AKMSuiteSupported,\r | |
859 | &CipherSuiteSupported\r | |
860 | );\r | |
90b24889 WF |
861 | if (EFI_ERROR (Status)) {\r |
862 | return Status;\r | |
863 | }\r | |
864 | \r | |
865 | if (AKMSuiteSupported && CipherSuiteSupported) {\r | |
866 | switch (SecurityType) {\r | |
867 | case SECURITY_TYPE_WPA2_PERSONAL:\r | |
e1eef3a8 | 868 | case SECURITY_TYPE_WPA3_PERSONAL:\r |
90b24889 WF |
869 | \r |
870 | Status = WifiMgrConfigPassword (Nic, Profile);\r | |
871 | if (EFI_ERROR (Status)) {\r | |
872 | if (Status == EFI_NOT_FOUND) {\r | |
873 | if (Nic->OneTimeConnectRequest) {\r | |
874 | WifiMgrUpdateConnectMessage (Nic, FALSE, L"Connect Failed: Invalid Password!");\r | |
875 | }\r | |
876 | }\r | |
d1050b9d | 877 | \r |
90b24889 WF |
878 | return Status;\r |
879 | }\r | |
d1050b9d | 880 | \r |
90b24889 WF |
881 | break;\r |
882 | \r | |
883 | case SECURITY_TYPE_WPA2_ENTERPRISE:\r | |
e1eef3a8 | 884 | case SECURITY_TYPE_WPA3_ENTERPRISE:\r |
90b24889 WF |
885 | \r |
886 | Status = WifiMgrConfigEap (Nic, Profile);\r | |
887 | if (EFI_ERROR (Status)) {\r | |
888 | if (Status == EFI_INVALID_PARAMETER) {\r | |
889 | if (Nic->OneTimeConnectRequest) {\r | |
890 | WifiMgrUpdateConnectMessage (Nic, FALSE, L"Connect Failed: Invalid Configuration!");\r | |
891 | }\r | |
892 | }\r | |
d1050b9d | 893 | \r |
90b24889 WF |
894 | return Status;\r |
895 | }\r | |
d1050b9d | 896 | \r |
90b24889 WF |
897 | break;\r |
898 | \r | |
899 | case SECURITY_TYPE_NONE:\r | |
900 | break;\r | |
901 | \r | |
902 | default:\r | |
903 | return EFI_UNSUPPORTED;\r | |
904 | }\r | |
905 | } else {\r | |
906 | return EFI_UNSUPPORTED;\r | |
907 | }\r | |
908 | \r | |
909 | return EFI_SUCCESS;\r | |
910 | }\r | |
911 | \r | |
fe405f08 ZCW |
912 | /**\r |
913 | Will reset NiC data, get profile from profile sync driver, and send for\r | |
914 | another connection attempt.This function should not be called more than\r | |
915 | 3 times.\r | |
916 | \r | |
917 | @param[in] WiFiProfileSyncProtocol The target network profile to connect.\r | |
918 | \r | |
919 | @retval EFI_SUCCESS The operation is completed.\r | |
920 | @retval other Operation failure.\r | |
921 | \r | |
922 | **/\r | |
923 | EFI_STATUS\r | |
924 | ConnectionRetry (\r | |
925 | IN EDKII_WIFI_PROFILE_SYNC_PROTOCOL *WiFiProfileSyncProtocol\r | |
926 | )\r | |
927 | {\r | |
928 | EFI_STATUS Status;\r | |
929 | WIFI_MGR_DEVICE_DATA *Nic;\r | |
930 | EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL *Wmp;\r | |
931 | EFI_SUPPLICANT_PROTOCOL *Supplicant;\r | |
932 | EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig;\r | |
933 | \r | |
934 | Nic = NULL;\r | |
935 | \r | |
936 | Status = gBS->LocateProtocol (\r | |
937 | &gEfiWiFi2ProtocolGuid,\r | |
938 | NULL,\r | |
939 | (VOID **)&Wmp\r | |
940 | );\r | |
941 | if (EFI_ERROR (Status)) {\r | |
942 | return Status;\r | |
943 | }\r | |
944 | \r | |
945 | Status = gBS->LocateProtocol (\r | |
946 | &gEfiSupplicantProtocolGuid,\r | |
947 | NULL,\r | |
948 | (VOID **)&Supplicant\r | |
949 | );\r | |
950 | if (EFI_ERROR (Status)) {\r | |
951 | Supplicant = NULL;\r | |
952 | }\r | |
953 | \r | |
954 | Status = gBS->LocateProtocol (\r | |
955 | &gEfiEapConfigurationProtocolGuid,\r | |
956 | NULL,\r | |
957 | (VOID **)&EapConfig\r | |
958 | );\r | |
959 | if (EFI_ERROR (Status)) {\r | |
960 | EapConfig = NULL;\r | |
961 | }\r | |
962 | \r | |
963 | //\r | |
964 | // Initialize Nic device data\r | |
965 | //\r | |
966 | Nic = AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA));\r | |
967 | if (Nic == NULL) {\r | |
968 | Status = EFI_OUT_OF_RESOURCES;\r | |
969 | return Status;\r | |
970 | }\r | |
971 | \r | |
972 | Nic->Signature = WIFI_MGR_DEVICE_DATA_SIGNATURE;\r | |
973 | Nic->Private = mPrivate;\r | |
974 | Nic->Wmp = Wmp;\r | |
975 | Nic->Supplicant = Supplicant;\r | |
976 | Nic->EapConfig = EapConfig;\r | |
977 | Nic->UserSelectedProfile = NULL;\r | |
978 | Nic->OneTimeScanRequest = FALSE;\r | |
979 | \r | |
980 | if (Nic->Supplicant != NULL) {\r | |
981 | Status = WifiMgrGetSupportedSuites (Nic);\r | |
982 | }\r | |
983 | \r | |
984 | if (!EFI_ERROR (Status)) {\r | |
985 | InitializeListHead (&Nic->ProfileList);\r | |
986 | \r | |
987 | Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));\r | |
988 | if (Nic->ConnectPendingNetwork == NULL) {\r | |
989 | Status = EFI_OUT_OF_RESOURCES;\r | |
990 | DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to allocate memory for ConnectPendingNetwork\n"));\r | |
991 | goto ERROR;\r | |
992 | }\r | |
993 | \r | |
994 | Status = WiFiProfileSyncProtocol->GetProfile (Nic->ConnectPendingNetwork, Nic->MacAddress);\r | |
995 | if (!EFI_ERROR (Status) && (Nic->ConnectPendingNetwork != NULL)) {\r | |
996 | Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);\r | |
997 | if (!EFI_ERROR (Status)) {\r | |
998 | return Status;\r | |
999 | }\r | |
1000 | } else {\r | |
1001 | DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get WiFi profile with status %r\n", Status));\r | |
1002 | }\r | |
1003 | } else {\r | |
1004 | DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get Supported suites with status %r\n", Status));\r | |
1005 | }\r | |
1006 | \r | |
1007 | if (Nic->ConnectPendingNetwork != NULL) {\r | |
1008 | if (Nic->ConnectPendingNetwork->Network.AKMSuite != NULL) {\r | |
1009 | FreePool (Nic->ConnectPendingNetwork->Network.AKMSuite);\r | |
1010 | }\r | |
1011 | \r | |
1012 | if (Nic->ConnectPendingNetwork->Network.CipherSuite != NULL) {\r | |
1013 | FreePool (Nic->ConnectPendingNetwork->Network.CipherSuite);\r | |
1014 | }\r | |
1015 | \r | |
1016 | FreePool (Nic->ConnectPendingNetwork);\r | |
1017 | }\r | |
1018 | \r | |
1019 | ERROR:\r | |
1020 | if (Nic->Supplicant != NULL) {\r | |
1021 | if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {\r | |
1022 | FreePool (Nic->SupportedSuites.SupportedAKMSuites);\r | |
1023 | }\r | |
1024 | \r | |
1025 | if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {\r | |
1026 | FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);\r | |
1027 | }\r | |
1028 | \r | |
1029 | if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {\r | |
1030 | FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);\r | |
1031 | }\r | |
1032 | }\r | |
1033 | \r | |
1034 | FreePool (Nic);\r | |
1035 | \r | |
1036 | return Status;\r | |
1037 | }\r | |
1038 | \r | |
90b24889 WF |
1039 | /**\r |
1040 | The callback function for connect operation.\r | |
1041 | \r | |
1042 | ASSERT when errors occur in config token.\r | |
1043 | \r | |
1044 | @param[in] Event The Connect token receive event.\r | |
1045 | @param[in] Context The context of the connect token.\r | |
1046 | \r | |
1047 | **/\r | |
1048 | VOID\r | |
1049 | EFIAPI\r | |
1050 | WifiMgrOnConnectFinished (\r | |
d1050b9d MK |
1051 | IN EFI_EVENT Event,\r |
1052 | IN VOID *Context\r | |
90b24889 WF |
1053 | )\r |
1054 | {\r | |
fe405f08 ZCW |
1055 | EFI_STATUS Status;\r |
1056 | WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;\r | |
1057 | WIFI_MGR_NETWORK_PROFILE *ConnectedProfile;\r | |
1058 | UINT8 SecurityType;\r | |
1059 | UINT8 SSIdLen;\r | |
1060 | CHAR8 *AsciiSSId;\r | |
1061 | EDKII_WIFI_PROFILE_SYNC_PROTOCOL *WiFiProfileSyncProtocol;\r | |
90b24889 WF |
1062 | \r |
1063 | ASSERT (Context != NULL);\r | |
1064 | \r | |
1065 | ConnectedProfile = NULL;\r | |
d1050b9d | 1066 | ConfigToken = (WIFI_MGR_MAC_CONFIG_TOKEN *)Context;\r |
90b24889 WF |
1067 | ASSERT (ConfigToken->Nic != NULL);\r |
1068 | \r | |
1069 | ConfigToken->Nic->ConnectState = WifiMgrDisconnected;\r | |
1070 | ASSERT (ConfigToken->Type == TokenTypeConnectNetworkToken);\r | |
1071 | \r | |
1072 | ASSERT (ConfigToken->Token.ConnectNetworkToken != NULL);\r | |
fe405f08 ZCW |
1073 | \r |
1074 | Status = gBS->LocateProtocol (&gEdkiiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);\r | |
1075 | if (!EFI_ERROR (Status)) {\r | |
1076 | WiFiProfileSyncProtocol->SetConnectState (ConfigToken->Token.ConnectNetworkToken->ResultCode);\r | |
1077 | if ((mWifiConnectionCount < MAX_WIFI_CONNETION_ATTEMPTS) &&\r | |
1078 | (ConfigToken->Token.ConnectNetworkToken->ResultCode != ConnectSuccess))\r | |
1079 | {\r | |
1080 | mWifiConnectionCount++;\r | |
1081 | gBS->CloseEvent (Event);\r | |
1082 | Status = ConnectionRetry (WiFiProfileSyncProtocol);\r | |
1083 | if (!EFI_ERROR (Status)) {\r | |
1084 | return;\r | |
1085 | }\r | |
1086 | \r | |
1087 | WiFiProfileSyncProtocol->SetConnectState (Status);\r | |
1088 | }\r | |
1089 | }\r | |
1090 | \r | |
90b24889 | 1091 | if (ConfigToken->Token.ConnectNetworkToken->Status != EFI_SUCCESS) {\r |
90b24889 WF |
1092 | if (ConfigToken->Nic->OneTimeConnectRequest) {\r |
1093 | //\r | |
1094 | // Only update message for user triggered connection\r | |
1095 | //\r | |
1096 | if (ConfigToken->Token.ConnectNetworkToken->Status == EFI_ACCESS_DENIED) {\r | |
90b24889 WF |
1097 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Connect Failed: Permission Denied!");\r |
1098 | } else {\r | |
1099 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Connect Failed!");\r | |
1100 | }\r | |
d1050b9d | 1101 | \r |
90b24889 WF |
1102 | ConfigToken->Nic->OneTimeConnectRequest = FALSE;\r |
1103 | }\r | |
d1050b9d | 1104 | \r |
90b24889 WF |
1105 | ConfigToken->Nic->CurrentOperateNetwork = NULL;\r |
1106 | return;\r | |
1107 | }\r | |
1108 | \r | |
1109 | if (ConfigToken->Token.ConnectNetworkToken->ResultCode != ConnectSuccess) {\r | |
90b24889 | 1110 | if (ConfigToken->Nic->OneTimeConnectRequest) {\r |
90b24889 WF |
1111 | if (ConfigToken->Token.ConnectNetworkToken->ResultCode == ConnectFailedReasonUnspecified) {\r |
1112 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Connect Failed: Wrong Password or Unexpected Error!");\r | |
1113 | } else {\r | |
1114 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Connect Failed!");\r | |
1115 | }\r | |
1116 | }\r | |
d1050b9d | 1117 | \r |
90b24889 WF |
1118 | goto Exit;\r |
1119 | }\r | |
1120 | \r | |
d1050b9d MK |
1121 | if ((ConfigToken->Token.ConnectNetworkToken->Data == NULL) ||\r |
1122 | (ConfigToken->Token.ConnectNetworkToken->Data->Network == NULL))\r | |
1123 | {\r | |
90b24889 WF |
1124 | //\r |
1125 | // An unexpected error occurs, tell low layer to perform a disconnect\r | |
1126 | //\r | |
1127 | ConfigToken->Nic->HasDisconnectPendingNetwork = TRUE;\r | |
1128 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL);\r | |
1129 | goto Exit;\r | |
1130 | }\r | |
1131 | \r | |
1132 | //\r | |
1133 | // A correct connect token received, terminate the connection process\r | |
1134 | //\r | |
d1050b9d MK |
1135 | Status = WifiMgrCheckRSN (\r |
1136 | ConfigToken->Token.ConnectNetworkToken->Data->Network->AKMSuite,\r | |
90b24889 | 1137 | ConfigToken->Token.ConnectNetworkToken->Data->Network->CipherSuite,\r |
d1050b9d MK |
1138 | ConfigToken->Nic,\r |
1139 | &SecurityType,\r | |
1140 | NULL,\r | |
1141 | NULL\r | |
1142 | );\r | |
1143 | if (EFI_ERROR (Status)) {\r | |
90b24889 WF |
1144 | SecurityType = SECURITY_TYPE_UNKNOWN;\r |
1145 | }\r | |
1146 | \r | |
1147 | SSIdLen = ConfigToken->Token.ConnectNetworkToken->Data->Network->SSId.SSIdLen;\r | |
d1050b9d | 1148 | AsciiSSId = (CHAR8 *)AllocateZeroPool (sizeof (CHAR8) * (SSIdLen + 1));\r |
90b24889 WF |
1149 | if (AsciiSSId == NULL) {\r |
1150 | ConfigToken->Nic->HasDisconnectPendingNetwork = TRUE;\r | |
1151 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL);\r | |
1152 | goto Exit;\r | |
1153 | }\r | |
1154 | \r | |
d1050b9d | 1155 | CopyMem (AsciiSSId, ConfigToken->Token.ConnectNetworkToken->Data->Network->SSId.SSId, SSIdLen);\r |
90b24889 WF |
1156 | *(AsciiSSId + SSIdLen) = '\0';\r |
1157 | \r | |
d1050b9d MK |
1158 | ConnectedProfile = WifiMgrGetProfileByAsciiSSId (AsciiSSId, SecurityType, &ConfigToken->Nic->ProfileList);\r |
1159 | FreePool (AsciiSSId);\r | |
90b24889 WF |
1160 | if (ConnectedProfile == NULL) {\r |
1161 | ConfigToken->Nic->HasDisconnectPendingNetwork = TRUE;\r | |
1162 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL);\r | |
1163 | goto Exit;\r | |
1164 | }\r | |
1165 | \r | |
1166 | ConfigToken->Nic->ConnectState = WifiMgrConnectedToAp;\r | |
1167 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, TRUE, NULL);\r | |
1168 | \r | |
1169 | Exit:\r | |
1170 | \r | |
1171 | if (ConfigToken->Nic->ConnectState == WifiMgrDisconnected) {\r | |
1172 | ConfigToken->Nic->CurrentOperateNetwork = NULL;\r | |
1173 | }\r | |
d1050b9d | 1174 | \r |
90b24889 | 1175 | ConfigToken->Nic->OneTimeConnectRequest = FALSE;\r |
d1050b9d | 1176 | WifiMgrFreeToken (ConfigToken);\r |
90b24889 WF |
1177 | }\r |
1178 | \r | |
1179 | /**\r | |
1180 | Start connect operation, and send out a token to connect to a target network.\r | |
1181 | \r | |
1182 | @param[in] Nic Pointer to the device data of the selected NIC.\r | |
1183 | @param[in] Profile The target network to be connected.\r | |
1184 | \r | |
1185 | @retval EFI_SUCCESS The operation is completed.\r | |
1186 | @retval EFI_ALREADY_STARTED Already in "connected" state, need to perform a disconnect\r | |
1187 | operation first.\r | |
1188 | @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r | |
1189 | @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r | |
1190 | @retval Other Errors Return errors when connecting network on low layer.\r | |
1191 | \r | |
1192 | **/\r | |
1193 | EFI_STATUS\r | |
1194 | WifiMgrConnectToNetwork (\r | |
d1050b9d MK |
1195 | IN WIFI_MGR_DEVICE_DATA *Nic,\r |
1196 | IN WIFI_MGR_NETWORK_PROFILE *Profile\r | |
90b24889 WF |
1197 | )\r |
1198 | {\r | |
d1050b9d MK |
1199 | EFI_STATUS Status;\r |
1200 | EFI_TPL OldTpl;\r | |
1201 | EFI_ADAPTER_INFO_MEDIA_STATE LinkState;\r | |
1202 | WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;\r | |
1203 | EFI_80211_CONNECT_NETWORK_TOKEN *ConnectToken;\r | |
90b24889 | 1204 | \r |
d1050b9d | 1205 | if ((Nic == NULL) || (Nic->Wmp == NULL) || (Profile == NULL)) {\r |
90b24889 WF |
1206 | return EFI_INVALID_PARAMETER;\r |
1207 | }\r | |
1208 | \r | |
1209 | Status = WifiMgrGetLinkState (Nic, &LinkState);\r | |
1210 | if (EFI_ERROR (Status)) {\r | |
1211 | return Status;\r | |
1212 | }\r | |
d1050b9d | 1213 | \r |
90b24889 WF |
1214 | if (LinkState.MediaState == EFI_SUCCESS) {\r |
1215 | return EFI_ALREADY_STARTED;\r | |
1216 | }\r | |
1217 | \r | |
1218 | OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r | |
1219 | Status = WifiMgrPrepareConnection (Nic, Profile);\r | |
1220 | if (EFI_ERROR (Status)) {\r | |
1221 | gBS->RestoreTPL (OldTpl);\r | |
1222 | return Status;\r | |
1223 | }\r | |
1224 | \r | |
1225 | //\r | |
1226 | // Create a new connect token\r | |
1227 | //\r | |
1228 | ConfigToken = AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN));\r | |
1229 | if (ConfigToken == NULL) {\r | |
1230 | Status = EFI_OUT_OF_RESOURCES;\r | |
1231 | goto Exit;\r | |
1232 | }\r | |
1233 | \r | |
d1050b9d MK |
1234 | ConfigToken->Type = TokenTypeConnectNetworkToken;\r |
1235 | ConfigToken->Nic = Nic;\r | |
1236 | ConfigToken->Token.ConnectNetworkToken = AllocateZeroPool (sizeof (EFI_80211_CONNECT_NETWORK_TOKEN));\r | |
90b24889 WF |
1237 | if (ConfigToken->Token.ConnectNetworkToken == NULL) {\r |
1238 | goto Exit;\r | |
1239 | }\r | |
1240 | \r | |
d1050b9d MK |
1241 | ConnectToken = ConfigToken->Token.ConnectNetworkToken;\r |
1242 | ConnectToken->Data = AllocateZeroPool (sizeof (EFI_80211_CONNECT_NETWORK_DATA));\r | |
90b24889 WF |
1243 | if (ConnectToken->Data == NULL) {\r |
1244 | goto Exit;\r | |
1245 | }\r | |
1246 | \r | |
1247 | ConnectToken->Data->Network = AllocateZeroPool (sizeof (EFI_80211_NETWORK));\r | |
1248 | if (ConnectToken->Data->Network == NULL) {\r | |
1249 | goto Exit;\r | |
1250 | }\r | |
d1050b9d MK |
1251 | \r |
1252 | CopyMem (ConnectToken->Data->Network, &Profile->Network, sizeof (EFI_80211_NETWORK));\r | |
90b24889 WF |
1253 | \r |
1254 | //\r | |
1255 | // Add event handle and start to connect\r | |
1256 | //\r | |
1257 | Status = gBS->CreateEvent (\r | |
1258 | EVT_NOTIFY_SIGNAL,\r | |
1259 | TPL_CALLBACK,\r | |
1260 | WifiMgrOnConnectFinished,\r | |
1261 | ConfigToken,\r | |
1262 | &ConnectToken->Event\r | |
1263 | );\r | |
1264 | if (EFI_ERROR (Status)) {\r | |
1265 | goto Exit;\r | |
1266 | }\r | |
1267 | \r | |
d1050b9d | 1268 | Nic->ConnectState = WifiMgrConnectingToAp;\r |
90b24889 WF |
1269 | Nic->CurrentOperateNetwork = Profile;\r |
1270 | WifiMgrUpdateConnectMessage (Nic, FALSE, NULL);\r | |
1271 | \r | |
1272 | //\r | |
d1050b9d | 1273 | // Start Connecting ...\r |
90b24889 WF |
1274 | //\r |
1275 | Status = Nic->Wmp->ConnectNetwork (Nic->Wmp, ConnectToken);\r | |
1276 | \r | |
1277 | //\r | |
1278 | // Erase secrets after connection is triggered\r | |
1279 | //\r | |
1280 | WifiMgrCleanProfileSecrets (Profile);\r | |
1281 | \r | |
1282 | if (EFI_ERROR (Status)) {\r | |
1283 | if (Status == EFI_ALREADY_STARTED) {\r | |
1284 | Nic->ConnectState = WifiMgrConnectedToAp;\r | |
1285 | WifiMgrUpdateConnectMessage (Nic, TRUE, NULL);\r | |
1286 | } else {\r | |
90b24889 WF |
1287 | Nic->ConnectState = WifiMgrDisconnected;\r |
1288 | Nic->CurrentOperateNetwork = NULL;\r | |
1289 | \r | |
1290 | if (Nic->OneTimeConnectRequest) {\r | |
1291 | if (Status == EFI_NOT_FOUND) {\r | |
1292 | WifiMgrUpdateConnectMessage (Nic, FALSE, L"Connect Failed: Not Available!");\r | |
1293 | } else {\r | |
1294 | WifiMgrUpdateConnectMessage (Nic, FALSE, L"Connect Failed: Unexpected Error!");\r | |
1295 | }\r | |
1296 | }\r | |
1297 | }\r | |
d1050b9d | 1298 | \r |
90b24889 WF |
1299 | goto Exit;\r |
1300 | }\r | |
1301 | \r | |
1302 | Exit:\r | |
1303 | \r | |
1304 | if (EFI_ERROR (Status)) {\r | |
1305 | WifiMgrFreeToken (ConfigToken);\r | |
1306 | }\r | |
d1050b9d | 1307 | \r |
90b24889 WF |
1308 | gBS->RestoreTPL (OldTpl);\r |
1309 | \r | |
1310 | DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] WifiMgrConnectToNetwork: %r\n", Status));\r | |
1311 | return Status;\r | |
1312 | }\r | |
1313 | \r | |
1314 | /**\r | |
1315 | The callback function for disconnect operation.\r | |
1316 | \r | |
1317 | ASSERT when errors occur in config token.\r | |
1318 | \r | |
1319 | @param[in] Event The Disconnect token receive event.\r | |
1320 | @param[in] Context The context of the Disconnect token.\r | |
1321 | \r | |
1322 | **/\r | |
1323 | VOID\r | |
1324 | EFIAPI\r | |
1325 | WifiMgrOnDisconnectFinished (\r | |
d1050b9d MK |
1326 | IN EFI_EVENT Event,\r |
1327 | IN VOID *Context\r | |
90b24889 WF |
1328 | )\r |
1329 | {\r | |
d1050b9d | 1330 | WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;\r |
90b24889 WF |
1331 | \r |
1332 | ASSERT (Context != NULL);\r | |
1333 | \r | |
d1050b9d | 1334 | ConfigToken = (WIFI_MGR_MAC_CONFIG_TOKEN *)Context;\r |
90b24889 WF |
1335 | ASSERT (ConfigToken->Nic != NULL);\r |
1336 | ASSERT (ConfigToken->Type == TokenTypeDisconnectNetworkToken);\r | |
1337 | \r | |
1338 | ASSERT (ConfigToken->Token.DisconnectNetworkToken != NULL);\r | |
1339 | if (ConfigToken->Token.DisconnectNetworkToken->Status != EFI_SUCCESS) {\r | |
d1050b9d | 1340 | ConfigToken->Nic->ConnectState = WifiMgrConnectedToAp;\r |
90b24889 WF |
1341 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL);\r |
1342 | ConfigToken->Nic->OneTimeDisconnectRequest = FALSE;\r | |
1343 | goto Exit;\r | |
1344 | }\r | |
1345 | \r | |
1346 | ConfigToken->Nic->ConnectState = WifiMgrDisconnected;\r | |
1347 | ConfigToken->Nic->CurrentOperateNetwork = NULL;\r | |
1348 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, TRUE, NULL);\r | |
1349 | ConfigToken->Nic->OneTimeDisconnectRequest = FALSE;\r | |
1350 | \r | |
1351 | //\r | |
1352 | // Disconnected network may not be in network list now, trigger a scan again!\r | |
1353 | //\r | |
d1050b9d | 1354 | ConfigToken->Nic->OneTimeScanRequest = TRUE;\r |
90b24889 | 1355 | \r |
d1050b9d MK |
1356 | Exit:\r |
1357 | WifiMgrFreeToken (ConfigToken);\r | |
1358 | return;\r | |
90b24889 WF |
1359 | }\r |
1360 | \r | |
1361 | /**\r | |
1362 | Start disconnect operation, and send out a token to disconnect from current connected\r | |
1363 | network.\r | |
1364 | \r | |
1365 | @param[in] Nic Pointer to the device data of the selected NIC.\r | |
1366 | \r | |
1367 | @retval EFI_SUCCESS The operation is completed.\r | |
1368 | @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r | |
1369 | @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r | |
1370 | @retval Other Errors Return errors when disconnecting a network on low layer.\r | |
1371 | \r | |
1372 | **/\r | |
1373 | EFI_STATUS\r | |
1374 | WifiMgrDisconnectToNetwork (\r | |
d1050b9d | 1375 | IN WIFI_MGR_DEVICE_DATA *Nic\r |
90b24889 WF |
1376 | )\r |
1377 | {\r | |
d1050b9d MK |
1378 | EFI_STATUS Status;\r |
1379 | EFI_TPL OldTpl;\r | |
1380 | WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;\r | |
1381 | EFI_80211_DISCONNECT_NETWORK_TOKEN *DisconnectToken;\r | |
90b24889 WF |
1382 | \r |
1383 | if (Nic == NULL) {\r | |
1384 | return EFI_INVALID_PARAMETER;\r | |
1385 | }\r | |
1386 | \r | |
1387 | OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r | |
1388 | Status = EFI_SUCCESS;\r | |
1389 | ConfigToken = AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN));\r | |
1390 | if (ConfigToken == NULL) {\r | |
1391 | gBS->RestoreTPL (OldTpl);\r | |
1392 | return EFI_OUT_OF_RESOURCES;\r | |
1393 | }\r | |
1394 | \r | |
d1050b9d MK |
1395 | ConfigToken->Type = TokenTypeDisconnectNetworkToken;\r |
1396 | ConfigToken->Nic = Nic;\r | |
90b24889 WF |
1397 | ConfigToken->Token.DisconnectNetworkToken = AllocateZeroPool (sizeof (EFI_80211_DISCONNECT_NETWORK_TOKEN));\r |
1398 | if (ConfigToken->Token.DisconnectNetworkToken == NULL) {\r | |
d1050b9d | 1399 | WifiMgrFreeToken (ConfigToken);\r |
90b24889 WF |
1400 | gBS->RestoreTPL (OldTpl);\r |
1401 | return EFI_OUT_OF_RESOURCES;\r | |
1402 | }\r | |
1403 | \r | |
1404 | DisconnectToken = ConfigToken->Token.DisconnectNetworkToken;\r | |
1405 | \r | |
1406 | Status = gBS->CreateEvent (\r | |
1407 | EVT_NOTIFY_SIGNAL,\r | |
1408 | TPL_CALLBACK,\r | |
1409 | WifiMgrOnDisconnectFinished,\r | |
1410 | ConfigToken,\r | |
1411 | &DisconnectToken->Event\r | |
1412 | );\r | |
1413 | if (EFI_ERROR (Status)) {\r | |
d1050b9d | 1414 | WifiMgrFreeToken (ConfigToken);\r |
90b24889 WF |
1415 | gBS->RestoreTPL (OldTpl);\r |
1416 | return Status;\r | |
1417 | }\r | |
1418 | \r | |
1419 | Nic->ConnectState = WifiMgrDisconnectingToAp;\r | |
1420 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL);\r | |
1421 | \r | |
1422 | Status = Nic->Wmp->DisconnectNetwork (Nic->Wmp, DisconnectToken);\r | |
1423 | if (EFI_ERROR (Status)) {\r | |
1424 | if (Status == EFI_NOT_FOUND) {\r | |
90b24889 WF |
1425 | Nic->ConnectState = WifiMgrDisconnected;\r |
1426 | Nic->CurrentOperateNetwork = NULL;\r | |
1427 | \r | |
1428 | //\r | |
1429 | // This network is not in network list now, trigger a scan again!\r | |
1430 | //\r | |
d1050b9d | 1431 | Nic->OneTimeScanRequest = TRUE;\r |
90b24889 WF |
1432 | \r |
1433 | //\r | |
1434 | // State has been changed from Connected to Disconnected\r | |
1435 | //\r | |
1436 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, TRUE, NULL);\r | |
d1050b9d | 1437 | Status = EFI_SUCCESS;\r |
90b24889 WF |
1438 | } else {\r |
1439 | if (Nic->OneTimeDisconnectRequest) {\r | |
90b24889 WF |
1440 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Disconnect Failed: Unexpected Error!");\r |
1441 | }\r | |
1442 | \r | |
d1050b9d | 1443 | Nic->ConnectState = WifiMgrConnectedToAp;\r |
90b24889 WF |
1444 | WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL);\r |
1445 | }\r | |
d1050b9d MK |
1446 | \r |
1447 | WifiMgrFreeToken (ConfigToken);\r | |
90b24889 WF |
1448 | }\r |
1449 | \r | |
1450 | gBS->RestoreTPL (OldTpl);\r | |
1451 | return Status;\r | |
1452 | }\r | |
1453 | \r | |
1454 | /**\r | |
1455 | The state machine of the connection manager, periodically check the state and\r | |
1456 | perform a corresponding operation.\r | |
1457 | \r | |
1458 | @param[in] Event The timer event to be triggered.\r | |
1459 | @param[in] Context The context of the Nic device data.\r | |
1460 | \r | |
1461 | **/\r | |
1462 | VOID\r | |
1463 | EFIAPI\r | |
1464 | WifiMgrOnTimerTick (\r | |
d1050b9d MK |
1465 | IN EFI_EVENT Event,\r |
1466 | IN VOID *Context\r | |
90b24889 WF |
1467 | )\r |
1468 | {\r | |
d1050b9d MK |
1469 | WIFI_MGR_DEVICE_DATA *Nic;\r |
1470 | EFI_STATUS Status;\r | |
1471 | EFI_ADAPTER_INFO_MEDIA_STATE LinkState;\r | |
1472 | WIFI_MGR_NETWORK_PROFILE *Profile;\r | |
90b24889 WF |
1473 | \r |
1474 | if (Context == NULL) {\r | |
1475 | return;\r | |
1476 | }\r | |
1477 | \r | |
d1050b9d | 1478 | Nic = (WIFI_MGR_DEVICE_DATA *)Context;\r |
90b24889 WF |
1479 | NET_CHECK_SIGNATURE (Nic, WIFI_MGR_DEVICE_DATA_SIGNATURE);\r |
1480 | \r | |
1481 | Status = WifiMgrGetLinkState (Nic, &LinkState);\r | |
1482 | if (EFI_ERROR (Status)) {\r | |
1483 | DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Error: Failed to get link state!\n"));\r | |
1484 | return;\r | |
1485 | }\r | |
1486 | \r | |
1487 | if (Nic->LastLinkState.MediaState != LinkState.MediaState) {\r | |
d1050b9d | 1488 | if ((Nic->LastLinkState.MediaState == EFI_SUCCESS) && (LinkState.MediaState == EFI_NO_MEDIA)) {\r |
90b24889 WF |
1489 | Nic->HasDisconnectPendingNetwork = TRUE;\r |
1490 | }\r | |
d1050b9d | 1491 | \r |
90b24889 WF |
1492 | Nic->LastLinkState.MediaState = LinkState.MediaState;\r |
1493 | }\r | |
1494 | \r | |
d1050b9d MK |
1495 | Nic->ScanTickTime++;\r |
1496 | if (((Nic->ScanTickTime > WIFI_SCAN_FREQUENCY) || Nic->OneTimeScanRequest) &&\r | |
1497 | (Nic->ScanState == WifiMgrScanFinished))\r | |
1498 | {\r | |
90b24889 | 1499 | Nic->OneTimeScanRequest = FALSE;\r |
d1050b9d | 1500 | Nic->ScanTickTime = 0;\r |
90b24889 WF |
1501 | \r |
1502 | DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Scan is triggered.\n"));\r | |
1503 | WifiMgrStartScan (Nic);\r | |
1504 | }\r | |
1505 | \r | |
d1050b9d | 1506 | if ((Nic->AvailableCount > 0) && (Nic->ScanState == WifiMgrScanFinished)) {\r |
90b24889 | 1507 | switch (Nic->ConnectState) {\r |
d1050b9d | 1508 | case WifiMgrDisconnected:\r |
90b24889 | 1509 | \r |
d1050b9d MK |
1510 | if (Nic->HasDisconnectPendingNetwork) {\r |
1511 | Nic->HasDisconnectPendingNetwork = FALSE;\r | |
1512 | }\r | |
90b24889 | 1513 | \r |
d1050b9d MK |
1514 | if (Nic->ConnectPendingNetwork != NULL) {\r |
1515 | Profile = Nic->ConnectPendingNetwork;\r | |
1516 | Status = WifiMgrConnectToNetwork (Nic, Profile);\r | |
1517 | Nic->ConnectPendingNetwork = NULL;\r | |
1518 | if (EFI_ERROR (Status)) {\r | |
1519 | //\r | |
1520 | // Some error happened, don't wait for a return connect token!\r | |
1521 | //\r | |
1522 | Nic->OneTimeConnectRequest = FALSE;\r | |
1523 | }\r | |
90b24889 | 1524 | }\r |
90b24889 | 1525 | \r |
d1050b9d | 1526 | break;\r |
90b24889 | 1527 | \r |
d1050b9d MK |
1528 | case WifiMgrConnectingToAp:\r |
1529 | break;\r | |
90b24889 | 1530 | \r |
d1050b9d MK |
1531 | case WifiMgrDisconnectingToAp:\r |
1532 | break;\r | |
90b24889 | 1533 | \r |
d1050b9d | 1534 | case WifiMgrConnectedToAp:\r |
90b24889 | 1535 | \r |
d1050b9d MK |
1536 | if ((Nic->ConnectPendingNetwork != NULL) || Nic->HasDisconnectPendingNetwork) {\r |
1537 | Status = WifiMgrDisconnectToNetwork (Nic);\r | |
1538 | if (EFI_ERROR (Status)) {\r | |
1539 | //\r | |
1540 | // Some error happened, don't wait for a return disconnect token!\r | |
1541 | //\r | |
1542 | Nic->OneTimeDisconnectRequest = FALSE;\r | |
1543 | }\r | |
90b24889 | 1544 | }\r |
90b24889 | 1545 | \r |
d1050b9d MK |
1546 | break;\r |
1547 | \r | |
1548 | default:\r | |
1549 | break;\r | |
90b24889 WF |
1550 | }\r |
1551 | }\r | |
1552 | }\r |