wifi断线重连

//WifiMgr.h
#pragma once
#include <windows.h>
#include <wlanapi.h>
#include <stdio.h>
#include <iostream>
#pragma comment(lib, "wlanapi.lib")

//连接方式
#define MODE_AUTO "auto"
#define MODE_MANUAL "manual"

//认证方式
#define AUTH_WPAPSK "WPAPSK"
#define AUTH_WPA2PSK "WPA2PSK"

//加密方式
#define ENCR_AES "AES"
#define ENCR_TKIP "TKIP"

/*WIFI信息*/
struct WIFIInfo {
	char account[64];

	char password[64];

	char mode[32];

	char auth[32];

	char encrypt[32];
};

class WifiMgr
{
public:
	WifiMgr();

	~WifiMgr();

	bool connect(const char* account, const char* password, const char* mode = MODE_MANUAL,
		const char* auth = AUTH_WPAPSK, const char* encrypt = ENCR_AES);

	bool connect(const WIFIInfo& info);

	bool reconnect();

	bool disconnect(bool removeProFile = true);

	bool connected();

	const char* getLastError();
protected:
	static void _stdcall wlanNotification(PWLAN_NOTIFICATION_DATA data, void* args);
private:
	bool m_connected = false;

	bool m_reconnect = false;

	char m_lastError[256] = { 0 };

	HANDLE m_handle = INVALID_HANDLE_VALUE;

	PWLAN_INTERFACE_INFO_LIST m_infoList = { 0 };

	WIFIInfo m_wifiInfo = { 0 };
};
//WifiMgr.cpp
#define _CRT_SECURE_NO_WARNINGS

#include "WifiMgr.h"


WifiMgr::WifiMgr()
{
}

WifiMgr::~WifiMgr()
{
	if (m_connected)
	{
		disconnect();
	}
}

