Line data Source code
1 : /* 2 : * 3 : * Copyright (c) 2020-2021 Project CHIP Authors 4 : * All rights reserved. 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 implements the CHIP Connection object that maintains a BLE connection. 22 : * 23 : */ 24 : 25 : #include <transport/raw/BLE.h> 26 : 27 : #include <lib/support/CodeUtils.h> 28 : #include <lib/support/logging/CHIPLogging.h> 29 : #include <transport/raw/MessageHeader.h> 30 : 31 : #include <inttypes.h> 32 : 33 : using namespace chip::Ble; 34 : using namespace chip::System; 35 : 36 : namespace chip { 37 : namespace Transport { 38 : 39 1 : BLEBase::~BLEBase() 40 : { 41 1 : ClearState(); 42 1 : } 43 : 44 1 : void BLEBase::ClearState() 45 : { 46 1 : if (mBleLayer) 47 : { 48 1 : mBleLayer->CancelBleIncompleteConnection(); 49 1 : mBleLayer->OnChipBleConnectReceived = nullptr; 50 1 : mBleLayer->mBleTransport = nullptr; 51 1 : mBleLayer = nullptr; 52 : } 53 : 54 1 : if (mBleEndPoint) 55 : { 56 0 : mBleEndPoint->Close(); 57 0 : mBleEndPoint = nullptr; 58 : } 59 : 60 1 : mState = State::kNotReady; 61 1 : } 62 : 63 1 : CHIP_ERROR BLEBase::Init(const BleListenParameters & param) 64 : { 65 1 : BleLayer * bleLayer = param.GetBleLayer(); 66 : 67 1 : VerifyOrReturnError(mState == State::kNotReady, CHIP_ERROR_INCORRECT_STATE); 68 1 : VerifyOrReturnError(bleLayer != nullptr, CHIP_ERROR_INCORRECT_STATE); 69 : 70 1 : mBleLayer = bleLayer; 71 1 : if (mBleLayer->mBleTransport == nullptr || !param.PreserveExistingBleLayerTransport()) 72 : { 73 1 : mBleLayer->mBleTransport = this; 74 1 : ChipLogDetail(Inet, "BLEBase::Init - setting/overriding transport"); 75 : } 76 : else 77 : { 78 0 : ChipLogDetail(Inet, "BLEBase::Init - not overriding transport"); 79 : } 80 1 : mBleLayer->OnChipBleConnectReceived = nullptr; 81 : 82 1 : mState = State::kInitialized; 83 : 84 1 : return CHIP_NO_ERROR; 85 : } 86 : 87 0 : CHIP_ERROR BLEBase::SetEndPoint(Ble::BLEEndPoint * endPoint) 88 : { 89 0 : VerifyOrReturnError(endPoint->mState == BLEEndPoint::kState_Connected, CHIP_ERROR_INVALID_ARGUMENT); 90 : 91 0 : mBleEndPoint = endPoint; 92 : 93 : // Manually trigger the OnConnectComplete callback. 94 0 : OnEndPointConnectComplete(endPoint, CHIP_NO_ERROR); 95 : 96 0 : return CHIP_NO_ERROR; 97 : } 98 : 99 0 : CHIP_ERROR BLEBase::SendMessage(const Transport::PeerAddress & address, System::PacketBufferHandle && msgBuf) 100 : { 101 0 : ReturnErrorCodeIf(address.GetTransportType() != Type::kBle, CHIP_ERROR_INVALID_ARGUMENT); 102 0 : ReturnErrorCodeIf(mBleEndPoint == nullptr, CHIP_ERROR_INCORRECT_STATE); 103 0 : ReturnErrorCodeIf(mState == State::kNotReady, CHIP_ERROR_INCORRECT_STATE); 104 : 105 0 : if (mState == State::kConnected) 106 : { 107 0 : ReturnErrorOnFailure(mBleEndPoint->Send(std::move(msgBuf))); 108 : } 109 : else 110 : { 111 0 : ReturnErrorOnFailure(SendAfterConnect(std::move(msgBuf))); 112 : } 113 : 114 0 : return CHIP_NO_ERROR; 115 : } 116 : 117 0 : CHIP_ERROR BLEBase::SendAfterConnect(System::PacketBufferHandle && msg) 118 : { 119 0 : CHIP_ERROR err = CHIP_ERROR_NO_MEMORY; 120 : 121 0 : for (size_t i = 0; i < mPendingPacketsSize; i++) 122 : { 123 0 : if (mPendingPackets[i].IsNull()) 124 : { 125 0 : ChipLogDetail(Inet, "Message appended to BLE send queue"); 126 0 : mPendingPackets[i] = std::move(msg); 127 0 : err = CHIP_NO_ERROR; 128 0 : break; 129 : } 130 : } 131 : 132 0 : return err; 133 : } 134 : 135 0 : void BLEBase::OnBleConnectionComplete(Ble::BLEEndPoint * endPoint) 136 : { 137 0 : CHIP_ERROR err = CHIP_NO_ERROR; 138 0 : ChipLogDetail(Inet, "BleConnectionComplete: endPoint %p", endPoint); 139 : 140 0 : mBleEndPoint = endPoint; 141 : 142 : // Initiate CHIP over BLE protocol connection. 143 0 : err = mBleEndPoint->StartConnect(); 144 0 : SuccessOrExit(err); 145 : 146 0 : exit: 147 0 : if (err != CHIP_NO_ERROR) 148 : { 149 0 : if (mBleEndPoint != nullptr) 150 : { 151 0 : mBleEndPoint->Close(); 152 0 : mBleEndPoint = nullptr; 153 : } 154 0 : ChipLogError(Inet, "Failed to setup BLE endPoint: %" CHIP_ERROR_FORMAT, err.Format()); 155 : } 156 0 : } 157 : 158 0 : void BLEBase::OnBleConnectionError(CHIP_ERROR err) 159 : { 160 0 : ClearPendingPackets(); 161 0 : ChipLogDetail(Inet, "BleConnection Error: %" CHIP_ERROR_FORMAT, err.Format()); 162 0 : } 163 : 164 0 : void BLEBase::OnEndPointMessageReceived(BLEEndPoint * endPoint, PacketBufferHandle && buffer) 165 : { 166 0 : HandleMessageReceived(Transport::PeerAddress(Transport::Type::kBle), std::move(buffer)); 167 0 : } 168 : 169 0 : void BLEBase::OnEndPointConnectComplete(BLEEndPoint * endPoint, CHIP_ERROR err) 170 : { 171 0 : mState = State::kConnected; 172 : 173 0 : if (err != CHIP_NO_ERROR) 174 : { 175 0 : ChipLogError(Inet, "Failed to establish BLE connection: %" CHIP_ERROR_FORMAT, err.Format()); 176 0 : OnEndPointConnectionClosed(endPoint, err); 177 0 : return; 178 : } 179 : 180 0 : for (size_t i = 0; i < mPendingPacketsSize; i++) 181 : { 182 0 : if (!mPendingPackets[i].IsNull()) 183 : { 184 0 : err = endPoint->Send(std::move(mPendingPackets[i])); 185 0 : if (err != CHIP_NO_ERROR) 186 : { 187 0 : ChipLogError(Inet, "Deferred sending failed: %" CHIP_ERROR_FORMAT, err.Format()); 188 : } 189 : } 190 : } 191 0 : ChipLogDetail(Inet, "BLE EndPoint %p Connection Complete", endPoint); 192 : } 193 : 194 0 : void BLEBase::OnEndPointConnectionClosed(BLEEndPoint * endPoint, CHIP_ERROR err) 195 : { 196 0 : mState = State::kInitialized; 197 0 : mBleEndPoint = nullptr; 198 0 : ClearPendingPackets(); 199 0 : } 200 : 201 0 : void BLEBase::ClearPendingPackets() 202 : { 203 0 : ChipLogDetail(Inet, "Clearing BLE pending packets."); 204 0 : for (size_t i = 0; i < mPendingPacketsSize; i++) 205 : { 206 0 : mPendingPackets[i] = nullptr; 207 : } 208 0 : } 209 : 210 : } // namespace Transport 211 : } // namespace chip