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