mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-06 15:05:59 +00:00
split rpcs3 and hle libraries
merge rpcs3 utilities
This commit is contained in:
parent
b33e2662b6
commit
62ad27d1e2
1233 changed files with 7004 additions and 3819 deletions
186
rpcs3/Emu/NP/upnp_handler.cpp
Normal file
186
rpcs3/Emu/NP/upnp_handler.cpp
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
#include "stdafx.h"
|
||||
#include "upnp_handler.h"
|
||||
#include "util/logs.hpp"
|
||||
|
||||
#include <miniwget.h>
|
||||
#include <upnpcommands.h>
|
||||
|
||||
LOG_CHANNEL(upnp_log, "UPNP");
|
||||
|
||||
upnp_handler::~upnp_handler()
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
for (const auto& [protocol, prot_bindings] : m_bindings)
|
||||
{
|
||||
for (const auto& [internal_port, external_port] : prot_bindings)
|
||||
{
|
||||
remove_port_redir_external(external_port, protocol);
|
||||
}
|
||||
}
|
||||
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
void upnp_handler::upnp_enable()
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
m_cfg.load();
|
||||
|
||||
auto check_igd = [&](const char* url) -> bool
|
||||
{
|
||||
int desc_xml_size = 0;
|
||||
int status_code = 0;
|
||||
|
||||
m_igd_data = {};
|
||||
m_igd_urls = {};
|
||||
|
||||
char* desc_xml = static_cast<char*>(miniwget(url, &desc_xml_size, 1, &status_code));
|
||||
|
||||
if (!desc_xml)
|
||||
return false;
|
||||
|
||||
parserootdesc(desc_xml, desc_xml_size, &m_igd_data);
|
||||
free(desc_xml);
|
||||
desc_xml = nullptr;
|
||||
GetUPNPUrls(&m_igd_urls, &m_igd_data, url, 1);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
std::string dev_url = m_cfg.get_device_url();
|
||||
|
||||
if (!dev_url.empty())
|
||||
{
|
||||
if (check_igd(dev_url.c_str()))
|
||||
{
|
||||
upnp_log.notice("Saved UPNP(%s) enabled", dev_url);
|
||||
m_active = true;
|
||||
return;
|
||||
}
|
||||
|
||||
upnp_log.error("Saved UPNP(%s) isn't available anymore", dev_url);
|
||||
}
|
||||
|
||||
upnp_log.notice("Starting UPNP search");
|
||||
|
||||
int upnperror = 0;
|
||||
UPNPDev* devlist = upnpDiscover(2000, nullptr, nullptr, 0, 0, 2, &upnperror);
|
||||
|
||||
if (!devlist)
|
||||
{
|
||||
upnp_log.error("No UPNP device was found");
|
||||
return;
|
||||
}
|
||||
|
||||
const UPNPDev* dev = devlist;
|
||||
for (; dev; dev = dev->pNext)
|
||||
{
|
||||
if (strstr(dev->st, "InternetGatewayDevice"))
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev)
|
||||
{
|
||||
int desc_xml_size = 0;
|
||||
int status_code = 0;
|
||||
char* desc_xml = static_cast<char*>(miniwget(dev->descURL, &desc_xml_size, 1, &status_code));
|
||||
|
||||
if (desc_xml)
|
||||
{
|
||||
IGDdatas igd_data{};
|
||||
UPNPUrls igd_urls{};
|
||||
parserootdesc(desc_xml, desc_xml_size, &igd_data);
|
||||
free(desc_xml);
|
||||
desc_xml = nullptr;
|
||||
GetUPNPUrls(&igd_urls, &igd_data, dev->descURL, 1);
|
||||
|
||||
upnp_log.notice("Found UPnP device type:%s at %s", dev->st, dev->descURL);
|
||||
|
||||
m_cfg.set_device_url(dev->descURL);
|
||||
m_cfg.save();
|
||||
|
||||
m_active = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
upnp_log.error("Failed to retrieve UPNP xml for %s", dev->descURL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
upnp_log.error("No UPNP IGD device was found");
|
||||
}
|
||||
|
||||
freeUPNPDevlist(devlist);
|
||||
}
|
||||
|
||||
void upnp_handler::add_port_redir(std::string_view addr, u16 internal_port, std::string_view protocol)
|
||||
{
|
||||
if (!m_active)
|
||||
return;
|
||||
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
u16 external_port = internal_port;
|
||||
std::string internal_port_str = fmt::format("%d", internal_port);
|
||||
int res = 0;
|
||||
|
||||
for (u16 external_port = internal_port; external_port < internal_port + 100; external_port++)
|
||||
{
|
||||
std::string external_port_str = fmt::format("%d", external_port);
|
||||
res = UPNP_AddPortMapping(m_igd_urls.controlURL, m_igd_data.first.servicetype, external_port_str.c_str(), internal_port_str.c_str(), addr.data(), "RPCS3", protocol.data(), nullptr, nullptr);
|
||||
if (res == UPNPCOMMAND_SUCCESS)
|
||||
{
|
||||
m_bindings[std::string(protocol)][internal_port] = external_port;
|
||||
upnp_log.notice("Successfully bound %s:%d(%s) to IGD:%d", addr, internal_port, protocol, external_port);
|
||||
return;
|
||||
}
|
||||
|
||||
// need more testing, may vary per router, etc, for now assume port conflict silently
|
||||
// else if (res != 718) // ConflictInMappingEntry
|
||||
// {
|
||||
// upnp_log.error("Failed to bind %s:%d(%s) to IGD:%d: %d", addr, internal_port, protocol, external_port, res);
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
|
||||
upnp_log.error("Failed to bind %s:%d(%s) to IGD:(%d=>%d): %d", addr, internal_port, protocol, internal_port, external_port, res);
|
||||
}
|
||||
|
||||
void upnp_handler::remove_port_redir(u16 internal_port, std::string_view protocol)
|
||||
{
|
||||
if (!m_active)
|
||||
return;
|
||||
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
const std::string str_protocol(protocol);
|
||||
|
||||
if (!m_bindings.contains(str_protocol) || !::at32(m_bindings, str_protocol).contains(internal_port))
|
||||
{
|
||||
upnp_log.error("tried to unbind port mapping %d to IGD(%s) but it isn't bound", internal_port, protocol);
|
||||
return;
|
||||
}
|
||||
|
||||
const u16 external_port = ::at32(::at32(m_bindings, str_protocol), internal_port);
|
||||
|
||||
remove_port_redir_external(external_port, protocol);
|
||||
|
||||
ensure(::at32(m_bindings, str_protocol).erase(internal_port));
|
||||
upnp_log.notice("Successfully deleted port mapping %d to IGD:%d(%s)", internal_port, external_port, protocol);
|
||||
}
|
||||
|
||||
void upnp_handler::remove_port_redir_external(u16 external_port, std::string_view protocol, bool verbose)
|
||||
{
|
||||
const std::string str_ext_port = fmt::format("%d", external_port);
|
||||
|
||||
if (int res = UPNP_DeletePortMapping(m_igd_urls.controlURL, m_igd_data.first.servicetype, str_ext_port.c_str(), protocol.data(), nullptr); res != 0 && verbose)
|
||||
upnp_log.error("Failed to delete port mapping IGD:%s(%s): %d", str_ext_port, protocol, res);
|
||||
}
|
||||
|
||||
bool upnp_handler::is_active() const
|
||||
{
|
||||
return m_active;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue