summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/nfc/common/device.h
blob: 0ed1ff34ca72439b39c570c23d0f14aed2096130 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <span>

#include "common/common_types.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/nfc/mifare_types.h"
#include "core/hle/service/nfc/nfc_types.h"
#include "core/hle/service/nfp/nfp_types.h"
#include "core/hle/service/service.h"
#include "core/hle/service/time/clock_types.h"

namespace Kernel {
class KEvent;
class KReadableEvent;
} // namespace Kernel

namespace Core {
class System;
} // namespace Core

namespace Core::HID {
class EmulatedController;
enum class ControllerTriggerType;
enum class NpadIdType : u32;
} // namespace Core::HID

namespace Service::NFC {
class NfcDevice {
public:
    NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_,
              KernelHelpers::ServiceContext& service_context_,
              Kernel::KEvent* availability_change_event_);
    ~NfcDevice();

    void Initialize();
    void Finalize();

    Result StartDetection(NfcProtocol allowed_protocol);
    Result StopDetection();

    Result GetTagInfo(TagInfo& tag_info) const;

    Result ReadMifare(std::span<const MifareReadBlockParameter> parameters,
                      std::span<MifareReadBlockData> read_block_data) const;

    Result WriteMifare(std::span<const MifareWriteBlockParameter> parameters);

    Result SendCommandByPassThrough(const Time::Clock::TimeSpanType& timeout,
                                    std::span<const u8> command_data, std::span<u8> out_data);

    Result Mount(NFP::ModelType model_type, NFP::MountTarget mount_target);
    Result Unmount();

    Result Flush();
    Result FlushDebug();
    Result FlushWithBreak(NFP::BreakType break_type);
    Result Restore();

    Result GetCommonInfo(NFP::CommonInfo& common_info) const;
    Result GetModelInfo(NFP::ModelInfo& model_info) const;
    Result GetRegisterInfo(NFP::RegisterInfo& register_info) const;
    Result GetRegisterInfoPrivate(NFP::RegisterInfoPrivate& register_info) const;
    Result GetAdminInfo(NFP::AdminInfo& admin_info) const;

    Result DeleteRegisterInfo();
    Result SetRegisterInfoPrivate(const NFP::RegisterInfoPrivate& register_info);
    Result RestoreAmiibo();
    Result Format();

    Result OpenApplicationArea(u32 access_id);
    Result GetApplicationAreaId(u32& application_area_id) const;
    Result GetApplicationArea(std::span<u8> data) const;
    Result SetApplicationArea(std::span<const u8> data);
    Result CreateApplicationArea(u32 access_id, std::span<const u8> data);
    Result RecreateApplicationArea(u32 access_id, std::span<const u8> data);
    Result DeleteApplicationArea();
    Result ExistsApplicationArea(bool& has_application_area) const;

    Result GetAll(NFP::NfpData& data) const;
    Result SetAll(const NFP::NfpData& data);
    Result BreakTag(NFP::BreakType break_type);
    Result HasBackup(const UniqueSerialNumber& uid, std::size_t uuid_size) const;
    Result HasBackup(const NFP::TagUuid& tag_uid) const;
    Result ReadBackupData(const UniqueSerialNumber& uid, std::size_t uuid_size,
                          std::span<u8> data) const;
    Result ReadBackupData(const NFP::TagUuid& tag_uid, std::span<u8> data) const;
    Result WriteBackupData(const UniqueSerialNumber& uid, std::size_t uuid_size,
                           std::span<const u8> data);
    Result WriteBackupData(const NFP::TagUuid& tag_uid, std::span<const u8> data);
    Result WriteNtf(std::span<const u8> data);

    u64 GetHandle() const;
    DeviceState GetCurrentState() const;
    Result GetNpadId(Core::HID::NpadIdType& out_npad_id) const;

    Kernel::KReadableEvent& GetActivateEvent() const;
    Kernel::KReadableEvent& GetDeactivateEvent() const;

private:
    void NpadUpdate(Core::HID::ControllerTriggerType type);
    bool LoadNfcTag(u8 protocol, u8 tag_type, u8 uuid_length, UniqueSerialNumber uuid);
    bool LoadAmiiboData();
    void CloseNfcTag();

    NFP::AmiiboName GetAmiiboName(const NFP::AmiiboSettings& settings) const;
    void SetAmiiboName(NFP::AmiiboSettings& settings, const NFP::AmiiboName& amiibo_name) const;
    NFP::AmiiboDate GetAmiiboDate(s64 posix_time) const;
    u64 GetCurrentPosixTime() const;
    u64 RemoveVersionByte(u64 application_id) const;
    void UpdateSettingsCrc();
    void UpdateRegisterInfoCrc();

    void BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data,
                                const NFP::EncryptedNTAG215File& encrypted_file) const;

    bool is_controller_set{};
    int callback_key;
    const Core::HID::NpadIdType npad_id;
    Core::System& system;
    Core::HID::EmulatedController* npad_device = nullptr;
    KernelHelpers::ServiceContext& service_context;
    Kernel::KEvent* activate_event = nullptr;
    Kernel::KEvent* deactivate_event = nullptr;
    Kernel::KEvent* availability_change_event = nullptr;

    bool is_initalized{};
    NfcProtocol allowed_protocols{};
    DeviceState device_state{DeviceState::Unavailable};

    // NFP data
    bool is_data_moddified{};
    bool is_app_area_open{};
    bool is_plain_amiibo{};
    bool is_write_protected{};
    NFP::MountTarget mount_target{NFP::MountTarget::None};

    TagInfo real_tag_info{};
    NFP::NTAG215File tag_data{};
    NFP::EncryptedNTAG215File encrypted_tag_data{};
};

} // namespace Service::NFC