// BeaconsDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Beacons.h"
#include "BeaconsDlg.h"
#include <cmath>

#include "..\..\..\..\Source\Bluetooth\wclUUIDs.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CBeaconsDlg dialog




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

void CBeaconsDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST_LOG, ListBox);
	DDX_Control(pDX, IDC_LIST_FRAMES, lbFrames);
	DDX_Control(pDX, IDC_EDIT_SCAN_INTERVAL, edScanInterval);
	DDX_Control(pDX, IDC_EDIT_SCAN_WINDOW, edScanWindow);
	DDX_Control(pDX, IDC_EDIT_ADV_INTERVAL, edAdvInterval);
	DDX_Control(pDX, IDC_CHECK_IBEACON, cbIBeacon);
	DDX_Control(pDX, IDC_CHECK_PROXIMITY_BEACON, cbProximityBeacon);
	DDX_Control(pDX, IDC_CHECK_ALT_BEACON, cbAltBeacon);
	DDX_Control(pDX, IDC_CHECK_EDDYSTONE_UID, cbEddystoneUid);
	DDX_Control(pDX, IDC_CHECK_EDDYSTONE_URL, cbEddystoneUrl);
	DDX_Control(pDX, IDC_CHECK_128_SOL_UUID, cb128SolUuid);
	DDX_Control(pDX, IDC_CHECK_MANUFACTURER, cbManufacturer);
	DDX_Control(pDX, IDC_CHECK_16_UUID_SERVICE, cb16UuidService);
	DDX_Control(pDX, IDC_CHECK_32_UUID_SERVICE, cb32UuidService);
	DDX_Control(pDX, IDC_CHECK_128_UUID_SERVICE, cb128UuidService);
	DDX_Control(pDX, IDC_CHECK_16_UUID_DATA, cb16UuidData);
	DDX_Control(pDX, IDC_CHECK_32_UUID_DATA, cb32UuidData);
	DDX_Control(pDX, IDC_CHECK_128_UUID_DATA, cb128UuidData);
	DDX_Control(pDX, IDC_CHECK_CUSTOM_RAW, cbCustomRaw);
	DDX_Control(pDX, IDC_CHECK_SE_EXTENDED, cbUseExtended);
	DDX_Control(pDX, IDC_CHECK_ANONYMOUS, cbAnonymous);
	DDX_Control(pDX, IDC_CHECK_INCLUDE_TX_RSSI, cbIncludeTxRssi);
	DDX_Control(pDX, IDC_CHECK1, cbScanMode);
}

BEGIN_MESSAGE_MAP(CBeaconsDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_BUTTON_OPEN, &CBeaconsDlg::OnBnClickedButtonOpen)
	ON_BN_CLICKED(IDC_BUTTON_CLOSE, &CBeaconsDlg::OnBnClickedButtonClose)
	ON_BN_CLICKED(IDC_BUTTON_START, &CBeaconsDlg::OnBnClickedButtonStart)
	ON_BN_CLICKED(IDC_BUTTON_STOP, &CBeaconsDlg::OnBnClickedButtonStop)
	ON_BN_CLICKED(IDC_BUTTON_CLEAR, &CBeaconsDlg::OnBnClickedButtonClear)
	ON_BN_CLICKED(IDC_BUTTON_CLEAR_LOG, &CBeaconsDlg::OnBnClickedButtonClearLog)
	ON_BN_CLICKED(IDC_BUTTON_STOP_ADVERTISING, &CBeaconsDlg::OnBnClickedButtonStopAdvertising)
	ON_BN_CLICKED(IDC_BUTTON_START_ADVERTISING, &CBeaconsDlg::OnBnClickedButtonStartAdvertising)
	ON_WM_HSCROLL()
	ON_BN_CLICKED(IDC_BUTTON1, &CBeaconsDlg::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON3, &CBeaconsDlg::OnBnClickedButton3)
END_MESSAGE_MAP()


// CBeaconsDlg message handlers

