
#include "stdafx.h"
#include "WiFiHostedNetwork.h"
#include "WiFiHostedNetworkDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

bool ShowResult(const int Res)
{
	if (Res != WCL_E_SUCCESS)
	{
		CString s;
		s.Format(_T("Error: 0x%.8X"), Res);
		AfxMessageBox(s);
		return false;
	}
	
	return true;
}

CString IntToHex(const int Res)
{
	CString s;
	s.Format(_T("%.8X"), Res);
	return s;
}

CString IntToStr(const int Val)
{
	CString s;
	s.Format(_T("%d"), Val);
	return s;
}

CString BoolToStr(const bool Value)
{
	if (Value)
		return _T("True");
	else
		return _T("False");
}

CString GuidToString(const GUID& Id)
{
	CString res;
	
	LPOLESTR lpszClsID;
	StringFromCLSID(Id, &lpszClsID);
	res = CString(lpszClsID);
	CoTaskMemFree(lpszClsID);
	return res;
}

CString GetEnumName(const wclWiFiHostedNetworkState Enum)
{
	switch (Enum)
	{
		case hnIdle:
			return _T("hnIdle");
		case hnActive:
			return _T("hnActive");
		case hnUnavailable:
			return _T("hnUnavailable");
		default:
			return _T("UNKNOWN");
	}
}

CString GetEnumName(const wclWiFiPhy Enum)
{
	switch (Enum)
	{
		case phyAny:
			return _T("phyAny");
		case phyFhss:
			return _T("phyFhss");
		case phyDsss:
			return _T("phyDsss");
		case phyIr:
			return _T("phyIr");
		case phyOfdm:
			return _T("phyOfdm");
		case phyHrDsss:
			return _T("phyHrDsss");
		case phyErp:
			return _T("phyErp");
		case phyHt:
			return _T("phyHt");
		case phyVht:
			return _T("phyVht");
		case phyUnknown:
			return _T("phyUnknown");
		default:
			return _T("UNKNOWN");
	}
}

CString GetEnumName(const wclWiFiHostedNetworkPeerAuthState Enum)
{
	switch (Enum)
	{
		case asAuthenticated:
			return _T("asAuthenticated");
		case asInvalid:
			return _T("asInvalid");
		default:
			return _T("UNKNOWN");
	}
}

CString GetEnumName(const wclWiFiAuthAlgorithm Enum)
{
	switch (Enum)
	{
		case auOpen:
			return _T("auOpen");
		case auSharedKey:
			return _T("auSharedKey");
		case auWpa:
			return _T("auWpa");
		case auWpaPsk:
			return _T("auWpaPsk");
		case auWpaNone:
			return _T("auWpaNone");
		case auRsna:
			return _T("auRsna");
		case auRsnaPsk:
			return _T("auRsnaPsk");
		case auWpa3:
			return _T("auWpa3");
		case auWpa3Sae:
			return _T("auWpa3Sae");
		case auOwe:
			return _T("auOwe");
		case auWpa3Ent:
			return _T("auWpa3Ent");
		case auUnknown:
			return _T("auUnknown");
		default:
			return _T("UNKNOWN");
	}
}

CString GetEnumName(const wclWiFiCipherAlgorithm Enum)
{
	switch (Enum)
	{
		case caNone:
			return _T("caNone");
		case caWep40:
			return _T("caWep40");
		case caTkip:
			return _T("caTkip");
		case caCcmp:
			return _T("caCcmp");
		case caWep104:
			return _T("caWep104");
		case caBip:
			return _T("caBip");
		case caGcmp128:
			return _T("caGcmp128");
		case caGcmp256:
			return _T("caGcmp256");
		case caCcmp256:
			return _T("caCcmp256");
		case caBipGmac128:
			return _T("caBipGmac128");
		case caBipGmac256:
			return _T("caBipGmac256");
		case caBipCmac256:
			return _T("caBipCmac256");
		case caUseGroup:
			return _T("caUseGroup");
		case caWep:
			return _T("caWep");
		case caUnknown:
			return _T("caUnknown");
		default:
			return _T("UNKNOWN");
	}
}

// CWiFiHostedNetworkDlg dialog




CWiFiHostedNetworkDlg::CWiFiHostedNetworkDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CWiFiHostedNetworkDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CWiFiHostedNetworkDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST_HN_DATA, lvHnData);
	DDX_Control(pDX, IDC_EDIT_HN_SSID, edHnSSID);
	DDX_Control(pDX, IDC_EDIT_HN_NUMBER_OF_PEERS, edHnNumberOfPeers);
	DDX_Control(pDX, IDC_EDIT_HN_KEY, edHnKey);
	DDX_Control(pDX, IDC_CHECK_HN_PERSISTENT, cbHnPersistent);
}

BEGIN_MESSAGE_MAP(CWiFiHostedNetworkDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BUTTON_HN_OPEN, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnOpen)
	ON_BN_CLICKED(IDC_BUTTON_HN_CLOSE, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnClose)
	ON_BN_CLICKED(IDC_BUTTON_HN_GET_CONNECTION_SETTINGS, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnGetConnectionSettings)
	ON_BN_CLICKED(IDC_BUTTON_HN_CLEAR, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnClear)
	ON_BN_CLICKED(IDC_BUTTON_HN_GET_KEY, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnGetKey)
	ON_BN_CLICKED(IDC_BUTTON_HN_GET_PROFILE, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnGetProfile)
	ON_BN_CLICKED(IDC_BUTTON_HN_GET_SECURITY_SETTINGS, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnGetSecuritySettings)
	ON_BN_CLICKED(IDC_BUTTON_HN_GET_STATUS, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnGetStatus)
	ON_BN_CLICKED(IDC_BUTTON_HN_REFRESH_SECURITY_SETTINGS, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnRefreshSecuritySettings)
	ON_BN_CLICKED(IDC_BUTTON_HN_SET_SETTINGS, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnSetSettings)
	ON_BN_CLICKED(IDC_BUTTON_HN_SET_KEY, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnSetKey)
	ON_BN_CLICKED(IDC_BUTTON_HN_ENABLE, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnEnable)
	ON_BN_CLICKED(IDC_BUTTON_HN_DISABLE, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnDisable)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_BUTTON_HN_GET_STATE, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnGetState)
	ON_BN_CLICKED(IDC_BUTTON_HN_RESTART, &CWiFiHostedNetworkDlg::OnBnClickedButtonHnRestart)
END_MESSAGE_MAP()


// CWiFiHostedNetworkDlg message handlers

BOOL CWiFiHostedNetworkDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here
	lvHnData.InsertColumn(0, _T("Parameter name"), 0, 200);
	lvHnData.InsertColumn(1, _T("Parameter value"), 0, 350);
	lvHnData.SetExtendedStyle(lvHnData.GetExtendedStyle() | LVS_EX_FULLROWSELECT);

	edHnSSID.SetWindowText(_T("MyHostedNetwork"));
	edHnNumberOfPeers.SetWindowText(_T("5"));
	edHnKey.SetWindowText(_T("123456789"));

	__hook(&CwclWiFiHostedNetwork::AfterOpen, &wclWiFiHostedNetwork, &CWiFiHostedNetworkDlg::HnAfterOpen);
	__hook(&CwclWiFiHostedNetwork::BeforeClose, &wclWiFiHostedNetwork, &CWiFiHostedNetworkDlg::HnBeforeClose);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CWiFiHostedNetworkDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CWiFiHostedNetworkDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnOpen()
{
	ShowResult(wclWiFiHostedNetwork.Open());
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnClose()
{
	ShowResult(wclWiFiHostedNetwork.Close());
}

void CWiFiHostedNetworkDlg::HnAfterOpen(void* Sender)
{
	UNREFERENCED_PARAMETER(Sender);

	AfxMessageBox(_T("WiFi Hosted Network opened"));
}

void CWiFiHostedNetworkDlg::HnBeforeClose(void* Sender)
{
	UNREFERENCED_PARAMETER(Sender);

	AfxMessageBox(_T("WiFi Hosted Network closing"));
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnGetConnectionSettings()
{
	HnClear();

	wclWiFiHostedNetworkConnectionSettings Settings;
	if (ShowResult(wclWiFiHostedNetwork.GetConnectionSettings(Settings)))
	{
		HnAddData(_T("SSID"), Settings.Ssid.c_str());
		HnAddData(_T("Max. number of peers"), IntToStr(Settings.MaxNumberOfPeers));
	}
}

void CWiFiHostedNetworkDlg::HnClear()
{
	lvHnData.DeleteAllItems();
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnClear()
{
	HnClear();
}

void CWiFiHostedNetworkDlg::HnAddData(const CString& ParamName, 
	const CString& ParamValue)
{
	int i = lvHnData.GetItemCount();
	lvHnData.InsertItem(i, ParamName);
	lvHnData.SetItemText(i, 1, ParamValue);
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnGetKey()
{
	HnClear();

	unsigned long KeyLength;
	void* KeyData;
	bool IsPassPhrase;
	bool Persistent;
	CString Str;
	
	if (ShowResult(wclWiFiHostedNetwork.GetKey(KeyLength, KeyData, IsPassPhrase, Persistent)))
	{
		if (IsPassPhrase)
			Str = CString((PCHAR)KeyData);
		else
			Str = _T("Binary data");
			
		HnAddData(_T("Key length"), IntToStr(KeyLength));
		HnAddData(_T("Key data"), Str);
		HnAddData(_T("Is pass phrase"), BoolToStr(IsPassPhrase));
		HnAddData(_T("Persistent"), BoolToStr(Persistent));
		
		wclWiFiHostedNetwork.FreeMemory(KeyData);
	}
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnGetProfile()
{
	HnClear();

	tstring XML;
	
	if (ShowResult(wclWiFiHostedNetwork.GetProfile(XML)))
		HnAddData(_T("Profile XML"), XML.c_str());
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnGetSecuritySettings()
{
	HnClear();
	
	wclWiFiAuthCipherPair Settings;
	if (ShowResult(wclWiFiHostedNetwork.GetSecuritySettings(Settings)))
	{
		HnAddData(_T("Auth algorithm"), GetEnumName(Settings.AuthAlgorithm));
		HnAddData(_T("Cipher algorithm"), GetEnumName(Settings.CipherAlgorithm));
	}
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnGetStatus()
{
	HnClear();

	wclWiFiHostedNetworkStatus Status;
	if (ShowResult(wclWiFiHostedNetwork.GetStatus(Status)))
	{
		HnAddData(_T("State"), GetEnumName(Status.State));
		HnAddData(_T("Interface ID"), GuidToString(Status.Id));
		HnAddData(_T("BSS ID"), Status.BssId.c_str());
		HnAddData(_T("Phy"), GetEnumName(Status.Phy));
		HnAddData(_T("ChannelFrequency"), IntToStr(Status.ChannelFrequency));
		
		tstring Address;
		int Res = wclWiFiHostedNetwork.GetLocalIp(Address);
		if (Res != WCL_E_SUCCESS)
			Address = _T("Get failed: 0x") + IntToHex(Res);
		HnAddData(_T("Local IP"), CString(Address.c_str()));
		
		if (Status.Peers.size() > 0)
		{
			for (unsigned int i = 0; i < Status.Peers.size(); i++)
			{
				HnAddData(_T("Peer[") + IntToStr(i) + _T("] MAC"),
					Status.Peers[i].Mac.c_str());
				Res = wclWiFiHostedNetwork.GetRemoteIp(Status.Peers[i].Mac, Address);
				if (Res == WCL_E_SUCCESS)
					HnAddData(_T("Peer[") + IntToStr(i) + _T("] IP"), CString(Address.c_str()));
				else
					HnAddData(_T("Peer[") + IntToStr(i) + _T("] IP"), _T("Get failed: 0x") + IntToHex(Res));
				HnAddData(_T("Peer[") + IntToStr(i) + _T("] auth state"),
					GetEnumName(Status.Peers[i].AuthState));
			}
		}
	}
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnRefreshSecuritySettings()
{
	ShowResult(wclWiFiHostedNetwork.RefreshSecuritySettings());
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnSetSettings()
{
	wclWiFiHostedNetworkConnectionSettings Settings;
	
	CString s;
	edHnSSID.GetWindowText(s);
	Settings.Ssid = tstring(s);

	edHnNumberOfPeers.GetWindowText(s);
	int i = _ttoi(s.GetBuffer());
	Settings.MaxNumberOfPeers = i;
	
	ShowResult(wclWiFiHostedNetwork.SetConnectionSettings(Settings));
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnSetKey()
{
	CString s;
	edHnKey.GetWindowText(s);
	CStringA sa(s);
	ShowResult(wclWiFiHostedNetwork.SetKey(sa.GetLength() + 1, sa.GetBuffer(),
		true, cbHnPersistent.GetCheck() != FALSE));
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnEnable()
{
	ShowResult(wclWiFiHostedNetwork.SetState(true));
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnDisable()
{
	ShowResult(wclWiFiHostedNetwork.SetState(false));
}

void CWiFiHostedNetworkDlg::OnDestroy()
{
	CDialog::OnDestroy();

	wclWiFiHostedNetwork.Close();
	__unhook(&wclWiFiHostedNetwork);
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnGetState()
{
	HnClear();
	
	bool State;
	if (ShowResult(wclWiFiHostedNetwork.GetState(State)))
		HnAddData(_T("Enabled"), BoolToStr(State));
}

void CWiFiHostedNetworkDlg::OnBnClickedButtonHnRestart()
{
	ShowResult(wclWiFiHostedNetwork.Restart());
}
