2020-08-25 19:23:38 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2020 ndeadly
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2020-05-11 20:30:08 +00:00
|
|
|
#include "btdrv_mitm_service.hpp"
|
2020-06-13 00:08:43 +00:00
|
|
|
#include "btdrv_mitm_flags.hpp"
|
2020-05-11 20:30:08 +00:00
|
|
|
#include "btdrv_shim.h"
|
2020-06-13 00:08:43 +00:00
|
|
|
#include "bluetooth/bluetooth_events.hpp"
|
2020-08-26 18:52:47 +00:00
|
|
|
#include "controllers/controller_management.hpp"
|
|
|
|
#include <switch.h>
|
|
|
|
#include <cstring>
|
2020-07-27 17:42:40 +00:00
|
|
|
|
2020-05-22 10:29:36 +00:00
|
|
|
namespace ams::mitm::btdrv {
|
|
|
|
|
|
|
|
Result BtdrvMitmService::InitializeBluetooth(sf::OutCopyHandle out_handle) {
|
2020-06-14 22:18:46 +00:00
|
|
|
if (!bluetooth::core::IsInitialized()) {
|
2020-05-22 10:29:36 +00:00
|
|
|
Handle handle = INVALID_HANDLE;
|
2020-06-13 17:15:59 +00:00
|
|
|
R_TRY(btdrvInitializeBluetoothFwd(this->forward_service.get(), &handle));
|
2020-06-14 22:18:46 +00:00
|
|
|
R_TRY(bluetooth::core::Initialize(handle));
|
2020-07-09 17:44:12 +00:00
|
|
|
R_TRY(bluetooth::hid::report::InitializeReportBuffer());
|
2020-06-15 12:13:17 +00:00
|
|
|
|
2020-06-13 17:15:59 +00:00
|
|
|
out_handle.SetValue(os::GetReadableHandleOfSystemEvent(bluetooth::core::GetForwardEvent()));
|
2020-05-22 10:29:36 +00:00
|
|
|
} else {
|
2020-06-13 17:15:59 +00:00
|
|
|
out_handle.SetValue(os::GetReadableHandleOfSystemEvent(bluetooth::core::GetUserForwardEvent()));
|
2020-05-22 10:29:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
|
|
|
Result BtdrvMitmService::FinalizeBluetooth(void) {
|
2020-06-13 00:08:43 +00:00
|
|
|
// Only btm should be able to make this call
|
2020-05-22 10:29:36 +00:00
|
|
|
if (this->client_info.program_id == ncm::SystemProgramId::Btm) {
|
2020-06-14 22:18:46 +00:00
|
|
|
R_TRY(btdrvFinalizeBluetoothFwd(this->forward_service.get()));
|
2020-05-22 10:29:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2020-07-01 13:34:07 +00:00
|
|
|
Result BtdrvMitmService::GetEventInfo(sf::Out<bluetooth::EventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
2020-06-22 21:14:54 +00:00
|
|
|
R_TRY(bluetooth::core::GetEventInfo(this->client_info.program_id,
|
|
|
|
out_type.GetPointer(),
|
2020-08-26 18:52:47 +00:00
|
|
|
static_cast<uint8_t *>(out_buffer.GetPointer()),
|
2020-06-14 22:18:46 +00:00
|
|
|
static_cast<size_t>(out_buffer.GetSize())
|
|
|
|
));
|
2020-05-22 10:29:36 +00:00
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
|
|
|
Result BtdrvMitmService::InitializeHid(sf::OutCopyHandle out_handle, u16 version) {
|
2020-06-14 22:18:46 +00:00
|
|
|
if (!bluetooth::hid::IsInitialized()) {
|
|
|
|
Handle handle = INVALID_HANDLE;
|
|
|
|
R_TRY(btdrvInitializeHidFwd(this->forward_service.get(), &handle, version));
|
|
|
|
R_TRY(bluetooth::hid::Initialize(handle));
|
2020-06-22 21:14:54 +00:00
|
|
|
|
2020-06-13 17:15:59 +00:00
|
|
|
out_handle.SetValue(os::GetReadableHandleOfSystemEvent(bluetooth::hid::GetForwardEvent()));
|
2020-05-22 10:29:36 +00:00
|
|
|
}
|
|
|
|
else {
|
2020-06-13 17:15:59 +00:00
|
|
|
out_handle.SetValue(os::GetReadableHandleOfSystemEvent(bluetooth::hid::GetUserForwardEvent()));
|
2020-05-22 10:29:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2020-07-01 13:34:07 +00:00
|
|
|
Result BtdrvMitmService::WriteHidData(bluetooth::Address address, const sf::InPointerBuffer &buffer) {
|
2020-08-25 00:05:19 +00:00
|
|
|
auto report = reinterpret_cast<const bluetooth::HidReport *>(buffer.GetPointer());
|
2020-06-22 21:14:54 +00:00
|
|
|
|
2020-05-22 10:29:36 +00:00
|
|
|
if (this->client_info.program_id == ncm::SystemProgramId::Hid) {
|
2020-08-26 18:52:47 +00:00
|
|
|
auto device = controller::LocateHandler(&address);
|
2020-07-27 17:42:40 +00:00
|
|
|
if (device) {
|
2020-08-26 18:52:47 +00:00
|
|
|
device->HandleOutgoingReport(report);
|
2020-05-22 10:29:36 +00:00
|
|
|
}
|
|
|
|
}
|
2020-08-25 00:05:19 +00:00
|
|
|
else {
|
2020-08-26 18:52:47 +00:00
|
|
|
R_TRY(btdrvWriteHidDataFwd(this->forward_service.get(), &address, report));
|
2020-07-27 17:42:40 +00:00
|
|
|
}
|
2020-05-22 10:29:36 +00:00
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2020-07-01 13:34:07 +00:00
|
|
|
Result BtdrvMitmService::GetPairedDeviceInfo(sf::Out<bluetooth::DeviceSettings> out, bluetooth::Address address) {
|
2020-06-30 08:05:33 +00:00
|
|
|
auto device = reinterpret_cast<BluetoothDevicesSettings *>(out.GetPointer());
|
2020-06-22 21:14:54 +00:00
|
|
|
|
2020-06-30 08:05:33 +00:00
|
|
|
R_TRY(btdrvGetPairedDeviceInfoFwd(this->forward_service.get(), &address, device));
|
2020-06-28 15:32:48 +00:00
|
|
|
|
|
|
|
if (this->client_info.program_id == ncm::SystemProgramId::Btm) {
|
2020-08-26 18:52:47 +00:00
|
|
|
if (!controller::IsOfficialSwitchControllerName(device->name)) {
|
|
|
|
std::strncpy(device->name, controller::pro_controller_name, sizeof(BluetoothLocalName) - 1);
|
2020-06-22 21:14:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
2020-06-28 15:32:48 +00:00
|
|
|
|
2020-05-22 10:29:36 +00:00
|
|
|
Result BtdrvMitmService::FinalizeHid(void) {
|
2020-06-13 00:08:43 +00:00
|
|
|
// Only btm should be able to make this call
|
2020-05-22 10:29:36 +00:00
|
|
|
if (this->client_info.program_id == ncm::SystemProgramId::Btm) {
|
2020-06-14 22:18:46 +00:00
|
|
|
R_TRY(btdrvFinalizeHidFwd(this->forward_service.get()));
|
2020-05-22 10:29:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2020-07-01 13:34:07 +00:00
|
|
|
Result BtdrvMitmService::GetHidEventInfo(sf::Out<bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
2020-06-22 21:14:54 +00:00
|
|
|
R_TRY(bluetooth::hid::GetEventInfo(this->client_info.program_id,
|
|
|
|
out_type.GetPointer(),
|
2020-08-26 18:52:47 +00:00
|
|
|
static_cast<uint8_t *>(out_buffer.GetPointer()),
|
2020-06-14 22:18:46 +00:00
|
|
|
static_cast<size_t>(out_buffer.GetSize())
|
|
|
|
));
|
2020-05-22 10:29:36 +00:00
|
|
|
|
2020-06-22 21:14:54 +00:00
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2020-06-12 21:25:09 +00:00
|
|
|
/* 1.0.0 - 3.0.2 */
|
|
|
|
Result BtdrvMitmService::RegisterHidReportEventDeprecated(sf::OutCopyHandle out_handle) {
|
|
|
|
return RegisterHidReportEvent(out_handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 4.0.0+ */
|
2020-05-22 10:29:36 +00:00
|
|
|
Result BtdrvMitmService::RegisterHidReportEvent(sf::OutCopyHandle out_handle) {
|
2020-06-14 22:18:46 +00:00
|
|
|
if (!bluetooth::hid::report::IsInitialized()) {
|
2020-06-02 21:24:40 +00:00
|
|
|
Handle handle = INVALID_HANDLE;
|
2020-06-14 22:18:46 +00:00
|
|
|
R_TRY(btdrvRegisterHidReportEventFwd(this->forward_service.get(), &handle));
|
2020-08-25 00:05:19 +00:00
|
|
|
R_TRY(bluetooth::hid::report::Initialize(handle, this->forward_service.get(), os::GetThreadId(os::GetCurrentThread())));
|
2020-06-13 17:15:59 +00:00
|
|
|
out_handle.SetValue(os::GetReadableHandleOfSystemEvent(bluetooth::hid::report::GetForwardEvent()));
|
2020-06-02 21:24:40 +00:00
|
|
|
}
|
|
|
|
else {
|
2020-06-13 17:15:59 +00:00
|
|
|
out_handle.SetValue(os::GetReadableHandleOfSystemEvent(bluetooth::hid::report::GetUserForwardEvent()));
|
2020-06-02 21:24:40 +00:00
|
|
|
}
|
2020-05-22 10:29:36 +00:00
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2020-06-14 22:18:46 +00:00
|
|
|
/* 1.0.0 - 6.2.0 */
|
2020-07-01 13:34:07 +00:00
|
|
|
Result _GetHidReportEventInfoDeprecated(Service *srv, sf::Out<bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
2020-06-22 21:14:54 +00:00
|
|
|
R_TRY(bluetooth::hid::report::GetEventInfo(out_type.GetPointer(),
|
2020-08-26 18:52:47 +00:00
|
|
|
static_cast<uint8_t *>(out_buffer.GetPointer()),
|
2020-06-12 21:25:09 +00:00
|
|
|
static_cast<size_t>(out_buffer.GetSize())
|
|
|
|
));
|
|
|
|
|
2020-06-14 22:18:46 +00:00
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
2020-06-12 21:25:09 +00:00
|
|
|
|
2020-06-14 22:18:46 +00:00
|
|
|
/* 1.0.0 - 3.0.2 */
|
2020-07-01 13:34:07 +00:00
|
|
|
Result BtdrvMitmService::GetHidReportEventInfoDeprecated1(sf::Out<bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
2020-06-14 22:18:46 +00:00
|
|
|
return _GetHidReportEventInfoDeprecated(this->forward_service.get(), out_type, out_buffer);
|
|
|
|
}
|
2020-06-12 21:25:09 +00:00
|
|
|
|
2020-06-14 22:18:46 +00:00
|
|
|
/* 4.0.0 - 6.2.0 */
|
2020-07-01 13:34:07 +00:00
|
|
|
Result BtdrvMitmService::GetHidReportEventInfoDeprecated2(sf::Out<bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
2020-06-14 22:18:46 +00:00
|
|
|
return _GetHidReportEventInfoDeprecated(this->forward_service.get(), out_type, out_buffer);
|
2020-06-12 21:25:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 7.0.0+ */
|
2020-05-22 10:29:36 +00:00
|
|
|
Result BtdrvMitmService::GetHidReportEventInfo(sf::OutCopyHandle out_handle) {
|
|
|
|
Handle handle = INVALID_HANDLE;
|
2020-06-14 22:18:46 +00:00
|
|
|
R_TRY(btdrvGetHidReportEventInfoFwd(this->forward_service.get(), &handle));
|
2020-06-13 17:15:59 +00:00
|
|
|
R_TRY(bluetooth::hid::report::MapRemoteSharedMemory(handle));
|
|
|
|
out_handle.SetValue(bluetooth::hid::report::GetFakeSharedMemory()->handle);
|
2020-06-02 21:24:40 +00:00
|
|
|
|
2020-05-22 10:29:36 +00:00
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
|
|
|
Result BtdrvMitmService::InitializeBle(sf::OutCopyHandle out_handle) {
|
2020-06-14 22:18:46 +00:00
|
|
|
if (!bluetooth::ble::IsInitialized()) {
|
|
|
|
Handle handle = INVALID_HANDLE;
|
|
|
|
R_TRY(btdrvInitializeBleFwd(this->forward_service.get(), &handle));
|
|
|
|
R_TRY(bluetooth::ble::Initialize(handle));
|
2020-06-22 21:14:54 +00:00
|
|
|
|
2020-06-13 17:15:59 +00:00
|
|
|
out_handle.SetValue(os::GetReadableHandleOfSystemEvent(bluetooth::ble::GetForwardEvent()));
|
2020-06-13 00:08:43 +00:00
|
|
|
}
|
|
|
|
else {
|
2020-06-13 17:15:59 +00:00
|
|
|
out_handle.SetValue(os::GetReadableHandleOfSystemEvent(bluetooth::ble::GetUserForwardEvent()));
|
2020-06-13 00:08:43 +00:00
|
|
|
}
|
2020-05-22 10:29:36 +00:00
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
|
|
|
Result BtdrvMitmService::FinalizeBle(void) {
|
|
|
|
if (this->client_info.program_id == ncm::SystemProgramId::Btm) {
|
2020-06-14 22:18:46 +00:00
|
|
|
R_TRY(btdrvFinalizeBleFwd(this->forward_service.get()));
|
2020-05-22 10:29:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
2020-05-11 20:30:08 +00:00
|
|
|
}
|
|
|
|
|
2020-07-01 13:34:07 +00:00
|
|
|
Result BtdrvMitmService::GetBleManagedEventInfoDeprecated(sf::Out<bluetooth::BleEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
2020-06-14 23:14:09 +00:00
|
|
|
return GetBleManagedEventInfo(out_type, out_buffer);
|
|
|
|
}
|
|
|
|
|
2020-08-26 18:52:47 +00:00
|
|
|
Result BtdrvMitmService::GetBleManagedEventInfo(sf::Out<bluetooth::BleEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
2020-06-22 21:14:54 +00:00
|
|
|
R_TRY(bluetooth::ble::GetEventInfo(this->client_info.program_id,
|
|
|
|
out_type.GetPointer(),
|
2020-08-26 18:52:47 +00:00
|
|
|
static_cast<uint8_t *>(out_buffer.GetPointer()),
|
2020-06-14 23:14:09 +00:00
|
|
|
static_cast<size_t>(out_buffer.GetSize())
|
|
|
|
));
|
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2020-08-26 18:52:47 +00:00
|
|
|
Result BtdrvMitmService::GetRealSharedMemory(sf::OutCopyHandle out_handle) {
|
|
|
|
out_handle.SetValue(bluetooth::hid::report::GetRealSharedMemory()->handle);
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
2020-06-02 21:24:40 +00:00
|
|
|
|
2020-08-26 18:52:47 +00:00
|
|
|
Result BtdrvMitmService::GetFakeSharedMemory(sf::OutCopyHandle out_handle) {
|
|
|
|
out_handle.SetValue(bluetooth::hid::report::GetFakeSharedMemory()->handle);
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
2020-06-02 21:24:40 +00:00
|
|
|
|
2020-08-26 18:52:47 +00:00
|
|
|
void BtdrvMitmService::RedirectCoreEvents(bool redirect) {
|
|
|
|
g_redirect_core_events = redirect;
|
2020-08-04 20:18:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BtdrvMitmService::RedirectHidEvents(bool redirect) {
|
2020-08-26 18:52:47 +00:00
|
|
|
g_redirect_hid_events = redirect;
|
2020-06-02 21:24:40 +00:00
|
|
|
}
|
|
|
|
|
2020-07-09 17:38:53 +00:00
|
|
|
void BtdrvMitmService::RedirectHidReportEvents(bool redirect) {
|
2020-08-26 18:52:47 +00:00
|
|
|
g_redirect_hid_report_events = redirect;
|
2020-07-09 17:38:53 +00:00
|
|
|
}
|
|
|
|
|
2020-08-04 20:18:15 +00:00
|
|
|
void BtdrvMitmService::RedirectBleEvents(bool redirect) {
|
2020-08-26 18:52:47 +00:00
|
|
|
g_redirect_ble_events = redirect;
|
2020-08-05 21:20:04 +00:00
|
|
|
}
|
|
|
|
|
2020-05-11 20:30:08 +00:00
|
|
|
}
|