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