mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-06 23:11:18 +12:00
Prevent connection attempts on still-connected controllers
This commit is contained in:
parent
08b0bfba8b
commit
a648fc7a08
2 changed files with 54 additions and 42 deletions
|
@ -245,7 +245,7 @@ void PairingDialog::WorkerThread()
|
||||||
// Search for device
|
// Search for device
|
||||||
inquiry_info* infos = nullptr;
|
inquiry_info* infos = nullptr;
|
||||||
m_cancelButton->Disable();
|
m_cancelButton->Disable();
|
||||||
const auto respCount = hci_inquiry(hostId, 5, 4, LIAC_LAP, &infos, IREQ_CACHE_FLUSH);
|
const auto respCount = hci_inquiry(hostId, 7, 4, LIAC_LAP, &infos, IREQ_CACHE_FLUSH);
|
||||||
m_cancelButton->Enable();
|
m_cancelButton->Enable();
|
||||||
if (respCount <= 0)
|
if (respCount <= 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,63 +1,70 @@
|
||||||
#include "L2CapWiimote.h"
|
#include "L2CapWiimote.h"
|
||||||
#include <bluetooth/l2cap.h>
|
#include <bluetooth/l2cap.h>
|
||||||
|
|
||||||
namespace {
|
constexpr auto comparator = [](const bdaddr_t& a, const bdaddr_t& b) {
|
||||||
std::vector<bdaddr_t> s_address;
|
return bacmp(&a, &b);
|
||||||
std::mutex s_addressMutex;
|
};
|
||||||
|
|
||||||
bool AttemptConnect(int& sockFd, const sockaddr_l2& addr)
|
static auto s_addresses = std::map<bdaddr_t, bool, decltype(comparator)>(comparator);
|
||||||
{
|
static std::mutex s_addressMutex;
|
||||||
|
|
||||||
|
static bool AttemptConnect(int sockFd, const sockaddr_l2& addr)
|
||||||
|
{
|
||||||
auto res = connect(sockFd, reinterpret_cast<const sockaddr*>(&addr),
|
auto res = connect(sockFd, reinterpret_cast<const sockaddr*>(&addr),
|
||||||
sizeof(sockaddr_l2));
|
sizeof(sockaddr_l2));
|
||||||
if (res == 0)
|
if (res == 0)
|
||||||
return true;
|
return true;
|
||||||
if (res != ECONNREFUSED)
|
|
||||||
return false;
|
|
||||||
return connect(sockFd, reinterpret_cast<const sockaddr*>(&addr),
|
return connect(sockFd, reinterpret_cast<const sockaddr*>(&addr),
|
||||||
sizeof(sockaddr_l2)) == 0;
|
sizeof(sockaddr_l2)) == 0;
|
||||||
}
|
}
|
||||||
bool AttemptSetNonBlock(int& sockFd)
|
|
||||||
{
|
static bool AttemptSetNonBlock(int sockFd)
|
||||||
|
{
|
||||||
return fcntl(sockFd, F_SETFL, fcntl(sockFd, F_GETFL) | O_NONBLOCK) == 0;
|
return fcntl(sockFd, F_SETFL, fcntl(sockFd, F_GETFL) | O_NONBLOCK) == 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool operator==(const bdaddr_t& a, const bdaddr_t& b)
|
L2CapWiimote::L2CapWiimote(int recvFd, int sendFd, bdaddr_t addr)
|
||||||
|
: m_recvFd(recvFd), m_sendFd(sendFd), m_addr(addr)
|
||||||
{
|
{
|
||||||
return bacmp(&a, &b) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
L2CapWiimote::L2CapWiimote(int recvFd,int sendFd, bdaddr_t addr)
|
|
||||||
: m_recvFd(recvFd), m_sendFd(sendFd), m_addr(addr)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
L2CapWiimote::~L2CapWiimote()
|
L2CapWiimote::~L2CapWiimote()
|
||||||
{
|
{
|
||||||
::close(m_recvFd);
|
close(m_recvFd);
|
||||||
::close(m_sendFd);
|
close(m_sendFd);
|
||||||
|
const auto& b = m_addr.b;
|
||||||
|
cemuLog_logDebug(LogType::Force, "Wiimote at {:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x} disconnected", b[5], b[4], b[3], b[2], b[1], b[0]);
|
||||||
|
|
||||||
|
// Re-add to candidate vec
|
||||||
|
s_addressMutex.lock();
|
||||||
|
s_addresses[m_addr] = false;
|
||||||
|
s_addressMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void L2CapWiimote::AddCandidateAddress(bdaddr_t addr)
|
void L2CapWiimote::AddCandidateAddress(bdaddr_t addr)
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(s_addressMutex);
|
std::scoped_lock lock(s_addressMutex);
|
||||||
vectorAppendUnique(s_address,addr);
|
s_addresses.try_emplace(addr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<WiimoteDevicePtr> L2CapWiimote::get_devices()
|
std::vector<WiimoteDevicePtr> L2CapWiimote::get_devices()
|
||||||
{
|
{
|
||||||
s_addressMutex.lock();
|
s_addressMutex.lock();
|
||||||
const auto addresses = s_address;
|
std::vector<bdaddr_t> unconnected;
|
||||||
|
for (const auto& [addr, connected] : s_addresses)
|
||||||
|
{
|
||||||
|
if (!connected)
|
||||||
|
unconnected.push_back(addr);
|
||||||
|
}
|
||||||
s_addressMutex.unlock();
|
s_addressMutex.unlock();
|
||||||
|
|
||||||
|
|
||||||
std::vector<WiimoteDevicePtr> outDevices;
|
std::vector<WiimoteDevicePtr> outDevices;
|
||||||
for (auto addr : addresses)
|
for (const auto& addr : unconnected)
|
||||||
{
|
{
|
||||||
// Socket for sending data to controller, PSM 0x11
|
// Socket for sending data to controller, PSM 0x11
|
||||||
auto sendFd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
|
auto sendFd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
|
||||||
if (sendFd < 0) {
|
if (sendFd < 0)
|
||||||
|
{
|
||||||
cemuLog_logDebug(LogType::Force, "Failed to open send socket: {}", strerror(errno));
|
cemuLog_logDebug(LogType::Force, "Failed to open send socket: {}", strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -67,9 +74,10 @@ std::vector<WiimoteDevicePtr> L2CapWiimote::get_devices()
|
||||||
sendAddr.l2_psm = htobs(0x11);
|
sendAddr.l2_psm = htobs(0x11);
|
||||||
sendAddr.l2_bdaddr = addr;
|
sendAddr.l2_bdaddr = addr;
|
||||||
|
|
||||||
if (!AttemptConnect(sendFd, sendAddr) || !AttemptSetNonBlock(sendFd)) {
|
if (!AttemptConnect(sendFd, sendAddr) || !AttemptSetNonBlock(sendFd))
|
||||||
|
{
|
||||||
const auto& b = addr.b;
|
const auto& b = addr.b;
|
||||||
cemuLog_logDebug(LogType::Force,"Failed to connect send socket to '{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}': {}",
|
cemuLog_logDebug(LogType::Force, "Failed to connect send socket to '{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}': {}",
|
||||||
b[5], b[4], b[3], b[2], b[1], b[0], strerror(errno));
|
b[5], b[4], b[3], b[2], b[1], b[0], strerror(errno));
|
||||||
close(sendFd);
|
close(sendFd);
|
||||||
continue;
|
continue;
|
||||||
|
@ -77,8 +85,9 @@ std::vector<WiimoteDevicePtr> L2CapWiimote::get_devices()
|
||||||
|
|
||||||
// Socket for receiving data from controller, PSM 0x13
|
// Socket for receiving data from controller, PSM 0x13
|
||||||
auto recvFd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
|
auto recvFd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
|
||||||
if (recvFd < 0) {
|
if (recvFd < 0)
|
||||||
cemuLog_logDebug(LogType::Force,"Failed to open recv socket: {}", strerror(errno));
|
{
|
||||||
|
cemuLog_logDebug(LogType::Force, "Failed to open recv socket: {}", strerror(errno));
|
||||||
close(sendFd);
|
close(sendFd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -87,16 +96,20 @@ std::vector<WiimoteDevicePtr> L2CapWiimote::get_devices()
|
||||||
recvAddr.l2_psm = htobs(0x13);
|
recvAddr.l2_psm = htobs(0x13);
|
||||||
recvAddr.l2_bdaddr = addr;
|
recvAddr.l2_bdaddr = addr;
|
||||||
|
|
||||||
if (!AttemptConnect(recvFd, recvAddr) || !AttemptSetNonBlock(recvFd)) {
|
if (!AttemptConnect(recvFd, recvAddr) || !AttemptSetNonBlock(recvFd))
|
||||||
|
{
|
||||||
const auto& b = addr.b;
|
const auto& b = addr.b;
|
||||||
cemuLog_logDebug(LogType::Force,"Failed to connect recv socket to '{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}': {}",
|
cemuLog_logDebug(LogType::Force, "Failed to connect recv socket to '{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}': {}",
|
||||||
b[5], b[4], b[3], b[2], b[1], b[0], strerror(errno));
|
b[5], b[4], b[3], b[2], b[1], b[0], strerror(errno));
|
||||||
close(sendFd);
|
close(sendFd);
|
||||||
close(recvFd);
|
close(recvFd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
outDevices.emplace_back(std::make_shared<L2CapWiimote>(sendFd, recvFd, addr));
|
outDevices.emplace_back(std::make_shared<L2CapWiimote>(sendFd, recvFd, addr));
|
||||||
|
|
||||||
|
s_addressMutex.lock();
|
||||||
|
s_addresses[addr] = true;
|
||||||
|
s_addressMutex.unlock();
|
||||||
}
|
}
|
||||||
return outDevices;
|
return outDevices;
|
||||||
}
|
}
|
||||||
|
@ -126,11 +139,10 @@ std::optional<std::vector<uint8>> L2CapWiimote::read_data()
|
||||||
return std::vector(buffer + 1, buffer + 1 + nBytes - 1);
|
return std::vector(buffer + 1, buffer + 1 + nBytes - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool L2CapWiimote::operator==(const WiimoteDevice& rhs) const
|
bool L2CapWiimote::operator==(const WiimoteDevice& rhs) const
|
||||||
{
|
{
|
||||||
auto mote = dynamic_cast<const L2CapWiimote*>(&rhs);
|
auto mote = dynamic_cast<const L2CapWiimote*>(&rhs);
|
||||||
if (!mote)
|
if (!mote)
|
||||||
return false;
|
return false;
|
||||||
return m_addr == mote->m_addr;
|
return bacmp(&m_addr, &mote->m_addr) == 0;
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue