astyle --formatted --mode=c --indent=spaces=2 --indent-switches --indent-preprocessor --keep-one-line-blocks --max-instatement-indent=60
This commit is contained in:
parent
26569c2202
commit
a2cd236441
45 changed files with 1096 additions and 1082 deletions
|
|
@ -32,29 +32,29 @@
|
|||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct nfc_emulator;
|
||||
struct nfc_emulation_state_machine;
|
||||
struct nfc_emulator;
|
||||
struct nfc_emulation_state_machine;
|
||||
|
||||
/**
|
||||
* @struct nfc_emulator
|
||||
* @brief NFC emulator structure
|
||||
*/
|
||||
struct nfc_emulator {
|
||||
nfc_target *target;
|
||||
struct nfc_emulation_state_machine *state_machine;
|
||||
void *user_data;
|
||||
};
|
||||
/**
|
||||
* @struct nfc_emulator
|
||||
* @brief NFC emulator structure
|
||||
*/
|
||||
struct nfc_emulator {
|
||||
nfc_target *target;
|
||||
struct nfc_emulation_state_machine *state_machine;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct nfc_emulation_state_machine
|
||||
* @brief NFC emulation state machine structure
|
||||
*/
|
||||
struct nfc_emulation_state_machine {
|
||||
int (*io)(struct nfc_emulator *emulator, const uint8_t *data_in, const size_t data_in_len, uint8_t *data_out, const size_t data_out_len);
|
||||
void *data;
|
||||
};
|
||||
/**
|
||||
* @struct nfc_emulation_state_machine
|
||||
* @brief NFC emulation state machine structure
|
||||
*/
|
||||
struct nfc_emulation_state_machine {
|
||||
int (*io)(struct nfc_emulator *emulator, const uint8_t *data_in, const size_t data_in_len, uint8_t *data_out, const size_t data_out_len);
|
||||
void *data;
|
||||
};
|
||||
|
||||
NFC_EXPORT int nfc_emulate_target (nfc_device* pnd, struct nfc_emulator *emulator);
|
||||
NFC_EXPORT int nfc_emulate_target (nfc_device* pnd, struct nfc_emulator *emulator);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,79 +48,79 @@ typedef char nfc_connstring[1024];
|
|||
* Properties
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* Default command processing timeout
|
||||
* Property value's (duration) unit is ms and 0 means no timeout (infinite).
|
||||
* Default value is set by driver layer
|
||||
*/
|
||||
/**
|
||||
* Default command processing timeout
|
||||
* Property value's (duration) unit is ms and 0 means no timeout (infinite).
|
||||
* Default value is set by driver layer
|
||||
*/
|
||||
NP_TIMEOUT_COMMAND,
|
||||
/**
|
||||
* Timeout between ATR_REQ and ATR_RES
|
||||
* When the device is in initiator mode, a target is considered as mute if no
|
||||
* valid ATR_RES is received within this timeout value.
|
||||
* Default value for this property is 103 ms on PN53x based devices.
|
||||
*/
|
||||
/**
|
||||
* Timeout between ATR_REQ and ATR_RES
|
||||
* When the device is in initiator mode, a target is considered as mute if no
|
||||
* valid ATR_RES is received within this timeout value.
|
||||
* Default value for this property is 103 ms on PN53x based devices.
|
||||
*/
|
||||
NP_TIMEOUT_ATR,
|
||||
/**
|
||||
* Timeout value to give up reception from the target in case of no answer.
|
||||
* Default value for this property is 52 ms).
|
||||
*/
|
||||
/**
|
||||
* Timeout value to give up reception from the target in case of no answer.
|
||||
* Default value for this property is 52 ms).
|
||||
*/
|
||||
NP_TIMEOUT_COM,
|
||||
/** Let the PN53X chip handle the CRC bytes. This means that the chip appends
|
||||
* the CRC bytes to the frames that are transmitted. It will parse the last
|
||||
* bytes from received frames as incoming CRC bytes. They will be verified
|
||||
* against the used modulation and protocol. If an frame is expected with
|
||||
* incorrect CRC bytes this option should be disabled. Example frames where
|
||||
* this is useful are the ATQA and UID+BCC that are transmitted without CRC
|
||||
* bytes during the anti-collision phase of the ISO14443-A protocol. */
|
||||
* the CRC bytes to the frames that are transmitted. It will parse the last
|
||||
* bytes from received frames as incoming CRC bytes. They will be verified
|
||||
* against the used modulation and protocol. If an frame is expected with
|
||||
* incorrect CRC bytes this option should be disabled. Example frames where
|
||||
* this is useful are the ATQA and UID+BCC that are transmitted without CRC
|
||||
* bytes during the anti-collision phase of the ISO14443-A protocol. */
|
||||
NP_HANDLE_CRC,
|
||||
/** Parity bits in the network layer of ISO14443-A are by default generated and
|
||||
* validated in the PN53X chip. This is a very convenient feature. On certain
|
||||
* times though it is useful to get full control of the transmitted data. The
|
||||
* proprietary MIFARE Classic protocol uses for example custom (encrypted)
|
||||
* parity bits. For interoperability it is required to be completely
|
||||
* compatible, including the arbitrary parity bits. When this option is
|
||||
* disabled, the functions to communicating bits should be used. */
|
||||
/** Parity bits in the network layer of ISO14443-A are by default generated and
|
||||
* validated in the PN53X chip. This is a very convenient feature. On certain
|
||||
* times though it is useful to get full control of the transmitted data. The
|
||||
* proprietary MIFARE Classic protocol uses for example custom (encrypted)
|
||||
* parity bits. For interoperability it is required to be completely
|
||||
* compatible, including the arbitrary parity bits. When this option is
|
||||
* disabled, the functions to communicating bits should be used. */
|
||||
NP_HANDLE_PARITY,
|
||||
/** This option can be used to enable or disable the electronic field of the
|
||||
* NFC device. */
|
||||
/** This option can be used to enable or disable the electronic field of the
|
||||
* NFC device. */
|
||||
NP_ACTIVATE_FIELD,
|
||||
/** The internal CRYPTO1 co-processor can be used to transmit messages
|
||||
* encrypted. This option is automatically activated after a successful MIFARE
|
||||
* Classic authentication. */
|
||||
/** The internal CRYPTO1 co-processor can be used to transmit messages
|
||||
* encrypted. This option is automatically activated after a successful MIFARE
|
||||
* Classic authentication. */
|
||||
NP_ACTIVATE_CRYPTO1,
|
||||
/** The default configuration defines that the PN53X chip will try indefinitely
|
||||
* to invite a tag in the field to respond. This could be desired when it is
|
||||
* certain a tag will enter the field. On the other hand, when this is
|
||||
* uncertain, it will block the application. This option could best be compared
|
||||
* to the (NON)BLOCKING option used by (socket)network programming. */
|
||||
/** The default configuration defines that the PN53X chip will try indefinitely
|
||||
* to invite a tag in the field to respond. This could be desired when it is
|
||||
* certain a tag will enter the field. On the other hand, when this is
|
||||
* uncertain, it will block the application. This option could best be compared
|
||||
* to the (NON)BLOCKING option used by (socket)network programming. */
|
||||
NP_INFINITE_SELECT,
|
||||
/** If this option is enabled, frames that carry less than 4 bits are allowed.
|
||||
* According to the standards these frames should normally be handles as
|
||||
* invalid frames. */
|
||||
/** If this option is enabled, frames that carry less than 4 bits are allowed.
|
||||
* According to the standards these frames should normally be handles as
|
||||
* invalid frames. */
|
||||
NP_ACCEPT_INVALID_FRAMES,
|
||||
/** If the NFC device should only listen to frames, it could be useful to let
|
||||
* it gather multiple frames in a sequence. They will be stored in the internal
|
||||
* FIFO of the PN53X chip. This could be retrieved by using the receive data
|
||||
* functions. Note that if the chip runs out of bytes (FIFO = 64 bytes long),
|
||||
* it will overwrite the first received frames, so quick retrieving of the
|
||||
* received data is desirable. */
|
||||
/** If the NFC device should only listen to frames, it could be useful to let
|
||||
* it gather multiple frames in a sequence. They will be stored in the internal
|
||||
* FIFO of the PN53X chip. This could be retrieved by using the receive data
|
||||
* functions. Note that if the chip runs out of bytes (FIFO = 64 bytes long),
|
||||
* it will overwrite the first received frames, so quick retrieving of the
|
||||
* received data is desirable. */
|
||||
NP_ACCEPT_MULTIPLE_FRAMES,
|
||||
/** This option can be used to enable or disable the auto-switching mode to
|
||||
* ISO14443-4 is device is compliant.
|
||||
* In initiator mode, it means that NFC chip will send RATS automatically when
|
||||
* select and it will automatically poll for ISO14443-4 card when ISO14443A is
|
||||
* requested.
|
||||
* In target mode, with a NFC chip compliant (ie. PN532), the chip will
|
||||
* emulate a 14443-4 PICC using hardware capability */
|
||||
/** This option can be used to enable or disable the auto-switching mode to
|
||||
* ISO14443-4 is device is compliant.
|
||||
* In initiator mode, it means that NFC chip will send RATS automatically when
|
||||
* select and it will automatically poll for ISO14443-4 card when ISO14443A is
|
||||
* requested.
|
||||
* In target mode, with a NFC chip compliant (ie. PN532), the chip will
|
||||
* emulate a 14443-4 PICC using hardware capability */
|
||||
NP_AUTO_ISO14443_4,
|
||||
/** Use automatic frames encapsulation and chaining. */
|
||||
/** Use automatic frames encapsulation and chaining. */
|
||||
NP_EASY_FRAMING,
|
||||
/** Force the chip to switch in ISO14443-A */
|
||||
/** Force the chip to switch in ISO14443-A */
|
||||
NP_FORCE_ISO14443_A,
|
||||
/** Force the chip to switch in ISO14443-B */
|
||||
/** Force the chip to switch in ISO14443-B */
|
||||
NP_FORCE_ISO14443_B,
|
||||
/** Force the chip to run at 106 kbps */
|
||||
/** Force the chip to run at 106 kbps */
|
||||
NP_FORCE_SPEED_106,
|
||||
} nfc_property;
|
||||
|
||||
|
|
@ -142,22 +142,22 @@ typedef enum {
|
|||
* @brief NFC target information in D.E.P. (Data Exchange Protocol) see ISO/IEC 18092 (NFCIP-1)
|
||||
*/
|
||||
typedef struct {
|
||||
/** NFCID3 */
|
||||
/** NFCID3 */
|
||||
uint8_t abtNFCID3[10];
|
||||
/** DID */
|
||||
/** DID */
|
||||
uint8_t btDID;
|
||||
/** Supported send-bit rate */
|
||||
/** Supported send-bit rate */
|
||||
uint8_t btBS;
|
||||
/** Supported receive-bit rate */
|
||||
/** Supported receive-bit rate */
|
||||
uint8_t btBR;
|
||||
/** Timeout value */
|
||||
/** Timeout value */
|
||||
uint8_t btTO;
|
||||
/** PP Parameters */
|
||||
/** PP Parameters */
|
||||
uint8_t btPP;
|
||||
/** General Bytes */
|
||||
/** General Bytes */
|
||||
uint8_t abtGB[48];
|
||||
size_t szGB;
|
||||
/** DEP mode */
|
||||
/** DEP mode */
|
||||
nfc_dep_mode ndm;
|
||||
} nfc_dep_info;
|
||||
|
||||
|
|
@ -191,13 +191,13 @@ typedef struct {
|
|||
* @brief NFC ISO14443B tag information
|
||||
*/
|
||||
typedef struct {
|
||||
/** abtPupi store PUPI contained in ATQB (Answer To reQuest of type B) (see ISO14443-3) */
|
||||
/** abtPupi store PUPI contained in ATQB (Answer To reQuest of type B) (see ISO14443-3) */
|
||||
uint8_t abtPupi[4];
|
||||
/** abtApplicationData store Application Data contained in ATQB (see ISO14443-3) */
|
||||
/** abtApplicationData store Application Data contained in ATQB (see ISO14443-3) */
|
||||
uint8_t abtApplicationData[4];
|
||||
/** abtProtocolInfo store Protocol Info contained in ATQB (see ISO14443-3) */
|
||||
/** abtProtocolInfo store Protocol Info contained in ATQB (see ISO14443-3) */
|
||||
uint8_t abtProtocolInfo[3];
|
||||
/** ui8CardIdentifier store CID (Card Identifier) attributted by PCD to the PICC */
|
||||
/** ui8CardIdentifier store CID (Card Identifier) attributted by PCD to the PICC */
|
||||
uint8_t ui8CardIdentifier;
|
||||
} nfc_iso14443b_info;
|
||||
|
||||
|
|
@ -206,13 +206,13 @@ typedef struct {
|
|||
* @brief NFC ISO14443B' tag information
|
||||
*/
|
||||
typedef struct {
|
||||
/** DIV: 4 LSBytes of tag serial number */
|
||||
/** DIV: 4 LSBytes of tag serial number */
|
||||
uint8_t abtDIV[4];
|
||||
/** Software version & type of REPGEN */
|
||||
/** Software version & type of REPGEN */
|
||||
uint8_t btVerLog;
|
||||
/** Config Byte, present if long REPGEN */
|
||||
/** Config Byte, present if long REPGEN */
|
||||
uint8_t btConfig;
|
||||
/** ATR, if any */
|
||||
/** ATR, if any */
|
||||
size_t szAtrLen;
|
||||
uint8_t abtAtr[33];
|
||||
} nfc_iso14443bi_info;
|
||||
|
|
|
|||
|
|
@ -34,27 +34,27 @@
|
|||
# include <stdbool.h>
|
||||
|
||||
# ifdef _WIN32
|
||||
/* Windows platform */
|
||||
/* Windows platform */
|
||||
# ifndef _WINDLL
|
||||
/* CMake compilation */
|
||||
/* CMake compilation */
|
||||
# ifdef nfc_EXPORTS
|
||||
# define NFC_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
/* nfc_EXPORTS */
|
||||
/* nfc_EXPORTS */
|
||||
# define NFC_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
/* nfc_EXPORTS */
|
||||
/* nfc_EXPORTS */
|
||||
# else
|
||||
/* _WINDLL */
|
||||
/* Manual makefile */
|
||||
/* _WINDLL */
|
||||
/* Manual makefile */
|
||||
# define NFC_EXPORT
|
||||
# endif
|
||||
/* _WINDLL */
|
||||
/* _WINDLL */
|
||||
# else
|
||||
/* _WIN32 */
|
||||
/* _WIN32 */
|
||||
# define NFC_EXPORT
|
||||
# endif
|
||||
/* _WIN32 */
|
||||
/* _WIN32 */
|
||||
|
||||
# include <nfc/nfc-types.h>
|
||||
|
||||
|
|
@ -62,11 +62,11 @@
|
|||
extern "C" {
|
||||
# endif // __cplusplus
|
||||
|
||||
/* Library initialization/deinitialization */
|
||||
/* Library initialization/deinitialization */
|
||||
NFC_EXPORT void nfc_init(nfc_context *context);
|
||||
NFC_EXPORT void nfc_exit(nfc_context *context);
|
||||
|
||||
/* NFC Device/Hardware manipulation */
|
||||
/* NFC Device/Hardware manipulation */
|
||||
NFC_EXPORT bool nfc_get_default_device (nfc_connstring *connstring);
|
||||
NFC_EXPORT nfc_device *nfc_open (nfc_context *context, const nfc_connstring connstring);
|
||||
NFC_EXPORT void nfc_close (nfc_device *pnd);
|
||||
|
|
@ -74,7 +74,7 @@ extern "C" {
|
|||
NFC_EXPORT size_t nfc_list_devices (nfc_context *context, nfc_connstring connstrings[], size_t connstrings_len);
|
||||
NFC_EXPORT int nfc_idle (nfc_device *pnd);
|
||||
|
||||
/* NFC initiator: act as "reader" */
|
||||
/* NFC initiator: act as "reader" */
|
||||
NFC_EXPORT int nfc_initiator_init (nfc_device *pnd);
|
||||
NFC_EXPORT int nfc_initiator_select_passive_target (nfc_device *pnd, const nfc_modulation nm, const uint8_t *pbtInitData, const size_t szInitData, nfc_target *pnt);
|
||||
NFC_EXPORT int nfc_initiator_list_passive_targets (nfc_device *pnd, const nfc_modulation nm, nfc_target ant[], const size_t szTargets);
|
||||
|
|
@ -88,30 +88,30 @@ extern "C" {
|
|||
NFC_EXPORT int nfc_initiator_transceive_bits_timed (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar, uint32_t *cycles);
|
||||
NFC_EXPORT int nfc_initiator_target_is_present (nfc_device *pnd, const nfc_target nt);
|
||||
|
||||
/* NFC target: act as tag (i.e. MIFARE Classic) or NFC target device. */
|
||||
/* NFC target: act as tag (i.e. MIFARE Classic) or NFC target device. */
|
||||
NFC_EXPORT int nfc_target_init (nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRx, int timeout);
|
||||
NFC_EXPORT int nfc_target_send_bytes (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int timeout);
|
||||
NFC_EXPORT int nfc_target_receive_bytes (nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, int timeout);
|
||||
NFC_EXPORT int nfc_target_send_bits (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar);
|
||||
NFC_EXPORT int nfc_target_receive_bits (nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar);
|
||||
|
||||
/* Error reporting */
|
||||
/* Error reporting */
|
||||
NFC_EXPORT const char *nfc_strerror (const nfc_device *pnd);
|
||||
NFC_EXPORT int nfc_strerror_r (const nfc_device *pnd, char *buf, size_t buflen);
|
||||
NFC_EXPORT void nfc_perror (const nfc_device *pnd, const char *s);
|
||||
NFC_EXPORT int nfc_device_get_last_error (const nfc_device *pnd);
|
||||
|
||||
/* Special data accessors */
|
||||
/* Special data accessors */
|
||||
NFC_EXPORT const char *nfc_device_get_name (nfc_device *pnd);
|
||||
NFC_EXPORT const char *nfc_device_get_connstring (nfc_device *pnd);
|
||||
NFC_EXPORT int nfc_device_get_supported_modulation (nfc_device *pnd, const nfc_mode mode, const nfc_modulation_type **const supported_mt);
|
||||
NFC_EXPORT int nfc_device_get_supported_baud_rate (nfc_device *pnd, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br);
|
||||
|
||||
/* Properties accessors */
|
||||
/* Properties accessors */
|
||||
NFC_EXPORT int nfc_device_set_property_int (nfc_device *pnd, const nfc_property property, const int value);
|
||||
NFC_EXPORT int nfc_device_set_property_bool (nfc_device *pnd, const nfc_property property, const bool bEnable);
|
||||
|
||||
/* Misc. functions */
|
||||
/* Misc. functions */
|
||||
NFC_EXPORT void iso14443a_crc (uint8_t *pbtData, size_t szLen, uint8_t *pbtCrc);
|
||||
NFC_EXPORT void iso14443a_crc_append (uint8_t *pbtData, size_t szLen);
|
||||
NFC_EXPORT uint8_t *iso14443a_locate_historical_bytes (uint8_t *pbtAts, size_t szAts, size_t *pszTk);
|
||||
|
|
@ -119,76 +119,76 @@ extern "C" {
|
|||
NFC_EXPORT const char *nfc_version (void);
|
||||
NFC_EXPORT int nfc_device_get_information_about (nfc_device *pnd, char *buf, size_t buflen);
|
||||
|
||||
/* String converter functions */
|
||||
/* String converter functions */
|
||||
NFC_EXPORT const char * str_nfc_modulation_type (const nfc_modulation_type nmt);
|
||||
NFC_EXPORT const char * str_nfc_baud_rate (const nfc_baud_rate nbr);
|
||||
|
||||
|
||||
/* Error codes */
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Success (no error)
|
||||
*/
|
||||
/* Error codes */
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Success (no error)
|
||||
*/
|
||||
#define NFC_SUCCESS 0
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Input / output error, device may not be usable anymore without re-open it
|
||||
*/
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Input / output error, device may not be usable anymore without re-open it
|
||||
*/
|
||||
#define NFC_EIO -1
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Invalid argument(s)
|
||||
*/
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Invalid argument(s)
|
||||
*/
|
||||
#define NFC_EINVARG -2
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Operation not supported by device
|
||||
*/
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Operation not supported by device
|
||||
*/
|
||||
#define NFC_EDEVNOTSUPP -3
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* No such device
|
||||
*/
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* No such device
|
||||
*/
|
||||
#define NFC_ENOTSUCHDEV -4
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Buffer overflow
|
||||
*/
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Buffer overflow
|
||||
*/
|
||||
#define NFC_EOVFLOW -5
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Operation timed out
|
||||
*/
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Operation timed out
|
||||
*/
|
||||
#define NFC_ETIMEOUT -6
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Operation aborted (by user)
|
||||
*/
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Operation aborted (by user)
|
||||
*/
|
||||
#define NFC_EOPABORTED -7
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Not (yet) implemented
|
||||
*/
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Not (yet) implemented
|
||||
*/
|
||||
#define NFC_ENOTIMPL -8
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Target released
|
||||
*/
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Target released
|
||||
*/
|
||||
#define NFC_ETGRELEASED -10
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Error while RF transmission
|
||||
*/
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Error while RF transmission
|
||||
*/
|
||||
#define NFC_ERFTRANS -20
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Software error (allocation, file/pipe creation, etc.)
|
||||
*/
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Software error (allocation, file/pipe creation, etc.)
|
||||
*/
|
||||
#define NFC_ESOFT -80
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Device's internal chip error
|
||||
*/
|
||||
/** @ingroup error
|
||||
* @hideinitializer
|
||||
* Device's internal chip error
|
||||
*/
|
||||
#define NFC_ECHIP -90
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue