From 2a9f876363e1f96bdfbb6673c7313c12ea239b3b Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Tue, 10 May 2011 19:13:08 +0000 Subject: [PATCH] Import BUFFER_* macros from libfreefare and use them in writeback cache --- libnfc/chips/pn53x.c | 26 +++++++------- libnfc/nfc-internal.h | 81 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 13 deletions(-) diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index 7ceed6d..705c3ff 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -509,8 +509,8 @@ bool pn53x_writeback_register (nfc_device_t * pnd) { // TODO Check at each step (ReadRegister, WriteRegister) if we didn't exceed max supported frame length - uint8_t abtCmd[PN53x_EXTENDED_FRAME__DATA_MAX_LEN] = { ReadRegister }; - size_t szCmd = 1; + BUFFER_INIT (abtReadRegisterCmd, PN53x_EXTENDED_FRAME__DATA_MAX_LEN); + BUFFER_APPEND (abtReadRegisterCmd, ReadRegister); // First step, it looks for registers to be readed before applying the requested mask CHIP_DATA (pnd)->wb_trigged = false; @@ -518,17 +518,17 @@ pn53x_writeback_register (nfc_device_t * pnd) if ((CHIP_DATA (pnd)->wb_mask[n]) && (CHIP_DATA (pnd)->wb_mask[n] != 0xff)) { // This register needs to be readed: mask is present but does not cover full data width (ie. mask != 0xff) const uint16_t pn53x_register_address = PN53X_CACHE_REGISTER_MIN_ADDRESS + n; - abtCmd[szCmd++] = pn53x_register_address >> 8; - abtCmd[szCmd++] = pn53x_register_address & 0xff; + BUFFER_APPEND (abtReadRegisterCmd, pn53x_register_address >> 8); + BUFFER_APPEND (abtReadRegisterCmd, pn53x_register_address & 0xff); } } - if (szCmd > 1) { + if (BUFFER_SIZE (abtReadRegisterCmd) > 1) { // It needs to read some registers uint8_t abtRes[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szRes = sizeof(abtRes); // It transceives the previously constructed ReadRegister command - if (!pn53x_transceive (pnd, abtCmd, szCmd, abtRes, &szRes)) { + if (!pn53x_transceive (pnd, abtReadRegisterCmd, BUFFER_SIZE (abtReadRegisterCmd), abtRes, &szRes)) { return false; } size_t i = 0; @@ -550,23 +550,23 @@ pn53x_writeback_register (nfc_device_t * pnd) } } // Now, the writeback-cache only has masks with 0xff, we can start to WriteRegister - szCmd = 1; - abtCmd[0] = WriteRegister; + BUFFER_INIT (abtWriteRegisterCmd, PN53x_EXTENDED_FRAME__DATA_MAX_LEN); + BUFFER_APPEND (abtWriteRegisterCmd, WriteRegister); for (size_t n = 0; n < PN53X_CACHE_REGISTER_SIZE; n++) { if (CHIP_DATA (pnd)->wb_mask[n] == 0xff) { const uint16_t pn53x_register_address = PN53X_CACHE_REGISTER_MIN_ADDRESS + n; - abtCmd[szCmd++] = pn53x_register_address >> 8; - abtCmd[szCmd++] = pn53x_register_address & 0xff; - abtCmd[szCmd++] = CHIP_DATA (pnd)->wb_data[n]; + BUFFER_APPEND (abtWriteRegisterCmd, pn53x_register_address >> 8); + BUFFER_APPEND (abtWriteRegisterCmd, pn53x_register_address & 0xff); + BUFFER_APPEND (abtWriteRegisterCmd, CHIP_DATA (pnd)->wb_data[n]); DBG ("WriteBackRegister will write (%04x, %02x)", pn53x_register_address, CHIP_DATA (pnd)->wb_data[n]); // This register is handled, we reset the mask to prevent CHIP_DATA (pnd)->wb_mask[n] = 0x00; } } - if (szCmd > 1) { + if (BUFFER_SIZE (abtWriteRegisterCmd) > 1) { // We need to write some registers - if (!pn53x_transceive (pnd, abtCmd, szCmd, NULL, NULL)) { + if (!pn53x_transceive (pnd, abtWriteRegisterCmd, BUFFER_SIZE (abtWriteRegisterCmd), NULL, NULL)) { return false; } } diff --git a/libnfc/nfc-internal.h b/libnfc/nfc-internal.h index e41bab8..58fb8fc 100644 --- a/libnfc/nfc-internal.h +++ b/libnfc/nfc-internal.h @@ -100,6 +100,87 @@ return false; \ } +/* + * Buffer management macros. + * + * The following macros ease setting-up and using buffers: + * BUFFER_INIT (data, 5); // data -> [ xx, xx, xx, xx, xx ] + * BUFFER_SIZE (data); // size -> 0 + * BUFFER_APPEND (data, 0x12); // data -> [ 12, xx, xx, xx, xx ] + * BUFFER_SIZE (data); // size -> 1 + * uint16_t x = 0x3456; // We suppose we are little endian + * BUFFER_APPEND_BYTES (data, x, 2); + * // data -> [ 12, 56, 34, xx, xx ] + * BUFFER_SIZE (data); // size -> 3 + * BUFFER_APPEND_LE (data, x, 2, sizeof (x)); + * // data -> [ 12, 56, 34, 34, 56 ] + * BUFFER_SIZE (data); // size -> 5 + */ + +/* + * Initialise a buffer named buffer_name of size bytes. + */ +#define BUFFER_INIT(buffer_name, size) \ + uint8_t buffer_name[size]; \ + size_t __##buffer_name##_n = 0 + +/* + * Create a wrapper for an existing buffer. + * BEWARE! It eats children! + */ +#define BUFFER_ALIAS(buffer_name, origin) \ + uint8_t *buffer_name = (void *)origin; \ + size_t __##buffer_name##_n = 0; + +#define BUFFER_SIZE(buffer_name) (__##buffer_name##_n) + +#define BUFFER_CLEAR(buffer_name) (__##buffer_name##_n = 0) +/* + * Append one byte of data to the buffer buffer_name. + */ +#define BUFFER_APPEND(buffer_name, data) \ + do { \ + buffer_name[__##buffer_name##_n++] = data; \ + } while (0) + +/* + * Append size bytes of data to the buffer buffer_name. + */ +#define BUFFER_APPEND_BYTES(buffer_name, data, size) \ + do { \ + size_t __n = 0; \ + while (__n < size) { \ + buffer_name[__##buffer_name##_n++] = ((uint8_t *)data)[__n++]; \ + } \ + } while (0) + +/* + * Append data_size bytes of data at the end of the buffer. Since data is + * copied as a little endian value, the storage size of the value has to be + * passed as the field_size parameter. + * + * Example: to copy 24 bits of data from a 32 bits value: + * BUFFER_APPEND_LE (buffer, data, 3, 4); + */ + +#if _BYTE_ORDER != _LITTLE_ENDIAN +#define BUFFER_APPEND_LE(buffer, data, data_size, field_size) \ + do { \ + size_t __data_size = data_size; \ + size_t __field_size = field_size; \ + while (__field_size--, __data_size--) { \ + buffer[__##buffer##_n++] = ((uint8_t *)&data)[__field_size]; \ + } \ + } while (0) +#else +#define BUFFER_APPEND_LE(buffer, data, data_size, field_size) \ + do { \ + memcpy (buffer + __##buffer##_n, &data, data_size); \ + __##buffer##_n += data_size; \ + } while (0) +#endif + + struct nfc_driver_t { const char *name; bool (*probe)(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);