Newer
Older
powermon_manager_sw / gui / gui_wifi_add.cpp
/* 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_add.h>
#include <gui_string_dialog.h>


#include <string.h>


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

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

	main_sizer->Add(new wxStaticText(this, wxID_ANY, wxT("Wireless Network List")), 0, wxBOTTOM | wxEXPAND, BORDER_SIZE);

	mNetworkListCtrl = new wxListCtrl(this, ID_LISTBOX_NETWORK, wxDefaultPosition, FromDIP(wxSize(300, 420)), wxLC_SINGLE_SEL | wxLC_LIST | wxLC_VRULES);
	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(10000);

	mPowermon.requestStartWifiScan([this](Powermon::ResponseCode status)
	{
	});
}


GuiWifiAdd::~GuiWifiAdd()
{
}


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

	EndModal(wxID_CANCEL);
}


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


void GuiWifiAdd::OnTimerEvent(wxTimerEvent &event)
{
	mPowermon.requestStartWifiScan([this](Powermon::ResponseCode status)
	{
	});
}


void GuiWifiAdd::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;
		memset(&network, 0, sizeof(Powermon::WifiNetwork));

		network.ssid_length = scan.ssid_length;
		memcpy(network.ssid, scan.ssid, sizeof(network.ssid));
		
		debug_printf("\r\nSelected: %.*s", scan.ssid_length, scan.ssid);
	
		if (scan.security.wpa2 || scan.security.wpa || scan.security.wep)
		{
			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);
		}

		wxMessageDialog msg(this, wxT("Is this network metered ? (mobile hotspot or limited data)"),
									wxT("Network Options"), wxYES | wxNO | wxICON_QUESTION | wxSTAY_ON_TOP | wxCENTRE);
		network.setMetered(msg.ShowModal() == wxID_OK);

		mPowermon.requestAddWifiNetwork(network, [this](Powermon::ResponseCode status)
		{
			debug_printf("\r\nADD WIFI Status: %X", status);

			wxQueueEvent(this, new GuiEvent([this, status](GuiEvent &event)
			{
				checkDeviceError(this, status);

				mTimer->Stop();
				mPowermon.setOnWifiScanReportCallback([this](const Powermon::WifiScanResult* result){});

				EndModal(status == Powermon::RSP_SUCCESS ? wxID_OK : wxID_CANCEL);
			}));
		});
	}
}

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