2020-06-13 19:27:07 +00:00
|
|
|
#include "bluetooth_hid.hpp"
|
2020-06-14 22:18:46 +00:00
|
|
|
|
|
|
|
#include <atomic>
|
|
|
|
#include <mutex>
|
|
|
|
#include <cstring>
|
2020-06-28 08:45:54 +00:00
|
|
|
|
2020-07-11 19:10:38 +00:00
|
|
|
#include "../controllers/controllermanager.hpp"
|
2020-06-13 00:08:43 +00:00
|
|
|
#include "../btdrv_mitm_flags.hpp"
|
|
|
|
|
|
|
|
#include "../btdrv_mitm_logging.hpp"
|
|
|
|
|
2020-06-13 17:15:59 +00:00
|
|
|
namespace ams::bluetooth::hid {
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2020-06-14 22:18:46 +00:00
|
|
|
std::atomic<bool> g_isInitialized(false);
|
2020-06-25 21:50:43 +00:00
|
|
|
std::atomic<bool> g_bufferRead(false);
|
2020-06-14 22:18:46 +00:00
|
|
|
|
|
|
|
os::Mutex g_eventDataLock(false);
|
2020-06-13 17:15:59 +00:00
|
|
|
u8 g_eventDataBuffer[0x480];
|
|
|
|
HidEventType g_currentEventType;
|
|
|
|
|
|
|
|
os::SystemEventType g_btHidSystemEvent;
|
|
|
|
os::SystemEventType g_btHidSystemEventFwd;
|
|
|
|
os::SystemEventType g_btHidSystemEventUser;
|
2020-06-28 08:45:54 +00:00
|
|
|
os::EventType g_dataReadEvent;
|
2020-06-13 17:15:59 +00:00
|
|
|
|
2020-06-14 22:18:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool IsInitialized(void) {
|
|
|
|
return g_isInitialized;
|
2020-06-13 00:08:43 +00:00
|
|
|
}
|
|
|
|
|
2020-06-13 17:15:59 +00:00
|
|
|
os::SystemEventType *GetSystemEvent(void) {
|
|
|
|
return &g_btHidSystemEvent;
|
|
|
|
}
|
2020-06-13 00:08:43 +00:00
|
|
|
|
2020-06-13 17:15:59 +00:00
|
|
|
os::SystemEventType *GetForwardEvent(void) {
|
|
|
|
return &g_btHidSystemEventFwd;
|
|
|
|
}
|
2020-06-13 00:08:43 +00:00
|
|
|
|
2020-06-13 17:15:59 +00:00
|
|
|
os::SystemEventType *GetUserForwardEvent(void) {
|
|
|
|
return &g_btHidSystemEventUser;
|
|
|
|
}
|
2020-06-13 00:08:43 +00:00
|
|
|
|
2020-06-14 22:18:46 +00:00
|
|
|
Result Initialize(Handle eventHandle) {
|
2020-06-25 21:50:43 +00:00
|
|
|
os::AttachReadableHandleToSystemEvent(&g_btHidSystemEvent, eventHandle, false, os::EventClearMode_ManualClear);
|
2020-06-14 22:18:46 +00:00
|
|
|
|
|
|
|
R_TRY(os::CreateSystemEvent(&g_btHidSystemEventFwd, os::EventClearMode_AutoClear, true));
|
|
|
|
R_TRY(os::CreateSystemEvent(&g_btHidSystemEventUser, os::EventClearMode_AutoClear, true));
|
2020-06-28 08:45:54 +00:00
|
|
|
os::InitializeEvent(&g_dataReadEvent, false, os::EventClearMode_AutoClear);
|
2020-06-14 22:18:46 +00:00
|
|
|
|
|
|
|
g_isInitialized = true;
|
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Finalize(void) {
|
2020-06-28 08:45:54 +00:00
|
|
|
os::FinalizeEvent(&g_dataReadEvent);
|
2020-06-14 22:18:46 +00:00
|
|
|
os::DestroySystemEvent(&g_btHidSystemEventUser);
|
|
|
|
os::DestroySystemEvent(&g_btHidSystemEventFwd);
|
|
|
|
|
|
|
|
g_isInitialized = false;
|
|
|
|
}
|
|
|
|
|
2020-06-17 23:40:11 +00:00
|
|
|
Result GetEventInfo(ncm::ProgramId program_id, HidEventType *type, u8* buffer, size_t size) {
|
2020-06-14 22:18:46 +00:00
|
|
|
std::scoped_lock lk(g_eventDataLock);
|
|
|
|
|
|
|
|
*type = g_currentEventType;
|
|
|
|
std::memcpy(buffer, g_eventDataBuffer, size);
|
|
|
|
|
2020-06-28 08:45:54 +00:00
|
|
|
os::SignalEvent(&g_dataReadEvent);
|
2020-06-25 21:50:43 +00:00
|
|
|
|
2020-06-14 22:18:46 +00:00
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2020-06-13 17:15:59 +00:00
|
|
|
void handleConnectionStateEvent(HidEventData *eventData) {
|
|
|
|
switch (eventData->connectionState.state) {
|
|
|
|
case HidConnectionState_Connected:
|
2020-07-11 19:10:38 +00:00
|
|
|
controller::attachDeviceHandler(&eventData->connectionState.address);
|
2020-07-27 23:02:17 +00:00
|
|
|
//BTDRV_LOG_FMT("device connected");
|
2020-06-13 17:15:59 +00:00
|
|
|
break;
|
|
|
|
case HidConnectionState_Disconnected:
|
2020-07-11 19:10:38 +00:00
|
|
|
controller::removeDeviceHandler(&eventData->connectionState.address);
|
2020-07-27 23:02:17 +00:00
|
|
|
//BTDRV_LOG_FMT("device disconnected");
|
2020-06-13 17:15:59 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void HandleEvent(void) {
|
2020-06-28 08:45:54 +00:00
|
|
|
{
|
|
|
|
std::scoped_lock lk(g_eventDataLock);
|
|
|
|
R_ABORT_UNLESS(btdrvGetHidEventInfo(&g_currentEventType, g_eventDataBuffer, sizeof(g_eventDataBuffer)));
|
|
|
|
}
|
2020-06-13 00:08:43 +00:00
|
|
|
|
2020-07-01 08:42:44 +00:00
|
|
|
BTDRV_LOG_FMT("[%02d] HID Event", g_currentEventType);
|
|
|
|
|
2020-06-28 08:45:54 +00:00
|
|
|
os::SignalSystemEvent(&g_btHidSystemEventFwd);
|
|
|
|
os::WaitEvent(&g_dataReadEvent);
|
|
|
|
|
2020-07-27 23:02:17 +00:00
|
|
|
if (g_btHidSystemEventUser.state)
|
2020-07-01 08:42:44 +00:00
|
|
|
os::SignalSystemEvent(&g_btHidSystemEventUser);
|
2020-06-14 22:18:46 +00:00
|
|
|
|
2020-07-01 13:29:09 +00:00
|
|
|
auto eventData = reinterpret_cast<HidEventData *>(g_eventDataBuffer);
|
|
|
|
|
2020-06-17 23:40:11 +00:00
|
|
|
switch (g_currentEventType) {
|
2020-06-14 22:18:46 +00:00
|
|
|
|
2020-06-17 23:40:11 +00:00
|
|
|
case HidEvent_ConnectionState:
|
|
|
|
handleConnectionStateEvent(eventData);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2020-06-13 00:08:43 +00:00
|
|
|
}
|
2020-06-17 23:40:11 +00:00
|
|
|
|
2020-06-13 17:15:59 +00:00
|
|
|
}
|
2020-06-13 00:08:43 +00:00
|
|
|
|
|
|
|
}
|