Line data Source code
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 _CHIP_BLE_BLE_H
31 : #error "Please include <ble/Ble.h> instead!"
32 : #endif
33 :
34 : #include <algorithm>
35 : #include <cstdint>
36 : #include <cstring>
37 :
38 : #include <lib/core/CHIPError.h>
39 : #include <system/SystemPacketBuffer.h>
40 :
41 : namespace chip {
42 : namespace Ble {
43 :
44 : inline constexpr size_t kTransferProtocolHeaderFlagsSize = 1; // Size in bytes of encoded BTP fragment header flag bits
45 : inline constexpr size_t kTransferProtocolSequenceNumSize = 1; // Size in bytes of encoded BTP sequence number
46 : inline constexpr size_t kTransferProtocolAckSize = 1; // Size in bytes of encoded BTP fragment acknowledgement number
47 : inline constexpr size_t kTransferProtocolMsgLenSize = 2; // Size in byte of encoded BTP total fragmented message length
48 :
49 : constexpr size_t kTransferProtocolMaxHeaderSize =
50 : kTransferProtocolHeaderFlagsSize + kTransferProtocolAckSize + kTransferProtocolSequenceNumSize + kTransferProtocolMsgLenSize;
51 : constexpr size_t kTransferProtocolMidFragmentMaxHeaderSize =
52 : kTransferProtocolHeaderFlagsSize + kTransferProtocolAckSize + kTransferProtocolSequenceNumSize;
53 : constexpr size_t kTransferProtocolStandaloneAckHeaderSize =
54 : kTransferProtocolHeaderFlagsSize + kTransferProtocolAckSize + kTransferProtocolSequenceNumSize;
55 :
56 : using ::chip::System::PacketBufferHandle;
57 :
58 : typedef uint8_t SequenceNumber_t; // If type changed from uint8_t, adjust assumptions in BtpEngine::IsValidAck and
59 : // BLEEndPoint::AdjustReceiveWindow.
60 :
61 : // Public data members:
62 : typedef enum
63 : {
64 : kType_Data = 0, // Default 0 for data
65 : kType_Control = 1,
66 : } PacketType_t; // BTP packet types
67 :
68 : class BtpEngine
69 : {
70 : public:
71 : // Public data members:
72 : typedef enum
73 : {
74 : kState_Idle = 0,
75 : kState_InProgress = 1,
76 : kState_Complete = 2,
77 : kState_Error = 3
78 : } State_t; // [READ-ONLY] Current state
79 :
80 : // Masks for BTP fragment header flag bits.
81 : enum class HeaderFlags : uint8_t
82 : {
83 : kStartMessage = 0x01,
84 : kContinueMessage = 0x02,
85 : kEndMessage = 0x04,
86 : kFragmentAck = 0x08,
87 : };
88 :
89 : static const uint16_t sDefaultFragmentSize;
90 : static const uint16_t sMaxFragmentSize;
91 : static const uint16_t sMinFragmentSize;
92 :
93 : // Public functions:
94 : CHIP_ERROR Init(void * an_app_state, bool expect_first_ack);
95 :
96 18 : inline void SetTxFragmentSize(uint16_t size) { mTxFragmentSize = std::clamp(size, sMinFragmentSize, sMaxFragmentSize); }
97 18 : inline void SetRxFragmentSize(uint16_t size) { mRxFragmentSize = std::clamp(size, sMinFragmentSize, sMaxFragmentSize); }
98 :
99 4 : uint16_t GetRxFragmentSize() const { return mRxFragmentSize; }
100 4 : uint16_t GetTxFragmentSize() const { return mTxFragmentSize; }
101 :
102 : SequenceNumber_t GetAndIncrementNextTxSeqNum();
103 : SequenceNumber_t GetAndRecordRxAckSeqNum();
104 :
105 1 : inline SequenceNumber_t GetLastReceivedSequenceNumber() const { return mRxNewestUnackedSeqNum; }
106 3 : inline SequenceNumber_t GetNewestUnackedSentSequenceNumber() const { return mTxNewestUnackedSeqNum; }
107 :
108 3 : inline bool ExpectingAck() const { return mExpectingAck; }
109 :
110 17 : inline State_t RxState() { return mRxState; }
111 39 : inline State_t TxState() { return mTxState; }
112 :
113 : bool HasUnackedData() const;
114 :
115 : CHIP_ERROR HandleCharacteristicReceived(System::PacketBufferHandle && data, SequenceNumber_t & receivedAck,
116 : bool & didReceiveAck);
117 : bool HandleCharacteristicSend(System::PacketBufferHandle data, bool send_ack);
118 : CHIP_ERROR EncodeStandAloneAck(const PacketBufferHandle & data);
119 :
120 : PacketBufferHandle TakeRxPacket();
121 : PacketBufferHandle BorrowRxPacket() { return mRxBuf.Retain(); }
122 19 : void ClearRxPacket() { (void) TakeRxPacket(); }
123 : PacketBufferHandle TakeTxPacket();
124 2 : PacketBufferHandle BorrowTxPacket() { return mTxBuf.Retain(); }
125 19 : void ClearTxPacket() { (void) TakeTxPacket(); }
126 :
127 : void LogState() const;
128 : void LogStateDebug() const;
129 :
130 : private:
131 : void * mAppState;
132 :
133 : State_t mRxState;
134 : System::PacketBufferHandle mRxBuf;
135 : SequenceNumber_t mRxNextSeqNum;
136 : SequenceNumber_t mRxNewestUnackedSeqNum;
137 : SequenceNumber_t mRxOldestUnackedSeqNum;
138 : uint16_t mRxFragmentSize;
139 : uint16_t mRxLength;
140 :
141 : State_t mTxState;
142 : System::PacketBufferHandle mTxBuf;
143 : SequenceNumber_t mTxNextSeqNum;
144 : SequenceNumber_t mTxNewestUnackedSeqNum;
145 : SequenceNumber_t mTxOldestUnackedSeqNum;
146 : uint16_t mTxFragmentSize;
147 : uint16_t mTxLength;
148 :
149 : uint16_t mRxCharCount;
150 : uint16_t mRxPacketCount;
151 : uint16_t mTxCharCount;
152 : uint16_t mTxPacketCount;
153 :
154 : bool mExpectingAck;
155 :
156 : // Private functions:
157 : bool IsValidAck(SequenceNumber_t ack_num) const;
158 : CHIP_ERROR HandleAckReceived(SequenceNumber_t ack_num);
159 : };
160 :
161 : } /* namespace Ble */
162 : } /* namespace chip */
|