• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *    Copyright (c) 2016, The OpenThread Authors.
3  *    All rights reserved.
4  *
5  *    Redistribution and use in source and binary forms, with or without
6  *    modification, are permitted provided that the following conditions are met:
7  *    1. Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *    2. Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *    3. Neither the name of the copyright holder nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20  *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /**
29  * @file
30  *   This file contains definitions for a HDLC based NCP interface to the OpenThread stack.
31  */
32 
33 #ifndef NCP_HDLC_HPP_
34 #define NCP_HDLC_HPP_
35 
36 #include "openthread-core-config.h"
37 
38 #include "lib/hdlc/hdlc.hpp"
39 #include "lib/spinel/multi_frame_buffer.hpp"
40 #include "ncp/ncp_base.hpp"
41 
42 #if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
43 #include "lib/spinel/spinel_encrypter.hpp"
44 #endif // OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
45 
46 namespace ot {
47 namespace Ncp {
48 
49 class NcpHdlc : public NcpBase
50 {
51     typedef NcpBase super_t;
52 
53 public:
54     /**
55      * Constructor
56      *
57      * @param[in]  aInstance  The OpenThread instance structure.
58      */
59     explicit NcpHdlc(Instance *aInstance, otNcpHdlcSendCallback aSendCallback);
60 
61 #if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE && OPENTHREAD_RADIO
62     /**
63      * Constructor
64      *
65      * @param[in]  aInstancs      The OpenThread instance pointers array.
66      * @param[in]  aCount         Number of instances in the array.
67      * @param[in]  aSendCallback  Callback for sending data.
68      */
69     explicit NcpHdlc(Instance **aInstances, uint8_t aCount, otNcpHdlcSendCallback aSendCallback);
70 
71 #endif // OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE && OPENTHREAD_RADIO
72 
73     /**
74      * Is called when uart tx is finished. It prepares and sends the next data chunk (if any) to uart.
75      */
76     void HandleHdlcSendDone(void);
77 
78     /**
79      * Is called when uart received a data buffer.
80      */
81     void HandleHdlcReceiveDone(const uint8_t *aBuf, uint16_t aBufLength);
82 
83 private:
84     enum
85     {
86         kHdlcTxBufferSize = OPENTHREAD_CONFIG_NCP_HDLC_TX_CHUNK_SIZE,   // HDLC tx buffer size.
87         kRxBufferSize     = OPENTHREAD_CONFIG_NCP_HDLC_RX_BUFFER_SIZE + // Rx buffer size (should be large enough to fit
88                         OPENTHREAD_CONFIG_NCP_SPINEL_ENCRYPTER_EXTRA_DATA_SIZE, // one whole (decoded) received frame).
89     };
90 
91     enum HdlcTxState
92     {
93         kStartingFrame,   // Starting a new frame.
94         kEncodingFrame,   // In middle of encoding a frame.
95         kFinalizingFrame, // Finalizing a frame.
96     };
97 
98 #if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
99     /**
100      * Wraps Spinel::Buffer allowing to read data through spinel encrypter.
101      * Creates additional buffers to allow transforming of the whole spinel frames.
102      */
103     class BufferEncrypterReader
104     {
105     public:
106         /**
107          * C-tor.
108          * Takes a reference to Spinel::Buffer in order to read spinel frames.
109          */
110         explicit BufferEncrypterReader(Spinel::Buffer &aTxFrameBuffer);
111         bool    IsEmpty(void) const;
112         otError OutFrameBegin(void);
113         bool    OutFrameHasEnded(void);
114         uint8_t OutFrameReadByte(void);
115         otError OutFrameRemove(void);
116 
117     private:
118         void Reset(void);
119 
120         Spinel::Buffer &mTxFrameBuffer;
121         uint8_t         mDataBuffer[kRxBufferSize];
122         size_t          mDataBufferReadIndex;
123         size_t          mOutputDataLength;
124     };
125 #endif // OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
126 
127     void EncodeAndSend(void);
128     void HandleFrame(otError aError);
129     void HandleError(otError aError, uint8_t *aBuf, uint16_t aBufLength);
130     void TxFrameBufferHasData(void);
131     void HandleFrameAddedToNcpBuffer(void);
132 
133     static void           EncodeAndSend(Tasklet &aTasklet);
134     static void           HandleFrame(void *aContext, otError aError);
135     static void           HandleFrameAddedToNcpBuffer(void                    *aContext,
136                                                       Spinel::Buffer::FrameTag aTag,
137                                                       Spinel::Buffer::Priority aPriority,
138                                                       Spinel::Buffer          *aBuffer);
139     otNcpHdlcSendCallback mSendCallback;
140 
141     Spinel::FrameBuffer<kHdlcTxBufferSize> mHdlcBuffer;
142     Hdlc::Encoder                          mFrameEncoder;
143     Hdlc::Decoder                          mFrameDecoder;
144     HdlcTxState                            mState;
145     uint8_t                                mByte;
146     Spinel::FrameBuffer<kRxBufferSize>     mRxBuffer;
147     bool                                   mHdlcSendImmediate;
148     Tasklet                                mHdlcSendTask;
149 
150 #if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
151     BufferEncrypterReader mTxFrameBufferEncrypterReader;
152 #endif // OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
153 };
154 
155 } // namespace Ncp
156 } // namespace ot
157 
158 #endif // NCP_HDLC_HPP_
159