mirror of
https://github.com/ndeadly/MissionControl
synced 2024-11-23 12:53:17 +00:00
158 lines
5.3 KiB
C++
158 lines
5.3 KiB
C++
#include "bluetooth_core.hpp"
|
|
|
|
#include <atomic>
|
|
#include <mutex>
|
|
#include <cstring>
|
|
|
|
#include "../btdrv_mitm_flags.hpp"
|
|
#include "../controllers/controllermanager.hpp"
|
|
|
|
#include "../btdrv_mitm_logging.hpp"
|
|
|
|
namespace ams::bluetooth::core {
|
|
|
|
namespace {
|
|
|
|
std::atomic<bool> g_isInitialized(false);
|
|
|
|
os::Mutex g_eventDataLock(false);
|
|
u8 g_eventDataBuffer[0x400];
|
|
EventType g_currentEventType;
|
|
|
|
os::SystemEventType g_systemEvent;
|
|
os::SystemEventType g_systemEventFwd;
|
|
os::SystemEventType g_systemEventUserFwd;
|
|
os::EventType g_dataReadEvent;
|
|
|
|
}
|
|
|
|
bool IsInitialized(void) {
|
|
return g_isInitialized;
|
|
}
|
|
|
|
os::SystemEventType *GetSystemEvent(void) {
|
|
return &g_systemEvent;
|
|
}
|
|
|
|
os::SystemEventType *GetForwardEvent(void) {
|
|
return &g_systemEventFwd;
|
|
}
|
|
|
|
os::SystemEventType *GetUserForwardEvent(void) {
|
|
return &g_systemEventUserFwd;
|
|
}
|
|
|
|
Result Initialize(Handle eventHandle) {
|
|
os::AttachReadableHandleToSystemEvent(&g_systemEvent, eventHandle, false, os::EventClearMode_ManualClear);
|
|
|
|
R_TRY(os::CreateSystemEvent(&g_systemEventFwd, os::EventClearMode_AutoClear, true));
|
|
R_TRY(os::CreateSystemEvent(&g_systemEventUserFwd, os::EventClearMode_AutoClear, true));
|
|
os::InitializeEvent(&g_dataReadEvent, false, os::EventClearMode_AutoClear);
|
|
|
|
g_isInitialized = true;
|
|
|
|
return ams::ResultSuccess();
|
|
}
|
|
|
|
void Finalize(void) {
|
|
os::FinalizeEvent(&g_dataReadEvent);
|
|
os::DestroySystemEvent(&g_systemEventUserFwd);
|
|
os::DestroySystemEvent(&g_systemEventFwd);
|
|
|
|
g_isInitialized = false;
|
|
}
|
|
|
|
void handleDeviceFoundEvent(EventData *eventData) {
|
|
if (controller::IsController(&eventData->deviceFound.cod) && !controller::IsValidSwitchControllerName(eventData->deviceFound.name)) {
|
|
std::strncpy(eventData->deviceFound.name, controller::proControllerName, sizeof(BluetoothName) - 1);
|
|
}
|
|
}
|
|
|
|
void handlePinRequestEvent(EventData *eventData) {
|
|
if (!controller::IsValidSwitchControllerName(eventData->pinReply.name)) {
|
|
std::strncpy(eventData->pinReply.name, controller::proControllerName, sizeof(BluetoothName) - 1);
|
|
}
|
|
}
|
|
|
|
void handleSspRequestEvent(EventData *eventData) {
|
|
if (!controller::IsValidSwitchControllerName(eventData->sspReply.name)) {
|
|
std::strncpy(eventData->sspReply.name, controller::proControllerName, sizeof(BluetoothName) - 1);
|
|
}
|
|
}
|
|
|
|
Result GetEventInfo(ncm::ProgramId program_id, EventType *type, u8* buffer, size_t size) {
|
|
std::scoped_lock lk(g_eventDataLock);
|
|
|
|
*type = g_currentEventType;
|
|
std::memcpy(buffer, g_eventDataBuffer, size);
|
|
|
|
auto eventData = reinterpret_cast<EventData *>(buffer);
|
|
|
|
if (program_id == ncm::SystemProgramId::Btm) {
|
|
|
|
switch (g_currentEventType) {
|
|
case BluetoothEvent_DeviceFound:
|
|
handleDeviceFoundEvent(eventData);
|
|
break;
|
|
case BluetoothEvent_PinRequest:
|
|
handlePinRequestEvent(eventData);
|
|
break;
|
|
case BluetoothEvent_SspRequest:
|
|
handleSspRequestEvent(eventData);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
os::SignalEvent(&g_dataReadEvent);
|
|
|
|
return ams::ResultSuccess();
|
|
}
|
|
|
|
void HandleEvent(void) {
|
|
{
|
|
std::scoped_lock lk(g_eventDataLock);
|
|
R_ABORT_UNLESS(btdrvGetEventInfo(&g_currentEventType, g_eventDataBuffer, sizeof(g_eventDataBuffer)));
|
|
}
|
|
|
|
//BTDRV_LOG_FMT("[%02d] Core Event", g_currentEventType);
|
|
|
|
if (!g_redirectCoreEvents) {
|
|
if (g_currentEventType == BluetoothEvent_PinRequest) {
|
|
auto eventData = reinterpret_cast<EventData *>(g_eventDataBuffer);
|
|
|
|
bluetooth::PinCode pincode = {};
|
|
u8 pin_length;
|
|
|
|
// Reverse host address as pincode for wii devices
|
|
const char *wii_prefix = "Nintendo RVL";
|
|
if (strncmp(eventData->pinReply.name, wii_prefix, strlen(wii_prefix)) == 0) {
|
|
// Fetch host adapter properties
|
|
BluetoothAdapterProperty props;
|
|
R_ABORT_UNLESS(btdrvGetAdapterProperties(&props));
|
|
// Reverse host address
|
|
*reinterpret_cast<u64 *>(&pincode) = util::SwapBytes(*reinterpret_cast<u64 *>(&props.address)) >> 16;
|
|
pin_length = sizeof(bluetooth::Address);
|
|
}
|
|
else {
|
|
// This is what the bluetooth sysmodule hardcodes
|
|
*reinterpret_cast<u32 *>(&pincode) = 0x30303030;
|
|
pin_length = sizeof(u32);
|
|
}
|
|
|
|
// Fuck BTM, we're sending the pin response ourselves if it won't.
|
|
R_ABORT_UNLESS(btdrvRespondToPinRequest(&eventData->pinReply.address, false, &pincode, pin_length));
|
|
}
|
|
else {
|
|
os::SignalSystemEvent(&g_systemEventFwd);
|
|
os::WaitEvent(&g_dataReadEvent);
|
|
}
|
|
}
|
|
|
|
if (g_systemEventUserFwd.state)
|
|
os::SignalSystemEvent(&g_systemEventUserFwd);
|
|
|
|
}
|
|
|
|
}
|