9 #pragma comment(lib, "wlanapi.lib") 10 #pragma comment(lib, "ole32.lib") 40 if (this->HClient != NULL)
42 LOG_ERROR(
"ClariusWifi already intialized, this initialization call was rejected");
46 DWORD maxClientVersion = 2;
47 DWORD res = WlanOpenHandle(maxClientVersion, NULL, &this->CurApiVersion, &this->HClient);
48 if (res != ERROR_SUCCESS)
50 LOG_ERROR(
"Failed to open WLAN API client handle");
61 if (this->HClient == NULL)
66 DWORD res = WlanCloseHandle(this->HClient, NULL);
67 if (res != ERROR_SUCCESS)
69 LOG_ERROR(
"Failed to close WLAN API client handle");
81 if (this->HClient == NULL)
83 LOG_ERROR(
"ClariusWifi must be initialized before calling IsClariusNetworkReady");
87 PWLAN_INTERFACE_INFO_LIST interfaces = NULL;
88 PWLAN_INTERFACE_INFO if_info = NULL;
89 DWORD res = WlanEnumInterfaces(this->HClient, NULL, &interfaces);
90 if (res != ERROR_SUCCESS)
92 LOG_ERROR(
"Failed to enumerate WLAN interfaces");
96 for (
int i = 0;
i < interfaces->dwNumberOfItems;
i++)
98 if_info = (WLAN_INTERFACE_INFO*)&interfaces->InterfaceInfo[
i];
101 res = WlanScan(this->HClient, &if_info->InterfaceGuid, NULL, NULL, NULL);
102 if (res != ERROR_SUCCESS)
104 LOG_ERROR(
"Failed to scan for networks");
107 PWLAN_AVAILABLE_NETWORK_LIST networks = NULL;
108 PWLAN_AVAILABLE_NETWORK nw_info = NULL;
109 res = WlanGetAvailableNetworkList(this->HClient, &if_info->InterfaceGuid,
111 if (res != ERROR_SUCCESS)
113 LOG_WARNING(
"Failed to list available networks for interface: " << if_info->strInterfaceDescription);
117 for (
int j = 0; j < networks->dwNumberOfItems; j++)
119 nw_info = (WLAN_AVAILABLE_NETWORK*)&networks->Network[j];
121 std::string candidate_ssid = (
char*)nw_info->dot11Ssid.ucSSID;
122 if (ssid.compare(candidate_ssid) == 0)
124 this->InterfaceGuid = if_info->InterfaceGuid;
130 if (networks != NULL)
132 WlanFreeMemory(networks);
138 if (interfaces != NULL)
140 WlanFreeMemory(interfaces);
151 if (this->HClient == NULL)
153 LOG_ERROR(
"ClariusWifi must be initialized before calling IsClariusNetworkReady");
157 PWLAN_INTERFACE_INFO_LIST interfaces = NULL;
158 PWLAN_INTERFACE_INFO if_info = NULL;
159 DWORD res = WlanEnumInterfaces(this->HClient, NULL, &interfaces);
160 if (res != ERROR_SUCCESS)
162 LOG_ERROR(
"Failed to enumerate WLAN interfaces");
166 WLAN_INTERFACE_STATE
state = wlan_interface_state_not_ready;
167 for (
int i = 0;
i < interfaces->dwNumberOfItems;
i++)
169 if_info = (WLAN_INTERFACE_INFO*)&interfaces->InterfaceInfo[
i];
170 if (if_info->InterfaceGuid == this->InterfaceGuid)
173 state = if_info->isState;
179 if (interfaces != NULL)
181 WlanFreeMemory(interfaces);
187 case wlan_interface_state_not_ready:
188 LOG_DEBUG(
"WiFi state: Not ready");
190 case wlan_interface_state_connected:
191 LOG_DEBUG(
"WiFi state: Connected");
193 case wlan_interface_state_ad_hoc_network_formed:
194 LOG_DEBUG(
"WiFi state: Ad hoc network formed");
196 case wlan_interface_state_disconnecting:
197 LOG_DEBUG(
"WiFi state: Disconnecting");
199 case wlan_interface_state_disconnected:
200 LOG_DEBUG(
"WiFi state: Disconnected");
202 case wlan_interface_state_associating:
203 LOG_DEBUG(
"WiFi state: Associating");
205 case wlan_interface_state_discovering:
206 LOG_DEBUG(
"WiFi state: Discovering");
208 case wlan_interface_state_authenticating:
209 LOG_DEBUG(
"WiFi state: Authenticating");
212 LOG_DEBUG(
"WiFi state: Unknown state");
225 LOG_ERROR(
"ClariusWifi already connected to Clarius network, this connection call was rejected");
229 if (this->HClient == NULL)
231 LOG_ERROR(
"ClariusWifi must be initialized before calling IsClariusNetworkReady");
236 std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now();
242 std::chrono::steady_clock::time_point
t = std::chrono::steady_clock::now();
243 std::chrono::duration<double> dur =
t - start_time;
246 LOG_ERROR(
"Waiting for Clarius wifi network to be ready timed out.");
252 std::this_thread::sleep_for(std::chrono::milliseconds(500));
260 LOG_ERROR(
"Failed to update Clarius wifi profile");
265 DOT11_SSID dot11_ssid = { 0 };
266 if (this->StringToSsid(ssid, &dot11_ssid) !=
PLUS_SUCCESS)
268 LOG_ERROR(
"Failed to convert ssid string to DOT11_SSID type");
273 std::wstring w_ssid = std::wstring(ssid.begin(), ssid.end());
274 WLAN_CONNECTION_PARAMETERS wlan_params;
275 wlan_params.pDot11Ssid = NULL;
276 wlan_params.strProfile = w_ssid.c_str();
277 wlan_params.wlanConnectionMode = wlan_connection_mode_profile;
278 wlan_params.pDesiredBssidList = NULL;
279 wlan_params.dot11BssType = this->BssType;
280 wlan_params.dwFlags = 0;
282 DWORD res = WlanConnect(this->HClient, &this->InterfaceGuid, &wlan_params, NULL);
283 if (res != ERROR_SUCCESS)
285 LOG_ERROR(
"Failed to connect to Clarius wifi network: Error code " << res);
289 start_time = std::chrono::steady_clock::now();
295 std::chrono::steady_clock::time_point
t = std::chrono::steady_clock::now();
296 std::chrono::duration<double> dur =
t - start_time;
299 LOG_ERROR(
"Waiting for Clarius wifi network to be ready timed out.");
305 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
311 this->Connected =
true;
318 bool profileUpdated =
false;
320 PWLAN_AVAILABLE_NETWORK_LIST networks = NULL;
321 PWLAN_AVAILABLE_NETWORK nw_info = NULL;
322 DWORD res = WlanGetAvailableNetworkList(this->HClient, &this->InterfaceGuid,
324 if (res != ERROR_SUCCESS)
326 LOG_WARNING(
"Failed to list available networks");
330 for (
int j = 0; j < networks->dwNumberOfItems; j++)
332 nw_info = (WLAN_AVAILABLE_NETWORK*)&networks->Network[j];
334 std::string candidate_ssid = (
char*)nw_info->dot11Ssid.ucSSID;
335 if (ssid.compare(candidate_ssid) != 0)
340 std::wstring authenticationAlgorithm;
341 switch (nw_info->dot11DefaultAuthAlgorithm)
343 case DOT11_AUTH_ALGO_80211_OPEN:
344 authenticationAlgorithm = L
"OPEN";
346 case DOT11_AUTH_ALGO_80211_SHARED_KEY:
347 authenticationAlgorithm = L
"SHARED";
349 case DOT11_AUTH_ALGO_WPA:
350 case DOT11_AUTH_ALGO_WPA_PSK:
351 case DOT11_AUTH_ALGO_WPA_NONE:
352 authenticationAlgorithm = L
"WPAPSK";
354 case DOT11_AUTH_ALGO_RSNA:
355 case DOT11_AUTH_ALGO_RSNA_PSK:
356 authenticationAlgorithm = L
"WPA2PSK";
359 authenticationAlgorithm = L
"UNKNOWN";
362 std::wstring encryptionAlgorithm;
363 std::wstring keyType = L
"passPhrase";
364 switch (nw_info->dot11DefaultCipherAlgorithm)
366 case DOT11_CIPHER_ALGO_NONE:
367 encryptionAlgorithm = L
"NONE";
369 case DOT11_CIPHER_ALGO_TKIP:
370 encryptionAlgorithm = L
"TKIP";
373 case DOT11_CIPHER_ALGO_CCMP:
374 encryptionAlgorithm = L
"AES";
377 encryptionAlgorithm = L
"WEP";
378 keyType = L
"networkKey";
381 std::wstringstream ss_w_clarius_profile_xml;
382 ss_w_clarius_profile_xml <<
"<?xml version=\"1.0\" encoding=\"US-ASCII\"?>" << std::endl;
383 ss_w_clarius_profile_xml <<
"<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">" << std::endl;
384 ss_w_clarius_profile_xml <<
" <name>" << std::wstring(ssid.begin(), ssid.end()) <<
"</name>" << std::endl;
385 ss_w_clarius_profile_xml <<
" <SSIDConfig>" << std::endl;
386 ss_w_clarius_profile_xml <<
" <SSID>" << std::endl;
387 ss_w_clarius_profile_xml <<
" <name>" << std::wstring(ssid.begin(), ssid.end()) <<
"</name>" << std::endl;
388 ss_w_clarius_profile_xml <<
" </SSID>" << std::endl;
389 ss_w_clarius_profile_xml <<
" </SSIDConfig>" << std::endl;
390 ss_w_clarius_profile_xml <<
" <connectionType>ESS</connectionType>" << std::endl;
391 ss_w_clarius_profile_xml <<
" <connectionMode>auto</connectionMode>" << std::endl;
392 ss_w_clarius_profile_xml <<
" <autoSwitch>false</autoSwitch>" << std::endl;
393 ss_w_clarius_profile_xml <<
" <MSM>" << std::endl;
394 ss_w_clarius_profile_xml <<
" <security>" << std::endl;
395 ss_w_clarius_profile_xml <<
" <authEncryption>" << std::endl;
396 ss_w_clarius_profile_xml <<
" <authentication>" << authenticationAlgorithm <<
"</authentication>" << std::endl;
397 ss_w_clarius_profile_xml <<
" <encryption>" << encryptionAlgorithm <<
"</encryption>" << std::endl;
398 ss_w_clarius_profile_xml <<
" <useOneX>false</useOneX>" << std::endl;
399 ss_w_clarius_profile_xml <<
" </authEncryption>" << std::endl;
400 if (nw_info->dot11DefaultCipherAlgorithm != DOT11_CIPHER_ALGO_NONE)
402 ss_w_clarius_profile_xml <<
" <sharedKey>" << std::endl;
403 ss_w_clarius_profile_xml <<
" <keyType>" << keyType <<
"</keyType>" << std::endl;
404 ss_w_clarius_profile_xml <<
" <protected>false</protected>" << std::endl;
405 ss_w_clarius_profile_xml <<
" <keyMaterial>" << std::wstring(
password.begin(),
password.end()) <<
"</keyMaterial>" << std::endl;
406 ss_w_clarius_profile_xml <<
" </sharedKey>" << std::endl;
408 ss_w_clarius_profile_xml <<
" </security>" << std::endl;
409 ss_w_clarius_profile_xml <<
" </MSM>" << std::endl;
410 ss_w_clarius_profile_xml <<
"</WLANProfile>";
411 std::wstring w_clarius_profile_xml = ss_w_clarius_profile_xml.str();
412 LOG_DEBUG_W(L
"WLAN Profile: \n" << ss_w_clarius_profile_xml.str());
415 DWORD reasonCode = 0;
416 res = WlanSetProfile(this->HClient, &this->InterfaceGuid, 0, w_clarius_profile_xml.c_str(), NULL,
TRUE, NULL, &reasonCode);
417 if (res != ERROR_SUCCESS)
419 WCHAR reasonCodeStr[256] = L
"\0";
420 WlanReasonCodeToString(reasonCode, 256, reasonCodeStr, NULL);
421 LOG_ERROR(
"Failed to set Wi-Fi profile: " << nw_info->strProfileName);
422 LOG_ERROR(
"Error code: " << res);
423 LOG_ERROR_W(L
"Reason: (" << reasonCode <<
") " << reasonCodeStr);
427 this->BssType = nw_info->dot11BssType;
428 profileUpdated =
true;
433 if (networks != NULL)
435 WlanFreeMemory(networks);
441 LOG_ERROR(
"Failed to find Clarius Wi-Fi network");
451 if (!this->Connected)
457 if (this->HClient == NULL)
459 LOG_ERROR(
"ClariusWifi must be initialized before calling IsClariusNetworkReady");
464 DWORD res = WlanDisconnect(this->HClient, &this->InterfaceGuid, NULL);
465 if (res != ERROR_SUCCESS)
467 LOG_ERROR(
"Failed to disconnect from Clarius wifi network with error: " << res);
471 this->Connected =
false;
476 PlusStatus ClariusWifi::StringToSsid(std::string ssid, PDOT11_SSID pdot11_ssid)
478 BYTE pb_ssid[DOT11_SSID_MAX_LENGTH + 1] = { 0 };
480 std::wstring w_ssid(ssid.begin(), ssid.end());
481 if (ssid.empty() || pdot11_ssid == NULL)
487 pdot11_ssid->uSSIDLength = WideCharToMultiByte(CP_ACP,
496 pdot11_ssid->uSSIDLength--;
497 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 IsClariusNetworkConnected()
static const float MAX_NETWORK_CONNECTED_WAIT_TIME_SEC
PlusStatus DisconnectFromClariusWifi()
const char int const char * password