mirror of
https://github.com/ndeadly/MissionControl
synced 2025-02-16 13:18:27 +00:00
mc.mitm: add support for loading global module config ini at startup and overriding bluetooth adapter name and address
This commit is contained in:
parent
d664c074fd
commit
d5ddeaac36
15 changed files with 220 additions and 19 deletions
5
Makefile
5
Makefile
|
@ -31,10 +31,13 @@ dist: all
|
|||
|
||||
mkdir -p dist/atmosphere/contents/$(MC_MITM_TID)/flags
|
||||
touch dist/atmosphere/contents/$(MC_MITM_TID)/flags/boot2.flag
|
||||
|
||||
|
||||
cp mc_mitm/toolbox.json dist/atmosphere/contents/$(MC_MITM_TID)/toolbox.json
|
||||
|
||||
cp -r exefs_patches dist/atmosphere/
|
||||
|
||||
mkdir -p dist/atmosphere/config_templates
|
||||
cp mc_mitm/config.ini dist/atmosphere/config_templates/missioncontrol.ini
|
||||
|
||||
cd dist; zip -r $(PROJECT_NAME)-$(BUILD_VERSION).zip ./*; cd ../;
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 17960517bad5d2d07effb28b744ac8d907d571e0
|
||||
Subproject commit bc08912dd31bb172467add8e24b4f0adac431939
|
11
mc_mitm/config.ini
Normal file
11
mc_mitm/config.ini
Normal file
|
@ -0,0 +1,11 @@
|
|||
[general]
|
||||
; Enable vibration support for unofficial controllers
|
||||
enable_rumble=true
|
||||
; Enable motion controls support for unoffical controllers
|
||||
enable_motion=true
|
||||
|
||||
[bluetooth]
|
||||
; Override host name of Bluetooth adapter
|
||||
host_name=Nintendo Switch!
|
||||
; Override host mac address of Bluetooth adapter
|
||||
host_address=04:20:69:04:20:69
|
|
@ -35,12 +35,21 @@ namespace ams::bluetooth::core {
|
|||
os::SystemEventType g_system_event_user_fwd;
|
||||
os::EventType g_data_read_event;
|
||||
|
||||
os::Event g_enable_event(os::EventClearMode_ManualClear);
|
||||
}
|
||||
|
||||
bool IsInitialized(void) {
|
||||
return g_is_initialized;
|
||||
}
|
||||
|
||||
void SignalEnabled(void) {
|
||||
g_enable_event.Signal();
|
||||
}
|
||||
|
||||
void WaitEnabled(void) {
|
||||
g_enable_event.Wait();
|
||||
}
|
||||
|
||||
os::SystemEventType *GetSystemEvent(void) {
|
||||
return &g_system_event;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
namespace ams::bluetooth::core {
|
||||
|
||||
bool IsInitialized(void);
|
||||
void SignalEnabled(void);
|
||||
void WaitEnabled(void);
|
||||
|
||||
os::SystemEventType *GetSystemEvent(void);
|
||||
os::SystemEventType *GetForwardEvent(void);
|
||||
|
|
|
@ -62,7 +62,6 @@ namespace ams::mitm::bluetooth {
|
|||
s32 g_btdrv_mitm_thread_priority = utils::ConvertToUserPriority(17);
|
||||
|
||||
void BtdrvMitmThreadFunction(void *arg) {
|
||||
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterMitmServer<BtdrvMitmService>(PortIndex_BtdrvMitm, BtdrvMitmServiceName)));
|
||||
g_server_manager.LoopProcess();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "bluetooth/bluetooth_core.hpp"
|
||||
#include "bluetooth/bluetooth_hid.hpp"
|
||||
#include "bluetooth/bluetooth_ble.hpp"
|
||||
#include "../mcmitm_initialization.hpp"
|
||||
#include "../controllers/controller_management.hpp"
|
||||
#include <switch.h>
|
||||
#include <cstring>
|
||||
|
@ -40,6 +41,16 @@ namespace ams::mitm::bluetooth {
|
|||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
Result BtdrvMitmService::EnableBluetooth(void) {
|
||||
R_TRY(btdrvEnableBluetoothFwd(this->forward_service.get()));
|
||||
ams::bluetooth::core::SignalEnabled();
|
||||
|
||||
// Wait until mc.mitm module initialisation has completed before returning
|
||||
ams::mitm::WaitInitialized();
|
||||
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
Result BtdrvMitmService::FinalizeBluetooth(void) {
|
||||
// Only btm should be able to make this call
|
||||
if (this->client_info.program_id == ncm::SystemProgramId::Btm) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#define AMS_BTDRV_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, InitializeBluetooth, (sf::OutCopyHandle out_handle), (out_handle)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, EnableBluetooth, (void), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, FinalizeBluetooth, (void), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 15, Result, GetEventInfo, (sf::Out<ams::bluetooth::EventType> out_type, const sf::OutPointerBuffer &out_buffer), (out_type, out_buffer)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 16, Result, InitializeHid, (sf::OutCopyHandle out_handle, u16 version), (out_handle, version)) \
|
||||
|
@ -58,6 +59,7 @@ namespace ams::mitm::bluetooth {
|
|||
|
||||
public:
|
||||
Result InitializeBluetooth(sf::OutCopyHandle out_handle);
|
||||
Result EnableBluetooth(void);
|
||||
Result FinalizeBluetooth(void);
|
||||
Result GetEventInfo(sf::Out<ams::bluetooth::EventType> out_type, const sf::OutPointerBuffer &out_buffer);
|
||||
Result InitializeHid(sf::OutCopyHandle out_handle, u16 version);
|
||||
|
|
|
@ -23,6 +23,10 @@ Result btdrvInitializeBluetoothFwd(Service* srv, Handle *out_handle) {
|
|||
);
|
||||
}
|
||||
|
||||
Result btdrvEnableBluetoothFwd(Service* srv) {
|
||||
return serviceMitmDispatch(srv, 2);
|
||||
}
|
||||
|
||||
Result btdrvFinalizeBluetoothFwd(Service* srv) {
|
||||
return serviceMitmDispatch(srv, 4);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
Result btdrvInitializeBluetoothFwd(Service* srv, Handle *out_handle);
|
||||
Result btdrvEnableBluetoothFwd(Service* srv);
|
||||
Result btdrvFinalizeBluetoothFwd(Service* srv);
|
||||
Result btdrvInitializeHidFwd(Service* srv, Handle *out_handle, u16 version);
|
||||
Result btdrvWriteHidDataFwd(Service* srv, const BtdrvAddress *address, const BtdrvHidReport *data);
|
||||
|
|
108
mc_mitm/source/mcmitm_config.cpp
Normal file
108
mc_mitm/source/mcmitm_config.cpp
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2021 ndeadly
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 <stratosphere.hpp>
|
||||
#include <cstring>
|
||||
#include "mcmitm_config.hpp"
|
||||
|
||||
namespace ams::mitm {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr const char *config_file_location = "sdmc:/atmosphere/config/missioncontrol.ini";
|
||||
|
||||
MissionControlConfig g_global_config = {
|
||||
.general = {
|
||||
.enable_rumble = true,
|
||||
.enable_motion = true
|
||||
}
|
||||
};
|
||||
|
||||
void ParseBoolean(const char *value, bool *out) {
|
||||
if (strcasecmp(value, "true") == 0)
|
||||
*out = true;
|
||||
else if (strcasecmp(value, "false") == 0)
|
||||
*out = false;
|
||||
}
|
||||
|
||||
void ParseBluetoothAddress(const char *value, bluetooth::Address *out) {
|
||||
// Check length of address string is correct
|
||||
if (std::strlen(value) != 3*sizeof(bluetooth::Address) - 1) return;
|
||||
|
||||
// Parse bluetooth mac address
|
||||
char buf[2 + 1];
|
||||
bluetooth::Address address = {};
|
||||
for (uint32_t i = 0; i < sizeof(bluetooth::Address); ++i) {
|
||||
// Convert hex pair to number
|
||||
std::memcpy(buf, &value[i*3], 2);
|
||||
address.address[i] = static_cast<uint8_t>(std::strtoul(buf, nullptr, 16));
|
||||
|
||||
// Check for colon separator
|
||||
if ((i < sizeof(bluetooth::Address) - 1) && (value[i*3 + 2] != ':'))
|
||||
return;
|
||||
}
|
||||
|
||||
*out = address;
|
||||
}
|
||||
|
||||
int ConfigIniHandler(void *user, const char *section, const char *name, const char *value) {
|
||||
auto config = reinterpret_cast<MissionControlConfig *>(user);
|
||||
|
||||
if (strcasecmp(section, "general") == 0) {
|
||||
if (strcasecmp(name, "enable_rumble") == 0)
|
||||
ParseBoolean(value, &config->general.enable_rumble);
|
||||
else if (strcasecmp(name, "enable_motion") == 0)
|
||||
ParseBoolean(value, &config->general.enable_motion);
|
||||
}
|
||||
else if (strcasecmp(section, "bluetooth") == 0) {
|
||||
if (strcasecmp(name, "host_name") == 0)
|
||||
std::strncpy(config->bluetooth.host_name, value, sizeof(config->bluetooth.host_name));
|
||||
else if (strcasecmp(name, "host_address") == 0)
|
||||
ParseBluetoothAddress(value, &config->bluetooth.host_address);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MissionControlConfig *GetGlobalConfig(void) {
|
||||
return &g_global_config;
|
||||
}
|
||||
|
||||
void ParseIniConfig(void) {
|
||||
const char *mount_name = "sdmc";
|
||||
if (R_FAILED(fs::MountSdCard(mount_name))) {
|
||||
return;
|
||||
}
|
||||
ON_SCOPE_EXIT { fs::Unmount(mount_name); };
|
||||
|
||||
/* Open the file. */
|
||||
fs::FileHandle file;
|
||||
{
|
||||
if (R_FAILED(fs::OpenFile(std::addressof(file), config_file_location, fs::OpenMode_Read))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||
|
||||
/* Parse the config. */
|
||||
util::ini::ParseFile(file, &g_global_config, ConfigIniHandler);
|
||||
}
|
||||
|
||||
}
|
35
mc_mitm/source/mcmitm_config.hpp
Normal file
35
mc_mitm/source/mcmitm_config.hpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2021 ndeadly
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 "bluetooth_mitm/bluetooth/bluetooth_types.hpp"
|
||||
|
||||
namespace ams::mitm {
|
||||
|
||||
struct MissionControlConfig {
|
||||
struct {
|
||||
bool enable_rumble;
|
||||
bool enable_motion;
|
||||
} general;
|
||||
|
||||
struct {
|
||||
char host_name[0x20];
|
||||
bluetooth::Address host_address;
|
||||
} bluetooth;
|
||||
};
|
||||
|
||||
MissionControlConfig *GetGlobalConfig(void);
|
||||
void ParseIniConfig(void);
|
||||
|
||||
}
|
|
@ -16,6 +16,8 @@
|
|||
#include <stratosphere.hpp>
|
||||
#include <switch.h>
|
||||
#include "mcmitm_initialization.hpp"
|
||||
#include "mcmitm_config.hpp"
|
||||
#include "bluetooth_mitm/btdrv_mitm_service.hpp"
|
||||
#include "bluetooth_mitm/bluetooth/bluetooth_events.hpp"
|
||||
#include "bluetooth_mitm/bluetooth/bluetooth_core.hpp"
|
||||
#include "bluetooth_mitm/bluetooth/bluetooth_hid.hpp"
|
||||
|
@ -25,52 +27,67 @@ namespace ams::mitm {
|
|||
|
||||
namespace {
|
||||
|
||||
constexpr size_t InitializeThreadStackSize = 0x2000;
|
||||
constexpr size_t InitializeThreadStackSize = 0x1000;
|
||||
|
||||
os::ThreadType g_initialize_thread;
|
||||
alignas(os::ThreadStackAlignment) u8 g_initialize_thread_stack[InitializeThreadStackSize];
|
||||
|
||||
os::Event g_init_event(os::EventClearMode_ManualClear);
|
||||
|
||||
void WaitInterfacesInitialized(void) {
|
||||
while (!(bluetooth::core::IsInitialized() && bluetooth::hid::IsInitialized() && (bluetooth::ble::IsInitialized() || (hos::GetVersion() < hos::Version_5_0_0)))) {
|
||||
while (!(ams::bluetooth::core::IsInitialized() && ams::bluetooth::hid::IsInitialized() && (ams::bluetooth::ble::IsInitialized() || (hos::GetVersion() < hos::Version_5_0_0)))) {
|
||||
svc::SleepThread(1'000'000ul);
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeThreadFunc(void *arg) {
|
||||
|
||||
void InitializeThreadFunc(void *arg) {
|
||||
// Wait for all bluetooth interfaces to be initialised
|
||||
WaitInterfacesInitialized();
|
||||
|
||||
// Connect to btdrv service now that we're up and running
|
||||
// Connect to btdrv service now that we're sure the mitm is up and running
|
||||
sm::DoWithSession([&]() {
|
||||
R_ABORT_UNLESS(btdrvInitialize());
|
||||
});
|
||||
|
||||
// Start bluetooth event handling thread
|
||||
bluetooth::events::Initialize();
|
||||
ams::bluetooth::events::Initialize();
|
||||
|
||||
// Parse config ini
|
||||
// Get global module settings
|
||||
auto config = GetGlobalConfig();
|
||||
|
||||
// Set host name override
|
||||
// Wait for system to call BluetoothEnable so the proceeding adapter properties aren't overwritten
|
||||
ams::bluetooth::core::WaitEnabled();
|
||||
|
||||
// Set host address override
|
||||
// Set bluetooth adapter host address override
|
||||
ams::bluetooth::Address null_address = {};
|
||||
if (std::memcmp(&config->bluetooth.host_address, &null_address, sizeof(ams::bluetooth::Address)) != 0) {
|
||||
R_ABORT_UNLESS(btdrvSetAdapterProperty(BtdrvBluetoothPropertyType_Address, &config->bluetooth.host_address, sizeof(ams::bluetooth::Address)));
|
||||
}
|
||||
|
||||
// Set bluetooth adapter host name override
|
||||
if (std::strlen(config->bluetooth.host_name) > 0) {
|
||||
R_ABORT_UNLESS(btdrvSetAdapterProperty(BtdrvBluetoothPropertyType_Name, config->bluetooth.host_name, std::strlen(config->bluetooth.host_name)));
|
||||
}
|
||||
|
||||
g_init_event.Signal();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void StartInitialize(void) {
|
||||
|
||||
R_ABORT_UNLESS(os::CreateThread(&g_initialize_thread,
|
||||
InitializeThreadFunc,
|
||||
nullptr,
|
||||
g_initialize_thread_stack,
|
||||
sizeof(g_initialize_thread_stack),
|
||||
9
|
||||
-7
|
||||
));
|
||||
|
||||
os::StartThread(&g_initialize_thread);
|
||||
}
|
||||
|
||||
void WaitInitialized(void) {
|
||||
g_init_event.Wait();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,5 +18,6 @@
|
|||
namespace ams::mitm {
|
||||
|
||||
void StartInitialize(void);
|
||||
void WaitInitialized(void);
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
#include "mcmitm_initialization.hpp"
|
||||
#include "mcmitm_config.hpp"
|
||||
#include "bluetooth_mitm/bluetoothmitm_module.hpp"
|
||||
#include "btm_mitm/btmmitm_module.hpp"
|
||||
|
||||
|
@ -73,16 +74,12 @@ void __appInit(void) {
|
|||
R_ABORT_UNLESS(pmdmntInitialize());
|
||||
R_ABORT_UNLESS(pminfoInitialize());
|
||||
});
|
||||
|
||||
R_ABORT_UNLESS(fsdevMountSdmc());
|
||||
}
|
||||
|
||||
void __appExit(void) {
|
||||
btdrvExit();
|
||||
pminfoExit();
|
||||
pmdmntExit();
|
||||
|
||||
fsdevUnmountAll();
|
||||
fsExit();
|
||||
}
|
||||
|
||||
|
@ -101,7 +98,8 @@ void WaitModules(void) {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
mitm::StartInitialize();
|
||||
ams::mitm::ParseIniConfig();
|
||||
ams::mitm::StartInitialize();
|
||||
LaunchModules();
|
||||
WaitModules();
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue