|
|
|
@ -401,6 +401,12 @@ Result NfcDevice::SendCommandByPassThrough(const Time::Clock::TimeSpanType& time |
|
|
|
} |
|
|
|
|
|
|
|
Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target_) { |
|
|
|
bool is_corrupted = false; |
|
|
|
|
|
|
|
if (model_type != NFP::ModelType::Amiibo) { |
|
|
|
return ResultInvalidArgument; |
|
|
|
} |
|
|
|
|
|
|
|
if (device_state != DeviceState::TagFound) { |
|
|
|
LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
|
|
|
return ResultWrongDeviceState; |
|
|
|
@ -420,26 +426,32 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target |
|
|
|
if (is_plain_amiibo) { |
|
|
|
std::vector<u8> data(sizeof(NFP::NTAG215File)); |
|
|
|
memcpy(data.data(), &tag_data, sizeof(tag_data)); |
|
|
|
WriteBackupData(tag_data.uid, data); |
|
|
|
} |
|
|
|
|
|
|
|
device_state = DeviceState::TagMounted; |
|
|
|
mount_target = mount_target_; |
|
|
|
return ResultSuccess; |
|
|
|
if (!is_plain_amiibo && !NFP::AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data)) { |
|
|
|
LOG_ERROR(Service_NFP, "Can't decode amiibo"); |
|
|
|
is_corrupted = true; |
|
|
|
} |
|
|
|
|
|
|
|
if (!NFP::AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data)) { |
|
|
|
bool has_backup = HasBackup(encrypted_tag_data.uuid).IsSuccess(); |
|
|
|
LOG_ERROR(Service_NFP, "Can't decode amiibo, has_backup= {}", has_backup); |
|
|
|
return has_backup ? ResultCorruptedDataWithBackup : ResultCorruptedData; |
|
|
|
if (tag_data.settings.settings.amiibo_initialized && !tag_data.owner_mii.IsValid()) { |
|
|
|
LOG_ERROR(Service_NFP, "Invalid mii data"); |
|
|
|
is_corrupted = true; |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File)); |
|
|
|
memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); |
|
|
|
WriteBackupData(encrypted_tag_data.uuid, data); |
|
|
|
if (!is_corrupted) { |
|
|
|
std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File)); |
|
|
|
memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); |
|
|
|
WriteBackupData(encrypted_tag_data.uuid, data); |
|
|
|
} |
|
|
|
|
|
|
|
device_state = DeviceState::TagMounted; |
|
|
|
mount_target = mount_target_; |
|
|
|
|
|
|
|
if (is_corrupted) { |
|
|
|
bool has_backup = HasBackup(encrypted_tag_data.uuid).IsSuccess(); |
|
|
|
return has_backup ? ResultCorruptedDataWithBackup : ResultCorruptedData; |
|
|
|
} |
|
|
|
|
|
|
|
return ResultSuccess; |
|
|
|
} |
|
|
|
|
|
|
|
@ -606,6 +618,17 @@ Result NfcDevice::Restore() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Restore mii data in case is corrupted by previous instances of yuzu
|
|
|
|
if (tag_data.settings.settings.amiibo_initialized && !tag_data.owner_mii.IsValid()) { |
|
|
|
LOG_ERROR(Service_NFP, "Regenerating mii data"); |
|
|
|
Mii::StoreData new_mii{}; |
|
|
|
new_mii.BuildRandom(Mii::Age::All, Mii::Gender::All, Mii::Race::All); |
|
|
|
new_mii.SetNickname({u'y', u'u', u'z', u'u', u'\0'}); |
|
|
|
|
|
|
|
tag_data.owner_mii.BuildFromStoreData(new_mii); |
|
|
|
tag_data.mii_extension.SetFromStoreData(new_mii); |
|
|
|
} |
|
|
|
|
|
|
|
// Overwrite tag contents with backup and mount the tag
|
|
|
|
tag_data = temporary_tag_data; |
|
|
|
encrypted_tag_data = temporary_encrypted_tag_data; |
|
|
|
@ -851,25 +874,6 @@ Result NfcDevice::SetRegisterInfoPrivate(const NFP::RegisterInfoPrivate& registe |
|
|
|
return Flush(); |
|
|
|
} |
|
|
|
|
|
|
|
Result NfcDevice::RestoreAmiibo() { |
|
|
|
if (device_state != DeviceState::TagMounted) { |
|
|
|
LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
|
|
|
if (device_state == DeviceState::TagRemoved) { |
|
|
|
return ResultTagRemoved; |
|
|
|
} |
|
|
|
return ResultWrongDeviceState; |
|
|
|
} |
|
|
|
|
|
|
|
if (mount_target == NFP::MountTarget::None || mount_target == NFP::MountTarget::Rom) { |
|
|
|
LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); |
|
|
|
return ResultWrongDeviceState; |
|
|
|
} |
|
|
|
|
|
|
|
// TODO: Load amiibo from backup on system
|
|
|
|
LOG_ERROR(Service_NFP, "Not Implemented"); |
|
|
|
return ResultSuccess; |
|
|
|
} |
|
|
|
|
|
|
|
Result NfcDevice::Format() { |
|
|
|
Result result = ResultSuccess; |
|
|
|
|
|
|
|
@ -877,7 +881,9 @@ Result NfcDevice::Format() { |
|
|
|
result = Mount(NFP::ModelType::Amiibo, NFP::MountTarget::All); |
|
|
|
} |
|
|
|
|
|
|
|
if (result.IsError()) { |
|
|
|
// We are formatting all data. Corruption is not an issue.
|
|
|
|
if (result.IsError() && |
|
|
|
(result != ResultCorruptedData && result != ResultCorruptedDataWithBackup)) { |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
|