blob: bb09cf65b2e8d8ef45edba7828509c603caa4d4d [file] [log] [blame]
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for an HDLC-lite encoder and decoder.
*/
#ifndef HDLC_HPP_
#define HDLC_HPP_
#include <openthread/config.h>
#include <openthread/types.h>
namespace ot {
/**
* @namespace ot::Hdlc
*
* @brief
* This namespace includes definitions for the HDLC-lite encoder and decoder.
*
*/
namespace Hdlc {
/**
* This class implements the HDLC-lite encoder.
*
*/
class Encoder
{
public:
/**
* This class defines a write iterator into a buffer used by Encoder.
*
* Hdlc users should sub-class this to add the actual buffer space.
*/
class BufferWriteIterator
{
public:
/**
* This method writes a byte to the buffer and updates the iterator (if space is available).
*
* @retval OT_ERROR_NONE Successfully wrote the byte and updates the iterator.
* @retval OT_ERROR_NO_BUFS Insufficient buffer space.
*
*/
otError WriteByte(uint8_t aByte);
/**
* This method checks if there is buffer space available to write @p aWriteLength bytes.
*
* param[in] aWriteLength Number of bytes to write.
*
* @retval true Enough buffer space available to write the requested number of bytes.
* @retval false Insufficient buffer space to write the requested number of bytes.
*
*/
bool CanWrite(uint16_t aWriteLength) const;
protected:
BufferWriteIterator(void); ///< Protected constructor to ensure no direct instantiation.
uint8_t *mWritePointer; ///< A pointer to current write position in the buffer.
uint16_t mRemainingLength; ///< Number of remaining bytes available to write.
};
/**
* This constructor initializes the object.
*
*/
Encoder(void);
/**
* This method begins an HDLC frame and puts the initial bytes into a buffer at the given @p aIterator.
*
* @param[inout] aIterator A reference to a buffer write iterator. On successful exit, the iterator is updated.
*
* @retval OT_ERROR_NONE Successfully started the HDLC frame.
* @retval OT_ERROR_NO_BUFS Insufficient buffer space available to start the HDLC frame.
*
*/
otError Init(BufferWriteIterator &aIterator);
/**
* This method encodes a single byte into a buffer at @p aIterator.
*
* If there is no space to add the byte, the write iterator remains the same.
*
* @param[in] aInByte A byte to encode and add.
* @param[inout] aIterator A reference to a write buffer iterator. On successful exit, the iterator is updated.
*
* @retval OT_ERROR_NONE Successfully encoded and added the byte.
* @retval OT_ERROR_NO_BUFS Insufficient buffer space available to encode and add the byte.
*
*/
otError Encode(uint8_t aInByte, BufferWriteIterator &aIterator);
/**
* This method encodes the frame into a buffer at @p aIterator.
*
* This method returns success only if there is space in buffer to encode the entire frame. If there is no space
* to encode the entire frame, the write iterator remains the same.
*
* @param[in] aInBuf A pointer to the input buffer.
* @param[in] aInLength The number of bytes in @p aInBuf to encode.
* @param[inout] aIterator A reference to a write buffer iterator. On successful exit, the iterator is updated.
*
* @retval OT_ERROR_NONE Successfully encoded the HDLC frame.
* @retval OT_ERROR_NO_BUFS Insufficient buffer space available to encode the HDLC frame.
*
*/
otError Encode(const uint8_t *aInBuf, uint16_t aInLength, BufferWriteIterator &aIterator);
/**
* This method finalizes an HDLC frame.
*
* @param[inout] aIterator A reference to a write buffer iterator. On successful exit, the iterator is updated.
*
* @retval OT_ERROR_NONE Successfully ended the HDLC frame.
* @retval OT_ERROR_NO_BUFS Insufficient buffer space available to end the HDLC frame.
*
*/
otError Finalize(BufferWriteIterator &aIterator);
private:
uint16_t mFcs;
};
/**
* This class implements the HDLC-lite decoder.
*
*/
class Decoder
{
public:
/**
* This function pointer is called when a complete frame has been formed.
*
* @param[in] aContext A pointer to arbitrary context information.
* @param[in] aFrame A pointer to the frame.
* @param[in] aFrameLength The frame length in bytes.
*
*/
typedef void (*FrameHandler)(void *aContext, uint8_t *aFrame, uint16_t aFrameLength);
/**
* This function pointer is called when an error has occurred.
*
* @param[in] aContext A pointer to arbitrary context information.
* @param[in] aError An error code describing the error.
* @param[in] aFrame A pointer to the frame.
* @param[in] aFrameLength The frame length in bytes.
*
*/
typedef void (*ErrorHandler)(void *aContext, otError aError, uint8_t *aFrame, uint16_t aFrameLength);
/**
* This constructor initializes the decoder.
*
* @param[in] aOutBuf A pointer to the output buffer.
* @param[in] aOutLength Size of the output buffer in bytes.
* @param[in] aFrameHandler A pointer to a function that is called when a complete frame is received.
* @param[in] aContext A pointer to arbitrary context information.
*
*/
Decoder(uint8_t *aOutBuf, uint16_t aOutLength, FrameHandler aFrameHandler, ErrorHandler aErrorHandler,
void *aContext);
/**
* This method streams bytes into the decoder.
*
* @param[in] aInBuf A pointer to the input buffer.
* @param[in] aInLength The number of bytes in @p aInBuf.
*
*/
void Decode(const uint8_t *aInBuf, uint16_t aInLength);
private:
enum State
{
kStateNoSync = 0,
kStateSync,
kStateEscaped,
};
State mState;
FrameHandler mFrameHandler;
ErrorHandler mErrorHandler;
void *mContext;
uint8_t *mOutBuf;
uint16_t mOutOffset;
uint16_t mOutLength;
uint16_t mFcs;
};
} // namespace Hdlc
} // namespace ot
#endif // HDLC_HPP_