Utility library to read and write Ndef messages from/to a Type4 NFC tag
Dependents: NFC M2M_2016_STM32 MyongjiElec_capstone1 IDW01M1_Cloud_IBM ... more
Fork of NDefLib by
NDEF NFC library
This library provides an abstract API to create NDEF formatted messages and records and to read/write them from/to a Type4 NFC Tag.
Implementations
At the moment, the NDEF API is implemented by X_NUCLEO_NFC01A1 and X_NUCLEO_NFC02A1 Dynamic NFC Tag libraries respectively driving the X-NUCLEO-NFC01A1 and X-NUCLEO-NFC02A1 boards.
Diff: NDefNfcTag.h
- Revision:
- 14:ba0c186ae6d6
- Parent:
- 12:ed4d9b8d1410
- Child:
- 15:01fc5a4b8366
--- a/NDefNfcTag.h Thu Jan 14 08:40:45 2016 +0000 +++ b/NDefNfcTag.h Thu Jan 28 14:01:07 2016 +0000 @@ -3,8 +3,9 @@ * @file Type4NfcTag.h * @author ST / Central Labs * @version V1.0.0 - * @date 1 Nov 2015 + * @date 21 Jan 2016 * @brief Generic interface that a device must implement for use the NDefLib + * with async communication ****************************************************************************** * @attention * @@ -34,42 +35,117 @@ * ****************************************************************************** */ - -#ifndef NDefNFCTAG_H_ -#define NDefNFCTAG_H_ + +#ifndef NDEFLIB_NDEFNFCTAG_H_ +#define NDEFLIB_NDEFNFCTAG_H_ #include "NDefLib/Message.h" namespace NDefLib { /** - * Abstract class used to write/read NDef messages to/from a nfc tag + * Abstract class used to write/read NDef messages to/from a nfc tag. + * This class is made for handle also asynchronous communication with the nfc component. + * All the function in this class will return immediately, when the operation end a proper callback function will + * be called. */ class NDefNfcTag { + public: - NDefNfcTag():mSessionIsOpen(false){} + /** + * Class that contains all the function called when a command finish. + * The default implementation is an empty function. + */ + class Callback { + public: + + /** + * Called when a session is open. + * @param tag tag where the session is open. + * @param success true if the operation has success. + */ + virtual void onSessionOpen(NDefNfcTag *tag,bool success){ + (void)tag;(void)success; + }; + + /** + * Called when a message is write. + * @param tag tag where the message is wrote. + * @param success true if the operation has success. + */ + virtual void onMessageWrite(NDefNfcTag *tag,bool success, + const Message &msg){ + (void)tag;(void)success; (void)msg; + + }; + + /** + * Called when a message is read. + * @param tag tag where the message is read. + * @param success true if the operation has success. + */ + virtual void onMessageRead(NDefNfcTag *tag,bool success, + const Message *msg){ + (void)tag;(void)success; (void)msg; + }; + + + /** + * Called when a session is close. + * @param tag tag where the session is close. + * @param success true if the operation has success. + */ + virtual void onSessionClose(NDefNfcTag *tag,bool success){ + (void)tag;(void)success; + }; + + virtual ~Callback(){}; + }; + +private: + + /** + * Data used for store the callback status. + */ + struct CallbackStatus{ + /**object that start the callback */ + NDefNfcTag *callOwner; + /** message that the callback is manage */ + Message *msg; + }; + +public: + + NDefNfcTag():mCallBack(&mDefaultCallBack){} + + /** + * Set the callback. + * @param c object contains the callback. + */ + void setCallBack(Callback *c){ + mCallBack=c; + }//setCallBack + /** * Open the communication session with the nfc tag. - * @par This method should be called at the end of an overriding implementation, just before returning. * @param force Force to open a communication. * @return true if success */ - virtual bool openSession(bool force = false){ - mSessionIsOpen=true; - return true; - } + virtual bool openSession(bool force = false)=0; /** * Close the communication with the nfc tag. - * @par This method should be called at the end of an overriding implementation, just before returning. * @return true if success */ - virtual bool closeSession(){ - mSessionIsOpen=false; - return true; - } + virtual bool closeSession()=0; + + /** + * Returns true if a communication with the nfc tag is open. + * @return true if a communication with the nfc tag is open + */ + virtual bool isSessionOpen()=0; /** * Write a message in the nfc tag. @@ -77,18 +153,25 @@ * @param msg Message to write. * @return true if success */ - bool write(const Message &msg) { - if(!mSessionIsOpen) + virtual bool write(Message &msg) { + if(!isSessionOpen()){ + mCallBack->onMessageWrite(this,false,msg); return false; + } const uint16_t length = msg.getByteLength(); uint8_t *buffer = new uint8_t[length]; - if(buffer==NULL) //impossible to allocate the buffer + if(buffer==NULL){ //impossible to allocate the buffer + mCallBack->onMessageWrite(this,false,msg); return false; + } + msg.write(buffer); - bool retValue = writeByte(buffer, length); - delete[] buffer; - return retValue; + + mCallBackStatus.callOwner=this; + mCallBackStatus.msg=&msg; + + return writeByte(buffer, length,0,NDefNfcTag::onWriteMessageCallback,&mCallBackStatus); } /** @@ -96,79 +179,149 @@ * @param[in,out] msg Message object the read records are added to. * @return true if success */ - bool read(Message *msg) { - if(!mSessionIsOpen) - return false; - - uint16_t length = getMessageLength(); - if (length == 0) + virtual bool read(Message *msg) { + if(!isSessionOpen()){ + mCallBack->onMessageRead(this,false,msg); return false; - //else - uint8_t *buffer = new uint8_t[length]; - if(buffer==NULL) - return false; + } - //read all the message contents - bool retValue = readByte(2, length, buffer); - if (retValue) { - Message::parseMessage(buffer, length, msg); + uint8_t *buffer = new uint8_t[2]; + if(buffer==NULL){ + mCallBack->onMessageRead(this,false,msg); + return false; } - delete[] buffer; - return retValue; + + mCallBackStatus.callOwner=this; + mCallBackStatus.msg=msg; + return readByte(0,2,buffer,NDefNfcTag::onReadMessageLength,&mCallBackStatus); } virtual ~NDefNfcTag() {} +protected: + + typedef struct CallbackStatus CallbackStatus_t; + /** - * Returns true if a communication with the nfc tag is open. - * @return true if a communication with the nfc tag is open + * Function that the component has to call when it finish a read/write operation + * @param interalState callback internal state data + * @param status true if the operation success + * @param buffer buffer write/read + * @param length number of byte read/write + * @return true if the operation had success */ - bool isSessionOpen(){ - return mSessionIsOpen; - } - - -protected: + typedef bool(*byteOperationCallback_t)(CallbackStatus_t *interalState, + bool status,const uint8_t *buffer, uint16_t length); /** * Write a sequence of bytes to the NDEF file. - * @param buffer Buffer to write. - * @param length Number of bytes to write. - * @param offset Write offset in bytes. - * @return true if success + * @param buffer buffer to write + * @param length number of bytes to write + * @param offset offset where start to write + * @param callback function to call when the operation ended + * @param callbackStatus parameter to pass to the callback function + * @return true if the operation has success */ - virtual bool writeByte(const uint8_t *buffer, uint16_t length, uint16_t offset=0)=0; + virtual bool writeByte(const uint8_t *buffer, uint16_t length,uint16_t offset, + byteOperationCallback_t callback,CallbackStatus_t *callbackStatus)=0; /** * Read a sequence of bytes from the NDEF file. - * @param byteOffset Read offsetin bytes. + * @param byteOffset Read offset in bytes. * @param byteLength Number of bytes to read. * @param[out] buffer Buffer to store the read data into. + * @param callback function to call when the operation ended + * @param callbackStatus parameter to pass to the callback function * @return true if success */ virtual bool readByte(const uint16_t byteOffset, const uint16_t byteLength, - uint8_t *buffer)=0; + uint8_t *buffer, byteOperationCallback_t callback,CallbackStatus_t *callbackStatus)=0; + + /** object with the user callback */ + Callback *mCallBack; private: + /** object with the current callback status */ + CallbackStatus_t mCallBackStatus; + /** default callback object, all the function are empty */ + Callback mDefaultCallBack; + /** - * Provides the status of a communication channel with the tag. + * function that the user will call when a write end, it will invoke onMessageWrite + * @param internalState object that invoke the write operation + * @param status true if the operation had success + * @param buffer buffer wrote + * @param length number of byte wrote + * @return true if the write had success */ - bool mSessionIsOpen; + static bool onWriteMessageCallback(CallbackStatus_t *internalState, + bool status,const uint8_t *buffer, uint16_t ){ + delete [] buffer; + + internalState->callOwner->mCallBack-> + onMessageWrite(internalState->callOwner,status,*internalState->msg); + return status; + } /** - * Read the NDEF message length. - * @return NDEF message length + * function that the use will call after a read operation. + * in this case we read the message length, this function will read all the message + * @param internalState object that invoke the write operation + * @param status true if the operation had success + * @param buffer buffer read + * @param length number of byte read + * @return true if the read had success */ - uint16_t getMessageLength() { - uint8_t lenghtByte[2]; - if (readByte(0, 2, lenghtByte)) - return (((uint16_t) lenghtByte[0]) << 8 | lenghtByte[1]); - return 0; - } //getMessageLength + static bool onReadMessageLength(CallbackStatus_t *internalState, + bool status,const uint8_t *buffer, uint16_t length){ + + if(!status || length!=2){ + internalState->callOwner->mCallBack-> + onMessageRead(internalState->callOwner,false,internalState->msg); + return false; + }//if + + length = (((uint16_t) buffer[0]) << 8 | buffer[1]); + delete [] buffer; + + uint8_t *readBuffer = new uint8_t[length]; + if(readBuffer==NULL){ + internalState->callOwner->mCallBack-> + onMessageRead(internalState->callOwner,false,internalState->msg); + return false; + }//readBuffer + + internalState->callOwner->readByte(2,length,readBuffer, + &NDefNfcTag::onReadMessageCallback,internalState); + return status; + } + -}; + /** + * function that the user will call when it read all the message + * @param internalState object that invoke the write operation + * @param status true if the operation had success + * @param buffer buffer read + * @param length number of byte read + * @return true if the read had success + */ + static bool onReadMessageCallback(CallbackStatus_t *internalState, + bool status,const uint8_t *buffer, uint16_t length){ + if(!status){ + internalState->callOwner->mCallBack-> + onMessageRead(internalState->callOwner,false,internalState->msg); + return false; + } + Message::parseMessage(buffer, length, internalState->msg); + delete [] buffer; + internalState->callOwner->mCallBack-> + onMessageRead(internalState->callOwner,true,internalState->msg); + return status ; + } -} /* namespace NDefLib */ +}; //class NDefNfcTagASync -#endif /* NDefNFCTAG_H_ */ +}// namespace NDefLib + +#endif /* NDEFLIB_NDEFNFCTAG_H_ */