9 #pragma comment(lib, "wlanapi.lib") 10 #pragma comment(lib, "ole32.lib") 36 if (this->HClient != NULL)
38 LOG_ERROR(
"ClariusWifi already intialized, this initialization call was rejected");
42 DWORD maxClientVersion = 2;
43 DWORD res = WlanOpenHandle(maxClientVersion, NULL, &this->CurApiVersion, &this->HClient);
44 if (res != ERROR_SUCCESS)
46 LOG_ERROR(
"Failed to open WLAN API client handle");
57 if (this->HClient == NULL)
62 DWORD res = WlanCloseHandle(this->HClient, NULL);
63 if (res != ERROR_SUCCESS)
65 LOG_ERROR(
"Failed to close WLAN API client handle");
77 if (this->HClient == NULL)
79 LOG_ERROR(
"ClariusWifi must be initialized before calling IsClariusNetworkReady");
83 PWLAN_INTERFACE_INFO_LIST interfaces = NULL;
84 PWLAN_INTERFACE_INFO if_info = NULL;
85 DWORD res = WlanEnumInterfaces(this->HClient, NULL, &interfaces);
86 if (res != ERROR_SUCCESS)
88 LOG_ERROR(
"Failed to enumerate WLAN interfaces");
92 for (
int i = 0;
i < interfaces->dwNumberOfItems;
i++)
94 if_info = (WLAN_INTERFACE_INFO*)&interfaces->InterfaceInfo[
i];
97 res = WlanScan(this->HClient, &if_info->InterfaceGuid, NULL, NULL, NULL);
98 if (res != ERROR_SUCCESS)
100 LOG_ERROR(
"Failed to scan for networks");
103 PWLAN_AVAILABLE_NETWORK_LIST networks = NULL;
104 PWLAN_AVAILABLE_NETWORK nw_info = NULL;
105 res = WlanGetAvailableNetworkList(this->HClient, &if_info->InterfaceGuid,
107 if (res != ERROR_SUCCESS)
109 LOG_WARNING(
"Failed to list available networks for interface: " << if_info->strInterfaceDescription);
113 for (
int j = 0; j < networks->dwNumberOfItems; j++)
115 nw_info = (WLAN_AVAILABLE_NETWORK*)&networks->Network[j];
117 std::string candidate_ssid = (
char*)nw_info->dot11Ssid.ucSSID;
118 if (ssid.compare(candidate_ssid) == 0)
120 this->InterfaceGuid = if_info->InterfaceGuid;
126 if (networks != NULL)
128 WlanFreeMemory(networks);
134 if (interfaces != NULL)
136 WlanFreeMemory(interfaces);
149 LOG_ERROR(
"ClariusWifi already connected to Clarius network, this connection call was rejected");
153 if (this->HClient == NULL)
155 LOG_ERROR(
"ClariusWifi must be initialized before calling IsClariusNetworkReady");
160 std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now();
166 std::chrono::steady_clock::time_point
t = std::chrono::steady_clock::now();
167 std::chrono::duration<double> dur =
t - start_time;
170 LOG_ERROR(
"Waiting for Clarius wifi network to be ready timed out.");
176 std::this_thread::sleep_for(std::chrono::milliseconds(500));
184 LOG_ERROR(
"Failed to update Clarius wifi profile");
189 DOT11_SSID dot11_ssid = { 0 };
190 if (this->StringToSsid(ssid, &dot11_ssid) !=
PLUS_SUCCESS)
192 LOG_ERROR(
"Failed to convert ssid string to DOT11_SSID type");
197 std::wstring w_ssid = std::wstring(ssid.begin(), ssid.end());
198 WLAN_CONNECTION_PARAMETERS wlan_params;
199 wlan_params.pDot11Ssid = NULL;
200 wlan_params.strProfile = w_ssid.c_str();
201 wlan_params.wlanConnectionMode = wlan_connection_mode_profile;
202 wlan_params.pDesiredBssidList = NULL;
203 wlan_params.dot11BssType = this->BssType;
204 wlan_params.dwFlags = 0;
206 DWORD res = WlanConnect(this->HClient, &this->InterfaceGuid, &wlan_params, NULL);
207 if (res != ERROR_SUCCESS)
209 LOG_ERROR(
"Failed to connect to Clarius wifi network: Error code " << res);
213 this->Connected =
true;
220 bool profileUpdated =
false;
222 PWLAN_AVAILABLE_NETWORK_LIST networks = NULL;
223 PWLAN_AVAILABLE_NETWORK nw_info = NULL;
224 DWORD res = WlanGetAvailableNetworkList(this->HClient, &this->InterfaceGuid,
226 if (res != ERROR_SUCCESS)
228 LOG_WARNING(
"Failed to list available networks");
232 for (
int j = 0; j < networks->dwNumberOfItems; j++)
234 nw_info = (WLAN_AVAILABLE_NETWORK*)&networks->Network[j];
236 std::string candidate_ssid = (
char*)nw_info->dot11Ssid.ucSSID;
237 if (ssid.compare(candidate_ssid) != 0)
242 std::wstring authenticationAlgorithm;
243 switch (nw_info->dot11DefaultAuthAlgorithm)
245 case DOT11_AUTH_ALGO_80211_OPEN:
246 authenticationAlgorithm = L
"OPEN";
248 case DOT11_AUTH_ALGO_80211_SHARED_KEY:
249 authenticationAlgorithm = L
"SHARED";
251 case DOT11_AUTH_ALGO_WPA:
252 case DOT11_AUTH_ALGO_WPA_PSK:
253 case DOT11_AUTH_ALGO_WPA_NONE:
254 authenticationAlgorithm = L
"WPAPSK";
256 case DOT11_AUTH_ALGO_RSNA:
257 case DOT11_AUTH_ALGO_RSNA_PSK:
258 authenticationAlgorithm = L
"WPA2PSK";
261 authenticationAlgorithm = L
"UNKNOWN";
264 std::wstring encryptionAlgorithm;
265 std::wstring keyType = L
"passPhrase";
266 switch (nw_info->dot11DefaultCipherAlgorithm)
268 case DOT11_CIPHER_ALGO_NONE:
269 encryptionAlgorithm = L
"NONE";
271 case DOT11_CIPHER_ALGO_TKIP:
272 encryptionAlgorithm = L
"TKIP";
275 case DOT11_CIPHER_ALGO_CCMP:
276 encryptionAlgorithm = L
"AES";
279 encryptionAlgorithm = L
"WEP";
280 keyType = L
"networkKey";
283 std::wstringstream ss_w_clarius_profile_xml;
284 ss_w_clarius_profile_xml <<
"<?xml version=\"1.0\" encoding=\"US-ASCII\"?>" << std::endl;
285 ss_w_clarius_profile_xml <<
"<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">" << std::endl;
286 ss_w_clarius_profile_xml <<
" <name>" << std::wstring(ssid.begin(), ssid.end()) <<
"</name>" << std::endl;
287 ss_w_clarius_profile_xml <<
" <SSIDConfig>" << std::endl;
288 ss_w_clarius_profile_xml <<
" <SSID>" << std::endl;
289 ss_w_clarius_profile_xml <<
" <name>" << std::wstring(ssid.begin(), ssid.end()) <<
"</name>" << std::endl;
290 ss_w_clarius_profile_xml <<
" </SSID>" << std::endl;
291 ss_w_clarius_profile_xml <<
" </SSIDConfig>" << std::endl;
292 ss_w_clarius_profile_xml <<
" <connectionType>ESS</connectionType>" << std::endl;
293 ss_w_clarius_profile_xml <<
" <connectionMode>auto</connectionMode>" << std::endl;
294 ss_w_clarius_profile_xml <<
" <autoSwitch>false</autoSwitch>" << std::endl;
295 ss_w_clarius_profile_xml <<
" <MSM>" << std::endl;
296 ss_w_clarius_profile_xml <<
" <security>" << std::endl;
297 ss_w_clarius_profile_xml <<
" <authEncryption>" << std::endl;
298 ss_w_clarius_profile_xml <<
" <authentication>" << authenticationAlgorithm <<
"</authentication>" << std::endl;
299 ss_w_clarius_profile_xml <<
" <encryption>" << encryptionAlgorithm <<
"</encryption>" << std::endl;
300 ss_w_clarius_profile_xml <<
" <useOneX>false</useOneX>" << std::endl;
301 ss_w_clarius_profile_xml <<
" </authEncryption>" << std::endl;
302 if (nw_info->dot11DefaultCipherAlgorithm != DOT11_CIPHER_ALGO_NONE)
304 ss_w_clarius_profile_xml <<
" <sharedKey>" << std::endl;
305 ss_w_clarius_profile_xml <<
" <keyType>" << keyType <<
"</keyType>" << std::endl;
306 ss_w_clarius_profile_xml <<
" <protected>false</protected>" << std::endl;
307 ss_w_clarius_profile_xml <<
" <keyMaterial>" << std::wstring(
password.begin(),
password.end()) <<
"</keyMaterial>" << std::endl;
308 ss_w_clarius_profile_xml <<
" </sharedKey>" << std::endl;
310 ss_w_clarius_profile_xml <<
" </security>" << std::endl;
311 ss_w_clarius_profile_xml <<
" </MSM>" << std::endl;
312 ss_w_clarius_profile_xml <<
"</WLANProfile>";
313 std::wstring w_clarius_profile_xml = ss_w_clarius_profile_xml.str();
314 LOG_DEBUG_W(L
"WLAN Profile: \n" << ss_w_clarius_profile_xml.str());
317 DWORD reasonCode = 0;
318 res = WlanSetProfile(this->HClient, &this->InterfaceGuid, 0, w_clarius_profile_xml.c_str(), NULL,
TRUE, NULL, &reasonCode);
319 if (res != ERROR_SUCCESS)
321 WCHAR reasonCodeStr[256] = L
"\0";
322 WlanReasonCodeToString(reasonCode, 256, reasonCodeStr, NULL);
323 LOG_ERROR(
"Failed to set Wi-Fi profile: " << nw_info->strProfileName);
324 LOG_ERROR(
"Error code: " << res);
325 LOG_ERROR_W(L
"Reason: (" << reasonCode <<
") " << reasonCodeStr);
329 this->BssType = nw_info->dot11BssType;
330 profileUpdated =
true;
335 if (networks != NULL)
337 WlanFreeMemory(networks);
343 LOG_ERROR(
"Failed to find Clarius Wi-Fi network");
353 if (!this->Connected)
359 if (this->HClient == NULL)
361 LOG_ERROR(
"ClariusWifi must be initialized before calling IsClariusNetworkReady");
366 DWORD res = WlanDisconnect(this->HClient, &this->InterfaceGuid, NULL);
367 if (res != ERROR_SUCCESS)
369 LOG_ERROR(
"Failed to disconnect from Clarius wifi network with error: " << res);
373 this->Connected =
false;
378 PlusStatus ClariusWifi::StringToSsid(std::string ssid, PDOT11_SSID pdot11_ssid)
380 BYTE pb_ssid[DOT11_SSID_MAX_LENGTH + 1] = { 0 };
382 std::wstring w_ssid(ssid.begin(), ssid.end());
383 if (ssid.empty() || pdot11_ssid == NULL)
389 pdot11_ssid->uSSIDLength = WideCharToMultiByte(CP_ACP,
398 pdot11_ssid->uSSIDLength--;
399 memcpy(&pdot11_ssid->ucSSID, pb_ssid, pdot11_ssid->uSSIDLength);
PlusStatus IsClariusNetworkReady(std::string ssid)
static const float MAX_NETWORK_READY_WAIT_TIME_SEC
PlusStatus DeInitialize()
PlusStatus UpdateClariusWifiProfile(std::string ssid, std::string password)
PlusStatus ConnectToClariusWifi(std::string ssid, std::string password)
PlusStatus DisconnectFromClariusWifi()
const char int const char * password