unleashed-firmware/lib/nfc/nfc_device.h

267 lines
9.1 KiB
C
Raw Normal View History

/**
* @file nfc_device.h
* @brief Abstract interface for managing NFC device data.
*
* Under the hood, it makes use of the protocol-specific functions that each one of them provides
* and abstracts it with a protocol-independent API.
*
* It does not perform any signal processing, but merely serves as a container with some handy
* operations such as loading and saving from and to a file.
*/
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "protocols/nfc_device_base.h"
#include "protocols/nfc_protocol.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief NfcDevice opaque type definition.
*/
typedef struct NfcDevice NfcDevice;
/**
* @brief Loading callback function signature.
*
* A function with such signature can be set as a callback to indicate
* the completion (or a failure) of nfc_device_load() and nfc_device_save() functions.
*
* This facility is commonly used to control GUI elements, such as progress dialogs.
*
* @param[in] context user-defined context that was passed in nfc_device_set_loading_callback().
* @param[in] state true if the data was loaded successfully, false otherwise.
*/
typedef void (*NfcLoadingCallback)(void* context, bool state);
/**
* @brief Allocate an NfcDevice instance.
*
* A newly created instance does not hold any data and thus is considered invalid. The most common
* use case would be to set its data by calling nfc_device_set_data() right afterwards.
*
* @returns pointer to the allocated instance.
*/
NfcDevice* nfc_device_alloc(void);
/**
* @brief Delete an NfcDevice instance.
*
* @param[in,out] instance pointer to the instance to be deleted.
*/
void nfc_device_free(NfcDevice* instance);
/**
* @brief Clear an NfcDevice instance.
*
* All data contained in the instance will be deleted and the instance itself will become invalid
* as if it was just allocated.
*
* @param[in,out] instance pointer to the instance to be cleared.
*/
void nfc_device_clear(NfcDevice* instance);
/**
* @brief Reset an NfcDevice instance.
*
* The data contained in the instance will be reset according to the protocol-defined procedure.
* Unlike the nfc_device_clear() function, the instance will remain valid.
*
* @param[in,out] instance pointer to the instance to be reset.
*/
void nfc_device_reset(NfcDevice* instance);
/**
* @brief Get the protocol identifier from an NfcDevice instance.
*
* If the instance is invalid, the return value will be NfcProtocolInvalid.
*
* @param[in] instance pointer to the instance to be queried.
* @returns protocol identifier contained in the instance.
*/
NfcProtocol nfc_device_get_protocol(const NfcDevice* instance);
/**
* @brief Get the protocol-specific data from an NfcDevice instance.
*
* The protocol parameter's behaviour is a bit tricky. The function will check
* whether there is such a protocol somewhere in the protocol hierarchy and return
* the data exactly from that level.
*
* Example: Call nfc_device_get_data() on an instance with Mf DESFire protocol.
* The protocol hierarchy will look like the following:
*
* `Mf DESFire --> ISO14443-4A --> ISO14443-3A`
*
* Thus, the following values of the protocol parameter are valid:
*
* * NfcProtocolIso14443_3a
* * NfcProtocolIso14443_4a
* * NfcProtocolMfDesfire
*
* and passing them to the call would result in the respective data being returned.
*
* However, supplying a protocol identifier which is not in the hierarchy will
* result in a crash. This is to improve type safety.
*
* @param instance pointer to the instance to be queried
* @param protocol protocol identifier of the data to be retrieved.
* @returns pointer to the instance's data.
*/
const NfcDeviceData* nfc_device_get_data(const NfcDevice* instance, NfcProtocol protocol);
/**
* @brief Get the protocol name by its identifier.
*
* This function does not require an instance as its return result depends only
* the protocol identifier.
*
* @param[in] protocol numeric identifier of the protocol in question.
* @returns pointer to a statically allocated string containing the protocol name.
*/
const char* nfc_device_get_protocol_name(NfcProtocol protocol);
/**
* @brief Get the name of an NfcDevice instance.
*
* The return value may change depending on the instance's internal state and the name_type parameter.
*
* @param[in] instance pointer to the instance to be queried.
* @param[in] name_type type of the name to be displayed.
* @returns pointer to a statically allocated string containing the device name.
*/
const char* nfc_device_get_name(const NfcDevice* instance, NfcDeviceNameType name_type);
/**
* @brief Get the unique identifier (UID) of an NfcDevice instance.
*
* The UID length is protocol-dependent. Additionally, a particular protocol might support
* several UID lengths.
*
* @param[in] instance pointer to the instance to be queried.
* @param[out] uid_len pointer to the variable to contain the UID length.
* @returns pointer to the byte array containing the instance's UID.
*/
const uint8_t* nfc_device_get_uid(const NfcDevice* instance, size_t* uid_len);
/**
* @brief Set the unique identifier (UID) of an NfcDevice instance.
*
* The UID length must be supported by the instance's protocol.
*
* @param[in,out] instance pointer to the instance to be modified.
* @param[in] uid pointer to the byte array containing the new UID.
* @param[in] uid_len length of the UID.
* @return true if the UID was valid and set, false otherwise.
*/
bool nfc_device_set_uid(NfcDevice* instance, const uint8_t* uid, size_t uid_len);
/**
* @brief Set the data and protocol of an NfcDevice instance.
*
* Any data previously contained in the instance will be deleted.
*
* @param[in,out] instance pointer to the instance to be modified.
* @param[in] protocol numeric identifier of the data's protocol.
* @param[in] protocol_data pointer to the protocol-specific data.
*/
void nfc_device_set_data(
NfcDevice* instance,
NfcProtocol protocol,
const NfcDeviceData* protocol_data);
/**
* @brief Copy (export) the data contained in an NfcDevice instance to an outside NfcDeviceData instance.
*
* This function does the inverse of nfc_device_set_data().
[FL-2605] NFC new design (#1364) * nfc: add new read scene * lib: refactore nfc library * mifare desfire: add read card fuction * lib nfc: add auto read worker * nfc: add supported cards * nfc: add mifare classic read success scene * nfc: add troyka support * submodule: update protobuf * nfc: mifare classic keys cache * nfc: rework mifare classic key cache * Correct spelling * nfc: add user dictionary * nfc: introduce block read map in fff * nfc: rework dict attack * nfc: improve dict attack * nfc: rework mifare classic format * nfc: rework MFC read with Reader * nfc: add gui for MFC read success scene * nfc: fix dict attack view gui * nfc: add retry and exit confirm scenes * nfc: add retry and exit scenes navigation * nfc: check user dictionary * nfc: remove unused scenes * nfc: rename functions in nfc worker * nfc: rename mf_classic_dict_attack -> dict_attack * nfc: change scenes names * nfc: remove scene tick events * nfc: rework dict calls with buffer streams * nfc: fix notifications * nfc: fix mf desfire navigation * nfc: remove notification from mf classic read success * nfc: fix read sectors calculation * nfc: add fallback for unknown card * nfc: show file name while emulating * nfc: fix build * nfc: fix memory leak * nfc: fix desfire read * nfc: add no dict found navigation * nfc: add read views * nfc: update card fix * nfc: fix access bytes save * nfc: add exit and retry confirm to mf ultralight read success * nfc: introduce detect reader * nfc: change record open arg to macros * nfc: fix start from archive Co-authored-by: Astra <astra@astrra.space> Co-authored-by: あく <alleteam@gmail.com>
2022-07-26 15:30:49 +00:00
* The protocol identifier passed as the protocol parameter MUST match the one
* stored in the instance, otherwise a crash will occur.
* This is to improve type safety.
*
* @param[in] instance pointer to the instance to be copied from.
* @param[in] protocol numeric identifier of the instance's protocol.
* @param[out] protocol_data pointer to the destination data.
*/
void nfc_device_copy_data(
const NfcDevice* instance,
NfcProtocol protocol,
NfcDeviceData* protocol_data);
/**
* @brief Check whether an NfcDevice instance holds certain data.
*
* This function's behaviour is similar to nfc_device_is_equal(), with the difference
* that it takes NfcProtocol and NfcDeviceData* instead of the second NfcDevice*.
*
* The following code snippets [1] and [2] are equivalent:
*
* [1]
* ```c
* bool is_equal = nfc_device_is_equal(device1, device2);
* ```
* [2]
* ```c
* NfcProtocol protocol = nfc_device_get_protocol(device2);
* const NfcDeviceData* data = nfc_device_get_data(device2, protocol);
* bool is_equal = nfc_device_is_equal_data(device1, protocol, data);
* ```
*
* @param[in] instance pointer to the instance to be compared.
* @param[in] protocol protocol identifier of the data to be compared.
* @param[in] protocol_data pointer to the NFC device data to be compared.
* @returns true if the instance is of the right type and the data matches, false otherwise.
*/
bool nfc_device_is_equal_data(
const NfcDevice* instance,
NfcProtocol protocol,
const NfcDeviceData* protocol_data);
Nfc: add basic Mifare DESFire support (#1024) * Fix TextBox word wrap behavior * Wrap width is 120 pixels, not 140. (140 is larger than the screen!) * Glyph width already includes spacing; don't add 1 additional px * When starting a new line, include wrapped glyph width in new line_width. * Call canvas_set_font before text_box_insert_endline so that glyph width is calculated using correct font. Previous approach worked somewhat well using default TextBoxFontText but this version is more robust, particularly when using TextBoxFontHex. * Add basic Mifare DESFire reading, file/app browser * Fix build with APP_ARCHIVE=0 * Add bool type to flipper_format * Add ability to save and load DESFire card data * Skip over NfcSceneDeviceInfo when viewing saved DESFire info * mf_df_clear: don't leak master key settings key versions * When opening a DESFire card from Archive, retain UID emulation behavior * rm unnecessary \r\n * show Popup instead of leaving view in bad state * Move NfcReaderRequestData out of union This makes it safe to emulate DESFire/EMV without clobbering card data. * Display saved DESFire cards via NfcSceneDeviceInfo * Display and save file metadata even when contents are missing This can happen when a file doesn't allow unauthenticated reads (see the call to mf_df_parse_read_data_response in nfc_worker.c). Co-authored-by: Kevin Wallace <git+flipperzero@kevin.wallace.seattle.wa.us> Co-authored-by: あく <alleteam@gmail.com> Co-authored-by: gornekich <n.gorbadey@gmail.com>
2022-03-23 13:45:37 +00:00
/**
* @brief Compare two NfcDevice instances to determine whether they are equal.
*
* @param[in] instance pointer to the first instance to be compared.
* @param[in] other pointer to the second instance to be compared.
* @returns true if both instances are considered equal, false otherwise.
*/
bool nfc_device_is_equal(const NfcDevice* instance, const NfcDevice* other);
/**
* @brief Set the loading callback function.
*
* @param[in,out] instance pointer to the instance to be modified.
* @param[in] callback pointer to a function to be called when the load operation completes.
* @param[in] context pointer to a user-specific context (will be passed to the callback).
*/
void nfc_device_set_loading_callback(
NfcDevice* instance,
NfcLoadingCallback callback,
void* context);
/**
* @brief Save NFC device data form an NfcDevice instance to a file.
*
* @param[in] instance pointer to the instance to be saved.
* @param[in] path pointer to a character string with a full file path.
* @returns true if the data was successfully saved, false otherwise.
*/
bool nfc_device_save(NfcDevice* instance, const char* path);
/**
* @brief Load NFC device data to an NfcDevice instance from a file.
*
* @param[in,out] instance pointer to the instance to be loaded into.
* @param[in] path pointer to a character string with a full file path.
* @returns true if the data was successfully loaded, false otherwise.
*/
bool nfc_device_load(NfcDevice* instance, const char* path);
#ifdef __cplusplus
}
#endif