Newer
Older
powermon_manager_sw / gui / gui_wifi_setup.cpp
@Razvan Turiac Razvan Turiac on 8 Jul 7 KB Initial import
/* Copyright (C) 2020 - 2024, Thornwave Labs Inc
 * Written by Razvan Turiac <razvan.turiac@thornwave.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
 * documentation files (the “Software”), to deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 
 * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * Attribution shall be given to Thornwave Labs Inc. and shall be made visible to the final user. 
 * 
 * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
 * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <gui_wifi_setup.h>
#include <gui_string_dialog.h>


#include <string.h>


GuiWifiSetup::GuiWifiSetup(wxWindow* parent, Powermon &powermon): wxDialog(parent, wxID_ANY, wxT("PowerMon WiFi Setup")), mPowermon(powermon)
{
	const size_t BORDER_SIZE = FromDIP(6);

	wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
	SetSizer(main_sizer);

	mNetworkStatic = new wxStaticText(this, wxID_ANY, wxT(""));
	mStatusStatic = new wxStaticText(this, wxID_ANY, wxT(""));

	wxBoxSizer*	h_sizer = new wxBoxSizer(wxHORIZONTAL);	
	h_sizer->Add(new wxStaticText(this, wxID_ANY, wxT("WiFi Network: ")), 0, wxALL | wxEXPAND, BORDER_SIZE);
	h_sizer->Add(mNetworkStatic, 0, wxALL | wxEXPAND, BORDER_SIZE);
	main_sizer->Add(h_sizer, 0, wxALL | wxEXPAND, 0);

	h_sizer = new wxBoxSizer(wxHORIZONTAL);
	h_sizer->Add(new wxStaticText(this, wxID_ANY, wxT("WiFi Status: ")), 0, wxALL | wxEXPAND, BORDER_SIZE);
	h_sizer->Add(mStatusStatic, 0, wxALL | wxEXPAND, BORDER_SIZE);
	main_sizer->Add(h_sizer, 0, wxDOWN | wxEXPAND, 20);

	mNetworkListCtrl = new wxListCtrl(this, ID_LISTBOX_NETWORK, wxDefaultPosition, FromDIP(wxSize(300, 420)), wxLC_SINGLE_SEL | wxLC_LIST | wxLC_VRULES);
	
	main_sizer->Add(new wxStaticText(this, wxID_ANY, wxT("Wireless Network List")), 0, wxBOTTOM | wxEXPAND, BORDER_SIZE);
	main_sizer->Add(mNetworkListCtrl, 1, wxEXPAND | wxALL, 0);
	
	main_sizer->SetSizeHints(this);
	Centre();

	mPowermon.setOnWifiScanReportCallback([this](const Powermon::WifiScanResult* result)
	{
		if (result)
		{
			Powermon::WifiScanResult report = *result;

			wxQueueEvent(this, new GuiEvent([this, report](const GuiEvent &event)
			{
				if (std::find(mNetworkList.begin(), mNetworkList.end(), report) == mNetworkList.end())
				{
					mNetworkList.push_back(report);
				
					char name[33];
					memset(name, 0, sizeof(name));

					if (report.ssid_length)
					{
						memcpy(name, report.ssid, report.ssid_length);

						char* ptr = name;
						for(uint32_t i = 0; i < report.ssid_length; i++)
						{
							if (isprint(*ptr) == false)
								*ptr = '-';

							ptr++;
						}
					}
					else
					{
						strcpy(name, "<unknown>");
					}

					mNetworkListCtrl->InsertItem(mNetworkListCtrl->GetItemCount(), wxString(name, wxConvUTF8));	
					mNetworkListCtrl->Refresh();
				}
			}));
		}
	});

	mTimer = new wxTimer(this, ID_TIMER);
	mTimer->Start(1000);

	UpdateInfo();

	mPowermon.requestStartWifiScan([this](uint16_t status)
	{
	});
}


GuiWifiSetup::~GuiWifiSetup()
{
}


void GuiWifiSetup::OnClose(wxCloseEvent &event)
{
	mPowermon.setOnWifiScanReportCallback([this](const Powermon::WifiScanResult* result){});
	mTimer->Stop();
	EndModal(wxID_CANCEL);
}


void GuiWifiSetup::OnGuiEvent(GuiEvent &event)
{
	event.process();
}


void GuiWifiSetup::OnTimerEvent(wxTimerEvent &event)
{
	UpdateInfo();
}


void GuiWifiSetup::UpdateInfo(void)
{
	mPowermon.requestGetInfo([this](uint16_t status, const Powermon::DeviceInfo &info)
	{
		if (status == Powermon::RSP_SUCCESS)
		{
			debug_printf("\r\nINFO Status: %X", status);
			debug_printf("\r\nSerial: %016lX, Name: %s %X", info.serial, info.name.c_str(), info.flags);

			wxQueueEvent(this, new GuiEvent([this, info](GuiEvent &event)
			{
				char cstr[MAX_WIFI_SSID_SIZE + 1];
				memcpy(cstr, info.ssid, info.ssid_length);
				cstr[info.ssid_length] = 0;
				
				mNetworkStatic->SetLabel(wxString(cstr, wxConvUTF8));

				if (info.isWifiFailed())
				{
					mStatusStatic->SetLabel(wxT("Cannot connect"));
				}
				else if (info.isWifiConnecting())
				{
					mStatusStatic->SetLabel(wxT("Connecting ..."));
				}
				else if (info.isWifiConnected())
				{
					if (info.address)
					{
						wxString str;
						str.Printf(wxT("Connected (%u.%u.%u.%u)"), (info.address >> 0) & 0xFF, 
													(info.address >> 8) & 0xFF, 
													(info.address >> 16) & 0xFF, 
													(info.address >> 24) & 0xFF);
						mStatusStatic->SetLabel(str);
					}
					else
					{
						mStatusStatic->SetLabel(wxT("Connected (obtaining IP ...)"));
					}
				}
				else
				{
					mNetworkStatic->SetLabel(wxT(""));
					mStatusStatic->SetLabel(wxT("Not connected"));
				}

				mNetworkStatic->Refresh();
				mStatusStatic->Refresh();
			}));
		}
	});
}


void GuiWifiSetup::OnListNetworkActivated(wxListEvent &event)
{
	const int32_t selected = mNetworkListCtrl->GetNextItem(-1, wxLIST_NEXT_BELOW, wxLIST_STATE_SELECTED);

	if (selected >= 0)
	{
		Powermon::WifiScanResult &scan = mNetworkList[selected];

		Powermon::WifiNetwork network;

		network.ssid_length = scan.ssid_length;
		memcpy(network.ssid, scan.ssid, sizeof(network.ssid));
		
		network.security = Powermon::WifiNetwork::SecurityMode::OPEN;
		if (scan.security.wpa2)
			network.security = Powermon::WifiNetwork::SecurityMode::WPA2_PSK;
		else if (scan.security.wpa)
			network.security = Powermon::WifiNetwork::SecurityMode::WPA2_WPA1_PSK;
		else if (scan.security.wep)
			network.security = Powermon::WifiNetwork::SecurityMode::WEP;
		
		debug_printf("\r\nSelected: %.*s", scan.ssid_length, scan.ssid);
	
		if (network.security)
		{
			GuiEnterString dialog(this, wxID_ANY, wxT("Enter password for network"), true, false);
			dialog.setMaxStringLength(64);
			dialog.setStringLabel(wxT("Network Password"));

			if (dialog.ShowModal() != wxID_OK)
				return;

			network.pass_length = dialog.getString().size();
			memcpy(network.pass, dialog.getString().mb_str(), network.pass_length);

			debug_printf("\r\nPass: %.*s", network.pass_length, network.pass);
		}

		mPowermon.requestWifiConfigure(network, [this](uint16_t status)
		{
			debug_printf("\r\nSET WIFI Status: %X %X", status);

			GuiEvent* event = new GuiEvent([this, status](GuiEvent &event)
			{
				if (status == Powermon::RSP_SUCCESS)
				{

				}
				else
				{

				}
			});

			wxQueueEvent(this, event);
		});
	}
}

BEGIN_EVENT_TABLE(GuiWifiSetup, wxDialog)
EVT_CLOSE(GuiWifiSetup::OnClose)
EVT_LIST_ITEM_ACTIVATED(ID_LISTBOX_NETWORK, GuiWifiSetup::OnListNetworkActivated)
GUI_EVT(GuiWifiSetup::OnGuiEvent)
EVT_TIMER(ID_TIMER, GuiWifiSetup::OnTimerEvent)
END_EVENT_TABLE()