#ifndef NCP_UART_HPP_
#define NCP_UART_HPP_
#include "openthread-core-config.h"
#include "lib/hdlc/hdlc.hpp"
#include "ncp/ncp_base.hpp"
#if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
#include "spinel_encrypter.hpp"
#endif
namespace ot {
namespace Ncp {
class NcpUart : public NcpBase
{
typedef NcpBase super_t;
public:
explicit NcpUart(Instance *aInstance);
void HandleUartSendDone(void);
void HandleUartReceiveDone(const uint8_t *aBuf, uint16_t aBufLength);
private:
enum
{
kUartTxBufferSize = OPENTHREAD_CONFIG_NCP_UART_TX_CHUNK_SIZE, kRxBufferSize = OPENTHREAD_CONFIG_NCP_UART_RX_BUFFER_SIZE + OPENTHREAD_CONFIG_NCP_SPINEL_ENCRYPTER_EXTRA_DATA_SIZE, };
enum UartTxState
{
kStartingFrame, kEncodingFrame, kFinalizingFrame, };
#if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
class Spinel::BufferEncrypterReader
{
public:
explicit Spinel::BufferEncrypterReader(Spinel::Buffer &aTxFrameBuffer);
bool IsEmpty(void) const;
otError OutFrameBegin(void);
bool OutFrameHasEnded(void);
uint8_t OutFrameReadByte(void);
otError OutFrameRemove(void);
private:
void Reset(void);
Spinel::Buffer &mTxFrameBuffer;
uint8_t mDataBuffer[kRxBufferSize];
size_t mDataBufferReadIndex;
size_t mOutputDataLength;
};
#endif
void EncodeAndSendToUart(void);
void HandleFrame(otError aError);
void HandleError(otError aError, uint8_t *aBuf, uint16_t aBufLength);
void TxFrameBufferHasData(void);
void HandleFrameAddedToNcpBuffer(void);
static void EncodeAndSendToUart(Tasklet &aTasklet);
static void HandleFrame(void *aContext, otError aError);
static void HandleFrameAddedToNcpBuffer(void * aContext,
Spinel::Buffer::FrameTag aTag,
Spinel::Buffer::Priority aPriority,
Spinel::Buffer * aBuffer);
Hdlc::Encoder mFrameEncoder;
Hdlc::Decoder mFrameDecoder;
Hdlc::FrameBuffer<kUartTxBufferSize> mUartBuffer;
UartTxState mState;
uint8_t mByte;
Hdlc::FrameBuffer<kRxBufferSize> mRxBuffer;
bool mUartSendImmediate;
Tasklet mUartSendTask;
#if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
Spinel::BufferEncrypterReader mTxFrameBufferEncrypterReader;
#endif };
} }
#endif