bool WifiMgr::connect(const char* account, const char* password, const char* mode,
	const char* auth, const char* encrypt)
{
	bool result = false;
	do
	{
		if (!m_reconnect)
		{
			strcpy(m_wifiInfo.account, account);
			strcpy(m_wifiInfo.password, password);
			strcpy(m_wifiInfo.mode, mode);
			strcpy(m_wifiInfo.auth, auth);
			strcpy(m_wifiInfo.encrypt, encrypt);
		}

		unsigned long version = 0, value = 0;
		value = WlanOpenHandle(WLAN_API_VERSION, NULL, &version, &m_handle);
		if (value != ERROR_SUCCESS)
		{
			sprintf(m_lastError, "打开WIFI句柄失败,错误代码:%lu", value);
			break;
		}

		value = WlanEnumInterfaces(m_handle, NULL, &m_infoList);
		if (value != ERROR_SUCCESS)
		{
			sprintf(m_lastError, "枚举WIFI接口失败,错误代码:%lu", value);
			break;
		}

		char xmlBuffer[4096] = { 0 };
		sprintf(xmlBuffer, "<?xml version =\"1.0\"?>\
                             <WLANProfile xmlns =\"http://www.microsoft.com/networking/WLAN/profile/v1\">\
                             <name>%s</name>\
                             <SSIDConfig>\
                             <SSID>\
                             <name>%s</name>\
                             </SSID>\
                             </SSIDConfig>\
                             <connectionType>ESS</connectionType>\
                             <connectionMode>%s</connectionMode>\
                             <autoSwitch>false</autoSwitch>\
                             <MSM>\
                             <security>\
                             <authEncryption>\
                             <authentication>%s</authentication>\
                             <encryption>%s</encryption>\
                             <useOneX>false</useOneX>\
                             </authEncryption>\
                             <sharedKey>\
                             <keyType>passPhrase</keyType>\
                             <protected>false</protected>\
                             <keyMaterial>%s</keyMaterial>\
                             </sharedKey>\
                             </security>\
                             </MSM>\
                             </WLANProfile>",
			account, account, mode, auth, encrypt, password);

		wchar_t fileData[4096] = { 0 };
		int length = strlen(xmlBuffer);
		for (int j = 0; j < length; j++)
		{
			mbtowc(&fileData[j], &xmlBuffer[j], 1);
		}
		fileData[length] = '\0';

		WlanDisconnect(m_handle, &m_infoList->InterfaceInfo[0].InterfaceGuid, NULL);

		WLAN_REASON_CODE reasonCode = { 0 };
		value = WlanSetProfile(m_handle, &(m_infoList->InterfaceInfo[0].InterfaceGuid),
			0, fileData, NULL, TRUE, NULL, &reasonCode);
		if (value != ERROR_SUCCESS)
		{
			sprintf(m_lastError, "设置WIFI配置文件失败,错误代码:%lu", value);
			break;
		}

		wchar_t wideSsid[256] = { 0 };
		if (!MultiByteToWideChar(CP_ACP, 0, account, strlen(account) + 1,
			wideSsid, sizeof(wideSsid) / sizeof(wideSsid[0])))
		{
			sprintf(m_lastError, "多字符转宽字符失败,错误代码:%lu", GetLastError());
			break;
		}

		DOT11_SSID dot11Ssid = { 0 };
		memcpy(dot11Ssid.ucSSID, account, strlen(account) + 1);
		dot11Ssid.uSSIDLength = strlen(account);

		WLAN_CONNECTION_PARAMETERS connectionParameters;
		memset(&connectionParameters, 0, sizeof(connectionParameters));
		connectionParameters.pDot11Ssid = &dot11Ssid;
		connectionParameters.wlanConnectionMode = wlan_connection_mode_profile;
		connectionParameters.strProfile = wideSsid;   /* clear 可以填NULL */
		connectionParameters.dot11BssType = dot11_BSS_type_any;//dot11_BSS_type_independent;  /* msdn说可以dot11_BSS_type_any,实测不行 */
		connectionParameters.pDesiredBssidList = NULL;
		connectionParameters.dwFlags = 0; /* WLAN_CONNECTION_ADHOC_JOIN_ONLY */

		Sleep(300);

		value = WlanConnect(m_handle, &(m_infoList->InterfaceInfo[0].InterfaceGuid),
			&connectionParameters, NULL);
		if (value != ERROR_SUCCESS)
		{
			sprintf(m_lastError, "连接WIFI失败,错误代码:%lu", value);
			break;
		}

		value = WlanRegisterNotification(m_handle, WLAN_NOTIFICATION_SOURCE_ALL, false,
			wlanNotification, this, NULL, NULL);
		if (value != ERROR_SUCCESS)
		{
			sprintf(m_lastError, "注册通知失败,错误代码:%lu", value);
			break;
		}
		m_connected = true;
		result = true;
	} while (false);
	return result;
}

bool WifiMgr::connect(const WIFIInfo& info)
{
	return connect(info.account, info.password, info.mode, info.auth, info.encrypt);
}

bool WifiMgr::reconnect()
{
	bool result = false;
	m_reconnect = true;
	result = disconnect() && connect(m_wifiInfo);
	m_reconnect = false;
	return result;
}

bool WifiMgr::disconnect(bool removeProFile)
{
	bool result = true;
	do
	{
		wchar_t profile[256] = { 0 };
		if (!MultiByteToWideChar(CP_ACP, 0, m_wifiInfo.account, strlen(m_wifiInfo.account) + 1,
			profile, sizeof(profile) / sizeof(profile[0])))
		{
			sprintf(m_lastError, "多字符转宽字符失败,错误代码:%lu", GetLastError());
			break;
		}

		unsigned long value = 0;

		if (removeProFile)
		{
			value = WlanDeleteProfile(m_handle, &(m_infoList->InterfaceInfo->InterfaceGuid),
				profile, NULL);
			if (value != ERROR_SUCCESS)
			{
				sprintf(m_lastError, "删除WIFI配置文件%s失败,错误代码:%lu", m_wifiInfo.account, value);
				result = false;
			}
		}

		value = WlanDisconnect(m_handle, &(m_infoList->InterfaceInfo->InterfaceGuid), NULL);
		if (value != ERROR_SUCCESS)
		{
			if (strlen(m_lastError))
			{
				strcat(m_lastError, ",");
			}
			char temp[256] = { 0 };
			sprintf(temp, "断开WIFI失败,错误代码:%lu", value);
			strcat(m_lastError, temp);
			result = false;
		}

		if (m_handle != INVALID_HANDLE_VALUE)
		{
			WlanCloseHandle(m_handle, NULL);
			m_handle = INVALID_HANDLE_VALUE;
		}
		WlanFreeMemory(m_infoList);
		m_connected = false;
	} while (false);
	return result;
}