BOOL CBeaconsDlg::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

	cbIBeacon.SetCheck(FALSE);
	cbProximityBeacon.SetCheck(FALSE);
	cbAltBeacon.SetCheck(FALSE);
	cbEddystoneUid.SetCheck(FALSE);
	cbEddystoneUrl.SetCheck(FALSE);
	cb128SolUuid.SetCheck(FALSE);
	cbManufacturer.SetCheck(FALSE);
	cb16UuidService.SetCheck(FALSE);
	cb32UuidService.SetCheck(FALSE);
	cb128UuidService.SetCheck(FALSE);
	cb16UuidData.SetCheck(FALSE);
	cb32UuidData.SetCheck(FALSE);
	cb128UuidData.SetCheck(FALSE);
	cbCustomRaw.SetCheck(FALSE);

	edAdvInterval.SetWindowText(IntToStr((unsigned long)WCL_BLE_DEFAULT_ADVERTISING_INTERVAL));

	DefaultScanParams();

	// TODO: Add extra initialization here
	__hook(&CwclBluetoothManager::AfterOpen, &wclBluetoothManager,
		&CBeaconsDlg::wclBluetoothManagerAfterOpen);
	__hook(&CwclBluetoothManager::BeforeClose, &wclBluetoothManager,
		&CBeaconsDlg::wclBluetoothManagerBeforeClose);
	__hook(&CwclBluetoothManager::OnStatusChanged, &wclBluetoothManager,
		&CBeaconsDlg::wclBluetoothManagerStatusChanged);

	__hook(&CwclBluetoothLeBeaconWatcher::OnStarted, &wclBluetoothLeBeaconWatcher, 
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherStarted);
	__hook(&CwclBluetoothLeBeaconWatcher::OnStopped, &wclBluetoothLeBeaconWatcher, 
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherStopped);
	__hook(&CwclBluetoothLeBeaconWatcher::OnProximityBeaconFrame, &wclBluetoothLeBeaconWatcher,
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherProximityBeaconFrame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAltBeaconFrame, &wclBluetoothLeBeaconWatcher, 
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAltBeaconFrame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnManufacturerRawFrame, &wclBluetoothLeBeaconWatcher,
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherManufacturerRawFrame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAdvertisementRawFrame, &wclBluetoothLeBeaconWatcher, 
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementRawFrame);	
	__hook(&CwclBluetoothLeBeaconWatcher::OnEddystoneUidFrame, &wclBluetoothLeBeaconWatcher, 
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherEddystoneUidFrame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnEddystoneUrlFrame, &wclBluetoothLeBeaconWatcher, 
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherEddystoneUrlFrame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnEddystoneTlmFrame, &wclBluetoothLeBeaconWatcher, 
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherEddystoneTlmFrame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAdvertisementFrameInformation, &wclBluetoothLeBeaconWatcher,
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementFrameInformation);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAdvertisementUuidFrame, &wclBluetoothLeBeaconWatcher,
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementUuidFrame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAdvertisementExtFrameInformation, &wclBluetoothLeBeaconWatcher, 
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementExtFrameInformation);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAdvertisementService128DataFrame, &wclBluetoothLeBeaconWatcher,
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementService128DataFrame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAdvertisementService32DataFrame, &wclBluetoothLeBeaconWatcher,
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementService32DataFrame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAdvertisementService16DataFrame, &wclBluetoothLeBeaconWatcher,
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementService16DataFrame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAdvertisementServiceSol128Frame, &wclBluetoothLeBeaconWatcher,
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementServiceSol128Frame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAdvertisementServiceSol32Frame, &wclBluetoothLeBeaconWatcher, 
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementServiceSol32Frame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAdvertisementServiceSol16Frame, &wclBluetoothLeBeaconWatcher, 
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementServiceSol16Frame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAdvertisementReceived, &wclBluetoothLeBeaconWatcher, 
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementReceived);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAdvertisementTxPowerLevelFrame, &wclBluetoothLeBeaconWatcher, 
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementTxPowerLevelFrame);
	__hook(&CwclBluetoothLeBeaconWatcher::OnAdvertisementAppearanceFrame, &wclBluetoothLeBeaconWatcher, 
		&CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementAppearanceFrame);

	__hook(&CwclBluetoothLeAdvertiser::OnStarted, &wclBluetoothLeAdvertiser,
		&CBeaconsDlg::wclBluetoothLeAdvertiserStarted);
	__hook(&CwclBluetoothLeAdvertiser::OnStopped, &wclBluetoothLeAdvertiser,
		&CBeaconsDlg::wclBluetoothLeAdvertiserStopped);
	
	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 CBeaconsDlg::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 CBeaconsDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

CString CBeaconsDlg::FloatToStr(const double f) const
{
	CString s;
	s.Format(_T("%f"), f);
	return s;
}

CString CBeaconsDlg::IntToStr(const char i) const
{
	CString s;
	s.Format(_T("%d"), i);
	return s;
}

CString CBeaconsDlg::IntToStr(const size_t i) const
{
	CString s;
	s.Format(_T("%d"), i);
	return s;
}

CString CBeaconsDlg::IntToStr(const unsigned char i) const
{
	CString s;
	s.Format(_T("%d"), i);
	return s;
}

CString CBeaconsDlg::IntToStr(const unsigned long i) const
{
	CString s;
	s.Format(_T("%d"), i);
	return s;
}

CString CBeaconsDlg::IntToHex(const unsigned char i) const
{
	CString s;
	s.Format(_T("%.2X"), i);
	return s;
}

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

CString CBeaconsDlg::IntToHex(const unsigned short i) const
{
	CString s;
	s.Format(_T("%.4X"), i);
	return s;
}

CString CBeaconsDlg::IntToHex(const __int64 i) const
{
	CString s;
	s.Format(_T("%.4X%.8X"), static_cast<INT32>((i >> 32) & 0x00000FFFF),
		static_cast<INT32>(i) & 0xFFFFFFFF);
	return s;
}

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

	wclBluetoothLeBeaconWatcher.Stop();
	wclBluetoothManager.Close();

	// On Visual Studio 2015 and above the __unhook() poroduces warning C4458
	// We we have to supress it. By some reason it can not be disabled by pragma
	// so we disabled it in the project settings.
	__unhook(&wclBluetoothManager);
	__unhook(&wclBluetoothLeBeaconWatcher);
	__unhook(&wclBluetoothLeAdvertiser);
}

void CBeaconsDlg::OnBnClickedButtonOpen()
{
	int Res = wclBluetoothManager.Open();
	if (Res != WCL_E_SUCCESS)
		AfxMessageBox(_T("Error: 0x") + IntToHex(Res));
}

void CBeaconsDlg::OnBnClickedButtonClose()
{
	int Res = wclBluetoothManager.Close();
	if (Res != WCL_E_SUCCESS)
		AfxMessageBox(_T("Error: 0x") + IntToHex(Res));
}

void CBeaconsDlg::OnBnClickedButtonStart()
{
	CwclBluetoothRadio* Radio = GetRadio();
	if (Radio != NULL)
	{
		wclBluetoothLeScanningMode Mode;
		if (cbScanMode.GetCheck())
			Mode = smActive;
		else
			Mode = smPassive;
		
		CString s;
		edScanInterval.GetWindowText(s);
		unsigned short Interval = LOWORD(_ttoi(s.GetBuffer()));
		edScanWindow.GetWindowText(s);
		unsigned short Window = LOWORD(_ttoi(s.GetBuffer()));
		
		int Res = wclBluetoothLeBeaconWatcher.Start(Radio, Mode, Interval, Window);
		if (Res != WCL_E_SUCCESS)
			AfxMessageBox(_T("Error: 0x") + IntToHex(Res));
	}
}

void CBeaconsDlg::OnBnClickedButtonStop()
{
	if (!wclBluetoothManager.Active)
		AfxMessageBox(_T("Bluetooth Manager was not opened"));
	else
	{
		int Res = wclBluetoothLeBeaconWatcher.Stop();
		if (Res != WCL_E_SUCCESS)
			AfxMessageBox(_T("Error: 0x") + IntToHex(Res));
	}
}

void CBeaconsDlg::wclBluetoothManagerAfterOpen(void* Sender)
{
	UNREFERENCED_PARAMETER(Sender);

	ListBox.AddString(_T("Bluetooth Manager Opened"));
}

