From cb1487d77468c7dd7ca49779d9f9010ed925e3fc Mon Sep 17 00:00:00 2001
From: german77 <juangerman-13@hotmail.com>
Date: Tue, 9 May 2023 00:30:25 -0600
Subject: [PATCH] input_common: Fix nfc detection for joycons

---
 .../joycon_protocol/common_protocol.cpp       |  7 +++---
 .../helpers/joycon_protocol/common_protocol.h |  2 +-
 .../helpers/joycon_protocol/joycon_types.h    |  7 ++++--
 .../helpers/joycon_protocol/nfc.cpp           | 24 +++++++++----------
 4 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/src/input_common/helpers/joycon_protocol/common_protocol.cpp b/src/input_common/helpers/joycon_protocol/common_protocol.cpp
index 2b42a4555a..077d72cd03 100644
--- a/src/input_common/helpers/joycon_protocol/common_protocol.cpp
+++ b/src/input_common/helpers/joycon_protocol/common_protocol.cpp
@@ -236,13 +236,13 @@ DriverResult JoyconCommonProtocol::GetMCUDataResponse(ReportMode report_mode,
     return DriverResult::Success;
 }
 
-DriverResult JoyconCommonProtocol::SendMCUData(ReportMode report_mode, SubCommand sc,
+DriverResult JoyconCommonProtocol::SendMCUData(ReportMode report_mode, MCUSubCommand sc,
                                                std::span<const u8> buffer,
                                                MCUCommandResponse& output) {
     SubCommandPacket packet{
         .output_report = OutputReport::MCU_DATA,
         .packet_counter = GetCounter(),
-        .sub_command = sc,
+        .mcu_sub_command = sc,
         .command_data = {},
     };
 
@@ -269,8 +269,7 @@ DriverResult JoyconCommonProtocol::WaitSetMCUMode(ReportMode report_mode, MCUMod
     std::size_t tries{};
 
     do {
-        const std::vector<u8> mcu_data{static_cast<u8>(MCUMode::Standby)};
-        const auto result = SendMCUData(report_mode, SubCommand::STATE, mcu_data, output);
+        const auto result = SendMCUData(report_mode, MCUSubCommand::SetDeviceMode, {}, output);
 
         if (result != DriverResult::Success) {
             return result;
diff --git a/src/input_common/helpers/joycon_protocol/common_protocol.h b/src/input_common/helpers/joycon_protocol/common_protocol.h
index 62cae739ae..411ec018a3 100644
--- a/src/input_common/helpers/joycon_protocol/common_protocol.h
+++ b/src/input_common/helpers/joycon_protocol/common_protocol.h
@@ -156,7 +156,7 @@ public:
      * @param buffer data to be send
      * @returns output buffer containing the response
      */
-    DriverResult SendMCUData(ReportMode report_mode, SubCommand sc, std::span<const u8> buffer,
+    DriverResult SendMCUData(ReportMode report_mode, MCUSubCommand sc, std::span<const u8> buffer,
                              MCUCommandResponse& output);
 
     /**
diff --git a/src/input_common/helpers/joycon_protocol/joycon_types.h b/src/input_common/helpers/joycon_protocol/joycon_types.h
index dcac0e4222..b03143e04c 100644
--- a/src/input_common/helpers/joycon_protocol/joycon_types.h
+++ b/src/input_common/helpers/joycon_protocol/joycon_types.h
@@ -575,7 +575,6 @@ struct NFCPollingCommandData {
 static_assert(sizeof(NFCPollingCommandData) == 0x05, "NFCPollingCommandData is an invalid size");
 
 struct NFCRequestState {
-    MCUSubCommand sub_command;
     NFCReadCommand command_argument;
     u8 packet_id;
     INSERT_PADDING_BYTES(0x1);
@@ -587,6 +586,7 @@ struct NFCRequestState {
         NFCPollingCommandData nfc_polling;
     };
     u8 crc;
+    INSERT_PADDING_BYTES(0x1);
 };
 static_assert(sizeof(NFCRequestState) == 0x26, "NFCRequestState is an invalid size");
 
@@ -659,7 +659,10 @@ struct SubCommandPacket {
     OutputReport output_report;
     u8 packet_counter;
     INSERT_PADDING_BYTES(0x8); // This contains vibration data
-    SubCommand sub_command;
+    union {
+        SubCommand sub_command;
+        MCUSubCommand mcu_sub_command;
+    };
     std::array<u8, 0x26> command_data;
 };
 static_assert(sizeof(SubCommandPacket) == 0x31, "SubCommandPacket is an invalid size");
diff --git a/src/input_common/helpers/joycon_protocol/nfc.cpp b/src/input_common/helpers/joycon_protocol/nfc.cpp
index eeba829860..77ea6d5cf2 100644
--- a/src/input_common/helpers/joycon_protocol/nfc.cpp
+++ b/src/input_common/helpers/joycon_protocol/nfc.cpp
@@ -278,7 +278,6 @@ DriverResult NfcProtocol::GetAmiiboData(std::vector<u8>& ntag_data) {
 
 DriverResult NfcProtocol::SendStartPollingRequest(MCUCommandResponse& output) {
     NFCRequestState request{
-        .sub_command = MCUSubCommand::ReadDeviceMode,
         .command_argument = NFCReadCommand::StartPolling,
         .packet_id = 0x0,
         .packet_flag = MCUPacketFlag::LastCommandPacket,
@@ -296,13 +295,13 @@ DriverResult NfcProtocol::SendStartPollingRequest(MCUCommandResponse& output) {
 
     std::array<u8, sizeof(NFCRequestState)> request_data{};
     memcpy(request_data.data(), &request, sizeof(NFCRequestState));
-    request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
-    return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output);
+    request_data[36] = CalculateMCU_CRC8(request_data.data(), 36);
+    return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, MCUSubCommand::ReadDeviceMode, request_data,
+                       output);
 }
 
 DriverResult NfcProtocol::SendStopPollingRequest(MCUCommandResponse& output) {
     NFCRequestState request{
-        .sub_command = MCUSubCommand::ReadDeviceMode,
         .command_argument = NFCReadCommand::StopPolling,
         .packet_id = 0x0,
         .packet_flag = MCUPacketFlag::LastCommandPacket,
@@ -313,13 +312,13 @@ DriverResult NfcProtocol::SendStopPollingRequest(MCUCommandResponse& output) {
 
     std::array<u8, sizeof(NFCRequestState)> request_data{};
     memcpy(request_data.data(), &request, sizeof(NFCRequestState));
-    request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
-    return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output);
+    request_data[36] = CalculateMCU_CRC8(request_data.data(), 36);
+    return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, MCUSubCommand::ReadDeviceMode, request_data,
+                       output);
 }
 
 DriverResult NfcProtocol::SendStartWaitingRecieveRequest(MCUCommandResponse& output) {
     NFCRequestState request{
-        .sub_command = MCUSubCommand::ReadDeviceMode,
         .command_argument = NFCReadCommand::StartWaitingRecieve,
         .packet_id = 0x0,
         .packet_flag = MCUPacketFlag::LastCommandPacket,
@@ -330,13 +329,13 @@ DriverResult NfcProtocol::SendStartWaitingRecieveRequest(MCUCommandResponse& out
 
     std::vector<u8> request_data(sizeof(NFCRequestState));
     memcpy(request_data.data(), &request, sizeof(NFCRequestState));
-    request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
-    return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output);
+    request_data[36] = CalculateMCU_CRC8(request_data.data(), 36);
+    return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, MCUSubCommand::ReadDeviceMode, request_data,
+                       output);
 }
 
 DriverResult NfcProtocol::SendReadAmiiboRequest(MCUCommandResponse& output, NFCPages ntag_pages) {
     NFCRequestState request{
-        .sub_command = MCUSubCommand::ReadDeviceMode,
         .command_argument = NFCReadCommand::Ntag,
         .packet_id = 0x0,
         .packet_flag = MCUPacketFlag::LastCommandPacket,
@@ -355,8 +354,9 @@ DriverResult NfcProtocol::SendReadAmiiboRequest(MCUCommandResponse& output, NFCP
 
     std::array<u8, sizeof(NFCRequestState)> request_data{};
     memcpy(request_data.data(), &request, sizeof(NFCRequestState));
-    request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
-    return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output);
+    request_data[36] = CalculateMCU_CRC8(request_data.data(), 36);
+    return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, MCUSubCommand::ReadDeviceMode, request_data,
+                       output);
 }
 
 NFCReadBlockCommand NfcProtocol::GetReadBlockCommand(NFCPages pages) const {