1*cfb92d14SAndroid Build Coastguard Worker /* 2*cfb92d14SAndroid Build Coastguard Worker * Copyright (c) 2016, The OpenThread Authors. 3*cfb92d14SAndroid Build Coastguard Worker * All rights reserved. 4*cfb92d14SAndroid Build Coastguard Worker * 5*cfb92d14SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without 6*cfb92d14SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met: 7*cfb92d14SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright 8*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer. 9*cfb92d14SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright 10*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the 11*cfb92d14SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution. 12*cfb92d14SAndroid Build Coastguard Worker * 3. Neither the name of the copyright holder nor the 13*cfb92d14SAndroid Build Coastguard Worker * names of its contributors may be used to endorse or promote products 14*cfb92d14SAndroid Build Coastguard Worker * derived from this software without specific prior written permission. 15*cfb92d14SAndroid Build Coastguard Worker * 16*cfb92d14SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17*cfb92d14SAndroid Build Coastguard Worker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18*cfb92d14SAndroid Build Coastguard Worker * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19*cfb92d14SAndroid Build Coastguard Worker * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 20*cfb92d14SAndroid Build Coastguard Worker * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21*cfb92d14SAndroid Build Coastguard Worker * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22*cfb92d14SAndroid Build Coastguard Worker * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23*cfb92d14SAndroid Build Coastguard Worker * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24*cfb92d14SAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25*cfb92d14SAndroid Build Coastguard Worker * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26*cfb92d14SAndroid Build Coastguard Worker */ 27*cfb92d14SAndroid Build Coastguard Worker 28*cfb92d14SAndroid Build Coastguard Worker /** 29*cfb92d14SAndroid Build Coastguard Worker * @file 30*cfb92d14SAndroid Build Coastguard Worker * This file includes definitions for an HDLC-lite encoder and decoder. 31*cfb92d14SAndroid Build Coastguard Worker */ 32*cfb92d14SAndroid Build Coastguard Worker 33*cfb92d14SAndroid Build Coastguard Worker #ifndef HDLC_HPP_ 34*cfb92d14SAndroid Build Coastguard Worker #define HDLC_HPP_ 35*cfb92d14SAndroid Build Coastguard Worker 36*cfb92d14SAndroid Build Coastguard Worker #include <stdint.h> 37*cfb92d14SAndroid Build Coastguard Worker #include <stdlib.h> 38*cfb92d14SAndroid Build Coastguard Worker #include <string.h> 39*cfb92d14SAndroid Build Coastguard Worker 40*cfb92d14SAndroid Build Coastguard Worker #include <openthread/error.h> 41*cfb92d14SAndroid Build Coastguard Worker 42*cfb92d14SAndroid Build Coastguard Worker #include "lib/spinel/multi_frame_buffer.hpp" 43*cfb92d14SAndroid Build Coastguard Worker 44*cfb92d14SAndroid Build Coastguard Worker namespace ot { 45*cfb92d14SAndroid Build Coastguard Worker 46*cfb92d14SAndroid Build Coastguard Worker /** 47*cfb92d14SAndroid Build Coastguard Worker * @namespace ot::Hdlc 48*cfb92d14SAndroid Build Coastguard Worker * 49*cfb92d14SAndroid Build Coastguard Worker * @brief 50*cfb92d14SAndroid Build Coastguard Worker * This namespace includes definitions for the HDLC-lite encoder and decoder. 51*cfb92d14SAndroid Build Coastguard Worker * 52*cfb92d14SAndroid Build Coastguard Worker */ 53*cfb92d14SAndroid Build Coastguard Worker namespace Hdlc { 54*cfb92d14SAndroid Build Coastguard Worker 55*cfb92d14SAndroid Build Coastguard Worker /** 56*cfb92d14SAndroid Build Coastguard Worker * Implements the HDLC-lite encoder. 57*cfb92d14SAndroid Build Coastguard Worker * 58*cfb92d14SAndroid Build Coastguard Worker */ 59*cfb92d14SAndroid Build Coastguard Worker class Encoder 60*cfb92d14SAndroid Build Coastguard Worker { 61*cfb92d14SAndroid Build Coastguard Worker public: 62*cfb92d14SAndroid Build Coastguard Worker /** 63*cfb92d14SAndroid Build Coastguard Worker * Initializes the object. 64*cfb92d14SAndroid Build Coastguard Worker * 65*cfb92d14SAndroid Build Coastguard Worker * @param[in] aWritePointer The `FrameWritePointer` used by `Encoder` to write the encoded frames. 66*cfb92d14SAndroid Build Coastguard Worker * 67*cfb92d14SAndroid Build Coastguard Worker */ 68*cfb92d14SAndroid Build Coastguard Worker explicit Encoder(Spinel::FrameWritePointer &aWritePointer); 69*cfb92d14SAndroid Build Coastguard Worker 70*cfb92d14SAndroid Build Coastguard Worker /** 71*cfb92d14SAndroid Build Coastguard Worker * Begins an HDLC frame. 72*cfb92d14SAndroid Build Coastguard Worker * 73*cfb92d14SAndroid Build Coastguard Worker * @retval OT_ERROR_NONE Successfully started the HDLC frame. 74*cfb92d14SAndroid Build Coastguard Worker * @retval OT_ERROR_NO_BUFS Insufficient buffer space available to start the HDLC frame. 75*cfb92d14SAndroid Build Coastguard Worker * 76*cfb92d14SAndroid Build Coastguard Worker */ 77*cfb92d14SAndroid Build Coastguard Worker otError BeginFrame(void); 78*cfb92d14SAndroid Build Coastguard Worker 79*cfb92d14SAndroid Build Coastguard Worker /** 80*cfb92d14SAndroid Build Coastguard Worker * Encodes a single byte into current frame. 81*cfb92d14SAndroid Build Coastguard Worker * 82*cfb92d14SAndroid Build Coastguard Worker * If there is no space to add the byte, the write pointer in frame buffer remains the same. 83*cfb92d14SAndroid Build Coastguard Worker * 84*cfb92d14SAndroid Build Coastguard Worker * @param[in] aByte A byte value to encode and add to frame. 85*cfb92d14SAndroid Build Coastguard Worker * 86*cfb92d14SAndroid Build Coastguard Worker * @retval OT_ERROR_NONE Successfully encoded and added the byte to frame buffer. 87*cfb92d14SAndroid Build Coastguard Worker * @retval OT_ERROR_NO_BUFS Insufficient buffer space available to encode and add the byte. 88*cfb92d14SAndroid Build Coastguard Worker * 89*cfb92d14SAndroid Build Coastguard Worker */ 90*cfb92d14SAndroid Build Coastguard Worker otError Encode(uint8_t aByte); 91*cfb92d14SAndroid Build Coastguard Worker 92*cfb92d14SAndroid Build Coastguard Worker /** 93*cfb92d14SAndroid Build Coastguard Worker * Encodes a given block of data into current frame. 94*cfb92d14SAndroid Build Coastguard Worker * 95*cfb92d14SAndroid Build Coastguard Worker * Returns success only if there is space in buffer to encode the entire block of data. If there is no 96*cfb92d14SAndroid Build Coastguard Worker * space to encode the entire block of data, the write pointer in frame buffer remains the same. 97*cfb92d14SAndroid Build Coastguard Worker * 98*cfb92d14SAndroid Build Coastguard Worker * @param[in] aData A pointer to a buffer containing the data to encode. 99*cfb92d14SAndroid Build Coastguard Worker * @param[in] aLength The number of bytes in @p aData. 100*cfb92d14SAndroid Build Coastguard Worker * 101*cfb92d14SAndroid Build Coastguard Worker * @retval OT_ERROR_NONE Successfully encoded and added the data to frame. 102*cfb92d14SAndroid Build Coastguard Worker * @retval OT_ERROR_NO_BUFS Insufficient buffer space available to add the frame. 103*cfb92d14SAndroid Build Coastguard Worker * 104*cfb92d14SAndroid Build Coastguard Worker */ 105*cfb92d14SAndroid Build Coastguard Worker otError Encode(const uint8_t *aData, uint16_t aLength); 106*cfb92d14SAndroid Build Coastguard Worker 107*cfb92d14SAndroid Build Coastguard Worker /** 108*cfb92d14SAndroid Build Coastguard Worker * Ends/finalizes the HDLC frame. 109*cfb92d14SAndroid Build Coastguard Worker * 110*cfb92d14SAndroid Build Coastguard Worker * @retval OT_ERROR_NONE Successfully ended the HDLC frame. 111*cfb92d14SAndroid Build Coastguard Worker * @retval OT_ERROR_NO_BUFS Insufficient buffer space available to end the HDLC frame. 112*cfb92d14SAndroid Build Coastguard Worker * 113*cfb92d14SAndroid Build Coastguard Worker */ 114*cfb92d14SAndroid Build Coastguard Worker otError EndFrame(void); 115*cfb92d14SAndroid Build Coastguard Worker 116*cfb92d14SAndroid Build Coastguard Worker private: 117*cfb92d14SAndroid Build Coastguard Worker Spinel::FrameWritePointer &mWritePointer; 118*cfb92d14SAndroid Build Coastguard Worker uint16_t mFcs; 119*cfb92d14SAndroid Build Coastguard Worker }; 120*cfb92d14SAndroid Build Coastguard Worker 121*cfb92d14SAndroid Build Coastguard Worker /** 122*cfb92d14SAndroid Build Coastguard Worker * Implements the HDLC-lite decoder. 123*cfb92d14SAndroid Build Coastguard Worker * 124*cfb92d14SAndroid Build Coastguard Worker */ 125*cfb92d14SAndroid Build Coastguard Worker class Decoder 126*cfb92d14SAndroid Build Coastguard Worker { 127*cfb92d14SAndroid Build Coastguard Worker public: 128*cfb92d14SAndroid Build Coastguard Worker /** 129*cfb92d14SAndroid Build Coastguard Worker * Pointer is called when either a complete frame has been decoded or an error occurs during 130*cfb92d14SAndroid Build Coastguard Worker * decoding. 131*cfb92d14SAndroid Build Coastguard Worker * 132*cfb92d14SAndroid Build Coastguard Worker * The decoded frame (or the partially decoded frame in case of an error) is available in `aFrameWritePointer` 133*cfb92d14SAndroid Build Coastguard Worker * buffer given in `Decoder` constructor. 134*cfb92d14SAndroid Build Coastguard Worker * 135*cfb92d14SAndroid Build Coastguard Worker * @param[in] aContext A pointer to arbitrary context information. 136*cfb92d14SAndroid Build Coastguard Worker * @param[in] aError OT_ERROR_NONE if the frame was decoded successfully, 137*cfb92d14SAndroid Build Coastguard Worker * OT_ERROR_PARSE if the Frame Check Sequence (FCS) was incorrect in decoded frame, 138*cfb92d14SAndroid Build Coastguard Worker * OT_ERROR_NO_BUFS insufficient buffer space available to save the decoded frame. 139*cfb92d14SAndroid Build Coastguard Worker * 140*cfb92d14SAndroid Build Coastguard Worker */ 141*cfb92d14SAndroid Build Coastguard Worker typedef void (*FrameHandler)(void *aContext, otError aError); 142*cfb92d14SAndroid Build Coastguard Worker 143*cfb92d14SAndroid Build Coastguard Worker /** 144*cfb92d14SAndroid Build Coastguard Worker * Initializes the object. 145*cfb92d14SAndroid Build Coastguard Worker * 146*cfb92d14SAndroid Build Coastguard Worker */ 147*cfb92d14SAndroid Build Coastguard Worker Decoder(void); 148*cfb92d14SAndroid Build Coastguard Worker 149*cfb92d14SAndroid Build Coastguard Worker /** 150*cfb92d14SAndroid Build Coastguard Worker * Initializes the decoder. 151*cfb92d14SAndroid Build Coastguard Worker * 152*cfb92d14SAndroid Build Coastguard Worker * @param[in] aFrameWritePointer The `FrameWritePointer` used by `Decoder` to write the decoded frames. 153*cfb92d14SAndroid Build Coastguard Worker * @param[in] aFrameHandler The frame handler callback function pointer. 154*cfb92d14SAndroid Build Coastguard Worker * @param[in] aContext A pointer to arbitrary context information. 155*cfb92d14SAndroid Build Coastguard Worker * 156*cfb92d14SAndroid Build Coastguard Worker */ 157*cfb92d14SAndroid Build Coastguard Worker void Init(Spinel::FrameWritePointer &aFrameWritePointer, FrameHandler aFrameHandler, void *aContext); 158*cfb92d14SAndroid Build Coastguard Worker 159*cfb92d14SAndroid Build Coastguard Worker /** 160*cfb92d14SAndroid Build Coastguard Worker * Feeds a block of data into the decoder. 161*cfb92d14SAndroid Build Coastguard Worker * 162*cfb92d14SAndroid Build Coastguard Worker * If during decoding, a full HDLC frame is successfully decoded or an error occurs, the `FrameHandler` callback 163*cfb92d14SAndroid Build Coastguard Worker * is called. The decoded frame (or the partially decoded frame in case of an error) is available in 164*cfb92d14SAndroid Build Coastguard Worker * `aFrameWritePointer` buffer from the constructor. The `Decoder` user (if required) must update/reset the write 165*cfb92d14SAndroid Build Coastguard Worker * pointer from this callback for the next frame to be decoded. 166*cfb92d14SAndroid Build Coastguard Worker * 167*cfb92d14SAndroid Build Coastguard Worker * @param[in] aData A pointer to a buffer containing data to be fed to decoder. 168*cfb92d14SAndroid Build Coastguard Worker * @param[in] aLength The number of bytes in @p aData. 169*cfb92d14SAndroid Build Coastguard Worker * 170*cfb92d14SAndroid Build Coastguard Worker */ 171*cfb92d14SAndroid Build Coastguard Worker void Decode(const uint8_t *aData, uint16_t aLength); 172*cfb92d14SAndroid Build Coastguard Worker 173*cfb92d14SAndroid Build Coastguard Worker /** 174*cfb92d14SAndroid Build Coastguard Worker * Resets internal states of the decoder. 175*cfb92d14SAndroid Build Coastguard Worker * 176*cfb92d14SAndroid Build Coastguard Worker */ 177*cfb92d14SAndroid Build Coastguard Worker void Reset(void); 178*cfb92d14SAndroid Build Coastguard Worker 179*cfb92d14SAndroid Build Coastguard Worker private: 180*cfb92d14SAndroid Build Coastguard Worker enum State 181*cfb92d14SAndroid Build Coastguard Worker { 182*cfb92d14SAndroid Build Coastguard Worker kStateNoSync, 183*cfb92d14SAndroid Build Coastguard Worker kStateSync, 184*cfb92d14SAndroid Build Coastguard Worker kStateEscaped, 185*cfb92d14SAndroid Build Coastguard Worker }; 186*cfb92d14SAndroid Build Coastguard Worker 187*cfb92d14SAndroid Build Coastguard Worker State mState; 188*cfb92d14SAndroid Build Coastguard Worker Spinel::FrameWritePointer *mWritePointer; 189*cfb92d14SAndroid Build Coastguard Worker FrameHandler mFrameHandler; 190*cfb92d14SAndroid Build Coastguard Worker void *mContext; 191*cfb92d14SAndroid Build Coastguard Worker uint16_t mFcs; 192*cfb92d14SAndroid Build Coastguard Worker uint16_t mDecodedLength; 193*cfb92d14SAndroid Build Coastguard Worker }; 194*cfb92d14SAndroid Build Coastguard Worker 195*cfb92d14SAndroid Build Coastguard Worker } // namespace Hdlc 196*cfb92d14SAndroid Build Coastguard Worker } // namespace ot 197*cfb92d14SAndroid Build Coastguard Worker 198*cfb92d14SAndroid Build Coastguard Worker #endif // HDLC_HPP_ 199