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 __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 <lib/support/BitFlags.h> 41 : #include <system/SystemPacketBuffer.h> 42 : 43 : namespace chip { 44 : namespace Ble { 45 : 46 : inline constexpr size_t kTransferProtocolHeaderFlagsSize = 1; // Size in bytes of enocded BTP fragment header flag bits 47 : inline constexpr size_t kTransferProtocolSequenceNumSize = 1; // Size in bytes of encoded BTP sequence number 48 : inline constexpr size_t kTransferProtocolAckSize = 1; // Size in bytes of encoded BTP fragment acknowledgement number 49 : inline 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 : // Masks for BTP fragment header flag bits. 91 : enum class HeaderFlags : uint8_t 92 : { 93 : kStartMessage = 0x01, 94 : kContinueMessage = 0x02, 95 : kEndMessage = 0x04, 96 : kFragmentAck = 0x08, 97 : #if CHIP_ENABLE_CHIPOBLE_TEST 98 : kCommandMessage = 0x10, 99 : #endif 100 : }; 101 : 102 : static const uint16_t sDefaultFragmentSize; 103 : static const uint16_t sMaxFragmentSize; 104 : 105 : // Public functions: 106 : CHIP_ERROR Init(void * an_app_state, bool expect_first_ack); 107 : 108 0 : inline void SetTxFragmentSize(uint16_t size) { mTxFragmentSize = size; } 109 0 : inline void SetRxFragmentSize(uint16_t size) { mRxFragmentSize = size; } 110 : 111 0 : uint16_t GetRxFragmentSize() const { return mRxFragmentSize; } 112 0 : uint16_t GetTxFragmentSize() const { return mTxFragmentSize; } 113 : 114 : SequenceNumber_t GetAndIncrementNextTxSeqNum(); 115 : SequenceNumber_t GetAndRecordRxAckSeqNum(); 116 : 117 : inline SequenceNumber_t GetLastReceivedSequenceNumber() const { return mRxNewestUnackedSeqNum; } 118 0 : inline SequenceNumber_t GetNewestUnackedSentSequenceNumber() const { return mTxNewestUnackedSeqNum; } 119 : 120 0 : inline bool ExpectingAck() const { return mExpectingAck; } 121 : 122 0 : inline State_t RxState() { return mRxState; } 123 0 : inline State_t TxState() { return mTxState; } 124 : #if CHIP_ENABLE_CHIPOBLE_TEST 125 : inline PacketType_t SetTxPacketType(PacketType_t type) { return (mTxPacketType = type); } 126 : inline PacketType_t SetRxPacketType(PacketType_t type) { return (mRxPacketType = type); } 127 : inline PacketType_t TxPacketType() { return mTxPacketType; } 128 : inline PacketType_t RxPacketType() { return mRxPacketType; } 129 : inline SequenceNumber_t SetTxPacketSeq(SequenceNumber_t seq) { return (mTxPacketSeq = seq); } 130 : inline SequenceNumber_t SetRxPacketSeq(SequenceNumber_t seq) { return (mRxPacketSeq = seq); } 131 : inline SequenceNumber_t TxPacketSeq() { return mTxPacketSeq; } 132 : inline SequenceNumber_t RxPacketSeq() { return mRxPacketSeq; } 133 : static bool IsCommandPacket(const PacketBufferHandle & p); 134 : inline void PushPacketTag(const PacketBufferHandle & p, PacketType_t type) 135 : { 136 : p->SetStart(p->Start() - sizeof(type)); 137 : memcpy(p->Start(), &type, sizeof(type)); 138 : } 139 : inline PacketType_t PopPacketTag(const PacketBufferHandle & p) 140 : { 141 : PacketType_t type; 142 : memcpy(&type, p->Start(), sizeof(type)); 143 : p->SetStart(p->Start() + sizeof(type)); 144 : return type; 145 : } 146 : #endif // CHIP_ENABLE_CHIPOBLE_TEST 147 : 148 : bool HasUnackedData() const; 149 : 150 : CHIP_ERROR HandleCharacteristicReceived(System::PacketBufferHandle && data, SequenceNumber_t & receivedAck, 151 : bool & didReceiveAck); 152 : bool HandleCharacteristicSend(System::PacketBufferHandle data, bool send_ack); 153 : CHIP_ERROR EncodeStandAloneAck(const PacketBufferHandle & data); 154 : 155 : PacketBufferHandle TakeRxPacket(); 156 : PacketBufferHandle BorrowRxPacket() { return mRxBuf.Retain(); } 157 0 : void ClearRxPacket() { (void) TakeRxPacket(); } 158 : PacketBufferHandle TakeTxPacket(); 159 0 : PacketBufferHandle BorrowTxPacket() { return mTxBuf.Retain(); } 160 0 : void ClearTxPacket() { (void) TakeTxPacket(); } 161 : 162 : void LogState() const; 163 : void LogStateDebug() const; 164 : 165 : private: 166 : // Private data members: 167 : #if CHIP_ENABLE_CHIPOBLE_TEST 168 : PacketType_t mTxPacketType; 169 : PacketType_t mRxPacketType; 170 : SequenceNumber_t mTxPacketSeq; 171 : SequenceNumber_t mRxPacketSeq; 172 : #endif 173 : State_t mRxState; 174 : uint16_t mRxLength; 175 : void * mAppState; 176 : System::PacketBufferHandle mRxBuf; 177 : SequenceNumber_t mRxNextSeqNum; 178 : SequenceNumber_t mRxNewestUnackedSeqNum; 179 : SequenceNumber_t mRxOldestUnackedSeqNum; 180 : uint16_t mRxFragmentSize; 181 : 182 : State_t mTxState; 183 : uint16_t mTxLength; 184 : System::PacketBufferHandle mTxBuf; 185 : SequenceNumber_t mTxNextSeqNum; 186 : SequenceNumber_t mTxNewestUnackedSeqNum; 187 : SequenceNumber_t mTxOldestUnackedSeqNum; 188 : bool mExpectingAck; 189 : uint16_t mTxFragmentSize; 190 : 191 : uint16_t mRxCharCount; 192 : uint16_t mRxPacketCount; 193 : uint16_t mTxCharCount; 194 : uint16_t mTxPacketCount; 195 : 196 : // Private functions: 197 : bool IsValidAck(SequenceNumber_t ack_num) const; 198 : CHIP_ERROR HandleAckReceived(SequenceNumber_t ack_num); 199 : }; 200 : 201 : } /* namespace Ble */ 202 : } /* namespace chip */