3 * Copyright (c) 2020 Project CHIP Authors
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * This file implements the CHIP Connection object that maintains a BLE connection.
25 #include <transport/BLE.h>
27 #include <support/CodeUtils.h>
28 #include <support/logging/CHIPLogging.h>
29 #include <transport/raw/MessageHeader.h>
33 using namespace chip::Ble;
34 using namespace chip::System;
44 void BLE::ClearState()
48 mBleLayer->CancelBleIncompleteConnection();
49 mBleLayer->OnChipBleConnectReceived = nullptr;
55 mBleEndPoint->Close();
56 mBleEndPoint = nullptr;
60 CHIP_ERROR BLE::Init(RendezvousSessionDelegate * delegate, const RendezvousParameters & params)
62 CHIP_ERROR err = CHIP_NO_ERROR;
63 BleLayer * bleLayer = params.GetBleLayer();
65 VerifyOrExit(mState == State::kNotReady, err = CHIP_ERROR_INCORRECT_STATE);
66 VerifyOrExit(bleLayer, err = CHIP_ERROR_INCORRECT_STATE);
71 mBleLayer->mAppState = reinterpret_cast<void *>(this);
72 mBleLayer->OnChipBleConnectReceived = OnNewConnection;
74 if (params.HasDiscriminator())
76 err = mBleLayer->NewBleConnection(reinterpret_cast<void *>(this), params.GetDiscriminator(), OnBleConnectionComplete,
77 OnBleConnectionError);
79 else if (params.HasConnectionObject())
81 err = InitInternal(params.GetConnectionObject());
89 CHIP_ERROR BLE::InitInternal(BLE_CONNECTION_OBJECT connObj)
91 CHIP_ERROR err = CHIP_NO_ERROR;
93 err = mBleLayer->NewBleEndPoint(&mBleEndPoint, connObj, kBleRole_Central, true);
96 // Initiate CHIP over BLE protocol connection.
97 SetupEvents(mBleEndPoint);
98 err = mBleEndPoint->StartConnect();
102 if (err != CHIP_NO_ERROR)
109 CHIP_ERROR BLE::SetEndPoint(Ble::BLEEndPoint * endPoint)
111 CHIP_ERROR err = CHIP_NO_ERROR;
113 VerifyOrExit(endPoint->mState == BLEEndPoint::kState_Connected, err = CHIP_ERROR_INVALID_ARGUMENT);
115 mBleEndPoint = endPoint;
116 SetupEvents(mBleEndPoint);
118 // Manually trigger the OnConnectComplete callback.
119 OnBleEndPointConnectionComplete(endPoint, err);
125 void BLE::SetupEvents(Ble::BLEEndPoint * endPoint)
127 endPoint->mAppState = reinterpret_cast<void *>(this);
128 endPoint->OnMessageReceived = OnBleEndPointReceive;
129 endPoint->OnConnectComplete = OnBleEndPointConnectionComplete;
130 endPoint->OnConnectionClosed = OnBleEndPointConnectionClosed;
133 CHIP_ERROR BLE::SendMessage(const PacketHeader & header, const Transport::PeerAddress & address, System::PacketBufferHandle msgBuf)
135 CHIP_ERROR err = CHIP_NO_ERROR;
137 VerifyOrExit(address.GetTransportType() == Type::kBle, err = CHIP_ERROR_INVALID_ARGUMENT);
138 VerifyOrExit(mState == State::kInitialized, err = CHIP_ERROR_INCORRECT_STATE);
139 VerifyOrExit(mBleEndPoint != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
141 err = header.EncodeBeforeData(msgBuf);
144 err = mBleEndPoint->Send(std::move(msgBuf));
151 void BLE::OnBleConnectionComplete(void * appState, BLE_CONNECTION_OBJECT connObj)
153 CHIP_ERROR err = CHIP_NO_ERROR;
154 BLE * ble = reinterpret_cast<BLE *>(appState);
156 // TODO(#4547): On darwin, OnBleConnectionComplete is called multiple times for the same peripheral, this should become an error
158 VerifyOrExit(ble->mBleEndPoint == nullptr || !ble->mBleEndPoint->ConnectionObjectIs(connObj),
159 ChipLogError(Ble, "Warning: OnBleConnectionComplete is called multiple times for the same peripheral."));
161 err = ble->InitInternal(connObj);
165 if (err != CHIP_NO_ERROR)
167 ble->OnBleConnectionError(appState, err);
171 void BLE::OnBleConnectionError(void * appState, BLE_ERROR err)
173 BLE * ble = reinterpret_cast<BLE *>(appState);
177 ble->mDelegate->OnRendezvousError(err);
181 void BLE::OnBleEndPointReceive(BLEEndPoint * endPoint, PacketBufferHandle buffer)
183 BLE * ble = reinterpret_cast<BLE *>(endPoint->mAppState);
184 CHIP_ERROR err = CHIP_NO_ERROR;
189 err = header.DecodeAndConsume(buffer);
192 ble->mDelegate->OnRendezvousMessageReceived(header, Transport::PeerAddress(Transport::Type::kBle), std::move(buffer));
195 if (err != CHIP_NO_ERROR)
197 ChipLogError(Inet, "Failed to receive BLE message: %s", ErrorStr(err));
201 void BLE::OnBleEndPointConnectionComplete(BLEEndPoint * endPoint, BLE_ERROR err)
203 BLE * ble = reinterpret_cast<BLE *>(endPoint->mAppState);
204 ble->mState = State::kInitialized;
208 if (err != BLE_NO_ERROR)
210 ble->mDelegate->OnRendezvousError(err);
214 ble->mDelegate->OnRendezvousConnectionOpened();
219 void BLE::OnBleEndPointConnectionClosed(BLEEndPoint * endPoint, BLE_ERROR err)
221 BLE * ble = reinterpret_cast<BLE *>(endPoint->mAppState);
222 ble->mState = State::kNotReady;
224 // Already closed, avoid closing again in our destructor.
225 ble->mBleEndPoint = nullptr;
229 if (err != BLE_NO_ERROR)
231 ble->mDelegate->OnRendezvousError(err);
235 // OnRendezvousError may delete |ble|; don't call both callbacks.
236 ble->mDelegate->OnRendezvousConnectionClosed();
241 void BLE::OnNewConnection(BLEEndPoint * endPoint)
243 BLE * ble = reinterpret_cast<BLE *>(endPoint->mAppState);
244 CHIP_ERROR err = ble->SetEndPoint(endPoint);
245 if (err != CHIP_NO_ERROR)
247 ChipLogError(Ble, "Transport::BLE Init failure: %s", ErrorStr(err));
251 } // namespace Transport