bool WifiMgr::connected()
{
	return m_connected;
}

const char* WifiMgr::getLastError()
{
	return m_lastError;
}

void WifiMgr::wlanNotification(PWLAN_NOTIFICATION_DATA data, void* args)
{
	WifiMgr* wifi = static_cast<WifiMgr*>(args);
	if (!wifi)
		return;

	unsigned long source = data->NotificationSource;
	unsigned long code = data->NotificationCode;
	unsigned long size = data->dwDataSize;
	const char* action = "unknown";
	if (source == WLAN_NOTIFICATION_SOURCE_ACM)
	{
		switch (source)
		{
		case wlan_notification_acm_start:
			action = "acm_start";
			break;
		case wlan_notification_acm_autoconf_enabled:
			action = "acm_autoconf_enabled";
			break;
		case wlan_notification_acm_autoconf_disabled:
			action = "acm_autoconf_disabled";
			break;
		case wlan_notification_acm_background_scan_enabled:
			action = "acm_background_scan_enabled";
			break;
		case wlan_notification_acm_background_scan_disabled:
			action = "acm_background_scan_disabled";
			break;
		case wlan_notification_acm_bss_type_change:
			action = "acm_bss_type_change";
			break;
		case wlan_notification_acm_power_setting_change:
			action = "acm_power_setting_change";
			break;
		case wlan_notification_acm_scan_complete:
			action = "acm_scan_complete";
			break;
		case wlan_notification_acm_scan_fail:
			action = "acm_scan_fail";
			break;
		case wlan_notification_acm_connection_start:
			action = "acm_connection_start";
			break;
		case wlan_notification_acm_connection_complete:
			action = "acm_connection_complete";
			break;
		case wlan_notification_acm_connection_attempt_fail:
			action = "acm_connection_attempt_fail";
			break;
		case wlan_notification_acm_filter_list_change:
			action = "acm_filter_list_change";
			break;
		case wlan_notification_acm_interface_arrival:
			action = "acm_interface_removal";
			break;
		case wlan_notification_acm_interface_removal:
			action = "acm_interface_removal";
			break;
		case wlan_notification_acm_profile_change:
			action = "acm_profile_change";
			break;
		case wlan_notification_acm_profile_name_change:
			action = "acm_profile_name_change";
			break;
		case wlan_notification_acm_profiles_exhausted:
			action = "acm_profiles_exhausted";
			break;
		case wlan_notification_acm_network_not_available:
			action = "acm_network_not_available";
			break;
		case wlan_notification_acm_network_available:
			action = "acm_network_available";
			break;
		case wlan_notification_acm_disconnecting:
			action = "acm_disconnecting";
			break;
		case wlan_notification_acm_disconnected:
			action = "acm_disconnected";
			break;
		case wlan_notification_acm_adhoc_network_state_change:
			action = "acm_adhoc_network_state_change";
			break;
		case wlan_notification_acm_end:
			action = "acm_end";
			break;
		default:break;
		}
	}
	else if (source == WLAN_NOTIFICATION_SOURCE_MSM)
	{
		switch (code)
		{
		case wlan_notification_msm_start:
			action = "msm_start";
			break;
		case wlan_notification_msm_associating:
		{
			auto ptr = ((PWLAN_MSM_NOTIFICATION_DATA)data->pData);
			std::cout << "ating reason:" << ptr->wlanReasonCode << std::endl;
		}
		action = "msm_associating";
		break;
		case wlan_notification_msm_associated:
		{
			auto ptr = ((PWLAN_MSM_NOTIFICATION_DATA)data->pData);
			std::cout << "ated reason:" << ptr->wlanReasonCode << std::endl;
		}
		action = "msm_associated";
		break;
		case wlan_notification_msm_authenticating:
		{
			auto ptr = ((PWLAN_MSM_NOTIFICATION_DATA)data->pData);
			std::cout << "auth reason:" << ptr->wlanReasonCode << std::endl;
		}
		action = "msm_authenticating";
		break;
		case wlan_notification_msm_connected:
			action = "msm_connected";
			break;
		case wlan_notification_msm_roaming_start:
			action = "msm_roaming_start";
			break;
		case wlan_notification_msm_roaming_end:
			action = "msm_roaming_end";
			break;
		case wlan_notification_msm_radio_state_change:
			action = "msm_radio_state_change";
			break;
		case wlan_notification_msm_signal_quality_change:
			action = "msm_signal_quality_change";
			printf("信号质量:%lu\n", *(unsigned long*)data->pData);
			break;
		case wlan_notification_msm_disassociating:
			action = "msm_disassociating";
			break;
		case wlan_notification_msm_disconnected:
		{
			auto ptr = ((PWLAN_MSM_NOTIFICATION_DATA)data->pData);
			std::cout << "dis reason:" << ptr->wlanReasonCode << std::endl;
		}
		action = "msm_disconnected";
		break;
		case wlan_notification_msm_peer_join:
			action = "msm_peer_join";
			break;
		case wlan_notification_msm_peer_leave:
			action = "msm_peer_leave";
			break;
		case wlan_notification_msm_adapter_removal:
			action = "msm_adapter_removal";
			break;
		case wlan_notification_msm_adapter_operation_mode_change:
			action = "msm_adapter_operation_mode_change";
			break;
		case wlan_notification_msm_end:
			action = "msm_end";
			break;
		default:break;
		}
	}
	printf("source %d,code %d,size %d,action %s\n", source, code, size, action);
	return;
}


//int main()
//{
//	std::cout << "base:" << WLAN_REASON_CODE_MSMSEC_KEY_SUCCESS_TIMEOUT << std::endl;
//	printf("sizeof %d,%d\n", sizeof(WLAN_CONNECTION_NOTIFICATION_DATA), sizeof(WLAN_MSM_NOTIFICATION_DATA));
//	WifiMgr mgr;
//	if (!mgr.connect("HONOR 9X PRO", "66666666"))
//	{
//		printf("连接wifi失败\n");
//	}
//	//Sleep(10000);
//	//printf("断开连接\n");
//	//mgr.disconnect();
//	//Sleep(10000);
//	getchar();
//	return 0;
//}
#include <Netlistmgr.h>
#include<iostream>
#include"WifiMgr.h"

bool checkIsNetwork() {
	bool bol = true; //是否联网,联网 true,不联网 false   
	CoInitialize(NULL);
	//  通过NLA接口获取网络状态
	IUnknown *pUnknown = NULL;
	HRESULT Result = CoCreateInstance(CLSID_NetworkListManager, NULL, CLSCTX_ALL, IID_IUnknown, (void **)&pUnknown);
	if (SUCCEEDED(Result))
	{
		INetworkListManager *pNetworkListManager = NULL;
		if (pUnknown)
			Result = pUnknown->QueryInterface(IID_INetworkListManager, (void **)&pNetworkListManager);
		if (SUCCEEDED(Result))
		{
			VARIANT_BOOL IsConnect = VARIANT_FALSE;
			if (pNetworkListManager)
				Result = pNetworkListManager->get_IsConnectedToInternet(&IsConnect);
			if (SUCCEEDED(Result))
			{
				bol = (IsConnect == VARIANT_TRUE) ? true : false;
			}
		}
		if (pNetworkListManager)
			pNetworkListManager->Release();
	}
	if (pUnknown)
		pUnknown->Release();
	CoUninitialize();
	return bol;
}

void main()
{
	bool result;
	while (true)
	{
		result=checkIsNetwork();
		if (result)
		{
			//printf("online\n");
		}
		else
		{

			std::cout << "base:" << WLAN_REASON_CODE_MSMSEC_KEY_SUCCESS_TIMEOUT << std::endl;
			printf("sizeof %d,%d\n", sizeof(WLAN_CONNECTION_NOTIFICATION_DATA), sizeof(WLAN_MSM_NOTIFICATION_DATA));

			printf("offline\n");
			WifiMgr mgr;
			if (!mgr.connect("网络名", "密码"))
			{
				printf("连接wifi失败\n");
			}
			Sleep(10000);

		}
	}
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值