| /* |
| * |
| * Copyright (c) 2020 Project CHIP Authors |
| * Copyright (c) 2014-2017 Nest Labs, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /** |
| * @file |
| * This file defines types and an object for the chip over |
| * Bluetooth Low Energy (CHIPoBLE) byte-stream, connection-oriented |
| * adaptation of chip for point-to-point Bluetooth Low Energy |
| * (BLE) links. |
| * |
| */ |
| |
| #ifndef BTP_ENGINE_H_ |
| #define BTP_ENGINE_H_ |
| |
| #ifndef __STDC_LIMIT_MACROS |
| #define __STDC_LIMIT_MACROS |
| #endif |
| |
| #include <stdint.h> |
| #include <string.h> |
| |
| #include <ble/BleConfig.h> |
| |
| #include <ble/BleError.h> |
| #include <support/BitFlags.h> |
| #include <system/SystemPacketBuffer.h> |
| |
| namespace chip { |
| namespace Ble { |
| |
| using ::chip::System::PacketBuffer; |
| |
| typedef uint8_t SequenceNumber_t; // If type changed from uint8_t, adjust assumptions in BtpEngine::IsValidAck and |
| // BLEEndPoint::AdjustReceiveWindow. |
| |
| #if CHIP_ENABLE_CHIPOBLE_TEST |
| class BLEEndPoint; |
| #endif |
| |
| // Public data members: |
| typedef enum |
| { |
| kType_Data = 0, // Default 0 for data |
| kType_Control = 1, |
| } PacketType_t; // BTP packet types |
| |
| class BtpEngine |
| { |
| #if CHIP_ENABLE_CHIPOBLE_TEST |
| friend class BLEEndPoint; |
| #endif |
| |
| public: |
| // Public data members: |
| typedef enum |
| { |
| kState_Idle = 0, |
| kState_InProgress = 1, |
| kState_Complete = 2, |
| kState_Error = 3 |
| } State_t; // [READ-ONLY] Current state |
| |
| enum |
| { |
| kHeaderFlag_StartMessage = 0x01, |
| kHeaderFlag_ContinueMessage = 0x02, |
| kHeaderFlag_EndMessage = 0x04, |
| kHeaderFlag_FragmentAck = 0x08, |
| #if CHIP_ENABLE_CHIPOBLE_TEST |
| kHeaderFlag_CommandMessage = 0x10, |
| #endif |
| }; // Masks for BTP fragment header flag bits. |
| |
| static const uint16_t sDefaultFragmentSize; |
| static const uint16_t sMaxFragmentSize; |
| |
| // Public functions: |
| BLE_ERROR Init(void * an_app_state, bool expect_first_ack); |
| |
| inline void SetTxFragmentSize(uint8_t size) { mTxFragmentSize = size; } |
| inline void SetRxFragmentSize(uint8_t size) { mRxFragmentSize = size; } |
| |
| uint16_t GetRxFragmentSize() { return mRxFragmentSize; } |
| uint16_t GetTxFragmentSize() { return mTxFragmentSize; } |
| |
| SequenceNumber_t GetAndIncrementNextTxSeqNum(); |
| SequenceNumber_t GetAndRecordRxAckSeqNum(); |
| |
| inline SequenceNumber_t GetLastReceivedSequenceNumber() { return mRxNewestUnackedSeqNum; } |
| inline SequenceNumber_t GetNewestUnackedSentSequenceNumber() { return mTxNewestUnackedSeqNum; } |
| |
| inline bool ExpectingAck() const { return mExpectingAck; } |
| |
| inline State_t RxState() { return mRxState; } |
| inline State_t TxState() { return mTxState; } |
| #if CHIP_ENABLE_CHIPOBLE_TEST |
| inline PacketType_t SetTxPacketType(PacketType_t type) { return (mTxPacketType = type); } |
| inline PacketType_t SetRxPacketType(PacketType_t type) { return (mRxPacketType = type); } |
| inline PacketType_t TxPacketType() { return mTxPacketType; } |
| inline PacketType_t RxPacketType() { return mRxPacketType; } |
| inline SequenceNumber_t SetTxPacketSeq(SequenceNumber_t seq) { return (mTxPacketSeq = seq); } |
| inline SequenceNumber_t SetRxPacketSeq(SequenceNumber_t seq) { return (mRxPacketSeq = seq); } |
| inline SequenceNumber_t TxPacketSeq() { return mTxPacketSeq; } |
| inline SequenceNumber_t RxPacketSeq() { return mRxPacketSeq; } |
| inline bool IsCommandPacket(PacketBuffer * p) { return GetFlag(*(p->Start()), kHeaderFlag_CommandMessage); } |
| inline void PushPacketTag(PacketBuffer * p, PacketType_t type) |
| { |
| p->SetStart(p->Start() - sizeof(type)); |
| memcpy(p->Start(), &type, sizeof(type)); |
| } |
| inline PacketType_t PopPacketTag(PacketBuffer * p) |
| { |
| PacketType_t type; |
| memcpy(&type, p->Start(), sizeof(type)); |
| p->SetStart(p->Start() + sizeof(type)); |
| return type; |
| } |
| #endif // CHIP_ENABLE_CHIPOBLE_TEST |
| |
| bool HasUnackedData() const; |
| |
| BLE_ERROR HandleCharacteristicReceived(PacketBuffer * data, SequenceNumber_t & receivedAck, bool & didReceiveAck); |
| bool HandleCharacteristicSend(PacketBuffer * data, bool send_ack); |
| BLE_ERROR EncodeStandAloneAck(PacketBuffer * data); |
| |
| PacketBuffer * RxPacket(); |
| PacketBuffer * TxPacket(); |
| |
| bool ClearRxPacket(); |
| bool ClearTxPacket(); |
| |
| void LogState() const; |
| void LogStateDebug() const; |
| |
| private: |
| // Private data members: |
| #if CHIP_ENABLE_CHIPOBLE_TEST |
| PacketType_t mTxPacketType; |
| PacketType_t mRxPacketType; |
| SequenceNumber_t mTxPacketSeq; |
| SequenceNumber_t mRxPacketSeq; |
| #endif |
| State_t mRxState; |
| uint16_t mRxLength; |
| void * mAppState; |
| PacketBuffer * mRxBuf; |
| SequenceNumber_t mRxNextSeqNum; |
| SequenceNumber_t mRxNewestUnackedSeqNum; |
| SequenceNumber_t mRxOldestUnackedSeqNum; |
| uint16_t mRxFragmentSize; |
| |
| State_t mTxState; |
| uint16_t mTxLength; |
| PacketBuffer * mTxBuf; |
| SequenceNumber_t mTxNextSeqNum; |
| SequenceNumber_t mTxNewestUnackedSeqNum; |
| SequenceNumber_t mTxOldestUnackedSeqNum; |
| bool mExpectingAck; |
| uint16_t mTxFragmentSize; |
| |
| uint16_t mRxCharCount; |
| uint16_t mRxPacketCount; |
| uint16_t mTxCharCount; |
| uint16_t mTxPacketCount; |
| |
| // Private functions: |
| bool IsValidAck(SequenceNumber_t ack_num) const; |
| BLE_ERROR HandleAckReceived(SequenceNumber_t ack_num); |
| }; |
| |
| } /* namespace Ble */ |
| } /* namespace chip */ |
| |
| #endif /* BTP_ENGINE_H_ */ |