void CBeaconsDlg::wclBluetoothManagerBeforeClose(void* Sender)
{
	UNREFERENCED_PARAMETER(Sender);

	ListBox.AddString(_T("Bluetooth Manager Closed"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherStarted(void* Sender)
{
	UNREFERENCED_PARAMETER(Sender);

	ListBox.AddString(_T("Beacons Monitoring Started"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherStopped(void* Sender)
{
	UNREFERENCED_PARAMETER(Sender);

	ListBox.AddString(_T("Beacons Monitoring Stopped"));	
}

CString CBeaconsDlg::ConvertTime(const __int64 Timestamp) const
{
	ULARGE_INTEGER li;
	FILETIME ft;
	SYSTEMTIME st;

	li.QuadPart = Timestamp;
	ft.dwLowDateTime = li.LowPart;
	ft.dwHighDateTime = li.HighPart;
	FileTimeToLocalFileTime(&ft, &ft);
	FileTimeToSystemTime(&ft, &st);
	CString DateTimeStr;
	DateTimeStr.Format(_T("%d-%02d-%02d %02d:%02d:%02d.%03d"),
		st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute,
		st.wSecond, st.wMilliseconds);
	return DateTimeStr;
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherProximityBeaconFrame(void* Sender, const __int64 Address,
	const __int64 Timestamp, const char Rssi, const unsigned short CompanyId, const unsigned short Major,
	const unsigned short Minor, const GUID& Uuid, const char TxRssi, 
	const wclBluetoothLeAdvertisementFrameRawData& Data)
{
	UNREFERENCED_PARAMETER(Sender);
	UNREFERENCED_PARAMETER(Data);

	LPOLESTR Guid;
	StringFromCLSID(Uuid, &Guid);
	
	// Clculate distance.
	double Dist = pow(10.0, (double)(TxRssi - Rssi) / 20.0);
	
	lbFrames.AddString(_T("PROXIMITY BEACON FRAME"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Company ID: ") + IntToHex(CompanyId));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	
	lbFrames.AddString(_T("  UUID: ") + CString(Guid));
	lbFrames.AddString(_T("  Major: ") + IntToHex(Major));
	lbFrames.AddString(_T("  Minor: ") + IntToHex(Minor));
	lbFrames.AddString(_T("  TX RSSI: ") + IntToStr(TxRssi));
	lbFrames.AddString(_T("  Distance: ") + FloatToStr(Dist));

	DumpData(Data);
	
	lbFrames.AddString(_T("-------------------------------------------------------"));
	
	CoTaskMemFree(Guid);
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAltBeaconFrame(void* Sender, const __int64 Address,
	const __int64 Timestamp, const char Rssi, const unsigned short CompanyId, const unsigned short Major,
	const unsigned short Minor, const GUID& Uuid, const char TxRssi, const unsigned char Reserved, 
	const wclBluetoothLeAdvertisementFrameRawData& Data)
{
	UNREFERENCED_PARAMETER(Sender);
	UNREFERENCED_PARAMETER(Data);

	LPOLESTR Guid;
	StringFromCLSID(Uuid, &Guid);
	
	// Clculate distance.
	double Dist = pow(10.0, (double)(TxRssi - Rssi) / 20.0);
	
	lbFrames.AddString(_T("ALT BEACON FRAME"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Company ID: ") + IntToHex(CompanyId));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	
	lbFrames.AddString(_T("  UUID: ") + CString(Guid));
	lbFrames.AddString(_T("  Major: ") + IntToHex(Major));
	lbFrames.AddString(_T("  Minor: ") + IntToHex(Minor));
	lbFrames.AddString(_T("  Reserved: ") + IntToHex(Reserved));
	lbFrames.AddString(_T("  TX RSSI: ") + IntToStr(TxRssi));
	lbFrames.AddString(_T("  Distance: ") + FloatToStr(Dist));

	DumpData(Data);
	
	lbFrames.AddString(_T("-------------------------------------------------------"));
	
	CoTaskMemFree(Guid);
}

void CBeaconsDlg::wclBluetoothManagerStatusChanged(void* Sender, CwclBluetoothRadio* const Radio)
{
	UNREFERENCED_PARAMETER(Sender);

	CString Str;
	if (Radio->Available)
		Str = _T("AVAILABLE");
	else
		Str = _T("UNAVAILABLE");
	ListBox.AddString(_T("Radio ") + CString(Radio->ApiName.c_str()) + _T(" status changed: ") + Str);
}

void CBeaconsDlg::OnBnClickedButtonClear()
{
	lbFrames.ResetContent();
}

void CBeaconsDlg::OnBnClickedButtonClearLog()
{
	ListBox.ResetContent();
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherManufacturerRawFrame(void* Sender, const __int64 Address,
	const __int64 Timestamp, const char Rssi, const unsigned short CompanyId, 
	const wclBluetoothLeAdvertisementFrameRawData& Data)
{
	UNREFERENCED_PARAMETER(Sender);

	lbFrames.AddString(_T("UNKNOWN MANUFACTURER RAW FRAME"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Company ID: ") + IntToHex(CompanyId));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	
	DumpData(Data);
	
	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementRawFrame(void* Sender, const __int64 Address,
	const __int64 Timestamp, const char Rssi, const unsigned char DataType, 
	const wclBluetoothLeAdvertisementFrameRawData& Data)
{
	UNREFERENCED_PARAMETER(Sender);

	lbFrames.AddString(_T("UNKNOWN RAW FRAME"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	
	lbFrames.AddString(_T("  Data type: ") + IntToHex(DataType));
	
	DumpData(Data);
	
	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherEddystoneUidFrame(void* Sender, const __int64 Address,
	const __int64 Timestamp, const char Rssi, const char TxRssi, const GUID& Uuid, 
	const wclBluetoothLeAdvertisementFrameRawData& Data)
{
	UNREFERENCED_PARAMETER(Sender);
	UNREFERENCED_PARAMETER(Data);

	LPOLESTR Guid;
	StringFromCLSID(Uuid, &Guid);
	
	// Clculate distance.
	double Dist = pow(10.0, (double)(TxRssi - 41.0 - Rssi) / 20.0);
	
	lbFrames.AddString(_T("EDDYSTONE UID FRAME"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	
	lbFrames.AddString(_T("  UUID: ") + CString(Guid));

	lbFrames.AddString(_T("  TX RSSI: ") + IntToStr(TxRssi));
	lbFrames.AddString(_T("  Distance: ") + FloatToStr(Dist));

	DumpData(Data);
	
	lbFrames.AddString(_T("-------------------------------------------------------"));
	
	CoTaskMemFree(Guid);
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherEddystoneUrlFrame(void* Sender, const __int64 Address,
	const __int64 Timestamp, const char Rssi, const char TxRssi, const tstring& Url)
{
	UNREFERENCED_PARAMETER(Sender);

	// Clculate distance.
	double Dist = pow(10.0, (double)(TxRssi - 41.0 - Rssi) / 20.0);
	
	lbFrames.AddString(_T("EDDYSTONE URL FRAME"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	
	lbFrames.AddString(_T("  URL: ") + CString(Url.c_str()));

	lbFrames.AddString(_T("  TX RSSI: ") + IntToStr(TxRssi));
	lbFrames.AddString(_T("  Distance: ") + FloatToStr(Dist));

	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherEddystoneTlmFrame(void* Sender, const __int64 Address,
	const __int64 Timestamp, const char Rssi, const unsigned long AdvCnt, const unsigned short Batt,
	const unsigned long SecCnt, const double Temp, const wclBluetoothLeAdvertisementFrameRawData& Data)
{
	UNREFERENCED_PARAMETER(Sender);
	UNREFERENCED_PARAMETER(Data);

	lbFrames.AddString(_T("ADDYSTONE TLM FRAME"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	
	lbFrames.AddString(_T("  Advertisements counter: ") + IntToStr(AdvCnt));
	lbFrames.AddString(_T("  Battery (mv): ") + IntToStr((unsigned long)Batt));
	lbFrames.AddString(_T("  Seconds running: ") + FloatToStr(SecCnt / 10));
	lbFrames.AddString(_T("  Temperature: ") + FloatToStr(Temp));

	DumpData(Data);
	
	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::OnBnClickedButtonStopAdvertising()
{
	int Res = wclBluetoothLeAdvertiser.Stop();
	if (Res != WCL_E_SUCCESS)
		ListBox.AddString(_T("Stop advertiser failed: 0x") + IntToHex(Res));
}

void CBeaconsDlg::OnBnClickedButtonStartAdvertising()
{
	wclBluetoothLeAdvertiser.Stop();
	
	static const GUID BEACON_UUID = { 0x09039835, 0x4A80, 0x443B, { 0x87, 0xAA, 0xDC, 0x56, 0x5D, 0x09, 0xEA, 0x61 } };

	CwclBluetoothRadio* Radio = GetRadio();
	if (Radio != NULL)
	{
		CwclBluetoothLeAdvertisement * Adv;

		// Create and add iBeacon advdertisement.
		if (cbIBeacon.GetCheck())
		{
			Adv = new CwclBluetoothLeiBeaconAdvertisement(-5, 0x0101, 0x0202,
				BEACON_UUID);
			AddAdvertisement(Adv);
		}
		
		// Create and add Proximity Beacon advertisement.
		if (cbProximityBeacon.GetCheck())
		{
			Adv = new CwclBluetoothLeProximityBeaconAdvertisement(-5, 0x0101, 0x0202,
				BEACON_UUID, 0xFFFE);
			AddAdvertisement(Adv);
		}
		
		// Create and add Alt Beacon advertisement.
		if (cbAltBeacon.GetCheck())
		{
			Adv = new CwclBluetoothLeAltBeaconAdvertisement(-5, 0x0101, 0x0202,
				BEACON_UUID, 0xFFFE, 0x11);
			AddAdvertisement(Adv);
		}
		
		// Create and add Eddystone UID advertisement.
		if (cbEddystoneUid.GetCheck())
		{
			Adv = new CwclBluetoothLeEddystoneUidBeaconAdvertisement(-5,
				BEACON_UUID);
			AddAdvertisement(Adv);
		}
		
		// Create and add Eddystone URL.
		if (cbEddystoneUrl.GetCheck())
		{
			Adv = new CwclBluetoothLeEddystoneUrlBeaconAdvertisement(-5, _T("https://www.btframework.com"));
			AddAdvertisement(Adv);
		}
		
		// Create and add custom advertisement.
		wclBluetoothLeAdvertisementFrameRawData Data;

		if (cb128SolUuid.GetCheck())
		{
			Data.resize(16);
			Data[0] = 0xD0;
			Data[1] = 0x00;
			Data[2] = 0x2D;
			Data[3] = 0x12;
			Data[4] = 0x1E;
			Data[5] = 0x4B;
			Data[6] = 0x0F;
			Data[7] = 0xA4;
			Data[8] = 0x99;
			Data[9] = 0x4E;
			Data[10] = 0xCE;
			Data[11] = 0xB5;
			Data[12] = 0x31;
			Data[13] = 0xF4;
			Data[14] = 0x05;
			Data[15] = 0x79;
			Adv = new CwclBluetoothLeCustomAdvertisement(LE_GAP_AD_TYPE_SERVICE_SOL_UUIDS_128, Data);
			AddAdvertisement(Adv);
		}
		
		// Create and add manufacturer specific advertisement.
		if (cbManufacturer.GetCheck())
		{
			Data.resize(2);
			Data[0] = 0x12;
			Data[1] = 0x34;
			Adv = new CwclBluetoothLeManufacturerAdvertisement(0x010E, Data);
			AddAdvertisement(Adv);
		}

		if (cb16UuidService.GetCheck())
		{
			Adv = new CwclBluetoothLe16ServiceAdvertisement(0x9835);
			AddAdvertisement(Adv);
		}
		
		if (cb32UuidService.GetCheck())
		{
			Adv = new CwclBluetoothLe32ServiceAdvertisement(0x09039835);
			AddAdvertisement(Adv);
		}
		
		if (cb128UuidService.GetCheck())
		{
			Adv = new CwclBluetoothLe128ServiceAdvertisement(BEACON_UUID);
			AddAdvertisement(Adv);
		}
		
		if (cb16UuidData.GetCheck())
		{
			Data.resize(2);
			Data[0] = 0x12;
			Data[1] = 0x34;
			Adv = new CwclBluetoothLe16ServiceDataAdvertisement(0x9835, Data);
			AddAdvertisement(Adv);
		}
		
		if (cb32UuidData.GetCheck())
		{
			Data.resize(2);
			Data[0] = 0x12;
			Data[1] = 0x34;
			Adv = new CwclBluetoothLe32ServiceDataAdvertisement(0x09039835, Data);
			AddAdvertisement(Adv);
		}
		
		if (cb128UuidData.GetCheck())
		{
			Data.resize(2);
			Data[0] = 0x12;
			Data[1] = 0x34;
			Adv = new CwclBluetoothLe128ServiceDataAdvertisement(BEACON_UUID,
				Data);
			AddAdvertisement(Adv);
		}

		if (cbCustomRaw.GetCheck())
		{
			Data.resize(20);
			
			// 16 bit Service Data
			Data[0] = 0x09; // Length.
			Data[1] = LE_GAP_AD_TYPE_SERVICE_DATA_16; // Data type.
			Data[2] = 0x12; // 16 UUID LO BYTE
			Data[3] = 0x34; // 16 UUID HI BYTE
			Data[4] = 0xFF; // Data 1st byte
			Data[5] = 0xFE; // Data 2st byte
			Data[6] = 0xFD; // Data 3st byte
			Data[7] = 0xFC; // Data 4st byte
			Data[8] = 0xFB; // Data 5st byte
			Data[9] = 0xFA; // Data 6st byte
			// Manufacturer specific data.
			Data[10] = 0x09; // Length.
			Data[11] = LE_GAP_AD_TYPE_MANUFACTURER; // Data type.
			Data[12] = 0x10; // Company ID.
			Data[13] = 0x12; // Company ID.
			Data[14] = 0x01; // Data 1st byte
			Data[15] = 0x02; // Data 2st byte
			Data[16] = 0x03; // Data 3st byte
			Data[17] = 0x04; // Data 4st byte
			Data[18] = 0x05; // Data 5st byte
			Data[19] = 0x06; // Data 6st byte
			
			Adv = new CwclBluetoothLeRawAdvertisement(Data);
			AddAdvertisement(Adv);
		}
		
		CString s;
		edAdvInterval.GetWindowText(s);
		unsigned short Interval = LOWORD(_ttoi(s.GetBuffer()));

		wclBluetoothLeAdvertiser.UseExtendedAdvertisement = (cbUseExtended.GetCheck() != FALSE);
		wclBluetoothLeAdvertiser.Anonymous = (cbAnonymous.GetCheck() != FALSE);
		wclBluetoothLeAdvertiser.IncludeTxRssi = (cbIncludeTxRssi.GetCheck() != FALSE);
		wclBluetoothLeAdvertiser.PreferredTxRssi = 10;
		int Res = wclBluetoothLeAdvertiser.Start(Radio, Interval);
		if (Res != WCL_E_SUCCESS)
		{
			ListBox.AddString(_T("Start advertiser failed: 0x") + IntToHex(Res));
			wclBluetoothLeAdvertiser.Clear();
		}
	}
}

void CBeaconsDlg::AddAdvertisement(CwclBluetoothLeAdvertisement* const Adv)
{
	int Res = wclBluetoothLeAdvertiser.Add(Adv);
	if (Res != WCL_E_SUCCESS)
	{
		ListBox.AddString(_T("Add advertisement failed: 0x") + IntToHex(Res));
		delete Adv;
	}
}

void CBeaconsDlg::wclBluetoothLeAdvertiserStarted(void* Sender)
{
	UNREFERENCED_PARAMETER(Sender);

	ListBox.AddString(_T("Bluetooth LE Advertising Started"));

	EnableAdvertisements(FALSE);
}

void CBeaconsDlg::wclBluetoothLeAdvertiserStopped(void* Sender)
{
	UNREFERENCED_PARAMETER(Sender);

	ListBox.AddString(_T("Bluetooth LE Advertising Stopped"));
	wclBluetoothLeAdvertiser.Clear();

	EnableAdvertisements(TRUE);
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementFrameInformation(
	void* Sender, const __int64 Address, const __int64 Timestamp, const char Rssi,
	const tstring& Name, const wclBluetoothLeAdvertisementType PacketType,
	const wclBluetoothLeAdvertisementFlags& Flags)
{
	UNREFERENCED_PARAMETER(Sender);

	lbFrames.AddString(_T("FRAME INFORMATION"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	lbFrames.AddString(_T("  Name: ") + CString(Name.c_str()));
	
	CString Str;
	switch (PacketType)
	{
		case atConnectableUndirected:
			Str = _T("Connectable Undirected");
			break;
		case atConnectableDirected:
			Str = _T("Connectable Directed");
			break;
		case atScannableUndirected:
			Str = _T("Scannable Undirecte");
			break;
		case atNonConnectableUndirected:
			Str = _T("Non Connectable Undirected");
			break;
		case atScanResponse:
			Str = _T("Scan Response");
			break;
		default:
			Str = _T("Unknown");
			break;
	}
	lbFrames.AddString(_T("  Frame type: ") + Str);
	
	Str = _T("[");
	if (Flags.find(afLimitedDiscoverableMode) != Flags.end())
		Str = Str + _T(" afLimitedDiscoverableMode");
	if (Flags.find(afGeneralDiscoverableMode) != Flags.end())
		Str = Str + _T(" afGeneralDiscoverableMode");
	if (Flags.find(afClassicNotSupported) != Flags.end())
		Str = Str + _T(" afClassicNotSupported");
	if (Flags.find(afDualModeControllerCapable) != Flags.end())
		Str = Str + _T(" afDualModeControllerCapable");
	if (Flags.find(afDualModeHostCapable) != Flags.end())
		Str = Str + _T(" afDualModeHostCapable");
	Str = Str + _T(" ]");
	lbFrames.AddString(_T("  Flags: ") + Str);

	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementUuidFrame(void* Sender,
	const __int64 Address, const __int64 Timestamp, const char Rssi, const GUID& Uuid)
{
	UNREFERENCED_PARAMETER(Sender);

	LPOLESTR Guid;
	StringFromCLSID(Uuid, &Guid);
	
	lbFrames.AddString(_T("UUID FRAME"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	lbFrames.AddString(_T("  UUID: ") + CString(Guid));
	
	lbFrames.AddString(_T("-------------------------------------------------------"));

	CoTaskMemFree(Guid);
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementExtFrameInformation(void* Sender,
	const __int64 Address, const __int64 Timestamp, const char Rssi, 
	const wclBluetoothAddressType AddressType, const char TxPower, 
	const wclBluetoothLeExtendedFrameFlags& Flags)
{
	UNREFERENCED_PARAMETER(Sender);

	lbFrames.AddString(_T("EXTENDED FRAME INFORMATION"));

	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	
	CString Str;
	switch (AddressType)
	{
		case atPublic:
			Str = _T("Public");
			break;
		case atRandom:
			Str = _T("Random");
			break;
		case atUnspecified:
			Str = _T("Unspecified");
			break;
		default:
			Str = _T("Unknown");
			break;
	}
	lbFrames.AddString(_T("  Address type: ") + Str);
	
	lbFrames.AddString(_T("  TX Power: ") + IntToStr(TxPower));
	
	Str = _T("[");
	if (Flags.find(efAnonymous) != Flags.end())
		Str = Str + _T(" efAnonymous");
	if (Flags.find(efConnectable) != Flags.end())
		Str = Str + _T(" efConnectable");
	if (Flags.find(efDirected) != Flags.end())
		Str = Str + _T(" efDirected");
	if (Flags.find(efScannable) != Flags.end())
		Str = Str + _T(" efScannable");
	if (Flags.find(efScanResponse) != Flags.end())
		Str = Str + _T(" efScanResponse");
	Str = Str + _T(" ]");
	lbFrames.AddString(_T("  Flags: ") + Str);

	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementService128DataFrame(void* Sender,
	const __int64 Address, const __int64 Timestamp, const char Rssi, const GUID& Uuid,
	const wclBluetoothLeAdvertisementFrameRawData& Data)
{
	UNREFERENCED_PARAMETER(Sender);

	LPOLESTR Guid;
	StringFromCLSID(Uuid, &Guid);

	lbFrames.AddString(_T("128 UUID SERVICE DATA"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	lbFrames.AddString(_T("  UUID: ") + CString(Guid));
	
	DumpData(Data);
	
	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementService32DataFrame(void* Sender,
	const __int64 Address, const __int64 Timestamp, const char Rssi, const unsigned long Uuid,
	const wclBluetoothLeAdvertisementFrameRawData& Data)
{
	UNREFERENCED_PARAMETER(Sender);

	lbFrames.AddString(_T("32 UUID SERVICE DATA"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	lbFrames.AddString(_T("  UUID: ") + IntToHex((int)Uuid));
	
	DumpData(Data);
	
	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementService16DataFrame(void* Sender,
	const __int64 Address, const __int64 Timestamp, const char Rssi, const unsigned short Uuid,
	const wclBluetoothLeAdvertisementFrameRawData& Data)
{
	UNREFERENCED_PARAMETER(Sender);

	lbFrames.AddString(_T("16 UUID SERVICE DATA"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	lbFrames.AddString(_T("  UUID: ") + IntToHex(Uuid));
	
	DumpData(Data);
	
	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementServiceSol128Frame(void* Sender,
	const __int64 Address, const __int64 Timestamp, const char Rssi, const GUID& Uuid)
{
	UNREFERENCED_PARAMETER(Sender);

	LPOLESTR Guid;
	StringFromCLSID(Uuid, &Guid);

	lbFrames.AddString(_T("128 UUID SOL SERVICE"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	lbFrames.AddString(_T("  UUID: ") + CString(Guid));

	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementServiceSol32Frame(void* Sender,
	const __int64 Address, const __int64 Timestamp, const char Rssi, const unsigned long Uuid)
{
	UNREFERENCED_PARAMETER(Sender);

	lbFrames.AddString(_T("32 UUID SOL SERVICE"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	lbFrames.AddString(_T("  UUID: ") + IntToHex((int)Uuid));

	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementServiceSol16Frame(void* Sender,
	const __int64 Address, const __int64 Timestamp, const char Rssi, const unsigned short Uuid)
{
	UNREFERENCED_PARAMETER(Sender);

	lbFrames.AddString(_T("16 UUID SOL SERVICE"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	lbFrames.AddString(_T("  UUID: ") + IntToHex(Uuid));

	lbFrames.AddString(_T("-------------------------------------------------------"));
}

CwclBluetoothRadio* CBeaconsDlg::GetRadio() const
{
	CwclBluetoothRadio* Radio;
	int Res = wclBluetoothManager.GetLeRadio(Radio);
	if (Res != WCL_E_SUCCESS)
	{
		AfxMessageBox(_T("Get working radio failed: 0x") + IntToHex(Res));
		return NULL;
	}
	
	return Radio;
}

void CBeaconsDlg::EnableAdvertisements(BOOL Enable)
{
	cbIBeacon.EnableWindow(Enable);
	cbProximityBeacon.EnableWindow(Enable);
	cbAltBeacon.EnableWindow(Enable);
	cbEddystoneUid.EnableWindow(Enable);
	cbEddystoneUrl.EnableWindow(Enable);
	cb128SolUuid.EnableWindow(Enable);
	cbManufacturer.EnableWindow(Enable);
	cb16UuidService.EnableWindow(Enable);
	cb32UuidService.EnableWindow(Enable);
	cb128UuidService.EnableWindow(Enable);
	cb16UuidData.EnableWindow(Enable);
	cb32UuidData.EnableWindow(Enable);
	cb128UuidData.EnableWindow(Enable);
	cbCustomRaw.EnableWindow(Enable);
}

void CBeaconsDlg::DumpData(const wclBluetoothLeAdvertisementFrameRawData& Data)
{
	if (Data.size() > 0)
	{
		CString Str = _T("");
		unsigned char c = 0;
		for (wclBluetoothLeAdvertisementFrameRawData::const_iterator i = Data.begin(); i != Data.end(); i++)
		{
			Str = Str + IntToHex((*i));
			if (c == 15)
			{
				lbFrames.AddString(_T("    ") + Str);
				Str = _T("");
				c = 0;
			}
			else
				c++;
		}
		if (Str != _T(""))
			lbFrames.AddString(_T("    ") + Str);
	}
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementReceived(void* Sender,
	const __int64 Address, const __int64 Timestamp, const char Rssi,
	const wclBluetoothLeAdvertisementFrameRawData& Data)
{
	UNREFERENCED_PARAMETER(Sender);

	lbFrames.AddString(_T("RAW ADVERTISEMENT FRAME"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));
	
	DumpData(Data);
	
	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementTxPowerLevelFrame(void* Sender,
	const __int64 Address, const __int64 Timestamp, const char Rssi, const char TxPower)
{
	UNREFERENCED_PARAMETER(Sender);

	lbFrames.AddString(_T("TX POWER FRAME"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));

	lbFrames.AddString(_T("  TX Power: ") + IntToStr(TxPower));
	
	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::wclBluetoothLeBeaconWatcherAdvertisementAppearanceFrame(void* Sender,
	const __int64 Address, const __int64 Timestamp, const char Rssi,
	const unsigned short Appearance)
{
	UNREFERENCED_PARAMETER(Sender);

	lbFrames.AddString(_T("APPEARANCE FRAME"));
	
	lbFrames.AddString(_T("  Address: ") + IntToHex(Address));
	lbFrames.AddString(_T("  Timestamp: ") + ConvertTime(Timestamp));
	lbFrames.AddString(_T("  RSSI: ") + IntToStr(Rssi));

	lbFrames.AddString(_T("  Appearance: ") + IntToHex(Appearance));

	lbFrames.AddString(_T("-------------------------------------------------------"));
}

void CBeaconsDlg::DefaultScanParams()
{
	cbScanMode.SetCheck(TRUE);
	edScanInterval.SetWindowText(IntToStr((unsigned long)WCL_BLE_DEFAULT_SCAN_INTERVAL));
	edScanWindow.SetWindowText(IntToStr((unsigned long)WCL_BLE_DEFAULT_SCAN_WINDOW));
}

void CBeaconsDlg::OnBnClickedButton1()
{
	  DefaultScanParams();
}

void CBeaconsDlg::OnBnClickedButton3()
{
	edAdvInterval.SetWindowText(IntToStr((unsigned long)WCL_BLE_DEFAULT_ADVERTISING_INTERVAL));
}
