2020-08-25 19:23:38 +00:00
|
|
|
/*
|
2021-01-26 03:03:26 +00:00
|
|
|
* Copyright (c) 2020-2021 ndeadly
|
2020-08-25 19:23:38 +00:00
|
|
|
*
|
2020-08-26 22:50:34 +00:00
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms and conditions of the GNU General Public License,
|
|
|
|
* version 2, as published by the Free Software Foundation.
|
2020-08-25 19:23:38 +00:00
|
|
|
*
|
2020-08-26 22:50:34 +00:00
|
|
|
* This program is distributed in the hope 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.
|
2020-08-25 19:23:38 +00:00
|
|
|
*
|
|
|
|
* 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"
|
2021-01-26 03:02:15 +00:00
|
|
|
#include "bluetooth/bluetooth_core.hpp"
|
|
|
|
#include "bluetooth/bluetooth_hid.hpp"
|
|
|
|
#include "bluetooth/bluetooth_ble.hpp"
|
2021-02-20 23:16:23 +00:00
|
|
|
#include "../mcmitm_initialization.hpp"
|
2020-09-11 20:03:41 +00:00
|
|
|
#include "../controllers/controller_management.hpp"
|
2020-08-26 18:52:47 +00:00
|
|
|
#include <switch.h>
|
|
|
|
#include <cstring>
|
2020-07-27 17:42:40 +00:00
|
|
|
|
2021-02-03 22:52:39 +00:00
|
|
|
namespace ams::mitm::bluetooth {
|
2020-05-22 10:29:36 +00:00
|
|
|
|
|
|
|
Result BtdrvMitmService::InitializeBluetooth(sf::OutCopyHandle out_handle) {
|
2021-02-03 22:21:59 +00:00
|
|
|
if (!ams::bluetooth::core::IsInitialized()) {
|
2021-02-21 18:35:19 +00:00
|
|
|
// Forward to the real function to obtain the system event handle
|
2021-10-16 22:15:56 +00:00
|
|
|
os::NativeHandle handle = os::InvalidNativeHandle;
|
|
|
|
R_TRY(btdrvInitializeBluetoothFwd(m_forward_service.get(), &handle));
|
2020-06-15 12:13:17 +00:00
|
|
|
|
2021-02-21 18:35:19 +00:00
|
|
|
// Attach the real system event handle to our own event
|
|
|
|
ams::bluetooth::core::GetSystemEvent()->AttachReadableHandle(handle, false, os::EventClearMode_ManualClear);
|
2021-10-16 22:15:56 +00:00
|
|
|
|
2021-02-21 18:35:19 +00:00
|
|
|
// Return our forwarder event handle to the caller instead
|
2021-10-16 22:15:56 +00:00
|
|
|
out_handle.SetValue(ams::bluetooth::core::GetForwardEvent()->GetReadableHandle(), false);
|
2021-02-21 18:35:19 +00:00
|
|
|
|
|
|
|
// Initialise the hid report circular buffer
|
|
|
|
R_TRY(ams::bluetooth::hid::report::InitializeReportBuffer());
|
2021-10-16 22:15:56 +00:00
|
|
|
|
2021-02-21 18:35:19 +00:00
|
|
|
// Signal that the interface is initialised
|
|
|
|
ams::bluetooth::core::SignalInitialized();
|
2020-05-22 10:29:36 +00:00
|
|
|
} else {
|
2021-10-16 22:15:56 +00:00
|
|
|
out_handle.SetValue(ams::bluetooth::core::GetUserForwardEvent()->GetReadableHandle(), false);
|
2020-05-22 10:29:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2021-02-20 23:16:23 +00:00
|
|
|
Result BtdrvMitmService::EnableBluetooth(void) {
|
2021-10-16 22:15:56 +00:00
|
|
|
R_TRY(btdrvEnableBluetoothFwd(m_forward_service.get()));
|
2021-02-20 23:16:23 +00:00
|
|
|
ams::bluetooth::core::SignalEnabled();
|
|
|
|
|
|
|
|
// Wait until mc.mitm module initialisation has completed before returning
|
|
|
|
ams::mitm::WaitInitialized();
|
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2021-10-16 22:15:56 +00:00
|
|
|
Result BtdrvMitmService::GetEventInfo(sf::Out<ams::bluetooth::EventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
|
|
|
R_TRY(ams::bluetooth::core::GetEventInfo(m_client_info.program_id,
|
2021-02-21 19:43:39 +00:00
|
|
|
out_type.GetPointer(),
|
2021-10-16 22:15:56 +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) {
|
2021-02-03 22:21:59 +00:00
|
|
|
if (!ams::bluetooth::hid::IsInitialized()) {
|
2021-02-21 18:35:19 +00:00
|
|
|
// Forward to the real function to obtain the system event handle
|
2021-10-16 22:15:56 +00:00
|
|
|
os::NativeHandle handle = os::InvalidNativeHandle;
|
|
|
|
R_TRY(btdrvInitializeHidFwd(m_forward_service.get(), &handle, version));
|
2020-06-22 21:14:54 +00:00
|
|
|
|
2021-02-21 18:35:19 +00:00
|
|
|
// Attach the real system event handle to our own event
|
|
|
|
ams::bluetooth::hid::GetSystemEvent()->AttachReadableHandle(handle, false, os::EventClearMode_ManualClear);
|
2021-10-16 22:15:56 +00:00
|
|
|
|
2021-02-21 18:35:19 +00:00
|
|
|
// Return our forwarder event handle to the caller instead
|
2021-10-16 22:15:56 +00:00
|
|
|
out_handle.SetValue(ams::bluetooth::hid::GetForwardEvent()->GetReadableHandle(), false);
|
2021-02-21 18:35:19 +00:00
|
|
|
|
|
|
|
// Signal that the interface is initialised
|
|
|
|
ams::bluetooth::hid::SignalInitialized();
|
2020-05-22 10:29:36 +00:00
|
|
|
}
|
|
|
|
else {
|
2021-10-16 22:15:56 +00:00
|
|
|
out_handle.SetValue(ams::bluetooth::hid::GetUserForwardEvent()->GetReadableHandle(), false);
|
2020-05-22 10:29:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2021-02-03 22:21:59 +00:00
|
|
|
Result BtdrvMitmService::WriteHidData(ams::bluetooth::Address address, const sf::InPointerBuffer &buffer) {
|
|
|
|
auto report = reinterpret_cast<const ams::bluetooth::HidReport *>(buffer.GetPointer());
|
2020-06-22 21:14:54 +00:00
|
|
|
|
2021-10-16 22:15:56 +00:00
|
|
|
if (m_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 {
|
2021-10-16 22:15:56 +00:00
|
|
|
R_TRY(btdrvWriteHidDataFwd(m_forward_service.get(), &address, report));
|
2020-07-27 17:42:40 +00:00
|
|
|
}
|
2020-05-22 10:29:36 +00:00
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2021-02-03 22:21:59 +00:00
|
|
|
Result BtdrvMitmService::GetHidEventInfo(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
2021-10-16 22:15:56 +00:00
|
|
|
R_TRY(ams::bluetooth::hid::GetEventInfo(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();
|
|
|
|
}
|
|
|
|
|
2021-02-09 20:52:43 +00:00
|
|
|
Result BtdrvMitmService::SetTsi(ams::bluetooth::Address address, u8 tsi) {
|
2021-02-09 21:18:43 +00:00
|
|
|
auto device = controller::LocateHandler(&address);
|
2021-07-09 13:20:38 +00:00
|
|
|
if (!device || device->SupportsSetTsiCommand())
|
2021-02-09 21:18:43 +00:00
|
|
|
return sm::mitm::ResultShouldForwardToSession();
|
|
|
|
|
|
|
|
if (hos::GetVersion() < hos::Version_9_0_0) {
|
|
|
|
const struct {
|
|
|
|
uint32_t type;
|
|
|
|
ams::bluetooth::Address address;
|
|
|
|
uint8_t pad[2];
|
|
|
|
uint32_t status;
|
|
|
|
} event_data = {tsi == 0xff ? 1u : 0u, address, {0, 0}, 0};
|
|
|
|
|
2021-05-17 17:46:50 +00:00
|
|
|
ams::bluetooth::hid::SignalFakeEvent(BtdrvHidEventTypeOld_Ext, &event_data, sizeof(event_data));
|
2021-02-09 21:18:43 +00:00
|
|
|
}
|
2021-04-14 22:10:22 +00:00
|
|
|
else if (hos::GetVersion() < hos::Version_12_0_0) {
|
2021-02-09 21:18:43 +00:00
|
|
|
const struct {
|
|
|
|
uint32_t type;
|
|
|
|
uint32_t status;
|
|
|
|
ams::bluetooth::Address address;
|
|
|
|
uint8_t pad[2];
|
|
|
|
} event_data = {tsi == 0xff ? 1u : 0u, 0, address, {0, 0}};
|
|
|
|
|
2021-05-17 17:46:50 +00:00
|
|
|
ams::bluetooth::hid::SignalFakeEvent(BtdrvHidEventTypeOld_Ext, &event_data, sizeof(event_data));
|
2021-02-09 21:18:43 +00:00
|
|
|
}
|
2021-04-14 22:10:22 +00:00
|
|
|
else {
|
|
|
|
const struct {
|
|
|
|
ams::bluetooth::Address address;
|
|
|
|
uint8_t flag;
|
|
|
|
uint8_t tsi;
|
|
|
|
} event_data = { address, 1, tsi };
|
|
|
|
|
2021-05-17 17:46:50 +00:00
|
|
|
ams::bluetooth::core::SignalFakeEvent(BtdrvEventType_Tsi, &event_data, sizeof(event_data));
|
2021-04-14 22:10:22 +00:00
|
|
|
}
|
2021-02-09 21:18:43 +00:00
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
2021-02-09 20:52:43 +00:00
|
|
|
}
|
|
|
|
|
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) {
|
2021-02-03 22:21:59 +00:00
|
|
|
if (!ams::bluetooth::hid::report::IsInitialized()) {
|
2021-10-16 22:15:56 +00:00
|
|
|
os::NativeHandle handle = os::InvalidNativeHandle;
|
|
|
|
R_TRY(btdrvRegisterHidReportEventFwd(m_forward_service.get(), &handle));
|
|
|
|
R_TRY(ams::bluetooth::hid::report::Initialize(handle, m_forward_service.get(), os::GetThreadId(os::GetCurrentThread())));
|
|
|
|
out_handle.SetValue(ams::bluetooth::hid::report::GetForwardEvent()->GetReadableHandle(), false);
|
2020-06-02 21:24:40 +00:00
|
|
|
}
|
|
|
|
else {
|
2021-10-16 22:15:56 +00:00
|
|
|
out_handle.SetValue(ams::bluetooth::hid::report::GetUserForwardEvent()->GetReadableHandle(), false);
|
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 */
|
2021-02-03 22:21:59 +00:00
|
|
|
Result _GetHidReportEventInfoDeprecated(Service *srv, sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
2021-10-16 22:15:56 +00:00
|
|
|
AMS_UNUSED(srv);
|
|
|
|
|
|
|
|
R_TRY(ams::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 */
|
2021-02-03 22:21:59 +00:00
|
|
|
Result BtdrvMitmService::GetHidReportEventInfoDeprecated1(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
2021-10-16 22:15:56 +00:00
|
|
|
return _GetHidReportEventInfoDeprecated(m_forward_service.get(), out_type, out_buffer);
|
2020-06-14 22:18:46 +00:00
|
|
|
}
|
2020-06-12 21:25:09 +00:00
|
|
|
|
2020-06-14 22:18:46 +00:00
|
|
|
/* 4.0.0 - 6.2.0 */
|
2021-02-03 22:21:59 +00:00
|
|
|
Result BtdrvMitmService::GetHidReportEventInfoDeprecated2(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
2021-10-16 22:15:56 +00:00
|
|
|
return _GetHidReportEventInfoDeprecated(m_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) {
|
2021-10-16 22:15:56 +00:00
|
|
|
os::NativeHandle handle = os::InvalidNativeHandle;
|
|
|
|
R_TRY(btdrvGetHidReportEventInfoFwd(m_forward_service.get(), &handle));
|
2021-02-03 22:21:59 +00:00
|
|
|
R_TRY(ams::bluetooth::hid::report::MapRemoteSharedMemory(handle));
|
2021-10-16 23:11:12 +00:00
|
|
|
out_handle.SetValue(ams::bluetooth::hid::report::GetFakeSharedMemory()->GetHandle(), false);
|
2021-10-16 22:15:56 +00:00
|
|
|
|
2020-05-22 10:29:36 +00:00
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
|
|
|
Result BtdrvMitmService::InitializeBle(sf::OutCopyHandle out_handle) {
|
2021-02-03 22:21:59 +00:00
|
|
|
if (!ams::bluetooth::ble::IsInitialized()) {
|
2021-02-21 18:35:19 +00:00
|
|
|
// Forward to the real function to obtain the system event handle
|
2021-10-16 22:15:56 +00:00
|
|
|
os::NativeHandle handle = os::InvalidNativeHandle;
|
|
|
|
R_TRY(btdrvInitializeBleFwd(m_forward_service.get(), &handle));
|
2020-06-22 21:14:54 +00:00
|
|
|
|
2021-02-21 18:35:19 +00:00
|
|
|
// Attach the real system event handle to our own event
|
|
|
|
ams::bluetooth::ble::GetSystemEvent()->AttachReadableHandle(handle, false, os::EventClearMode_ManualClear);
|
2021-10-16 22:15:56 +00:00
|
|
|
|
2021-02-21 18:35:19 +00:00
|
|
|
// Return our forwarder event handle to the caller instead
|
2021-10-16 22:15:56 +00:00
|
|
|
out_handle.SetValue(ams::bluetooth::ble::GetForwardEvent()->GetReadableHandle(), false);
|
|
|
|
|
2021-02-21 18:35:19 +00:00
|
|
|
// Signal that the interface is initialised
|
|
|
|
ams::bluetooth::ble::SignalInitialized();
|
2020-06-13 00:08:43 +00:00
|
|
|
}
|
|
|
|
else {
|
2021-10-16 22:15:56 +00:00
|
|
|
out_handle.SetValue(ams::bluetooth::ble::GetUserForwardEvent()->GetReadableHandle(), false);
|
2020-06-13 00:08:43 +00:00
|
|
|
}
|
2020-05-22 10:29:36 +00:00
|
|
|
|
|
|
|
return ams::ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2021-02-03 22:21:59 +00:00
|
|
|
Result BtdrvMitmService::GetBleManagedEventInfoDeprecated(sf::Out<ams::bluetooth::BleEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
2020-06-14 23:14:09 +00:00
|
|
|
return GetBleManagedEventInfo(out_type, out_buffer);
|
|
|
|
}
|
2021-10-16 22:15:56 +00:00
|
|
|
|
|
|
|
Result BtdrvMitmService::GetBleManagedEventInfo(sf::Out<ams::bluetooth::BleEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
|
|
|
R_TRY(ams::bluetooth::ble::GetEventInfo(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) {
|
2021-10-16 23:11:12 +00:00
|
|
|
out_handle.SetValue(ams::bluetooth::hid::report::GetRealSharedMemory()->GetHandle(), false);
|
2020-08-26 18:52:47 +00:00
|
|
|
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) {
|
2021-10-16 23:11:12 +00:00
|
|
|
out_handle.SetValue(ams::bluetooth::hid::report::GetFakeSharedMemory()->GetHandle(), false);
|
2020-08-26 18:52:47 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2021-06-23 00:10:05 +00:00
|
|
|
void BtdrvMitmService::SignalHidReportRead(void) {
|
|
|
|
ams::bluetooth::hid::report::SignalReportRead();
|
|
|
|
}
|
|
|
|
|
2020-05-11 20:30:08 +00:00
|
|
|
}
|