/* 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()