9b7a6c5c20e2e3d7c36aa96cc9e9607d6e220197
[platform/upstream/connectedhomeip.git] / src / ble / BtpEngine.h
1 /*
2  *
3  *    Copyright (c) 2020-2021 Project CHIP Authors
4  *    Copyright (c) 2014-2017 Nest Labs, Inc.
5  *
6  *    Licensed under the Apache License, Version 2.0 (the "License");
7  *    you may not use this file except in compliance with the License.
8  *    You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *    Unless required by applicable law or agreed to in writing, software
13  *    distributed under the License is distributed on an "AS IS" BASIS,
14  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *    See the License for the specific language governing permissions and
16  *    limitations under the License.
17  */
18
19 /**
20  *    @file
21  *      This file defines types and an object for the chip over
22  *      Bluetooth Low Energy (CHIPoBLE) byte-stream, connection-oriented
23  *      adaptation of chip for point-to-point Bluetooth Low Energy
24  *      (BLE) links.
25  *
26  */
27
28 #pragma once
29
30 #ifndef __STDC_LIMIT_MACROS
31 #define __STDC_LIMIT_MACROS
32 #endif
33
34 #include <stdint.h>
35 #include <string.h>
36
37 #include <ble/BleConfig.h>
38
39 #include <ble/BleError.h>
40 #include <support/BitFlags.h>
41 #include <system/SystemPacketBuffer.h>
42
43 namespace chip {
44 namespace Ble {
45
46 constexpr size_t kTransferProtocolHeaderFlagsSize = 1; // Size in bytes of enocded BTP fragment header flag bits
47 constexpr size_t kTransferProtocolSequenceNumSize = 1; // Size in bytes of encoded BTP sequence number
48 constexpr size_t kTransferProtocolAckSize         = 1; // Size in bytes of encoded BTP fragment acknowledgement number
49 constexpr size_t kTransferProtocolMsgLenSize      = 2; // Size in byte of encoded BTP total fragmented message length
50
51 constexpr size_t kTransferProtocolMaxHeaderSize =
52     kTransferProtocolHeaderFlagsSize + kTransferProtocolAckSize + kTransferProtocolSequenceNumSize + kTransferProtocolMsgLenSize;
53 constexpr size_t kTransferProtocolMidFragmentMaxHeaderSize =
54     kTransferProtocolHeaderFlagsSize + kTransferProtocolAckSize + kTransferProtocolSequenceNumSize;
55 constexpr size_t kTransferProtocolStandaloneAckHeaderSize =
56     kTransferProtocolHeaderFlagsSize + kTransferProtocolAckSize + kTransferProtocolSequenceNumSize;
57
58 using ::chip::System::PacketBufferHandle;
59
60 typedef uint8_t SequenceNumber_t; // If type changed from uint8_t, adjust assumptions in BtpEngine::IsValidAck and
61                                   // BLEEndPoint::AdjustReceiveWindow.
62
63 #if CHIP_ENABLE_CHIPOBLE_TEST
64 class BLEEndPoint;
65 #endif
66
67 // Public data members:
68 typedef enum
69 {
70     kType_Data    = 0, // Default 0 for data
71     kType_Control = 1,
72 } PacketType_t; // BTP packet types
73
74 class BtpEngine
75 {
76 #if CHIP_ENABLE_CHIPOBLE_TEST
77     friend class BLEEndPoint;
78 #endif
79
80 public:
81     // Public data members:
82     typedef enum
83     {
84         kState_Idle       = 0,
85         kState_InProgress = 1,
86         kState_Complete   = 2,
87         kState_Error      = 3
88     } State_t; // [READ-ONLY] Current state
89
90     enum
91     {
92         kHeaderFlag_StartMessage    = 0x01,
93         kHeaderFlag_ContinueMessage = 0x02,
94         kHeaderFlag_EndMessage      = 0x04,
95         kHeaderFlag_FragmentAck     = 0x08,
96 #if CHIP_ENABLE_CHIPOBLE_TEST
97         kHeaderFlag_CommandMessage = 0x10,
98 #endif
99     }; // Masks for BTP fragment header flag bits.
100
101     static const uint16_t sDefaultFragmentSize;
102     static const uint16_t sMaxFragmentSize;
103
104     // Public functions:
105     BLE_ERROR Init(void * an_app_state, bool expect_first_ack);
106
107     inline void SetTxFragmentSize(uint16_t size) { mTxFragmentSize = size; }
108     inline void SetRxFragmentSize(uint16_t size) { mRxFragmentSize = size; }
109
110     uint16_t GetRxFragmentSize() { return mRxFragmentSize; }
111     uint16_t GetTxFragmentSize() { return mTxFragmentSize; }
112
113     SequenceNumber_t GetAndIncrementNextTxSeqNum();
114     SequenceNumber_t GetAndRecordRxAckSeqNum();
115
116     inline SequenceNumber_t GetLastReceivedSequenceNumber() { return mRxNewestUnackedSeqNum; }
117     inline SequenceNumber_t GetNewestUnackedSentSequenceNumber() { return mTxNewestUnackedSeqNum; }
118
119     inline bool ExpectingAck() const { return mExpectingAck; }
120
121     inline State_t RxState() { return mRxState; }
122     inline State_t TxState() { return mTxState; }
123 #if CHIP_ENABLE_CHIPOBLE_TEST
124     inline PacketType_t SetTxPacketType(PacketType_t type) { return (mTxPacketType = type); }
125     inline PacketType_t SetRxPacketType(PacketType_t type) { return (mRxPacketType = type); }
126     inline PacketType_t TxPacketType() { return mTxPacketType; }
127     inline PacketType_t RxPacketType() { return mRxPacketType; }
128     inline SequenceNumber_t SetTxPacketSeq(SequenceNumber_t seq) { return (mTxPacketSeq = seq); }
129     inline SequenceNumber_t SetRxPacketSeq(SequenceNumber_t seq) { return (mRxPacketSeq = seq); }
130     inline SequenceNumber_t TxPacketSeq() { return mTxPacketSeq; }
131     inline SequenceNumber_t RxPacketSeq() { return mRxPacketSeq; }
132     inline bool IsCommandPacket(const PacketBufferHandle & p) { return GetFlag(*(p->Start()), kHeaderFlag_CommandMessage); }
133     inline void PushPacketTag(const PacketBufferHandle & p, PacketType_t type)
134     {
135         p->SetStart(p->Start() - sizeof(type));
136         memcpy(p->Start(), &type, sizeof(type));
137     }
138     inline PacketType_t PopPacketTag(const PacketBufferHandle & p)
139     {
140         PacketType_t type;
141         memcpy(&type, p->Start(), sizeof(type));
142         p->SetStart(p->Start() + sizeof(type));
143         return type;
144     }
145 #endif // CHIP_ENABLE_CHIPOBLE_TEST
146
147     bool HasUnackedData() const;
148
149     BLE_ERROR HandleCharacteristicReceived(System::PacketBufferHandle data, SequenceNumber_t & receivedAck, bool & didReceiveAck);
150     bool HandleCharacteristicSend(System::PacketBufferHandle data, bool send_ack);
151     BLE_ERROR EncodeStandAloneAck(const PacketBufferHandle & data);
152
153     PacketBufferHandle TakeRxPacket();
154     PacketBufferHandle BorrowRxPacket() { return mRxBuf.Retain(); }
155     void ClearRxPacket() { (void) TakeRxPacket(); }
156     PacketBufferHandle TakeTxPacket();
157     PacketBufferHandle BorrowTxPacket() { return mTxBuf.Retain(); }
158     void ClearTxPacket() { (void) TakeTxPacket(); }
159
160     void LogState() const;
161     void LogStateDebug() const;
162
163 private:
164     // Private data members:
165 #if CHIP_ENABLE_CHIPOBLE_TEST
166     PacketType_t mTxPacketType;
167     PacketType_t mRxPacketType;
168     SequenceNumber_t mTxPacketSeq;
169     SequenceNumber_t mRxPacketSeq;
170 #endif
171     State_t mRxState;
172     uint16_t mRxLength;
173     void * mAppState;
174     System::PacketBufferHandle mRxBuf;
175     SequenceNumber_t mRxNextSeqNum;
176     SequenceNumber_t mRxNewestUnackedSeqNum;
177     SequenceNumber_t mRxOldestUnackedSeqNum;
178     uint16_t mRxFragmentSize;
179
180     State_t mTxState;
181     uint16_t mTxLength;
182     System::PacketBufferHandle mTxBuf;
183     SequenceNumber_t mTxNextSeqNum;
184     SequenceNumber_t mTxNewestUnackedSeqNum;
185     SequenceNumber_t mTxOldestUnackedSeqNum;
186     bool mExpectingAck;
187     uint16_t mTxFragmentSize;
188
189     uint16_t mRxCharCount;
190     uint16_t mRxPacketCount;
191     uint16_t mTxCharCount;
192     uint16_t mTxPacketCount;
193
194     // Private functions:
195     bool IsValidAck(SequenceNumber_t ack_num) const;
196     BLE_ERROR HandleAckReceived(SequenceNumber_t ack_num);
197 };
198
199 } /* namespace Ble */
200 } /* namespace chip */