diff options
Diffstat (limited to 'src/input_common/helpers/joycon_protocol/nfc.cpp')
| -rw-r--r-- | src/input_common/helpers/joycon_protocol/nfc.cpp | 68 |
1 files changed, 37 insertions, 31 deletions
diff --git a/src/input_common/helpers/joycon_protocol/nfc.cpp b/src/input_common/helpers/joycon_protocol/nfc.cpp index 5c0f71722..eeba82986 100644 --- a/src/input_common/helpers/joycon_protocol/nfc.cpp +++ b/src/input_common/helpers/joycon_protocol/nfc.cpp | |||
| @@ -110,7 +110,7 @@ bool NfcProtocol::HasAmiibo() { | |||
| 110 | 110 | ||
| 111 | DriverResult NfcProtocol::WaitUntilNfcIsReady() { | 111 | DriverResult NfcProtocol::WaitUntilNfcIsReady() { |
| 112 | constexpr std::size_t timeout_limit = 10; | 112 | constexpr std::size_t timeout_limit = 10; |
| 113 | std::vector<u8> output; | 113 | MCUCommandResponse output{}; |
| 114 | std::size_t tries = 0; | 114 | std::size_t tries = 0; |
| 115 | 115 | ||
| 116 | do { | 116 | do { |
| @@ -122,8 +122,9 @@ DriverResult NfcProtocol::WaitUntilNfcIsReady() { | |||
| 122 | if (tries++ > timeout_limit) { | 122 | if (tries++ > timeout_limit) { |
| 123 | return DriverResult::Timeout; | 123 | return DriverResult::Timeout; |
| 124 | } | 124 | } |
| 125 | } while (output[49] != 0x2a || (output[51] << 8) + output[50] != 0x0500 || output[55] != 0x31 || | 125 | } while (output.mcu_report != MCUReport::NFCState || |
| 126 | output[56] != 0x00); | 126 | (output.mcu_data[1] << 8) + output.mcu_data[0] != 0x0500 || |
| 127 | output.mcu_data[5] != 0x31 || output.mcu_data[6] != 0x00); | ||
| 127 | 128 | ||
| 128 | return DriverResult::Success; | 129 | return DriverResult::Success; |
| 129 | } | 130 | } |
| @@ -131,7 +132,7 @@ DriverResult NfcProtocol::WaitUntilNfcIsReady() { | |||
| 131 | DriverResult NfcProtocol::StartPolling(TagFoundData& data) { | 132 | DriverResult NfcProtocol::StartPolling(TagFoundData& data) { |
| 132 | LOG_DEBUG(Input, "Start Polling for tag"); | 133 | LOG_DEBUG(Input, "Start Polling for tag"); |
| 133 | constexpr std::size_t timeout_limit = 7; | 134 | constexpr std::size_t timeout_limit = 7; |
| 134 | std::vector<u8> output; | 135 | MCUCommandResponse output{}; |
| 135 | std::size_t tries = 0; | 136 | std::size_t tries = 0; |
| 136 | 137 | ||
| 137 | do { | 138 | do { |
| @@ -142,18 +143,20 @@ DriverResult NfcProtocol::StartPolling(TagFoundData& data) { | |||
| 142 | if (tries++ > timeout_limit) { | 143 | if (tries++ > timeout_limit) { |
| 143 | return DriverResult::Timeout; | 144 | return DriverResult::Timeout; |
| 144 | } | 145 | } |
| 145 | } while (output[49] != 0x2a || (output[51] << 8) + output[50] != 0x0500 || output[56] != 0x09); | 146 | } while (output.mcu_report != MCUReport::NFCState || |
| 147 | (output.mcu_data[1] << 8) + output.mcu_data[0] != 0x0500 || | ||
| 148 | output.mcu_data[6] != 0x09); | ||
| 146 | 149 | ||
| 147 | data.type = output[62]; | 150 | data.type = output.mcu_data[12]; |
| 148 | data.uuid.resize(output[64]); | 151 | data.uuid.resize(output.mcu_data[14]); |
| 149 | memcpy(data.uuid.data(), output.data() + 65, data.uuid.size()); | 152 | memcpy(data.uuid.data(), output.mcu_data.data() + 15, data.uuid.size()); |
| 150 | 153 | ||
| 151 | return DriverResult::Success; | 154 | return DriverResult::Success; |
| 152 | } | 155 | } |
| 153 | 156 | ||
| 154 | DriverResult NfcProtocol::ReadTag(const TagFoundData& data) { | 157 | DriverResult NfcProtocol::ReadTag(const TagFoundData& data) { |
| 155 | constexpr std::size_t timeout_limit = 10; | 158 | constexpr std::size_t timeout_limit = 10; |
| 156 | std::vector<u8> output; | 159 | MCUCommandResponse output{}; |
| 157 | std::size_t tries = 0; | 160 | std::size_t tries = 0; |
| 158 | 161 | ||
| 159 | std::string uuid_string; | 162 | std::string uuid_string; |
| @@ -168,23 +171,24 @@ DriverResult NfcProtocol::ReadTag(const TagFoundData& data) { | |||
| 168 | // Read Tag data | 171 | // Read Tag data |
| 169 | while (true) { | 172 | while (true) { |
| 170 | auto result = SendReadAmiiboRequest(output, ntag_pages); | 173 | auto result = SendReadAmiiboRequest(output, ntag_pages); |
| 171 | const auto mcu_report = static_cast<MCUReport>(output[49]); | 174 | const auto nfc_status = static_cast<NFCStatus>(output.mcu_data[6]); |
| 172 | const auto nfc_status = static_cast<NFCStatus>(output[56]); | ||
| 173 | 175 | ||
| 174 | if (result != DriverResult::Success) { | 176 | if (result != DriverResult::Success) { |
| 175 | return result; | 177 | return result; |
| 176 | } | 178 | } |
| 177 | 179 | ||
| 178 | if ((mcu_report == MCUReport::NFCReadData || mcu_report == MCUReport::NFCState) && | 180 | if ((output.mcu_report == MCUReport::NFCReadData || |
| 181 | output.mcu_report == MCUReport::NFCState) && | ||
| 179 | nfc_status == NFCStatus::TagLost) { | 182 | nfc_status == NFCStatus::TagLost) { |
| 180 | return DriverResult::ErrorReadingData; | 183 | return DriverResult::ErrorReadingData; |
| 181 | } | 184 | } |
| 182 | 185 | ||
| 183 | if (mcu_report == MCUReport::NFCReadData && output[51] == 0x07 && output[52] == 0x01) { | 186 | if (output.mcu_report == MCUReport::NFCReadData && output.mcu_data[1] == 0x07 && |
| 187 | output.mcu_data[2] == 0x01) { | ||
| 184 | if (data.type != 2) { | 188 | if (data.type != 2) { |
| 185 | continue; | 189 | continue; |
| 186 | } | 190 | } |
| 187 | switch (output[74]) { | 191 | switch (output.mcu_data[24]) { |
| 188 | case 0: | 192 | case 0: |
| 189 | ntag_pages = NFCPages::Block135; | 193 | ntag_pages = NFCPages::Block135; |
| 190 | break; | 194 | break; |
| @@ -200,14 +204,14 @@ DriverResult NfcProtocol::ReadTag(const TagFoundData& data) { | |||
| 200 | continue; | 204 | continue; |
| 201 | } | 205 | } |
| 202 | 206 | ||
| 203 | if (mcu_report == MCUReport::NFCState && nfc_status == NFCStatus::LastPackage) { | 207 | if (output.mcu_report == MCUReport::NFCState && nfc_status == NFCStatus::LastPackage) { |
| 204 | // finished | 208 | // finished |
| 205 | SendStopPollingRequest(output); | 209 | SendStopPollingRequest(output); |
| 206 | return DriverResult::Success; | 210 | return DriverResult::Success; |
| 207 | } | 211 | } |
| 208 | 212 | ||
| 209 | // Ignore other state reports | 213 | // Ignore other state reports |
| 210 | if (mcu_report == MCUReport::NFCState) { | 214 | if (output.mcu_report == MCUReport::NFCState) { |
| 211 | continue; | 215 | continue; |
| 212 | } | 216 | } |
| 213 | 217 | ||
| @@ -221,7 +225,7 @@ DriverResult NfcProtocol::ReadTag(const TagFoundData& data) { | |||
| 221 | 225 | ||
| 222 | DriverResult NfcProtocol::GetAmiiboData(std::vector<u8>& ntag_data) { | 226 | DriverResult NfcProtocol::GetAmiiboData(std::vector<u8>& ntag_data) { |
| 223 | constexpr std::size_t timeout_limit = 10; | 227 | constexpr std::size_t timeout_limit = 10; |
| 224 | std::vector<u8> output; | 228 | MCUCommandResponse output{}; |
| 225 | std::size_t tries = 0; | 229 | std::size_t tries = 0; |
| 226 | 230 | ||
| 227 | NFCPages ntag_pages = NFCPages::Block135; | 231 | NFCPages ntag_pages = NFCPages::Block135; |
| @@ -229,36 +233,38 @@ DriverResult NfcProtocol::GetAmiiboData(std::vector<u8>& ntag_data) { | |||
| 229 | // Read Tag data | 233 | // Read Tag data |
| 230 | while (true) { | 234 | while (true) { |
| 231 | auto result = SendReadAmiiboRequest(output, ntag_pages); | 235 | auto result = SendReadAmiiboRequest(output, ntag_pages); |
| 232 | const auto mcu_report = static_cast<MCUReport>(output[49]); | 236 | const auto nfc_status = static_cast<NFCStatus>(output.mcu_data[6]); |
| 233 | const auto nfc_status = static_cast<NFCStatus>(output[56]); | ||
| 234 | 237 | ||
| 235 | if (result != DriverResult::Success) { | 238 | if (result != DriverResult::Success) { |
| 236 | return result; | 239 | return result; |
| 237 | } | 240 | } |
| 238 | 241 | ||
| 239 | if ((mcu_report == MCUReport::NFCReadData || mcu_report == MCUReport::NFCState) && | 242 | if ((output.mcu_report == MCUReport::NFCReadData || |
| 243 | output.mcu_report == MCUReport::NFCState) && | ||
| 240 | nfc_status == NFCStatus::TagLost) { | 244 | nfc_status == NFCStatus::TagLost) { |
| 241 | return DriverResult::ErrorReadingData; | 245 | return DriverResult::ErrorReadingData; |
| 242 | } | 246 | } |
| 243 | 247 | ||
| 244 | if (mcu_report == MCUReport::NFCReadData && output[51] == 0x07) { | 248 | if (output.mcu_report == MCUReport::NFCReadData && output.mcu_data[1] == 0x07) { |
| 245 | std::size_t payload_size = (output[54] << 8 | output[55]) & 0x7FF; | 249 | std::size_t payload_size = (output.mcu_data[4] << 8 | output.mcu_data[5]) & 0x7FF; |
| 246 | if (output[52] == 0x01) { | 250 | if (output.mcu_data[2] == 0x01) { |
| 247 | memcpy(ntag_data.data() + ntag_buffer_pos, output.data() + 116, payload_size - 60); | 251 | memcpy(ntag_data.data() + ntag_buffer_pos, output.mcu_data.data() + 66, |
| 252 | payload_size - 60); | ||
| 248 | ntag_buffer_pos += payload_size - 60; | 253 | ntag_buffer_pos += payload_size - 60; |
| 249 | } else { | 254 | } else { |
| 250 | memcpy(ntag_data.data() + ntag_buffer_pos, output.data() + 56, payload_size); | 255 | memcpy(ntag_data.data() + ntag_buffer_pos, output.mcu_data.data() + 6, |
| 256 | payload_size); | ||
| 251 | } | 257 | } |
| 252 | continue; | 258 | continue; |
| 253 | } | 259 | } |
| 254 | 260 | ||
| 255 | if (mcu_report == MCUReport::NFCState && nfc_status == NFCStatus::LastPackage) { | 261 | if (output.mcu_report == MCUReport::NFCState && nfc_status == NFCStatus::LastPackage) { |
| 256 | LOG_INFO(Input, "Finished reading amiibo"); | 262 | LOG_INFO(Input, "Finished reading amiibo"); |
| 257 | return DriverResult::Success; | 263 | return DriverResult::Success; |
| 258 | } | 264 | } |
| 259 | 265 | ||
| 260 | // Ignore other state reports | 266 | // Ignore other state reports |
| 261 | if (mcu_report == MCUReport::NFCState) { | 267 | if (output.mcu_report == MCUReport::NFCState) { |
| 262 | continue; | 268 | continue; |
| 263 | } | 269 | } |
| 264 | 270 | ||
| @@ -270,7 +276,7 @@ DriverResult NfcProtocol::GetAmiiboData(std::vector<u8>& ntag_data) { | |||
| 270 | return DriverResult::Success; | 276 | return DriverResult::Success; |
| 271 | } | 277 | } |
| 272 | 278 | ||
| 273 | DriverResult NfcProtocol::SendStartPollingRequest(std::vector<u8>& output) { | 279 | DriverResult NfcProtocol::SendStartPollingRequest(MCUCommandResponse& output) { |
| 274 | NFCRequestState request{ | 280 | NFCRequestState request{ |
| 275 | .sub_command = MCUSubCommand::ReadDeviceMode, | 281 | .sub_command = MCUSubCommand::ReadDeviceMode, |
| 276 | .command_argument = NFCReadCommand::StartPolling, | 282 | .command_argument = NFCReadCommand::StartPolling, |
| @@ -294,7 +300,7 @@ DriverResult NfcProtocol::SendStartPollingRequest(std::vector<u8>& output) { | |||
| 294 | return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); | 300 | return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); |
| 295 | } | 301 | } |
| 296 | 302 | ||
| 297 | DriverResult NfcProtocol::SendStopPollingRequest(std::vector<u8>& output) { | 303 | DriverResult NfcProtocol::SendStopPollingRequest(MCUCommandResponse& output) { |
| 298 | NFCRequestState request{ | 304 | NFCRequestState request{ |
| 299 | .sub_command = MCUSubCommand::ReadDeviceMode, | 305 | .sub_command = MCUSubCommand::ReadDeviceMode, |
| 300 | .command_argument = NFCReadCommand::StopPolling, | 306 | .command_argument = NFCReadCommand::StopPolling, |
| @@ -311,7 +317,7 @@ DriverResult NfcProtocol::SendStopPollingRequest(std::vector<u8>& output) { | |||
| 311 | return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); | 317 | return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); |
| 312 | } | 318 | } |
| 313 | 319 | ||
| 314 | DriverResult NfcProtocol::SendStartWaitingRecieveRequest(std::vector<u8>& output) { | 320 | DriverResult NfcProtocol::SendStartWaitingRecieveRequest(MCUCommandResponse& output) { |
| 315 | NFCRequestState request{ | 321 | NFCRequestState request{ |
| 316 | .sub_command = MCUSubCommand::ReadDeviceMode, | 322 | .sub_command = MCUSubCommand::ReadDeviceMode, |
| 317 | .command_argument = NFCReadCommand::StartWaitingRecieve, | 323 | .command_argument = NFCReadCommand::StartWaitingRecieve, |
| @@ -328,7 +334,7 @@ DriverResult NfcProtocol::SendStartWaitingRecieveRequest(std::vector<u8>& output | |||
| 328 | return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); | 334 | return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); |
| 329 | } | 335 | } |
| 330 | 336 | ||
| 331 | DriverResult NfcProtocol::SendReadAmiiboRequest(std::vector<u8>& output, NFCPages ntag_pages) { | 337 | DriverResult NfcProtocol::SendReadAmiiboRequest(MCUCommandResponse& output, NFCPages ntag_pages) { |
| 332 | NFCRequestState request{ | 338 | NFCRequestState request{ |
| 333 | .sub_command = MCUSubCommand::ReadDeviceMode, | 339 | .sub_command = MCUSubCommand::ReadDeviceMode, |
| 334 | .command_argument = NFCReadCommand::Ntag, | 340 | .command_argument = NFCReadCommand::Ntag, |