mirror of https://github.com/ARMmbed/mbed-os.git
Astyle formatting
parent
ce39e77f3d
commit
0e2484f7f3
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue