mirror of
https://github.com/ndeadly/MissionControl
synced 2024-11-23 04:43:10 +00:00
Merge branch 'feature/integrated-btm-mitm' into develop
# Conflicts: # bluetooth-mitm/source/btdrv_mitm/controllers/default_controller.cpp # bluetooth-mitm/source/btdrv_mitm/controllers/default_controller.hpp
This commit is contained in:
commit
b4f8b61eb0
58 changed files with 553 additions and 156 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -3,7 +3,7 @@
|
||||||
.patches/
|
.patches/
|
||||||
tests/
|
tests/
|
||||||
dist/
|
dist/
|
||||||
btdrv-mitm/build/
|
bluetooth-mitm/build/
|
||||||
*.log
|
*.log
|
||||||
*.elf
|
*.elf
|
||||||
*.nro
|
*.nro
|
||||||
|
|
19
Makefile
19
Makefile
|
@ -1,27 +1,28 @@
|
||||||
PROJECT_NAME := MissionControl
|
PROJECT_NAME := MissionControl
|
||||||
BTDRVMITM_TID := 010000000000bd00
|
BLUETOOTH_MITM_TID := 010000000000bd00
|
||||||
|
|
||||||
TARGETS := btdrv-mitm
|
TARGETS := bluetooth-mitm
|
||||||
|
|
||||||
all: $(TARGETS)
|
all: $(TARGETS)
|
||||||
|
|
||||||
btdrv-mitm:
|
bluetooth-mitm:
|
||||||
$(MAKE) -C $@
|
$(MAKE) -C $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C Atmosphere/libraries clean
|
$(MAKE) -C Atmosphere/libraries clean
|
||||||
$(MAKE) -C btdrv-mitm clean
|
$(MAKE) -C bluetooth-mitm clean
|
||||||
rm -rf dist
|
rm -rf dist
|
||||||
|
|
||||||
dist: all
|
dist: all
|
||||||
rm -rf dist
|
rm -rf dist
|
||||||
|
|
||||||
mkdir -p dist/atmosphere/contents/$(BTDRVMITM_TID)
|
mkdir -p dist/atmosphere/contents/$(BLUETOOTH_MITM_TID)
|
||||||
cp btdrv-mitm/btdrv-mitm.nsp dist/atmosphere/contents/$(BTDRVMITM_TID)/exefs.nsp
|
cp bluetooth-mitm/bluetooth-mitm.nsp dist/atmosphere/contents/$(BLUETOOTH_MITM_TID)/exefs.nsp
|
||||||
echo "btdrv" > dist/atmosphere/contents/$(BTDRVMITM_TID)/mitm.lst
|
echo "btdrv" >> dist/atmosphere/contents/$(BLUETOOTH_MITM_TID)/mitm.lst
|
||||||
|
echo "btm" >> dist/atmosphere/contents/$(BLUETOOTH_MITM_TID)/mitm.lst
|
||||||
|
|
||||||
mkdir -p dist/atmosphere/contents/$(BTDRVMITM_TID)/flags
|
mkdir -p dist/atmosphere/contents/$(BLUETOOTH_MITM_TID)/flags
|
||||||
touch dist/atmosphere/contents/$(BTDRVMITM_TID)/flags/boot2.flag
|
touch dist/atmosphere/contents/$(BLUETOOTH_MITM_TID)/flags/boot2.flag
|
||||||
|
|
||||||
cp -r exefs_patches dist/atmosphere/
|
cp -r exefs_patches dist/atmosphere/
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
{
|
{
|
||||||
"name": "btdrv.mitm",
|
"name": "bluetooth.mitm",
|
||||||
"title_id": "0x010000000000bd00",
|
"title_id": "0x010000000000bd00",
|
||||||
"title_id_range_min": "0x010000000000bd00",
|
"title_id_range_min": "0x010000000000bd00",
|
||||||
"title_id_range_max": "0x010000000000bd00",
|
"title_id_range_max": "0x010000000000bd00",
|
||||||
"main_thread_stack_size": "0x4000",
|
"main_thread_stack_size": "0x1000",
|
||||||
"main_thread_priority": 16,
|
"main_thread_priority": 42,
|
||||||
"default_cpu_id": 3,
|
"default_cpu_id": 3,
|
||||||
"process_category": 1,
|
"process_category": 1,
|
||||||
"is_retail": true,
|
"is_retail": true,
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
"type": "kernel_flags",
|
"type": "kernel_flags",
|
||||||
"value": {
|
"value": {
|
||||||
"highest_thread_priority": 63,
|
"highest_thread_priority": 63,
|
||||||
"lowest_thread_priority": 4,
|
"lowest_thread_priority": 12,
|
||||||
"lowest_cpu_id": 3,
|
"lowest_cpu_id": 3,
|
||||||
"highest_cpu_id": 3
|
"highest_cpu_id": 3
|
||||||
}
|
}
|
|
@ -16,9 +16,8 @@
|
||||||
*/
|
*/
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include "btdrv_mitm_service.hpp"
|
#include "btdrv_mitm/btdrvmitm_module.hpp"
|
||||||
#include "bluetooth/bluetooth_events.hpp"
|
#include "btm_mitm/btmmitm_module.hpp"
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
@ -93,27 +92,20 @@ void __libnx_exception_handler(ThreadExceptionDump* ctx) {
|
||||||
ams::CrashHandler(ctx);
|
ams::CrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
ams::Result LaunchModules(void) {
|
||||||
|
R_TRY(ams::mitm::btdrv::Launch());
|
||||||
constexpr sm::ServiceName BtdrvMitmServiceName = sm::ServiceName::Encode("btdrv");
|
R_TRY(ams::mitm::btm::Launch());
|
||||||
|
return ams::ResultSuccess();
|
||||||
struct ServerOptions {
|
}
|
||||||
static constexpr size_t PointerBufferSize = 0x1000;
|
|
||||||
static constexpr size_t MaxDomains = 0;
|
|
||||||
static constexpr size_t MaxDomainObjects = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr size_t MaxServers = 1;
|
|
||||||
constexpr size_t MaxSessions = 6;
|
|
||||||
|
|
||||||
|
void WaitModules(void) {
|
||||||
|
ams::mitm::btm::WaitFinished();
|
||||||
|
ams::mitm::btdrv::WaitFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
R_ABORT_UNLESS(bluetooth::events::Initialize());
|
R_ABORT_UNLESS(LaunchModules());
|
||||||
|
WaitModules();
|
||||||
auto server_manager = std::make_unique<sf::hipc::ServerManager<MaxServers, ServerOptions, MaxSessions>>();
|
|
||||||
R_ABORT_UNLESS((server_manager->RegisterMitmServer<ams::mitm::btdrv::IBtdrvMitmInterface, ams::mitm::btdrv::BtdrvMitmService>(BtdrvMitmServiceName)));
|
|
||||||
server_manager->LoopProcess();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
#include "bluetooth_core.hpp"
|
#include "bluetooth_core.hpp"
|
||||||
#include "../btdrv_mitm_flags.hpp"
|
#include "../btdrv_mitm_flags.hpp"
|
||||||
#include "../controllers/controller_management.hpp"
|
#include "../../controllers/controller_management.hpp"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -84,17 +84,17 @@ namespace ams::bluetooth::core {
|
||||||
if (program_id == ncm::SystemProgramId::Btm) {
|
if (program_id == ncm::SystemProgramId::Btm) {
|
||||||
switch (g_current_event_type) {
|
switch (g_current_event_type) {
|
||||||
case BluetoothEvent_DeviceFound:
|
case BluetoothEvent_DeviceFound:
|
||||||
if (controller::IsGamepad(&event_data->deviceFound.cod) && !controller::IsOfficialSwitchControllerName(event_data->deviceFound.name)) {
|
if (controller::IsGamepad(&event_data->deviceFound.cod) && !controller::IsOfficialSwitchControllerName(event_data->deviceFound.name, sizeof(BluetoothName))) {
|
||||||
std::strncpy(event_data->deviceFound.name, controller::pro_controller_name, sizeof(BluetoothName) - 1);
|
std::strncpy(event_data->deviceFound.name, controller::pro_controller_name, sizeof(BluetoothName) - 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BluetoothEvent_PinRequest:
|
case BluetoothEvent_PinRequest:
|
||||||
if (!controller::IsOfficialSwitchControllerName(event_data->pinReply.name)) {
|
if (!controller::IsOfficialSwitchControllerName(event_data->pinReply.name, sizeof(BluetoothName))) {
|
||||||
std::strncpy(event_data->pinReply.name, controller::pro_controller_name, sizeof(BluetoothName) - 1);
|
std::strncpy(event_data->pinReply.name, controller::pro_controller_name, sizeof(BluetoothName) - 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BluetoothEvent_SspRequest:
|
case BluetoothEvent_SspRequest:
|
||||||
if (!controller::IsOfficialSwitchControllerName(event_data->sspReply.name)) {
|
if (!controller::IsOfficialSwitchControllerName(event_data->sspReply.name, sizeof(BluetoothName))) {
|
||||||
std::strncpy(event_data->sspReply.name, controller::pro_controller_name, sizeof(BluetoothName) - 1);
|
std::strncpy(event_data->sspReply.name, controller::pro_controller_name, sizeof(BluetoothName) - 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
#include "bluetooth_hid.hpp"
|
#include "bluetooth_hid.hpp"
|
||||||
#include "../btdrv_mitm_flags.hpp"
|
#include "../btdrv_mitm_flags.hpp"
|
||||||
#include "../controllers/controller_management.hpp"
|
#include "../../controllers/controller_management.hpp"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <cstring>
|
#include <cstring>
|
|
@ -18,7 +18,7 @@
|
||||||
#include "bluetooth_circular_buffer.hpp"
|
#include "bluetooth_circular_buffer.hpp"
|
||||||
#include "../btdrv_shim.h"
|
#include "../btdrv_shim.h"
|
||||||
#include "../btdrv_mitm_flags.hpp"
|
#include "../btdrv_mitm_flags.hpp"
|
||||||
#include "../controllers/controller_management.hpp"
|
#include "../../controllers/controller_management.hpp"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <cstring>
|
#include <cstring>
|
|
@ -20,32 +20,6 @@
|
||||||
|
|
||||||
namespace ams::bluetooth {
|
namespace ams::bluetooth {
|
||||||
|
|
||||||
enum SubCmdType : u8 {
|
|
||||||
SubCmd_GetControllerState = 0x00,
|
|
||||||
SubCmd_ManualPair = 0x01,
|
|
||||||
SubCmd_RequestDeviceInfo = 0x02,
|
|
||||||
SubCmd_SetInputReportMode = 0x03,
|
|
||||||
SubCmd_TriggersElapsedTime = 0x04,
|
|
||||||
SubCmd_SetHciState = 0x06,
|
|
||||||
SubCmd_ResetPairingInfo = 0x07,
|
|
||||||
SubCmd_SetShipPowerState = 0x08,
|
|
||||||
SubCmd_SpiFlashRead = 0x10,
|
|
||||||
SubCmd_SpiFlashWrite = 0x11,
|
|
||||||
SubCmd_SpiSectorErase = 0x12,
|
|
||||||
SubCmd_ResetMcu = 0x20,
|
|
||||||
SubCmd_SetMcuConfig = 0x21,
|
|
||||||
SubCmd_SetMcuState = 0x22,
|
|
||||||
SubCmd_SetPlayerLeds = 0x30,
|
|
||||||
SubCmd_GetPlayerLeds = 0x31,
|
|
||||||
SubCmd_SetHomeLed = 0x38,
|
|
||||||
SubCmd_EnableImu = 0x40,
|
|
||||||
SubCmd_SetImuSensitivity = 0x41,
|
|
||||||
SubCmd_WriteImuRegisters = 0x42,
|
|
||||||
SubCmd_ReadImuRegisters = 0x43,
|
|
||||||
SubCmd_EnableVibration = 0x48,
|
|
||||||
SubCmd_GetRegulatedVoltage = 0x50,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef BluetoothEventType EventType;
|
typedef BluetoothEventType EventType;
|
||||||
typedef BluetoothHidEventType HidEventType;
|
typedef BluetoothHidEventType HidEventType;
|
||||||
typedef BluetoothBleEventType BleEventType;
|
typedef BluetoothBleEventType BleEventType;
|
||||||
|
@ -63,8 +37,4 @@ namespace ams::bluetooth {
|
||||||
|
|
||||||
typedef BluetoothHhReportType HhReportType;
|
typedef BluetoothHhReportType HhReportType;
|
||||||
|
|
||||||
struct DeviceSettings : sf::LargeData {
|
|
||||||
BluetoothDevicesSettings device;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -18,7 +18,7 @@
|
||||||
#include "btdrv_mitm_flags.hpp"
|
#include "btdrv_mitm_flags.hpp"
|
||||||
#include "btdrv_shim.h"
|
#include "btdrv_shim.h"
|
||||||
#include "bluetooth/bluetooth_events.hpp"
|
#include "bluetooth/bluetooth_events.hpp"
|
||||||
#include "controllers/controller_management.hpp"
|
#include "../controllers/controller_management.hpp"
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
@ -89,20 +89,6 @@ namespace ams::mitm::btdrv {
|
||||||
return ams::ResultSuccess();
|
return ams::ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result BtdrvMitmService::GetPairedDeviceInfo(sf::Out<bluetooth::DeviceSettings> out, bluetooth::Address address) {
|
|
||||||
auto device = reinterpret_cast<BluetoothDevicesSettings *>(out.GetPointer());
|
|
||||||
|
|
||||||
R_TRY(btdrvGetPairedDeviceInfoFwd(this->forward_service.get(), &address, device));
|
|
||||||
|
|
||||||
if (this->client_info.program_id == ncm::SystemProgramId::Btm) {
|
|
||||||
if (!controller::IsOfficialSwitchControllerName(device->name)) {
|
|
||||||
std::strncpy(device->name, controller::pro_controller_name, sizeof(BluetoothLocalName) - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ams::ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result BtdrvMitmService::FinalizeHid(void) {
|
Result BtdrvMitmService::FinalizeHid(void) {
|
||||||
// Only btm should be able to make this call
|
// Only btm should be able to make this call
|
||||||
if (this->client_info.program_id == ncm::SystemProgramId::Btm) {
|
if (this->client_info.program_id == ncm::SystemProgramId::Btm) {
|
|
@ -28,7 +28,6 @@ namespace ams::mitm::btdrv {
|
||||||
AMS_SF_METHOD_INFO(C, H, 15, Result, GetEventInfo, (sf::Out<bluetooth::EventType> out_type, const sf::OutPointerBuffer &out_buffer)) \
|
AMS_SF_METHOD_INFO(C, H, 15, Result, GetEventInfo, (sf::Out<bluetooth::EventType> out_type, const sf::OutPointerBuffer &out_buffer)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 16, Result, InitializeHid, (sf::OutCopyHandle out_handle, u16 version)) \
|
AMS_SF_METHOD_INFO(C, H, 16, Result, InitializeHid, (sf::OutCopyHandle out_handle, u16 version)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 19, Result, WriteHidData, (bluetooth::Address address, const sf::InPointerBuffer &buffer)) \
|
AMS_SF_METHOD_INFO(C, H, 19, Result, WriteHidData, (bluetooth::Address address, const sf::InPointerBuffer &buffer)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 25, Result, GetPairedDeviceInfo, (sf::Out<bluetooth::DeviceSettings> out, bluetooth::Address address)) \
|
|
||||||
AMS_SF_METHOD_INFO(C, H, 26, Result, FinalizeHid, (void)) \
|
AMS_SF_METHOD_INFO(C, H, 26, Result, FinalizeHid, (void)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 27, Result, GetHidEventInfo, (sf::Out<bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer)) \
|
AMS_SF_METHOD_INFO(C, H, 27, Result, GetHidEventInfo, (sf::Out<bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 36, Result, RegisterHidReportEventDeprecated, (sf::OutCopyHandle out_handle), hos::Version_1_0_0, hos::Version_3_0_2) \
|
AMS_SF_METHOD_INFO(C, H, 36, Result, RegisterHidReportEventDeprecated, (sf::OutCopyHandle out_handle), hos::Version_1_0_0, hos::Version_3_0_2) \
|
||||||
|
@ -67,7 +66,6 @@ namespace ams::mitm::btdrv {
|
||||||
Result GetEventInfo(sf::Out<bluetooth::EventType> out_type, const sf::OutPointerBuffer &out_buffer);
|
Result GetEventInfo(sf::Out<bluetooth::EventType> out_type, const sf::OutPointerBuffer &out_buffer);
|
||||||
Result InitializeHid(sf::OutCopyHandle out_handle, u16 version);
|
Result InitializeHid(sf::OutCopyHandle out_handle, u16 version);
|
||||||
Result WriteHidData(bluetooth::Address address, const sf::InPointerBuffer &buffer);
|
Result WriteHidData(bluetooth::Address address, const sf::InPointerBuffer &buffer);
|
||||||
Result GetPairedDeviceInfo(sf::Out<bluetooth::DeviceSettings> out, bluetooth::Address address);
|
|
||||||
Result FinalizeHid(void);
|
Result FinalizeHid(void);
|
||||||
Result GetHidEventInfo(sf::Out<bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer);
|
Result GetHidEventInfo(sf::Out<bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer);
|
||||||
Result RegisterHidReportEventDeprecated(sf::OutCopyHandle out_handle);
|
Result RegisterHidReportEventDeprecated(sf::OutCopyHandle out_handle);
|
|
@ -46,17 +46,6 @@ Result btdrvWriteHidDataFwd(Service* srv, const BluetoothAddress *address, const
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result btdrvGetPairedDeviceInfoFwd(Service* srv, const BluetoothAddress *address, BluetoothDevicesSettings *device) {
|
|
||||||
const struct {
|
|
||||||
BluetoothAddress address;
|
|
||||||
} in = { *address };
|
|
||||||
|
|
||||||
return serviceMitmDispatchIn(srv, 25, in,
|
|
||||||
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
|
||||||
.buffers = { {device, sizeof(BluetoothDevicesSettings)} }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result btdrvFinalizeHidFwd(Service* srv) {
|
Result btdrvFinalizeHidFwd(Service* srv) {
|
||||||
return serviceMitmDispatch(srv, 26);
|
return serviceMitmDispatch(srv, 26);
|
||||||
}
|
}
|
|
@ -25,7 +25,6 @@ Result btdrvInitializeBluetoothFwd(Service* srv, Handle *out_handle);
|
||||||
Result btdrvFinalizeBluetoothFwd(Service* srv);
|
Result btdrvFinalizeBluetoothFwd(Service* srv);
|
||||||
Result btdrvInitializeHidFwd(Service* srv, Handle *out_handle, u16 version);
|
Result btdrvInitializeHidFwd(Service* srv, Handle *out_handle, u16 version);
|
||||||
Result btdrvWriteHidDataFwd(Service* srv, const BluetoothAddress *address, const BluetoothHidReport *data);
|
Result btdrvWriteHidDataFwd(Service* srv, const BluetoothAddress *address, const BluetoothHidReport *data);
|
||||||
Result btdrvGetPairedDeviceInfoFwd(Service* srv, const BluetoothAddress *address, BluetoothDevicesSettings *device);
|
|
||||||
Result btdrvFinalizeHidFwd(Service* srv);
|
Result btdrvFinalizeHidFwd(Service* srv);
|
||||||
Result btdrvRegisterHidReportEventFwd(Service* srv, Handle *out_handle);
|
Result btdrvRegisterHidReportEventFwd(Service* srv, Handle *out_handle);
|
||||||
Result btdrvGetHidReportEventInfoFwd(Service* srv, Handle *out_handle);
|
Result btdrvGetHidReportEventInfoFwd(Service* srv, Handle *out_handle);
|
70
bluetooth-mitm/source/btdrv_mitm/btdrvmitm_module.cpp
Normal file
70
bluetooth-mitm/source/btdrv_mitm/btdrvmitm_module.cpp
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#include "btdrvmitm_module.hpp"
|
||||||
|
#include "btdrv_mitm_service.hpp"
|
||||||
|
#include "bluetooth/bluetooth_events.hpp"
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ams::mitm::btdrv {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr sm::ServiceName MitmServiceName = sm::ServiceName::Encode("btdrv");
|
||||||
|
|
||||||
|
struct ServerOptions {
|
||||||
|
static constexpr size_t PointerBufferSize = 0x1000;
|
||||||
|
static constexpr size_t MaxDomains = 0;
|
||||||
|
static constexpr size_t MaxDomainObjects = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr size_t MaxServers = 1;
|
||||||
|
constexpr size_t MaxSessions = 6;
|
||||||
|
|
||||||
|
os::ThreadType g_btdrv_mitm_thread;
|
||||||
|
alignas(os::ThreadStackAlignment) u8 g_btdrv_mitm_thread_stack[0x2000];
|
||||||
|
constexpr s32 g_btdrv_mitm_thread_priority = 16;
|
||||||
|
|
||||||
|
void BtdrvMitmThreadFunction(void *arg) {
|
||||||
|
R_ABORT_UNLESS(bluetooth::events::Initialize());
|
||||||
|
|
||||||
|
auto server_manager = std::make_unique<sf::hipc::ServerManager<MaxServers, ServerOptions, MaxSessions>>();
|
||||||
|
R_ABORT_UNLESS((server_manager->RegisterMitmServer<ams::mitm::btdrv::IBtdrvMitmInterface, ams::mitm::btdrv::BtdrvMitmService>(MitmServiceName)));
|
||||||
|
server_manager->LoopProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Launch(void) {
|
||||||
|
R_TRY(os::CreateThread(&g_btdrv_mitm_thread,
|
||||||
|
BtdrvMitmThreadFunction,
|
||||||
|
nullptr,
|
||||||
|
g_btdrv_mitm_thread_stack,
|
||||||
|
sizeof(g_btdrv_mitm_thread_stack),
|
||||||
|
g_btdrv_mitm_thread_priority
|
||||||
|
));
|
||||||
|
|
||||||
|
os::StartThread(&g_btdrv_mitm_thread);
|
||||||
|
|
||||||
|
return ams::ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitFinished(void) {
|
||||||
|
os::WaitThread(&g_btdrv_mitm_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
25
bluetooth-mitm/source/btdrv_mitm/btdrvmitm_module.hpp
Normal file
25
bluetooth-mitm/source/btdrv_mitm/btdrvmitm_module.hpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::mitm::btdrv {
|
||||||
|
|
||||||
|
Result Launch(void);
|
||||||
|
void WaitFinished(void);
|
||||||
|
|
||||||
|
}
|
43
bluetooth-mitm/source/btm_mitm/btm/btm_types.hpp
Normal file
43
bluetooth-mitm/source/btm_mitm/btm/btm_types.hpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::mitm::btm {
|
||||||
|
|
||||||
|
struct DeviceConditionV100 : sf::LargeData {
|
||||||
|
BtmDeviceConditionV100 condition;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeviceConditionV510 : sf::LargeData {
|
||||||
|
BtmDeviceConditionV510 condition;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeviceConditionV800 : sf::LargeData {
|
||||||
|
BtmDeviceConditionV800 condition;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeviceCondition : sf::LargeData {
|
||||||
|
BtmDeviceConditionV900 condition;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeviceInfo : sf::LargeData {
|
||||||
|
BtmDeviceInfo info;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
79
bluetooth-mitm/source/btm_mitm/btm_mitm_service.cpp
Normal file
79
bluetooth-mitm/source/btm_mitm/btm_mitm_service.cpp
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#include "btm_mitm_service.hpp"
|
||||||
|
#include "btm_shim.h"
|
||||||
|
#include "../controllers/controller_management.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace ams::mitm::btm {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void RenameConnectedDevices(BtmConnectedDevice devices[], size_t count) {
|
||||||
|
for (unsigned int i = 0; i < count; ++i) {
|
||||||
|
auto device = &devices[i];
|
||||||
|
if (!controller::IsOfficialSwitchControllerName(device->name, sizeof(device->name))) {
|
||||||
|
std::strncpy(device->name, controller::pro_controller_name, sizeof(device->name) - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Result BtmMitmService::GetDeviceConditionDeprecated1(sf::Out<DeviceConditionV100> out) {
|
||||||
|
auto device_condition = reinterpret_cast<BtmDeviceConditionV100 *>(out.GetPointer());
|
||||||
|
R_TRY(btmGetDeviceConditionDeprecated1Fwd(this->forward_service.get(), device_condition));
|
||||||
|
RenameConnectedDevices(device_condition->devices, device_condition->connected_count);
|
||||||
|
return ams::ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result BtmMitmService::GetDeviceConditionDeprecated2(sf::Out<DeviceConditionV510> out) {
|
||||||
|
auto device_condition = reinterpret_cast<BtmDeviceConditionV510 *>(out.GetPointer());
|
||||||
|
R_TRY(btmGetDeviceConditionDeprecated2Fwd(this->forward_service.get(), device_condition));
|
||||||
|
RenameConnectedDevices(device_condition->devices, device_condition->connected_count);
|
||||||
|
return ams::ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result BtmMitmService::GetDeviceConditionDeprecated3(sf::Out<DeviceConditionV800> out) {
|
||||||
|
auto device_condition = reinterpret_cast<BtmDeviceConditionV800 *>(out.GetPointer());
|
||||||
|
R_TRY(btmGetDeviceConditionDeprecated1Fwd(this->forward_service.get(), device_condition));
|
||||||
|
RenameConnectedDevices(device_condition->devices, device_condition->connected_count);
|
||||||
|
return ams::ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result BtmMitmService::GetDeviceCondition(sf::Out<btm::DeviceCondition> out) {
|
||||||
|
auto device_condition = reinterpret_cast<BtmDeviceConditionV900 *>(out.GetPointer());
|
||||||
|
R_TRY(btmGetDeviceConditionFwd(this->forward_service.get(), device_condition));
|
||||||
|
RenameConnectedDevices(device_condition->devices, device_condition->connected_count);
|
||||||
|
return ams::ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result BtmMitmService::GetDeviceInfo(sf::Out<btm::DeviceInfo> out) {
|
||||||
|
auto device_info = reinterpret_cast<BtmDeviceInfo *>(out.GetPointer());
|
||||||
|
R_TRY(btmGetDeviceInfoFwd(this->forward_service.get(), device_info));
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < device_info->count; ++i) {
|
||||||
|
auto device = &device_info->devices[i];
|
||||||
|
if (!controller::IsOfficialSwitchControllerName(device->name, sizeof(device->name))) {
|
||||||
|
std::strncpy(device->name, controller::pro_controller_name, sizeof(device->name) - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ams::ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
55
bluetooth-mitm/source/btm_mitm/btm_mitm_service.hpp
Normal file
55
bluetooth-mitm/source/btm_mitm/btm_mitm_service.hpp
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include "btm/btm_types.hpp"
|
||||||
|
|
||||||
|
namespace ams::mitm::btm {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
#define AMS_BTM_MITM_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceConditionDeprecated1, (sf::Out<DeviceConditionV100>), hos::Version_1_0_0, hos::Version_5_0_2) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceConditionDeprecated2, (sf::Out<DeviceConditionV510>), hos::Version_5_1_0, hos::Version_7_0_1) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceConditionDeprecated3, (sf::Out<DeviceConditionV800>), hos::Version_8_0_0, hos::Version_8_1_1) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceCondition, (sf::Out<DeviceCondition>), hos::Version_9_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 9, Result, GetDeviceInfo, (sf::Out<DeviceInfo>)) \
|
||||||
|
|
||||||
|
AMS_SF_DEFINE_MITM_INTERFACE(IBtmMitmInterface, AMS_BTM_MITM_INTERFACE_INFO)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class BtmMitmService : public sf::MitmServiceImplBase {
|
||||||
|
|
||||||
|
public:
|
||||||
|
using MitmServiceImplBase::MitmServiceImplBase;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static bool ShouldMitm(const sm::MitmProcessInfo &client_info) {
|
||||||
|
return client_info.program_id == ncm::SystemProgramId::Hid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Result GetDeviceConditionDeprecated1(sf::Out<DeviceConditionV100> out);
|
||||||
|
Result GetDeviceConditionDeprecated2(sf::Out<DeviceConditionV510> out);
|
||||||
|
Result GetDeviceConditionDeprecated3(sf::Out<DeviceConditionV800> out);
|
||||||
|
Result GetDeviceCondition(sf::Out<btm::DeviceCondition> out);
|
||||||
|
Result GetDeviceInfo(sf::Out<btm::DeviceInfo> out);
|
||||||
|
};
|
||||||
|
static_assert(IsIBtmMitmInterface<BtmMitmService>);
|
||||||
|
|
||||||
|
}
|
53
bluetooth-mitm/source/btm_mitm/btm_shim.c
Normal file
53
bluetooth-mitm/source/btm_mitm/btm_shim.c
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#include "btm_shim.h"
|
||||||
|
#include <stratosphere/sf/sf_mitm_dispatch.h>
|
||||||
|
|
||||||
|
Result btmGetDeviceConditionDeprecated1Fwd(Service* s, BtmDeviceConditionV100 *condition) {
|
||||||
|
return serviceMitmDispatch(s, 3,
|
||||||
|
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
||||||
|
.buffers = { {condition, sizeof(BtmDeviceConditionV100)} }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result btmGetDeviceConditionDeprecated2Fwd(Service* s, BtmDeviceConditionV510 *condition) {
|
||||||
|
return serviceMitmDispatch(s, 3,
|
||||||
|
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
||||||
|
.buffers = { {condition, sizeof(BtmDeviceConditionV510)} }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result btmGetDeviceConditionDeprecated3Fwd(Service* s, BtmDeviceConditionV800 *condition) {
|
||||||
|
return serviceMitmDispatch(s, 3,
|
||||||
|
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
||||||
|
.buffers = { {condition, sizeof(BtmDeviceConditionV800)} }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result btmGetDeviceConditionFwd(Service* s, BtmDeviceConditionV900 *condition) {
|
||||||
|
return serviceMitmDispatch(s, 3,
|
||||||
|
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
||||||
|
.buffers = { {condition, sizeof(BtmDeviceConditionV900)} }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result btmGetDeviceInfoFwd(Service* s, BtmDeviceInfo *devices) {
|
||||||
|
return serviceMitmDispatch(s, 9,
|
||||||
|
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
||||||
|
.buffers = { {devices, sizeof(BtmDeviceInfo)} }
|
||||||
|
);
|
||||||
|
}
|
32
bluetooth-mitm/source/btm_mitm/btm_shim.h
Normal file
32
bluetooth-mitm/source/btm_mitm/btm_shim.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <switch.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Result btmGetDeviceConditionDeprecated1Fwd(Service* s, BtmDeviceConditionV100 *condition);
|
||||||
|
Result btmGetDeviceConditionDeprecated2Fwd(Service* s, BtmDeviceConditionV510 *condition);
|
||||||
|
Result btmGetDeviceConditionDeprecated3Fwd(Service* s, BtmDeviceConditionV800 *condition);
|
||||||
|
Result btmGetDeviceConditionFwd(Service* s, BtmDeviceConditionV900 *condition);
|
||||||
|
Result btmGetDeviceInfoFwd(Service* s, BtmDeviceInfo *devices);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
67
bluetooth-mitm/source/btm_mitm/btmmitm_module.cpp
Normal file
67
bluetooth-mitm/source/btm_mitm/btmmitm_module.cpp
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#include "btmmitm_module.hpp"
|
||||||
|
#include "btm_mitm_service.hpp"
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ams::mitm::btm {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr sm::ServiceName MitmServiceName = sm::ServiceName::Encode("btm");
|
||||||
|
|
||||||
|
struct ServerOptions {
|
||||||
|
static constexpr size_t PointerBufferSize = 0x1000;
|
||||||
|
static constexpr size_t MaxDomains = 0;
|
||||||
|
static constexpr size_t MaxDomainObjects = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr size_t MaxServers = 1;
|
||||||
|
constexpr size_t MaxSessions = 6;
|
||||||
|
|
||||||
|
os::ThreadType g_btm_mitm_thread;
|
||||||
|
alignas(os::ThreadStackAlignment) u8 g_btm_mitm_thread_stack[0x2000];
|
||||||
|
constexpr s32 g_btm_mitm_thread_priority = 34;
|
||||||
|
|
||||||
|
void BtmMitmThreadFunction(void *arg) {
|
||||||
|
auto server_manager = std::make_unique<sf::hipc::ServerManager<MaxServers, ServerOptions, MaxSessions>>();
|
||||||
|
R_ABORT_UNLESS((server_manager->RegisterMitmServer<ams::mitm::btm::IBtmMitmInterface, ams::mitm::btm::BtmMitmService>(MitmServiceName)));
|
||||||
|
server_manager->LoopProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Launch(void) {
|
||||||
|
R_TRY(os::CreateThread(&g_btm_mitm_thread,
|
||||||
|
BtmMitmThreadFunction,
|
||||||
|
nullptr,
|
||||||
|
g_btm_mitm_thread_stack,
|
||||||
|
sizeof(g_btm_mitm_thread_stack),
|
||||||
|
g_btm_mitm_thread_priority
|
||||||
|
));
|
||||||
|
|
||||||
|
os::StartThread(&g_btm_mitm_thread);
|
||||||
|
|
||||||
|
return ams::ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitFinished(void) {
|
||||||
|
os::WaitThread(&g_btm_mitm_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
25
bluetooth-mitm/source/btm_mitm/btmmitm_module.hpp
Normal file
25
bluetooth-mitm/source/btm_mitm/btmmitm_module.hpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::mitm::btm {
|
||||||
|
|
||||||
|
Result Launch(void);
|
||||||
|
void WaitFinished(void);
|
||||||
|
|
||||||
|
}
|
|
@ -39,11 +39,9 @@ namespace ams::controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerType Identify(const BluetoothDevicesSettings *device) {
|
ControllerType Identify(const BluetoothDevicesSettings *device) {
|
||||||
for (auto hwId : SwitchController::hardware_ids) {
|
|
||||||
if ( (device->vid == hwId.vid) && (device->pid == hwId.pid) ) {
|
if (IsOfficialSwitchControllerName(device->name, sizeof(device->name)))
|
||||||
return ControllerType_Switch;
|
return ControllerType_Switch;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto hwId : WiiController::hardware_ids) {
|
for (auto hwId : WiiController::hardware_ids) {
|
||||||
if ( (device->vid == hwId.vid) && (device->pid == hwId.pid) ) {
|
if ( (device->vid == hwId.vid) && (device->pid == hwId.pid) ) {
|
||||||
|
@ -93,11 +91,6 @@ namespace ams::controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the case where joycons have been assigned random hardware ids when paired via rails
|
|
||||||
if (IsJoyCon(device->name)) {
|
|
||||||
return ControllerType_Switch;;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ControllerType_Unknown;
|
return ControllerType_Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,20 +99,15 @@ namespace ams::controller {
|
||||||
(((cod->cod[2] & 0x0f) == cod_minor_gamepad) || ((cod->cod[2] & 0x0f) == cod_minor_joystick));
|
(((cod->cod[2] & 0x0f) == cod_minor_gamepad) || ((cod->cod[2] & 0x0f) == cod_minor_joystick));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsJoyCon(const char *name) {
|
bool IsOfficialSwitchControllerName(const char *name, size_t size) {
|
||||||
return std::strncmp(name, "Joy-Con (L)", sizeof(BluetoothName)) == 0 ||
|
return std::strncmp(name, "Joy-Con (L)", size) == 0 ||
|
||||||
std::strncmp(name, "Joy-Con (R)", sizeof(BluetoothName)) == 0;
|
std::strncmp(name, "Joy-Con (R)", size) == 0 ||
|
||||||
}
|
std::strncmp(name, "Pro Controller", size) == 0 ||
|
||||||
|
std::strncmp(name, "Lic Pro Controller", size) == 0 ||
|
||||||
bool IsOfficialSwitchControllerName(const char *name) {
|
std::strncmp(name, "NES Controller", size) == 0 ||
|
||||||
return std::strncmp(name, "Joy-Con (L)", sizeof(BluetoothName)) == 0 ||
|
std::strncmp(name, "HVC Controller", size) == 0 ||
|
||||||
std::strncmp(name, "Joy-Con (R)", sizeof(BluetoothName)) == 0 ||
|
std::strncmp(name, "SNES Controller", size) == 0 ||
|
||||||
std::strncmp(name, "Pro Controller", sizeof(BluetoothName)) == 0 ||
|
std::strncmp(name, "NintendoGamepad", size) == 0 ;
|
||||||
std::strncmp(name, "Lic Pro Controller", sizeof(BluetoothName)) == 0 ||
|
|
||||||
std::strncmp(name, "NES Controller", sizeof(BluetoothName)) == 0 ||
|
|
||||||
std::strncmp(name, "HVC Controller", sizeof(BluetoothName)) == 0 ||
|
|
||||||
std::strncmp(name, "SNES Controller", sizeof(BluetoothName)) == 0 ||
|
|
||||||
std::strncmp(name, "NintendoGamepad", sizeof(BluetoothName)) == 0 ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachHandler(const bluetooth::Address *address) {
|
void AttachHandler(const bluetooth::Address *address) {
|
|
@ -47,8 +47,7 @@ namespace ams::controller {
|
||||||
|
|
||||||
ControllerType Identify(const BluetoothDevicesSettings *device);
|
ControllerType Identify(const BluetoothDevicesSettings *device);
|
||||||
bool IsGamepad(const bluetooth::DeviceClass *cod);
|
bool IsGamepad(const bluetooth::DeviceClass *cod);
|
||||||
bool IsJoyCon(const char *name);
|
bool IsOfficialSwitchControllerName(const char *name, size_t size);
|
||||||
bool IsOfficialSwitchControllerName(const char *name);
|
|
||||||
|
|
||||||
void AttachHandler(const bluetooth::Address *address);
|
void AttachHandler(const bluetooth::Address *address);
|
||||||
void RemoveHandler(const bluetooth::Address *address);
|
void RemoveHandler(const bluetooth::Address *address);
|
|
@ -54,46 +54,46 @@ namespace ams::controller {
|
||||||
|
|
||||||
Result EmulatedSwitchController::HandleSubCmdReport(const bluetooth::HidReport *report) {
|
Result EmulatedSwitchController::HandleSubCmdReport(const bluetooth::HidReport *report) {
|
||||||
const uint8_t *subcmd = &report->data[10];
|
const uint8_t *subcmd = &report->data[10];
|
||||||
auto subcmd_id = static_cast<bluetooth::SubCmdType>(subcmd[0]);
|
auto subcmd_id = static_cast<SubCmdType>(subcmd[0]);
|
||||||
|
|
||||||
switch (subcmd_id) {
|
switch (subcmd_id) {
|
||||||
case bluetooth::SubCmd_RequestDeviceInfo:
|
case SubCmd_RequestDeviceInfo:
|
||||||
R_TRY(this->SubCmdRequestDeviceInfo(report));
|
R_TRY(this->SubCmdRequestDeviceInfo(report));
|
||||||
break;
|
break;
|
||||||
case bluetooth::SubCmd_SpiFlashRead:
|
case SubCmd_SpiFlashRead:
|
||||||
R_TRY(this->SubCmdSpiFlashRead(report));
|
R_TRY(this->SubCmdSpiFlashRead(report));
|
||||||
break;
|
break;
|
||||||
case bluetooth::SubCmd_SpiFlashWrite:
|
case SubCmd_SpiFlashWrite:
|
||||||
R_TRY(this->SubCmdSpiFlashWrite(report));
|
R_TRY(this->SubCmdSpiFlashWrite(report));
|
||||||
break;
|
break;
|
||||||
case bluetooth::SubCmd_SpiSectorErase:
|
case SubCmd_SpiSectorErase:
|
||||||
R_TRY(this->SubCmdSpiSectorErase(report));
|
R_TRY(this->SubCmdSpiSectorErase(report));
|
||||||
break;
|
break;
|
||||||
case bluetooth::SubCmd_SetInputReportMode:
|
case SubCmd_SetInputReportMode:
|
||||||
R_TRY(this->SubCmdSetInputReportMode(report));
|
R_TRY(this->SubCmdSetInputReportMode(report));
|
||||||
break;
|
break;
|
||||||
case bluetooth::SubCmd_TriggersElapsedTime:
|
case SubCmd_TriggersElapsedTime:
|
||||||
R_TRY(this->SubCmdTriggersElapsedTime(report));
|
R_TRY(this->SubCmdTriggersElapsedTime(report));
|
||||||
break;
|
break;
|
||||||
case bluetooth::SubCmd_SetShipPowerState:
|
case SubCmd_SetShipPowerState:
|
||||||
R_TRY(this->SubCmdSetShipPowerState(report));
|
R_TRY(this->SubCmdSetShipPowerState(report));
|
||||||
break;
|
break;
|
||||||
case bluetooth::SubCmd_SetMcuConfig:
|
case SubCmd_SetMcuConfig:
|
||||||
R_TRY(this->SubCmdSetMcuConfig(report));
|
R_TRY(this->SubCmdSetMcuConfig(report));
|
||||||
break;
|
break;
|
||||||
case bluetooth::SubCmd_SetMcuState:
|
case SubCmd_SetMcuState:
|
||||||
R_TRY(this->SubCmdSetMcuState(report));
|
R_TRY(this->SubCmdSetMcuState(report));
|
||||||
break;
|
break;
|
||||||
case bluetooth::SubCmd_SetPlayerLeds:
|
case SubCmd_SetPlayerLeds:
|
||||||
R_TRY(this->SubCmdSetPlayerLeds(report));
|
R_TRY(this->SubCmdSetPlayerLeds(report));
|
||||||
break;
|
break;
|
||||||
case bluetooth::SubCmd_SetHomeLed:
|
case SubCmd_SetHomeLed:
|
||||||
R_TRY(this->SubCmdSetHomeLed(report));
|
R_TRY(this->SubCmdSetHomeLed(report));
|
||||||
break;
|
break;
|
||||||
case bluetooth::SubCmd_EnableImu:
|
case SubCmd_EnableImu:
|
||||||
R_TRY(this->SubCmdEnableImu(report));
|
R_TRY(this->SubCmdEnableImu(report));
|
||||||
break;
|
break;
|
||||||
case bluetooth::SubCmd_EnableVibration:
|
case SubCmd_EnableVibration:
|
||||||
R_TRY(this->SubCmdEnableVibration(report));
|
R_TRY(this->SubCmdEnableVibration(report));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -121,7 +121,7 @@ namespace ams::controller {
|
||||||
uint32_t read_addr = *(uint32_t *)(&report->data[11]);
|
uint32_t read_addr = *(uint32_t *)(&report->data[11]);
|
||||||
uint8_t read_size = report->data[15];
|
uint8_t read_size = report->data[15];
|
||||||
|
|
||||||
const uint8_t prefix[] = {0x90, bluetooth::SubCmd_SpiFlashRead, report->data[11], report->data[12], report->data[13], report->data[14], report->data[15]};
|
const uint8_t prefix[] = {0x90, SubCmd_SpiFlashRead, report->data[11], report->data[12], report->data[13], report->data[14], report->data[15]};
|
||||||
|
|
||||||
int response_size = read_size + sizeof(prefix);
|
int response_size = read_size + sizeof(prefix);
|
||||||
auto response = std::make_unique<uint8_t[]>(response_size);
|
auto response = std::make_unique<uint8_t[]>(response_size);
|
||||||
|
@ -137,37 +137,37 @@ namespace ams::controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EmulatedSwitchController::SubCmdSpiFlashWrite(const bluetooth::HidReport *report) {
|
Result EmulatedSwitchController::SubCmdSpiFlashWrite(const bluetooth::HidReport *report) {
|
||||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SpiFlashWrite, 0x01};
|
const uint8_t response[] = {0x80, SubCmd_SpiFlashWrite, 0x01};
|
||||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EmulatedSwitchController::SubCmdSpiSectorErase(const bluetooth::HidReport *report) {
|
Result EmulatedSwitchController::SubCmdSpiSectorErase(const bluetooth::HidReport *report) {
|
||||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SpiSectorErase, 0x01};
|
const uint8_t response[] = {0x80, SubCmd_SpiSectorErase, 0x01};
|
||||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EmulatedSwitchController::SubCmdSetInputReportMode(const bluetooth::HidReport *report) {
|
Result EmulatedSwitchController::SubCmdSetInputReportMode(const bluetooth::HidReport *report) {
|
||||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SetInputReportMode};
|
const uint8_t response[] = {0x80, SubCmd_SetInputReportMode};
|
||||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EmulatedSwitchController::SubCmdTriggersElapsedTime(const bluetooth::HidReport *report) {
|
Result EmulatedSwitchController::SubCmdTriggersElapsedTime(const bluetooth::HidReport *report) {
|
||||||
const uint8_t response[] = {0x83, bluetooth::SubCmd_TriggersElapsedTime};
|
const uint8_t response[] = {0x83, SubCmd_TriggersElapsedTime};
|
||||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EmulatedSwitchController::SubCmdSetShipPowerState(const bluetooth::HidReport *report) {
|
Result EmulatedSwitchController::SubCmdSetShipPowerState(const bluetooth::HidReport *report) {
|
||||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SetShipPowerState, 0x00};
|
const uint8_t response[] = {0x80, SubCmd_SetShipPowerState, 0x00};
|
||||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EmulatedSwitchController::SubCmdSetMcuConfig(const bluetooth::HidReport *report) {
|
Result EmulatedSwitchController::SubCmdSetMcuConfig(const bluetooth::HidReport *report) {
|
||||||
const uint8_t response[] = {0xa0, bluetooth::SubCmd_SetMcuConfig, 0x01, 0x00, 0xff, 0x00, 0x03, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c};
|
const uint8_t response[] = {0xa0, SubCmd_SetMcuConfig, 0x01, 0x00, 0xff, 0x00, 0x03, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c};
|
||||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EmulatedSwitchController::SubCmdSetMcuState(const bluetooth::HidReport *report) {
|
Result EmulatedSwitchController::SubCmdSetMcuState(const bluetooth::HidReport *report) {
|
||||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SetMcuState};
|
const uint8_t response[] = {0x80, SubCmd_SetMcuState};
|
||||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,22 +176,22 @@ namespace ams::controller {
|
||||||
uint8_t led_mask = subCmd[1];
|
uint8_t led_mask = subCmd[1];
|
||||||
R_TRY(this->SetPlayerLed(led_mask));
|
R_TRY(this->SetPlayerLed(led_mask));
|
||||||
|
|
||||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SetPlayerLeds};
|
const uint8_t response[] = {0x80, SubCmd_SetPlayerLeds};
|
||||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EmulatedSwitchController::SubCmdSetHomeLed(const bluetooth::HidReport *report) {
|
Result EmulatedSwitchController::SubCmdSetHomeLed(const bluetooth::HidReport *report) {
|
||||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SetHomeLed};
|
const uint8_t response[] = {0x80, SubCmd_SetHomeLed};
|
||||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EmulatedSwitchController::SubCmdEnableImu(const bluetooth::HidReport *report) {
|
Result EmulatedSwitchController::SubCmdEnableImu(const bluetooth::HidReport *report) {
|
||||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_EnableImu};
|
const uint8_t response[] = {0x80, SubCmd_EnableImu};
|
||||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EmulatedSwitchController::SubCmdEnableVibration(const bluetooth::HidReport *report) {
|
Result EmulatedSwitchController::SubCmdEnableVibration(const bluetooth::HidReport *report) {
|
||||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_EnableVibration};
|
const uint8_t response[] = {0x80, SubCmd_EnableVibration};
|
||||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../bluetooth/bluetooth_types.hpp"
|
#include "../btdrv_mitm/bluetooth/bluetooth_types.hpp"
|
||||||
#include "../bluetooth/bluetooth_hid_report.hpp"
|
#include "../btdrv_mitm/bluetooth/bluetooth_hid_report.hpp"
|
||||||
|
|
||||||
namespace ams::controller {
|
namespace ams::controller {
|
||||||
|
|
||||||
|
@ -68,6 +68,32 @@ namespace ams::controller {
|
||||||
uint16_t gyro_3;
|
uint16_t gyro_3;
|
||||||
} __attribute__ ((__packed__));
|
} __attribute__ ((__packed__));
|
||||||
|
|
||||||
|
enum SubCmdType : u8 {
|
||||||
|
SubCmd_GetControllerState = 0x00,
|
||||||
|
SubCmd_ManualPair = 0x01,
|
||||||
|
SubCmd_RequestDeviceInfo = 0x02,
|
||||||
|
SubCmd_SetInputReportMode = 0x03,
|
||||||
|
SubCmd_TriggersElapsedTime = 0x04,
|
||||||
|
SubCmd_SetHciState = 0x06,
|
||||||
|
SubCmd_ResetPairingInfo = 0x07,
|
||||||
|
SubCmd_SetShipPowerState = 0x08,
|
||||||
|
SubCmd_SpiFlashRead = 0x10,
|
||||||
|
SubCmd_SpiFlashWrite = 0x11,
|
||||||
|
SubCmd_SpiSectorErase = 0x12,
|
||||||
|
SubCmd_ResetMcu = 0x20,
|
||||||
|
SubCmd_SetMcuConfig = 0x21,
|
||||||
|
SubCmd_SetMcuState = 0x22,
|
||||||
|
SubCmd_SetPlayerLeds = 0x30,
|
||||||
|
SubCmd_GetPlayerLeds = 0x31,
|
||||||
|
SubCmd_SetHomeLed = 0x38,
|
||||||
|
SubCmd_EnableImu = 0x40,
|
||||||
|
SubCmd_SetImuSensitivity = 0x41,
|
||||||
|
SubCmd_WriteImuRegisters = 0x42,
|
||||||
|
SubCmd_ReadImuRegisters = 0x43,
|
||||||
|
SubCmd_EnableVibration = 0x48,
|
||||||
|
SubCmd_GetRegulatedVoltage = 0x50,
|
||||||
|
};
|
||||||
|
|
||||||
struct SwitchOutputReport0x01;
|
struct SwitchOutputReport0x01;
|
||||||
struct SwitchOutputReport0x03;
|
struct SwitchOutputReport0x03;
|
||||||
struct SwitchOutputReport0x10;
|
struct SwitchOutputReport0x10;
|
2
libnx
2
libnx
|
@ -1 +1 @@
|
||||||
Subproject commit 050a95dcc2223fe534eb97d07a76f899d45ba8e6
|
Subproject commit ffde37ae3d0be30269f5aa5d0c1986e6d7dcdb10
|
Loading…
Reference in a new issue