Astyle formatting

pull/7822/head
Donatien Garnier 2018-08-21 15:19:51 +01:00
parent ce39e77f3d
commit 0e2484f7f3
74 changed files with 5018 additions and 5438 deletions

View File

@ -37,11 +37,10 @@ extern "C" {
#include "stddef.h"
#include "stdbool.h"
typedef struct __ac_buffer
{
const uint8_t* data;
size_t size;
struct __ac_buffer* pNext;
typedef struct __ac_buffer {
const uint8_t *data;
size_t size;
struct __ac_buffer *pNext;
} ac_buffer_t;
/** Initialize ac_buffer using underlying byte array, set ac_buffer's length to 0 (empty)
@ -49,66 +48,66 @@ typedef struct __ac_buffer
* \param data byte array to use
* \param size size of byte array
*/
void ac_buffer_init(ac_buffer_t* pBuf, const uint8_t* data, size_t size);
void ac_buffer_init(ac_buffer_t *pBuf, const uint8_t *data, size_t size);
/** Copy pBufIn to pBuf
* \param pBuf pointer to ac_buffer_t structure to initialize
* \param pBufIn the source buffer
*/
void ac_buffer_dup(ac_buffer_t* pBuf, const ac_buffer_t* pBufIn);
void ac_buffer_dup(ac_buffer_t *pBuf, const ac_buffer_t *pBufIn);
/** Get buffer's underlying byte array
* \param pBuf pointer to ac_buffer_t structure
* \return underlying array
*/
static inline const uint8_t* ac_buffer_data(const ac_buffer_t* pBuf)
static inline const uint8_t *ac_buffer_data(const ac_buffer_t *pBuf)
{
return pBuf->data;
return pBuf->data;
}
/** Get buffer's size
* \param pBuf pointer to ac_buffer_t structure
* \return buffer's size
*/
static inline size_t ac_buffer_size(const ac_buffer_t* pBuf)
static inline size_t ac_buffer_size(const ac_buffer_t *pBuf)
{
return pBuf->size;
return pBuf->size;
}
/** Get next buffer in chain
* \param pBuf pointer to ac_buffer_t structure
* \return pointer to next buffer
*/
static inline ac_buffer_t* ac_buffer_next(const ac_buffer_t* pBuf)
static inline ac_buffer_t *ac_buffer_next(const ac_buffer_t *pBuf)
{
return pBuf->pNext;
return pBuf->pNext;
}
/** Set next buffer in chain
* \param pBuf pointer to ac_buffer_t structure
* \param pNextBuf pointer to next buffer (or NULL to break chain)
*/
static inline void ac_buffer_set_next(ac_buffer_t* pBuf, ac_buffer_t* pNextBuf)
static inline void ac_buffer_set_next(ac_buffer_t *pBuf, ac_buffer_t *pNextBuf)
{
pBuf->pNext = (ac_buffer_t*) pNextBuf;
pBuf->pNext = (ac_buffer_t *) pNextBuf;
}
/** Append buffer to end of chain
* \param pBuf pointer to ac_buffer_t structure
* \param pAppBuf pointer to buffer to append to chain
*/
void ac_buffer_append(ac_buffer_t* pBuf, ac_buffer_t* pAppBuf);
void ac_buffer_append(ac_buffer_t *pBuf, ac_buffer_t *pAppBuf);
/** Truncate pBuf to length bytes and save the remaining bytes in pEndBuf
* \param pBuf The buffer to split (will be set to invalid state)
* \param pStartBuf A new buffer at the head of the split
* \param pEndBuf A new buffer at the tail of the split
* \param pEndBuf A new buffer at the tail of the split
* \param length How long pStartBuf should be (if longer than pBuf, then pStartBuf will be pBuf)
*/
void ac_buffer_split(ac_buffer_t* pStartBuf, ac_buffer_t* pEndBuf, ac_buffer_t* pBuf, size_t length);
void ac_buffer_split(ac_buffer_t *pStartBuf, ac_buffer_t *pEndBuf, ac_buffer_t *pBuf, size_t length);
//Debug
void ac_buffer_dump(ac_buffer_t* pBuf);
void ac_buffer_dump(ac_buffer_t *pBuf);
#ifdef __cplusplus
}

View File

@ -39,11 +39,10 @@ extern "C" {
#include "acore/buffer.h"
typedef struct __ac_buffer_builder
{
ac_buffer_t ac_buffer;
uint8_t* data;
size_t size;
typedef struct __ac_buffer_builder {
ac_buffer_t ac_buffer;
uint8_t *data;
size_t size;
} ac_buffer_builder_t;
/** Write data to big endian ac_buffer (on a LE architecture, byte order will be swapped)
@ -51,14 +50,14 @@ typedef struct __ac_buffer_builder
* \param buf pointer to data
* \param size the data size
*/
void ac_buffer_builder_write_be(ac_buffer_builder_t* pBuilder, const uint8_t* buf, size_t size);
void ac_buffer_builder_write_be(ac_buffer_builder_t *pBuilder, const uint8_t *buf, size_t size);
/** Write data to little endian ac_buffer (on a LE architecture, byte order will be preserved)
* \param pBuilder ac_buffer builder to use
* \param buf pointer to data
* \param size the data size
*/
void ac_buffer_builder_write_le(ac_buffer_builder_t* pBuilder, const uint8_t* buf, size_t size);
void ac_buffer_builder_write_le(ac_buffer_builder_t *pBuilder, const uint8_t *buf, size_t size);
/** Write data to big endian ac_buffer at specific position (on a LE architecture, byte order will be swapped)
* \param pBuilder ac_buffer builder to use
@ -66,7 +65,7 @@ void ac_buffer_builder_write_le(ac_buffer_builder_t* pBuilder, const uint8_t* bu
* \param buf pointer to data
* \param size the data size
*/
void ac_buffer_builder_write_be_at(ac_buffer_builder_t* pBuilder, size_t pos, const uint8_t* buf, size_t size);
void ac_buffer_builder_write_be_at(ac_buffer_builder_t *pBuilder, size_t pos, const uint8_t *buf, size_t size);
/** Write data to little endian ac_buffer at specific position (on a LE architecture, byte order will be preserved)
* \param pBuilder ac_buffer builder to use
@ -74,199 +73,190 @@ void ac_buffer_builder_write_be_at(ac_buffer_builder_t* pBuilder, size_t pos, co
* \param buf pointer to data
* \param size the data size
*/
void ac_buffer_builder_write_le_at(ac_buffer_builder_t* pBuilder, size_t pos, const uint8_t* buf, size_t size);
void ac_buffer_builder_write_le_at(ac_buffer_builder_t *pBuilder, size_t pos, const uint8_t *buf, size_t size);
/** Initialize ac_buffer builder
* \param pBuilder ac_buffer builder to init
* \param data pointer to byte array to use
* \param size of byte array
*/
void ac_buffer_builder_init(ac_buffer_builder_t* pBuilder, uint8_t* data, size_t size);
void ac_buffer_builder_init(ac_buffer_builder_t *pBuilder, uint8_t *data, size_t size);
/** Initialize ac_buffer builder from underlying ac_buffer
* \param pBuilder ac_buffer builder to init
*/
void ac_buffer_builder_from_ac_buffer(ac_buffer_builder_t* pBuilder);
void ac_buffer_builder_from_ac_buffer(ac_buffer_builder_t *pBuilder);
/** Reset ac_buffer builder
* \param pBuilder ac_buffer builder to reset
*/
void ac_buffer_builder_reset(ac_buffer_builder_t* pBuilder);
void ac_buffer_builder_reset(ac_buffer_builder_t *pBuilder);
/** Set ac_buffer builder's ac_buffer to full size
* \param pBuilder ac_buffer builder to set to full size
*/
void ac_buffer_builder_set_full(ac_buffer_builder_t* pBuilder);
void ac_buffer_builder_set_full(ac_buffer_builder_t *pBuilder);
/** Get ac_buffer builder's length
* \param pBuilder ac_buffer builder to get length of
* \return number of valid bytes in ac_buffer
*/
static inline size_t ac_buffer_builder_length(ac_buffer_builder_t* pBuilder)
static inline size_t ac_buffer_builder_length(ac_buffer_builder_t *pBuilder)
{
return ac_buffer_size(&pBuilder->ac_buffer);
return ac_buffer_size(&pBuilder->ac_buffer);
}
/** Set ac_buffer builder's length
* \param pBuilder ac_buffer builder to set length of
* \param length number of valid bytes in ac_buffer
*/
static inline void ac_buffer_builder_set_length(ac_buffer_builder_t* pBuilder, size_t length)
static inline void ac_buffer_builder_set_length(ac_buffer_builder_t *pBuilder, size_t length)
{
if( ac_buffer_data(&pBuilder->ac_buffer) + length > pBuilder->data + pBuilder->size )
{
return;
}
pBuilder->ac_buffer.size = length;
if (ac_buffer_data(&pBuilder->ac_buffer) + length > pBuilder->data + pBuilder->size) {
return;
}
pBuilder->ac_buffer.size = length;
}
/** Get ac_buffer builder's pointer to write position
* \param pBuilder ac_buffer builder
* \return pointer to write position
*/
static inline uint8_t* ac_buffer_builder_write_position(ac_buffer_builder_t* pBuilder)
static inline uint8_t *ac_buffer_builder_write_position(ac_buffer_builder_t *pBuilder)
{
return (uint8_t*)ac_buffer_data(&pBuilder->ac_buffer) + ac_buffer_size(&pBuilder->ac_buffer);
return (uint8_t *)ac_buffer_data(&pBuilder->ac_buffer) + ac_buffer_size(&pBuilder->ac_buffer);
}
/** Get ac_buffer builder's write offset
* \param pBuilder ac_buffer builder
* \return write offset
*/
static inline size_t ac_buffer_builder_write_offset(ac_buffer_builder_t* pBuilder)
static inline size_t ac_buffer_builder_write_offset(ac_buffer_builder_t *pBuilder)
{
return ac_buffer_data(&pBuilder->ac_buffer) + ac_buffer_size(&pBuilder->ac_buffer) - pBuilder->data;
return ac_buffer_data(&pBuilder->ac_buffer) + ac_buffer_size(&pBuilder->ac_buffer) - pBuilder->data;
}
/** Set ac_buffer builder's write offset
* \param pBuilder ac_buffer builder
* \param off new write offset
*/
static inline void ac_buffer_builder_set_write_offset(ac_buffer_builder_t* pBuilder, size_t off)
static inline void ac_buffer_builder_set_write_offset(ac_buffer_builder_t *pBuilder, size_t off)
{
if( off > pBuilder->size )
{
return;
}
if( pBuilder->data + off > pBuilder->ac_buffer.data )
{
pBuilder->ac_buffer.size = off - (pBuilder->ac_buffer.data - pBuilder->data);
}
else
{
pBuilder->ac_buffer.size = 0;
}
if (off > pBuilder->size) {
return;
}
if (pBuilder->data + off > pBuilder->ac_buffer.data) {
pBuilder->ac_buffer.size = off - (pBuilder->ac_buffer.data - pBuilder->data);
} else {
pBuilder->ac_buffer.size = 0;
}
}
/** Get ac_buffer builder's read offset
* \param pBuilder ac_buffer builder
* \return read offset
*/
static inline size_t ac_buffer_builder_read_offset(ac_buffer_builder_t* pBuilder)
static inline size_t ac_buffer_builder_read_offset(ac_buffer_builder_t *pBuilder)
{
return ac_buffer_data(&pBuilder->ac_buffer) - pBuilder->data;
return ac_buffer_data(&pBuilder->ac_buffer) - pBuilder->data;
}
/** Set ac_buffer builder's read offset
* \param pBuilder ac_buffer builder
* \param off new read offset
*/
static inline void ac_buffer_builder_set_read_offset(ac_buffer_builder_t* pBuilder, size_t off)
static inline void ac_buffer_builder_set_read_offset(ac_buffer_builder_t *pBuilder, size_t off)
{
if( off > pBuilder->size )
{
return;
}
if( pBuilder->data + off < pBuilder->ac_buffer.data + pBuilder->ac_buffer.size )
{
pBuilder->ac_buffer.size = pBuilder->ac_buffer.data - (pBuilder->data + off);
}
else
{
pBuilder->ac_buffer.size = 0;
}
pBuilder->ac_buffer.data = pBuilder->data + off;
if (off > pBuilder->size) {
return;
}
if (pBuilder->data + off < pBuilder->ac_buffer.data + pBuilder->ac_buffer.size) {
pBuilder->ac_buffer.size = pBuilder->ac_buffer.data - (pBuilder->data + off);
} else {
pBuilder->ac_buffer.size = 0;
}
pBuilder->ac_buffer.data = pBuilder->data + off;
}
/** Get ac_buffer builder's underlying ac_buffer
* \param pBuilder ac_buffer builder
* \return ac_buffer
*/
static inline ac_buffer_t* ac_buffer_builder_buffer(ac_buffer_builder_t* pBuilder)
static inline ac_buffer_t *ac_buffer_builder_buffer(ac_buffer_builder_t *pBuilder)
{
return &pBuilder->ac_buffer;
return &pBuilder->ac_buffer;
}
/** Get space in ac_buffer builder
* \param pBuilder ac_buffer builder
* \return number of free bytes in ac_buffer builder
*/
static inline size_t ac_buffer_builder_space(ac_buffer_builder_t* pBuilder)
static inline size_t ac_buffer_builder_space(ac_buffer_builder_t *pBuilder)
{
return pBuilder->size - (ac_buffer_data(&pBuilder->ac_buffer) - pBuilder->data + ac_buffer_size(&pBuilder->ac_buffer));
return pBuilder->size - (ac_buffer_data(&pBuilder->ac_buffer) - pBuilder->data + ac_buffer_size(&pBuilder->ac_buffer));
}
/** Is ac_buffer builder empty
* \param pBuilder ac_buffer builder
* \return true if ac_buffer builder is empty
*/
static inline bool ac_buffer_builder_empty(ac_buffer_builder_t* pBuilder)
static inline bool ac_buffer_builder_empty(ac_buffer_builder_t *pBuilder)
{
return (ac_buffer_builder_length(pBuilder) == 0);
return (ac_buffer_builder_length(pBuilder) == 0);
}
/** Is ac_buffer builder full
* \param pBuilder ac_buffer builder
* \return true if ac_buffer builder is full
*/
static inline bool ac_buffer_full(ac_buffer_builder_t* pBuilder)
static inline bool ac_buffer_full(ac_buffer_builder_t *pBuilder)
{
return (ac_buffer_builder_space(pBuilder) == 0);
return (ac_buffer_builder_space(pBuilder) == 0);
}
/** Write 8-bit value in ac_buffer builder
* \param pBuilder ac_buffer builder
* \param hu8 8-bit value to write
*/
static inline void ac_buffer_builder_write_nu8(ac_buffer_builder_t* pBuilder, uint8_t hu8)
static inline void ac_buffer_builder_write_nu8(ac_buffer_builder_t *pBuilder, uint8_t hu8)
{
ac_buffer_builder_write_be(pBuilder, &hu8, 1);
ac_buffer_builder_write_be(pBuilder, &hu8, 1);
}
/** Write 16-bit value in ac_buffer builder
* \param pBuilder ac_buffer builder
* \param hu16 16-bit value to write in big-endian format
*/
static inline void ac_buffer_builder_write_nu16(ac_buffer_builder_t* pBuilder, uint16_t hu16)
static inline void ac_buffer_builder_write_nu16(ac_buffer_builder_t *pBuilder, uint16_t hu16)
{
ac_buffer_builder_write_be(pBuilder, (uint8_t*)&hu16, 2);
ac_buffer_builder_write_be(pBuilder, (uint8_t *)&hu16, 2);
}
/** Write 24-bit value in ac_buffer builder
* \param pBuilder ac_buffer builder
* \param hu24 24-bit value to write in big-endian format
*/
static inline void ac_buffer_builder_write_nu24(ac_buffer_builder_t* pBuilder, uint32_t hu24)
static inline void ac_buffer_builder_write_nu24(ac_buffer_builder_t *pBuilder, uint32_t hu24)
{
ac_buffer_builder_write_be(pBuilder, (uint8_t*)&hu24, 3);
ac_buffer_builder_write_be(pBuilder, (uint8_t *)&hu24, 3);
}
/** Write 32-bit value in ac_buffer builder
* \param pBuilder ac_buffer builder
* \param hu32 32-bit value to write in big-endian format
*/
static inline void ac_buffer_builder_write_nu32(ac_buffer_builder_t* pBuilder, uint32_t hu32)
static inline void ac_buffer_builder_write_nu32(ac_buffer_builder_t *pBuilder, uint32_t hu32)
{
ac_buffer_builder_write_be(pBuilder, (uint8_t*)&hu32, 4);
ac_buffer_builder_write_be(pBuilder, (uint8_t *)&hu32, 4);
}
/** Write 64-bit value in ac_buffer builder
* \param pBuilder ac_buffer builder
* \param hu64 64-bit value to write in big-endian format
*/
static inline void ac_buffer_builder_write_nu64(ac_buffer_builder_t* pBuilder, uint64_t hu64)
static inline void ac_buffer_builder_write_nu64(ac_buffer_builder_t *pBuilder, uint64_t hu64)
{
ac_buffer_builder_write_be(pBuilder, (uint8_t*)&hu64, 8);
ac_buffer_builder_write_be(pBuilder, (uint8_t *)&hu64, 8);
}
/** Write n-bytes value in ac_buffer builder
@ -274,9 +264,9 @@ static inline void ac_buffer_builder_write_nu64(ac_buffer_builder_t* pBuilder, u
* \param data data to write
* \param size data length
*/
static inline void ac_buffer_builder_write_n_bytes(ac_buffer_builder_t* pBuilder, const uint8_t* data, size_t size)
static inline void ac_buffer_builder_write_n_bytes(ac_buffer_builder_t *pBuilder, const uint8_t *data, size_t size)
{
ac_buffer_builder_write_le(pBuilder, data, size);
ac_buffer_builder_write_le(pBuilder, data, size);
}
/** Write 8-bit value in ac_buffer builder at specified position
@ -284,9 +274,9 @@ static inline void ac_buffer_builder_write_n_bytes(ac_buffer_builder_t* pBuilder
* \param off offset at which to write
* \param hu8 8-bit value to write
*/
static inline void ac_buffer_builder_write_nu8_at(ac_buffer_builder_t* pBuilder, size_t off, uint8_t hu8)
static inline void ac_buffer_builder_write_nu8_at(ac_buffer_builder_t *pBuilder, size_t off, uint8_t hu8)
{
ac_buffer_builder_write_be_at(pBuilder, off, &hu8, 1);
ac_buffer_builder_write_be_at(pBuilder, off, &hu8, 1);
}
/** Write 16-bit value in ac_buffer builder at specified position
@ -294,9 +284,9 @@ static inline void ac_buffer_builder_write_nu8_at(ac_buffer_builder_t* pBuilder,
* \param off offset at which to write
* \param hu16 16-bit value to write
*/
static inline void ac_buffer_builder_write_nu16_at(ac_buffer_builder_t* pBuilder, size_t off, uint16_t hu16)
static inline void ac_buffer_builder_write_nu16_at(ac_buffer_builder_t *pBuilder, size_t off, uint16_t hu16)
{
ac_buffer_builder_write_be_at(pBuilder, off, (uint8_t*)&hu16, 2);
ac_buffer_builder_write_be_at(pBuilder, off, (uint8_t *)&hu16, 2);
}
/** Write 24-bit value in ac_buffer builder at specified position
@ -304,9 +294,9 @@ static inline void ac_buffer_builder_write_nu16_at(ac_buffer_builder_t* pBuilder
* \param off offset at which to write
* \param hu24 24-bit value to write
*/
static inline void ac_buffer_builder_write_nu24_at(ac_buffer_builder_t* pBuilder, size_t off, uint32_t hu24)
static inline void ac_buffer_builder_write_nu24_at(ac_buffer_builder_t *pBuilder, size_t off, uint32_t hu24)
{
ac_buffer_builder_write_be_at(pBuilder, off, (uint8_t*)&hu24, 3);
ac_buffer_builder_write_be_at(pBuilder, off, (uint8_t *)&hu24, 3);
}
/** Write 32-bit value in ac_buffer builder at specified position
@ -314,9 +304,9 @@ static inline void ac_buffer_builder_write_nu24_at(ac_buffer_builder_t* pBuilder
* \param off offset at which to write
* \param hu32 32-bit value to write
*/
static inline void ac_buffer_builder_write_nu32_at(ac_buffer_builder_t* pBuilder, size_t off, uint32_t hu32)
static inline void ac_buffer_builder_write_nu32_at(ac_buffer_builder_t *pBuilder, size_t off, uint32_t hu32)
{
ac_buffer_builder_write_be_at(pBuilder, off, (uint8_t*)&hu32, 4);
ac_buffer_builder_write_be_at(pBuilder, off, (uint8_t *)&hu32, 4);
}
/** Write 64-bit value in ac_buffer builder at specified position
@ -324,9 +314,9 @@ static inline void ac_buffer_builder_write_nu32_at(ac_buffer_builder_t* pBuilder
* \param off offset at which to write
* \param hu64 64-bit value to write
*/
static inline void ac_buffer_builder_write_nu64_at(ac_buffer_builder_t* pBuilder, size_t off, uint64_t hu64)
static inline void ac_buffer_builder_write_nu64_at(ac_buffer_builder_t *pBuilder, size_t off, uint64_t hu64)
{
ac_buffer_builder_write_be_at(pBuilder, off, (uint8_t*)&hu64, 8);
ac_buffer_builder_write_be_at(pBuilder, off, (uint8_t *)&hu64, 8);
}
/** Write n-bytes value in ac_buffer builder at specified position
@ -335,37 +325,37 @@ static inline void ac_buffer_builder_write_nu64_at(ac_buffer_builder_t* pBuilder
* \param data data to write
* \param size data length
*/
static inline void ac_buffer_builder_write_n_bytes_at(ac_buffer_builder_t* pBuilder, size_t off, const uint8_t* data, size_t size)
static inline void ac_buffer_builder_write_n_bytes_at(ac_buffer_builder_t *pBuilder, size_t off, const uint8_t *data, size_t size)
{
ac_buffer_builder_write_be_at(pBuilder, off, data, size);
ac_buffer_builder_write_be_at(pBuilder, off, data, size);
}
/** Skip n-bytes in ac_buffer builder
* \param pBuilder ac_buffer builder
* \param size number of bytes to skip
*/
void ac_buffer_builder_write_n_skip(ac_buffer_builder_t* pBuilder, size_t size);
void ac_buffer_builder_write_n_skip(ac_buffer_builder_t *pBuilder, size_t size);
/** Copy n bytes from buffer to builder
* \param pBuilderOut ac_buffer builder
* \param pBufIn the input buffer
* \param size number of bytes to copy
*/
void ac_buffer_builder_copy_n_bytes(ac_buffer_builder_t* pBuilderOut, ac_buffer_t* pBufIn, size_t size);
void ac_buffer_builder_copy_n_bytes(ac_buffer_builder_t *pBuilderOut, ac_buffer_t *pBufIn, size_t size);
/** Compact builder
* Will move underlying buffer's byte to start of allocated buffer
* \param pBuilder ac_buffer builder
*/
void ac_buffer_builder_compact(ac_buffer_builder_t* pBuilder);
void ac_buffer_builder_compact(ac_buffer_builder_t *pBuilder);
/** Get number of writable bytes in ac_buffer builder
* \param pBuilder ac_buffer builder
* \return number of free bytes in ac_buffer builder
*/
static inline size_t ac_buffer_builder_writable(ac_buffer_builder_t* pBuilder)
static inline size_t ac_buffer_builder_writable(ac_buffer_builder_t *pBuilder)
{
return ac_buffer_builder_space(pBuilder);
return ac_buffer_builder_space(pBuilder);
}
#ifdef __cplusplus

View File

@ -44,68 +44,68 @@ extern "C" {
* \param buf the array to write to
* \param size the number of bytes to read
*/
void ac_buffer_read_be(ac_buffer_t* pBuf, uint8_t* buf, size_t size);
void ac_buffer_read_be(ac_buffer_t *pBuf, uint8_t *buf, size_t size);
/** Read n-bytes in little-endian format from buffer reader and advance read posiion
* \param pBuf the buffer to read from
* \param buf the array to write to
* \param size the number of bytes to read
*/
void ac_buffer_read_le(ac_buffer_t* pBuf, uint8_t* buf, size_t size);
void ac_buffer_read_le(ac_buffer_t *pBuf, uint8_t *buf, size_t size);
/** Read 8-bit value from buffer reader and advance read posiion
* \param pBuf the buffer to read from
* \return 8-bit value read
*/
static inline uint8_t ac_buffer_read_nu8(ac_buffer_t* pBuf)
static inline uint8_t ac_buffer_read_nu8(ac_buffer_t *pBuf)
{
uint8_t hu8;
ac_buffer_read_be(pBuf, &hu8, 1);
return hu8;
uint8_t hu8;
ac_buffer_read_be(pBuf, &hu8, 1);
return hu8;
}
/** Read BE 16-bit value from buffer reader and advance read posiion
* \param pBuf the buffer to read from
* \return 16-bit value read
*/
static inline uint16_t ac_buffer_read_nu16(ac_buffer_t* pBuf)
static inline uint16_t ac_buffer_read_nu16(ac_buffer_t *pBuf)
{
uint16_t hu16;
ac_buffer_read_be(pBuf, (uint8_t*)&hu16, 2);
return hu16;
uint16_t hu16;
ac_buffer_read_be(pBuf, (uint8_t *)&hu16, 2);
return hu16;
}
/** Read BE 24-bit value from buffer reader and advance read posiion
* \param pBuf the buffer to read from
* \return 24-bit value read
*/
static inline uint32_t ac_buffer_read_nu24(ac_buffer_t* pBuf)
static inline uint32_t ac_buffer_read_nu24(ac_buffer_t *pBuf)
{
uint32_t hu24;
ac_buffer_read_be(pBuf, (uint8_t*)&hu24, 3);
return hu24;
uint32_t hu24;
ac_buffer_read_be(pBuf, (uint8_t *)&hu24, 3);
return hu24;
}
/** Read BE 32-bit value from buffer reader and advance read posiion
* \param pBuf the buffer to read from
* \return 32-bit value read
*/
static inline uint32_t ac_buffer_read_nu32(ac_buffer_t* pBuf)
static inline uint32_t ac_buffer_read_nu32(ac_buffer_t *pBuf)
{
uint32_t hu32;
ac_buffer_read_be(pBuf, (uint8_t*)&hu32, 4);
return hu32;
uint32_t hu32;
ac_buffer_read_be(pBuf, (uint8_t *)&hu32, 4);
return hu32;
}
/** Read BE 64-bit value from buffer reader and advance read posiion
* \param pBuf the buffer to read from
* \return 64-bit value read
*/
static inline uint64_t ac_buffer_read_nu64(ac_buffer_t* pBuf)
static inline uint64_t ac_buffer_read_nu64(ac_buffer_t *pBuf)
{
uint64_t hu64;
ac_buffer_read_be(pBuf, (uint8_t*)&hu64, 8);
return hu64;
uint64_t hu64;
ac_buffer_read_be(pBuf, (uint8_t *)&hu64, 8);
return hu64;
}
/** Read n bytes from buffer reader and advance read posiion
@ -113,34 +113,34 @@ static inline uint64_t ac_buffer_read_nu64(ac_buffer_t* pBuf)
* \param data the array to write bytes to
* \param size the number of bytes to read
*/
static inline void ac_buffer_read_n_bytes(ac_buffer_t* pBuf, uint8_t* data, size_t size)
static inline void ac_buffer_read_n_bytes(ac_buffer_t *pBuf, uint8_t *data, size_t size)
{
ac_buffer_read_le(pBuf, data, size);
ac_buffer_read_le(pBuf, data, size);
}
/** Skip n bytes from buffer reader and advance read posiion
* \param pBuf the buffer to read from
* \param size the number of bytes to skip
*/
void ac_buffer_read_n_skip(ac_buffer_t* pBuf, size_t size);
void ac_buffer_read_n_skip(ac_buffer_t *pBuf, size_t size);
/** Get number of bytes readable from buffer
* \param pBuf the buffer to read from
* \return The number of bytes which can be read
*/
size_t ac_buffer_reader_readable(const ac_buffer_t* pBuf);
size_t ac_buffer_reader_readable(const ac_buffer_t *pBuf);
/** Get a pointer to the current position within this buffer's current backing array
* \param pBuf the buffer to read from
* \return A pointer to the current position within the current backing array
*/
const uint8_t* ac_buffer_reader_current_buffer_pointer(ac_buffer_t* pBuf);
const uint8_t *ac_buffer_reader_current_buffer_pointer(ac_buffer_t *pBuf);
/** Get the number of bytes readable within the current backing array
* \param pBuf the buffer to read from
* \return The number of bytes readable within the current backing array
*/
size_t ac_buffer_reader_current_buffer_length(ac_buffer_t* pBuf);
size_t ac_buffer_reader_current_buffer_length(ac_buffer_t *pBuf);
/** Compare buffer with array (does not advance read position)
* \param pBuf the buffer to compare from
@ -148,14 +148,14 @@ size_t ac_buffer_reader_current_buffer_length(ac_buffer_t* pBuf);
* \param length the array length
* \return Whether the buffer is AT LEAST as long as the array AND the buffer and array have the same content
*/
bool ac_buffer_reader_cmp_bytes(const ac_buffer_t* pBuf, const uint8_t* bytes, size_t length);
bool ac_buffer_reader_cmp_bytes(const ac_buffer_t *pBuf, const uint8_t *bytes, size_t length);
/** Compare buffer with array (does not advance read position)
* \param pBuf1 the buffer to compare from
* \param pBuf2 the buffer to compare with
* \return Whether the buffers have the same length and content
*/
bool ac_buffer_reader_cmp(const ac_buffer_t* pBuf1, const ac_buffer_t* pBuf2);
bool ac_buffer_reader_cmp(const ac_buffer_t *pBuf1, const ac_buffer_t *pBuf2);
#ifdef __cplusplus
}

View File

@ -39,32 +39,30 @@ typedef struct __ac_ostream ac_ostream_t;
#include "acore/buffer.h"
typedef void (*ac_istream_fn)(ac_buffer_t* pDataIn, bool* pClose, size_t maxLength, void* pUserParam);
typedef void (*ac_ostream_fn)(ac_buffer_t* pDataOut, bool closed, void* pUserParam);
typedef void (*ac_istream_fn)(ac_buffer_t *pDataIn, bool *pClose, size_t maxLength, void *pUserParam);
typedef void (*ac_ostream_fn)(ac_buffer_t *pDataOut, bool closed, void *pUserParam);
//Input stream -- pulled by consumer
struct __ac_istream
{
ac_istream_fn fn;
void* pUserParam;
struct __ac_istream {
ac_istream_fn fn;
void *pUserParam;
};
//Output stream -- pushed by supplier
struct __ac_ostream
{
ac_ostream_fn fn;
void* pUserParam;
struct __ac_ostream {
ac_ostream_fn fn;
void *pUserParam;
};
//Called by supplier
void ac_istream_init(ac_istream_t* pac_istream, ac_istream_fn fn, void* pUserParam);
void ac_istream_init(ac_istream_t *pac_istream, ac_istream_fn fn, void *pUserParam);
//Called by consumer
void ac_istream_pull(ac_istream_t* pac_istream, ac_buffer_t* pDataIn, bool* pClose, size_t maxLength);
void ac_istream_pull(ac_istream_t *pac_istream, ac_buffer_t *pDataIn, bool *pClose, size_t maxLength);
//Called by consumer
void ac_ostream_init(ac_ostream_t* pac_ostream, ac_ostream_fn fn, void* pUserParam);
void ac_ostream_init(ac_ostream_t *pac_ostream, ac_ostream_fn fn, void *pUserParam);
//Called by supplier
void ac_ostream_push(ac_ostream_t* pac_ostream, ac_buffer_t* pDataOut, bool closed);
void ac_ostream_push(ac_ostream_t *pac_ostream, ac_buffer_t *pDataOut, bool closed);
#ifdef __cplusplus
}

View File

@ -29,77 +29,70 @@
#include "acore/debug.h"
void ac_buffer_init(ac_buffer_t* pBuf, const uint8_t* data, size_t size)
void ac_buffer_init(ac_buffer_t *pBuf, const uint8_t *data, size_t size)
{
pBuf->data = data;
pBuf->size = size;
pBuf->data = data;
pBuf->size = size;
pBuf->pNext = NULL;
pBuf->pNext = NULL;
}
void ac_buffer_dup(ac_buffer_t* pBuf, const ac_buffer_t* pBufIn)
void ac_buffer_dup(ac_buffer_t *pBuf, const ac_buffer_t *pBufIn)
{
if(pBuf != pBufIn)
{
memcpy(pBuf, pBufIn, sizeof(ac_buffer_t));
}
if (pBuf != pBufIn) {
memcpy(pBuf, pBufIn, sizeof(ac_buffer_t));
}
}
void ac_buffer_append(ac_buffer_t* pBuf, ac_buffer_t* pAppBuf)
void ac_buffer_append(ac_buffer_t *pBuf, ac_buffer_t *pAppBuf)
{
while(pBuf->pNext != NULL)
{
pBuf = pBuf->pNext;
}
pBuf->pNext = pAppBuf;
while (pBuf->pNext != NULL) {
pBuf = pBuf->pNext;
}
pBuf->pNext = pAppBuf;
}
void ac_buffer_split(ac_buffer_t* pStartBuf, ac_buffer_t* pEndBuf, ac_buffer_t* pBuf, size_t length)
void ac_buffer_split(ac_buffer_t *pStartBuf, ac_buffer_t *pEndBuf, ac_buffer_t *pBuf, size_t length)
{
ac_buffer_dup(pStartBuf, pBuf);
ac_buffer_dup(pEndBuf, pBuf);
ac_buffer_dup(pStartBuf, pBuf);
ac_buffer_dup(pEndBuf, pBuf);
ac_buffer_read_n_skip(pEndBuf, length);
ac_buffer_read_n_skip(pEndBuf, length);
while( length > ac_buffer_size(pStartBuf) )
{
length -= pStartBuf->size;
pStartBuf = pStartBuf->pNext;
}
while (length > ac_buffer_size(pStartBuf)) {
length -= pStartBuf->size;
pStartBuf = pStartBuf->pNext;
}
pStartBuf->size = length;
pStartBuf->pNext = NULL;
pStartBuf->size = length;
pStartBuf->pNext = NULL;
}
/** Dump a ac_buffer's content to stdout (useful for debugging)
* \param pBuf pointer to ac_buffer_t structure
*/
void ac_buffer_dump(ac_buffer_t* pBuf)
void ac_buffer_dump(ac_buffer_t *pBuf)
{
#if !defined(NDEBUG)
ACORE_STDIO_LOCK();
while(pBuf != NULL)
{
size_t r = ac_buffer_size(pBuf);
size_t i = 0;
size_t j = 0;
while(i < r)
{
for(j = i; j < MIN(i + 16, r); j++)
{
ACORE_STDIO_PRINT("%02x ", ac_buffer_data(pBuf)[j]);
}
ACORE_STDIO_PRINT("\r\n");
i = j;
ACORE_STDIO_LOCK();
while (pBuf != NULL) {
size_t r = ac_buffer_size(pBuf);
size_t i = 0;
size_t j = 0;
while (i < r) {
for (j = i; j < MIN(i + 16, r); j++) {
ACORE_STDIO_PRINT("%02x ", ac_buffer_data(pBuf)[j]);
}
ACORE_STDIO_PRINT("\r\n");
i = j;
}
pBuf = ac_buffer_next(pBuf);
if (pBuf != NULL) {
ACORE_STDIO_PRINT("->\r\n");
}
}
pBuf = ac_buffer_next(pBuf);
if(pBuf != NULL)
{
ACORE_STDIO_PRINT("->\r\n");
}
}
ACORE_STDIO_UNLOCK();
ACORE_STDIO_UNLOCK();
#else
(void)pBuf;
(void)pBuf;
#endif
}

View File

@ -29,91 +29,88 @@
#define VOID
#define ENSURE_WRITE_LENGTH(pBuilder, n) do{ if( ac_buffer_builder_space(pBuilder) < n ) { return; } }while(0);
void ac_buffer_builder_init(ac_buffer_builder_t* pBuilder, uint8_t* data, size_t size)
void ac_buffer_builder_init(ac_buffer_builder_t *pBuilder, uint8_t *data, size_t size)
{
pBuilder->data = data;
pBuilder->size = size;
ac_buffer_init(&pBuilder->ac_buffer, data, 0);
pBuilder->data = data;
pBuilder->size = size;
ac_buffer_init(&pBuilder->ac_buffer, data, 0);
}
void ac_buffer_builder_from_ac_buffer(ac_buffer_builder_t* pBuilder)
void ac_buffer_builder_from_ac_buffer(ac_buffer_builder_t *pBuilder)
{
pBuilder->data = (uint8_t*)pBuilder->ac_buffer.data;
pBuilder->size = pBuilder->ac_buffer.size;
pBuilder->ac_buffer.size = 0;
pBuilder->data = (uint8_t *)pBuilder->ac_buffer.data;
pBuilder->size = pBuilder->ac_buffer.size;
pBuilder->ac_buffer.size = 0;
}
void ac_buffer_builder_reset(ac_buffer_builder_t* pBuilder)
void ac_buffer_builder_reset(ac_buffer_builder_t *pBuilder)
{
ac_buffer_init(&pBuilder->ac_buffer, pBuilder->data, 0);
ac_buffer_init(&pBuilder->ac_buffer, pBuilder->data, 0);
}
void ac_buffer_builder_set_full(ac_buffer_builder_t* pBuilder)
void ac_buffer_builder_set_full(ac_buffer_builder_t *pBuilder)
{
ac_buffer_init(&pBuilder->ac_buffer, pBuilder->data, pBuilder->size);
ac_buffer_init(&pBuilder->ac_buffer, pBuilder->data, pBuilder->size);
}
void ac_buffer_builder_write_be(ac_buffer_builder_t* pBuilder, const uint8_t* buf, size_t size)
void ac_buffer_builder_write_be(ac_buffer_builder_t *pBuilder, const uint8_t *buf, size_t size)
{
ENSURE_WRITE_LENGTH(pBuilder, size);
buf += size;
while(size > 0)
{
buf--;
*ac_buffer_builder_write_position(pBuilder) = *buf;
pBuilder->ac_buffer.size++;
size--;
}
ENSURE_WRITE_LENGTH(pBuilder, size);
buf += size;
while (size > 0) {
buf--;
*ac_buffer_builder_write_position(pBuilder) = *buf;
pBuilder->ac_buffer.size++;
size--;
}
}
void ac_buffer_builder_write_le(ac_buffer_builder_t* pBuilder, const uint8_t* buf, size_t size)
void ac_buffer_builder_write_le(ac_buffer_builder_t *pBuilder, const uint8_t *buf, size_t size)
{
ENSURE_WRITE_LENGTH(pBuilder, size);
memcpy(ac_buffer_builder_write_position(pBuilder), buf, size);
pBuilder->ac_buffer.size+=size;
ENSURE_WRITE_LENGTH(pBuilder, size);
memcpy(ac_buffer_builder_write_position(pBuilder), buf, size);
pBuilder->ac_buffer.size += size;
}
void ac_buffer_builder_write_be_at(ac_buffer_builder_t* pBuilder, size_t pos, const uint8_t* buf, size_t size)
void ac_buffer_builder_write_be_at(ac_buffer_builder_t *pBuilder, size_t pos, const uint8_t *buf, size_t size)
{
size_t currentPos = pBuilder->ac_buffer.size;
pBuilder->ac_buffer.size = pos;
ac_buffer_builder_write_be(pBuilder, buf, size);
pBuilder->ac_buffer.size = currentPos;
size_t currentPos = pBuilder->ac_buffer.size;
pBuilder->ac_buffer.size = pos;
ac_buffer_builder_write_be(pBuilder, buf, size);
pBuilder->ac_buffer.size = currentPos;
}
void ac_buffer_builder_write_le_at(ac_buffer_builder_t* pBuilder, size_t pos, const uint8_t* buf, size_t size)
void ac_buffer_builder_write_le_at(ac_buffer_builder_t *pBuilder, size_t pos, const uint8_t *buf, size_t size)
{
size_t currentPos = pBuilder->ac_buffer.size;
pBuilder->ac_buffer.size = pos;
ac_buffer_builder_write_le(pBuilder, buf, size);
pBuilder->ac_buffer.size = currentPos;
size_t currentPos = pBuilder->ac_buffer.size;
pBuilder->ac_buffer.size = pos;
ac_buffer_builder_write_le(pBuilder, buf, size);
pBuilder->ac_buffer.size = currentPos;
}
void ac_buffer_builder_write_n_skip(ac_buffer_builder_t* pBuilder, size_t size)
void ac_buffer_builder_write_n_skip(ac_buffer_builder_t *pBuilder, size_t size)
{
ENSURE_WRITE_LENGTH(pBuilder, size);
pBuilder->ac_buffer.size += size;
ENSURE_WRITE_LENGTH(pBuilder, size);
pBuilder->ac_buffer.size += size;
}
void ac_buffer_builder_copy_n_bytes(ac_buffer_builder_t* pBuilderOut, ac_buffer_t* pBufIn, size_t size)
void ac_buffer_builder_copy_n_bytes(ac_buffer_builder_t *pBuilderOut, ac_buffer_t *pBufIn, size_t size)
{
ENSURE_WRITE_LENGTH(pBuilderOut, size);
if( ac_buffer_reader_readable(pBufIn) < size )
{
return;
}
while(size > 0)
{
size_t cpy = ac_buffer_reader_current_buffer_length(pBufIn);
cpy = MIN(cpy, size);
ac_buffer_builder_write_n_bytes(pBuilderOut, ac_buffer_reader_current_buffer_pointer(pBufIn), cpy);
ac_buffer_read_n_skip(pBufIn, cpy);
size -= cpy;
}
ENSURE_WRITE_LENGTH(pBuilderOut, size);
if (ac_buffer_reader_readable(pBufIn) < size) {
return;
}
while (size > 0) {
size_t cpy = ac_buffer_reader_current_buffer_length(pBufIn);
cpy = MIN(cpy, size);
ac_buffer_builder_write_n_bytes(pBuilderOut, ac_buffer_reader_current_buffer_pointer(pBufIn), cpy);
ac_buffer_read_n_skip(pBufIn, cpy);
size -= cpy;
}
}
void ac_buffer_builder_compact(ac_buffer_builder_t* pBuilder)
void ac_buffer_builder_compact(ac_buffer_builder_t *pBuilder)
{
memmove(pBuilder->data, ac_buffer_data(&pBuilder->ac_buffer), ac_buffer_size(&pBuilder->ac_buffer));
pBuilder->ac_buffer.data = pBuilder->data;
memmove(pBuilder->data, ac_buffer_data(&pBuilder->ac_buffer), ac_buffer_size(&pBuilder->ac_buffer));
pBuilder->ac_buffer.data = pBuilder->data;
}

View File

@ -28,156 +28,139 @@
#define VOID
#define ENSURE_READ_LENGTH(pBuf, n) do{ if( ac_buffer_reader_readable(pBuf) < n ) { return; } }while(0);
static inline void update_buf(ac_buffer_t* pBuf)
static inline void update_buf(ac_buffer_t *pBuf)
{
while( ac_buffer_size(pBuf) == 0 )
{
if( ac_buffer_next(pBuf) != NULL )
{
ac_buffer_t* pNext = ac_buffer_next(pBuf);
ac_buffer_init(pBuf, ac_buffer_data(pNext), ac_buffer_size(pNext));
pBuf->pNext = ac_buffer_next(pNext);
while (ac_buffer_size(pBuf) == 0) {
if (ac_buffer_next(pBuf) != NULL) {
ac_buffer_t *pNext = ac_buffer_next(pBuf);
ac_buffer_init(pBuf, ac_buffer_data(pNext), ac_buffer_size(pNext));
pBuf->pNext = ac_buffer_next(pNext);
} else if (pBuf->data != NULL) {
ac_buffer_init(pBuf, NULL, 0);
} else {
return;
}
}
else if( pBuf->data != NULL )
{
ac_buffer_init(pBuf, NULL, 0);
}
else
{
return;
}
}
}
void ac_buffer_read_be(ac_buffer_t* pBuf, uint8_t* buf, size_t size)
void ac_buffer_read_be(ac_buffer_t *pBuf, uint8_t *buf, size_t size)
{
ENSURE_READ_LENGTH(pBuf, size);
buf += size;
while (size > 0) {
buf--;
*buf = *ac_buffer_data(pBuf);
pBuf->data++;
pBuf->size--;
update_buf(pBuf);
size--;
}
}
void ac_buffer_read_le(ac_buffer_t *pBuf, uint8_t *buf, size_t size)
{
ENSURE_READ_LENGTH(pBuf, size);
while (size > 0) {
size_t cpy = ac_buffer_size(pBuf);
cpy = MIN(cpy, size);
memcpy(buf, ac_buffer_data(pBuf), cpy);
pBuf->data += cpy;
pBuf->size -= cpy;
update_buf(pBuf);
size -= cpy;
buf += cpy;
}
}
void ac_buffer_read_n_skip(ac_buffer_t *pBuf, size_t size)
{
ENSURE_READ_LENGTH(pBuf, size);
while (size > 0) {
size_t cpy = ac_buffer_size(pBuf);
cpy = MIN(cpy, size);
pBuf->data += cpy;
pBuf->size -= cpy;
update_buf(pBuf);
size -= cpy;
}
}
size_t ac_buffer_reader_readable(const ac_buffer_t *pBuf)
{
size_t r = 0;
while (pBuf != NULL) {
r += ac_buffer_size(pBuf);
pBuf = ac_buffer_next(pBuf);
}
return r;
}
const uint8_t *ac_buffer_reader_current_buffer_pointer(ac_buffer_t *pBuf)
{
ENSURE_READ_LENGTH(pBuf, size);
buf += size;
while(size > 0)
{
buf--;
*buf = *ac_buffer_data(pBuf);
pBuf->data++;
pBuf->size--;
update_buf(pBuf);
size--;
}
return ac_buffer_data(pBuf);
}
void ac_buffer_read_le(ac_buffer_t* pBuf, uint8_t* buf, size_t size)
size_t ac_buffer_reader_current_buffer_length(ac_buffer_t *pBuf)
{
ENSURE_READ_LENGTH(pBuf, size);
while(size > 0)
{
size_t cpy = ac_buffer_size(pBuf);
cpy = MIN(cpy, size);
memcpy(buf, ac_buffer_data(pBuf), cpy);
pBuf->data+=cpy;
pBuf->size-=cpy;
update_buf(pBuf);
size-=cpy;
buf+=cpy;
}
return ac_buffer_size(pBuf);
}
void ac_buffer_read_n_skip(ac_buffer_t* pBuf, size_t size)
bool ac_buffer_reader_cmp_bytes(const ac_buffer_t *pBuf, const uint8_t *bytes, size_t length)
{
ENSURE_READ_LENGTH(pBuf, size);
while(size > 0)
{
size_t cpy = ac_buffer_size(pBuf);
cpy = MIN(cpy, size);
pBuf->data+=cpy;
pBuf->size-=cpy;
update_buf(pBuf);
size-=cpy;
}
}
ac_buffer_t reader;
size_t ac_buffer_reader_readable(const ac_buffer_t* pBuf)
{
size_t r = 0;
while( pBuf != NULL )
{
r += ac_buffer_size(pBuf);
pBuf = ac_buffer_next(pBuf);
}
return r;
}
const uint8_t* ac_buffer_reader_current_buffer_pointer(ac_buffer_t* pBuf)
{
update_buf(pBuf);
return ac_buffer_data(pBuf);
}
size_t ac_buffer_reader_current_buffer_length(ac_buffer_t* pBuf)
{
update_buf(pBuf);
return ac_buffer_size(pBuf);
}
bool ac_buffer_reader_cmp_bytes(const ac_buffer_t* pBuf, const uint8_t* bytes, size_t length)
{
ac_buffer_t reader;
if( length > ac_buffer_reader_readable(pBuf) )
{
return false;
}
ac_buffer_dup(&reader, pBuf);
while(length > 0)
{
size_t sz = ac_buffer_reader_current_buffer_length(&reader);
if( sz > length )
{
sz = length;
if (length > ac_buffer_reader_readable(pBuf)) {
return false;
}
int c = memcmp(ac_buffer_reader_current_buffer_pointer(&reader), bytes, sz);
if(c)
{
return false;
}
length -= sz;
bytes += sz;
ac_buffer_read_n_skip(&reader, sz);
}
return true;
ac_buffer_dup(&reader, pBuf);
while (length > 0) {
size_t sz = ac_buffer_reader_current_buffer_length(&reader);
if (sz > length) {
sz = length;
}
int c = memcmp(ac_buffer_reader_current_buffer_pointer(&reader), bytes, sz);
if (c) {
return false;
}
length -= sz;
bytes += sz;
ac_buffer_read_n_skip(&reader, sz);
}
return true;
}
bool ac_buffer_reader_cmp(const ac_buffer_t* pBuf1, const ac_buffer_t* pBuf2)
bool ac_buffer_reader_cmp(const ac_buffer_t *pBuf1, const ac_buffer_t *pBuf2)
{
ac_buffer_t reader1;
ac_buffer_t reader2;
ac_buffer_t reader1;
ac_buffer_t reader2;
if( ac_buffer_reader_readable(pBuf1) != ac_buffer_reader_readable(pBuf2) )
{
return false;
}
ac_buffer_dup(&reader1, pBuf1);
ac_buffer_dup(&reader2, pBuf2);
size_t length = ac_buffer_reader_readable(pBuf1);
while(length > 0)
{
size_t sz1 = ac_buffer_reader_current_buffer_length(&reader1);
size_t sz2 = ac_buffer_reader_current_buffer_length(&reader2);
size_t sz = MIN(sz1, sz2);
int c = memcmp(ac_buffer_reader_current_buffer_pointer(&reader1), ac_buffer_reader_current_buffer_pointer(&reader2), sz);
if(c)
{
return false;
if (ac_buffer_reader_readable(pBuf1) != ac_buffer_reader_readable(pBuf2)) {
return false;
}
length -= sz;
ac_buffer_read_n_skip(&reader1, sz);
ac_buffer_read_n_skip(&reader2, sz);
}
return true;
ac_buffer_dup(&reader1, pBuf1);
ac_buffer_dup(&reader2, pBuf2);
size_t length = ac_buffer_reader_readable(pBuf1);
while (length > 0) {
size_t sz1 = ac_buffer_reader_current_buffer_length(&reader1);
size_t sz2 = ac_buffer_reader_current_buffer_length(&reader2);
size_t sz = MIN(sz1, sz2);
int c = memcmp(ac_buffer_reader_current_buffer_pointer(&reader1), ac_buffer_reader_current_buffer_pointer(&reader2), sz);
if (c) {
return false;
}
length -= sz;
ac_buffer_read_n_skip(&reader1, sz);
ac_buffer_read_n_skip(&reader2, sz);
}
return true;
}

View File

@ -24,27 +24,27 @@
#include "acore/macros.h"
//Called by supplier
void ac_istream_init(ac_istream_t* pac_istream, ac_istream_fn fn, void* pUserParam)
void ac_istream_init(ac_istream_t *pac_istream, ac_istream_fn fn, void *pUserParam)
{
pac_istream->fn = fn;
pac_istream->pUserParam = pUserParam;
pac_istream->fn = fn;
pac_istream->pUserParam = pUserParam;
}
//Called by consumer
void ac_istream_pull(ac_istream_t* pac_istream, ac_buffer_t* pDataIn, bool* pClose, size_t maxLength)
void ac_istream_pull(ac_istream_t *pac_istream, ac_buffer_t *pDataIn, bool *pClose, size_t maxLength)
{
pac_istream->fn(pDataIn, pClose, maxLength, pac_istream->pUserParam);
pac_istream->fn(pDataIn, pClose, maxLength, pac_istream->pUserParam);
}
//Called by consumer
void ac_ostream_init(ac_ostream_t* pac_ostream, ac_ostream_fn fn, void* pUserParam)
void ac_ostream_init(ac_ostream_t *pac_ostream, ac_ostream_fn fn, void *pUserParam)
{
pac_ostream->fn = fn;
pac_ostream->pUserParam = pUserParam;
pac_ostream->fn = fn;
pac_ostream->pUserParam = pUserParam;
}
//Called by supplier
void ac_ostream_push(ac_ostream_t* pac_ostream, ac_buffer_t* pDataOut, bool closed)
void ac_ostream_push(ac_ostream_t *pac_ostream, ac_buffer_t *pDataOut, bool closed)
{
pac_ostream->fn(pDataOut, closed, pac_ostream->pUserParam);
pac_ostream->fn(pDataOut, closed, pac_ostream->pUserParam);
}

View File

@ -25,21 +25,21 @@
namespace mbed {
namespace nfc {
struct PN512TransportDriver;
class PN512Driver : public NFCControllerDriver, private PN512TransportDriver::Delegate {
public:
PN512Driver(PN512TransportDriver* transport_driver);
struct PN512TransportDriver;
class PN512Driver : public NFCControllerDriver, private PN512TransportDriver::Delegate {
public:
PN512Driver(PN512TransportDriver *transport_driver);
virtual nfc_transceiver_t* initialize(nfc_scheduler_timer_t* scheduler_timer);
virtual void get_supported_nfc_techs(nfc_tech_t* initiator, nfc_tech_t* target) const;
virtual nfc_transceiver_t *initialize(nfc_scheduler_timer_t *scheduler_timer);
virtual void get_supported_nfc_techs(nfc_tech_t *initiator, nfc_tech_t *target) const;
private:
// PN512TransportDriver::Delegate implementation
void on_hw_interrupt();
private:
// PN512TransportDriver::Delegate implementation
void on_hw_interrupt();
PN512TransportDriver* _transport_driver;
pn512_t _pn512;
};
PN512TransportDriver *_transport_driver;
pn512_t _pn512;
};
} // namespace nfc
} // namespace mbed

View File

@ -26,29 +26,29 @@
namespace mbed {
namespace nfc {
class PN512SPITransportDriver : public PN512TransportDriver {
public:
PN512SPITransportDriver(PinName mosi, PinName miso, PinName sclk, PinName ssel, PinName irq, PinName rst);
private:
virtual void initialize();
virtual nfc_transport_t* get_transport() const;
class PN512SPITransportDriver : public PN512TransportDriver {
public:
PN512SPITransportDriver(PinName mosi, PinName miso, PinName sclk, PinName ssel, PinName irq, PinName rst);
void transport_write( uint8_t address, const uint8_t* outBuf, size_t outLen );
void transport_read( uint8_t address, uint8_t* inBuf, size_t inLen );
private:
virtual void initialize();
virtual nfc_transport_t *get_transport() const;
// Callbacks from munfc
static void s_transport_write( uint8_t address, const uint8_t* outBuf, size_t outLen, void* pUser );
static void s_transport_read( uint8_t address, uint8_t* inBuf, size_t inLen, void* pUser );
void transport_write(uint8_t address, const uint8_t *outBuf, size_t outLen);
void transport_read(uint8_t address, uint8_t *inBuf, size_t inLen);
// Callbacks from munfc
static void s_transport_write(uint8_t address, const uint8_t *outBuf, size_t outLen, void *pUser);
static void s_transport_read(uint8_t address, uint8_t *inBuf, size_t inLen, void *pUser);
nfc_transport_t _nfc_transport;
SPI _spi;
DigitalOut _ssel;
InterruptIn _irq;
DigitalOut _rst;
};
nfc_transport_t _nfc_transport;
SPI _spi;
DigitalOut _ssel;
InterruptIn _irq;
DigitalOut _rst;
};
} // namespace nfc
} // namespace mbed

View File

@ -23,55 +23,55 @@
namespace mbed {
namespace nfc {
/**
* The PN512 supports multiple transport mechanisms (SPI, I2C, UART): this class provides a unified API across these transports
*/
class PN512TransportDriver {
public:
/**
* The PN512 supports multiple transport mechanisms (SPI, I2C, UART): this class provides a unified API across these transports
*/
class PN512TransportDriver {
public:
* The PN512TransportDriver delegate
*/
struct Delegate {
/**
* The PN512TransportDriver delegate
*/
struct Delegate {
/**
* Called when the PN512 asserts the interrupt line
*/
void on_hw_interrupt();
};
/**
* Create a PN512TransportDriver instance
*/
PN512TransportDriver();
/**
* Initialize transport driver and perform a chip reset
*/
virtual void initialize() = 0;
/**
* Retrieve the nfc_transport_t struct for the stack to use
*
* @return a pointer to a nfc_transport_t struct
*/
virtual nfc_transport_t* get_transport() const = 0;
/**
* Set this instance's delegate
*
* @param[in] delegate the delegate instance to use
*/
void set_delegate(Delegate* delegate);
protected:
/**
* An implementation must call this function (can be called from interrupt context)
* when the PN512 asserts its interrupt line
*/
void hw_interrupt();
private:
Delegate* _delegate;
* Called when the PN512 asserts the interrupt line
*/
void on_hw_interrupt();
};
/**
* Create a PN512TransportDriver instance
*/
PN512TransportDriver();
/**
* Initialize transport driver and perform a chip reset
*/
virtual void initialize() = 0;
/**
* Retrieve the nfc_transport_t struct for the stack to use
*
* @return a pointer to a nfc_transport_t struct
*/
virtual nfc_transport_t *get_transport() const = 0;
/**
* Set this instance's delegate
*
* @param[in] delegate the delegate instance to use
*/
void set_delegate(Delegate *delegate);
protected:
/**
* An implementation must call this function (can be called from interrupt context)
* when the PN512 asserts its interrupt line
*/
void hw_interrupt();
private:
Delegate *_delegate;
};
} // namespace nfc
} // namespace mbed

View File

@ -25,111 +25,109 @@
namespace mbed {
namespace nfc {
/**
* @addtogroup nfc
* @{
*/
class Type4RemoteInitiator;
/**
* This base class represents an ISO7816-4 application.
*/
class ISO7816App {
/**
* @addtogroup nfc
* @{
* This class describes an ISO7816-4 exchange (Command/Response).
*/
class Type4RemoteInitiator;
/**
* This base class represents an ISO7816-4 application.
*/
class ISO7816App {
class Exchange {
public:
/**
* This class describes an ISO7816-4 exchange (Command/Response).
*/
class Exchange {
public:
/**
* A Command APDU (Application Protocol Data Unit) .
*/
struct CAPDU
{
uint8_t cla; ///< CLA - Instruction class
uint8_t ins; ///< INS - Instruction code
uint8_t p1; ///< P1 - First parameter
uint8_t p2; ///< P2 - Second parameter
ac_buffer_t dataIn; ///< Command data
size_t maxRespLength; ///< Maximum response length
};
/**
* A Response APDU (Application Protocol Data Unit)
*/
struct RAPDU
{
ac_buffer_t dataOut; ///< Response data
uint16_t sw; ///< Status word
};
/**
* Access Command APDU.
*
* @return a const reference to the Command ADPU
*/
const CAPDU& command() const;
/**
* Access Response APDU.
*
* @return a mutable reference to the Command ADPU
*/
RAPDU& response();
/**
* Respond to command.
*
* @return NFC_OK if the response could be sent back successfully, or an error code otherwise
*/
nfc_err_t respond();
private:
CAPDU _command;
RAPDU _response;
ISO7816App* _iso7816_app;
* A Command APDU (Application Protocol Data Unit) .
*/
struct CAPDU {
uint8_t cla; ///< CLA - Instruction class
uint8_t ins; ///< INS - Instruction code
uint8_t p1; ///< P1 - First parameter
uint8_t p2; ///< P2 - Second parameter
ac_buffer_t dataIn; ///< Command data
size_t maxRespLength; ///< Maximum response length
};
/**
* Construct ISO7816 app instance
*/
ISO7816App();
/**
* A Response APDU (Application Protocol Data Unit)
*/
struct RAPDU {
ac_buffer_t dataOut; ///< Response data
uint16_t sw; ///< Status word
};
/**
* Access Command APDU.
*
* @return a const reference to the Command ADPU
*/
const CAPDU &command() const;
/**
* Access Response APDU.
*
* @return a mutable reference to the Command ADPU
*/
RAPDU &response();
/**
* Respond to command.
*
* @return NFC_OK if the response could be sent back successfully, or an error code otherwise
*/
nfc_err_t respond();
private:
friend class Type4RemoteInitiator;
/**
* Retrieve the application's identifier (AID).
* AIDs are composed of a RID (Registered Application Provider Identifier) that needs to be registered and a custom suffix.
*
* @return a pointer to a const buffer containing the application's identifier (AID).
*/
virtual const ac_buffer_t* get_aid() const = 0;
/**
* Called when the application is selected and before any exchange is performed.
*/
virtual void on_selected() = 0;
/**
* Called when the application is deselected (or link is lost).
*/
virtual void on_deselected() = 0;
/**
* Called when an exchange is performed.
* The application must respond using the respond() method of the Exchange class.
*
* @param[in] exchange an instance of the Exchange class populated with the C-APDU which was received
*/
virtual void on_exchange(Exchange* exchange) = 0;
nfc_tech_iso7816_app_t iso7816_app;
CAPDU _command;
RAPDU _response;
ISO7816App *_iso7816_app;
};
/**
* @}
* Construct ISO7816 app instance
*/
ISO7816App();
private:
friend class Type4RemoteInitiator;
/**
* Retrieve the application's identifier (AID).
* AIDs are composed of a RID (Registered Application Provider Identifier) that needs to be registered and a custom suffix.
*
* @return a pointer to a const buffer containing the application's identifier (AID).
*/
virtual const ac_buffer_t *get_aid() const = 0;
/**
* Called when the application is selected and before any exchange is performed.
*/
virtual void on_selected() = 0;
/**
* Called when the application is deselected (or link is lost).
*/
virtual void on_deselected() = 0;
/**
* Called when an exchange is performed.
* The application must respond using the respond() method of the Exchange class.
*
* @param[in] exchange an instance of the Exchange class populated with the C-APDU which was received
*/
virtual void on_exchange(Exchange *exchange) = 0;
nfc_tech_iso7816_app_t iso7816_app;
};
/**
* @}
*/
} // namespace nfc
} // namespace mbed

View File

@ -27,155 +27,155 @@
namespace mbed {
namespace nfc {
class NFCRemoteInitiator;
class NFCRemoteTarget;
class NFCControllerDriver;
class NFCRemoteInitiator;
class NFCRemoteTarget;
class NFCControllerDriver;
/**
* @addtogroup nfc
* @{
*/
/**
* This class represents a NFC Controller.
*
* A controller can be in one of three different states:
* * Idle/sleep state
* * Discovery state: The controller tries to discover a remote endpoint (initiator or target)
* * Connected state: The controller exchanges data with an endpoint (initiator or target)
*
* A NFCController instance needs to be initialized with a NFCControllerDriver instance which abstracts the specific controller being used.
* A delegate needs to be set by the user to receive discovery events.
*/
class NFCController : private NFCControllerDriver::Delegate {
public:
/**
* @addtogroup nfc
* @{
* The NFCController delegate. Users of the NFCController class need to implement this delegate's methods to receive events.
*/
/**
* This class represents a NFC Controller.
*
* A controller can be in one of three different states:
* * Idle/sleep state
* * Discovery state: The controller tries to discover a remote endpoint (initiator or target)
* * Connected state: The controller exchanges data with an endpoint (initiator or target)
*
* A NFCController instance needs to be initialized with a NFCControllerDriver instance which abstracts the specific controller being used.
* A delegate needs to be set by the user to receive discovery events.
*/
class NFCController : private NFCControllerDriver::Delegate {
public:
struct Delegate {
/**
* The NFCController delegate. Users of the NFCController class need to implement this delegate's methods to receive events.
* A enumeration of causes for the discovery process terminating.
*/
struct Delegate {
/**
* A enumeration of causes for the discovery process terminating.
*/
enum nfc_discovery_terminated_reason_t {
nfc_discovery_terminated_completed = 0, ///< Process completed, at least one endpoint was discovered
nfc_discovery_terminated_canceled, ///< Process was canceled by the user
nfc_discovery_terminated_rf_error ///< An unexpected error was encountered during an exchange on the air interface
};
/**
* The discovery process terminated.
* @param[in] reason the cause for the termination
*/
virtual void on_discovery_terminated(nfc_discovery_terminated_reason_t reason) {}
/**
* A remote initiator was discovered (the local controller is in target mode).
* @param[in] the NFCRemoteInitiator instance
*/
virtual void on_nfc_initiator_discovered(const SharedPtr<NFCRemoteInitiator>& nfc_initiator) {}
/**
* A remote target was discovered (the local controller is in initiator mode).
* @param[in] the NFCRemoteTarget instance
*/
virtual void on_nfc_target_discovered(const SharedPtr<NFCRemoteTarget>& nfc_target) {}
enum nfc_discovery_terminated_reason_t {
nfc_discovery_terminated_completed = 0, ///< Process completed, at least one endpoint was discovered
nfc_discovery_terminated_canceled, ///< Process was canceled by the user
nfc_discovery_terminated_rf_error ///< An unexpected error was encountered during an exchange on the air interface
};
/**
* Construct a NFCController instance.
*
* @param[in] driver a pointer to a NFCControllerDriver instance
* @param[in] queue a pointer to the events queue to use
* @param[in] ndef_buffer a bytes array used to store NDEF messages
* @param[in] ndef_buffer_sz the array size in bytes
/**
* The discovery process terminated.
* @param[in] reason the cause for the termination
*/
NFCController(NFCControllerDriver* driver, events::EventQueue* queue, uint8_t* ndef_buffer, size_t ndef_buffer_sz);
virtual void on_discovery_terminated(nfc_discovery_terminated_reason_t reason) {}
/**
* Initialize the NFC controller
*
* This method must be called before any other method call.
*
* @return NFC_OK, or an error.
/**
* A remote initiator was discovered (the local controller is in target mode).
* @param[in] the NFCRemoteInitiator instance
*/
nfc_err_t initialize();
/**
* Set the delegate that will receive events generated by this controller.
*
* @oaram[in] delegate the delegate instance to use
*/
void set_delegate(Delegate* delegate);
virtual void on_nfc_initiator_discovered(const SharedPtr<NFCRemoteInitiator> &nfc_initiator) {}
/**
* Get the list of RF protocols supported by this controller.
*
* @return a bitmask of RF protocols supported by the controller
* A remote target was discovered (the local controller is in initiator mode).
* @param[in] the NFCRemoteTarget instance
*/
nfc_rf_protocols_bitmask_t get_supported_rf_protocols() const;
/**
* Set the list of RF protocols to look for during discovery.
*
* @param[in] rf_protocols the relevant bitmask
* @return NFC_OK on success, or
* NFC_ERR_UNSUPPORTED if a protocol is not supported by the controller,
* NFC_ERR_BUSY if the discovery process is already running
*/
nfc_err_t configure_rf_protocols(nfc_rf_protocols_bitmask_t rf_protocols);
/**
* Start the discovery process using the protocols configured previously.
*
* If remote endpoints are connected when this is called, they will be disconnected.
*
* @return NFC_OK on success, or
* NFC_ERR_BUSY if the discovery process is already running
*/
nfc_err_t start_discovery();
/**
* Cancel/stop a running discovery process.
*
* @return NFC_OK
*/
nfc_err_t cancel_discovery();
private:
friend class NFCRemoteEndpoint;
friend class NFCRemoteInitiator;
friend class Type4RemoteInitiator;
nfc_transceiver_t* transceiver() const;
void polling_callback(nfc_err_t ret);
// NFC Stack scheduler
void scheduler_process(bool hw_interrupt);
// Callbacks from NFC stack
static void s_polling_callback(nfc_transceiver_t* pTransceiver, nfc_err_t ret, void* pUserData);
// Implementation of NFCControllerDriver::Delegate
void on_hw_interrupt();
// Triggers when scheduler must be run again
void on_timeout();
NFCControllerDriver* _driver;
events::EventQueue* _queue;
nfc_transceiver_t* _transceiver;
nfc_scheduler_t* _scheduler;
Timer _timer;
Timeout _timeout;
Delegate* _delegate;
bool _discovery_running;
uint8_t* _ndef_buffer;
size_t _ndef_buffer_sz;
virtual void on_nfc_target_discovered(const SharedPtr<NFCRemoteTarget> &nfc_target) {}
};
/**
* @}
* Construct a NFCController instance.
*
* @param[in] driver a pointer to a NFCControllerDriver instance
* @param[in] queue a pointer to the events queue to use
* @param[in] ndef_buffer a bytes array used to store NDEF messages
* @param[in] ndef_buffer_sz the array size in bytes
*/
NFCController(NFCControllerDriver *driver, events::EventQueue *queue, uint8_t *ndef_buffer, size_t ndef_buffer_sz);
/**
* Initialize the NFC controller
*
* This method must be called before any other method call.
*
* @return NFC_OK, or an error.
*/
nfc_err_t initialize();
/**
* Set the delegate that will receive events generated by this controller.
*
* @oaram[in] delegate the delegate instance to use
*/
void set_delegate(Delegate *delegate);
/**
* Get the list of RF protocols supported by this controller.
*
* @return a bitmask of RF protocols supported by the controller
*/
nfc_rf_protocols_bitmask_t get_supported_rf_protocols() const;
/**
* Set the list of RF protocols to look for during discovery.
*
* @param[in] rf_protocols the relevant bitmask
* @return NFC_OK on success, or
* NFC_ERR_UNSUPPORTED if a protocol is not supported by the controller,
* NFC_ERR_BUSY if the discovery process is already running
*/
nfc_err_t configure_rf_protocols(nfc_rf_protocols_bitmask_t rf_protocols);
/**
* Start the discovery process using the protocols configured previously.
*
* If remote endpoints are connected when this is called, they will be disconnected.
*
* @return NFC_OK on success, or
* NFC_ERR_BUSY if the discovery process is already running
*/
nfc_err_t start_discovery();
/**
* Cancel/stop a running discovery process.
*
* @return NFC_OK
*/
nfc_err_t cancel_discovery();
private:
friend class NFCRemoteEndpoint;
friend class NFCRemoteInitiator;
friend class Type4RemoteInitiator;
nfc_transceiver_t *transceiver() const;
void polling_callback(nfc_err_t ret);
// NFC Stack scheduler
void scheduler_process(bool hw_interrupt);
// Callbacks from NFC stack
static void s_polling_callback(nfc_transceiver_t *pTransceiver, nfc_err_t ret, void *pUserData);
// Implementation of NFCControllerDriver::Delegate
void on_hw_interrupt();
// Triggers when scheduler must be run again
void on_timeout();
NFCControllerDriver *_driver;
events::EventQueue *_queue;
nfc_transceiver_t *_transceiver;
nfc_scheduler_t *_scheduler;
Timer _timer;
Timeout _timeout;
Delegate *_delegate;
bool _discovery_running;
uint8_t *_ndef_buffer;
size_t _ndef_buffer_sz;
};
/**
* @}
*/
} // namespace nfc
} // namespace mbed

View File

@ -27,67 +27,67 @@
namespace mbed {
namespace nfc {
/**
* @addtogroup nfc
* @{
*/
/**
* The abstraction for a NFC controller driver.
* Implementers need to derive from this class and implement its methods.
*/
class NFCControllerDriver {
/**
* @addtogroup nfc
* @{
* Instantiate a NFCControllerDriver
*/
NFCControllerDriver();
/**
* The abstraction for a NFC controller driver.
* Implementers need to derive from this class and implement its methods.
*/
class NFCControllerDriver {
* The NFCControllerDriver delegate
*/
struct Delegate {
/**
* Instantiate a NFCControllerDriver
*/
NFCControllerDriver();
/**
* The NFCControllerDriver delegate
*/
struct Delegate {
/**
* Called when the controller asserts the interrupt line
*/
virtual void on_hw_interrupt() {}
};
/**
* Initialize the driver and retrieve the interface to the controller.
*
* @param[in] scheduler_timer a timer to initialize the controller's scheduler instance with
* @return an initialized MicroNFC nfc_transceiver_t instance
*/
virtual nfc_transceiver_t* initialize(nfc_scheduler_timer_t* scheduler_timer) = 0;
/**
* Retrieve list of technologies supported by the controller
* @param[out] initiator bitmask of technologies supported when the controller is in initiator mode
* @param[out] target bitmask of technologies supported when the controller is in target mode
*/
virtual void get_supported_nfc_techs(nfc_tech_t* initiator, nfc_tech_t* target) const = 0;
/**
* Set this instance's delegate
*
* @param[in] delegate the delegate instance to use
*/
void set_delegate(Delegate* delegate);
protected:
/**
* An implementation must call this function (can be called from interrupt context)
* when the controller asserts its interrupt line
*/
void hw_interrupt();
private:
Delegate* _delegate;
* Called when the controller asserts the interrupt line
*/
virtual void on_hw_interrupt() {}
};
/**
* @}
* Initialize the driver and retrieve the interface to the controller.
*
* @param[in] scheduler_timer a timer to initialize the controller's scheduler instance with
* @return an initialized MicroNFC nfc_transceiver_t instance
*/
virtual nfc_transceiver_t *initialize(nfc_scheduler_timer_t *scheduler_timer) = 0;
/**
* Retrieve list of technologies supported by the controller
* @param[out] initiator bitmask of technologies supported when the controller is in initiator mode
* @param[out] target bitmask of technologies supported when the controller is in target mode
*/
virtual void get_supported_nfc_techs(nfc_tech_t *initiator, nfc_tech_t *target) const = 0;
/**
* Set this instance's delegate
*
* @param[in] delegate the delegate instance to use
*/
void set_delegate(Delegate *delegate);
protected:
/**
* An implementation must call this function (can be called from interrupt context)
* when the controller asserts its interrupt line
*/
void hw_interrupt();
private:
Delegate *_delegate;
};
/**
* @}
*/
} // namespace nfc
} // namespace mbed

View File

@ -24,31 +24,30 @@
namespace mbed {
namespace nfc {
struct nfc_rf_protocols_bitmask_t
{
uint8_t initiator_t1t : 1;
uint8_t initiator_t2t : 1;
uint8_t initiator_t3t : 1;
uint8_t initiator_iso_dep : 1;
uint8_t initiator_nfc_dep : 1;
uint8_t initiator_t5t : 1;
struct nfc_rf_protocols_bitmask_t {
uint8_t initiator_t1t : 1;
uint8_t initiator_t2t : 1;
uint8_t initiator_t3t : 1;
uint8_t initiator_iso_dep : 1;
uint8_t initiator_nfc_dep : 1;
uint8_t initiator_t5t : 1;
uint8_t target_t1t : 1;
uint8_t target_t2t : 1;
uint8_t target_t3t : 1;
uint8_t target_iso_dep : 1;
uint8_t target_nfc_dep : 1;
uint8_t target_t5t : 1;
};
uint8_t target_t1t : 1;
uint8_t target_t2t : 1;
uint8_t target_t3t : 1;
uint8_t target_iso_dep : 1;
uint8_t target_nfc_dep : 1;
uint8_t target_t5t : 1;
};
enum nfc_tag_type_t {
nfc_tag_type_1,
nfc_tag_type_2,
nfc_tag_type_3,
nfc_tag_type_4a,
nfc_tag_type_4b,
nfc_tag_type_5
};
enum nfc_tag_type_t {
nfc_tag_type_1,
nfc_tag_type_2,
nfc_tag_type_3,
nfc_tag_type_4a,
nfc_tag_type_4b,
nfc_tag_type_5
};
} // namespace nfc
} // namespace mbed

View File

@ -26,110 +26,110 @@
namespace mbed {
namespace nfc {
/**
* @addtogroup nfc
* @{
*/
/**
* The NFC EEPROM class represents a NFC target device connected using a wired
* link (I2C, SPI, etc).
*
* These EEPROMs essentially provide addressable memory that can be accessed
* using either a wired or NFC interface.
*
* In NFC mode these most often conform to one of the NFC tag types defined
* by the NFC Forum, therefore encoding NDEF data in these EEPROMs will
* ensure that it is understandable by a NFC reader.
*/
class NFCEEPROM : public NFCTarget, public NFCEEPROMDriver::Delegate {
public:
/**
* @addtogroup nfc
* @{
* Construct a NFCEEPROM instance.
*
* @param[in] driver a pointer to a NFCEEPROMDriver instance
* @param[in] queue a pointer to the events queue to use
* @param[in] ndef_buffer a bytes array used to store NDEF messages
* @param[in] ndef_buffer_sz the array size in bytes
*/
NFCEEPROM(NFCEEPROMDriver *driver, events::EventQueue *queue, uint8_t *ndef_buffer, size_t ndef_buffer_sz);
/**
* The NFC EEPROM class represents a NFC target device connected using a wired
* link (I2C, SPI, etc).
*
* These EEPROMs essentially provide addressable memory that can be accessed
* using either a wired or NFC interface.
*
* In NFC mode these most often conform to one of the NFC tag types defined
* by the NFC Forum, therefore encoding NDEF data in these EEPROMs will
* ensure that it is understandable by a NFC reader.
*/
class NFCEEPROM : public NFCTarget, public NFCEEPROMDriver::Delegate {
public:
/**
* Construct a NFCEEPROM instance.
*
* @param[in] driver a pointer to a NFCEEPROMDriver instance
* @param[in] queue a pointer to the events queue to use
* @param[in] ndef_buffer a bytes array used to store NDEF messages
* @param[in] ndef_buffer_sz the array size in bytes
*/
NFCEEPROM(NFCEEPROMDriver* driver, events::EventQueue* queue, uint8_t* ndef_buffer, size_t ndef_buffer_sz);
/**
* The NFCEEPROM delegate. Users of the NFCEEPROM class need to implement this delegate's methods to receive events.
*/
struct Delegate : NFCTarget::Delegate {
};
/**
* Initialize the NFC EEPROM
*
* This method must be called before any other method call.
*
* @return NFC_OK, or an error.
*/
nfc_err_t initialize();
/**
* Set the delegate that will receive events generated by this EEPROM.
*
* @oaram[in] delegate the delegate instance to use
*/
void set_delegate(Delegate* delegate);
private:
// Implementation of NFCTarget
virtual void write_ndef_message();
virtual void read_ndef_message();
virtual void erase_ndef_message();
// Implementation of NFCEEPROMDriver::Delegate
virtual void on_session_started(bool success);
virtual void on_session_ended(bool success);
virtual void on_bytes_read(size_t count);
virtual void on_bytes_written(size_t count);
virtual void on_size_written(bool success);
virtual void on_size_read(bool success, size_t size);
virtual void on_bytes_erased(size_t count);
virtual void on_event();
void handle_error(nfc_err_t ret);
void continue_write();
void continue_read();
void continue_erase();
enum class nfc_eeprom_operation_t {
nfc_eeprom_idle,
nfc_eeprom_write_start_session,
nfc_eeprom_write_write_bytes,
nfc_eeprom_write_write_size,
nfc_eeprom_write_end_session,
nfc_eeprom_write_start_session,
nfc_eeprom_read_read_size,
nfc_eeprom_read_read_bytes,
nfc_eeprom_read_end_session,
nfc_eeprom_erase_start_session,
nfc_eeprom_erase_erase_bytes,
nfc_eeprom_erase_write_size,
nfc_eeprom_erase_end_session
};
NFCEEPROMDriver* _driver;
events::EventQueue* _queue;
bool _initialized;
nfc_eeprom_operation_t _current_op;
buffer_t _ndef_buffer_reader;
size_t _ndef_buffer_read_sz;
uint32_t _eeprom_address;
nfc_err_t _operation_result;
/**
* The NFCEEPROM delegate. Users of the NFCEEPROM class need to implement this delegate's methods to receive events.
*/
struct Delegate : NFCTarget::Delegate {
};
/**
* @}
* Initialize the NFC EEPROM
*
* This method must be called before any other method call.
*
* @return NFC_OK, or an error.
*/
nfc_err_t initialize();
/**
* Set the delegate that will receive events generated by this EEPROM.
*
* @oaram[in] delegate the delegate instance to use
*/
void set_delegate(Delegate *delegate);
private:
// Implementation of NFCTarget
virtual void write_ndef_message();
virtual void read_ndef_message();
virtual void erase_ndef_message();
// Implementation of NFCEEPROMDriver::Delegate
virtual void on_session_started(bool success);
virtual void on_session_ended(bool success);
virtual void on_bytes_read(size_t count);
virtual void on_bytes_written(size_t count);
virtual void on_size_written(bool success);
virtual void on_size_read(bool success, size_t size);
virtual void on_bytes_erased(size_t count);
virtual void on_event();
void handle_error(nfc_err_t ret);
void continue_write();
void continue_read();
void continue_erase();
enum class nfc_eeprom_operation_t {
nfc_eeprom_idle,
nfc_eeprom_write_start_session,
nfc_eeprom_write_write_bytes,
nfc_eeprom_write_write_size,
nfc_eeprom_write_end_session,
nfc_eeprom_write_start_session,
nfc_eeprom_read_read_size,
nfc_eeprom_read_read_bytes,
nfc_eeprom_read_end_session,
nfc_eeprom_erase_start_session,
nfc_eeprom_erase_erase_bytes,
nfc_eeprom_erase_write_size,
nfc_eeprom_erase_end_session
};
NFCEEPROMDriver *_driver;
events::EventQueue *_queue;
bool _initialized;
nfc_eeprom_operation_t _current_op;
buffer_t _ndef_buffer_reader;
size_t _ndef_buffer_read_sz;
uint32_t _eeprom_address;
nfc_err_t _operation_result;
};
/**
* @}
*/
} // namespace nfc

View File

@ -26,173 +26,173 @@
namespace mbed {
namespace nfc {
/**
* @addtogroup nfc
* @{
*/
/**
* The abstraction for a NFC EEPROM driver.
* Implementers need to derive from this class and implement its methods.
*/
class NFCEEPROMDriver {
public:
/**
* @addtogroup nfc
* @{
* Construct a NFCEEPROM driver instance.
*/
NFCEEPROMDriver();
/**
* The abstraction for a NFC EEPROM driver.
* Implementers need to derive from this class and implement its methods.
*/
class NFCEEPROMDriver {
public:
* The NFCEEPROMDriver delegate.
* Methods in this class are called by the driver on completion of long-running operations.
*/
struct Delegate {
/**
* Construct a NFCEEPROM driver instance.
* Completion of session start operation.
*
* @param[in] success whether this operation succeeded
*/
NFCEEPROMDriver();
virtual void on_session_started(bool success) = 0;
/**
* The NFCEEPROMDriver delegate.
* Methods in this class are called by the driver on completion of long-running operations.
* Completion of session end operation.
*
* @param[in] success whether this operation succeeded
*/
struct Delegate {
/**
* Completion of session start operation.
*
* @param[in] success whether this operation succeeded
*/
virtual void on_session_started(bool success) = 0;
/**
* Completion of session end operation.
*
* @param[in] success whether this operation succeeded
*/
virtual void on_session_ended(bool success) = 0;
/**
* Completion of read operation.
*
* @param[in] count number of bytes actually read
*/
virtual void on_bytes_read(size_t count) = 0;
/**
* Completion of write operation.
*
* @param[in] count number of bytes actually written
*/
virtual void on_bytes_written(size_t count) = 0;
/**
* Completion of size retrieval operation.
*
* @param[in] success whether this operation succeeded
* @param[out] the current addressable memory size
*/
virtual void on_size_read(bool success, size_t size) = 0;
/**
* Completion of size setting operation.
*
* @param[in] success whether this operation succeeded
*/
virtual void on_size_written(bool success) = 0;
/**
* Completion of erasing operation.
*
* @param[in] count number of bytes actually erased
*/
virtual void on_bytes_erased(size_t count) = 0;
/**
* Signal the user that the process_events() need to be called
*
* @note this function can be called in interrupt context
*/
virtual void on_event() = 0;
};
/**
* Set the delegate that will receive events generated by this EEPROM.
*
* @oaram[in] delegate the delegate instance to use
*/
void set_delegate(Delegate* delegate);
/**
* Reset and initialize the EEPROM.
* This method should complete synchronously.
*/
virtual void reset() = 0;
virtual void on_session_ended(bool success) = 0;
/**
* Process events raised by the driver in interrupt context.
*/
virtual void process_events();
* Completion of read operation.
*
* @param[in] count number of bytes actually read
*/
virtual void on_bytes_read(size_t count) = 0;
/**
* Get the maximum memory size addressable by the EEPROM.
*/
virtual size_t get_max_size() = 0;
* Completion of write operation.
*
* @param[in] count number of bytes actually written
*/
virtual void on_bytes_written(size_t count) = 0;
/**
* Start a session of operations (reads, writes, erases, size gets/sets).
* This method is called prior to any memory access to allow the underlying implementation
* to disable the RF interface or abort the transaction if it's being used.
* This method should complete asynchronously by calling has_started_session().
*/
virtual void start_session() = 0; // This could lock the chip's RF interface
* Completion of size retrieval operation.
*
* @param[in] success whether this operation succeeded
* @param[out] the current addressable memory size
*/
virtual void on_size_read(bool success, size_t size) = 0;
/**
* End a session.
* This method should complete asynchronously by calling has_ended_session().
*/
virtual void end_session() = 0;
* Completion of size setting operation.
*
* @param[in] success whether this operation succeeded
*/
virtual void on_size_written(bool success) = 0;
/**
* Read bytes from memory.
* @param[in] address the virtual address (starting from 0) from which to start the read.
* @param[out] bytes a buffer in which the read bytes will be stored.
* This buffer should remain valid till the callback is called.
* @oaram[in] count the number of bytes to read.
* This method should complete asynchronously by calling has_read_bytes().
*/
virtual void read_bytes(uint32_t address, uint8_t* bytes, size_t count) = 0;
* Completion of erasing operation.
*
* @param[in] count number of bytes actually erased
*/
virtual void on_bytes_erased(size_t count) = 0;
/**
* Write bytes to memory.
* @param[in] address the virtual address (starting from 0) from which to start the write.
* @param[in] bytes a buffer from to copy.
* This buffer should remain valid till the callback is called.
* @oaram[in] count the number of bytes to write.
* This method should complete asynchronously by calling has_written_bytes().
*/
virtual void write_bytes(uint32_t address, const uint8_t* bytes, size_t count) = 0;
/**
* Retrieve the size of the addressable memory.
* This method should complete asynchronously by calling has_gotten_size().
*/
virtual void read_size() = 0;
/**
* Set the size of the addressable memory.
* @oaram[in] count the number of addressable bytes.
* This method should complete asynchronously by calling has_set_size().
*/
virtual void write_size(size_t count) = 0;
/**
* Erase bytes from memory.
* @param[in] address the virtual address (starting from 0) from which to start erasing.
* @oaram[in] count the number of bytes to erase.
* This method should complete asynchronously by calling has_erased_bytes().
*/
virtual void erase_bytes(uint32_t address, size_t size) = 0;
protected:
Delegate* delegate();
private:
Delegate* _delegate;
* Signal the user that the process_events() need to be called
*
* @note this function can be called in interrupt context
*/
virtual void on_event() = 0;
};
/**
* @}
* Set the delegate that will receive events generated by this EEPROM.
*
* @oaram[in] delegate the delegate instance to use
*/
void set_delegate(Delegate *delegate);
/**
* Reset and initialize the EEPROM.
* This method should complete synchronously.
*/
virtual void reset() = 0;
/**
* Process events raised by the driver in interrupt context.
*/
virtual void process_events();
/**
* Get the maximum memory size addressable by the EEPROM.
*/
virtual size_t get_max_size() = 0;
/**
* Start a session of operations (reads, writes, erases, size gets/sets).
* This method is called prior to any memory access to allow the underlying implementation
* to disable the RF interface or abort the transaction if it's being used.
* This method should complete asynchronously by calling has_started_session().
*/
virtual void start_session() = 0; // This could lock the chip's RF interface
/**
* End a session.
* This method should complete asynchronously by calling has_ended_session().
*/
virtual void end_session() = 0;
/**
* Read bytes from memory.
* @param[in] address the virtual address (starting from 0) from which to start the read.
* @param[out] bytes a buffer in which the read bytes will be stored.
* This buffer should remain valid till the callback is called.
* @oaram[in] count the number of bytes to read.
* This method should complete asynchronously by calling has_read_bytes().
*/
virtual void read_bytes(uint32_t address, uint8_t *bytes, size_t count) = 0;
/**
* Write bytes to memory.
* @param[in] address the virtual address (starting from 0) from which to start the write.
* @param[in] bytes a buffer from to copy.
* This buffer should remain valid till the callback is called.
* @oaram[in] count the number of bytes to write.
* This method should complete asynchronously by calling has_written_bytes().
*/
virtual void write_bytes(uint32_t address, const uint8_t *bytes, size_t count) = 0;
/**
* Retrieve the size of the addressable memory.
* This method should complete asynchronously by calling has_gotten_size().
*/
virtual void read_size() = 0;
/**
* Set the size of the addressable memory.
* @oaram[in] count the number of addressable bytes.
* This method should complete asynchronously by calling has_set_size().
*/
virtual void write_size(size_t count) = 0;
/**
* Erase bytes from memory.
* @param[in] address the virtual address (starting from 0) from which to start erasing.
* @oaram[in] count the number of bytes to erase.
* This method should complete asynchronously by calling has_erased_bytes().
*/
virtual void erase_bytes(uint32_t address, size_t size) = 0;
protected:
Delegate *delegate();
private:
Delegate *_delegate;
};
/**
* @}
*/
} // namespace nfc
} // namespace mbed

View File

@ -24,93 +24,99 @@
namespace mbed {
namespace nfc {
/**
* @addtogroup nfc
* @{
*/
/**
* The base class for all endpoints that can support NDEF content.
*/
class NFCNDEFCapable {
public:
/**
* @addtogroup nfc
* @{
* Construct a NFCNDEFCapable instance.
* @param[in] buffer a bytes array used to store NDEF messages
* @param[in] buffer_size the array size in bytes
*/
NFCNDEFCapable(uint8_t *buffer, size_t buffer_size);
/**
* The base class for all endpoints that can support NDEF content.
*/
class NFCNDEFCapable {
public:
/**
* Construct a NFCNDEFCapable instance.
* @param[in] buffer a bytes array used to store NDEF messages
* @param[in] buffer_size the array size in bytes
*/
NFCNDEFCapable(uint8_t* buffer, size_t buffer_size);
* Check if this instance actually supports NDEF content.
*
* @return whether NDEF content is supported
*/
virtual bool is_ndef_supported() const
{
return false;
}
/**
* Check if this instance actually supports NDEF content.
*
* @return whether NDEF content is supported
*/
virtual bool is_ndef_supported() const { return false; }
struct Delegate {
/**
* Parse a NDEF message.
*
* @param[in] buffer a buffer containing the message to parse
* @param[in] size the buffer's size
*/
virtual void parse_ndef_message(const uint8_t* buffer, size_t size) { }
/**
* Build a NDEF message.
*
* @param[in] buffer a mutable buffer in which the message should be stored
* @param[in] capacity the buffer's capacity
* @return the number of bytes actually used
*/
virtual size_t build_ndef_message(uint8_t* buffer, size_t capacity) { return 0; }
};
/**
* Set the delegate that will receive events generated by this class.
*
* @oaram[in] delegate the delegate instance to use
*/
void set_ndef_delegate(Delegate* delegate);
protected:
struct Delegate {
/**
* Parse a NDEF message.
*
* @param[in] a buffer containing a NDEF message
*/
void parse_ndef_message(const ac_buffer_t& buffer);
*
* @param[in] buffer a buffer containing the message to parse
* @param[in] size the buffer's size
*/
virtual void parse_ndef_message(const uint8_t *buffer, size_t size) { }
/**
* Build NDEF message.
*
* @param[in,out] a buffer builder in which to create the NDEF message.
* The backing buffer is guaranteed to be continuous.
*/
void build_ndef_message(ac_buffer_builder_t& buffer_builder);
/**
* Retrieve underlying NDEF message instance
* @return pointer to NDEF message instance
*/
ndef_msg_t* ndef_message();
private:
// Callbacks from NDEF stack
static nfc_err_t s_ndef_encode(ndef_msg_t* pTag, buffer_builder_t* pBufferBldr, void* pUserData);
static nfc_err_t s_ndef_decode(ndef_msg_t* pTag, buffer_t* pBuffer, void* pUserData);
nfc_err_t ndef_encode(buffer_builder_t* pBufferBldr);
nfc_err_t ndef_decode(buffer_t* pBuffer);
Delegate* _delegate;
ndef_msg_t _ndef_message;
* Build a NDEF message.
*
* @param[in] buffer a mutable buffer in which the message should be stored
* @param[in] capacity the buffer's capacity
* @return the number of bytes actually used
*/
virtual size_t build_ndef_message(uint8_t *buffer, size_t capacity)
{
return 0;
}
};
/**
* @}
* Set the delegate that will receive events generated by this class.
*
* @oaram[in] delegate the delegate instance to use
*/
void set_ndef_delegate(Delegate *delegate);
protected:
/**
* Parse a NDEF message.
*
* @param[in] a buffer containing a NDEF message
*/
void parse_ndef_message(const ac_buffer_t &buffer);
/**
* Build NDEF message.
*
* @param[in,out] a buffer builder in which to create the NDEF message.
* The backing buffer is guaranteed to be continuous.
*/
void build_ndef_message(ac_buffer_builder_t &buffer_builder);
/**
* Retrieve underlying NDEF message instance
* @return pointer to NDEF message instance
*/
ndef_msg_t *ndef_message();
private:
// Callbacks from NDEF stack
static nfc_err_t s_ndef_encode(ndef_msg_t *pTag, buffer_builder_t *pBufferBldr, void *pUserData);
static nfc_err_t s_ndef_decode(ndef_msg_t *pTag, buffer_t *pBuffer, void *pUserData);
nfc_err_t ndef_encode(buffer_builder_t *pBufferBldr);
nfc_err_t ndef_decode(buffer_t *pBuffer);
Delegate *_delegate;
ndef_msg_t _ndef_message;
};
/**
* @}
*/
} // namespace nfc
} // namespace mbed

View File

@ -24,83 +24,83 @@
namespace mbed {
namespace nfc {
/**
* @addtogroup nfc
* @{
*/
class NFCController;
/**
* This is the base class for all remote endpoints (initiators and targets)
* addressable over the air interface.
*/
class NFCRemoteEndpoint {
public:
NFCRemoteEndpoint();
/**
* @addtogroup nfc
* @{
* The NFCRemoteEndpoint base delegate.
*/
class NFCController;
/**
* This is the base class for all remote endpoints (initiators and targets)
* addressable over the air interface.
*/
class NFCRemoteEndpoint {
public:
NFCRemoteEndpoint();
struct Delegate {
/**
* The NFCRemoteEndpoint base delegate.
* This method is called when the endpoint is connected
*/
struct Delegate {
/**
* This method is called when the endpoint is connected
*/
virtual void on_connected() {};
/**
* This method is called when the endpoint is lost (air interface link disconnnected)
*/
virtual void on_disconnected() {};
};
virtual void on_connected() {};
/**
* Connect the remote endpoint
*
* @return NFC_OK or an error code
* This method is called when the endpoint is lost (air interface link disconnnected)
*/
virtual nfc_err_t connect() = 0;
/**
* Disconnect the remote endpoint
*
* @return NFC_OK or an error code
*/
virtual nfc_err_t disconnect() = 0;
/**
* Check if the endpoint is connected.
* @return whether the endpoint is connected
*/
virtual bool is_connected() const = 0;
/**
* Check if the endpoint is disconnected/lost.
* @return whether the endpoint has been disconnected
*/
virtual bool is_disconnected() const = 0;
/**
* Get the list of RF protocols supported and activated over the air interface.
* @return a bitmask of activated protocols
*/
virtual nfc_rf_protocols_bitmask_t rf_protocols() = 0;
protected:
/**
* Mark endpoint as connected
*/
void connected();
/**
* Mark endpoint as disconnected
*/
void disconnected();
virtual void on_disconnected() {};
};
/**
* @}
* Connect the remote endpoint
*
* @return NFC_OK or an error code
*/
virtual nfc_err_t connect() = 0;
/**
* Disconnect the remote endpoint
*
* @return NFC_OK or an error code
*/
virtual nfc_err_t disconnect() = 0;
/**
* Check if the endpoint is connected.
* @return whether the endpoint is connected
*/
virtual bool is_connected() const = 0;
/**
* Check if the endpoint is disconnected/lost.
* @return whether the endpoint has been disconnected
*/
virtual bool is_disconnected() const = 0;
/**
* Get the list of RF protocols supported and activated over the air interface.
* @return a bitmask of activated protocols
*/
virtual nfc_rf_protocols_bitmask_t rf_protocols() = 0;
protected:
/**
* Mark endpoint as connected
*/
void connected();
/**
* Mark endpoint as disconnected
*/
void disconnected();
};
/**
* @}
*/
} // namespace nfc
} // namespace mbed

View File

@ -26,70 +26,70 @@
namespace mbed {
namespace nfc {
/**
* @addtogroup nfc
* @{
*/
class NFCController;
/**
* This class represents a remote NFC initiator (the local controller being in target mode).
*
* An initiator can be a NFC reader, a NFC-enabled phone or other NFC device capable of generating a RF field.
*/
class NFCRemoteInitiator : public NFCRemoteEndpoint, public NFCNDEFCapable {
public:
/**
* @addtogroup nfc
* @{
* Create a NFCRemoteInitiator.
* @param[in] buffer a bytes array used to store NDEF messages
* @param[in] buffer_size the array size in bytes
*/
NFCRemoteInitiator(uint8_t *buffer, size_t buffer_size);
virtual ~NFCRemoteInitiator();
class NFCController;
/**
* This class represents a remote NFC initiator (the local controller being in target mode).
*
* An initiator can be a NFC reader, a NFC-enabled phone or other NFC device capable of generating a RF field.
*/
class NFCRemoteInitiator : public NFCRemoteEndpoint, public NFCNDEFCapable {
public:
/**
* Create a NFCRemoteInitiator.
* @param[in] buffer a bytes array used to store NDEF messages
* @param[in] buffer_size the array size in bytes
*/
NFCRemoteInitiator(uint8_t* buffer, size_t buffer_size);
virtual ~NFCRemoteInitiator();
* The NFCRemoteInitiator delegate. Users of the NFCRemoteInitiator class need to implement this delegate's methods to receive events.
*/
struct Delegate : NFCEndpoint::Delegate, NFCNDEFCapable::Delegate {
/**
* The NFCRemoteInitiator delegate. Users of the NFCRemoteInitiator class need to implement this delegate's methods to receive events.
*/
struct Delegate : NFCEndpoint::Delegate, NFCNDEFCapable::Delegate {
};
/**
* Set the delegate that will receive events generated by the initiator.
*
* @oaram[in] delegate the delegate instance to use
*/
void set_remote_initiator_delegate(Delegate* delegate);
/**
* Retrieve the NFC tag type exposed by the controller to communicate with the initiator.
*
* @return the relevant NFC tag type
*/
virtual nfc_tag_type_t nfc_tag_type() const = 0;
/**
* Retrieve whether ISO7816 applications are supported by the underlying technology.
*
* @return whether ISO7816 applications are supported
*/
virtual bool is_iso7816_supported() const = 0;
/**
* Register an ISO7816 application to be used by the initiator.
*
* @param[in] application a pointer to an ISO7816App instance
*/
virtual void add_iso7816_application(ISO7816App* application) = 0;
private:
Delegate* _delegate;
};
/**
* @}
* Set the delegate that will receive events generated by the initiator.
*
* @oaram[in] delegate the delegate instance to use
*/
void set_remote_initiator_delegate(Delegate *delegate);
/**
* Retrieve the NFC tag type exposed by the controller to communicate with the initiator.
*
* @return the relevant NFC tag type
*/
virtual nfc_tag_type_t nfc_tag_type() const = 0;
/**
* Retrieve whether ISO7816 applications are supported by the underlying technology.
*
* @return whether ISO7816 applications are supported
*/
virtual bool is_iso7816_supported() const = 0;
/**
* Register an ISO7816 application to be used by the initiator.
*
* @param[in] application a pointer to an ISO7816App instance
*/
virtual void add_iso7816_application(ISO7816App *application) = 0;
private:
Delegate *_delegate;
};
/**
* @}
*/
} // namespace nfc
} // namespace mbed

View File

@ -26,75 +26,75 @@
namespace mbed {
namespace nfc {
/**
* @addtogroup nfc
* @{
*/
/**
* This class represents a NFC target (either a remote target when the local controller in in initiator mode, or a target connected through a wired connection).
*
* A target can be a NFC tag/card, a NFC-enabled phone or other NFC device capable of modulating a RF field.
*/
class NFCTarget : public NFCNDEFCapable {
public:
/**
* @addtogroup nfc
* @{
* Create a NFCTarget.
*
* @param[in] buffer a bytes array used to store NDEF messages
* @param[in] buffer_size the array size in bytes
*/
/**
* This class represents a NFC target (either a remote target when the local controller in in initiator mode, or a target connected through a wired connection).
*
* A target can be a NFC tag/card, a NFC-enabled phone or other NFC device capable of modulating a RF field.
*/
class NFCTarget : public NFCNDEFCapable {
public:
NFCTarget(uint8_t *buffer, size_t buffer_size);
virtual ~NFCTarget();
struct Delegate {
/**
* Create a NFCTarget.
*
* @param[in] buffer a bytes array used to store NDEF messages
* @param[in] buffer_size the array size in bytes
*/
NFCTarget(uint8_t* buffer, size_t buffer_size);
virtual ~NFCTarget();
struct Delegate {
/**
* The NDEF message erasing request completed.
*
* @param[in] result NFC_OK or an error code on failure
*/
virtual void on_ndef_message_erased(nfc_err_t result) {}
/**
* The NDEF message writing request completed.
*
* @param[in] result NFC_OK or an error code on failure
*/
virtual void on_ndef_message_written(nfc_err_t result) {}
/**
* The NDEF message reading request completed.
*
* @param[in] result NFC_OK or an error code on failure
*/
virtual void on_ndef_message_read(nfc_err_t result) {}
};
* The NDEF message erasing request completed.
*
* @param[in] result NFC_OK or an error code on failure
*/
virtual void on_ndef_message_erased(nfc_err_t result) {}
/**
* Write a NDEF message to the target.
*
* on_ndef_message_written() will be called on completion.
*/
virtual void write_ndef_message() = 0;
* The NDEF message writing request completed.
*
* @param[in] result NFC_OK or an error code on failure
*/
virtual void on_ndef_message_written(nfc_err_t result) {}
/**
* Read a NDEF message from the target.
*
* on_ndef_message_read() will be called on completion.
*/
virtual void read_ndef_message() = 0;
/**
* Erase the NDEF message in the target.
*
* on_ndef_message_erased() will be called on completion.
*/
virtual void erase_ndef_message() = 0;
* The NDEF message reading request completed.
*
* @param[in] result NFC_OK or an error code on failure
*/
virtual void on_ndef_message_read(nfc_err_t result) {}
};
/**
* @}
* Write a NDEF message to the target.
*
* on_ndef_message_written() will be called on completion.
*/
virtual void write_ndef_message() = 0;
/**
* Read a NDEF message from the target.
*
* on_ndef_message_read() will be called on completion.
*/
virtual void read_ndef_message() = 0;
/**
* Erase the NDEF message in the target.
*
* on_ndef_message_erased() will be called on completion.
*/
virtual void erase_ndef_message() = 0;
};
/**
* @}
*/
} // namespace nfc
} // namespace mbed

View File

@ -29,54 +29,54 @@
namespace mbed {
namespace nfc {
/**
* @addtogroup nfc
* @{
*/
/**
* This class is an implementation of the Type 4 tag application.
*/
class Type4RemoteInitiator : public NFCRemoteInitiator {
private:
/**
* @addtogroup nfc
* @{
* Create a Type4RemoteInitiator.
*
* @param[in] controller pointer to the NFCController instance that created this object
* @param[in] buffer a bytes array used to store NDEF messages
* @param[in] buffer_size the array size in bytes
*/
/**
* This class is an implementation of the Type 4 tag application.
*/
class Type4RemoteInitiator : public NFCRemoteInitiator {
private:
/**
* Create a Type4RemoteInitiator.
*
* @param[in] controller pointer to the NFCController instance that created this object
* @param[in] buffer a bytes array used to store NDEF messages
* @param[in] buffer_size the array size in bytes
*/
Type4RemoteInitiator(NFCController* controller, uint8_t* buffer, size_t buffer_size);
Type4RemoteInitiator(NFCController *controller, uint8_t *buffer, size_t buffer_size);
// NFCRemoteEndpoint implementation
virtual nfc_err_t connect();
virtual nfc_err_t disconnect();
virtual bool is_connected();
virtual bool is_disconnected();
virtual nfc_rf_protocols_bitmask_t rf_protocols();
// NFCRemoteEndpoint implementation
virtual nfc_err_t connect();
virtual nfc_err_t disconnect();
virtual bool is_connected();
virtual bool is_disconnected();
virtual nfc_rf_protocols_bitmask_t rf_protocols();
// NFCRemoteInitiator implementation
virtual nfc_tag_type_t nfc_tag_type() const;
virtual bool is_iso7816_supported() const;
virtual void add_iso7816_application(ISO7816App* application);
// NFCRemoteInitiator implementation
virtual nfc_tag_type_t nfc_tag_type() const;
virtual bool is_iso7816_supported() const;
virtual void add_iso7816_application(ISO7816App *application);
// NFCNDEFCapable implementation
virtual bool is_ndef_supported() const;
// NFCNDEFCapable implementation
virtual bool is_ndef_supported() const;
// Callbacks from NFC stack
void disconnected_callback(bool deselected);
static void s_disconnected_callback(nfc_tech_iso7816_t* pIso7816, bool deselected, void* pUserData);
// Callbacks from NFC stack
void disconnected_callback(bool deselected);
static void s_disconnected_callback(nfc_tech_iso7816_t *pIso7816, bool deselected, void *pUserData);
NFCController* _controller;
bool _is_connected;
bool _is_disconnected;
nfc_tech_iso7816_t _iso7816;
nfc_tech_type4_target_t _type4;
};
NFCController *_controller;
bool _is_connected;
bool _is_disconnected;
nfc_tech_iso7816_t _iso7816;
nfc_tech_type4_target_t _type4;
};
/**
* @}
*/
/**
* @}
*/
} // namespace nfc
} // namespace mbed

View File

@ -16,17 +16,18 @@
#include "PN512Driver.h"
PN512Driver::PN512Driver(PN512TransportDriver* transport_driver) : NFCControllerDriver(), _transport_driver(transport_driver) {
PN512Driver::PN512Driver(PN512TransportDriver *transport_driver) : NFCControllerDriver(), _transport_driver(transport_driver)
{
_transport_driver->set_delegate(this);
}
nfc_transceiver_t* PN512Driver::initialize(nfc_scheduler_timer_t* scheduler_timer) {
nfc_transceiver_t *PN512Driver::initialize(nfc_scheduler_timer_t *scheduler_timer)
{
// Initialize transport
_transport_driver->initialize();
nfc_err_t ret = pn512_init(&pn512, _transport_driver->get_transport(), scheduler_timer);
if( ret != NFC_OK )
{
if (ret != NFC_OK) {
NFC_ERR("PN512 init error (%d)", ret);
return NULL;
}
@ -35,7 +36,8 @@ nfc_transceiver_t* PN512Driver::initialize(nfc_scheduler_timer_t* scheduler_time
return pn512_get_transceiver(&pn512);
}
void PN512Driver::get_supported_nfc_techs(nfc_tech_t* initiator, nfc_tech_t* target) const {
void PN512Driver::get_supported_nfc_techs(nfc_tech_t *initiator, nfc_tech_t *target) const
{
initiator->nfc_type1 = 0;
initiator->nfc_type2 = 1;
initiator->nfc_type3 = 1;
@ -55,6 +57,7 @@ void PN512Driver::get_supported_nfc_techs(nfc_tech_t* initiator, nfc_tech_t* tar
target->nfc_nfc_dep_f_424 = 1;
}
void PN512Driver::on_hw_interrupt() {
void PN512Driver::on_hw_interrupt()
{
hw_interrupt(); // Propagate interrupt signal
}

View File

@ -22,12 +22,13 @@
using namespace mbed;
using namespace mbed::nfc;
PN512SPITransportDriver::PN512SPITransportDriver(PinName mosi, PinName miso, PinName sclk, PinName ssel, PinName irq, PinName rst)) :
PN512SPITransportDriver::PN512SPITransportDriver(PinName mosi, PinName miso, PinName sclk, PinName ssel, PinName irq, PinName rst)) :
_spi(mosi, miso, sclk),
_ssel(ssel, 1),
_irq(irq, PullNone),
_rst(rst, 1) {
_rst(rst, 1)
{
// Use SPI mode 0
_spi.format(8, 0);
@ -38,7 +39,8 @@ PN512SPITransportDriver::PN512SPITransportDriver(PinName mosi, PinName miso, Pin
nfc_transport_init(&_nfc_transport, &PN512SPITransportDriver::s_transport_write, &PN512SPITransportDriver::s_transport_read, this);
}
void PN512SPITransportDriver::initialize() {
void PN512SPITransportDriver::initialize()
{
// Deactivate IRQ
_irq.rise(callback(NULL));
@ -53,12 +55,14 @@ void PN512SPITransportDriver::initialize() {
_irq.rise(callback(this, &PN512SPITransportDriver::hw_interrupt));
}
nfc_transport_t* PN512SPITransportDriver::get_transport() const {
nfc_transport_t *PN512SPITransportDriver::get_transport() const
{
return &_nfc_transport;
}
void PN512SPITransportDriver::transport_write( uint8_t address, const uint8_t* outBuf, size_t outLen ) {
if( outLen == 0 ) {
void PN512SPITransportDriver::transport_write(uint8_t address, const uint8_t *outBuf, size_t outLen)
{
if (outLen == 0) {
return;
}
@ -70,19 +74,20 @@ void PN512SPITransportDriver::transport_write( uint8_t address, const uint8_t* o
_ssel = 1;
}
void PN512SPITransportDriver::transport_read( uint8_t address, uint8_t* inBuf, size_t inLen ) {
if( inLen == 0 ) {
void PN512SPITransportDriver::transport_read(uint8_t address, uint8_t *inBuf, size_t inLen)
{
if (inLen == 0) {
return;
}
// Address byte is (address << 1) | 0x80 for a read
// This should be repeated accross the transfer, except for the last byte which should be 0
address = (address << 1) | 0x80;
// Set this byte across inBuf so that it's repeated accross the transfer
// Bit cheeky, but will work
memset(inBuf, address, inLen - 1);
// Also terminate with 0 so that it's a no-op
inBuf[inLen - 1] = 0;
@ -93,12 +98,14 @@ void PN512SPITransportDriver::transport_read( uint8_t address, uint8_t* inBuf, s
}
// Callbacks from munfc
static void PN512SPITransportDriver::s_transport_write( uint8_t address, const uint8_t* outBuf, size_t outLen, void* pUser ) {
PN512SPITransportDriver* self = (PN512SPITransportDriver*)pUser;
static void PN512SPITransportDriver::s_transport_write(uint8_t address, const uint8_t *outBuf, size_t outLen, void *pUser)
{
PN512SPITransportDriver *self = (PN512SPITransportDriver *)pUser;
self->transport_write(address, outBuf, outLen);
}
static void PN512SPITransportDriver::s_transport_read( uint8_t address, uint8_t* inBuf, size_t inLen, void* pUser ) {
PN512SPITransportDriver* self = (PN512SPITransportDriver*)pUser;
static void PN512SPITransportDriver::s_transport_read(uint8_t address, uint8_t *inBuf, size_t inLen, void *pUser)
{
PN512SPITransportDriver *self = (PN512SPITransportDriver *)pUser;
self->transport_read(address, inBuf, inLen);
}

View File

@ -19,16 +19,19 @@
using namespace mbed;
using namespace mbed::nfc;
PN512TransportDriver::PN512TransportDriver() : _delegate(NULL) {
PN512TransportDriver::PN512TransportDriver() : _delegate(NULL)
{
}
void PN512TransportDriver::set_delegate(Delegate* delegate) {
void PN512TransportDriver::set_delegate(Delegate *delegate)
{
_delegate = delegate;
}
void PN512TransportDriver::hw_interrupt() {
if(_delegate != NULL) {
void PN512TransportDriver::hw_interrupt()
{
if (_delegate != NULL) {
_delegate->on_hw_interrupt();
}
}

View File

@ -23,7 +23,7 @@
using namespace mbed;
using namespace mbed::nfc;
NFCController::NFCController(NFCControllerDriver* driver, events::EventQueue* queue, uint8_t* ndef_buffer, size_t ndef_buffer_sz) :
NFCController::NFCController(NFCControllerDriver *driver, events::EventQueue *queue, uint8_t *ndef_buffer, size_t ndef_buffer_sz) :
_driver(driver), _queue(queue), _transceiver(NULL), _scheduler(NULL), _delegate(NULL), _discovery_running(false), _ndef_buffer_sz(ndef_buffer_sz)
{
_driver->set_delegate(this);
@ -32,9 +32,9 @@ NFCController::NFCController(NFCControllerDriver* driver, events::EventQueue* qu
nfc_err_t NFCController::initialize()
{
MBED_ASSERT(_transceiver == NULL); // Initialize should only be called once
_transceiver = _driver->initialize((nfc_scheduler_timer_t*)&_timer); // See implementation below
_transceiver = _driver->initialize((nfc_scheduler_timer_t *)&_timer); // See implementation below
if( _transceiver == NULL ) {
if (_transceiver == NULL) {
// Initialization error
return NFC_ERR_CONTROLLER; // Controller error
}
@ -46,7 +46,7 @@ nfc_err_t NFCController::initialize()
_queue->call(this, NFCController::scheduler_process, false);
}
void NFCController::set_delegate(Delegate* delegate)
void NFCController::set_delegate(Delegate *delegate)
{
_delegate = delegate;
}
@ -69,19 +69,19 @@ nfc_rf_protocols_bitmask_t NFCController::get_supported_rf_protocols() const
// rf_protocols.initiator_t3t = initiator_tech.nfc_type3;
// rf_protocols.initiator_iso_dep = initiator_tech.nfc_iso_dep_a || initiator_tech.nfc_iso_dep_b;
// rf_protocols.initiator_nfc_dep = initiator_tech.nfc_nfc_dep_a || initiator_tech.nfc_nfc_dep_f_212 || initiator_tech.nfc_nfc_dep_f_424;
// rf_protocols.target_t1t = target_tech.nfc_type1;
// rf_protocols.target_t2t = target_tech.nfc_type2;
// rf_protocols.target_t3t = target_tech.nfc_type3;
rf_protocols.target_iso_dep = target_tech.nfc_iso_dep_a || target_tech.nfc_iso_dep_b;
// rf_protocols.target_nfc_dep = target_tech.nfc_nfc_dep_a || target_tech.nfc_nfc_dep_f_212 || target_tech.nfc_nfc_dep_f_424;
return rf_protocols;
}
nfc_err_t NFCController::configure_rf_protocols(nfc_rf_protocols_bitmask_t rf_protocols)
{
if( _discovery_running ) {
if (_discovery_running) {
// Cannot configure RF protocols if discovery is running
return NFC_ERR_BUSY;
}
@ -103,7 +103,7 @@ nfc_err_t NFCController::configure_rf_protocols(nfc_rf_protocols_bitmask_t rf_pr
nfc_err_t NFCController::start_discovery()
{
if( _discovery_running ) {
if (_discovery_running) {
// Cannot start discovery if it's already running
return NFC_ERR_BUSY;
}
@ -113,14 +113,14 @@ nfc_err_t NFCController::start_discovery()
nfc_err_t NFCController::cancel_discovery()
{
if( !_discovery_running ) {
if (!_discovery_running) {
return NFC_OK;
}
transceiver_abort(_transceiver);
}
nfc_transceiver_t* NFCController::transceiver() const
nfc_transceiver_t *NFCController::transceiver() const
{
return _transceiver;
}
@ -130,16 +130,16 @@ void NFCController::polling_callback(nfc_err_t ret)
// Polling has completed
_discovery_running = false;
if( ret == NFC_OK ) {
if (ret == NFC_OK) {
// Check if a remote initiator was detected and if so, instantiate it
if( !transceiver_is_initiator_mode(_transceiver) ) {
if (!transceiver_is_initiator_mode(_transceiver)) {
nfc_tech_t active_tech = transceiver_get_active_techs(_transceiver);
if( active_tech.nfc_iso_dep_a || active_tech.nfc_iso_dep_b ) {
if (active_tech.nfc_iso_dep_a || active_tech.nfc_iso_dep_b) {
Type4RemoteInitiator type4_remote_initiator_ptr = new (std::nothrow) Type4RemoteInitiator(_transceiver, _ndef_buffer, _ndef_buffer_sz);
if( type4_remote_initiator_ptr == NULL ) {
if (type4_remote_initiator_ptr == NULL) {
// No memory :(
SharedPtr<Type4RemoteInitiator> type4_remote_initiator( type4_remote_initiator_ptr );
if( _delegate != NULL ) {
SharedPtr<Type4RemoteInitiator> type4_remote_initiator(type4_remote_initiator_ptr);
if (_delegate != NULL) {
_delegate->on_nfc_initiator_discovered(type4_remote_initiator);
}
}
@ -147,11 +147,11 @@ void NFCController::polling_callback(nfc_err_t ret)
}
}
if( _delegate != NULL ) {
if (_delegate != NULL) {
nfc_discovery_terminated_reason_t reason;
// Map reason
switch(ret) {
switch (ret) {
case NFC_OK:
reason = nfc_discovery_terminated_completed;
break;
@ -168,53 +168,61 @@ void NFCController::polling_callback(nfc_err_t ret)
}
}
void NFCController::scheduler_process(bool hw_interrupt) {
void NFCController::scheduler_process(bool hw_interrupt)
{
_timer.detach(); // Cancel timeout - if it triggers, it's ok as we'll have an "early" iteration which will likely be a no-op
// Process stack events
uint32_t timeout = nfc_scheduler_iteration(_scheduler, hw_interrupt?EVENT_HW_INTERRUPT:EVENT_NONE);
uint32_t timeout = nfc_scheduler_iteration(_scheduler, hw_interrupt ? EVENT_HW_INTERRUPT : EVENT_NONE);
_timer.attach(callback(this, &NFCController::on_timeout));
}
void NFCController::on_hw_interrupt() {
void NFCController::on_hw_interrupt()
{
// Run scheduler - this is called in interrupt context
_timer.detach(); // Cancel timeout - if it triggers anyways, it's ok
_queue->call(this, NFCController::scheduler_process, true);
}
void NFCController::on_timeout() {
void NFCController::on_timeout()
{
// Run scheduler - this is called in interrupt context
_queue->call(this, NFCController::scheduler_process, false);
}
static void NFCController::s_polling_callback(nfc_transceiver_t* pTransceiver, nfc_err_t ret, void* pUserData)
static void NFCController::s_polling_callback(nfc_transceiver_t *pTransceiver, nfc_err_t ret, void *pUserData)
{
NFCController* self = (NFCController*) pUserData;
NFCController *self = (NFCController *) pUserData;
self->polling_callback(ret);
}
// Implementation nfc_scheduler_timer_t
void nfc_scheduler_timer_init(nfc_scheduler_timer_t* timer) {
void nfc_scheduler_timer_init(nfc_scheduler_timer_t *timer)
{
(void)timer; // This is a no-op
}
void nfc_scheduler_timer_start(nfc_scheduler_timer_t* timer) {
Timer* mbed_timer = (Timer*)timer;
void nfc_scheduler_timer_start(nfc_scheduler_timer_t *timer)
{
Timer *mbed_timer = (Timer *)timer;
mbed_timer->start();
}
uint32_t nfc_scheduler_timer_get(nfc_scheduler_timer_t* timer) {
Timer* mbed_timer = (Timer*)timer;
uint32_t nfc_scheduler_timer_get(nfc_scheduler_timer_t *timer)
{
Timer *mbed_timer = (Timer *)timer;
return (uint32_t)mbed_timer->read_ms();
}
void nfc_scheduler_timer_stop(nfc_scheduler_timer_t* timer) {
Timer* mbed_timer = (Timer*)timer;
void nfc_scheduler_timer_stop(nfc_scheduler_timer_t *timer)
{
Timer *mbed_timer = (Timer *)timer;
mbed_timer->stop();
}
void nfc_scheduler_timer_reset(nfc_scheduler_timer_t* timer) {
Timer* mbed_timer = (Timer*)timer;
void nfc_scheduler_timer_reset(nfc_scheduler_timer_t *timer)
{
Timer *mbed_timer = (Timer *)timer;
mbed_timer->reset();
}

View File

@ -19,16 +19,19 @@
using namespace mbed;
using namespace mbed::nfc;
NFCControllerDriver::NFCControllerDriver() : _delegate(NULL) {
NFCControllerDriver::NFCControllerDriver() : _delegate(NULL)
{
}
void NFCControllerDriver::set_delegate(Delegate* delegate) {
void NFCControllerDriver::set_delegate(Delegate *delegate)
{
_delegate = delegate;
}
void NFCControllerDriver::hw_interrupt() {
if(_delegate != NULL) {
void NFCControllerDriver::hw_interrupt()
{
if (_delegate != NULL) {
_delegate->on_hw_interrupt();
}
}

View File

@ -20,13 +20,14 @@
using namespace mbed;
using namespace mbed::nfc;
NFCEEPROM(NFCEEPROMDriver* driver, events::EventQueue* queue, uint8_t* ndef_buffer, size_t ndef_buffer_sz) : NFCTarget( ndef_buffer, ndef_buffer_sz )
_driver(driver), _queue(queue), _initialized(false), _current_op(nfc_eeprom_idle), _eeprom_address(0), _operation_result(NFC_ERR_UNKNOWN)
NFCEEPROM(NFCEEPROMDriver *driver, events::EventQueue *queue, uint8_t *ndef_buffer, size_t ndef_buffer_sz) : NFCTarget(ndef_buffer, ndef_buffer_sz)
_driver(driver), _queue(queue), _initialized(false), _current_op(nfc_eeprom_idle), _eeprom_address(0), _operation_result(NFC_ERR_UNKNOWN)
{
_driver->set_delegate(this);
}
nfc_err_t NFCEEPROM::initialize() {
nfc_err_t NFCEEPROM::initialize()
{
MBED_ASSERT(_initialized == false); // Initialize should only be called once
// Initialize driver
@ -34,14 +35,16 @@ nfc_err_t NFCEEPROM::initialize() {
_initialized = true;
}
void NFCEEPROM::set_delegate(NFCEEPROM::Delegate* delegate) {
void NFCEEPROM::set_delegate(NFCEEPROM::Delegate *delegate)
{
_delegate = delegate;
}
void NFCEEPROM::write_ndef_message() {
void NFCEEPROM::write_ndef_message()
{
MBED_ASSERT(_initialized == true);
if(_current_op != nfc_eeprom_idle) {
if(_delegate != NULL) {
if (_current_op != nfc_eeprom_idle) {
if (_delegate != NULL) {
_delegate->on_ndef_message_written(NFC_ERR_BUSY);
}
return;
@ -51,32 +54,33 @@ void NFCEEPROM::write_ndef_message() {
ndef_msg_encode(ndef_message());
_current_op = nfc_eeprom_write_start_session;
// Retrieve reader
ac_buffer_dup(&_ndef_buffer_reader, ac_buffer_builder_buffer(ndef_msg_buffer_builder(ndef_message()) );
// Check that NDEF message is not too big
if( ac_buffer_reader_readable(&_ndef_buffer_reader) > _driver->get_max_size() ) {
handle_error(NFC_ERR_BUFFER_TOO_SMALL);
// Retrieve reader
ac_buffer_dup(&_ndef_buffer_reader, ac_buffer_builder_buffer(ndef_msg_buffer_builder(ndef_message()));
// Check that NDEF message is not too big
if (ac_buffer_reader_readable(&_ndef_buffer_reader) > _driver->get_max_size()) {
handle_error(NFC_ERR_BUFFER_TOO_SMALL);
return;
}
// Reset EEPROM address
_eeprom_address = 0;
// Go through the steps!
_driver->start_session();
// Go through the steps!
_driver->start_session();
// 1 - Start session
// 2 - Write bytes (can be repeated)
// 3 - Set NDEF message size
// 4 - End session
// 1 - Start session
// 2 - Write bytes (can be repeated)
// 3 - Set NDEF message size
// 4 - End session
}
void NFCEEPROM::read_ndef_message() {
void NFCEEPROM::read_ndef_message()
{
MBED_ASSERT(_initialized == true);
if(_current_op != nfc_eeprom_idle) {
if(_delegate != NULL) {
if (_current_op != nfc_eeprom_idle) {
if (_delegate != NULL) {
_delegate->on_ndef_message_written(NFC_ERR_BUSY);
}
return;
@ -96,13 +100,14 @@ void NFCEEPROM::read_ndef_message() {
// 4 - End session
}
void NFCEEPROM::erase_ndef_message() {
void NFCEEPROM::erase_ndef_message()
{
// We don't want to take any risks, so erase the whole address space
// And set the message size to 0
MBED_ASSERT(_initialized == true);
if(_current_op != nfc_eeprom_idle) {
if(_delegate != NULL) {
if (_current_op != nfc_eeprom_idle) {
if (_delegate != NULL) {
_delegate->on_ndef_message_erased(NFC_ERR_BUSY);
}
return;
@ -122,10 +127,11 @@ void NFCEEPROM::erase_ndef_message() {
// 4 - End session
}
void NFCEEPROM::on_session_started(bool success) {
switch(_current_op) {
void NFCEEPROM::on_session_started(bool success)
{
switch (_current_op) {
case nfc_eeprom_write_start_session:
if(!success) {
if (!success) {
handle_error(NFC_ERR_CONTROLLER); // An EEPROM is not really a controller but close enough
return;
}
@ -134,7 +140,7 @@ void NFCEEPROM::on_session_started(bool success) {
break;
case nfc_eeprom_read_start_session:
if(!success) {
if (!success) {
handle_error(NFC_ERR_CONTROLLER);
return;
}
@ -143,7 +149,7 @@ void NFCEEPROM::on_session_started(bool success) {
break;
case nfc_eeprom_erase_start_session:
if(!success) {
if (!success) {
handle_error(NFC_ERR_CONTROLLER);
return;
}
@ -158,21 +164,22 @@ void NFCEEPROM::on_session_started(bool success) {
}
}
void NFCEEPROM::on_session_ended(bool success) {
switch(_current_op) {
void NFCEEPROM::on_session_ended(bool success)
{
switch (_current_op) {
case nfc_eeprom_write_end_session:
if(!success) {
if (!success) {
handle_error(NFC_ERR_CONTROLLER);
return;
}
_current_op = nfc_eeprom_idle;
if( _delegate != NULL ) {
if (_delegate != NULL) {
_driver->on_ndef_message_written(_operation_result);
}
break;
case nfc_eeprom_read_end_session:
if(!success) {
if (!success) {
handle_error(NFC_ERR_CONTROLLER);
return;
}
@ -181,18 +188,18 @@ void NFCEEPROM::on_session_ended(bool success) {
// Try to parse the NDEF message
ndef_msg_decode(ndef_message());
if( _delegate != NULL ) {
if (_delegate != NULL) {
_driver->on_ndef_message_read(_operation_result);
}
break;
case nfc_eeprom_erase_end_session:
if(!success) {
if (!success) {
handle_error(NFC_ERR_CONTROLLER);
return;
}
_current_op = nfc_eeprom_idle;
if( _delegate != NULL ) {
if (_delegate != NULL) {
_driver->on_ndef_message_erased(_operation_result);
}
break;
@ -204,17 +211,18 @@ void NFCEEPROM::on_session_ended(bool success) {
}
}
void NFCEEPROM::on_bytes_read(size_t count) {
switch(_current_op) {
void NFCEEPROM::on_bytes_read(size_t count)
{
switch (_current_op) {
case nfc_eeprom_read_read_bytes:
if(count == 0) {
if (count == 0) {
handle_error(NFC_ERR_CONTROLLER);
return;
}
// Discard bytes that were actually read and update address
_eeprom_address += count;
ac_buffer_builder_t* buffer_builder = ndef_msg_buffer_builder(ndef_message());
ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message());
ac_buffer_builder_write_n_skip(buffer_builder, count);
// Continue reading
@ -227,10 +235,11 @@ void NFCEEPROM::on_bytes_read(size_t count) {
}
}
void NFCEEPROM::on_bytes_written(size_t count) {
switch(_current_op) {
void NFCEEPROM::on_bytes_written(size_t count)
{
switch (_current_op) {
case nfc_eeprom_write_write_bytes:
if(count == 0) {
if (count == 0) {
handle_error(NFC_ERR_CONTROLLER);
return;
}
@ -249,10 +258,11 @@ void NFCEEPROM::on_bytes_written(size_t count) {
}
}
void NFCEEPROM::on_size_written(bool success) {
switch(_current_op) {
void NFCEEPROM::on_size_written(bool success)
{
switch (_current_op) {
case nfc_eeprom_write_write_size:
if(!success) {
if (!success) {
handle_error(NFC_ERR_CONTROLLER);
return;
}
@ -263,7 +273,7 @@ void NFCEEPROM::on_size_written(bool success) {
_driver->end_session();
break;
case nfc_eeprom_erase_write_size:
if(!success) {
if (!success) {
handle_error(NFC_ERR_CONTROLLER);
return;
}
@ -280,21 +290,21 @@ void NFCEEPROM::on_size_written(bool success) {
}
}
void NFCEEPROM::on_size_read(bool success, size_t size) {
switch(_current_op) {
void NFCEEPROM::on_size_read(bool success, size_t size)
{
switch (_current_op) {
case nfc_eeprom_read_read_size:
if(!success) {
if (!success) {
handle_error(NFC_ERR_CONTROLLER);
return;
}
// Reset NDEF message buffer builder
ac_buffer_builder_t* buffer_builder = ndef_msg_buffer_builder(ndef_message());
ac_buffer_builder_reset( buffer_builder );
ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message());
ac_buffer_builder_reset(buffer_builder);
// Check that we have a big enough buffer to read the message
if( size > ac_buffer_builder_writable(buffer_builder) )
{
if (size > ac_buffer_builder_writable(buffer_builder)) {
// Not enough space, close session
_current_op = nfc_eeprom_read_end_session;
_operation_result = NFC_ERR_BUFFER_TOO_SMALL;
@ -317,10 +327,11 @@ void NFCEEPROM::on_size_read(bool success, size_t size) {
}
}
void NFCEEPROM::on_bytes_erased(size_t count) {
switch(_current_op) {
void NFCEEPROM::on_bytes_erased(size_t count)
{
switch (_current_op) {
case nfc_eeprom_erase_erase_bytes:
if(count == 0) {
if (count == 0) {
handle_error(NFC_ERR_CONTROLLER);
return;
}
@ -338,61 +349,61 @@ void NFCEEPROM::on_bytes_erased(size_t count) {
}
}
void NFCEEPROM::on_event() {
void NFCEEPROM::on_event()
{
// Just schedule a task on event queue
_queue->call(_driver, NFCEEPROMDriver::process_events);
}
void NFCEEPROM::continue_write() {
if( ac_buffer_reader_readable(&_ndef_buffer_reader) > 0 ) {
void NFCEEPROM::continue_write()
{
if (ac_buffer_reader_readable(&_ndef_buffer_reader) > 0) {
// Continue writing
_driver->write_bytes(_eeprom_address, ac_buffer_reader_current_buffer_pointer(&_ndef_buffer_reader), ac_buffer_reader_current_buffer_length(&_ndef_buffer_reader));
}
else {
} else {
// Now update size
_current_op = nfc_eeprom_write_write_size;
_driver->write_size(_eeprom_address);
}
}
void NFCEEPROM::continue_erase() {
if( _eeprom_address < _driver->get_max_size() ) {
void NFCEEPROM::continue_erase()
{
if (_eeprom_address < _driver->get_max_size()) {
// Continue erasing
_driver->erase_bytes(_eeprom_address, _driver->get_max_size() - _eeprom_address);
}
else {
} else {
// Now update size
_current_op = nfc_eeprom_erase_write_size;
_driver->write_size(0);
}
}
void NFCEEPROM::continue_read() {
if( _eeprom_address < _ndef_buffer_read_sz ) {
void NFCEEPROM::continue_read()
{
if (_eeprom_address < _ndef_buffer_read_sz) {
// Continue reading
ac_buffer_builder_t* buffer_builder = ndef_msg_buffer_builder(ndef_message());
ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message());
_driver->read_bytes(_eeprom_address, ac_buffer_builder_write_position(buffer_builder), _ndef_buffer_read_sz - _eeprom_address);
}
else {
} else {
// Done, close session
_operation_result = NFC_OK;
_driver->end_session();
}
}
void NFCEEPROM::handle_error(nfc_err_t ret) {
void NFCEEPROM::handle_error(nfc_err_t ret)
{
// Save & reset current op
nfc_eeprom_operation_t last_op = _current_op;
_current_op = nfc_eeprom_idle;
if(_delegate != NULL) {
if(last_op <= nfc_eeprom_write_end_session) {
if (_delegate != NULL) {
if (last_op <= nfc_eeprom_write_end_session) {
_delegate->on_ndef_message_written(ret);
}
else if(last_op <= nfc_eeprom_read_end_session) {
} else if (last_op <= nfc_eeprom_read_end_session) {
_delegate->on_ndef_message_read(ret);
}
else if(last_op <= nfc_eeprom_erase_end_session) {
} else if (last_op <= nfc_eeprom_erase_end_session) {
_delegate->on_ndef_message_erased(ret);
}
}

View File

@ -19,10 +19,12 @@
using namespace mbed;
using namespace mbed::nfc;
NFCEEPROMDriver::NFCEEPROMDriver() : _delegate(NULL) {
NFCEEPROMDriver::NFCEEPROMDriver() : _delegate(NULL)
{
}
void NFCEEPROMDriver::set_delegate(Delegate* delegate) {
void NFCEEPROMDriver::set_delegate(Delegate *delegate)
{
_delegate = delegate;
}

View File

@ -25,49 +25,53 @@
using namespace mbed;
using namespace mbed::nfc;
NFCNDEFCapable::NFCNDEFCapable(uint8_t* buffer, size_t buffer_size) : _delegate(NULL)
NFCNDEFCapable::NFCNDEFCapable(uint8_t *buffer, size_t buffer_size) : _delegate(NULL)
{
ndef_msg_init(&_ndef_message, s_encode_callback, s_decode_callback);
}
void NFCNDEFCapable::set_ndef_delegate(NFCNDEFCapable::Delegate* delegate)
void NFCNDEFCapable::set_ndef_delegate(NFCNDEFCapable::Delegate *delegate)
{
_delegate = delegate;
}
void NFCNDEFCapable::parse_ndef_message(const ac_buffer_t& buffer)
void NFCNDEFCapable::parse_ndef_message(const ac_buffer_t &buffer)
{
ac_buffer_t reader;
ac_buffer_dup(&reader, &buffer);
if(_delegate != NULL) {
if (_delegate != NULL) {
_delegate->parse_ndef_message(ac_buffer_reader_current_buffer_pointer(&reader), ac_buffer_reader_current_buffer_length(&reader));
}
}
void NFCNDEFCapable::build_ndef_message(ac_buffer_builder_t& buffer_builder)
void NFCNDEFCapable::build_ndef_message(ac_buffer_builder_t &buffer_builder)
{
if(_delegate != NULL) {
size_t count = _delegate->build_ndef_message( ac_buffer_builder_write_position(&buffer_builder), ac_buffer_builder_writable(&buffer_builder) );
if (_delegate != NULL) {
size_t count = _delegate->build_ndef_message(ac_buffer_builder_write_position(&buffer_builder), ac_buffer_builder_writable(&buffer_builder));
ac_buffer_builder_write_n_skip(&buffer_builder, count);
}
}
nfc_err_t NFCNDEFCapable::s_ndef_encode(ndef_msg_t* pTag, buffer_builder_t* pBufferBldr, void* pUserData) {
NFCNDEFCapable* self = (NFCNDEFCapable*)pUserData;
nfc_err_t NFCNDEFCapable::s_ndef_encode(ndef_msg_t *pTag, buffer_builder_t *pBufferBldr, void *pUserData)
{
NFCNDEFCapable *self = (NFCNDEFCapable *)pUserData;
self->ndef_encode(pBufferBldr);
}
nfc_err_t NFCNDEFCapable::s_ndef_decode(ndef_msg_t* pTag, buffer_t* pBuffer, void* pUserData) {
NFCNDEFCapable* self = (NFCNDEFCapable*)pUserData;
nfc_err_t NFCNDEFCapable::s_ndef_decode(ndef_msg_t *pTag, buffer_t *pBuffer, void *pUserData)
{
NFCNDEFCapable *self = (NFCNDEFCapable *)pUserData;
self->ndef_decode(pBuffer);
}
nfc_err_t NFCNDEFCapable::ndef_encode(buffer_builder_t* pBufferBldr) {
nfc_err_t NFCNDEFCapable::ndef_encode(buffer_builder_t *pBufferBldr)
{
build_ndef_message(buffer_builder);
return NFC_OK;
}
nfc_err_t NFCNDEFCapable::ndef_decode(buffer_t* pBuffer) {
nfc_err_t NFCNDEFCapable::ndef_decode(buffer_t *pBuffer)
{
parse_ndef_message(pBuffer);
return NFC_OK;
}

View File

@ -25,19 +25,21 @@
using namespace mbed;
using namespace mbed::nfc;
NFCRemoteEndpoint::NFCRemoteEndpoint(NFCController* controller) : _controller(controller), _is_lost(false) {
NFCRemoteEndpoint::NFCRemoteEndpoint(NFCController *controller) : _controller(controller), _is_lost(false)
{
}
bool NFCRemoteEndpoint::is_lost() const {
bool NFCRemoteEndpoint::is_lost() const
{
return _is_lost;
}
nfc_rf_protocols_bitmask_t NFCRemoteEndpoint::rf_protocols() {
nfc_rf_protocols_bitmask_t NFCRemoteEndpoint::rf_protocols()
{
nfc_rf_protocols_bitmask_t rf_protocols = {0};
nfc_tech_t active_tech = transceiver_get_active_techs(_transceiver);
if(!transceiver_is_initiator_mode(_transceiver))
{
if (!transceiver_is_initiator_mode(_transceiver)) {
// Note: We only support ISO-DEP for now
rf_protocols.target_iso_dep = active_tech.nfc_iso_dep_a || active_tech.nfc_iso_dep_b;
}
@ -45,11 +47,13 @@ nfc_rf_protocols_bitmask_t NFCRemoteEndpoint::rf_protocols() {
return rf_protocols;
}
void NFCRemoteEndpoint::set_lost() {
void NFCRemoteEndpoint::set_lost()
{
_is_lost = true;
}
NFCController* NFCRemoteEndpoint::nfc_controller() const {
NFCController *NFCRemoteEndpoint::nfc_controller() const
{
return _controller;
}

View File

@ -19,17 +19,19 @@
using namespace mbed;
using namespace mbed::nfc;
NFCRemoteInitiator::NFCRemoteInitiator(NFCController* controller, uint8_t* buffer, size_t buffer_size) :
NFCRemoteEndpoint(controller), NFCNDEFCapable(buffer, buffer_size) {
NFCRemoteInitiator::NFCRemoteInitiator(NFCController *controller, uint8_t *buffer, size_t buffer_size) :
NFCRemoteEndpoint(controller), NFCNDEFCapable(buffer, buffer_size)
{
}
NFCRemoteInitiator::~NFCRemoteInitiator() {
NFCRemoteInitiator::~NFCRemoteInitiator()
{
}
void NFCRemoteInitiator::set_remote_initiator_delegate(Delegate* delegate)
void NFCRemoteInitiator::set_remote_initiator_delegate(Delegate *delegate)
{
_delegate = delegate;
}

View File

@ -19,11 +19,13 @@
using namespace mbed;
using namespace mbed::nfc;
NFCTarget::NFCTarget(uint8_t* buffer, size_t buffer_size) :
NFCNDEFCapable(buffer, buffer_size) {
NFCTarget::NFCTarget(uint8_t *buffer, size_t buffer_size) :
NFCNDEFCapable(buffer, buffer_size)
{
}
NFCTarget::~NFCTarget() {
NFCTarget::~NFCTarget()
{
}

View File

@ -28,22 +28,24 @@
using namespace mbed;
using namespace mbed::nfc;
Type4RemoteInitiator::Type4RemoteInitiator(NFCController* controller, uint8_t* buffer, size_t buffer_size) :
Type4RemoteInitiator::Type4RemoteInitiator(NFCController *controller, uint8_t *buffer, size_t buffer_size) :
NFCRemoteInitiator(ndef_buffer, ndef_buffer_sz),
_controller(controller), _is_connected(false) , _is_disconnected(false), _apps(NULL) {
_controller(controller), _is_connected(false), _is_disconnected(false), _apps(NULL)
{
// Init ISO7816
nfc_tech_iso7816_init(&_iso7816, _controller->transceiver(), &Type4RemoteInitiator::s_disconnected_callback, this);
// Init Type 4 app
nfc_tech_type4_target_init(&_type4, &_iso7816, ndef_message());
}
nfc_err_t Type4RemoteInitiator::connect() {
if(_is_connected) {
nfc_err_t Type4RemoteInitiator::connect()
{
if (_is_connected) {
return NFC_BUSY;
}
if(_is_disconnected) {
if (_is_disconnected) {
return NFC_ERR_DISCONNECTED;
}
@ -54,12 +56,13 @@ nfc_err_t Type4RemoteInitiator::connect() {
connected();
}
nfc_err_t Type4RemoteInitiator::disconnect() {
if(!_is_connected) {
nfc_err_t Type4RemoteInitiator::disconnect()
{
if (!_is_connected) {
return NFC_OK;
}
if(_is_disconnected) {
if (_is_disconnected) {
return NFC_OK;
}
@ -67,19 +70,21 @@ nfc_err_t Type4RemoteInitiator::disconnect() {
nfc_tech_iso7816_disconnect(&_iso7816);
}
bool Type4RemoteInitiator::is_connected() const {
bool Type4RemoteInitiator::is_connected() const
{
return _is_connected;
}
bool Type4RemoteInitiator::is_disconnected() const {
bool Type4RemoteInitiator::is_disconnected() const
{
return _is_disconnected;
}
nfc_rf_protocols_bitmask_t Type4RemoteInitiator::rf_protocols() {
nfc_rf_protocols_bitmask_t Type4RemoteInitiator::rf_protocols()
{
nfc_rf_protocols_bitmask_t rf_protocols = {0};
nfc_tech_t active_tech = transceiver_get_active_techs(_transceiver);
if(!transceiver_is_initiator_mode(_transceiver))
{
if (!transceiver_is_initiator_mode(_transceiver)) {
// We only support ISO-DEP
rf_protocols.target_iso_dep = active_tech.nfc_iso_dep_a || active_tech.nfc_iso_dep_b;
}
@ -87,24 +92,27 @@ nfc_rf_protocols_bitmask_t Type4RemoteInitiator::rf_protocols() {
return rf_protocols;
}
virtual nfc_tag_type_t Type4RemoteInitiator::nfc_tag_type() const {
virtual nfc_tag_type_t Type4RemoteInitiator::nfc_tag_type() const
{
nfc_tech_t active_tech = transceiver_get_active_techs(_transceiver);
if(active_tech.nfc_iso_dep_a) {
if (active_tech.nfc_iso_dep_a) {
return nfc_tag_type_4a;
}
else { // if(active_tech.nfc_iso_dep_b)
} else { // if(active_tech.nfc_iso_dep_b)
return nfc_tag_type_4b;
}
}
virtual bool Type4RemoteInitiator::is_iso7816_supported() const {
virtual bool Type4RemoteInitiator::is_iso7816_supported() const
{
return true;
}
virtual void Type4RemoteInitiator::add_iso7816_application(ISO7816App* application) {
virtual void Type4RemoteInitiator::add_iso7816_application(ISO7816App *application)
{
nfc_tech_iso7816_add_app(&_iso7816, application->_iso7816_app);
}
virtual bool Type4RemoteInitiator::is_ndef_supported() const {
virtual bool Type4RemoteInitiator::is_ndef_supported() const
{
return true;
}

View File

@ -39,12 +39,12 @@
* \param buffer_size size of the underlying buffer
* \param pImpl pointer to actual implementation
*/
void ndef_msg_init( ndef_msg_t* pNdef, ndef_encode_fn_t encode, ndef_decode_fn_t decode, uint8_t* data, size_t size, void* pUserData )
void ndef_msg_init(ndef_msg_t *pNdef, ndef_encode_fn_t encode, ndef_decode_fn_t decode, uint8_t *data, size_t size, void *pUserData)
{
pNdef->encode = encode;
pNdef->decode = decode;
buffer_builder_init(&pNdef->bufferBldr, data, size);
pNdef->pUserData = pUserData;
pNdef->encode = encode;
pNdef->decode = decode;
buffer_builder_init(&pNdef->bufferBldr, data, size);
pNdef->pUserData = pUserData;
}
/** Get NDEF tag implementation

View File

@ -43,45 +43,42 @@ typedef struct __ndef_msg ndef_msg_t;
* \param pTag pointer to ndef_tag_t instance
* \param type pMem buffer in which to store the generated content
*/
typedef nfc_err_t (*ndef_encode_fn_t)(ndef_msg_t* pTag, buffer_builder_t* pBufferBldr, void* pUserData);
typedef nfc_err_t (*ndef_encode_fn_t)(ndef_msg_t *pTag, buffer_builder_t *pBufferBldr, void *pUserData);
/** Function called to decode the tag's content on write (target mode) or read (reader mode)
* \param pTag pointer to ndef_tag_t instance
* \param type pMem buffer containing the tag's content
*/
typedef nfc_err_t (*ndef_decode_fn_t)(ndef_msg_t* pTag, buffer_t* pBuffer, void* pUserData);
typedef nfc_err_t (*ndef_decode_fn_t)(ndef_msg_t *pTag, buffer_t *pBuffer, void *pUserData);
typedef struct __ndef_msg
{
ndef_encode_fn_t encode;
ndef_decode_fn_t decode;
buffer_builder_t bufferBldr;
void* pUserData;
typedef struct __ndef_msg {
ndef_encode_fn_t encode;
ndef_decode_fn_t decode;
buffer_builder_t bufferBldr;
void *pUserData;
} ndef_msg_t;
void ndef_msg_init( ndef_msg_t* pNdef, ndef_encode_fn_t encode, ndef_decode_fn_t decode, uint8_t* data, size_t size, void* pUserData );
void ndef_msg_init(ndef_msg_t *pNdef, ndef_encode_fn_t encode, ndef_decode_fn_t decode, uint8_t *data, size_t size, void *pUserData);
static inline nfc_err_t ndef_msg_encode(ndef_msg_t* pNdef)
static inline nfc_err_t ndef_msg_encode(ndef_msg_t *pNdef)
{
if(pNdef->encode == NULL)
{
return NFC_OK;
}
return pNdef->encode(pNdef, &pNdef->bufferBldr, pNdef->pUserData);
if (pNdef->encode == NULL) {
return NFC_OK;
}
return pNdef->encode(pNdef, &pNdef->bufferBldr, pNdef->pUserData);
}
static inline nfc_err_t ndef_msg_decode(ndef_msg_t* pNdef)
static inline nfc_err_t ndef_msg_decode(ndef_msg_t *pNdef)
{
if(pNdef->decode == NULL)
{
return NFC_OK;
}
return pNdef->decode(pNdef, buffer_builder_buffer(&pNdef->bufferBldr), pNdef->pUserData);
if (pNdef->decode == NULL) {
return NFC_OK;
}
return pNdef->decode(pNdef, buffer_builder_buffer(&pNdef->bufferBldr), pNdef->pUserData);
}
static inline buffer_builder_t* ndef_msg_buffer_builder(ndef_msg_t* pNdef)
static inline buffer_builder_t *ndef_msg_buffer_builder(ndef_msg_t *pNdef)
{
return &pNdef->bufferBldr;
return &pNdef->bufferBldr;
}
//void* ndef_tag_impl(ndef_tag_t* pNdefTag);

View File

@ -21,7 +21,8 @@
#if NFC_DEBUG && !defined(NDEBUG)
#include "stdio.h"
#include "stdarg.h"
static inline void nfc_dbg_print(const char* type, const char* module, unsigned int line, const char* fmt, ...) {
static inline void nfc_dbg_print(const char *type, const char *module, unsigned int line, const char *fmt, ...)
{
#if !defined(NDEBUG)
printf("NFC [%s] %s:%u ", type, module, line);
va_list args;

View File

@ -27,182 +27,158 @@
#include "platform/nfc_scheduler.h"
void nfc_scheduler_init(nfc_scheduler_t* pScheduler, nfc_scheduler_timer_t* pTimer)
void nfc_scheduler_init(nfc_scheduler_t *pScheduler, nfc_scheduler_timer_t *pTimer)
{
pScheduler->pNext = NULL;
pScheduler->pTimer = pTimer;
pScheduler->pNext = NULL;
pScheduler->pTimer = pTimer;
//Start timer
nfc_scheduler_timer_start(pTimer);
//Start timer
nfc_scheduler_timer_start(pTimer);
}
#define MAX_TIMEOUT UINT32_MAX
uint32_t nfc_scheduler_iteration(nfc_scheduler_t* pScheduler, uint32_t events)
uint32_t nfc_scheduler_iteration(nfc_scheduler_t *pScheduler, uint32_t events)
{
bool triggered = false;
while(true)
{
nfc_task_t* pPrioTask = NULL;
nfc_task_t* pPrioTaskPrevious = NULL;
uint32_t prioTaskEvent = 0;
int64_t timeout;
nfc_task_t* pPreviousTask = NULL;
nfc_task_t* pTask = pScheduler->pNext;
bool triggered = false;
while (true) {
nfc_task_t *pPrioTask = NULL;
nfc_task_t *pPrioTaskPrevious = NULL;
uint32_t prioTaskEvent = 0;
int64_t timeout;
nfc_task_t *pPreviousTask = NULL;
nfc_task_t *pTask = pScheduler->pNext;
if( pTask == NULL )
{
NFC_DBG("Empty queue, %lu ms elapsed", nfc_scheduler_timer_get(pScheduler->pTimer));
//Empty queue, return
return MAX_TIMEOUT;
}
if (pTask == NULL) {
NFC_DBG("Empty queue, %lu ms elapsed", nfc_scheduler_timer_get(pScheduler->pTimer));
//Empty queue, return
return MAX_TIMEOUT;
}
//Get timer value
uint32_t timeElapsed = nfc_scheduler_timer_get(pScheduler->pTimer);
NFC_DBG("%lu ms elapsed", timeElapsed);
nfc_scheduler_timer_reset(pScheduler->pTimer);
//Get timer value
uint32_t timeElapsed = nfc_scheduler_timer_get(pScheduler->pTimer);
NFC_DBG("%lu ms elapsed", timeElapsed);
nfc_scheduler_timer_reset(pScheduler->pTimer);
do
{
//Apply timeouts
if( pTask->events & EVENT_TIMEOUT )
{
pTask->timeout -= timeElapsed;
}
pPreviousTask = pTask;
pTask = pTask->pNext;
} while( pTask != NULL );
do {
//Apply timeouts
if (pTask->events & EVENT_TIMEOUT) {
pTask->timeout -= timeElapsed;
}
pPreviousTask = pTask;
pTask = pTask->pNext;
} while (pTask != NULL);
pTask = pScheduler->pNext;
pPreviousTask = NULL;
timeout = MAX_TIMEOUT;
do
{
//Check which task should be woken up first
if( (events & EVENT_HW_INTERRUPT) && (pTask->events & EVENT_HW_INTERRUPT) )
{
//Hardware interrupts have prio
pPrioTask = pTask;
pPrioTaskPrevious = pPreviousTask;
timeout = 0;
pTask = pScheduler->pNext;
pPreviousTask = NULL;
timeout = MAX_TIMEOUT;
do {
//Check which task should be woken up first
if ((events & EVENT_HW_INTERRUPT) && (pTask->events & EVENT_HW_INTERRUPT)) {
//Hardware interrupts have prio
pPrioTask = pTask;
pPrioTaskPrevious = pPreviousTask;
timeout = 0;
events &= ~EVENT_HW_INTERRUPT; //Only one task gets triggered per event
prioTaskEvent = EVENT_HW_INTERRUPT;
break;
} else if ((pTask->events & EVENT_TIMEOUT) && (pTask->timeout < timeout)) {
pPrioTask = pTask;
pPrioTaskPrevious = pPreviousTask;
timeout = pTask->timeout;
prioTaskEvent = EVENT_TIMEOUT;
}
pPreviousTask = pTask;
pTask = pTask->pNext;
} while (pTask != NULL);
if (pPrioTask == NULL) {
//No task to wake up, exit
NFC_DBG("No task to wake up");
return MAX_TIMEOUT;
}
if (timeout > 0) {
//No task to wake up yet
if (timeout > MAX_TIMEOUT) {
NFC_DBG("No task to wake up");
return MAX_TIMEOUT;
} else {
NFC_DBG("No task to wake up, wait %lu ms", timeout);
return timeout;
}
}
//Dequeue task
if (pPrioTaskPrevious == NULL) {
pScheduler->pNext = pPrioTask->pNext;
} else {
pPrioTaskPrevious->pNext = pPrioTask->pNext;
}
pPrioTask->pNext = NULL;
//Execute task
NFC_DBG("Calling task %p - events %02X", pPrioTask, prioTaskEvent);
pPrioTask->fn(prioTaskEvent, pPrioTask->pUserData);
events &= ~EVENT_HW_INTERRUPT; //Only one task gets triggered per event
prioTaskEvent = EVENT_HW_INTERRUPT;
break;
}
else if( (pTask->events & EVENT_TIMEOUT) && (pTask->timeout < timeout) )
{
pPrioTask = pTask;
pPrioTaskPrevious = pPreviousTask;
timeout = pTask->timeout;
prioTaskEvent = EVENT_TIMEOUT;
}
pPreviousTask = pTask;
pTask = pTask->pNext;
} while( pTask != NULL );
if( pPrioTask == NULL )
{
//No task to wake up, exit
NFC_DBG("No task to wake up");
return MAX_TIMEOUT;
triggered = true;
}
if( timeout > 0 )
{
//No task to wake up yet
if( timeout > MAX_TIMEOUT )
{
NFC_DBG("No task to wake up");
return MAX_TIMEOUT;
}
else
{
NFC_DBG("No task to wake up, wait %lu ms", timeout);
return timeout;
}
}
//Dequeue task
if( pPrioTaskPrevious == NULL )
{
pScheduler->pNext = pPrioTask->pNext;
}
else
{
pPrioTaskPrevious->pNext = pPrioTask->pNext;
}
pPrioTask->pNext = NULL;
//Execute task
NFC_DBG("Calling task %p - events %02X", pPrioTask, prioTaskEvent);
pPrioTask->fn(prioTaskEvent, pPrioTask->pUserData);
events &= ~EVENT_HW_INTERRUPT; //Only one task gets triggered per event
triggered = true;
}
return MAX_TIMEOUT;
return MAX_TIMEOUT;
}
void nfc_scheduler_queue_task(nfc_scheduler_t* pScheduler, nfc_task_t* pTask)
void nfc_scheduler_queue_task(nfc_scheduler_t *pScheduler, nfc_task_t *pTask)
{
pTask->timeout = pTask->timeoutInitial + nfc_scheduler_timer_get(pScheduler->pTimer);
NFC_DBG("Queuing task %p: events %1X, timeout %lu ms", pTask, pTask->events, pTask->timeout);
//Find last task
nfc_task_t* pPrevTask = pScheduler->pNext;
pTask->pNext = NULL;
if( pPrevTask == NULL )
{
pScheduler->pNext = pTask;
return;
}
while( pPrevTask->pNext != NULL )
{
pPrevTask = pPrevTask->pNext;
}
pPrevTask->pNext = pTask;
}
void nfc_scheduler_dequeue_task(nfc_scheduler_t* pScheduler, bool abort, nfc_task_t* pTask)
{
NFC_DBG("Dequeuing task %p", pTask);
//Find task
nfc_task_t* pPrevTask = pScheduler->pNext;
if( pPrevTask == NULL )
{
pTask->timeout = pTask->timeoutInitial + nfc_scheduler_timer_get(pScheduler->pTimer);
NFC_DBG("Queuing task %p: events %1X, timeout %lu ms", pTask, pTask->events, pTask->timeout);
//Find last task
nfc_task_t *pPrevTask = pScheduler->pNext;
pTask->pNext = NULL;
return;
}
if( pPrevTask == pTask )
{
if(abort)
{
pTask->fn(EVENT_ABORTED, pTask->pUserData);
if (pPrevTask == NULL) {
pScheduler->pNext = pTask;
return;
}
pScheduler->pNext = pTask->pNext;
pTask->pNext = NULL;
return;
}
while( pPrevTask->pNext != NULL )
{
if(pPrevTask->pNext == pTask)
{
if(abort)
{
pTask->fn(EVENT_ABORTED, pTask->pUserData);
}
pPrevTask->pNext = pTask->pNext;
pTask->pNext = NULL;
return;
while (pPrevTask->pNext != NULL) {
pPrevTask = pPrevTask->pNext;
}
pPrevTask = pPrevTask->pNext;
}
pTask->pNext = NULL;
pPrevTask->pNext = pTask;
}
void task_init(nfc_task_t* pTask, uint32_t events, uint32_t timeout, nfc_task_fn fn, void* pUserData)
void nfc_scheduler_dequeue_task(nfc_scheduler_t *pScheduler, bool abort, nfc_task_t *pTask)
{
pTask->events = events;
pTask->timeoutInitial = timeout;
pTask->fn = fn;
pTask->pUserData = pUserData;
pTask->pNext = NULL;
NFC_DBG("Dequeuing task %p", pTask);
//Find task
nfc_task_t *pPrevTask = pScheduler->pNext;
if (pPrevTask == NULL) {
pTask->pNext = NULL;
return;
}
if (pPrevTask == pTask) {
if (abort) {
pTask->fn(EVENT_ABORTED, pTask->pUserData);
}
pScheduler->pNext = pTask->pNext;
pTask->pNext = NULL;
return;
}
while (pPrevTask->pNext != NULL) {
if (pPrevTask->pNext == pTask) {
if (abort) {
pTask->fn(EVENT_ABORTED, pTask->pUserData);
}
pPrevTask->pNext = pTask->pNext;
pTask->pNext = NULL;
return;
}
pPrevTask = pPrevTask->pNext;
}
pTask->pNext = NULL;
}
void task_init(nfc_task_t *pTask, uint32_t events, uint32_t timeout, nfc_task_fn fn, void *pUserData)
{
pTask->events = events;
pTask->timeoutInitial = timeout;
pTask->fn = fn;
pTask->pUserData = pUserData;
pTask->pNext = NULL;
}

View File

@ -45,62 +45,60 @@ typedef struct __nfc_timer nfc_scheduler_timer_t;
struct __nfc_task;
typedef struct __nfc_task nfc_task_t;
typedef struct __scheduler
{
nfc_task_t* pNext;
nfc_scheduler_timer_t* pTimer;
typedef struct __scheduler {
nfc_task_t *pNext;
nfc_scheduler_timer_t *pTimer;
} nfc_scheduler_t;
typedef void (*nfc_task_fn)(uint32_t events, void* pUserData);
typedef void (*nfc_task_fn)(uint32_t events, void *pUserData);
struct __nfc_task
{
uint32_t events;
int64_t timeout; //millisecs
int64_t timeoutInitial;
struct __nfc_task {
uint32_t events;
int64_t timeout; //millisecs
int64_t timeoutInitial;
nfc_task_fn fn;
void* pUserData;
nfc_task_fn fn;
void *pUserData;
nfc_task_t* pNext;
nfc_task_t *pNext;
};
void nfc_scheduler_timer_init(nfc_scheduler_timer_t* timer);
void nfc_scheduler_timer_init(nfc_scheduler_timer_t *timer);
void nfc_scheduler_timer_start(nfc_scheduler_timer_t* timer);
void nfc_scheduler_timer_start(nfc_scheduler_timer_t *timer);
uint32_t nfc_scheduler_timer_get(nfc_scheduler_timer_t* timer);
uint32_t nfc_scheduler_timer_get(nfc_scheduler_timer_t *timer);
void nfc_scheduler_timer_stop(nfc_scheduler_timer_t* timer);
void nfc_scheduler_timer_stop(nfc_scheduler_timer_t *timer);
void nfc_scheduler_timer_reset(nfc_scheduler_timer_t* timer);
void nfc_scheduler_timer_reset(nfc_scheduler_timer_t *timer);
/** Init scheduler
* \param pScheduler scheduler instance to init
* \param pTimer timer instance
*/
void nfc_scheduler_init(nfc_scheduler_t* pScheduler, nfc_scheduler_timer_t* pTimer);
void nfc_scheduler_init(nfc_scheduler_t *pScheduler, nfc_scheduler_timer_t *pTimer);
/** Iterate through all tasks
* \param pScheduler scheduler instance
* \param events mask of events (except EVENT_TIMEOUT) that have been raised since this function last returned (0 on first call)
* \return time after which this function must be called again if no other event arises
*/
uint32_t nfc_scheduler_iteration(nfc_scheduler_t* pScheduler, uint32_t events);
uint32_t nfc_scheduler_iteration(nfc_scheduler_t *pScheduler, uint32_t events);
/** Queue a task to execute
* \param pScheduler scheduler instance
* \param pTask task to queue
*
*/
void nfc_scheduler_queue_task(nfc_scheduler_t* pScheduler, nfc_task_t* pTask);
void nfc_scheduler_queue_task(nfc_scheduler_t *pScheduler, nfc_task_t *pTask);
/** Remove a task to execute
* \param pScheduler scheduler instance
* \param pTask task to remove
* \param abort abort task if queued
*/
void nfc_scheduler_dequeue_task(nfc_scheduler_t* pScheduler, bool abort, nfc_task_t* pTask);
void nfc_scheduler_dequeue_task(nfc_scheduler_t *pScheduler, bool abort, nfc_task_t *pTask);
/** Initialize task with the following parameters
* \param pTask task to initialize
@ -109,7 +107,7 @@ void nfc_scheduler_dequeue_task(nfc_scheduler_t* pScheduler, bool abort, nfc_tas
* \param fn function to be called
* \param pUserData data that will be passed to function
*/
void task_init(nfc_task_t* pTask, uint32_t events, uint32_t timeout, nfc_task_fn fn, void* pUserData);
void task_init(nfc_task_t *pTask, uint32_t events, uint32_t timeout, nfc_task_fn fn, void *pUserData);
#ifdef __cplusplus
}

View File

@ -36,11 +36,11 @@
* \param read transport read function
* \param pUser parameter that will be passed to any of the above functions
*/
void nfc_transport_init( nfc_transport_t* pTransport, nfc_transport_write_fn_t write, nfc_transport_read_fn_t read, void* pUser )
void nfc_transport_init(nfc_transport_t *pTransport, nfc_transport_write_fn_t write, nfc_transport_read_fn_t read, void *pUser)
{
pTransport->write = write;
pTransport->read = read;
pTransport->pUser = pUser;
pTransport->write = write;
pTransport->read = read;
pTransport->pUser = pUser;
}

View File

@ -41,7 +41,7 @@ extern "C" {
* \param outLen buffer's length
* \param pUser parameter passed to the nfc_transport_init function
*/
typedef void (*nfc_transport_write_fn_t)( uint8_t address, const uint8_t* outBuf, size_t outLen, void* pUser );
typedef void (*nfc_transport_write_fn_t)(uint8_t address, const uint8_t *outBuf, size_t outLen, void *pUser);
/** Function called to read a register's value
* \param address address to read packet from
@ -49,25 +49,24 @@ typedef void (*nfc_transport_write_fn_t)( uint8_t address, const uint8_t* outBuf
* \param outLen buffer's length
* \param pUser parameter passed to the nfc_transport_init function
*/
typedef void (*nfc_transport_read_fn_t)( uint8_t address, uint8_t* inBuf, size_t inLen, void* pUser );
typedef void (*nfc_transport_read_fn_t)(uint8_t address, uint8_t *inBuf, size_t inLen, void *pUser);
typedef struct __transport
{
nfc_transport_write_fn_t write;
nfc_transport_read_fn_t read;
void* pUser;
typedef struct __transport {
nfc_transport_write_fn_t write;
nfc_transport_read_fn_t read;
void *pUser;
} nfc_transport_t;
void nfc_transport_init( nfc_transport_t* pTransport, nfc_transport_write_fn_t write, nfc_transport_read_fn_t read, void* pUser );
void nfc_transport_init(nfc_transport_t *pTransport, nfc_transport_write_fn_t write, nfc_transport_read_fn_t read, void *pUser);
static inline void nfc_transport_write( nfc_transport_t* pTransport, uint8_t address, const uint8_t* outBuf, size_t outLen )
static inline void nfc_transport_write(nfc_transport_t *pTransport, uint8_t address, const uint8_t *outBuf, size_t outLen)
{
pTransport->write( address, outBuf, outLen, pTransport->pUser );
pTransport->write(address, outBuf, outLen, pTransport->pUser);
}
static inline void nfc_transport_read( nfc_transport_t* pTransport, uint8_t address, uint8_t* inBuf, size_t inLen )
static inline void nfc_transport_read(nfc_transport_t *pTransport, uint8_t address, uint8_t *inBuf, size_t inLen)
{
pTransport->read( address, inBuf, inLen, pTransport->pUser );
pTransport->read(address, inBuf, inLen, pTransport->pUser);
}
#ifdef __cplusplus

View File

@ -32,181 +32,169 @@
#include "iso7816_defs.h"
#include "tech/isodep/isodep_target.h"
static void iso7816_disconnected(nfc_tech_iso7816_t* pIso7816, bool deselected);
static void iso7816_disconnected(nfc_tech_iso7816_t *pIso7816, bool deselected);
static nfc_err_t iso7816_parse(nfc_tech_iso7816_t* pIso7816);
static nfc_err_t iso7816_parse(nfc_tech_iso7816_t *pIso7816);
static void iso7816_receive(nfc_tech_iso7816_t* pIso7816);
static nfc_err_t iso7816_transmit(nfc_tech_iso7816_t* pIso7816);
static void iso7816_receive(nfc_tech_iso7816_t *pIso7816);
static nfc_err_t iso7816_transmit(nfc_tech_iso7816_t *pIso7816);
static bool iso7816_mf_command(nfc_tech_iso7816_t* pIso7816);
static bool iso7816_mf_command(nfc_tech_iso7816_t *pIso7816);
static void iso_dep_received_cb(nfc_tech_isodep_t* pIsodep, nfc_err_t ret, void* pUserData);
static void iso_dep_transmitted_cb(nfc_tech_isodep_t* pIsodep, nfc_err_t ret, void* pUserData);
static void iso_dep_disconnected_cb(nfc_tech_isodep_t* pIsodep, bool deselected, void* pUserData);
static void iso_dep_received_cb(nfc_tech_isodep_t *pIsodep, nfc_err_t ret, void *pUserData);
static void iso_dep_transmitted_cb(nfc_tech_isodep_t *pIsodep, nfc_err_t ret, void *pUserData);
static void iso_dep_disconnected_cb(nfc_tech_isodep_t *pIsodep, bool deselected, void *pUserData);
static void iso_dep_stream_transmit_cb(buffer_t* ppDataIn, bool* pClose, size_t maxLength, void* pUserParam);
static void iso_dep_stream_receive_cb(buffer_t* pDataOut, bool closed, void* pUserParam);
static void iso_dep_stream_transmit_cb(buffer_t *ppDataIn, bool *pClose, size_t maxLength, void *pUserParam);
static void iso_dep_stream_receive_cb(buffer_t *pDataOut, bool closed, void *pUserParam);
void nfc_tech_iso7816_init(nfc_tech_iso7816_t* pIso7816, nfc_transceiver_t* pTransceiver, nfc_tech_iso7816_disconnected_cb disconnectedCb, void* pUserData)
void nfc_tech_iso7816_init(nfc_tech_iso7816_t *pIso7816, nfc_transceiver_t *pTransceiver, nfc_tech_iso7816_disconnected_cb disconnectedCb, void *pUserData)
{
buffer_init(&pIso7816->hist, NULL, 0);
nfc_tech_isodep_target_init(&pIso7816->isoDepTarget, pTransceiver, &pIso7816->hist, iso_dep_disconnected_cb, pIso7816);
pIso7816->pAppList = NULL;
pIso7816->pSelectedApp = NULL;
pIso7816->disconnectedCb = disconnectedCb;
istream_init(&pIso7816->inputStream, iso_dep_stream_transmit_cb, pIso7816);
ostream_init(&pIso7816->outputStream, iso_dep_stream_receive_cb, pIso7816);
buffer_builder_init(&pIso7816->txBldr, pIso7816->txBuf, 2); //Just enough to fit sw
buffer_builder_init(&pIso7816->rxBldr, pIso7816->rxBuf, ISO7816_RX_BUFFER_SIZE);
pIso7816->pUserData = pUserData;
}
void nfc_tech_iso7816_connect(nfc_tech_iso7816_t* pIso7816)
{
pIso7816->disconnected = false;
pIso7816->responseReady = true;
iso7816_receive(pIso7816);
nfc_tech_isodep_target_connect(&pIso7816->isoDepTarget);
}
void nfc_tech_iso7816_disconnect(nfc_tech_iso7816_t* pIso7816)
{
nfc_tech_isodep_target_disconnect(&pIso7816->isoDepTarget);
}
void nfc_tech_iso7816_add_app(nfc_tech_iso7816_t* pIso7816, nfc_tech_iso7816_app_t* pIso7816App)
{
nfc_tech_iso7816_app_t** ppPrevApp = &pIso7816->pAppList;
while( *ppPrevApp != NULL )
{
ppPrevApp = &((*ppPrevApp)->pNext);
}
*ppPrevApp = pIso7816App;
pIso7816App->pNext = NULL;
}
nfc_err_t nfc_tech_iso7816_reply(nfc_tech_iso7816_t* pIso7816)
{
nfc_err_t ret;
//Serialize APDU and send
buffer_builder_reset(&pIso7816->txBldr);
buffer_builder_write_nu16(&pIso7816->txBldr, pIso7816->rApdu.sw);
buffer_append(&pIso7816->rApdu.dataOut, buffer_builder_buffer(&pIso7816->txBldr));
NFC_DBG("R-ADPU: (LE):%02X SW:%04X", buffer_reader_readable(&pIso7816->rApdu.dataOut), pIso7816->rApdu.sw);
DBG_BLOCK( buffer_dump(&pIso7816->rApdu.dataOut); )
ret = iso7816_transmit(pIso7816);
if(ret)
{
return ret;
}
return NFC_OK;
}
void iso7816_disconnected(nfc_tech_iso7816_t* pIso7816, bool deselected)
{
pIso7816->disconnected = true;
if(pIso7816->pSelectedApp != NULL)
{
//Deselect previous app
pIso7816->pSelectedApp->deselected(pIso7816->pSelectedApp, pIso7816->pSelectedApp->pUserData);
buffer_init(&pIso7816->hist, NULL, 0);
nfc_tech_isodep_target_init(&pIso7816->isoDepTarget, pTransceiver, &pIso7816->hist, iso_dep_disconnected_cb, pIso7816);
pIso7816->pAppList = NULL;
pIso7816->pSelectedApp = NULL;
}
pIso7816->disconnectedCb(pIso7816, deselected, pIso7816->pUserData);
pIso7816->disconnectedCb = disconnectedCb;
istream_init(&pIso7816->inputStream, iso_dep_stream_transmit_cb, pIso7816);
ostream_init(&pIso7816->outputStream, iso_dep_stream_receive_cb, pIso7816);
buffer_builder_init(&pIso7816->txBldr, pIso7816->txBuf, 2); //Just enough to fit sw
buffer_builder_init(&pIso7816->rxBldr, pIso7816->rxBuf, ISO7816_RX_BUFFER_SIZE);
pIso7816->pUserData = pUserData;
}
nfc_err_t iso7816_parse(nfc_tech_iso7816_t* pIso7816)
void nfc_tech_iso7816_connect(nfc_tech_iso7816_t *pIso7816)
{
//Reset R-APDU
buffer_init(&pIso7816->rApdu.dataOut, NULL, 0);
pIso7816->rApdu.sw = ISO7816_SW_OK;
pIso7816->disconnected = false;
pIso7816->responseReady = true;
DBG_BLOCK( buffer_dump(buffer_builder_buffer(&pIso7816->rxBldr)); )
iso7816_receive(pIso7816);
nfc_tech_isodep_target_connect(&pIso7816->isoDepTarget);
}
if( buffer_reader_readable( buffer_builder_buffer(&pIso7816->rxBldr) ) < 4 )
{
NFC_ERR("C-APDU is too small");
pIso7816->rApdu.sw = ISO7816_SW_INVALID_CLASS;
nfc_tech_iso7816_reply(pIso7816);
return NFC_ERR_PROTOCOL;
}
void nfc_tech_iso7816_disconnect(nfc_tech_iso7816_t *pIso7816)
{
nfc_tech_isodep_target_disconnect(&pIso7816->isoDepTarget);
}
pIso7816->cApdu.cla = buffer_read_nu8(buffer_builder_buffer(&pIso7816->rxBldr));
pIso7816->cApdu.ins = buffer_read_nu8(buffer_builder_buffer(&pIso7816->rxBldr));
pIso7816->cApdu.p1 = buffer_read_nu8(buffer_builder_buffer(&pIso7816->rxBldr));
pIso7816->cApdu.p2 = buffer_read_nu8(buffer_builder_buffer(&pIso7816->rxBldr));
buffer_init(&pIso7816->cApdu.dataIn, NULL, 0);
pIso7816->cApdu.maxRespLength = 0;
if( buffer_reader_readable(buffer_builder_buffer(&pIso7816->rxBldr)) > 1 )
{
size_t lc = buffer_read_nu8(buffer_builder_buffer(&pIso7816->rxBldr));
if( buffer_reader_readable(buffer_builder_buffer(&pIso7816->rxBldr)) >= lc )
{
buffer_split(&pIso7816->cApdu.dataIn, buffer_builder_buffer(&pIso7816->rxBldr), buffer_builder_buffer(&pIso7816->rxBldr), lc);
void nfc_tech_iso7816_add_app(nfc_tech_iso7816_t *pIso7816, nfc_tech_iso7816_app_t *pIso7816App)
{
nfc_tech_iso7816_app_t **ppPrevApp = &pIso7816->pAppList;
while (*ppPrevApp != NULL) {
ppPrevApp = &((*ppPrevApp)->pNext);
}
else
{
pIso7816->rApdu.sw = ISO7816_SW_WRONG_LENGTH;
nfc_tech_iso7816_reply(pIso7816);
return NFC_ERR_LENGTH; //Not a valid frame
*ppPrevApp = pIso7816App;
pIso7816App->pNext = NULL;
}
nfc_err_t nfc_tech_iso7816_reply(nfc_tech_iso7816_t *pIso7816)
{
nfc_err_t ret;
//Serialize APDU and send
buffer_builder_reset(&pIso7816->txBldr);
buffer_builder_write_nu16(&pIso7816->txBldr, pIso7816->rApdu.sw);
buffer_append(&pIso7816->rApdu.dataOut, buffer_builder_buffer(&pIso7816->txBldr));
NFC_DBG("R-ADPU: (LE):%02X SW:%04X", buffer_reader_readable(&pIso7816->rApdu.dataOut), pIso7816->rApdu.sw);
DBG_BLOCK(buffer_dump(&pIso7816->rApdu.dataOut);)
ret = iso7816_transmit(pIso7816);
if (ret) {
return ret;
}
}
if( buffer_reader_readable(buffer_builder_buffer(&pIso7816->rxBldr)) >= 1 )
{
pIso7816->cApdu.maxRespLength = buffer_read_nu8(buffer_builder_buffer(&pIso7816->rxBldr));
}
NFC_DBG("C-APDU: CLA:%02X INS:%02X P1:%02X P2:%02X LC:%02X LE:%02X", pIso7816->cApdu.cla, pIso7816->cApdu.ins, pIso7816->cApdu.p1, pIso7816->cApdu.p2,
buffer_reader_readable(&pIso7816->cApdu.dataIn), pIso7816->cApdu.maxRespLength);
if( buffer_reader_readable(buffer_builder_buffer(&pIso7816->rxBldr)) > 0 )
{
pIso7816->rApdu.sw = ISO7816_SW_WRONG_LENGTH;
nfc_tech_iso7816_reply(pIso7816);
return NFC_ERR_LENGTH; //Not a valid frame
}
//See if can select an app
if( iso7816_mf_command(pIso7816) )
{
nfc_tech_iso7816_reply(pIso7816);
return NFC_OK;
}
//Pass command to selected app
if( pIso7816->pSelectedApp == NULL )
{
pIso7816->rApdu.sw = ISO7816_SW_NOT_FOUND;
nfc_tech_iso7816_reply(pIso7816);
return NFC_ERR_NOT_FOUND; //Not a valid frame
}
pIso7816->pSelectedApp->apdu(pIso7816->pSelectedApp, pIso7816->pSelectedApp->pUserData);
return NFC_OK;
}
void iso7816_receive(nfc_tech_iso7816_t* pIso7816)
void iso7816_disconnected(nfc_tech_iso7816_t *pIso7816, bool deselected)
{
buffer_builder_reset(&pIso7816->rxBldr);
nfc_tech_isodep_target_receive(&pIso7816->isoDepTarget, &pIso7816->outputStream, iso_dep_received_cb, pIso7816);
pIso7816->disconnected = true;
if (pIso7816->pSelectedApp != NULL) {
//Deselect previous app
pIso7816->pSelectedApp->deselected(pIso7816->pSelectedApp, pIso7816->pSelectedApp->pUserData);
pIso7816->pSelectedApp = NULL;
}
pIso7816->disconnectedCb(pIso7816, deselected, pIso7816->pUserData);
}
nfc_err_t iso7816_transmit(nfc_tech_iso7816_t* pIso7816)
nfc_err_t iso7816_parse(nfc_tech_iso7816_t *pIso7816)
{
return nfc_tech_isodep_target_transmit(&pIso7816->isoDepTarget, &pIso7816->inputStream, iso_dep_transmitted_cb, pIso7816);
//Reset R-APDU
buffer_init(&pIso7816->rApdu.dataOut, NULL, 0);
pIso7816->rApdu.sw = ISO7816_SW_OK;
DBG_BLOCK(buffer_dump(buffer_builder_buffer(&pIso7816->rxBldr));)
if (buffer_reader_readable(buffer_builder_buffer(&pIso7816->rxBldr)) < 4) {
NFC_ERR("C-APDU is too small");
pIso7816->rApdu.sw = ISO7816_SW_INVALID_CLASS;
nfc_tech_iso7816_reply(pIso7816);
return NFC_ERR_PROTOCOL;
}
pIso7816->cApdu.cla = buffer_read_nu8(buffer_builder_buffer(&pIso7816->rxBldr));
pIso7816->cApdu.ins = buffer_read_nu8(buffer_builder_buffer(&pIso7816->rxBldr));
pIso7816->cApdu.p1 = buffer_read_nu8(buffer_builder_buffer(&pIso7816->rxBldr));
pIso7816->cApdu.p2 = buffer_read_nu8(buffer_builder_buffer(&pIso7816->rxBldr));
buffer_init(&pIso7816->cApdu.dataIn, NULL, 0);
pIso7816->cApdu.maxRespLength = 0;
if (buffer_reader_readable(buffer_builder_buffer(&pIso7816->rxBldr)) > 1) {
size_t lc = buffer_read_nu8(buffer_builder_buffer(&pIso7816->rxBldr));
if (buffer_reader_readable(buffer_builder_buffer(&pIso7816->rxBldr)) >= lc) {
buffer_split(&pIso7816->cApdu.dataIn, buffer_builder_buffer(&pIso7816->rxBldr), buffer_builder_buffer(&pIso7816->rxBldr), lc);
} else {
pIso7816->rApdu.sw = ISO7816_SW_WRONG_LENGTH;
nfc_tech_iso7816_reply(pIso7816);
return NFC_ERR_LENGTH; //Not a valid frame
}
}
if (buffer_reader_readable(buffer_builder_buffer(&pIso7816->rxBldr)) >= 1) {
pIso7816->cApdu.maxRespLength = buffer_read_nu8(buffer_builder_buffer(&pIso7816->rxBldr));
}
NFC_DBG("C-APDU: CLA:%02X INS:%02X P1:%02X P2:%02X LC:%02X LE:%02X", pIso7816->cApdu.cla, pIso7816->cApdu.ins, pIso7816->cApdu.p1, pIso7816->cApdu.p2,
buffer_reader_readable(&pIso7816->cApdu.dataIn), pIso7816->cApdu.maxRespLength);
if (buffer_reader_readable(buffer_builder_buffer(&pIso7816->rxBldr)) > 0) {
pIso7816->rApdu.sw = ISO7816_SW_WRONG_LENGTH;
nfc_tech_iso7816_reply(pIso7816);
return NFC_ERR_LENGTH; //Not a valid frame
}
//See if can select an app
if (iso7816_mf_command(pIso7816)) {
nfc_tech_iso7816_reply(pIso7816);
return NFC_OK;
}
//Pass command to selected app
if (pIso7816->pSelectedApp == NULL) {
pIso7816->rApdu.sw = ISO7816_SW_NOT_FOUND;
nfc_tech_iso7816_reply(pIso7816);
return NFC_ERR_NOT_FOUND; //Not a valid frame
}
pIso7816->pSelectedApp->apdu(pIso7816->pSelectedApp, pIso7816->pSelectedApp->pUserData);
return NFC_OK;
}
void iso7816_receive(nfc_tech_iso7816_t *pIso7816)
{
buffer_builder_reset(&pIso7816->rxBldr);
nfc_tech_isodep_target_receive(&pIso7816->isoDepTarget, &pIso7816->outputStream, iso_dep_received_cb, pIso7816);
}
nfc_err_t iso7816_transmit(nfc_tech_iso7816_t *pIso7816)
{
return nfc_tech_isodep_target_transmit(&pIso7816->isoDepTarget, &pIso7816->inputStream, iso_dep_transmitted_cb, pIso7816);
}
/** Handle ISO7816-4 command
@ -220,147 +208,128 @@ nfc_err_t iso7816_transmit(nfc_tech_iso7816_t* pIso7816)
* \param SW status word
* \return true if command was handled, false if it should be passed to the selected application
*/
bool iso7816_mf_command(nfc_tech_iso7816_t* pIso7816)
bool iso7816_mf_command(nfc_tech_iso7816_t *pIso7816)
{
nfc_tech_iso7816_app_t* pApp;
if(pIso7816->cApdu.cla != 0x00)
{
return false;
}
switch(pIso7816->cApdu.ins)
{
case ISO7816_INS_SELECT:
switch(pIso7816->cApdu.p1)
{
case 0x04: //Selection by DF name
pApp = pIso7816->pAppList;
while(pApp != NULL)
{
if( buffer_reader_readable(&pIso7816->cApdu.dataIn) <= pApp->aidSize )
{
if( buffer_reader_cmp_bytes(&pIso7816->cApdu.dataIn, pApp->aid, buffer_reader_readable(&pIso7816->cApdu.dataIn)) )
{
if(pIso7816->pSelectedApp != NULL)
{
//Deselect previous app
pIso7816->pSelectedApp->deselected(pIso7816->pSelectedApp, pIso7816->pSelectedApp->pUserData);
}
pIso7816->pSelectedApp = pApp;
pIso7816->pSelectedApp->selected(pIso7816->pSelectedApp, pIso7816->pSelectedApp->pUserData);
pIso7816->rApdu.sw = ISO7816_SW_OK;
return true;
}
}
pApp = pApp->pNext;
}
pIso7816->rApdu.sw = ISO7816_SW_NOT_FOUND;
return true;
default:
if(pIso7816->pSelectedApp == NULL)
{
pIso7816->rApdu.sw = ISO7816_SW_NOT_FOUND;
return true;
}
else
{
nfc_tech_iso7816_app_t *pApp;
if (pIso7816->cApdu.cla != 0x00) {
return false;
}
}
break;
default:
if(pIso7816->pSelectedApp == NULL)
switch (pIso7816->cApdu.ins) {
case ISO7816_INS_SELECT:
switch (pIso7816->cApdu.p1) {
case 0x04: //Selection by DF name
pApp = pIso7816->pAppList;
while (pApp != NULL) {
if (buffer_reader_readable(&pIso7816->cApdu.dataIn) <= pApp->aidSize) {
if (buffer_reader_cmp_bytes(&pIso7816->cApdu.dataIn, pApp->aid, buffer_reader_readable(&pIso7816->cApdu.dataIn))) {
if (pIso7816->pSelectedApp != NULL) {
//Deselect previous app
pIso7816->pSelectedApp->deselected(pIso7816->pSelectedApp, pIso7816->pSelectedApp->pUserData);
}
pIso7816->pSelectedApp = pApp;
pIso7816->pSelectedApp->selected(pIso7816->pSelectedApp, pIso7816->pSelectedApp->pUserData);
pIso7816->rApdu.sw = ISO7816_SW_OK;
return true;
}
}
pApp = pApp->pNext;
}
pIso7816->rApdu.sw = ISO7816_SW_NOT_FOUND;
return true;
default:
if (pIso7816->pSelectedApp == NULL) {
pIso7816->rApdu.sw = ISO7816_SW_NOT_FOUND;
return true;
} else {
return false;
}
}
break;
default:
if (pIso7816->pSelectedApp == NULL) {
pIso7816->rApdu.sw = ISO7816_SW_INVALID_INS;
return true;
} else {
return false;
}
break;
}
}
void iso_dep_received_cb(nfc_tech_isodep_t *pIsodep, nfc_err_t ret, void *pUserData)
{
nfc_tech_iso7816_t *pIso7816 = (nfc_tech_iso7816_t *) pUserData;
(void) pIsodep;
if (ret) {
NFC_WARN("Got error %d", ret);
return;
}
//Parse received APDU
ret = iso7816_parse(pIso7816);
if (ret) {
NFC_WARN("Got error %d", ret);
return;
}
}
void iso_dep_transmitted_cb(nfc_tech_isodep_t *pIsodep, nfc_err_t ret, void *pUserData)
{
nfc_tech_iso7816_t *pIso7816 = (nfc_tech_iso7816_t *) pUserData;
(void) pIsodep;
if (ret) {
NFC_WARN("Got error %d", ret);
return;
}
//Advertise that we have space in our buffer?
//Switch to receive mode!
iso7816_receive(pIso7816);
}
void iso_dep_disconnected_cb(nfc_tech_isodep_t *pIsodep, bool deselected, void *pUserData)
{
nfc_tech_iso7816_t *pIso7816 = (nfc_tech_iso7816_t *) pUserData;
(void) pIsodep;
NFC_DBG("ISO DEP disconnected");
iso7816_disconnected(pIso7816, deselected);
}
void iso_dep_stream_transmit_cb(buffer_t *pDataIn, bool *pClose, size_t maxLength, void *pUserParam)
{
nfc_tech_iso7816_t *pIso7816 = (nfc_tech_iso7816_t *) pUserParam;
//Only close if buffer fits in this frame
if (maxLength >= buffer_reader_readable(&pIso7816->rApdu.dataOut))
//if( buffer_total_length(&pLlcp->tx) <= maxLength )
{
pIso7816->rApdu.sw = ISO7816_SW_INVALID_INS;
return true;
maxLength = buffer_reader_readable(&pIso7816->rApdu.dataOut);
*pClose = true;
} else {
*pClose = false;
}
else
{
return false;
buffer_split(pDataIn, &pIso7816->rApdu.dataOut, &pIso7816->rApdu.dataOut, maxLength);
}
void iso_dep_stream_receive_cb(buffer_t *pDataOut, bool closed, void *pUserParam)
{
nfc_tech_iso7816_t *pIso7816 = (nfc_tech_iso7816_t *) pUserParam;
(void) closed;
if (buffer_reader_readable(pDataOut) > buffer_builder_writeable(&pIso7816->rxBldr)) {
NFC_ERR("Frame will not fit (%d > %d)", buffer_reader_readable(pDataOut), buffer_builder_writeable(&pIso7816->rxBldr));
}
break;
}
}
void iso_dep_received_cb(nfc_tech_isodep_t* pIsodep, nfc_err_t ret, void* pUserData)
{
nfc_tech_iso7816_t* pIso7816 = (nfc_tech_iso7816_t*) pUserData;
(void) pIsodep;
if( ret )
{
NFC_WARN("Got error %d", ret);
return;
}
//Parse received APDU
ret = iso7816_parse(pIso7816);
if( ret )
{
NFC_WARN("Got error %d", ret);
return;
}
}
void iso_dep_transmitted_cb(nfc_tech_isodep_t* pIsodep, nfc_err_t ret, void* pUserData)
{
nfc_tech_iso7816_t* pIso7816 = (nfc_tech_iso7816_t*) pUserData;
(void) pIsodep;
if( ret )
{
NFC_WARN("Got error %d", ret);
return;
}
//Advertise that we have space in our buffer?
//Switch to receive mode!
iso7816_receive(pIso7816);
}
void iso_dep_disconnected_cb(nfc_tech_isodep_t* pIsodep, bool deselected, void* pUserData)
{
nfc_tech_iso7816_t* pIso7816 = (nfc_tech_iso7816_t*) pUserData;
(void) pIsodep;
NFC_DBG("ISO DEP disconnected");
iso7816_disconnected(pIso7816, deselected);
}
void iso_dep_stream_transmit_cb(buffer_t* pDataIn, bool* pClose, size_t maxLength, void* pUserParam)
{
nfc_tech_iso7816_t* pIso7816 = (nfc_tech_iso7816_t*) pUserParam;
//Only close if buffer fits in this frame
if( maxLength >= buffer_reader_readable(&pIso7816->rApdu.dataOut) )
//if( buffer_total_length(&pLlcp->tx) <= maxLength )
{
maxLength = buffer_reader_readable(&pIso7816->rApdu.dataOut);
*pClose = true;
}
else
{
*pClose = false;
}
buffer_split(pDataIn, &pIso7816->rApdu.dataOut, &pIso7816->rApdu.dataOut, maxLength);
}
void iso_dep_stream_receive_cb(buffer_t* pDataOut, bool closed, void* pUserParam)
{
nfc_tech_iso7816_t* pIso7816 = (nfc_tech_iso7816_t*) pUserParam;
(void) closed;
if( buffer_reader_readable(pDataOut) > buffer_builder_writeable(&pIso7816->rxBldr) )
{
NFC_ERR("Frame will not fit (%d > %d)", buffer_reader_readable(pDataOut), buffer_builder_writeable(&pIso7816->rxBldr) );
}
//Feed rx buffer
buffer_builder_copy_n_bytes(&pIso7816->rxBldr, pDataOut, buffer_reader_readable(pDataOut));
//Feed rx buffer
buffer_builder_copy_n_bytes(&pIso7816->rxBldr, pDataOut, buffer_reader_readable(pDataOut));
}

View File

@ -32,20 +32,18 @@ extern "C" {
#include "tech/isodep/isodep_target.h"
struct nfc_tech_iso7816_c_apdu
{
uint8_t cla;
uint8_t ins;
uint8_t p1;
uint8_t p2;
buffer_t dataIn;
size_t maxRespLength;
struct nfc_tech_iso7816_c_apdu {
uint8_t cla;
uint8_t ins;
uint8_t p1;
uint8_t p2;
buffer_t dataIn;
size_t maxRespLength;
};
struct nfc_tech_iso7816_r_apdu
{
buffer_t dataOut;
uint16_t sw;
struct nfc_tech_iso7816_r_apdu {
buffer_t dataOut;
uint16_t sw;
};
#define ISO7816_RX_BUFFER_SIZE 256
@ -55,56 +53,55 @@ typedef struct nfc_tech_iso7816_r_apdu nfc_tech_iso7816_r_apdu_t;
typedef struct nfc_tech_iso7816 nfc_tech_iso7816_t;
typedef void (*nfc_tech_iso7816_disconnected_cb)(nfc_tech_iso7816_t* pIso7816, bool deselected, void* pUserData);
typedef void (*nfc_tech_iso7816_disconnected_cb)(nfc_tech_iso7816_t *pIso7816, bool deselected, void *pUserData);
struct nfc_tech_iso7816_app;
typedef struct nfc_tech_iso7816_app nfc_tech_iso7816_app_t;
struct nfc_tech_iso7816
{
nfc_tech_isodep_target_t isoDepTarget;
struct nfc_tech_iso7816 {
nfc_tech_isodep_target_t isoDepTarget;
nfc_tech_iso7816_app_t* pAppList;
nfc_tech_iso7816_app_t* pSelectedApp;
nfc_tech_iso7816_app_t *pAppList;
nfc_tech_iso7816_app_t *pSelectedApp;
bool disconnected;
bool disconnected;
nfc_tech_iso7816_c_apdu_t cApdu;
nfc_tech_iso7816_r_apdu_t rApdu;
nfc_tech_iso7816_c_apdu_t cApdu;
nfc_tech_iso7816_r_apdu_t rApdu;
bool responseReady;
bool responseReady;
nfc_tech_iso7816_disconnected_cb disconnectedCb;
void* pUserData;
nfc_tech_iso7816_disconnected_cb disconnectedCb;
void *pUserData;
buffer_t hist; //Historical bytes
buffer_t hist; //Historical bytes
istream_t inputStream;
ostream_t outputStream;
istream_t inputStream;
ostream_t outputStream;
//PDU buffer (tx)
uint8_t txBuf[2];
buffer_builder_t txBldr;
//PDU buffer (tx)
uint8_t txBuf[2];
buffer_builder_t txBldr;
//Receive buffer
uint8_t rxBuf[ISO7816_RX_BUFFER_SIZE];
buffer_builder_t rxBldr;
//Receive buffer
uint8_t rxBuf[ISO7816_RX_BUFFER_SIZE];
buffer_builder_t rxBldr;
};
void nfc_tech_iso7816_init(nfc_tech_iso7816_t* pIso7816, nfc_transceiver_t* pTransceiver, nfc_tech_iso7816_disconnected_cb disconnectedCb, void* pUserData);
void nfc_tech_iso7816_add_app(nfc_tech_iso7816_t* pIso7816, nfc_tech_iso7816_app_t* pIso7816App);
void nfc_tech_iso7816_connect(nfc_tech_iso7816_t* pIso7816);
void nfc_tech_iso7816_disconnect(nfc_tech_iso7816_t* pIso7816);
nfc_err_t nfc_tech_iso7816_reply(nfc_tech_iso7816_t* pIso7816);
void nfc_tech_iso7816_init(nfc_tech_iso7816_t *pIso7816, nfc_transceiver_t *pTransceiver, nfc_tech_iso7816_disconnected_cb disconnectedCb, void *pUserData);
void nfc_tech_iso7816_add_app(nfc_tech_iso7816_t *pIso7816, nfc_tech_iso7816_app_t *pIso7816App);
void nfc_tech_iso7816_connect(nfc_tech_iso7816_t *pIso7816);
void nfc_tech_iso7816_disconnect(nfc_tech_iso7816_t *pIso7816);
nfc_err_t nfc_tech_iso7816_reply(nfc_tech_iso7816_t *pIso7816);
inline static nfc_tech_iso7816_c_apdu_t* nfc_tech_iso7816_c_apdu(nfc_tech_iso7816_t* pIso7816)
inline static nfc_tech_iso7816_c_apdu_t *nfc_tech_iso7816_c_apdu(nfc_tech_iso7816_t *pIso7816)
{
return &pIso7816->cApdu;
return &pIso7816->cApdu;
}
inline static nfc_tech_iso7816_r_apdu_t* nfc_tech_iso7816_r_apdu(nfc_tech_iso7816_t* pIso7816)
inline static nfc_tech_iso7816_r_apdu_t *nfc_tech_iso7816_r_apdu(nfc_tech_iso7816_t *pIso7816)
{
return &pIso7816->rApdu;
return &pIso7816->rApdu;
}
#ifdef __cplusplus

View File

@ -22,21 +22,21 @@
#include "iso7816_app.h"
void nfc_tech_iso7816_app_init(nfc_tech_iso7816_app_t* pIso7816App,
nfc_tech_iso7816_t* pIso7816,
const uint8_t* aid, size_t aidSize,
nfc_tech_iso7816_app_cb selected,
nfc_tech_iso7816_app_cb deselected,
nfc_tech_iso7816_app_cb apdu,
void* pUserData
)
void nfc_tech_iso7816_app_init(nfc_tech_iso7816_app_t *pIso7816App,
nfc_tech_iso7816_t *pIso7816,
const uint8_t *aid, size_t aidSize,
nfc_tech_iso7816_app_cb selected,
nfc_tech_iso7816_app_cb deselected,
nfc_tech_iso7816_app_cb apdu,
void *pUserData
)
{
pIso7816App->pIso7816 = pIso7816;
pIso7816App->aid = aid;
pIso7816App->aidSize = aidSize;
pIso7816App->selected = selected;
pIso7816App->deselected = deselected;
pIso7816App->apdu = apdu;
pIso7816App->pUserData = pUserData;
pIso7816App->pNext = NULL;
pIso7816App->pIso7816 = pIso7816;
pIso7816App->aid = aid;
pIso7816App->aidSize = aidSize;
pIso7816App->selected = selected;
pIso7816App->deselected = deselected;
pIso7816App->apdu = apdu;
pIso7816App->pUserData = pUserData;
pIso7816App->pNext = NULL;
}

View File

@ -34,44 +34,43 @@ struct nfc_tech_iso7816_app;
typedef struct nfc_tech_iso7816 nfc_tech_iso7816_t;
typedef struct nfc_tech_iso7816_app nfc_tech_iso7816_app_t;
typedef void (*nfc_tech_iso7816_app_cb)( nfc_tech_iso7816_app_t* pIso7816App, void* pUserData );
typedef void (*nfc_tech_iso7816_app_cb)(nfc_tech_iso7816_app_t *pIso7816App, void *pUserData);
struct nfc_tech_iso7816_app
{
nfc_tech_iso7816_t* pIso7816;
struct nfc_tech_iso7816_app {
nfc_tech_iso7816_t *pIso7816;
const uint8_t* aid;
size_t aidSize;
const uint8_t *aid;
size_t aidSize;
nfc_tech_iso7816_app_cb selected;
nfc_tech_iso7816_app_cb deselected;
nfc_tech_iso7816_app_cb apdu;
nfc_tech_iso7816_app_cb selected;
nfc_tech_iso7816_app_cb deselected;
nfc_tech_iso7816_app_cb apdu;
void* pUserData;
void *pUserData;
nfc_tech_iso7816_app_t* pNext;
nfc_tech_iso7816_app_t *pNext;
};
void nfc_tech_iso7816_app_init(nfc_tech_iso7816_app_t* pIso7816App, nfc_tech_iso7816_t* pIso7816, const uint8_t* aid, size_t aidSize,
nfc_tech_iso7816_app_cb selected,
nfc_tech_iso7816_app_cb deselected,
nfc_tech_iso7816_app_cb apdu,
void* pUserData
);
void nfc_tech_iso7816_app_init(nfc_tech_iso7816_app_t *pIso7816App, nfc_tech_iso7816_t *pIso7816, const uint8_t *aid, size_t aidSize,
nfc_tech_iso7816_app_cb selected,
nfc_tech_iso7816_app_cb deselected,
nfc_tech_iso7816_app_cb apdu,
void *pUserData
);
inline static nfc_err_t nfc_tech_iso7816_app_reply(nfc_tech_iso7816_app_t* pIso7816App)
inline static nfc_err_t nfc_tech_iso7816_app_reply(nfc_tech_iso7816_app_t *pIso7816App)
{
return nfc_tech_iso7816_reply(pIso7816App->pIso7816);
return nfc_tech_iso7816_reply(pIso7816App->pIso7816);
}
inline static nfc_tech_iso7816_c_apdu_t* nfc_tech_iso7816_app_c_apdu(nfc_tech_iso7816_app_t* pIso7816App)
inline static nfc_tech_iso7816_c_apdu_t *nfc_tech_iso7816_app_c_apdu(nfc_tech_iso7816_app_t *pIso7816App)
{
return nfc_tech_iso7816_c_apdu(pIso7816App->pIso7816);
return nfc_tech_iso7816_c_apdu(pIso7816App->pIso7816);
}
inline static nfc_tech_iso7816_r_apdu_t* nfc_tech_iso7816_app_r_apdu(nfc_tech_iso7816_app_t* pIso7816App)
inline static nfc_tech_iso7816_r_apdu_t *nfc_tech_iso7816_app_r_apdu(nfc_tech_iso7816_app_t *pIso7816App)
{
return nfc_tech_iso7816_r_apdu(pIso7816App->pIso7816);
return nfc_tech_iso7816_r_apdu(pIso7816App->pIso7816);
}
#ifdef __cplusplus

View File

@ -32,12 +32,11 @@ extern "C" {
struct nfc_tech_isodep;
typedef struct nfc_tech_isodep nfc_tech_isodep_t;
typedef void (*nfc_tech_isodep_cb_t)(nfc_tech_isodep_t* pIsodep, nfc_err_t ret, void* pUserData);
typedef void (*nfc_tech_isodep_disconnected_cb)(nfc_tech_isodep_t* pIsodep, bool deselected, void* pUserData);
typedef void (*nfc_tech_isodep_cb_t)(nfc_tech_isodep_t *pIsodep, nfc_err_t ret, void *pUserData);
typedef void (*nfc_tech_isodep_disconnected_cb)(nfc_tech_isodep_t *pIsodep, bool deselected, void *pUserData);
struct nfc_tech_isodep
{
struct nfc_tech_isodep {
};

File diff suppressed because it is too large Load Diff

View File

@ -35,81 +35,76 @@ struct nfc_tech_isodep_target;
typedef struct nfc_tech_isodep_target nfc_tech_isodep_target_t;
typedef struct nfc_tech_isodep_target nfc_tech_isodep_target_t;
struct nfc_tech_isodep_target
{
nfc_tech_isodep_t isodep;
nfc_transceiver_t* pTransceiver;
struct nfc_tech_isodep_target {
nfc_tech_isodep_t isodep;
nfc_transceiver_t *pTransceiver;
struct
{
ostream_t* pReqStream;
istream_t* pResStream;
struct {
ostream_t *pReqStream;
istream_t *pResStream;
nfc_tech_isodep_cb_t reqCb;
void* pReqUserData;
nfc_tech_isodep_cb_t reqCb;
void *pReqUserData;
nfc_tech_isodep_cb_t resCb;
void* pResUserData;
nfc_tech_isodep_cb_t resCb;
void *pResUserData;
buffer_t res;
bool chaining;
buffer_t res;
bool chaining;
uint8_t blockNumber;
uint8_t blockNumber;
enum
{
ISO_DEP_TARGET_DEP_FRAME_IDLE,
ISO_DEP_TARGET_DEP_FRAME_WTX_RECEIVED,
ISO_DEP_TARGET_DEP_FRAME_WTX_SENT,
ISO_DEP_TARGET_DEP_FRAME_INFORMATION_RECEIVED,
ISO_DEP_TARGET_DEP_FRAME_INFORMATION_SENT,
ISO_DEP_TARGET_DEP_FRAME_NACK_RECEIVED,
ISO_DEP_TARGET_DEP_FRAME_NACK_DIFF_BLOCK_NUMBER_RECEIVED,
ISO_DEP_TARGET_DEP_FRAME_NACK_SENT,
ISO_DEP_TARGET_DEP_FRAME_ACK_RECEIVED,
ISO_DEP_TARGET_DEP_FRAME_ACK_SENT,
ISO_DEP_TARGET_DEP_FRAME_DESELECT_RECEIVED,
ISO_DEP_TARGET_DEP_FRAME_DESELECT_SENT,
} frameState;
} dep;
struct
{
enum
{
ISO_DEP_TARGET_COMMANDS_DISCONNECTED,
enum {
ISO_DEP_TARGET_DEP_FRAME_IDLE,
ISO_DEP_TARGET_DEP_FRAME_WTX_RECEIVED,
ISO_DEP_TARGET_DEP_FRAME_WTX_SENT,
ISO_DEP_TARGET_DEP_FRAME_INFORMATION_RECEIVED,
ISO_DEP_TARGET_DEP_FRAME_INFORMATION_SENT,
ISO_DEP_TARGET_DEP_FRAME_NACK_RECEIVED,
ISO_DEP_TARGET_DEP_FRAME_NACK_DIFF_BLOCK_NUMBER_RECEIVED,
ISO_DEP_TARGET_DEP_FRAME_NACK_SENT,
ISO_DEP_TARGET_DEP_FRAME_ACK_RECEIVED,
ISO_DEP_TARGET_DEP_FRAME_ACK_SENT,
ISO_DEP_TARGET_DEP_FRAME_DESELECT_RECEIVED,
ISO_DEP_TARGET_DEP_FRAME_DESELECT_SENT,
} frameState;
} dep;
struct {
enum {
ISO_DEP_TARGET_COMMANDS_DISCONNECTED,
ISO_DEP_TARGET_COMMANDS_CONNECTING,
ISO_DEP_TARGET_COMMANDS_CONNECTING,
ISO_DEP_TARGET_COMMANDS_ATS_REQ_RECVD,
ISO_DEP_TARGET_COMMANDS_ATS_RES_SENT,
ISO_DEP_TARGET_COMMANDS_ATS_REQ_RECVD,
ISO_DEP_TARGET_COMMANDS_ATS_RES_SENT,
ISO_DEP_TARGET_COMMANDS_DEP_REQ_RECVD,
ISO_DEP_TARGET_COMMANDS_DEP_RES_SENT,
} state;
ISO_DEP_TARGET_COMMANDS_DEP_REQ_RECVD,
ISO_DEP_TARGET_COMMANDS_DEP_RES_SENT,
} state;
size_t inPayloadSize;
size_t inPayloadSize;
buffer_builder_t respBldr;
uint8_t respBuf[32];
buffer_builder_t respBldr;
uint8_t respBuf[32];
buffer_t* pReq;
} commands;
buffer_t *pReq;
} commands;
buffer_t* pHist;
buffer_t *pHist;
nfc_tech_isodep_disconnected_cb disconnectedCb;
void* pUserData;
nfc_tech_isodep_disconnected_cb disconnectedCb;
void *pUserData;
};
//High-level Target functions
void nfc_tech_isodep_target_init(nfc_tech_isodep_target_t* pIsodepTarget, nfc_transceiver_t* pTransceiver,
buffer_t* pHist, nfc_tech_isodep_disconnected_cb disconnectedCb, void* pUserData);
void nfc_tech_isodep_target_init(nfc_tech_isodep_target_t *pIsodepTarget, nfc_transceiver_t *pTransceiver,
buffer_t *pHist, nfc_tech_isodep_disconnected_cb disconnectedCb, void *pUserData);
nfc_err_t nfc_tech_isodep_target_connect(nfc_tech_isodep_target_t* pIsodepTarget);
void nfc_tech_isodep_target_disconnect(nfc_tech_isodep_target_t* pIsodepTarget);
nfc_err_t nfc_tech_isodep_target_connect(nfc_tech_isodep_target_t *pIsodepTarget);
void nfc_tech_isodep_target_disconnect(nfc_tech_isodep_target_t *pIsodepTarget);
nfc_err_t nfc_tech_isodep_target_transmit(nfc_tech_isodep_target_t* pIsodepTarget, istream_t* pStream, nfc_tech_isodep_cb_t cb, void* pUserData);
nfc_err_t nfc_tech_isodep_target_receive(nfc_tech_isodep_target_t* pIsodepTarget, ostream_t* pStream, nfc_tech_isodep_cb_t cb, void* pUserData);
nfc_err_t nfc_tech_isodep_target_transmit(nfc_tech_isodep_target_t *pIsodepTarget, istream_t *pStream, nfc_tech_isodep_cb_t cb, void *pUserData);
nfc_err_t nfc_tech_isodep_target_receive(nfc_tech_isodep_target_t *pIsodepTarget, ostream_t *pStream, nfc_tech_isodep_cb_t cb, void *pUserData);
#ifdef __cplusplus

View File

@ -41,272 +41,246 @@ static const uint8_t aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00 };
#define NDEF_FILE 0xA443
#define DEFAULT_FILE 0x0000
static void app_selected( nfc_tech_iso7816_app_t* pIso7816App, void* pUserData );
static void app_deselected( nfc_tech_iso7816_app_t* pIso7816App, void* pUserData );
static void app_apdu( nfc_tech_iso7816_app_t* pIso7816App, void* pUserData );
static void app_selected(nfc_tech_iso7816_app_t *pIso7816App, void *pUserData);
static void app_deselected(nfc_tech_iso7816_app_t *pIso7816App, void *pUserData);
static void app_apdu(nfc_tech_iso7816_app_t *pIso7816App, void *pUserData);
static nfc_err_t data_read(nfc_tech_type4_target_t* pType4Target, buffer_t* pBuf, uint16_t file, size_t off, size_t len);
static nfc_err_t data_write(nfc_tech_type4_target_t* pType4Target, buffer_t* pBuf, uint16_t file, size_t off);
static nfc_err_t data_read(nfc_tech_type4_target_t *pType4Target, buffer_t *pBuf, uint16_t file, size_t off, size_t len);
static nfc_err_t data_write(nfc_tech_type4_target_t *pType4Target, buffer_t *pBuf, uint16_t file, size_t off);
void nfc_tech_type4_target_init(nfc_tech_type4_target_t* pType4Target, nfc_tech_iso7816_t* pIso7816, ndef_msg_t* pNdef)
void nfc_tech_type4_target_init(nfc_tech_type4_target_t *pType4Target, nfc_tech_iso7816_t *pIso7816, ndef_msg_t *pNdef)
{
buffer_builder_init(&pType4Target->ccFileBldr, pType4Target->ccFileBuf, /*sizeof(pType4Target->ccFileBuf)*/15);
buffer_builder_init(&pType4Target->ccFileBldr, pType4Target->ccFileBuf, /*sizeof(pType4Target->ccFileBuf)*/15);
buffer_builder_init(&pType4Target->ndefFileBldr, pType4Target->ndefFileBuf, /*sizeof(pType4Target->ndefFileBuf)*/2);
buffer_builder_init(&pType4Target->ndefFileBldr, pType4Target->ndefFileBuf, /*sizeof(pType4Target->ndefFileBuf)*/2);
pType4Target->selFile = DEFAULT_FILE;
pType4Target->pNdef = pNdef;
pType4Target->written = false;
pType4Target->selFile = DEFAULT_FILE;
pType4Target->pNdef = pNdef;
pType4Target->written = false;
nfc_tech_iso7816_app_init(&pType4Target->app, pIso7816, aid, sizeof(aid), app_selected, app_deselected, app_apdu, pType4Target);
nfc_tech_iso7816_app_init(&pType4Target->app, pIso7816, aid, sizeof(aid), app_selected, app_deselected, app_apdu, pType4Target);
nfc_tech_iso7816_add_app(pIso7816, &pType4Target->app);
nfc_tech_iso7816_add_app(pIso7816, &pType4Target->app);
}
void app_selected( nfc_tech_iso7816_app_t* pIso7816App, void* pUserData )
void app_selected(nfc_tech_iso7816_app_t *pIso7816App, void *pUserData)
{
nfc_tech_type4_target_t* pType4Target = (nfc_tech_type4_target_t*) pUserData;
DBG("Selected");
nfc_tech_type4_target_t *pType4Target = (nfc_tech_type4_target_t *) pUserData;
DBG("Selected");
(void) pIso7816App;
(void) pIso7816App;
buffer_builder_reset(ndef_msg_buffer_builder(pType4Target->pNdef));
buffer_builder_reset(ndef_msg_buffer_builder(pType4Target->pNdef));
//Populate CC file
buffer_builder_reset(&pType4Target->ccFileBldr);
buffer_builder_write_nu16( &pType4Target->ccFileBldr, 15 ); //CC file is 15 bytes long
//Populate CC file
buffer_builder_reset(&pType4Target->ccFileBldr);
buffer_builder_write_nu16(&pType4Target->ccFileBldr, 15); //CC file is 15 bytes long
#if TYPE4_NDEF_VERSION == 2
buffer_builder_write_nu8( &pType4Target->ccFileBldr, 0x20 ); //NFC Forum Tag Type 4 V2.0 compliant
buffer_builder_write_nu8(&pType4Target->ccFileBldr, 0x20); //NFC Forum Tag Type 4 V2.0 compliant
#else
buffer_builder_write_nu8( &pType4Target->ccFileBldr, 0x10 ); //NFC Forum Tag Type 4 V1.0 compliant
buffer_builder_write_nu8(&pType4Target->ccFileBldr, 0x10); //NFC Forum Tag Type 4 V1.0 compliant
#endif
buffer_builder_write_nu16( &pType4Target->ccFileBldr, 256 /* Max frame size */ - 2 /* SW */ - 3 /* ISO-DEP PFB + DID + NAD */ ); //Max data size that can be read from the tag
buffer_builder_write_nu16( &pType4Target->ccFileBldr, 256 /* Max frame size */ - 6 /* CLA INS P1 P2 LC LE */ - 3 /* ISO-DEP PFB + DID + NAD */ ); //Max data size that can be written to the tag
buffer_builder_write_nu8( &pType4Target->ccFileBldr, 0x04 ); //NDEF File Control TLV - Type
buffer_builder_write_nu8( &pType4Target->ccFileBldr, 6 ); //NDEF File Control TLV - Length
buffer_builder_write_nu16( &pType4Target->ccFileBldr, NDEF_FILE ); //NDEF file id
buffer_builder_write_nu16( &pType4Target->ccFileBldr, 2 /* length header */ + buffer_builder_writeable( ndef_msg_buffer_builder(pType4Target->pNdef) ) ); //Max size of NDEF data
buffer_builder_write_nu8( &pType4Target->ccFileBldr, 0x00 ); //Open read access
buffer_builder_write_nu8( &pType4Target->ccFileBldr, 0x00 ); //Open write access
buffer_builder_write_nu16(&pType4Target->ccFileBldr, 256 /* Max frame size */ - 2 /* SW */ - 3 /* ISO-DEP PFB + DID + NAD */); //Max data size that can be read from the tag
buffer_builder_write_nu16(&pType4Target->ccFileBldr, 256 /* Max frame size */ - 6 /* CLA INS P1 P2 LC LE */ - 3 /* ISO-DEP PFB + DID + NAD */); //Max data size that can be written to the tag
buffer_builder_write_nu8(&pType4Target->ccFileBldr, 0x04); //NDEF File Control TLV - Type
buffer_builder_write_nu8(&pType4Target->ccFileBldr, 6); //NDEF File Control TLV - Length
buffer_builder_write_nu16(&pType4Target->ccFileBldr, NDEF_FILE); //NDEF file id
buffer_builder_write_nu16(&pType4Target->ccFileBldr, 2 /* length header */ + buffer_builder_writeable(ndef_msg_buffer_builder(pType4Target->pNdef))); //Max size of NDEF data
buffer_builder_write_nu8(&pType4Target->ccFileBldr, 0x00); //Open read access
buffer_builder_write_nu8(&pType4Target->ccFileBldr, 0x00); //Open write access
//Encode NDEF file
ndef_msg_encode(pType4Target->pNdef);
//Encode NDEF file
ndef_msg_encode(pType4Target->pNdef);
//Populate NDEF file
buffer_builder_init(&pType4Target->ndefFileBldr, pType4Target->ndefFileBuf, /*sizeof(pType4Target->ndefFileBuf)*/2);
//Populate NDEF file
buffer_builder_init(&pType4Target->ndefFileBldr, pType4Target->ndefFileBuf, /*sizeof(pType4Target->ndefFileBuf)*/2);
buffer_builder_write_nu16( &pType4Target->ndefFileBldr, buffer_reader_readable( buffer_builder_buffer(ndef_msg_buffer_builder(pType4Target->pNdef)) ) );
buffer_builder_write_nu16(&pType4Target->ndefFileBldr, buffer_reader_readable(buffer_builder_buffer(ndef_msg_buffer_builder(pType4Target->pNdef))));
//Pad NDEF file with 0s
while( buffer_builder_writeable( ndef_msg_buffer_builder(pType4Target->pNdef) ) > 0 )
{
buffer_builder_write_nu8(ndef_msg_buffer_builder(pType4Target->pNdef), 0);
}
//Pad NDEF file with 0s
while (buffer_builder_writeable(ndef_msg_buffer_builder(pType4Target->pNdef)) > 0) {
buffer_builder_write_nu8(ndef_msg_buffer_builder(pType4Target->pNdef), 0);
}
//No file selected
pType4Target->selFile = DEFAULT_FILE;
//No file selected
pType4Target->selFile = DEFAULT_FILE;
pType4Target->written = false;
pType4Target->written = false;
}
void app_deselected( nfc_tech_iso7816_app_t* pIso7816App, void* pUserData )
void app_deselected(nfc_tech_iso7816_app_t *pIso7816App, void *pUserData)
{
nfc_tech_type4_target_t* pType4Target = (nfc_tech_type4_target_t*) pUserData;
nfc_tech_type4_target_t *pType4Target = (nfc_tech_type4_target_t *) pUserData;
(void) pIso7816App;
(void) pIso7816App;
//Reset buffers
buffer_builder_reset(&pType4Target->ccFileBldr);
buffer_builder_set_full(&pType4Target->ndefFileBldr); //To read length
buffer_builder_reset(ndef_msg_buffer_builder(pType4Target->pNdef));
//Reset buffers
buffer_builder_reset(&pType4Target->ccFileBldr);
buffer_builder_set_full(&pType4Target->ndefFileBldr); //To read length
buffer_builder_reset(ndef_msg_buffer_builder(pType4Target->pNdef));
DBG("Deselected");
DBG("Deselected");
if(pType4Target->written)
{
DBG("New content has been written");
//Try to parse NDEF
//Set buffer length based on file header
size_t length = buffer_read_nu16(buffer_builder_buffer(&pType4Target->ndefFileBldr));
DBG("Length is %lu", length);
if( length < buffer_builder_writeable( ndef_msg_buffer_builder(pType4Target->pNdef) ))
{
buffer_builder_set_write_offset( ndef_msg_buffer_builder(pType4Target->pNdef), length );
ndef_msg_decode(pType4Target->pNdef);
if (pType4Target->written) {
DBG("New content has been written");
//Try to parse NDEF
//Set buffer length based on file header
size_t length = buffer_read_nu16(buffer_builder_buffer(&pType4Target->ndefFileBldr));
DBG("Length is %lu", length);
if (length < buffer_builder_writeable(ndef_msg_buffer_builder(pType4Target->pNdef))) {
buffer_builder_set_write_offset(ndef_msg_buffer_builder(pType4Target->pNdef), length);
ndef_msg_decode(pType4Target->pNdef);
} else {
ERR("Invalid length");
}
}
else
{
ERR("Invalid length");
}
}
}
void app_apdu( nfc_tech_iso7816_app_t* pIso7816App, void* pUserData )
void app_apdu(nfc_tech_iso7816_app_t *pIso7816App, void *pUserData)
{
nfc_tech_type4_target_t* pType4Target = (nfc_tech_type4_target_t*) pUserData;
nfc_tech_type4_target_t *pType4Target = (nfc_tech_type4_target_t *) pUserData;
//Reset buffers
buffer_builder_set_full(&pType4Target->ccFileBldr);
buffer_builder_set_full(&pType4Target->ndefFileBldr);
buffer_builder_set_full( ndef_msg_buffer_builder(pType4Target->pNdef) ); //Set offset to 0, size to max
//Reset buffers
buffer_builder_set_full(&pType4Target->ccFileBldr);
buffer_builder_set_full(&pType4Target->ndefFileBldr);
buffer_builder_set_full(ndef_msg_buffer_builder(pType4Target->pNdef)); //Set offset to 0, size to max
buffer_set_next(buffer_builder_buffer(&pType4Target->ndefFileBldr), buffer_builder_buffer(ndef_msg_buffer_builder(pType4Target->pNdef)));
buffer_set_next(buffer_builder_buffer(&pType4Target->ndefFileBldr), buffer_builder_buffer(ndef_msg_buffer_builder(pType4Target->pNdef)));
//Recover PDU
nfc_tech_iso7816_c_apdu_t* pCApdu = nfc_tech_iso7816_app_c_apdu(pIso7816App);
nfc_tech_iso7816_r_apdu_t* pRApdu = nfc_tech_iso7816_app_r_apdu(pIso7816App);
//Recover PDU
nfc_tech_iso7816_c_apdu_t *pCApdu = nfc_tech_iso7816_app_c_apdu(pIso7816App);
nfc_tech_iso7816_r_apdu_t *pRApdu = nfc_tech_iso7816_app_r_apdu(pIso7816App);
nfc_err_t ret;
switch(pCApdu->ins)
{
case ISO7816_INS_SELECT:
switch (pCApdu->p1)
{
case 0x00: //Selection by ID
case 0x02: //Selection by child ID
if ( buffer_reader_readable(&pCApdu->dataIn) != 2)
{
pRApdu->sw = ISO7816_SW_NOT_FOUND;
break;
}
nfc_err_t ret;
switch (pCApdu->ins) {
case ISO7816_INS_SELECT:
switch (pCApdu->p1) {
case 0x00: //Selection by ID
case 0x02: //Selection by child ID
if (buffer_reader_readable(&pCApdu->dataIn) != 2) {
pRApdu->sw = ISO7816_SW_NOT_FOUND;
break;
}
uint16_t file = buffer_read_nu16(&pCApdu->dataIn);
if ( file == NDEF_FILE )
{
pType4Target->selFile = NDEF_FILE;
DBG("NDEF File selected");
pRApdu->sw = ISO7816_SW_OK;
}
else if ( file == CC_FILE )
{
pType4Target->selFile = CC_FILE;
DBG("CC File selected");
pRApdu->sw = ISO7816_SW_OK;
}
else
{
//file = DEFAULT_FILE;
DBG("Could not select file %04X", file);
pRApdu->sw = ISO7816_SW_NOT_FOUND;
}
break;
default:
pRApdu->sw = ISO7816_SW_NOT_FOUND;
break;
uint16_t file = buffer_read_nu16(&pCApdu->dataIn);
if (file == NDEF_FILE) {
pType4Target->selFile = NDEF_FILE;
DBG("NDEF File selected");
pRApdu->sw = ISO7816_SW_OK;
} else if (file == CC_FILE) {
pType4Target->selFile = CC_FILE;
DBG("CC File selected");
pRApdu->sw = ISO7816_SW_OK;
} else {
//file = DEFAULT_FILE;
DBG("Could not select file %04X", file);
pRApdu->sw = ISO7816_SW_NOT_FOUND;
}
break;
default:
pRApdu->sw = ISO7816_SW_NOT_FOUND;
break;
}
break;
case 0xB0: //Read binary
DBG("Trying to read %d bytes at offset %d from file %04x", pCApdu->maxRespLength, (pCApdu->p1 << 8) | pCApdu->p2, pType4Target->selFile);
ret = data_read(pType4Target, &pRApdu->dataOut, pType4Target->selFile, (pCApdu->p1 << 8) | pCApdu->p2, pCApdu->maxRespLength);
if (ret == NFC_OK) {
DBG("Read %d bytes", buffer_reader_readable(&pRApdu->dataOut));
DBG_BLOCK(buffer_dump(&pRApdu->dataOut);)
pRApdu->sw = ISO7816_SW_OK;
} else {
DBG("Failed with ret code %d", ret);
pRApdu->sw = ISO7816_SW_WRONG_LENGTH;
}
break;
case 0xD6: //Update binary
DBG("Trying to write %d bytes at offset %d to file %04x", buffer_reader_readable(&pCApdu->dataIn), (pCApdu->p1 << 8) | pCApdu->p2, pType4Target->selFile);
ret = data_write(pType4Target, &pCApdu->dataIn, pType4Target->selFile, (pCApdu->p1 << 8) | pCApdu->p2);
if (ret == NFC_OK) {
DBG("OK");
pRApdu->sw = ISO7816_SW_OK;
pType4Target->written = true;
} else {
DBG("Failed with ret code %d", ret);
pRApdu->sw = ISO7816_SW_WRONG_LENGTH;
}
break;
default:
pRApdu->sw = ISO7816_SW_INVALID_INS;
break;
}
break;
case 0xB0: //Read binary
DBG("Trying to read %d bytes at offset %d from file %04x", pCApdu->maxRespLength, (pCApdu->p1 << 8) | pCApdu->p2, pType4Target->selFile);
ret = data_read(pType4Target, &pRApdu->dataOut, pType4Target->selFile, (pCApdu->p1 << 8) | pCApdu->p2, pCApdu->maxRespLength);
if (ret == NFC_OK)
{
DBG("Read %d bytes", buffer_reader_readable(&pRApdu->dataOut));
DBG_BLOCK( buffer_dump(&pRApdu->dataOut); )
pRApdu->sw = ISO7816_SW_OK;
}
else
{
DBG("Failed with ret code %d", ret);
pRApdu->sw = ISO7816_SW_WRONG_LENGTH;
}
break;
case 0xD6: //Update binary
DBG("Trying to write %d bytes at offset %d to file %04x", buffer_reader_readable(&pCApdu->dataIn), (pCApdu->p1 << 8) | pCApdu->p2, pType4Target->selFile);
ret = data_write(pType4Target, &pCApdu->dataIn, pType4Target->selFile, (pCApdu->p1 << 8) | pCApdu->p2);
if (ret == NFC_OK)
{
DBG("OK");
pRApdu->sw = ISO7816_SW_OK;
pType4Target->written = true;
}
else
{
DBG("Failed with ret code %d", ret);
pRApdu->sw = ISO7816_SW_WRONG_LENGTH;
}
break;
default:
pRApdu->sw = ISO7816_SW_INVALID_INS;
break;
}
//Send reply
nfc_tech_iso7816_app_reply(pIso7816App);
//Send reply
nfc_tech_iso7816_app_reply(pIso7816App);
}
nfc_err_t data_read(nfc_tech_type4_target_t* pType4Target, buffer_t* pBuf, uint16_t file, size_t off, size_t len)
nfc_err_t data_read(nfc_tech_type4_target_t *pType4Target, buffer_t *pBuf, uint16_t file, size_t off, size_t len)
{
buffer_t* pFile;
switch(file)
{
case CC_FILE:
pFile = buffer_builder_buffer(&pType4Target->ccFileBldr);
break;
case NDEF_FILE:
pFile = buffer_builder_buffer(&pType4Target->ndefFileBldr);
break;
default:
return NFC_ERR_NOT_FOUND;
}
buffer_t *pFile;
switch (file) {
case CC_FILE:
pFile = buffer_builder_buffer(&pType4Target->ccFileBldr);
break;
case NDEF_FILE:
pFile = buffer_builder_buffer(&pType4Target->ndefFileBldr);
break;
default:
return NFC_ERR_NOT_FOUND;
}
if( off > buffer_reader_readable(pFile) )
{
return NFC_ERR_LENGTH;
}
if (off > buffer_reader_readable(pFile)) {
return NFC_ERR_LENGTH;
}
buffer_read_n_skip(pFile, off);
buffer_read_n_skip(pFile, off);
if( len > buffer_reader_readable(pFile))
{
len = buffer_reader_readable(pFile);
}
if (len > buffer_reader_readable(pFile)) {
len = buffer_reader_readable(pFile);
}
buffer_split(pBuf, pFile, pFile, len);
buffer_split(pBuf, pFile, pFile, len);
return NFC_OK;
return NFC_OK;
}
nfc_err_t data_write(nfc_tech_type4_target_t* pType4Target, buffer_t* pBuf, uint16_t file, size_t off)
nfc_err_t data_write(nfc_tech_type4_target_t *pType4Target, buffer_t *pBuf, uint16_t file, size_t off)
{
buffer_t* pFile;
switch(file)
{
case NDEF_FILE:
pFile = buffer_builder_buffer(&pType4Target->ndefFileBldr);
break;
case CC_FILE: //Cannot write to CC file!
default:
return NFC_ERR_NOT_FOUND;
}
buffer_t *pFile;
switch (file) {
case NDEF_FILE:
pFile = buffer_builder_buffer(&pType4Target->ndefFileBldr);
break;
case CC_FILE: //Cannot write to CC file!
default:
return NFC_ERR_NOT_FOUND;
}
size_t len = buffer_reader_readable(pBuf);
size_t len = buffer_reader_readable(pBuf);
if( off > buffer_reader_readable(pFile) )
{
return NFC_ERR_LENGTH;
}
if (off > buffer_reader_readable(pFile)) {
return NFC_ERR_LENGTH;
}
buffer_read_n_skip(pFile, off);
buffer_read_n_skip(pFile, off);
if( len > buffer_reader_readable(pFile) )
{
len = buffer_reader_readable(pFile);
}
if (len > buffer_reader_readable(pFile)) {
len = buffer_reader_readable(pFile);
}
while( len > 0 )
{
size_t cpy;
buffer_builder_t builder;
buffer_dup(buffer_builder_buffer(&builder), pFile);
buffer_builder_from_buffer(&builder);
cpy = buffer_builder_writeable(&builder);
cpy = MIN(cpy, len);
buffer_builder_copy_n_bytes(&builder, pBuf, cpy);
pFile = buffer_next(pFile);
len -= cpy;
}
while (len > 0) {
size_t cpy;
buffer_builder_t builder;
buffer_dup(buffer_builder_buffer(&builder), pFile);
buffer_builder_from_buffer(&builder);
cpy = buffer_builder_writeable(&builder);
cpy = MIN(cpy, len);
buffer_builder_copy_n_bytes(&builder, pBuf, cpy);
pFile = buffer_next(pFile);
len -= cpy;
}
return NFC_OK;
return NFC_OK;
}

View File

@ -35,26 +35,25 @@ extern "C" {
typedef struct nfc_tech_type4_target nfc_tech_type4_target_t;
typedef void (*nfc_tech_type4_cb)(nfc_tech_type4_target_t* pType4Target, nfc_err_t ret, void* pUserData);
typedef void (*nfc_tech_type4_cb)(nfc_tech_type4_target_t *pType4Target, nfc_err_t ret, void *pUserData);
struct nfc_tech_type4_target
{
nfc_tech_iso7816_app_t app;
struct nfc_tech_type4_target {
nfc_tech_iso7816_app_t app;
ndef_msg_t* pNdef;
ndef_msg_t *pNdef;
uint8_t ccFileBuf[15];
buffer_builder_t ccFileBldr;
uint8_t ccFileBuf[15];
buffer_builder_t ccFileBldr;
uint8_t ndefFileBuf[2];
buffer_builder_t ndefFileBldr;
uint8_t ndefFileBuf[2];
buffer_builder_t ndefFileBldr;
uint16_t selFile;
uint16_t selFile;
bool written;
bool written;
};
void nfc_tech_type4_target_init(nfc_tech_type4_target_t* pType4Target, nfc_tech_iso7816_t* pIso7816, ndef_msg_t* pNdef);
void nfc_tech_type4_target_init(nfc_tech_type4_target_t *pType4Target, nfc_tech_iso7816_t *pIso7816, ndef_msg_t *pNdef);
#ifdef __cplusplus
}

View File

@ -60,8 +60,7 @@
//PN 512 VTABLE
static const transceiver_impl_t pn512_impl =
{
static const transceiver_impl_t pn512_impl = {
.set_protocols = pn512_set_protocols,
.poll = pn512_poll,
.transceive = pn512_transceive,
@ -76,7 +75,7 @@ static const transceiver_impl_t pn512_impl =
.get_last_byte_length = pn512_get_last_byte_length,
.set_first_byte_align = pn512_set_first_byte_align,
.close = pn512_close,
.sleep = pn512_sleep
.sleep = pn512_sleep
};
/** Initialize PN512 transceiver
@ -84,291 +83,271 @@ static const transceiver_impl_t pn512_impl =
* \param pTransport pointer to already initialized nfc_transport_t structure
* \return NFC_OK (0) on success or NFC_ERR_* error on failure
*/
nfc_err_t pn512_init(pn512_t* pPN512, nfc_transport_t* pTransport, nfc_scheduler_timer_t* pTimer)
nfc_err_t pn512_init(pn512_t *pPN512, nfc_transport_t *pTransport, nfc_scheduler_timer_t *pTimer)
{
////
//For Self-test
////
#if NFC_PN512_SELFTEST
const uint8_t null_array[25] = {0};
#endif
////
uint8_t r;
////
//For Self-test
////
#if NFC_PN512_SELFTEST
const uint8_t null_array[25] = {0};
#endif
////
uint8_t r;
//Init transceiver
transceiver_init((nfc_transceiver_t*)pPN512, pTransport, pTimer);
//Init transceiver
transceiver_init((nfc_transceiver_t *)pPN512, pTransport, pTimer);
//Init buffer
buffer_builder_init(&pPN512->readBufBldr, pPN512->payload, 256);
//Init buffer
buffer_builder_init(&pPN512->readBufBldr, pPN512->payload, 256);
pPN512->readFirstByteAlign = 0;
pPN512->readLastByteLength = 8;
pPN512->writeLastByteLength = 8;
pPN512->readFirstByteAlign = 0;
pPN512->readLastByteLength = 8;
pPN512->writeLastByteLength = 8;
//Populate functions
pPN512->transceiver.fn = &pn512_impl;
//Populate functions
pPN512->transceiver.fn = &pn512_impl;
//Init variables
memset(&pPN512->config.initiators, 0, sizeof(nfc_tech_t));
memset(&pPN512->config.targets, 0, sizeof(nfc_tech_t));
pPN512->timeout = -1;
pPN512->nextFrameMode = pn512_transceive_mode_transceive;
//Init variables
memset(&pPN512->config.initiators, 0, sizeof(nfc_tech_t));
memset(&pPN512->config.targets, 0, sizeof(nfc_tech_t));
pPN512->timeout = -1;
pPN512->nextFrameMode = pn512_transceive_mode_transceive;
pn512_hw_init(pPN512);
pn512_registers_init(pPN512); //Cannot switch page now
pn512_cmd_init(pPN512);
pn512_hw_init(pPN512);
pn512_registers_init(pPN512); //Cannot switch page now
pn512_cmd_init(pPN512);
pn512_cmd_exec(pPN512, PN512_CMD_SOFTRST);
pn512_cmd_wait_idle(pPN512, -1);
pn512_cmd_exec(pPN512, PN512_CMD_SOFTRST);
pn512_cmd_wait_idle(pPN512, -1);
//pn512_registers_init(pPN512);
//Put into known state
pn512_registers_reset(pPN512);
//pn512_registers_init(pPN512);
//Put into known state
pn512_registers_reset(pPN512);
pPN512->transceive.mode = pn512_transceive_mode_idle;
pPN512->transceive.mode = pn512_transceive_mode_idle;
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
pn512_fifo_clear(pPN512);
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pn512_cmd_wait_idle(pPN512, -1);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
pn512_fifo_clear(pPN512);
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pn512_cmd_wait_idle(pPN512, -1);
pn512_rf_field_switch_off(pPN512);
pn512_rf_field_switch_off(pPN512);
//Required for polling loop
srand(4242);
//Required for polling loop
srand(4242);
#if NFC_PN512_SELFTEST // Self test
pn512_cmd_exec(pPN512, PN512_CMD_SOFTRST);
pn512_cmd_wait_idle(pPN512, -1);
pn512_cmd_exec(pPN512, PN512_CMD_SOFTRST);
pn512_cmd_wait_idle(pPN512, -1);
const uint8_t null_array_buf[25]={0}; //FIXME
buffer_t null_array;
buffer_init(&null_array, null_array_buf, 25);
const uint8_t null_array_buf[25] = {0}; //FIXME
buffer_t null_array;
buffer_init(&null_array, null_array_buf, 25);
//Perform self test
pn512_fifo_write(pPN512, &null_array);
pn512_cmd_exec(pPN512, PN512_CMD_CONFIG);
while(pn512_cmd_get(pPN512) != PN512_CMD_IDLE);
pn512_register_write(pPN512, PN512_REG_AUTOTEST, 0x09);
//Perform self test
pn512_fifo_write(pPN512, &null_array);
pn512_cmd_exec(pPN512, PN512_CMD_CONFIG);
while (pn512_cmd_get(pPN512) != PN512_CMD_IDLE);
pn512_register_write(pPN512, PN512_REG_AUTOTEST, 0x09);
buffer_init(&null_array, null_array_buf, 1);
buffer_init(&null_array, null_array_buf, 1);
pn512_fifo_write(pPN512, &null_array);
pn512_cmd_exec(pPN512, PN512_CMD_CRC);
while(pn512_cmd_get(pPN512) != PN512_CMD_IDLE);
pn512_fifo_write(pPN512, &null_array);
pn512_cmd_exec(pPN512, PN512_CMD_CRC);
while (pn512_cmd_get(pPN512) != PN512_CMD_IDLE);
DBGX_ENTER();
NFC_DBG("Test result:");
while(pn512_fifo_length(pPN512))
{
buffer_builder_t read_byte;
buffer_builder_init(&read_byte, null_array_buf, 1);
DBGX_ENTER();
NFC_DBG("Test result:");
while (pn512_fifo_length(pPN512)) {
buffer_builder_t read_byte;
buffer_builder_init(&read_byte, null_array_buf, 1);
pn512_fifo_read(pPN512, &read_byte);
DBGX("%02x ", null_array_buf[0]);
}
DBGX("\n");
DBGX_LEAVE();
pn512_fifo_read(pPN512, &read_byte);
DBGX("%02x ", null_array_buf[0]);
}
DBGX("\n");
DBGX_LEAVE();
#endif
r = pn512_register_read(pPN512, PN512_REG_VERSION);
r = pn512_register_read(pPN512, PN512_REG_VERSION);
DBG_BLOCK(
NFC_DBG("PN512 version %02x", r);
)
DBG_BLOCK(
NFC_DBG("PN512 version %02x", r);
)
if((r != 0x82) && (r != 0xB1) && (r != 0xB2))
{
return NFC_ERR_UNSUPPORTED; //PN512 not found
}
if ((r != 0x82) && (r != 0xB1) && (r != 0xB2)) {
return NFC_ERR_UNSUPPORTED; //PN512 not found
}
return NFC_OK;
return NFC_OK;
}
/** Get pointer to nfc_transceiver_t structure
* \param pPN512 pointer to pn512_t instance
* \return pointer to initialized nfc_transceiver_t instance
*/
nfc_transceiver_t* pn512_get_transceiver(pn512_t* pPN512)
nfc_transceiver_t *pn512_get_transceiver(pn512_t *pPN512)
{
return &pPN512->transceiver;
return &pPN512->transceiver;
}
void pn512_set_protocols(nfc_transceiver_t* pTransceiver, nfc_tech_t initiators, nfc_tech_t targets, polling_options_t options)
void pn512_set_protocols(nfc_transceiver_t *pTransceiver, nfc_tech_t initiators, nfc_tech_t targets, polling_options_t options)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
//If different, reconfigure
if( memcmp(&initiators, &pPN512->config.initiators, sizeof(nfc_tech_t)) || memcmp(&targets, &pPN512->config.targets, sizeof(nfc_tech_t)) )
{
pPN512->config.initiators = initiators;
if( memcmp(&targets, &pPN512->config.targets, sizeof(nfc_tech_t)) )
{
pPN512->config.targets = targets;
pn512_poll_setup(pPN512);
pn512_t *pPN512 = (pn512_t *) pTransceiver;
//If different, reconfigure
if (memcmp(&initiators, &pPN512->config.initiators, sizeof(nfc_tech_t)) || memcmp(&targets, &pPN512->config.targets, sizeof(nfc_tech_t))) {
pPN512->config.initiators = initiators;
if (memcmp(&targets, &pPN512->config.targets, sizeof(nfc_tech_t))) {
pPN512->config.targets = targets;
pn512_poll_setup(pPN512);
}
pTransceiver->initiator_ntarget = false;
memset(&pTransceiver->active_tech, 0, sizeof(nfc_tech_t));
}
pTransceiver->initiator_ntarget = false;
memset(&pTransceiver->active_tech, 0, sizeof(nfc_tech_t));
}
pPN512->config.options = options;
pPN512->config.options = options;
}
void pn512_poll(nfc_transceiver_t* pTransceiver)
void pn512_poll(nfc_transceiver_t *pTransceiver)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
pPN512->nextFrameMode = pn512_transceive_mode_transceive;
return pn512_poll_hw(pPN512, pn512_transceiver_callback);
}
void pn512_set_crc(nfc_transceiver_t* pTransceiver, bool crc_out, bool crc_in)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
pn512_framing_crc_set(pPN512, crc_out, crc_in);
}
void pn512_set_timeout(nfc_transceiver_t* pTransceiver, int timeout)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
pPN512->timeout = timeout;
}
void pn512_set_transceive_options(nfc_transceiver_t* pTransceiver, bool transmit, bool receive, bool repoll)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
if( transmit && receive )
{
pn512_t *pPN512 = (pn512_t *) pTransceiver;
pPN512->nextFrameMode = pn512_transceive_mode_transceive;
}
else if(transmit && repoll)
{
pPN512->nextFrameMode = pn512_transceive_mode_transmit_and_target_autocoll;
}
else if(transmit)
{
pPN512->nextFrameMode = pn512_transceive_mode_transmit;
}
else if(receive)
{
pPN512->nextFrameMode = pn512_transceive_mode_receive;
}
else
{
pPN512->nextFrameMode = pn512_transceive_mode_target_autocoll;
}
return pn512_poll_hw(pPN512, pn512_transceiver_callback);
}
void pn512_set_transceive_framing(nfc_transceiver_t* pTransceiver, nfc_framing_t framing)
void pn512_set_crc(nfc_transceiver_t *pTransceiver, bool crc_out, bool crc_in)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
pn512_framing_set(pPN512, framing);
pn512_t *pPN512 = (pn512_t *) pTransceiver;
pn512_framing_crc_set(pPN512, crc_out, crc_in);
}
//Switch NFC tech if NFC DEP
if( pTransceiver->active_tech.nfc_nfc_dep_a
|| pTransceiver->active_tech.nfc_nfc_dep_f_212
|| pTransceiver->active_tech.nfc_nfc_dep_f_424 )
{
//FIXME
pTransceiver->active_tech.nfc_nfc_dep_a = 0;
pTransceiver->active_tech.nfc_nfc_dep_f_212 = 0;
pTransceiver->active_tech.nfc_nfc_dep_f_424 = 0;
switch(framing)
{
case nfc_framing_target_a_106:
case nfc_framing_initiator_a_106:
pTransceiver->active_tech.nfc_nfc_dep_a = 1;
break;
case nfc_framing_target_f_212:
case nfc_framing_initiator_f_212:
pTransceiver->active_tech.nfc_nfc_dep_f_212 = 1;
break;
case nfc_framing_target_f_424:
case nfc_framing_initiator_f_424:
pTransceiver->active_tech.nfc_nfc_dep_f_424 = 1;
break;
default:
break;
void pn512_set_timeout(nfc_transceiver_t *pTransceiver, int timeout)
{
pn512_t *pPN512 = (pn512_t *) pTransceiver;
pPN512->timeout = timeout;
}
void pn512_set_transceive_options(nfc_transceiver_t *pTransceiver, bool transmit, bool receive, bool repoll)
{
pn512_t *pPN512 = (pn512_t *) pTransceiver;
if (transmit && receive) {
pPN512->nextFrameMode = pn512_transceive_mode_transceive;
} else if (transmit && repoll) {
pPN512->nextFrameMode = pn512_transceive_mode_transmit_and_target_autocoll;
} else if (transmit) {
pPN512->nextFrameMode = pn512_transceive_mode_transmit;
} else if (receive) {
pPN512->nextFrameMode = pn512_transceive_mode_receive;
} else {
pPN512->nextFrameMode = pn512_transceive_mode_target_autocoll;
}
}
}
void pn512_set_write(nfc_transceiver_t* pTransceiver, buffer_t* pWriteBuf)
void pn512_set_transceive_framing(nfc_transceiver_t *pTransceiver, nfc_framing_t framing)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
if( pWriteBuf == NULL )
{
buffer_init(&pPN512->writeBuf, NULL, 0);
pn512_t *pPN512 = (pn512_t *) pTransceiver;
pn512_framing_set(pPN512, framing);
//Switch NFC tech if NFC DEP
if (pTransceiver->active_tech.nfc_nfc_dep_a
|| pTransceiver->active_tech.nfc_nfc_dep_f_212
|| pTransceiver->active_tech.nfc_nfc_dep_f_424) {
//FIXME
pTransceiver->active_tech.nfc_nfc_dep_a = 0;
pTransceiver->active_tech.nfc_nfc_dep_f_212 = 0;
pTransceiver->active_tech.nfc_nfc_dep_f_424 = 0;
switch (framing) {
case nfc_framing_target_a_106:
case nfc_framing_initiator_a_106:
pTransceiver->active_tech.nfc_nfc_dep_a = 1;
break;
case nfc_framing_target_f_212:
case nfc_framing_initiator_f_212:
pTransceiver->active_tech.nfc_nfc_dep_f_212 = 1;
break;
case nfc_framing_target_f_424:
case nfc_framing_initiator_f_424:
pTransceiver->active_tech.nfc_nfc_dep_f_424 = 1;
break;
default:
break;
}
}
}
void pn512_set_write(nfc_transceiver_t *pTransceiver, buffer_t *pWriteBuf)
{
pn512_t *pPN512 = (pn512_t *) pTransceiver;
if (pWriteBuf == NULL) {
buffer_init(&pPN512->writeBuf, NULL, 0);
return;
}
buffer_dup(&pPN512->writeBuf, pWriteBuf);
}
buffer_t *pn512_get_read(nfc_transceiver_t *pTransceiver)
{
pn512_t *pPN512 = (pn512_t *) pTransceiver;
return buffer_builder_buffer(&pPN512->readBufBldr);
}
void pn512_set_last_byte_length(nfc_transceiver_t *pTransceiver, size_t lastByteLength)
{
pn512_t *pPN512 = (pn512_t *) pTransceiver;
if ((lastByteLength > 8) || (lastByteLength == 0)) {
lastByteLength = 8;
}
pPN512->writeLastByteLength = lastByteLength;
}
void pn512_set_first_byte_align(nfc_transceiver_t *pTransceiver, size_t firstByteAlign)
{
pn512_t *pPN512 = (pn512_t *) pTransceiver;
firstByteAlign &= 0x7;
pPN512->readFirstByteAlign = firstByteAlign;
}
size_t pn512_get_last_byte_length(nfc_transceiver_t *pTransceiver)
{
pn512_t *pPN512 = (pn512_t *) pTransceiver;
return pPN512->readLastByteLength;
}
void pn512_transceive(nfc_transceiver_t *pTransceiver)
{
pn512_t *pPN512 = (pn512_t *) pTransceiver;
pn512_transceive_hw(pPN512, pPN512->nextFrameMode, pn512_transceiver_callback);
pPN512->nextFrameMode = pn512_transceive_mode_transceive;
}
void pn512_abort(nfc_transceiver_t *pTransceiver)
{
pn512_t *pPN512 = (pn512_t *) pTransceiver;
scheduler_dequeue_task(&pTransceiver->scheduler, true, &pPN512->transceiver.task);
}
void pn512_close(nfc_transceiver_t *pTransceiver)
{
//pn512_t* pPN512 = (pn512_t*) pTransceiver;
(void) pTransceiver;
//TODO
return;
}
buffer_dup(&pPN512->writeBuf, pWriteBuf);
}
buffer_t* pn512_get_read(nfc_transceiver_t* pTransceiver)
void pn512_sleep(nfc_transceiver_t *pTransceiver, bool sleep)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
return buffer_builder_buffer(&pPN512->readBufBldr);
pn512_t *pPN512 = (pn512_t *) pTransceiver;
if (sleep) {
pn512_register_write(pPN512, PN512_REG_COMMAND, 0x30); //Receiver off + soft power down
} else {
pn512_register_write(pPN512, PN512_REG_COMMAND, 0x00);
while (pn512_register_read(pPN512, PN512_REG_COMMAND) & 0x10);
}
}
void pn512_set_last_byte_length(nfc_transceiver_t* pTransceiver, size_t lastByteLength)
void pn512_transceiver_callback(pn512_t *pPN512, nfc_err_t ret)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
if( (lastByteLength > 8) || (lastByteLength == 0) )
{
lastByteLength = 8;
}
pPN512->writeLastByteLength = lastByteLength;
}
void pn512_set_first_byte_align(nfc_transceiver_t* pTransceiver, size_t firstByteAlign)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
firstByteAlign &= 0x7;
pPN512->readFirstByteAlign = firstByteAlign;
}
size_t pn512_get_last_byte_length(nfc_transceiver_t* pTransceiver)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
return pPN512->readLastByteLength;
}
void pn512_transceive(nfc_transceiver_t* pTransceiver)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
pn512_transceive_hw(pPN512, pPN512->nextFrameMode, pn512_transceiver_callback);
pPN512->nextFrameMode = pn512_transceive_mode_transceive;
}
void pn512_abort(nfc_transceiver_t* pTransceiver)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
scheduler_dequeue_task(&pTransceiver->scheduler, true, &pPN512->transceiver.task);
}
void pn512_close(nfc_transceiver_t* pTransceiver)
{
//pn512_t* pPN512 = (pn512_t*) pTransceiver;
(void) pTransceiver;
//TODO
return;
}
void pn512_sleep(nfc_transceiver_t* pTransceiver, bool sleep)
{
pn512_t* pPN512 = (pn512_t*) pTransceiver;
if(sleep)
{
pn512_register_write(pPN512, PN512_REG_COMMAND, 0x30); //Receiver off + soft power down
}
else
{
pn512_register_write(pPN512, PN512_REG_COMMAND, 0x00);
while( pn512_register_read(pPN512, PN512_REG_COMMAND) & 0x10 );
}
}
void pn512_transceiver_callback(pn512_t* pPN512, nfc_err_t ret)
{
transceiver_callback(&pPN512->transceiver, ret);
transceiver_callback(&pPN512->transceiver, ret);
}
/**

View File

@ -34,131 +34,118 @@ typedef struct __pn512 pn512_t;
#include "pn512_callback.h"
#include "pn512_types.h"
typedef enum __pn512_state
{
pn512_state_ready,
pn512_state_target_autocoll,
pn512_state_initiator_transceive_first_frame,
pn512_state_transceive,
pn512_state_transceive_last_frame,
typedef enum __pn512_state {
pn512_state_ready,
pn512_state_target_autocoll,
pn512_state_initiator_transceive_first_frame,
pn512_state_transceive,
pn512_state_transceive_last_frame,
} pn512_state_t;
typedef enum __pn512_transceive_mode
{
pn512_transceive_mode_idle,
pn512_transceive_mode_target_autocoll,
pn512_transceive_mode_transmit,
pn512_transceive_mode_transmit_and_target_autocoll,
pn512_transceive_mode_transceive,
pn512_transceive_mode_receive,
typedef enum __pn512_transceive_mode {
pn512_transceive_mode_idle,
pn512_transceive_mode_target_autocoll,
pn512_transceive_mode_transmit,
pn512_transceive_mode_transmit_and_target_autocoll,
pn512_transceive_mode_transceive,
pn512_transceive_mode_receive,
} pn512_transceive_mode_t;
typedef struct __pn512
{
nfc_transceiver_t transceiver;
//Impl specific
pn512_registers_t registers;
bool rf_on;
struct
{
bool out;
bool in;
} crc;
int timeout;
typedef struct __pn512 {
nfc_transceiver_t transceiver;
//Impl specific
pn512_registers_t registers;
bool rf_on;
struct {
bool out;
bool in;
} crc;
int timeout;
struct
{
nfc_tech_t initiators;
nfc_tech_t targets;
polling_options_t options;
} config;
struct {
nfc_tech_t initiators;
nfc_tech_t targets;
polling_options_t options;
} config;
//Transceive options
pn512_transceive_mode_t nextFrameMode;
//Transceive options
pn512_transceive_mode_t nextFrameMode;
nfc_framing_t framing;
uint16_t irqsEn;
uint8_t payload[256]; //Incoming buffer
nfc_framing_t framing;
uint16_t irqsEn;
uint8_t payload[256]; //Incoming buffer
buffer_builder_t readBufBldr;
buffer_t writeBuf;
buffer_builder_t readBufBldr;
buffer_t writeBuf;
uint8_t readFirstByteAlign;
uint8_t readLastByteLength;
uint8_t writeLastByteLength;
uint8_t readFirstByteAlign;
uint8_t readLastByteLength;
uint8_t writeLastByteLength;
//Task parameters
struct
{
//Polling
struct
{
enum {
pn512_polling_state_start_listening,
//Task parameters
struct {
//Polling
struct {
enum {
pn512_polling_state_start_listening,
pn512_polling_state_listen_wait_for_remote_field,
pn512_polling_state_listen_anticollision,
pn512_polling_state_listen_wait_for_remote_field,
pn512_polling_state_listen_anticollision,
pn512_polling_state_listen_no_target_found,
pn512_polling_state_listen_no_target_found,
pn512_polling_state_start_polling,
pn512_polling_state_start_polling,
pn512_polling_state_rf_collision_avoidance, // TID + n × TRFW, n is random, TID>4096/(13.56E6) ~ 302.06us, TRFW=51/(13.56E6) ~ 37.76us
pn512_polling_state_polling_nfc_a_start,
pn512_polling_state_polling_nfc_a_gt, // guard time nfc a >= 5.0 ms
pn512_polling_state_polling_nfc_a_anticollision, // polling for nfc a
pn512_polling_state_polling_nfc_b_start,
pn512_polling_state_polling_nfc_b_gt, // guard time nfc b >= 5.0 ms
pn512_polling_state_polling_nfc_b_anticollision, // polling for nfc b
pn512_polling_state_polling_nfc_f_start,
pn512_polling_state_polling_nfc_f_gt, // guard time nfc f >= 20 ms
pn512_polling_state_polling_nfc_f_anticollision, // polling for nfc f
pn512_polling_state_rf_collision_avoidance, // TID + n × TRFW, n is random, TID>4096/(13.56E6) ~ 302.06us, TRFW=51/(13.56E6) ~ 37.76us
pn512_polling_state_polling_nfc_a_start,
pn512_polling_state_polling_nfc_a_gt, // guard time nfc a >= 5.0 ms
pn512_polling_state_polling_nfc_a_anticollision, // polling for nfc a
pn512_polling_state_polling_nfc_b_start,
pn512_polling_state_polling_nfc_b_gt, // guard time nfc b >= 5.0 ms
pn512_polling_state_polling_nfc_b_anticollision, // polling for nfc b
pn512_polling_state_polling_nfc_f_start,
pn512_polling_state_polling_nfc_f_gt, // guard time nfc f >= 20 ms
pn512_polling_state_polling_nfc_f_anticollision, // polling for nfc f
pn512_polling_state_finish_polling,
pn512_polling_state_finish_polling,
} state;
} state;
pn512_cb_t cb;
} poll;
struct
{
pn512_cb_t cb;
pn512_transceive_mode_t mode;
} transceive;
struct
{
pn512_cb_t cb;
} rf;
struct
{
union
{
// ISO A
struct
{
bool more_targets; // Collision detected
uint8_t cascade_level;
uint8_t cln[5];
uint8_t valid_bits; // valid bits within cascade level
} iso_a;
// ISO B
struct
{
bool more_targets; // Collision detected
uint8_t slots_num_exponent;
uint8_t slot_number;
bool found_one;
} iso_b;
};
pn512_cb_t cb;
} anticollision;
};
pn512_cb_t cb;
} poll;
struct {
pn512_cb_t cb;
pn512_transceive_mode_t mode;
} transceive;
struct {
pn512_cb_t cb;
} rf;
struct {
union {
// ISO A
struct {
bool more_targets; // Collision detected
uint8_t cascade_level;
uint8_t cln[5];
uint8_t valid_bits; // valid bits within cascade level
} iso_a;
// ISO B
struct {
bool more_targets; // Collision detected
uint8_t slots_num_exponent;
uint8_t slot_number;
bool found_one;
} iso_b;
};
pn512_cb_t cb;
} anticollision;
};
} pn512_t;
nfc_err_t pn512_init(pn512_t* pPN512, nfc_transport_t* pTransport, nfc_scheduler_timer_t* pTimer);
nfc_err_t pn512_init(pn512_t *pPN512, nfc_transport_t *pTransport, nfc_scheduler_timer_t *pTimer);
nfc_transceiver_t* pn512_get_transceiver(pn512_t* pPN512);
nfc_transceiver_t *pn512_get_transceiver(pn512_t *pPN512);
#ifdef __cplusplus
}

View File

@ -28,7 +28,7 @@ extern "C" {
#endif
typedef struct __pn512 pn512_t;
typedef void (*pn512_cb_t)(pn512_t* pPN512, nfc_err_t ret);
typedef void (*pn512_cb_t)(pn512_t *pPN512, nfc_err_t ret);
#ifdef __cplusplus
}

View File

@ -47,9 +47,9 @@
/** \internal Initialize underlying pn512_cmd_t structure
* \param pPN512 pointer to pn512_t structure
*/
void pn512_cmd_init(pn512_t* pPN512)
void pn512_cmd_init(pn512_t *pPN512)
{
(void) pPN512;
(void) pPN512;
}
//Fifo read / write
@ -57,64 +57,64 @@ void pn512_cmd_init(pn512_t* pPN512)
* \param pPN512 pointer to pn512_t structure
* \param pData buffer to write
*/
void pn512_fifo_write(pn512_t* pPN512, buffer_t* pData)
void pn512_fifo_write(pn512_t *pPN512, buffer_t *pData)
{
uint8_t fifo_space = pn512_fifo_space(pPN512); //Do not call this fn twice
size_t len = buffer_reader_readable(pData);
len = MIN(fifo_space, len);
uint8_t fifo_space = pn512_fifo_space(pPN512); //Do not call this fn twice
size_t len = buffer_reader_readable(pData);
len = MIN(fifo_space, len);
pn512_register_switch_page(pPN512, PN512_REG_FIFODATA);
pn512_hw_write_buffer(pPN512, PN512_REG_FIFODATA, pData, len);
pn512_register_switch_page(pPN512, PN512_REG_FIFODATA);
pn512_hw_write_buffer(pPN512, PN512_REG_FIFODATA, pData, len);
}
/** \internal Read bytes from FIFO
* \param pPN512 pointer to pn512_t structure
* \param pData buffer in which to read
*/
void pn512_fifo_read(pn512_t* pPN512, buffer_builder_t* pData)
void pn512_fifo_read(pn512_t *pPN512, buffer_builder_t *pData)
{
uint8_t fifo_len = pn512_fifo_length(pPN512); //Do not call this fn twice
size_t len = buffer_builder_writeable(pData);
len = MIN(fifo_len, len);
uint8_t fifo_len = pn512_fifo_length(pPN512); //Do not call this fn twice
size_t len = buffer_builder_writeable(pData);
len = MIN(fifo_len, len);
pn512_register_switch_page(pPN512, PN512_REG_FIFODATA);
pn512_hw_read_buffer(pPN512, PN512_REG_FIFODATA, pData, len);
pn512_register_switch_page(pPN512, PN512_REG_FIFODATA);
pn512_hw_read_buffer(pPN512, PN512_REG_FIFODATA, pData, len);
}
/** \internal Clear FIFO
* Removes any bytes left in FIFO
* \param pPN512 pointer to pn512_t structure
*/
void pn512_fifo_clear(pn512_t* pPN512)
void pn512_fifo_clear(pn512_t *pPN512)
{
pn512_register_write(pPN512, PN512_REG_FIFOLEVEL, 0x80); //Flush FIFO
pn512_register_write(pPN512, PN512_REG_FIFOLEVEL, 0x80); //Flush FIFO
}
/** \internal Get space in FIFO
* \param pPN512 pointer to pn512_t structure
* \return number of bytes that can be written to FIFO
*/
size_t pn512_fifo_space(pn512_t* pPN512)
size_t pn512_fifo_space(pn512_t *pPN512)
{
return PN512_FIFO_SIZE - pn512_register_read(pPN512, PN512_REG_FIFOLEVEL);
return PN512_FIFO_SIZE - pn512_register_read(pPN512, PN512_REG_FIFOLEVEL);
}
/** \internal Get FIFO length
* \param pPN512 pointer to pn512_t structure
* \return number of bytes that can be read from FIFO
*/
size_t pn512_fifo_length(pn512_t* pPN512)
size_t pn512_fifo_length(pn512_t *pPN512)
{
return pn512_register_read(pPN512, PN512_REG_FIFOLEVEL);
return pn512_register_read(pPN512, PN512_REG_FIFOLEVEL);
}
/** \internal Execute command
* \param pPN512 pointer to pn512_t structure
* \param cmd PN512 command to execute
*/
void pn512_cmd_exec(pn512_t* pPN512, uint8_t cmd)
void pn512_cmd_exec(pn512_t *pPN512, uint8_t cmd)
{
pn512_register_write(pPN512, PN512_REG_COMMAND, cmd);
pn512_register_write(pPN512, PN512_REG_COMMAND, cmd);
}
/** \internal Wait for command completion
@ -122,14 +122,13 @@ void pn512_cmd_exec(pn512_t* pPN512, uint8_t cmd)
* \param timeout timeout in milliseconds or -1 for blocking mode
* \return NFC_OK on success or NFC_ERR_TIMEOUT on timeout
*/
nfc_err_t pn512_cmd_wait_idle(pn512_t* pPN512, int timeout)
nfc_err_t pn512_cmd_wait_idle(pn512_t *pPN512, int timeout)
{
(void) timeout;
while( pn512_cmd_get(pPN512) != PN512_CMD_IDLE )
{
(void) timeout;
while (pn512_cmd_get(pPN512) != PN512_CMD_IDLE) {
}
return NFC_OK;
}
return NFC_OK;
}
@ -137,9 +136,9 @@ nfc_err_t pn512_cmd_wait_idle(pn512_t* pPN512, int timeout)
* \param pPN512 pointer to pn512_t structure
* \return PN512 command being executed
*/
uint8_t pn512_cmd_get(pn512_t* pPN512)
uint8_t pn512_cmd_get(pn512_t *pPN512)
{
return pn512_register_read(pPN512, PN512_REG_COMMAND) & PN512_CMD_REG_MASK;
return pn512_register_read(pPN512, PN512_REG_COMMAND) & PN512_CMD_REG_MASK;
}
/**

View File

@ -47,28 +47,28 @@ extern "C" {
#define PN512_CMD_REG_MASK 0x0F
void pn512_cmd_init(pn512_t* pPN512);
void pn512_cmd_init(pn512_t *pPN512);
//Fifo read / write
void pn512_fifo_write(pn512_t* pPN512, buffer_t* pData);
void pn512_fifo_read(pn512_t* pPN512, buffer_builder_t* pData);
void pn512_fifo_write(pn512_t *pPN512, buffer_t *pData);
void pn512_fifo_read(pn512_t *pPN512, buffer_builder_t *pData);
//Fifo clear
void pn512_fifo_clear(pn512_t* pPN512);
void pn512_fifo_clear(pn512_t *pPN512);
//Fifo bytes read
size_t pn512_fifo_space(pn512_t* pPN512);
size_t pn512_fifo_length(pn512_t* pPN512);
size_t pn512_fifo_space(pn512_t *pPN512);
size_t pn512_fifo_length(pn512_t *pPN512);
//Execute command
void pn512_cmd_exec(pn512_t* pPN512, uint8_t cmd);
void pn512_cmd_exec(pn512_t *pPN512, uint8_t cmd);
//Wait for command completion
nfc_err_t pn512_cmd_wait_idle(pn512_t* pPN512, int timeout);
nfc_err_t pn512_cmd_wait_idle(pn512_t *pPN512, int timeout);
//Read executed command
uint8_t pn512_cmd_get(pn512_t* pPN512);
uint8_t pn512_cmd_get(pn512_t *pPN512);
#ifdef __cplusplus

View File

@ -40,10 +40,10 @@
/** \internal Initialize underlying pn512_hw_t structure
* \param pPN512 pointer to pn512_t structure
*/
void pn512_hw_init(pn512_t* pPN512)
void pn512_hw_init(pn512_t *pPN512)
{
//Nothing to init in this implementation
(void) pPN512;
//Nothing to init in this implementation
(void) pPN512;
}

View File

@ -35,7 +35,7 @@ extern "C" {
#define PN512_SPI_ADDR_R(x) ((1<<7) | ((x) << 1))
#define PN512_SPI_ADDR_W(x) ((0<<7) | ((x) << 1))
void pn512_hw_init(pn512_t* pPN512);
void pn512_hw_init(pn512_t *pPN512);
/** \internal Write bytes at the specified address on the underlying transport link
* \param pPN512 pointer to pn512_t structure
@ -43,9 +43,9 @@ void pn512_hw_init(pn512_t* pPN512);
* \param buf buffer to write
* \param len length of buffer
*/
static inline void pn512_hw_write(pn512_t* pPN512, uint8_t addr, uint8_t* buf, size_t len)
static inline void pn512_hw_write(pn512_t *pPN512, uint8_t addr, uint8_t *buf, size_t len)
{
nfc_transport_write(((nfc_transceiver_t*)pPN512)->pTransport, addr, buf, len);
nfc_transport_write(((nfc_transceiver_t *)pPN512)->pTransport, addr, buf, len);
}
/** \internal Read bytes from the specified address on the underlying transport link
@ -54,40 +54,36 @@ static inline void pn512_hw_write(pn512_t* pPN512, uint8_t addr, uint8_t* buf, s
* \param buf buffer to read
* \param len length of buffer
*/
static inline void pn512_hw_read(pn512_t* pPN512, uint8_t addr, uint8_t* buf, size_t len)
static inline void pn512_hw_read(pn512_t *pPN512, uint8_t addr, uint8_t *buf, size_t len)
{
nfc_transport_read(((nfc_transceiver_t*)pPN512)->pTransport, addr, buf, len);
nfc_transport_read(((nfc_transceiver_t *)pPN512)->pTransport, addr, buf, len);
}
static inline void pn512_hw_write_buffer(pn512_t* pPN512, uint8_t addr, buffer_t* pData, size_t len)
static inline void pn512_hw_write_buffer(pn512_t *pPN512, uint8_t addr, buffer_t *pData, size_t len)
{
while( len > 0 )
{
if( buffer_reader_readable(pData) == 0 )
{
return;
while (len > 0) {
if (buffer_reader_readable(pData) == 0) {
return;
}
size_t cpyLen = MIN(len, buffer_reader_current_buffer_length(pData));
nfc_transport_write(((nfc_transceiver_t *)pPN512)->pTransport, addr, buffer_reader_current_buffer_pointer(pData), cpyLen);
buffer_read_n_skip(pData, cpyLen);
len -= cpyLen;
}
size_t cpyLen = MIN(len, buffer_reader_current_buffer_length(pData));
nfc_transport_write(((nfc_transceiver_t*)pPN512)->pTransport, addr, buffer_reader_current_buffer_pointer(pData), cpyLen);
buffer_read_n_skip(pData, cpyLen);
len -= cpyLen;
}
}
static inline void pn512_hw_read_buffer(pn512_t* pPN512, uint8_t addr, buffer_builder_t* pData, size_t len)
static inline void pn512_hw_read_buffer(pn512_t *pPN512, uint8_t addr, buffer_builder_t *pData, size_t len)
{
while( len > 0 )
{
if( buffer_builder_writeable(pData) == 0 )
{
return;
while (len > 0) {
if (buffer_builder_writeable(pData) == 0) {
return;
}
//Read payload
size_t cpyLen = MIN(len, buffer_builder_space(pData));
nfc_transport_read(((nfc_transceiver_t *)pPN512)->pTransport, addr, buffer_builder_write_position(pData), cpyLen);
buffer_builder_write_n_skip(pData, cpyLen);
len -= cpyLen;
}
//Read payload
size_t cpyLen = MIN(len, buffer_builder_space(pData));
nfc_transport_read(((nfc_transceiver_t*)pPN512)->pTransport, addr, buffer_builder_write_position(pData), cpyLen);
buffer_builder_write_n_skip(pData, cpyLen);
len -= cpyLen;
}
}
#ifdef __cplusplus

View File

@ -35,42 +35,42 @@ extern "C" {
#include "pn512_callback.h"
//Public
void pn512_set_protocols(nfc_transceiver_t* pTransceiver, nfc_tech_t initiators, nfc_tech_t targets, polling_options_t options);
void pn512_poll(nfc_transceiver_t* pTransceiver);
void pn512_set_crc(nfc_transceiver_t* pTransceiver, bool crc_out, bool crc_in);
void pn512_set_timeout(nfc_transceiver_t* pTransceiver, int timeout);
void pn512_set_transceive_options(nfc_transceiver_t* pTransceiver, bool transmit, bool receive, bool repoll);
void pn512_set_transceive_framing(nfc_transceiver_t* pTransceiver, nfc_framing_t framing);
void pn512_set_write(nfc_transceiver_t* pTransceiver, buffer_t* pWriteBuf);
buffer_t* pn512_get_read(nfc_transceiver_t* pTransceiver);
size_t pn512_get_last_byte_length(nfc_transceiver_t* pTransceiver);
void pn512_set_last_byte_length(nfc_transceiver_t* pTransceiver, size_t lastByteLength);
void pn512_set_first_byte_align(nfc_transceiver_t* pTransceiver, size_t firstByteAlign);
void pn512_abort(nfc_transceiver_t* pTransceiver);
void pn512_transceive(nfc_transceiver_t* pTransceiver);
void pn512_close(nfc_transceiver_t* pTransceiver);
void pn512_sleep(nfc_transceiver_t* pTransceiver, bool sleep);
void pn512_set_protocols(nfc_transceiver_t *pTransceiver, nfc_tech_t initiators, nfc_tech_t targets, polling_options_t options);
void pn512_poll(nfc_transceiver_t *pTransceiver);
void pn512_set_crc(nfc_transceiver_t *pTransceiver, bool crc_out, bool crc_in);
void pn512_set_timeout(nfc_transceiver_t *pTransceiver, int timeout);
void pn512_set_transceive_options(nfc_transceiver_t *pTransceiver, bool transmit, bool receive, bool repoll);
void pn512_set_transceive_framing(nfc_transceiver_t *pTransceiver, nfc_framing_t framing);
void pn512_set_write(nfc_transceiver_t *pTransceiver, buffer_t *pWriteBuf);
buffer_t *pn512_get_read(nfc_transceiver_t *pTransceiver);
size_t pn512_get_last_byte_length(nfc_transceiver_t *pTransceiver);
void pn512_set_last_byte_length(nfc_transceiver_t *pTransceiver, size_t lastByteLength);
void pn512_set_first_byte_align(nfc_transceiver_t *pTransceiver, size_t firstByteAlign);
void pn512_abort(nfc_transceiver_t *pTransceiver);
void pn512_transceive(nfc_transceiver_t *pTransceiver);
void pn512_close(nfc_transceiver_t *pTransceiver);
void pn512_sleep(nfc_transceiver_t *pTransceiver, bool sleep);
void pn512_transceiver_callback(pn512_t* pPN512, nfc_err_t ret);
void pn512_transceiver_callback(pn512_t *pPN512, nfc_err_t ret);
static inline void pn512_rf_callback(pn512_t* pPN512, nfc_err_t ret)
static inline void pn512_rf_callback(pn512_t *pPN512, nfc_err_t ret)
{
pPN512->rf.cb(pPN512, ret);
pPN512->rf.cb(pPN512, ret);
}
static inline void pn512_poll_callback(pn512_t* pPN512, nfc_err_t ret)
static inline void pn512_poll_callback(pn512_t *pPN512, nfc_err_t ret)
{
pPN512->poll.cb(pPN512, ret);
pPN512->poll.cb(pPN512, ret);
}
static inline void pn512_anticollision_callback(pn512_t* pPN512, nfc_err_t ret)
static inline void pn512_anticollision_callback(pn512_t *pPN512, nfc_err_t ret)
{
pPN512->anticollision.cb(pPN512, ret);
pPN512->anticollision.cb(pPN512, ret);
}
static inline void pn512_transceive_callback(pn512_t* pPN512, nfc_err_t ret)
static inline void pn512_transceive_callback(pn512_t *pPN512, nfc_err_t ret)
{
pPN512->transceive.cb(pPN512, ret);
pPN512->transceive.cb(pPN512, ret);
}

View File

@ -65,20 +65,20 @@ extern "C" {
* \param pPN512 pointer to pn512_t structure
* \param irqs MSB is DIVIEN value, LSB is COMIEN value
*/
static inline void pn512_irq_set(pn512_t* pPN512, uint16_t irqs) //ORed
static inline void pn512_irq_set(pn512_t *pPN512, uint16_t irqs) //ORed
{
pn512_register_write(pPN512, PN512_REG_COMIEN, PN512_REG_COMIEN_VAL | (PN512_REG_COMIEN_MASK & (irqs & 0xFF)));
pn512_register_write(pPN512, PN512_REG_DIVIEN, PN512_REG_DIVIEN_VAL | (PN512_REG_DIVIEN_MASK & (irqs >> 8)));
pPN512->irqsEn = irqs;
pn512_register_write(pPN512, PN512_REG_COMIEN, PN512_REG_COMIEN_VAL | (PN512_REG_COMIEN_MASK & (irqs & 0xFF)));
pn512_register_write(pPN512, PN512_REG_DIVIEN, PN512_REG_DIVIEN_VAL | (PN512_REG_DIVIEN_MASK & (irqs >> 8)));
pPN512->irqsEn = irqs;
}
/** \internal Get IRQ enable registers
* \param pPN512 pointer to pn512_t structure
* \return MSB is DIVIEN value, LSB is COMIEN value
*/
static inline uint16_t pn512_irq_enabled(pn512_t* pPN512) //ORed
static inline uint16_t pn512_irq_enabled(pn512_t *pPN512) //ORed
{
return pPN512->irqsEn /*(pn512_register_read(pPN512, PN512_REG_COMIEN_VAL) & PN512_REG_COMIEN_MASK)
return pPN512->irqsEn /*(pn512_register_read(pPN512, PN512_REG_COMIEN_VAL) & PN512_REG_COMIEN_MASK)
| ((pn512_register_read(pPN512, PN512_REG_DIVIEN_VAL) & PN512_REG_DIVIEN_MASK) << 8)*/;
}
@ -86,20 +86,20 @@ static inline uint16_t pn512_irq_enabled(pn512_t* pPN512) //ORed
* \param pPN512 pointer to pn512_t structure
* \return MSB is DIVIRQ value, LSB is COMIRQ value
*/
static inline uint16_t pn512_irq_get(pn512_t* pPN512) //ORed
static inline uint16_t pn512_irq_get(pn512_t *pPN512) //ORed
{
return ((pn512_register_read(pPN512, PN512_REG_COMIRQ) & PN512_REG_COMIEN_MASK)
| ((pn512_register_read(pPN512, PN512_REG_DIVIRQ) & PN512_REG_DIVIEN_MASK) << 8)) & pPN512->irqsEn;
return ((pn512_register_read(pPN512, PN512_REG_COMIRQ) & PN512_REG_COMIEN_MASK)
| ((pn512_register_read(pPN512, PN512_REG_DIVIRQ) & PN512_REG_DIVIEN_MASK) << 8)) & pPN512->irqsEn;
}
/** \internal Clear some interrupts
* \param pPN512 pointer to pn512_t structure
* \param irqs MSB is DIVIEN value, LSB is COMIEN value
*/
static inline void pn512_irq_clear(pn512_t* pPN512, uint16_t irqs)
static inline void pn512_irq_clear(pn512_t *pPN512, uint16_t irqs)
{
pn512_register_write(pPN512, PN512_REG_COMIRQ, PN512_REG_COMIRQ_CLEAR | (PN512_REG_COMIRQ_MASK & (irqs & 0xFF)));
pn512_register_write(pPN512, PN512_REG_DIVIRQ, PN512_REG_DIVIRQ_CLEAR | (PN512_REG_DIVIRQ_MASK & (irqs >> 8)));
pn512_register_write(pPN512, PN512_REG_COMIRQ, PN512_REG_COMIRQ_CLEAR | (PN512_REG_COMIRQ_MASK & (irqs & 0xFF)));
pn512_register_write(pPN512, PN512_REG_DIVIRQ, PN512_REG_DIVIRQ_CLEAR | (PN512_REG_DIVIRQ_MASK & (irqs >> 8)));
}
#ifdef __cplusplus

File diff suppressed because it is too large Load Diff

View File

@ -30,8 +30,8 @@ extern "C" {
#include "inc/nfc.h"
void pn512_poll_setup(pn512_t* pPN512);
void pn512_poll_hw(pn512_t* pPN512, pn512_cb_t cb);
void pn512_poll_setup(pn512_t *pPN512);
void pn512_poll_hw(pn512_t *pPN512, pn512_cb_t cb);
#ifdef __cplusplus

View File

@ -43,14 +43,14 @@
* @{
*/
static void pn512_register_switch_page_intl(pn512_t* pPN512, uint8_t page);
static void pn512_register_switch_page_intl(pn512_t *pPN512, uint8_t page);
/** \internal Initialize underlying pn512_registers_t structure
* \param pPN512 pointer to pn512_t structure
*/
void pn512_registers_init(pn512_t* pPN512)
void pn512_registers_init(pn512_t *pPN512)
{
pPN512->registers.registers_page = 0;
pPN512->registers.registers_page = 0;
}
#define PN512_CFG_INIT_LEN 9
@ -80,13 +80,12 @@ static const uint8_t PN512_CFG_INIT_VALS[] = {
/** \internal Switch to known (0) registers page, reset registers state
* \param pPN512 pointer to pn512_t structure
*/
void pn512_registers_reset(pn512_t* pPN512)
void pn512_registers_reset(pn512_t *pPN512)
{
pn512_register_switch_page_intl(pPN512, 0);
for(int i = 0; i < PN512_CFG_INIT_LEN; i++)
{
pn512_register_write(pPN512, PN512_CFG_INIT_REGS[i], PN512_CFG_INIT_VALS[i]);
}
pn512_register_switch_page_intl(pPN512, 0);
for (int i = 0; i < PN512_CFG_INIT_LEN; i++) {
pn512_register_write(pPN512, PN512_CFG_INIT_REGS[i], PN512_CFG_INIT_VALS[i]);
}
}
/** \internal Write register
@ -94,15 +93,14 @@ void pn512_registers_reset(pn512_t* pPN512)
* \param address register address
* \param data value to write in register
*/
void pn512_register_write(pn512_t* pPN512, uint8_t address, uint8_t data)
void pn512_register_write(pn512_t *pPN512, uint8_t address, uint8_t data)
{
NFC_DBG("Write [%02x] << %02x", address, data);
if(REGISTER_PAGE(address) != pPN512->registers.registers_page)
{
pn512_register_switch_page_intl(pPN512, REGISTER_PAGE(address));
}
address=REGISTER_ADDR(address);
pn512_hw_write(pPN512, address, &data, 1);
NFC_DBG("Write [%02x] << %02x", address, data);
if (REGISTER_PAGE(address) != pPN512->registers.registers_page) {
pn512_register_switch_page_intl(pPN512, REGISTER_PAGE(address));
}
address = REGISTER_ADDR(address);
pn512_hw_write(pPN512, address, &data, 1);
}
/** \internal Read register
@ -110,43 +108,41 @@ void pn512_register_write(pn512_t* pPN512, uint8_t address, uint8_t data)
* \param address register address
* \return data value read from register
*/
uint8_t pn512_register_read(pn512_t* pPN512, uint8_t address)
uint8_t pn512_register_read(pn512_t *pPN512, uint8_t address)
{
uint8_t data;
DBG_BLOCK(
uint8_t __dbg_addr;
__dbg_addr = address; //FIXME
)
if(REGISTER_PAGE(address) != pPN512->registers.registers_page)
{
pn512_register_switch_page_intl(pPN512, REGISTER_PAGE(address));
}
address=REGISTER_ADDR(address);
pn512_hw_read(pPN512, address, &data, 1);
NFC_DBG("Read [%02x] >> %02x", __dbg_addr, data);
return data;
uint8_t data;
DBG_BLOCK(
uint8_t __dbg_addr;
__dbg_addr = address; //FIXME
)
if (REGISTER_PAGE(address) != pPN512->registers.registers_page) {
pn512_register_switch_page_intl(pPN512, REGISTER_PAGE(address));
}
address = REGISTER_ADDR(address);
pn512_hw_read(pPN512, address, &data, 1);
NFC_DBG("Read [%02x] >> %02x", __dbg_addr, data);
return data;
}
void pn512_register_switch_page(pn512_t* pPN512, uint8_t address)
void pn512_register_switch_page(pn512_t *pPN512, uint8_t address)
{
if(REGISTER_PAGE(address) != pPN512->registers.registers_page)
{
pn512_register_switch_page_intl(pPN512, REGISTER_PAGE(address));
}
if (REGISTER_PAGE(address) != pPN512->registers.registers_page) {
pn512_register_switch_page_intl(pPN512, REGISTER_PAGE(address));
}
}
/** \internal Switch registers page
* \param pPN512 pointer to pn512_t structure
* \param page registers page
*/
void pn512_register_switch_page_intl(pn512_t* pPN512, uint8_t page)
void pn512_register_switch_page_intl(pn512_t *pPN512, uint8_t page)
{
uint8_t pageRegValue;
pageRegValue = (1 << 7) | page;
uint8_t pageRegValue;
pageRegValue = (1 << 7) | page;
pn512_hw_write(pPN512, PN512_REG_PAGE, &pageRegValue, 1);
pn512_hw_write(pPN512, PN512_REG_PAGE, &pageRegValue, 1);
pPN512->registers.registers_page = page;
pPN512->registers.registers_page = page;
}

View File

@ -99,13 +99,13 @@ extern "C" {
#define PN512_REG_TESTADC 0x3B //Shows the actual value of ADC I and Q
void pn512_registers_init(pn512_t* pPN512);
void pn512_registers_reset(pn512_t* pPN512);
void pn512_registers_init(pn512_t *pPN512);
void pn512_registers_reset(pn512_t *pPN512);
void pn512_register_write(pn512_t* pPN512, uint8_t address, uint8_t data);
uint8_t pn512_register_read(pn512_t* pPN512, uint8_t address);
void pn512_register_write(pn512_t *pPN512, uint8_t address, uint8_t data);
uint8_t pn512_register_read(pn512_t *pPN512, uint8_t address);
void pn512_register_switch_page(pn512_t* pPN512, uint8_t address);
void pn512_register_switch_page(pn512_t *pPN512, uint8_t address);
#ifdef __cplusplus
}

View File

@ -46,296 +46,279 @@ static const uint8_t framing_registers_target_iso14443a_106k[] = { 0x3D, 0x80, 0
static const uint8_t framing_registers_felica_212k[] = { 0x3A, 0x92, 0x92, 0x12, 0x55, 0x15 };
static const uint8_t framing_registers_felica_414k[] = { 0x3A, 0xA2, 0xA2, 0x12, 0x55, 0x0A };
nfc_err_t pn512_framing_set(pn512_t* pPN512, nfc_framing_t framing)
nfc_err_t pn512_framing_set(pn512_t *pPN512, nfc_framing_t framing)
{
if(framing == pPN512->framing) //No need to do anything
{
return NFC_OK;
}
if (framing == pPN512->framing) { //No need to do anything
return NFC_OK;
}
NFC_DBG("Switching to %u", framing);
NFC_DBG("Switching to %u", framing);
const uint8_t* framing_registers_values;
switch(framing)
{
case nfc_framing_target_mode_detector:
framing_registers_values = framing_registers_mode_detector;
break;
case nfc_framing_target_a_106:
framing_registers_values = framing_registers_target_iso14443a_106k;
break;
case nfc_framing_initiator_a_106:
framing_registers_values = framing_registers_initiator_iso14443a_106k;
break;
case nfc_framing_initiator_b_106:
framing_registers_values = framing_registers_initiator_iso14443b_106k;
break;
case nfc_framing_target_f_212:
case nfc_framing_initiator_f_212:
framing_registers_values = framing_registers_felica_212k;
break;
case nfc_framing_target_f_424:
case nfc_framing_initiator_f_424:
framing_registers_values = framing_registers_felica_414k;
break;
default:
return NFC_ERR_UNSUPPORTED;
}
const uint8_t *framing_registers_values;
switch (framing) {
case nfc_framing_target_mode_detector:
framing_registers_values = framing_registers_mode_detector;
break;
case nfc_framing_target_a_106:
framing_registers_values = framing_registers_target_iso14443a_106k;
break;
case nfc_framing_initiator_a_106:
framing_registers_values = framing_registers_initiator_iso14443a_106k;
break;
case nfc_framing_initiator_b_106:
framing_registers_values = framing_registers_initiator_iso14443b_106k;
break;
case nfc_framing_target_f_212:
case nfc_framing_initiator_f_212:
framing_registers_values = framing_registers_felica_212k;
break;
case nfc_framing_target_f_424:
case nfc_framing_initiator_f_424:
framing_registers_values = framing_registers_felica_414k;
break;
default:
return NFC_ERR_UNSUPPORTED;
}
for(int i = 0; i < PN512_FRAMING_REGS; i++)
{
pn512_register_write(pPN512, framing_registers[i], framing_registers_values[i]);
}
for (int i = 0; i < PN512_FRAMING_REGS; i++) {
pn512_register_write(pPN512, framing_registers[i], framing_registers_values[i]);
}
pPN512->framing = framing;
pPN512->crc.out = true;
pPN512->crc.in = true;
pPN512->framing = framing;
pPN512->crc.out = true;
pPN512->crc.in = true;
//TODO initiator: PN512_REG_MODGSP
//TODO initiator: PN512_REG_MODGSP
switch(pPN512->framing)
{
case nfc_framing_initiator_a_106:
case nfc_framing_initiator_b_106:
case nfc_framing_initiator_f_212:
case nfc_framing_initiator_f_424:
pn512_register_write(pPN512, PN512_REG_CONTROL, 0x10); //Act as initiator
break;
case nfc_framing_target_mode_detector:
case nfc_framing_target_a_106:
case nfc_framing_target_f_212:
case nfc_framing_target_f_424:
pn512_register_write(pPN512, PN512_REG_CONTROL, 0x00); //Act as target
break;
default:
return NFC_ERR_UNSUPPORTED;
}
switch (pPN512->framing) {
case nfc_framing_initiator_a_106:
case nfc_framing_initiator_b_106:
case nfc_framing_initiator_f_212:
case nfc_framing_initiator_f_424:
pn512_register_write(pPN512, PN512_REG_CONTROL, 0x10); //Act as initiator
break;
case nfc_framing_target_mode_detector:
case nfc_framing_target_a_106:
case nfc_framing_target_f_212:
case nfc_framing_target_f_424:
pn512_register_write(pPN512, PN512_REG_CONTROL, 0x00); //Act as target
break;
default:
return NFC_ERR_UNSUPPORTED;
}
#if 1
if( (pPN512->framing == nfc_framing_initiator_a_106) /*|| (pPN512->framing == pn512_framing_target_iso14443a_106k)*/ )
{
//Enable 100% ASK Modulation
pn512_register_write(pPN512, PN512_REG_TXAUTO, pn512_register_read(pPN512, PN512_REG_TXAUTO) | 0x40 );
}
else
{
pn512_register_write(pPN512, PN512_REG_TXAUTO, pn512_register_read(pPN512, PN512_REG_TXAUTO) & (~0x40) );
}
if ((pPN512->framing == nfc_framing_initiator_a_106) /*|| (pPN512->framing == pn512_framing_target_iso14443a_106k)*/) {
//Enable 100% ASK Modulation
pn512_register_write(pPN512, PN512_REG_TXAUTO, pn512_register_read(pPN512, PN512_REG_TXAUTO) | 0x40);
} else {
pn512_register_write(pPN512, PN512_REG_TXAUTO, pn512_register_read(pPN512, PN512_REG_TXAUTO) & (~0x40));
}
#endif
return NFC_OK;
return NFC_OK;
}
nfc_err_t pn512_framing_crc_set(pn512_t* pPN512, bool out, bool in)
nfc_err_t pn512_framing_crc_set(pn512_t *pPN512, bool out, bool in)
{
const uint8_t* framing_registers_values;
switch(pPN512->framing)
{
case nfc_framing_target_mode_detector:
framing_registers_values = framing_registers_mode_detector;
break;
case nfc_framing_target_a_106:
framing_registers_values = framing_registers_target_iso14443a_106k;
break;
case nfc_framing_initiator_a_106:
framing_registers_values = framing_registers_initiator_iso14443a_106k;
break;
case nfc_framing_initiator_b_106:
framing_registers_values = framing_registers_initiator_iso14443b_106k;
break;
case nfc_framing_target_f_212:
case nfc_framing_initiator_f_212:
framing_registers_values = framing_registers_felica_212k;
break;
case nfc_framing_target_f_424:
case nfc_framing_initiator_f_424:
framing_registers_values = framing_registers_felica_414k;
break;
default:
return NFC_ERR_UNSUPPORTED;
}
const uint8_t *framing_registers_values;
switch (pPN512->framing) {
case nfc_framing_target_mode_detector:
framing_registers_values = framing_registers_mode_detector;
break;
case nfc_framing_target_a_106:
framing_registers_values = framing_registers_target_iso14443a_106k;
break;
case nfc_framing_initiator_a_106:
framing_registers_values = framing_registers_initiator_iso14443a_106k;
break;
case nfc_framing_initiator_b_106:
framing_registers_values = framing_registers_initiator_iso14443b_106k;
break;
case nfc_framing_target_f_212:
case nfc_framing_initiator_f_212:
framing_registers_values = framing_registers_felica_212k;
break;
case nfc_framing_target_f_424:
case nfc_framing_initiator_f_424:
framing_registers_values = framing_registers_felica_414k;
break;
default:
return NFC_ERR_UNSUPPORTED;
}
if(pPN512->crc.out != out)
{
pn512_register_write(pPN512, framing_registers[1], (framing_registers_values[1] & 0x7F) | (out?0x80:0x00)); //TXMODE
pPN512->crc.out = out;
}
if(pPN512->crc.in != in)
{
pn512_register_write(pPN512, framing_registers[2], (framing_registers_values[2] & 0x7F) | (in?0x80:0x00)); //RXMODE
pPN512->crc.in = in;
}
if (pPN512->crc.out != out) {
pn512_register_write(pPN512, framing_registers[1], (framing_registers_values[1] & 0x7F) | (out ? 0x80 : 0x00)); //TXMODE
pPN512->crc.out = out;
}
if (pPN512->crc.in != in) {
pn512_register_write(pPN512, framing_registers[2], (framing_registers_values[2] & 0x7F) | (in ? 0x80 : 0x00)); //RXMODE
pPN512->crc.in = in;
}
return NFC_OK;
return NFC_OK;
}
nfc_err_t pn512_framing_rx_multiple_enable(pn512_t* pPN512)
nfc_err_t pn512_framing_rx_multiple_enable(pn512_t *pPN512)
{
const uint8_t* framing_registers_values;
switch(pPN512->framing)
{
case nfc_framing_target_mode_detector:
framing_registers_values = framing_registers_mode_detector;
break;
case nfc_framing_target_a_106:
framing_registers_values = framing_registers_target_iso14443a_106k;
break;
case nfc_framing_initiator_a_106:
framing_registers_values = framing_registers_initiator_iso14443a_106k;
break;
case nfc_framing_initiator_b_106:
framing_registers_values = framing_registers_initiator_iso14443b_106k;
break;
case nfc_framing_target_f_212:
case nfc_framing_initiator_f_212:
framing_registers_values = framing_registers_felica_212k;
break;
case nfc_framing_target_f_424:
case nfc_framing_initiator_f_424:
framing_registers_values = framing_registers_felica_414k;
break;
default:
return NFC_ERR_UNSUPPORTED;
}
const uint8_t *framing_registers_values;
switch (pPN512->framing) {
case nfc_framing_target_mode_detector:
framing_registers_values = framing_registers_mode_detector;
break;
case nfc_framing_target_a_106:
framing_registers_values = framing_registers_target_iso14443a_106k;
break;
case nfc_framing_initiator_a_106:
framing_registers_values = framing_registers_initiator_iso14443a_106k;
break;
case nfc_framing_initiator_b_106:
framing_registers_values = framing_registers_initiator_iso14443b_106k;
break;
case nfc_framing_target_f_212:
case nfc_framing_initiator_f_212:
framing_registers_values = framing_registers_felica_212k;
break;
case nfc_framing_target_f_424:
case nfc_framing_initiator_f_424:
framing_registers_values = framing_registers_felica_414k;
break;
default:
return NFC_ERR_UNSUPPORTED;
}
pn512_register_write(pPN512, framing_registers[2], (framing_registers_values[2] & 0x7F) | (pPN512->crc.in?0x80:0x00) | 0x04); //RXMODE
pn512_register_write(pPN512, framing_registers[2], (framing_registers_values[2] & 0x7F) | (pPN512->crc.in ? 0x80 : 0x00) | 0x04); //RXMODE
return NFC_OK;
return NFC_OK;
}
void pn512_rf_field_switch_off(pn512_t* pPN512)
void pn512_rf_field_switch_off(pn512_t *pPN512)
{
pn512_register_write(pPN512, PN512_REG_TXAUTO, 0x00);
pn512_register_write(pPN512, PN512_REG_TXCONTROL, 0x80);
pPN512->rf_on = false;
}
void pn512_rf_field_nfcip1_rf_collision_avoidance_complete(uint32_t events, void* pUserData)
{
pn512_t* pPN512 = (pn512_t*) pUserData;
uint16_t irq_res = pn512_irq_get(pPN512);
(void) events;
pn512_timer_stop(pPN512);
pn512_timer_config(pPN512, false, 0, 0xffff); //Deactivate autostart
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_RF_ON | PN512_IRQ_TIMER);
if(irq_res & PN512_IRQ_RF_ON)
{
NFC_DBG("External field on");
//Clear TXAUTO register
pn512_register_write(pPN512, PN512_REG_TXAUTO, 0x00);
pPN512->rf_on = false; //External field on
pn512_rf_callback(pPN512, NFC_OK);
return;
}
//Has our RF field been switched on?
if( pn512_register_read(pPN512, PN512_REG_TXAUTO) & 0x40 ) //InitialRFOn bit is cleared automatically, if the RF field is switched on
{
NFC_ERR("InitialRFOn bit still set");
pn512_rf_callback(pPN512, NFC_ERR_UNKNOWN);
return;
}
pPN512->rf_on = true; //Own field on and guard time ok
NFC_DBG("RF field enabled");
pn512_rf_callback(pPN512, NFC_OK);
pn512_register_write(pPN512, PN512_REG_TXCONTROL, 0x80);
pPN512->rf_on = false;
}
void pn512_rf_field_nfcip1_rf_collision_avoidance(pn512_t* pPN512, pn512_cb_t cb)
void pn512_rf_field_nfcip1_rf_collision_avoidance_complete(uint32_t events, void *pUserData)
{
pPN512->rf.cb = cb;
pn512_irq_clear(pPN512, PN512_IRQ_RF_ON | PN512_IRQ_TIMER);
pn512_t *pPN512 = (pn512_t *) pUserData;
//If our field is switched on, Wait TIRFG according to NFC-IP1 = 5ms => 67800 clock edges = (3+1)*8475
pn512_timer_config(pPN512, true, 3, 8475);
uint16_t irq_res = pn512_irq_get(pPN512);
pn512_irq_set(pPN512, PN512_IRQ_RF_ON /* External field switched on */
| PN512_IRQ_TIMER /* Timer reached 0 */ );
(void) events;
//Try to enable RF field in compliance with NFC-IP1
pn512_register_write(pPN512, PN512_REG_TXAUTO, 0x0F);
//Is external RF Field already on?
if( pn512_register_read(pPN512, PN512_REG_STATUS1) & 0x4 )
{
NFC_DBG("External field already on");
pPN512->rf_on = false; //External field on
//Cancel
pn512_timer_stop(pPN512);
pn512_timer_config(pPN512, false, 0, 0xffff); //Deactivate autostart
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_RF_ON | PN512_IRQ_TIMER);
if (irq_res & PN512_IRQ_RF_ON) {
NFC_DBG("External field on");
//Clear TXAUTO register
pn512_register_write(pPN512, PN512_REG_TXAUTO, 0x00);
pPN512->rf_on = false; //External field on
pn512_rf_callback(pPN512, NFC_OK);
return;
}
//Has our RF field been switched on?
if (pn512_register_read(pPN512, PN512_REG_TXAUTO) & 0x40) { //InitialRFOn bit is cleared automatically, if the RF field is switched on
NFC_ERR("InitialRFOn bit still set");
pn512_rf_callback(pPN512, NFC_ERR_UNKNOWN);
return;
}
pPN512->rf_on = true; //Own field on and guard time ok
NFC_DBG("RF field enabled");
pn512_rf_callback(pPN512, NFC_OK);
return;
}
//Queue task to process IRQ
task_init(&pPN512->transceiver.task, EVENT_HW_INTERRUPT | EVENT_TIMEOUT, -1, pn512_rf_field_nfcip1_rf_collision_avoidance_complete, pPN512);
scheduler_queue_task(&pPN512->transceiver.scheduler, &pPN512->transceiver.task);
}
void pn512_rf_field_wait_for_external_complete_task(uint32_t events, void* pUserData)
void pn512_rf_field_nfcip1_rf_collision_avoidance(pn512_t *pPN512, pn512_cb_t cb)
{
pn512_t* pPN512 = (pn512_t*) pUserData;
pPN512->rf.cb = cb;
pn512_irq_clear(pPN512, PN512_IRQ_RF_ON | PN512_IRQ_TIMER);
NFC_DBG("%lu events", events);
//If our field is switched on, Wait TIRFG according to NFC-IP1 = 5ms => 67800 clock edges = (3+1)*8475
pn512_timer_config(pPN512, true, 3, 8475);
//Wake up PN512
pn512_register_write(pPN512, PN512_REG_COMMAND, 0x00);
while( pn512_register_read(pPN512, PN512_REG_COMMAND) & 0x10 );
pn512_irq_set(pPN512, PN512_IRQ_RF_ON /* External field switched on */
| PN512_IRQ_TIMER /* Timer reached 0 */);
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_RF_ON);
//Try to enable RF field in compliance with NFC-IP1
pn512_register_write(pPN512, PN512_REG_TXAUTO, 0x0F);
if(events & EVENT_ABORTED)
{
pn512_rf_callback(pPN512, NFC_ERR_ABORTED);
return;
}
//Is external RF Field already on?
if (pn512_register_read(pPN512, PN512_REG_STATUS1) & 0x4) {
NFC_DBG("External field already on");
pPN512->rf_on = false; //External field on
if( events & EVENT_TIMEOUT )
{
NFC_DBG("Timeout");
pn512_rf_callback(pPN512, NFC_ERR_TIMEOUT);
return;
}
//Cancel
pn512_timer_stop(pPN512);
pn512_timer_config(pPN512, false, 0, 0xffff); //Deactivate autostart
pn512_irq_clear(pPN512, PN512_IRQ_RF_ON | PN512_IRQ_TIMER);
pn512_rf_callback(pPN512, NFC_OK);
return;
}
NFC_DBG("On");
pn512_rf_callback(pPN512, NFC_OK);
//Queue task to process IRQ
task_init(&pPN512->transceiver.task, EVENT_HW_INTERRUPT | EVENT_TIMEOUT, -1, pn512_rf_field_nfcip1_rf_collision_avoidance_complete, pPN512);
scheduler_queue_task(&pPN512->transceiver.scheduler, &pPN512->transceiver.task);
}
void pn512_rf_field_wait_for_external(pn512_t* pPN512, int timeout, pn512_cb_t cb)
void pn512_rf_field_wait_for_external_complete_task(uint32_t events, void *pUserData)
{
pPN512->rf.cb = cb;
pn512_t *pPN512 = (pn512_t *) pUserData;
pn512_irq_clear(pPN512, PN512_IRQ_RF_ON);
NFC_DBG("%lu events", events);
NFC_DBG("Wait for RF field to come up (timeout %d)", timeout);
//Wake up PN512
pn512_register_write(pPN512, PN512_REG_COMMAND, 0x00);
while (pn512_register_read(pPN512, PN512_REG_COMMAND) & 0x10);
//Is external RF Field already on?
pn512_irq_set(pPN512, PN512_IRQ_RF_ON /* External field switched on */);
if( pn512_register_read(pPN512, PN512_REG_STATUS1) & 0x4 )
{
NFC_DBG("RF field already on");
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_RF_ON);
if (events & EVENT_ABORTED) {
pn512_rf_callback(pPN512, NFC_ERR_ABORTED);
return;
}
if (events & EVENT_TIMEOUT) {
NFC_DBG("Timeout");
pn512_rf_callback(pPN512, NFC_ERR_TIMEOUT);
return;
}
NFC_DBG("On");
pn512_rf_callback(pPN512, NFC_OK);
return;
}
}
//Send PN512 to sleep mode
pn512_register_write(pPN512, PN512_REG_COMMAND, 0x30); //Receiver off + soft power down
void pn512_rf_field_wait_for_external(pn512_t *pPN512, int timeout, pn512_cb_t cb)
{
pPN512->rf.cb = cb;
//Queue task to process IRQ
task_init(&pPN512->transceiver.task, EVENT_HW_INTERRUPT | EVENT_TIMEOUT, timeout, pn512_rf_field_wait_for_external_complete_task, pPN512);
scheduler_queue_task(&pPN512->transceiver.scheduler, &pPN512->transceiver.task);
pn512_irq_clear(pPN512, PN512_IRQ_RF_ON);
NFC_DBG("Wait for RF field to come up (timeout %d)", timeout);
//Is external RF Field already on?
pn512_irq_set(pPN512, PN512_IRQ_RF_ON /* External field switched on */);
if (pn512_register_read(pPN512, PN512_REG_STATUS1) & 0x4) {
NFC_DBG("RF field already on");
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_RF_ON);
pn512_rf_callback(pPN512, NFC_OK);
return;
}
//Send PN512 to sleep mode
pn512_register_write(pPN512, PN512_REG_COMMAND, 0x30); //Receiver off + soft power down
//Queue task to process IRQ
task_init(&pPN512->transceiver.task, EVENT_HW_INTERRUPT | EVENT_TIMEOUT, timeout, pn512_rf_field_wait_for_external_complete_task, pPN512);
scheduler_queue_task(&pPN512->transceiver.scheduler, &pPN512->transceiver.task);
}

View File

@ -34,19 +34,19 @@ extern "C" {
typedef struct __pn512 pn512_t;
nfc_err_t pn512_framing_set(pn512_t* pPN512, nfc_framing_t framing);
nfc_err_t pn512_framing_set(pn512_t *pPN512, nfc_framing_t framing);
nfc_err_t pn512_framing_crc_set(pn512_t* pPN512, bool out, bool in);
nfc_err_t pn512_framing_crc_set(pn512_t *pPN512, bool out, bool in);
nfc_err_t pn512_framing_rx_multiple_enable(pn512_t* pPN512);
nfc_err_t pn512_framing_rx_multiple_enable(pn512_t *pPN512);
#define PN512_FRAMING_IS_TARGET( framing ) ((framing) <= nfc_framing_target_f_424)
void pn512_rf_field_switch_off(pn512_t* pPN512);
void pn512_rf_field_switch_off(pn512_t *pPN512);
void pn512_rf_field_nfcip1_rf_collision_avoidance(pn512_t* pPN512, pn512_cb_t cb);
void pn512_rf_field_nfcip1_rf_collision_avoidance(pn512_t *pPN512, pn512_cb_t cb);
void pn512_rf_field_wait_for_external(pn512_t* pPN512, int timeout, pn512_cb_t cb);
void pn512_rf_field_wait_for_external(pn512_t *pPN512, int timeout, pn512_cb_t cb);
#ifdef __cplusplus

View File

@ -25,53 +25,51 @@
#include "pn512_timer.h"
#include "pn512_registers.h"
void pn512_timer_config(pn512_t* pPN512, bool autostart, uint16_t prescaler, uint16_t countdown_value)
void pn512_timer_config(pn512_t *pPN512, bool autostart, uint16_t prescaler, uint16_t countdown_value)
{
pn512_timer_stop(pPN512); //just in case...
pn512_timer_stop(pPN512); //just in case...
pn512_register_write(pPN512, PN512_REG_TRELOADLOW, countdown_value & 0xFF);
pn512_register_write(pPN512, PN512_REG_TRELOADHIGH, (countdown_value >> 8) & 0xFF);
pn512_register_write(pPN512, PN512_REG_TRELOADLOW, countdown_value & 0xFF);
pn512_register_write(pPN512, PN512_REG_TRELOADHIGH, (countdown_value >> 8) & 0xFF);
pn512_register_write(pPN512, PN512_REG_TPRESCALERLOW, prescaler & 0xFF);
pn512_register_write(pPN512, PN512_REG_TMODE_TPRESCALERHIGH, (autostart?0x80:0x00) | ((prescaler>>8) & 0x0F) );
pn512_register_write(pPN512, PN512_REG_TPRESCALERLOW, prescaler & 0xFF);
pn512_register_write(pPN512, PN512_REG_TMODE_TPRESCALERHIGH, (autostart ? 0x80 : 0x00) | ((prescaler >> 8) & 0x0F));
}
void pn512_timer_start(pn512_t* pPN512)
void pn512_timer_start(pn512_t *pPN512)
{
//The control register also contains the initiator bit that we must set correctly
switch(pPN512->framing)
{
case nfc_framing_initiator_a_106:
case nfc_framing_initiator_f_212:
case nfc_framing_initiator_f_424:
pn512_register_write(pPN512, PN512_REG_CONTROL, 0x50);
break;
case nfc_framing_target_mode_detector:
case nfc_framing_target_a_106:
case nfc_framing_target_f_212:
case nfc_framing_target_f_424:
default:
pn512_register_write(pPN512, PN512_REG_CONTROL, 0x40);
break;
}
//The control register also contains the initiator bit that we must set correctly
switch (pPN512->framing) {
case nfc_framing_initiator_a_106:
case nfc_framing_initiator_f_212:
case nfc_framing_initiator_f_424:
pn512_register_write(pPN512, PN512_REG_CONTROL, 0x50);
break;
case nfc_framing_target_mode_detector:
case nfc_framing_target_a_106:
case nfc_framing_target_f_212:
case nfc_framing_target_f_424:
default:
pn512_register_write(pPN512, PN512_REG_CONTROL, 0x40);
break;
}
}
void pn512_timer_stop(pn512_t* pPN512)
void pn512_timer_stop(pn512_t *pPN512)
{
//The control register also contains the initiator bit that we must set correctly
switch(pPN512->framing)
{
case nfc_framing_initiator_a_106:
case nfc_framing_initiator_f_212:
case nfc_framing_initiator_f_424:
pn512_register_write(pPN512, PN512_REG_CONTROL, 0x90);
break;
case nfc_framing_target_mode_detector:
case nfc_framing_target_a_106:
case nfc_framing_target_f_212:
case nfc_framing_target_f_424:
default:
pn512_register_write(pPN512, PN512_REG_CONTROL, 0x80);
break;
}
//The control register also contains the initiator bit that we must set correctly
switch (pPN512->framing) {
case nfc_framing_initiator_a_106:
case nfc_framing_initiator_f_212:
case nfc_framing_initiator_f_424:
pn512_register_write(pPN512, PN512_REG_CONTROL, 0x90);
break;
case nfc_framing_target_mode_detector:
case nfc_framing_target_a_106:
case nfc_framing_target_f_212:
case nfc_framing_target_f_424:
default:
pn512_register_write(pPN512, PN512_REG_CONTROL, 0x80);
break;
}
}

View File

@ -31,10 +31,10 @@ extern "C" {
typedef struct __pn512 pn512_t;
void pn512_timer_config(pn512_t* pPN512, bool autostart, uint16_t prescaler, uint16_t countdown_value);
void pn512_timer_config(pn512_t *pPN512, bool autostart, uint16_t prescaler, uint16_t countdown_value);
void pn512_timer_start(pn512_t* pPN512);
void pn512_timer_stop(pn512_t* pPN512);
void pn512_timer_start(pn512_t *pPN512);
void pn512_timer_stop(pn512_t *pPN512);
#ifdef __cplusplus
}

View File

@ -38,283 +38,212 @@
#define TIMEOUT 1000
void pn512_transceive_hw_tx_iteration(pn512_t* pPN512, bool start)
void pn512_transceive_hw_tx_iteration(pn512_t *pPN512, bool start)
{
uint16_t irqs_en = pn512_irq_enabled(pPN512);
uint16_t irqs_en = pn512_irq_enabled(pPN512);
if( buffer_reader_readable(&pPN512->writeBuf) > 0 )
{
//Fill FIFO
pn512_fifo_write(pPN512, &pPN512->writeBuf);
if (buffer_reader_readable(&pPN512->writeBuf) > 0) {
//Fill FIFO
pn512_fifo_write(pPN512, &pPN512->writeBuf);
if (buffer_reader_readable(&pPN512->writeBuf) > 0) //Did not fit in FIFO
{
pn512_irq_clear(pPN512, PN512_IRQ_LOW_ALERT);
//Has low FIFO alert IRQ already been enabled?
if (!(irqs_en & PN512_IRQ_LOW_ALERT))
{
irqs_en |= PN512_IRQ_LOW_ALERT;
pn512_irq_set(pPN512, irqs_en);
}
}
else
{
if (irqs_en & PN512_IRQ_LOW_ALERT)
{
//Buffer has been fully sent
irqs_en &= ~PN512_IRQ_LOW_ALERT;
pn512_irq_set(pPN512, irqs_en);
}
}
}
if (start)
{
if ( (pPN512->transceive.mode == pn512_transceive_mode_transmit) || (pPN512->transceive.mode == pn512_transceive_mode_transmit_and_target_autocoll) )
{
//Update bitframing register
pn512_register_write(pPN512, PN512_REG_BITFRAMING,
0x00 | ((pPN512->readFirstByteAlign & 0x7) << 4) | (pPN512->writeLastByteLength & 0x7));
//Use transmit command
pn512_cmd_exec(pPN512, PN512_CMD_TRANSMIT);
}
else
{
NFC_DBG("Bitframing %02X", 0x80 | ((pPN512->readFirstByteAlign & 0x7) << 4) | (pPN512->writeLastByteLength & 0x7));
//Update bitframing register to start transmission
pn512_register_write(pPN512, PN512_REG_BITFRAMING,
0x80 | ((pPN512->readFirstByteAlign & 0x7) << 4) | (pPN512->writeLastByteLength & 0x7));
if (buffer_reader_readable(&pPN512->writeBuf) > 0) { //Did not fit in FIFO
pn512_irq_clear(pPN512, PN512_IRQ_LOW_ALERT);
//Has low FIFO alert IRQ already been enabled?
if (!(irqs_en & PN512_IRQ_LOW_ALERT)) {
irqs_en |= PN512_IRQ_LOW_ALERT;
pn512_irq_set(pPN512, irqs_en);
}
} else {
if (irqs_en & PN512_IRQ_LOW_ALERT) {
//Buffer has been fully sent
irqs_en &= ~PN512_IRQ_LOW_ALERT;
pn512_irq_set(pPN512, irqs_en);
}
}
}
//Reset last byte length, first byte align
pPN512->writeLastByteLength = 8;
pPN512->readFirstByteAlign = 0;
}
//Queue task to process IRQ
task_init(&pPN512->transceiver.task, EVENT_HW_INTERRUPT | EVENT_TIMEOUT, TIMEOUT, pn512_transceive_hw_tx_task, pPN512);
scheduler_queue_task(&pPN512->transceiver.scheduler, &pPN512->transceiver.task);
if (start) {
if ((pPN512->transceive.mode == pn512_transceive_mode_transmit) || (pPN512->transceive.mode == pn512_transceive_mode_transmit_and_target_autocoll)) {
//Update bitframing register
pn512_register_write(pPN512, PN512_REG_BITFRAMING,
0x00 | ((pPN512->readFirstByteAlign & 0x7) << 4) | (pPN512->writeLastByteLength & 0x7));
//Use transmit command
pn512_cmd_exec(pPN512, PN512_CMD_TRANSMIT);
} else {
NFC_DBG("Bitframing %02X", 0x80 | ((pPN512->readFirstByteAlign & 0x7) << 4) | (pPN512->writeLastByteLength & 0x7));
//Update bitframing register to start transmission
pn512_register_write(pPN512, PN512_REG_BITFRAMING,
0x80 | ((pPN512->readFirstByteAlign & 0x7) << 4) | (pPN512->writeLastByteLength & 0x7));
}
//Reset last byte length, first byte align
pPN512->writeLastByteLength = 8;
pPN512->readFirstByteAlign = 0;
}
//Queue task to process IRQ
task_init(&pPN512->transceiver.task, EVENT_HW_INTERRUPT | EVENT_TIMEOUT, TIMEOUT, pn512_transceive_hw_tx_task, pPN512);
scheduler_queue_task(&pPN512->transceiver.scheduler, &pPN512->transceiver.task);
}
void pn512_transceive_hw_tx_task(uint32_t events, void* pUserData)
void pn512_transceive_hw_tx_task(uint32_t events, void *pUserData)
{
pn512_t* pPN512 = (pn512_t*) pUserData;
pn512_t *pPN512 = (pn512_t *) pUserData;
if(events & EVENT_ABORTED)
{
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
if (events & EVENT_ABORTED) {
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
NFC_ERR("Aborted TX");
NFC_ERR("Aborted TX");
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
pn512_transceive_callback(pPN512, NFC_ERR_ABORTED);
return;
}
NFC_DBG("TX task");
if(events & EVENT_TIMEOUT)
{
// Check status
NFC_DBG("Status = %02X %02X", pn512_register_read(pPN512, PN512_REG_STATUS1), pn512_register_read(pPN512, PN512_REG_STATUS2));
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
NFC_ERR("Timeout on TX");
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
//Call callback
pn512_transceive_callback(pPN512, NFC_ERR_TIMEOUT);
return;
}
uint16_t irqs_en = pn512_irq_enabled(pPN512);
uint16_t irqs = pn512_irq_get(pPN512);
if( irqs & PN512_IRQ_RF_OFF )
{
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
NFC_WARN("RF Off");
pn512_transceive_callback(pPN512, NFC_ERR_FIELD);
return;
}
if( irqs & PN512_IRQ_TX )
{
if( irqs_en & PN512_IRQ_LOW_ALERT )
{
//If the transmission has been completed without us getting a chance to fill the buffer up it means that we had a buffer underflow
NFC_ERR("Buffer underflow");
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
pn512_transceive_callback(pPN512, NFC_ERR_UNDERFLOW);
return;
pn512_transceive_callback(pPN512, NFC_ERR_ABORTED);
return;
}
//Transmission complete
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_TX | PN512_IRQ_LOW_ALERT);
NFC_DBG("TX task");
if (events & EVENT_TIMEOUT) {
// Check status
NFC_DBG("Status = %02X %02X", pn512_register_read(pPN512, PN512_REG_STATUS1), pn512_register_read(pPN512, PN512_REG_STATUS2));
//Start receiving
NFC_DBG("Transmission complete");
if(pPN512->transceive.mode != pn512_transceive_mode_transmit)
{
if(pPN512->transceive.mode == pn512_transceive_mode_transmit_and_target_autocoll)
{
//Make sure bitframing reg is clean
pn512_register_write(pPN512, PN512_REG_BITFRAMING, 0x00);
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
NFC_ERR("Timeout on TX");
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
//Call callback
pn512_transceive_callback(pPN512, NFC_ERR_TIMEOUT);
return;
}
uint16_t irqs_en = pn512_irq_enabled(pPN512);
uint16_t irqs = pn512_irq_get(pPN512);
if (irqs & PN512_IRQ_RF_OFF) {
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
NFC_WARN("RF Off");
pn512_transceive_callback(pPN512, NFC_ERR_FIELD);
return;
}
if (irqs & PN512_IRQ_TX) {
if (irqs_en & PN512_IRQ_LOW_ALERT) {
//If the transmission has been completed without us getting a chance to fill the buffer up it means that we had a buffer underflow
NFC_ERR("Buffer underflow");
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
pn512_transceive_callback(pPN512, NFC_ERR_UNDERFLOW);
return;
}
//Transmission complete
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_TX | PN512_IRQ_LOW_ALERT);
//Start receiving
NFC_DBG("Transmission complete");
if (pPN512->transceive.mode != pn512_transceive_mode_transmit) {
if (pPN512->transceive.mode == pn512_transceive_mode_transmit_and_target_autocoll) {
//Make sure bitframing reg is clean
pn512_register_write(pPN512, PN512_REG_BITFRAMING, 0x00);
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pn512_transceive_hw_rx_start(pPN512);
//Start autocoll
pn512_cmd_exec(pPN512, PN512_CMD_AUTOCOLL);
} else {
pn512_transceive_hw_rx_start(pPN512);
}
return;
} else {
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_RX | PN512_IRQ_HIGH_ALERT);
pn512_transceive_callback(pPN512, NFC_OK);
return;
}
}
if ((irqs & PN512_IRQ_LOW_ALERT) && (buffer_reader_readable(&pPN512->writeBuf) > 0)) {
//Continue to fill FIFO
pn512_irq_clear(pPN512, PN512_IRQ_LOW_ALERT);
pn512_transceive_hw_tx_iteration(pPN512, false);
return;
}
if (irqs & PN512_IRQ_IDLE) {
pn512_irq_clear(pPN512, PN512_IRQ_ERR);
NFC_ERR("Modem went to idle");
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pn512_transceive_hw_rx_start(pPN512);
pPN512->transceive.mode = pn512_transceive_mode_idle;
//Start autocoll
pn512_cmd_exec(pPN512, PN512_CMD_AUTOCOLL);
}
else
{
pn512_transceive_hw_rx_start(pPN512);
}
return;
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
pn512_transceive_callback(pPN512, NFC_ERR_WRONG_COMM);
return;
}
else
{
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_RX | PN512_IRQ_HIGH_ALERT);
pn512_transceive_callback(pPN512, NFC_OK);
return;
}
}
if( (irqs & PN512_IRQ_LOW_ALERT) && (buffer_reader_readable(&pPN512->writeBuf) > 0) )
{
//Continue to fill FIFO
pn512_irq_clear(pPN512, PN512_IRQ_LOW_ALERT);
//Call back function
pn512_transceive_hw_tx_iteration(pPN512, false);
return;
}
if( irqs & PN512_IRQ_IDLE )
{
pn512_irq_clear(pPN512, PN512_IRQ_ERR);
NFC_ERR("Modem went to idle");
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
pn512_transceive_callback(pPN512, NFC_ERR_WRONG_COMM);
return;
}
//Call back function
pn512_transceive_hw_tx_iteration(pPN512, false);
}
void pn512_transceive_hw_rx_start(pn512_t* pPN512)
void pn512_transceive_hw_rx_start(pn512_t *pPN512)
{
uint16_t irqs_en = PN512_IRQ_RX | PN512_IRQ_HIGH_ALERT | PN512_IRQ_ERR;
if(PN512_FRAMING_IS_TARGET(pPN512->framing))
{
irqs_en |= PN512_IRQ_RF_OFF;
}
uint16_t irqs_en = PN512_IRQ_RX | PN512_IRQ_HIGH_ALERT | PN512_IRQ_ERR;
if (PN512_FRAMING_IS_TARGET(pPN512->framing)) {
irqs_en |= PN512_IRQ_RF_OFF;
}
pn512_irq_set(pPN512, irqs_en);
pn512_irq_set(pPN512, irqs_en);
//Reset buffer except if data should be appended to this -- TODO
buffer_builder_reset(&pPN512->readBufBldr);
//Reset buffer except if data should be appended to this -- TODO
buffer_builder_reset(&pPN512->readBufBldr);
//Queue task to process IRQ
task_init(&pPN512->transceiver.task, EVENT_HW_INTERRUPT | EVENT_TIMEOUT,
pPN512->timeout, pn512_transceive_hw_rx_task, pPN512);
scheduler_queue_task(&pPN512->transceiver.scheduler,
&pPN512->transceiver.task);
//Queue task to process IRQ
task_init(&pPN512->transceiver.task, EVENT_HW_INTERRUPT | EVENT_TIMEOUT,
pPN512->timeout, pn512_transceive_hw_rx_task, pPN512);
scheduler_queue_task(&pPN512->transceiver.scheduler,
&pPN512->transceiver.task);
}
void pn512_transceive_hw_rx_task(uint32_t events, void* pUserData)
void pn512_transceive_hw_rx_task(uint32_t events, void *pUserData)
{
pn512_t* pPN512 = (pn512_t*) pUserData;
pn512_t *pPN512 = (pn512_t *) pUserData;
NFC_DBG("RX task");
if(events & EVENT_ABORTED)
{
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
NFC_DBG("RX task");
if (events & EVENT_ABORTED) {
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
NFC_ERR("Aborted RX");
NFC_ERR("Aborted RX");
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
pn512_transceive_callback(pPN512, NFC_ERR_ABORTED);
return;
}
if(events & EVENT_TIMEOUT)
{
NFC_WARN("Timeout");
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
//Call callback
pn512_transceive_callback(pPN512, NFC_ERR_TIMEOUT);
return;
}
uint16_t irqs = pn512_irq_get(pPN512);
NFC_DBG("irqs %04x", irqs);
bool collision_detected = false;
if( irqs & PN512_IRQ_ERR )
{
pn512_irq_clear(pPN512, PN512_IRQ_ERR);
uint8_t err_reg = pn512_register_read(pPN512, PN512_REG_ERROR);
NFC_ERR("Got error - error reg is %02X", err_reg);
// if err_reg == 0, sticky error that must have been cleared automatically, continue
if( err_reg != 0 )
{
//If it's a collsision, flag it but still carry on with RX procedure
collision_detected = true;
if( (err_reg == 0x08) || (err_reg == 0x0A) ) // Collision (and maybe parity) (and no other error)
{
irqs &= ~PN512_IRQ_ERR;
irqs |= PN512_IRQ_RX;
}
else
{
DBG_BLOCK(
//Empty FIFO into buffer
pn512_fifo_read(pPN512, &pPN512->readBufBldr);
NFC_DBG("Received");
buffer_dump( buffer_builder_buffer(&pPN512->readBufBldr) );
NFC_DBG("Computed CRC = %02X %02X", pn512_register_read(pPN512, PN512_REG_CRCRESULT_MSB), pn512_register_read(pPN512, PN512_REG_CRCRESULT_LSB));
)
pn512_transceive_callback(pPN512, NFC_ERR_ABORTED);
return;
}
if (events & EVENT_TIMEOUT) {
NFC_WARN("Timeout");
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
@ -323,172 +252,189 @@ void pn512_transceive_hw_rx_task(uint32_t events, void* pUserData)
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
//Call callback
pn512_transceive_callback(pPN512, NFC_ERR_WRONG_COMM);
pn512_transceive_callback(pPN512, NFC_ERR_TIMEOUT);
return;
}
}
}
if( (irqs & PN512_IRQ_RX) || (irqs & PN512_IRQ_HIGH_ALERT) )
{
//Empty FIFO into buffer
pn512_fifo_read(pPN512, &pPN512->readBufBldr);
if( (buffer_builder_writeable(&pPN512->readBufBldr) == 0) && (pn512_fifo_length(pPN512) > 0) )
{
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
NFC_WARN("RX buffer overflow");
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
//Call callback
pn512_transceive_callback(pPN512, NFC_ERR_BUFFER_TOO_SMALL);
return; //overflow
}
if( irqs & PN512_IRQ_HIGH_ALERT )
{
NFC_DBG("High alert");
pn512_irq_clear(pPN512, PN512_IRQ_HIGH_ALERT);
}
uint16_t irqs = pn512_irq_get(pPN512);
NFC_DBG("irqs %04x", irqs);
bool collision_detected = false;
if (irqs & PN512_IRQ_ERR) {
pn512_irq_clear(pPN512, PN512_IRQ_ERR);
if( irqs & PN512_IRQ_RX )
{
pn512_irq_clear(pPN512, PN512_IRQ_RX);
uint8_t err_reg = pn512_register_read(pPN512, PN512_REG_ERROR);
NFC_ERR("Got error - error reg is %02X", err_reg);
// if err_reg == 0, sticky error that must have been cleared automatically, continue
if (err_reg != 0) {
//If it's a collsision, flag it but still carry on with RX procedure
collision_detected = true;
size_t last_byte_length = pn512_register_read(pPN512, PN512_REG_CONTROL) & 0x7;
if( last_byte_length == 0 )
{
last_byte_length = 8;
}
pPN512->readLastByteLength = last_byte_length;
if ((err_reg == 0x08) || (err_reg == 0x0A)) { // Collision (and maybe parity) (and no other error)
irqs &= ~PN512_IRQ_ERR;
irqs |= PN512_IRQ_RX;
} else {
DBG_BLOCK(
//Empty FIFO into buffer
pn512_fifo_read(pPN512, &pPN512->readBufBldr);
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_RX | PN512_IRQ_HIGH_ALERT);
NFC_DBG("Received");
buffer_dump(buffer_builder_buffer(&pPN512->readBufBldr));
NFC_DBG("Received:");
DBG_BLOCK( buffer_dump( buffer_builder_buffer(&pPN512->readBufBldr) ); )
NFC_DBG("Computed CRC = %02X %02X", pn512_register_read(pPN512, PN512_REG_CRCRESULT_MSB), pn512_register_read(pPN512, PN512_REG_CRCRESULT_LSB));
if( (pPN512->transceive.mode == pn512_transceive_mode_target_autocoll) || (pPN512->transceive.mode == pn512_transceive_mode_transmit_and_target_autocoll) )
{
//Check if target was activated
if( !(pn512_register_read(pPN512, PN512_REG_STATUS2) & 0x10) )
{
pPN512->transceive.mode = pn512_transceive_mode_idle;
)
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
//Call callback
pn512_transceive_callback(pPN512, NFC_ERR_PROTOCOL);
return;
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
//Call callback
pn512_transceive_callback(pPN512, NFC_ERR_WRONG_COMM);
return;
}
}
//PN512 switches to transceive automatically
pPN512->transceive.mode = pn512_transceive_mode_transceive;
}
else if( pPN512->transceive.mode == pn512_transceive_mode_receive )
{
pPN512->transceive.mode = pn512_transceive_mode_transceive;
//pn512_cmd_exec(pPN512, PN512_CMD_IDLE); //Useful?
}
if(!collision_detected)
{
pn512_transceive_callback(pPN512, NFC_OK);
}
else
{
pn512_transceive_callback(pPN512, NFC_ERR_COLLISION);
}
return;
}
}
if( irqs & PN512_IRQ_RF_OFF )
{
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
if ((irqs & PN512_IRQ_RX) || (irqs & PN512_IRQ_HIGH_ALERT)) {
//Empty FIFO into buffer
pn512_fifo_read(pPN512, &pPN512->readBufBldr);
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
if ((buffer_builder_writeable(&pPN512->readBufBldr) == 0) && (pn512_fifo_length(pPN512) > 0)) {
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
//Call callback
pn512_transceive_callback(pPN512, NFC_ERR_FIELD);
return;
}
NFC_WARN("RX buffer overflow");
//Queue task to process IRQ
task_init(&pPN512->transceiver.task, EVENT_HW_INTERRUPT | EVENT_TIMEOUT,
pPN512->timeout, pn512_transceive_hw_rx_task, pPN512);
scheduler_queue_task(&pPN512->transceiver.scheduler,
&pPN512->transceiver.task);
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
//Call callback
pn512_transceive_callback(pPN512, NFC_ERR_BUFFER_TOO_SMALL);
return; //overflow
}
if (irqs & PN512_IRQ_HIGH_ALERT) {
NFC_DBG("High alert");
pn512_irq_clear(pPN512, PN512_IRQ_HIGH_ALERT);
}
if (irqs & PN512_IRQ_RX) {
pn512_irq_clear(pPN512, PN512_IRQ_RX);
size_t last_byte_length = pn512_register_read(pPN512, PN512_REG_CONTROL) & 0x7;
if (last_byte_length == 0) {
last_byte_length = 8;
}
pPN512->readLastByteLength = last_byte_length;
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_RX | PN512_IRQ_HIGH_ALERT);
NFC_DBG("Received:");
DBG_BLOCK(buffer_dump(buffer_builder_buffer(&pPN512->readBufBldr));)
if ((pPN512->transceive.mode == pn512_transceive_mode_target_autocoll) || (pPN512->transceive.mode == pn512_transceive_mode_transmit_and_target_autocoll)) {
//Check if target was activated
if (!(pn512_register_read(pPN512, PN512_REG_STATUS2) & 0x10)) {
pPN512->transceive.mode = pn512_transceive_mode_idle;
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
//Call callback
pn512_transceive_callback(pPN512, NFC_ERR_PROTOCOL);
return;
}
//PN512 switches to transceive automatically
pPN512->transceive.mode = pn512_transceive_mode_transceive;
} else if (pPN512->transceive.mode == pn512_transceive_mode_receive) {
pPN512->transceive.mode = pn512_transceive_mode_transceive;
//pn512_cmd_exec(pPN512, PN512_CMD_IDLE); //Useful?
}
if (!collision_detected) {
pn512_transceive_callback(pPN512, NFC_OK);
} else {
pn512_transceive_callback(pPN512, NFC_ERR_COLLISION);
}
return;
}
}
if (irqs & PN512_IRQ_RF_OFF) {
//Stop command
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pPN512->transceive.mode = pn512_transceive_mode_idle;
pn512_irq_set(pPN512, PN512_IRQ_NONE);
pn512_irq_clear(pPN512, PN512_IRQ_ALL);
//Call callback
pn512_transceive_callback(pPN512, NFC_ERR_FIELD);
return;
}
//Queue task to process IRQ
task_init(&pPN512->transceiver.task, EVENT_HW_INTERRUPT | EVENT_TIMEOUT,
pPN512->timeout, pn512_transceive_hw_rx_task, pPN512);
scheduler_queue_task(&pPN512->transceiver.scheduler,
&pPN512->transceiver.task);
}
void pn512_transceive_hw(pn512_t* pPN512, pn512_transceive_mode_t mode, pn512_cb_t cb)
void pn512_transceive_hw(pn512_t *pPN512, pn512_transceive_mode_t mode, pn512_cb_t cb)
{
uint16_t irqs_en;
uint16_t irqs_en;
//Store callback
pPN512->transceive.cb = cb;
//Store callback
pPN512->transceive.cb = cb;
//Clear FIFO
pn512_fifo_clear(pPN512);
//Clear FIFO
pn512_fifo_clear(pPN512);
//Clear previous IRQs if present
pn512_irq_clear(pPN512, PN512_IRQ_RX | PN512_IRQ_TX | PN512_IRQ_HIGH_ALERT | PN512_IRQ_LOW_ALERT | PN512_IRQ_ERR | PN512_IRQ_IDLE | PN512_IRQ_RF_OFF );
//Clear previous IRQs if present
pn512_irq_clear(pPN512, PN512_IRQ_RX | PN512_IRQ_TX | PN512_IRQ_HIGH_ALERT | PN512_IRQ_LOW_ALERT | PN512_IRQ_ERR | PN512_IRQ_IDLE | PN512_IRQ_RF_OFF);
if( PN512_FRAMING_IS_TARGET(pPN512->framing) )
{
//RF off?
if(!(pn512_register_read(pPN512, PN512_REG_STATUS1) & 0x04))
{
//Call callback
pn512_transceive_callback(pPN512, NFC_ERR_FIELD);
return;
}
}
else if((pPN512->transceive.mode != mode) && (mode == pn512_transceive_mode_transceive))
{
pn512_cmd_exec(pPN512, PN512_CMD_TRANSCEIVE);
}
pPN512->transceive.mode = mode;
if( mode == pn512_transceive_mode_receive )
{
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pn512_transceive_hw_rx_start(pPN512);
pn512_cmd_exec(pPN512, PN512_CMD_TRANSCEIVE);
}
else if(mode == pn512_transceive_mode_target_autocoll)
{
//Make sure bitframing reg is clean
pn512_register_write(pPN512, PN512_REG_BITFRAMING, 0x00);
pn512_transceive_hw_rx_start(pPN512);
//Start autocoll
pn512_cmd_exec(pPN512, PN512_CMD_AUTOCOLL);
return;
}
else
{
NFC_DBG("Sending:");
DBG_BLOCK( buffer_dump(&pPN512->writeBuf); )
//Transmit a frame to remote target/initiator
irqs_en = PN512_IRQ_TX | PN512_IRQ_IDLE;
if( PN512_FRAMING_IS_TARGET(pPN512->framing) )
{
irqs_en |= PN512_IRQ_RF_OFF;
if (PN512_FRAMING_IS_TARGET(pPN512->framing)) {
//RF off?
if (!(pn512_register_read(pPN512, PN512_REG_STATUS1) & 0x04)) {
//Call callback
pn512_transceive_callback(pPN512, NFC_ERR_FIELD);
return;
}
} else if ((pPN512->transceive.mode != mode) && (mode == pn512_transceive_mode_transceive)) {
pn512_cmd_exec(pPN512, PN512_CMD_TRANSCEIVE);
}
pn512_irq_set(pPN512, irqs_en);
pPN512->transceive.mode = mode;
pn512_transceive_hw_tx_iteration(pPN512, true);
}
if (mode == pn512_transceive_mode_receive) {
pn512_cmd_exec(pPN512, PN512_CMD_IDLE);
pn512_transceive_hw_rx_start(pPN512);
pn512_cmd_exec(pPN512, PN512_CMD_TRANSCEIVE);
} else if (mode == pn512_transceive_mode_target_autocoll) {
//Make sure bitframing reg is clean
pn512_register_write(pPN512, PN512_REG_BITFRAMING, 0x00);
pn512_transceive_hw_rx_start(pPN512);
//Start autocoll
pn512_cmd_exec(pPN512, PN512_CMD_AUTOCOLL);
return;
} else {
NFC_DBG("Sending:");
DBG_BLOCK(buffer_dump(&pPN512->writeBuf);)
//Transmit a frame to remote target/initiator
irqs_en = PN512_IRQ_TX | PN512_IRQ_IDLE;
if (PN512_FRAMING_IS_TARGET(pPN512->framing)) {
irqs_en |= PN512_IRQ_RF_OFF;
}
pn512_irq_set(pPN512, irqs_en);
pn512_transceive_hw_tx_iteration(pPN512, true);
}
}

View File

@ -29,13 +29,13 @@ extern "C" {
#include "pn512.h"
void pn512_transceive_hw(pn512_t* pPN512, pn512_transceive_mode_t mode, pn512_cb_t cb);
void pn512_transceive_hw(pn512_t *pPN512, pn512_transceive_mode_t mode, pn512_cb_t cb);
void pn512_transceive_hw_tx_task(uint32_t events, void* pUserData);
void pn512_transceive_hw_tx_iteration(pn512_t* pPN512, bool start);
void pn512_transceive_hw_tx_task(uint32_t events, void *pUserData);
void pn512_transceive_hw_tx_iteration(pn512_t *pPN512, bool start);
void pn512_transceive_hw_rx_start(pn512_t* pPN512);
void pn512_transceive_hw_rx_task(uint32_t events, void* pUserData);
void pn512_transceive_hw_rx_start(pn512_t *pPN512);
void pn512_transceive_hw_rx_task(uint32_t events, void *pUserData);
#ifdef __cplusplus

View File

@ -27,9 +27,8 @@
extern "C" {
#endif
typedef struct __pn512_registers
{
int8_t registers_page;
typedef struct __pn512_registers {
int8_t registers_page;
} pn512_registers_t;
#ifdef __cplusplus

View File

@ -34,24 +34,23 @@
extern "C" {
#endif
typedef enum __RF_PROTOCOL
{
__RF_PROTOCOL_UNKNOWN = 0,
//Reader
RF_PROTOCOL_ISO_14443_A_READER,
RF_PROTOCOL_ISO_14443_B_READER,
RF_PROTOCOL_INNOVATRON_READER,
RF_PROTOCOL_ISO_15693_READER,
RF_PROTOCOL_FELICA_READER,
//... add other protocols here
RF_PROTOCOL_ISO_14443_A_TARGET,
RF_PROTOCOL_ISO_14443_B_TARGET,
RF_PROTOCOL_INNOVATRON_TARGET,
RF_PROTOCOL_ISO_15693_TARGET,
RF_PROTOCOL_FELICA_TARGET,
RF_PROTOCOL_ISO_DEP_TARGET, //ISO 14443-4 transport protocol
RF_PROTOCOL_NFC_DEP_TARGET, //NFC-IP 1 transport protocol
//... add other protocols here
typedef enum __RF_PROTOCOL {
__RF_PROTOCOL_UNKNOWN = 0,
//Reader
RF_PROTOCOL_ISO_14443_A_READER,
RF_PROTOCOL_ISO_14443_B_READER,
RF_PROTOCOL_INNOVATRON_READER,
RF_PROTOCOL_ISO_15693_READER,
RF_PROTOCOL_FELICA_READER,
//... add other protocols here
RF_PROTOCOL_ISO_14443_A_TARGET,
RF_PROTOCOL_ISO_14443_B_TARGET,
RF_PROTOCOL_INNOVATRON_TARGET,
RF_PROTOCOL_ISO_15693_TARGET,
RF_PROTOCOL_FELICA_TARGET,
RF_PROTOCOL_ISO_DEP_TARGET, //ISO 14443-4 transport protocol
RF_PROTOCOL_NFC_DEP_TARGET, //NFC-IP 1 transport protocol
//... add other protocols here
} RF_PROTOCOL;
@ -67,12 +66,11 @@ typedef uint32_t RF_OPTION;
#define RF_OPTION_CHECK_PARITY 0x08
#define RF_OPTION_CLOSE 0x10 //Last frame
typedef enum __RF_BITRATE
{
RF_BITRATE_106K=0x00,
RF_BITRATE_212K=0x01,
RF_BITRATE_424K=0x02,
RF_BITRATE_848K=0x03,
typedef enum __RF_BITRATE {
RF_BITRATE_106K = 0x00,
RF_BITRATE_212K = 0x01,
RF_BITRATE_424K = 0x02,
RF_BITRATE_848K = 0x03,
} RF_BITRATE;

View File

@ -34,10 +34,10 @@
* \param pTransport pointer to already initialized nfc_transport_t structure
* \param pImpl pointer to the structure implementing the transceiver interface (eg pn512_t or pn532_t)
*/
void transceiver_init(nfc_transceiver_t* pTransceiver, nfc_transport_t* pTransport, nfc_scheduler_timer_t* pTimer)
void transceiver_init(nfc_transceiver_t *pTransceiver, nfc_transport_t *pTransport, nfc_scheduler_timer_t *pTimer)
{
pTransceiver->pTransport = pTransport;
scheduler_init(&pTransceiver->scheduler, pTimer);
pTransceiver->pTransport = pTransport;
scheduler_init(&pTransceiver->scheduler, pTimer);
}

View File

@ -37,239 +37,230 @@ typedef struct __transceiver_impl transceiver_impl_t;
typedef enum __nfc_framing nfc_framing_t;
enum __nfc_framing {
nfc_framing_unknown,
nfc_framing_unknown,
nfc_framing_target_mode_detector, //Framing is unknown and will be detected by the hardware
nfc_framing_target_a_106,
nfc_framing_target_b_106,
nfc_framing_target_f_212,
nfc_framing_target_f_424,
nfc_framing_target_mode_detector, //Framing is unknown and will be detected by the hardware
nfc_framing_target_a_106,
nfc_framing_target_b_106,
nfc_framing_target_f_212,
nfc_framing_target_f_424,
nfc_framing_initiator_a_106,
nfc_framing_initiator_b_106,
nfc_framing_initiator_f_212,
nfc_framing_initiator_f_424,
nfc_framing_initiator_a_106,
nfc_framing_initiator_b_106,
nfc_framing_initiator_f_212,
nfc_framing_initiator_f_424,
};
typedef struct __nfc_tech
{
unsigned int nfc_type1 : 1;
unsigned int nfc_type2 : 1;
unsigned int nfc_type3 : 1;
unsigned int nfc_iso_dep_a : 1;
unsigned int nfc_iso_dep_b : 1;
unsigned int nfc_nfc_dep_a : 1;
unsigned int nfc_nfc_dep_f_212 : 1;
unsigned int nfc_nfc_dep_f_424 : 1;
typedef struct __nfc_tech {
unsigned int nfc_type1 : 1;
unsigned int nfc_type2 : 1;
unsigned int nfc_type3 : 1;
unsigned int nfc_iso_dep_a : 1;
unsigned int nfc_iso_dep_b : 1;
unsigned int nfc_nfc_dep_a : 1;
unsigned int nfc_nfc_dep_f_212 : 1;
unsigned int nfc_nfc_dep_f_424 : 1;
} nfc_tech_t;
typedef struct __polling_options polling_options_t;
struct __polling_options
{
unsigned int bail_at_first_target : 1;
unsigned int bail_at_first_tech : 1;
int32_t listen_for;
struct __polling_options {
unsigned int bail_at_first_target : 1;
unsigned int bail_at_first_tech : 1;
int32_t listen_for;
};
typedef void (*transceiver_cb_t)(nfc_transceiver_t* pTransceiver, nfc_err_t ret, void* pUserData);
typedef void (*set_protocols_fn_t)(nfc_transceiver_t* pTransceiver, nfc_tech_t initiators, nfc_tech_t targets, polling_options_t options);
typedef void (*poll_fn_t)(nfc_transceiver_t* pTransceiver);
typedef void (*set_crc_fn_t)(nfc_transceiver_t* pTransceiver, bool crcOut, bool crcIn);
typedef void (*set_timeout_fn_t)(nfc_transceiver_t* pTransceiver, int timeout);
typedef void (*set_transceive_options_fn_t)(nfc_transceiver_t* pTransceiver, bool transmit, bool receive, bool repoll);
typedef void (*set_transceive_framing_fn_t)(nfc_transceiver_t* pTransceiver, nfc_framing_t framing);
typedef void (*set_write_fn_t)(nfc_transceiver_t* pTransceiver, buffer_t* pWriteBuf); //Set write buffer
typedef buffer_t* (*get_read_fn_t)(nfc_transceiver_t* pTransceiver); //Get read buffer
typedef size_t (*get_last_byte_length_fn_t)(nfc_transceiver_t* pTransceiver);
typedef void (*set_last_byte_length_fn_t)(nfc_transceiver_t* pTransceiver, size_t lastByteLength);
typedef size_t (*get_first_byte_align_fn_t)(nfc_transceiver_t* pTransceiver);
typedef void (*set_first_byte_align_fn_t)(nfc_transceiver_t* pTransceiver, size_t firstByteAlign);
typedef void (*transceive_fn_t)(nfc_transceiver_t* pTransceiver);
typedef void (*abort_fn_t)(nfc_transceiver_t* pTransceiver);
typedef void (*close_fn_t)(nfc_transceiver_t* pTransceiver);
typedef void (*sleep_fn_t)(nfc_transceiver_t* pTransceiver, bool sleep);
typedef void (*transceiver_cb_t)(nfc_transceiver_t *pTransceiver, nfc_err_t ret, void *pUserData);
typedef void (*set_protocols_fn_t)(nfc_transceiver_t *pTransceiver, nfc_tech_t initiators, nfc_tech_t targets, polling_options_t options);
typedef void (*poll_fn_t)(nfc_transceiver_t *pTransceiver);
typedef void (*set_crc_fn_t)(nfc_transceiver_t *pTransceiver, bool crcOut, bool crcIn);
typedef void (*set_timeout_fn_t)(nfc_transceiver_t *pTransceiver, int timeout);
typedef void (*set_transceive_options_fn_t)(nfc_transceiver_t *pTransceiver, bool transmit, bool receive, bool repoll);
typedef void (*set_transceive_framing_fn_t)(nfc_transceiver_t *pTransceiver, nfc_framing_t framing);
typedef void (*set_write_fn_t)(nfc_transceiver_t *pTransceiver, buffer_t *pWriteBuf); //Set write buffer
typedef buffer_t *(*get_read_fn_t)(nfc_transceiver_t *pTransceiver); //Get read buffer
typedef size_t (*get_last_byte_length_fn_t)(nfc_transceiver_t *pTransceiver);
typedef void (*set_last_byte_length_fn_t)(nfc_transceiver_t *pTransceiver, size_t lastByteLength);
typedef size_t (*get_first_byte_align_fn_t)(nfc_transceiver_t *pTransceiver);
typedef void (*set_first_byte_align_fn_t)(nfc_transceiver_t *pTransceiver, size_t firstByteAlign);
typedef void (*transceive_fn_t)(nfc_transceiver_t *pTransceiver);
typedef void (*abort_fn_t)(nfc_transceiver_t *pTransceiver);
typedef void (*close_fn_t)(nfc_transceiver_t *pTransceiver);
typedef void (*sleep_fn_t)(nfc_transceiver_t *pTransceiver, bool sleep);
struct __transceiver_impl
{
set_protocols_fn_t set_protocols;
poll_fn_t poll;
set_crc_fn_t set_crc;
set_timeout_fn_t set_timeout;
set_transceive_options_fn_t set_transceive_options;
set_transceive_framing_fn_t set_transceive_framing;
set_write_fn_t set_write;
get_read_fn_t get_read;
set_last_byte_length_fn_t set_last_byte_length;
get_last_byte_length_fn_t get_last_byte_length;
set_first_byte_align_fn_t set_first_byte_align;
transceive_fn_t transceive;
abort_fn_t abort;
close_fn_t close;
sleep_fn_t sleep;
struct __transceiver_impl {
set_protocols_fn_t set_protocols;
poll_fn_t poll;
set_crc_fn_t set_crc;
set_timeout_fn_t set_timeout;
set_transceive_options_fn_t set_transceive_options;
set_transceive_framing_fn_t set_transceive_framing;
set_write_fn_t set_write;
get_read_fn_t get_read;
set_last_byte_length_fn_t set_last_byte_length;
get_last_byte_length_fn_t get_last_byte_length;
set_first_byte_align_fn_t set_first_byte_align;
transceive_fn_t transceive;
abort_fn_t abort;
close_fn_t close;
sleep_fn_t sleep;
};
typedef struct __nfc_a_info nfc_a_info_t;
struct __nfc_a_info
{
uint8_t uid[10];
size_t uidLength;
uint8_t sak;
uint8_t atqa[2];
struct __nfc_a_info {
uint8_t uid[10];
size_t uidLength;
uint8_t sak;
uint8_t atqa[2];
};
typedef struct __nfc_b_info nfc_b_info_t;
struct __nfc_b_info
{
uint8_t pupi[4];
uint8_t application_data[4];
uint8_t protocol_info[3];
struct __nfc_b_info {
uint8_t pupi[4];
uint8_t application_data[4];
uint8_t protocol_info[3];
};
typedef struct __nfc_f_info nfc_f_info_t;
struct __nfc_f_info
{
uint8_t nfcid2[8];
struct __nfc_f_info {
uint8_t nfcid2[8];
};
typedef struct __nfc_info nfc_info_t;
struct __nfc_info
{
nfc_tech_t type;
union {
nfc_a_info_t nfcA;
nfc_b_info_t nfcB;
nfc_f_info_t nfcF;
};
struct __nfc_info {
nfc_tech_t type;
union {
nfc_a_info_t nfcA;
nfc_b_info_t nfcB;
nfc_f_info_t nfcF;
};
};
#define MUNFC_MAX_REMOTE_TARGETS 4
struct __transceiver
{
const transceiver_impl_t* fn; //vtable
struct __transceiver {
const transceiver_impl_t *fn; //vtable
bool initiator_ntarget;
nfc_info_t remote_targets[MUNFC_MAX_REMOTE_TARGETS];
size_t remote_targets_count;
bool initiator_ntarget;
nfc_info_t remote_targets[MUNFC_MAX_REMOTE_TARGETS];
size_t remote_targets_count;
nfc_tech_t active_tech;
nfc_tech_t active_tech;
transceiver_cb_t cb; //Callback to upper layer
void* pUserData;
nfc_task_t task; //Task for deferred execution
transceiver_cb_t cb; //Callback to upper layer
void *pUserData;
nfc_task_t task; //Task for deferred execution
nfc_transport_t* pTransport;
nfc_scheduler_t scheduler;
nfc_transport_t *pTransport;
nfc_scheduler_t scheduler;
};
void transceiver_init(nfc_transceiver_t* pTransceiver, nfc_transport_t* pTransport, nfc_scheduler_timer_t* pTimer);
void transceiver_init(nfc_transceiver_t *pTransceiver, nfc_transport_t *pTransport, nfc_scheduler_timer_t *pTimer);
static inline void transceiver_set_protocols(nfc_transceiver_t* pTransceiver, nfc_tech_t initiators, nfc_tech_t targets, polling_options_t options)
static inline void transceiver_set_protocols(nfc_transceiver_t *pTransceiver, nfc_tech_t initiators, nfc_tech_t targets, polling_options_t options)
{
pTransceiver->fn->set_protocols(pTransceiver, initiators, targets, options);
pTransceiver->fn->set_protocols(pTransceiver, initiators, targets, options);
}
static inline void transceiver_poll(nfc_transceiver_t* pTransceiver, transceiver_cb_t cb, void* pUserData)
static inline void transceiver_poll(nfc_transceiver_t *pTransceiver, transceiver_cb_t cb, void *pUserData)
{
pTransceiver->cb = cb;
pTransceiver->pUserData = pUserData;
pTransceiver->fn->poll(pTransceiver);
pTransceiver->cb = cb;
pTransceiver->pUserData = pUserData;
pTransceiver->fn->poll(pTransceiver);
}
static inline void transceiver_set_crc(nfc_transceiver_t* pTransceiver, bool crcOut, bool crcIn)
static inline void transceiver_set_crc(nfc_transceiver_t *pTransceiver, bool crcOut, bool crcIn)
{
pTransceiver->fn->set_crc(pTransceiver, crcOut, crcIn);
pTransceiver->fn->set_crc(pTransceiver, crcOut, crcIn);
}
static inline void transceiver_set_timeout(nfc_transceiver_t* pTransceiver, int timeout)
static inline void transceiver_set_timeout(nfc_transceiver_t *pTransceiver, int timeout)
{
pTransceiver->fn->set_timeout(pTransceiver, timeout);
pTransceiver->fn->set_timeout(pTransceiver, timeout);
}
static inline void transceiver_set_transceive_options(nfc_transceiver_t* pTransceiver, bool transmit, bool receive, bool repoll)
static inline void transceiver_set_transceive_options(nfc_transceiver_t *pTransceiver, bool transmit, bool receive, bool repoll)
{
pTransceiver->fn->set_transceive_options(pTransceiver, transmit, receive, repoll);
pTransceiver->fn->set_transceive_options(pTransceiver, transmit, receive, repoll);
}
static inline void transceiver_set_transceive_framing(nfc_transceiver_t* pTransceiver, nfc_framing_t framing)
static inline void transceiver_set_transceive_framing(nfc_transceiver_t *pTransceiver, nfc_framing_t framing)
{
pTransceiver->fn->set_transceive_framing(pTransceiver, framing);
pTransceiver->fn->set_transceive_framing(pTransceiver, framing);
}
static inline void transceiver_set_write(nfc_transceiver_t* pTransceiver, buffer_t* pWriteBuf)
static inline void transceiver_set_write(nfc_transceiver_t *pTransceiver, buffer_t *pWriteBuf)
{
pTransceiver->fn->set_write(pTransceiver, pWriteBuf);
pTransceiver->fn->set_write(pTransceiver, pWriteBuf);
}
static inline buffer_t* transceiver_get_read(nfc_transceiver_t* pTransceiver)
static inline buffer_t *transceiver_get_read(nfc_transceiver_t *pTransceiver)
{
return pTransceiver->fn->get_read(pTransceiver);
return pTransceiver->fn->get_read(pTransceiver);
}
static inline size_t transceiver_get_last_byte_length(nfc_transceiver_t* pTransceiver)
static inline size_t transceiver_get_last_byte_length(nfc_transceiver_t *pTransceiver)
{
return pTransceiver->fn->get_last_byte_length(pTransceiver);
return pTransceiver->fn->get_last_byte_length(pTransceiver);
}
static inline void transceiver_set_last_byte_length(nfc_transceiver_t* pTransceiver, size_t lastByteLength)
static inline void transceiver_set_last_byte_length(nfc_transceiver_t *pTransceiver, size_t lastByteLength)
{
pTransceiver->fn->set_last_byte_length(pTransceiver, lastByteLength);
pTransceiver->fn->set_last_byte_length(pTransceiver, lastByteLength);
}
static inline void transceiver_set_first_byte_align(nfc_transceiver_t* pTransceiver, size_t firstByteAlign)
static inline void transceiver_set_first_byte_align(nfc_transceiver_t *pTransceiver, size_t firstByteAlign)
{
pTransceiver->fn->set_first_byte_align(pTransceiver, firstByteAlign);
pTransceiver->fn->set_first_byte_align(pTransceiver, firstByteAlign);
}
static inline void nfc_transceiver_transceive(nfc_transceiver_t* pTransceiver, transceiver_cb_t cb, void* pUserData)
static inline void nfc_transceiver_transceive(nfc_transceiver_t *pTransceiver, transceiver_cb_t cb, void *pUserData)
{
pTransceiver->cb = cb;
pTransceiver->pUserData = pUserData;
pTransceiver->fn->transceive(pTransceiver);
pTransceiver->cb = cb;
pTransceiver->pUserData = pUserData;
pTransceiver->fn->transceive(pTransceiver);
}
static inline void transceiver_abort(nfc_transceiver_t* pTransceiver)
static inline void transceiver_abort(nfc_transceiver_t *pTransceiver)
{
pTransceiver->fn->abort(pTransceiver);
pTransceiver->fn->abort(pTransceiver);
}
static inline void transceiver_close(nfc_transceiver_t* pTransceiver)
static inline void transceiver_close(nfc_transceiver_t *pTransceiver)
{
pTransceiver->fn->close(pTransceiver);
pTransceiver->fn->close(pTransceiver);
}
static inline bool transceiver_is_initiator_mode(nfc_transceiver_t* pTransceiver)
static inline bool transceiver_is_initiator_mode(nfc_transceiver_t *pTransceiver)
{
return pTransceiver->initiator_ntarget;
return pTransceiver->initiator_ntarget;
}
static inline nfc_tech_t transceiver_get_active_techs(nfc_transceiver_t* pTransceiver)
static inline nfc_tech_t transceiver_get_active_techs(nfc_transceiver_t *pTransceiver)
{
return pTransceiver->active_tech;
return pTransceiver->active_tech;
}
static inline nfc_scheduler_t* transceiver_get_scheduler(nfc_transceiver_t* pTransceiver)
static inline nfc_scheduler_t *transceiver_get_scheduler(nfc_transceiver_t *pTransceiver)
{
return &pTransceiver->scheduler;
return &pTransceiver->scheduler;
}
static inline const nfc_info_t* transceiver_get_remote_target_info(nfc_transceiver_t* pTransceiver, size_t number)
static inline const nfc_info_t *transceiver_get_remote_target_info(nfc_transceiver_t *pTransceiver, size_t number)
{
if( number > pTransceiver->remote_targets_count )
{
return NULL;
}
return &pTransceiver->remote_targets[number];
if (number > pTransceiver->remote_targets_count) {
return NULL;
}
return &pTransceiver->remote_targets[number];
}
static inline size_t transceiver_get_remote_targets_count(nfc_transceiver_t* pTransceiver)
static inline size_t transceiver_get_remote_targets_count(nfc_transceiver_t *pTransceiver)
{
return pTransceiver->remote_targets_count;
return pTransceiver->remote_targets_count;
}
static inline void transceiver_sleep(nfc_transceiver_t* pTransceiver, bool sleep)
static inline void transceiver_sleep(nfc_transceiver_t *pTransceiver, bool sleep)
{
pTransceiver->fn->sleep(pTransceiver, sleep);
pTransceiver->fn->sleep(pTransceiver, sleep);
}
#ifdef __cplusplus

View File

@ -29,9 +29,9 @@ extern "C" {
#include "transceiver.h"
static inline void transceiver_callback(nfc_transceiver_t* pTransceiver, nfc_err_t ret)
static inline void transceiver_callback(nfc_transceiver_t *pTransceiver, nfc_err_t ret)
{
pTransceiver->cb(pTransceiver, ret, pTransceiver->pUserData);
pTransceiver->cb(pTransceiver, ret, pTransceiver->pUserData);
}
#ifdef __cplusplus