diff --git a/switch/include/gui.h b/switch/include/gui.h index 0d41ee4..9ebbab4 100644 --- a/switch/include/gui.h +++ b/switch/include/gui.h @@ -32,7 +32,9 @@ class HostInterface HostInterface(brls::List * hostList, IO * io, Host * host, Settings * settings); ~HostInterface(); - void Register(bool pin_incorrect); + static void Register(IO * io, Host * host, + Settings * settings, std::function success_cb = nullptr); + void Register(); void Wakeup(brls::View * view); void Connect(brls::View * view); void ConnectSession(); @@ -51,7 +53,13 @@ class MainApplication IO * io; brls::TabFrame * rootFrame; std::map host_menuitems; + // add_host local settings + std::string remote_display_name = ""; + std::string remote_addr = ""; + int remote_ps4_version = 8000000; + bool BuildConfigurationMenu(brls::List *, Host * host = nullptr); + void BuildAddHostConfigurationMenu(brls::List *); public: MainApplication(std::map * hosts, Settings * settings, DiscoveryManager * discoverymanager, diff --git a/switch/include/settings.h b/switch/include/settings.h index 1a8eb03..176f864 100644 --- a/switch/include/settings.h +++ b/switch/include/settings.h @@ -28,7 +28,7 @@ class Settings { UNKNOWN, HOST_NAME, - HOST_IP, + HOST_ADDR, PSN_ONLINE_ID, PSN_ACCOUNT_ID, RP_KEY, @@ -43,7 +43,7 @@ class Settings // the goal is to read/write inernal flat configuration file const std::map re_map = { { HOST_NAME, std::regex("^\\[\\s*(.+)\\s*\\]") }, - { HOST_IP, std::regex("^\\s*host_ip\\s*=\\s*\"?(\\d+\\.\\d+\\.\\d+\\.\\d+)\"?") }, + { HOST_ADDR, std::regex("^\\s*host_(?:ip|addr)\\s*=\\s*\"?((\\d+\\.\\d+\\.\\d+\\.\\d+)|([A-Za-z0-9-]{1,255}))\"?") }, { PSN_ONLINE_ID, std::regex("^\\s*psn_online_id\\s*=\\s*\"?(\\w+)\"?") }, { PSN_ACCOUNT_ID, std::regex("^\\s*psn_account_id\\s*=\\s*\"?([\\w/=+]+)\"?") }, { RP_KEY, std::regex("^\\s*rp_key\\s*=\\s*\"?([\\w/=+]+)\"?") }, @@ -75,7 +75,7 @@ class Settings void SetVideoFPS(Host * host, ChiakiVideoFPSPreset value); void SetVideoResolution(Host * host, std::string value); void SetVideoFPS(Host * host, std::string value); - std::string GetHostIPAddr(Host * host); + std::string GetHostAddr(Host * host); std::string GetHostName(Host * host); bool SetHostRPKeyType(Host * host, std::string value); int GetHostRPKeyType(Host * host); diff --git a/switch/src/gui.cpp b/switch/src/gui.cpp index 77a71e6..4ffecfc 100644 --- a/switch/src/gui.cpp +++ b/switch/src/gui.cpp @@ -48,17 +48,53 @@ HostInterface::~HostInterface() Disconnect(); } -void HostInterface::Register(bool pin_incorrect) +void HostInterface::Register(IO * io, Host * host, Settings * settings, std::function success_cb) { - if(pin_incorrect) + // user must provide psn id for registration + std::string account_id = settings->GetPSNAccountID(host); + std::string online_id = settings->GetPSNOnlineID(host); + if(host->system_version >= 7000000 && account_id.length() <= 0) { - DIALOG(srfpvyps, "Session Registration Failed, Please verify your PlayStation settings"); + // PS4 firmware > 7.0 + DIALOG(upaid, "Undefined PSN Account ID (Please configure a valid psn_account_id)"); + return; + } + else if( host->system_version < 7000000 && host->system_version > 0 && online_id.length() <= 0) + { + // use oline ID for ps4 < 7.0 + DIALOG(upoid, "Undefined PSN Online ID (Please configure a valid psn_online_id)"); return; } + // add HostConnected function to regist_event_type_finished_success + auto event_type_finished_success_cb = [settings, success_cb]() + { + // save RP keys + settings->WriteFile(); + if(success_cb != nullptr) + { + // FIXME: may raise a connection refused + // when the connection is triggered + // just after the register success + sleep(2); + success_cb(); + } + // decrement block input token number + brls::Application::unblockInputs(); + }; + host->SetRegistEventTypeFinishedSuccess(event_type_finished_success_cb); + + auto event_type_finished_failed_cb = []() + { + // unlock user inputs + brls::Application::unblockInputs(); + brls::Application::notify("Registration failed"); + }; + host->SetRegistEventTypeFinishedFailed(event_type_finished_failed_cb); + // the host is not registered yet brls::Dialog* peprpc = new brls::Dialog("Please enter your PlayStation registration PIN code"); - brls::GenericEvent::Callback cb_peprpc = [this, peprpc](brls::View* view) + brls::GenericEvent::Callback cb_peprpc = [host, io, peprpc](brls::View* view) { bool pin_provided = false; char pin_input[9] = {0}; @@ -68,12 +104,12 @@ void HostInterface::Register(bool pin_incorrect) // before the the ReadUserKeyboard peprpc->close(); - pin_provided = this->io->ReadUserKeyboard(pin_input, sizeof(pin_input)); + pin_provided = io->ReadUserKeyboard(pin_input, sizeof(pin_input)); if(pin_provided) { // prevent users form messing with the gui brls::Application::blockInputs(); - int ret = this->host->Register(pin_input); + int ret = host->Register(pin_input); if(ret != HOST_REGISTER_OK) { switch(ret) @@ -96,6 +132,13 @@ void HostInterface::Register(bool pin_incorrect) peprpc->open(); } +void HostInterface::Register() +{ + // use Connect just after the registration to save user inputs + HostInterface::Register(this->io, this->host, + this->settings, std::bind(&HostInterface::ConnectSession, this)); +} + void HostInterface::Wakeup(brls::View * view) { if(!this->host->rp_key_data) @@ -120,7 +163,15 @@ void HostInterface::Wakeup(brls::View * view) void HostInterface::Connect(brls::View * view) { // check that all requirements are met - if(this->host->state != CHIAKI_DISCOVERY_HOST_STATE_READY) + if(!this->host->discovered && !this->host->rp_key_data) + { + // at this point the host must be discovered or registered manually + // to validate the system_version accuracy + brls::Application::crash("Undefined PlayStation remote version"); + } + + // ignore state for remote hosts + if(this->host->discovered && this->host->state != CHIAKI_DISCOVERY_HOST_STATE_READY) { // host in standby mode DIALOG(ptoyp, "Please turn on your PlayStation"); @@ -129,46 +180,7 @@ void HostInterface::Connect(brls::View * view) if(!this->host->rp_key_data) { - // user must provide psn id for registration - std::string account_id = this->settings->GetPSNAccountID(this->host); - std::string online_id = this->settings->GetPSNOnlineID(this->host); - if(this->host->system_version >= 7000000 && account_id.length() <= 0) - { - // PS4 firmware > 7.0 - DIALOG(upaid, "Undefined PSN Account ID (Please configure a valid psn_account_id)"); - return; - } - else if( this->host->system_version < 7000000 && this->host->system_version > 0 && online_id.length() <= 0) - { - // use oline ID for ps4 < 7.0 - DIALOG(upoid, "Undefined PSN Online ID (Please configure a valid psn_online_id)"); - return; - } - - // add HostConnected function to regist_event_type_finished_success - auto event_type_finished_success_cb = [this]() - { - // save RP keys - this->settings->WriteFile(); - // FIXME: may raise a connection refused - // when the connection is triggered - // just after the register success - sleep(2); - ConnectSession(); - // decrement block input token number - brls::Application::unblockInputs(); - }; - this->host->SetRegistEventTypeFinishedSuccess(event_type_finished_success_cb); - - auto event_type_finished_failed_cb = [this]() - { - // unlock user inputs - brls::Application::unblockInputs(); - brls::Application::notify("Registration failed"); - }; - this->host->SetRegistEventTypeFinishedFailed(event_type_finished_failed_cb); - - this->Register(false); + this->Register(); } else { @@ -280,9 +292,12 @@ bool MainApplication::Load() this->rootFrame->setIcon(BOREALIS_ASSET("icon.jpg")); brls::List* config = new brls::List(); - BuildConfigurationMenu(config); + brls::List* add_host = new brls::List(); + BuildConfigurationMenu(config); + BuildAddHostConfigurationMenu(add_host); this->rootFrame->addTab("Configuration", config); + this->rootFrame->addTab("Add Host", add_host); // ---------------- this->rootFrame->addSeparator(); @@ -292,7 +307,9 @@ bool MainApplication::Load() { for(auto it = this->hosts->begin(); it != this->hosts->end(); it++) { - if(this->host_menuitems.find(&it->second) == this->host_menuitems.end()) + // add host to the gui only if the host is registered or discovered + if(this->host_menuitems.find(&it->second) == this->host_menuitems.end() + && (it->second.rp_key_data == true || it->second.discovered == true)) { brls::List* new_host = new brls::List(); this->host_menuitems[&it->second] = new_host; @@ -432,10 +449,10 @@ bool MainApplication::BuildConfigurationMenu(brls::List * ls, Host * host) host_name->setValue(host_name_string.c_str()); ls->addView(host_name); - std::string host_ipaddr_string = settings->GetHostIPAddr(host); - brls::ListItem* host_ipaddr = new brls::ListItem("PS IP Address"); - host_ipaddr->setValue(host_ipaddr_string.c_str()); - ls->addView(host_ipaddr); + std::string host_addr_string = settings->GetHostAddr(host); + brls::ListItem* host_addr = new brls::ListItem("PS4 Address"); + host_addr->setValue(host_addr_string.c_str()); + ls->addView(host_addr); std::string host_rp_regist_key_string = settings->GetHostRPRegistKey(host); brls::ListItem* host_rp_regist_key = new brls::ListItem("RP Register Key"); @@ -457,6 +474,105 @@ bool MainApplication::BuildConfigurationMenu(brls::List * ls, Host * host) return true; } +void MainApplication::BuildAddHostConfigurationMenu(brls::List * add_host) +{ + // create host for wan connection + // brls::Label* add_host_label = new brls::Label(brls::LabelStyle::REGULAR, + // "Add Host configuration", true); + + brls::ListItem* display_name = new brls::ListItem("Display name"); + auto display_name_cb = [this, display_name](brls::View * view) + { + char name[16] = {0}; + bool input = this->io->ReadUserKeyboard(name, sizeof(name)); + if(input) + { + // update gui + display_name->setValue(name); + // set internal value + this->remote_display_name = name; + } + }; + display_name->getClickEvent()->subscribe(display_name_cb); + add_host->addView(display_name); + + brls::ListItem* address = new brls::ListItem("Remote IP/name"); + auto address_cb = [this, address](brls::View * view) + { + char addr[256] = {0}; + bool input = this->io->ReadUserKeyboard(addr, sizeof(addr)); + if(input) + { + // update gui + address->setValue(addr); + // set internal value + this->remote_addr = addr; + } + }; + address->getClickEvent()->subscribe(address_cb); + add_host->addView(address); + + + // TODO + // brls::ListItem* port = new brls::ListItem("Remote session port", "tcp/udp 9295"); + // brls::ListItem* port = new brls::ListItem("Remote stream port", "udp 9296"); + // brls::ListItem* port = new brls::ListItem("Remote Senkusha port", "udp 9297"); + brls::SelectListItem* ps4_version = new brls::SelectListItem("PS4 Version", + { "PS4 > 8", "7 < PS4 < 8", "PS4 < 7"}); + auto ps4_version_cb = [this, ps4_version](int result) + { + switch(result) + { + case 0: + this->remote_ps4_version = 8000000; + break; + case 1: + this->remote_ps4_version = 7000000; + break; + case 2: + this->remote_ps4_version = 6000000; + break; + } + }; + ps4_version->getValueSelectedEvent()->subscribe(ps4_version_cb); + add_host->addView(ps4_version); + + brls::ListItem* register_host = new brls::ListItem("Register"); + auto register_host_cb = [this](brls::View * view) + { + bool err = false; + if(this->remote_display_name.length() <= 0) + { + brls::Application::notify("No Display name defined"); + err = true; + } + + if(this->remote_addr.length() <= 0) + { + brls::Application::notify("No Remote address provided"); + err = true; + } + + if(this->remote_ps4_version < 0) + { + brls::Application::notify("No PS4 Version provided"); + err = true; + } + + if(err) + return; + + Host * host = this->settings->GetOrCreateHost(&this->remote_display_name); + host->host_addr = this->remote_addr; + host->system_version = this->remote_ps4_version; + + HostInterface::Register(this->io, host, this->settings); + }; + register_host->getClickEvent()->subscribe(register_host_cb); + + add_host->addView(register_host); +} + PSRemotePlay::PSRemotePlay(IO * io, Host * host) : io(io), host(host) { diff --git a/switch/src/settings.cpp b/switch/src/settings.cpp index ed8d222..3c443bc 100644 --- a/switch/src/settings.cpp +++ b/switch/src/settings.cpp @@ -259,12 +259,12 @@ void Settings::SetCPUOverclock(Host * host, std::string value) } #endif -std::string Settings::GetHostIPAddr(Host * host) +std::string Settings::GetHostAddr(Host * host) { if(host != nullptr) return host->host_addr; else - CHIAKI_LOGE(this->log, "Cannot GetHostIPAddr from nullptr host"); + CHIAKI_LOGE(this->log, "Cannot GetHostAddr from nullptr host"); return ""; } @@ -393,7 +393,7 @@ void Settings::ParseFile() config_file.open(this->filename, std::fstream::in); std::string line; std::string value; - bool rp_key_b, rp_regist_key_b, rp_key_type_b; + bool rp_key_b = false, rp_regist_key_b = false, rp_key_type_b = false; Host *current_host = nullptr; if(config_file.is_open()) { @@ -413,17 +413,16 @@ void Settings::ParseFile() // current host is in context current_host = this->GetOrCreateHost(&value); // all following case will edit the current_host config - break; - case HOST_IP: - CHIAKI_LOGV(this->log, "HOST_IP %s", value.c_str()); - if(current_host != nullptr) - current_host->host_addr = value; - // reset bool flags rp_key_b=false; rp_regist_key_b=false; rp_key_type_b=false; break; + case HOST_ADDR: + CHIAKI_LOGV(this->log, "HOST_ADDR %s", value.c_str()); + if(current_host != nullptr) + current_host->host_addr = value; + break; case PSN_ONLINE_ID: CHIAKI_LOGV(this->log, "PSN_ONLINE_ID %s", value.c_str()); // current_host == nullptr @@ -510,7 +509,7 @@ int Settings::WriteFile() CHIAKI_LOGD(this->log, "Write Host config file %s", it->first.c_str()); config_file << "[" << it->first << "]\n" - << "host_ip = \"" << it->second.host_addr << "\"\n"; + << "host_addr = \"" << it->second.host_addr << "\"\n"; if(it->second.video_resolution) config_file << "video_resolution = \""