Matter SDK Coverage Report
Current view: top level - ble - BleLayer.cpp (source / functions) Coverage Total Hit
Test: SHA:3640a4f95bebd68003e5aea27c711ffe4cd39423 Lines: 97.0 % 267 259
Test Date: 2025-09-15 07:12:22 Functions: 97.1 % 35 34

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020-2021 Project CHIP Authors
       4              :  *    Copyright (c) 2014-2017 Nest Labs, Inc.
       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 objects which provide an abstraction layer between
      22              :  *      a platform's Bluetooth Low Energy (BLE) implementation and the CHIP
      23              :  *      stack.
      24              :  *
      25              :  *      The BleLayer object accepts BLE data and control input from the
      26              :  *      application via a functional interface. It performs the fragmentation
      27              :  *      and reassembly required to transmit CHIP message via a BLE GATT
      28              :  *      characteristic interface, and drives incoming messages up the CHIP
      29              :  *      stack.
      30              :  *
      31              :  *      During initialization, the BleLayer object requires a pointer to the
      32              :  *      platform's implementation of the BlePlatformDelegate and
      33              :  *      BleApplicationDelegate objects.
      34              :  *
      35              :  *      The BlePlatformDelegate provides the CHIP stack with an interface
      36              :  *      by which to form and cancel GATT subscriptions, read and write
      37              :  *      GATT characteristic values, send GATT characteristic notifications,
      38              :  *      respond to GATT read requests, and close BLE connections.
      39              :  *
      40              :  *      The BleApplicationDelegate provides a mechanism for CHIP to inform
      41              :  *      the application when it has finished using a given BLE connection,
      42              :  *      i.e when the chipConnection object wrapping this connection has
      43              :  *      closed. This allows the application to either close the BLE connection
      44              :  *      or continue to keep it open for non-CHIP purposes.
      45              :  *
      46              :  *      To enable CHIP over BLE for a new platform, the application developer
      47              :  *      must provide an implementation for both delegates, provides points to
      48              :  *      instances of these delegates on startup, and ensure that the
      49              :  *      application calls the necessary BleLayer functions when appropriate to
      50              :  *      drive BLE data and control input up the stack.
      51              :  */
      52              : 
      53              : #define _CHIP_BLE_BLE_H
      54              : #include "BleLayer.h"
      55              : 
      56              : #include <cstddef>
      57              : #include <cstring>
      58              : #include <utility>
      59              : 
      60              : #include <lib/core/CHIPEncoding.h>
      61              : #include <lib/support/CodeUtils.h>
      62              : #include <lib/support/SetupDiscriminator.h>
      63              : #include <lib/support/logging/CHIPLogging.h>
      64              : #include <system/SystemLayer.h>
      65              : #include <system/SystemPacketBuffer.h>
      66              : 
      67              : #include "BLEEndPoint.h"
      68              : #include "BleApplicationDelegate.h"
      69              : #include "BleConfig.h"
      70              : #include "BleConnectionDelegate.h"
      71              : #include "BleError.h"
      72              : #include "BleLayerDelegate.h"
      73              : #include "BlePlatformDelegate.h"
      74              : #include "BleRole.h"
      75              : #include "BleUUID.h"
      76              : 
      77              : // Magic values expected in first 2 bytes of valid BLE transport capabilities request or response:
      78              : #define CAPABILITIES_MSG_CHECK_BYTE_1 0b01100101
      79              : #define CAPABILITIES_MSG_CHECK_BYTE_2 0b01101100
      80              : 
      81              : namespace chip {
      82              : namespace Ble {
      83              : 
      84              : class BleEndPointPool
      85              : {
      86              : public:
      87              :     int Size() const { return BLE_LAYER_NUM_BLE_ENDPOINTS; }
      88              : 
      89          146 :     BLEEndPoint * Get(size_t i) const
      90              :     {
      91              :         alignas(BLEEndPoint) static std::byte sStorage[sizeof(BLEEndPoint) * BLE_LAYER_NUM_BLE_ENDPOINTS];
      92          146 :         VerifyOrReturnValue(i < BLE_LAYER_NUM_BLE_ENDPOINTS, nullptr);
      93          146 :         return reinterpret_cast<BLEEndPoint *>(sStorage) + i;
      94              :     }
      95              : 
      96           33 :     BLEEndPoint * Find(BLE_CONNECTION_OBJECT c) const
      97              :     {
      98           33 :         if (c == BLE_CONNECTION_UNINITIALIZED)
      99              :         {
     100            1 :             return nullptr;
     101              :         }
     102              : 
     103           46 :         for (size_t i = 0; i < BLE_LAYER_NUM_BLE_ENDPOINTS; i++)
     104              :         {
     105           32 :             BLEEndPoint * elem = Get(i);
     106           32 :             if (elem->mBle != nullptr && elem->mConnObj == c)
     107              :             {
     108           18 :                 return elem;
     109              :             }
     110              :         }
     111              : 
     112           14 :         return nullptr;
     113              :     }
     114              : 
     115           21 :     BLEEndPoint * GetFree() const
     116              :     {
     117           23 :         for (size_t i = 0; i < BLE_LAYER_NUM_BLE_ENDPOINTS; i++)
     118              :         {
     119           21 :             BLEEndPoint * elem = Get(i);
     120           21 :             if (elem->mBle == nullptr)
     121              :             {
     122           19 :                 return elem;
     123              :             }
     124              :         }
     125            2 :         return nullptr;
     126              :     }
     127              : };
     128              : 
     129              : // EndPoint Pools
     130              : //
     131              : static BleEndPointPool sBLEEndPointPool;
     132              : 
     133              : // BleTransportCapabilitiesRequestMessage implementation:
     134              : 
     135            6 : void BleTransportCapabilitiesRequestMessage::SetSupportedProtocolVersion(uint8_t index, uint8_t version)
     136              : {
     137              :     uint8_t mask;
     138              : 
     139              :     // If even-index, store version in lower 4 bits; else, higher 4 bits.
     140            6 :     if (index % 2 == 0)
     141              :     {
     142            5 :         mask = 0x0F;
     143              :     }
     144              :     else
     145              :     {
     146            1 :         mask    = 0xF0;
     147            1 :         version = static_cast<uint8_t>(version << 4);
     148              :     }
     149              : 
     150            6 :     version &= mask;
     151              : 
     152            6 :     uint8_t & slot = mSupportedProtocolVersions[(index / 2)];
     153            6 :     slot           = static_cast<uint8_t>(slot & ~mask); // Clear version at index; leave other version in same byte alone
     154            6 :     slot |= version;
     155            6 : }
     156              : 
     157            5 : CHIP_ERROR BleTransportCapabilitiesRequestMessage::Encode(const PacketBufferHandle & msgBuf) const
     158              : {
     159            5 :     uint8_t * p = msgBuf->Start();
     160              : 
     161              :     // Verify we can write the fixed-length request without running into the end of the buffer.
     162            5 :     VerifyOrReturnError(msgBuf->MaxDataLength() >= kCapabilitiesRequestLength, CHIP_ERROR_NO_MEMORY);
     163              : 
     164            5 :     chip::Encoding::Write8(p, CAPABILITIES_MSG_CHECK_BYTE_1);
     165            5 :     chip::Encoding::Write8(p, CAPABILITIES_MSG_CHECK_BYTE_2);
     166              : 
     167           25 :     for (uint8_t version : mSupportedProtocolVersions)
     168              :     {
     169           20 :         chip::Encoding::Write8(p, version);
     170              :     }
     171              : 
     172            5 :     chip::Encoding::LittleEndian::Write16(p, mMtu);
     173            5 :     chip::Encoding::Write8(p, mWindowSize);
     174              : 
     175            5 :     msgBuf->SetDataLength(kCapabilitiesRequestLength);
     176              : 
     177            5 :     return CHIP_NO_ERROR;
     178              : }
     179              : 
     180           15 : CHIP_ERROR BleTransportCapabilitiesRequestMessage::Decode(const PacketBufferHandle & msgBuf,
     181              :                                                           BleTransportCapabilitiesRequestMessage & msg)
     182              : {
     183           15 :     const uint8_t * p = msgBuf->Start();
     184              : 
     185              :     // Verify we can read the fixed-length request without running into the end of the buffer.
     186           15 :     VerifyOrReturnError(msgBuf->DataLength() >= kCapabilitiesRequestLength, CHIP_ERROR_MESSAGE_INCOMPLETE);
     187              : 
     188           15 :     VerifyOrReturnError(CAPABILITIES_MSG_CHECK_BYTE_1 == chip::Encoding::Read8(p), BLE_ERROR_INVALID_MESSAGE);
     189           15 :     VerifyOrReturnError(CAPABILITIES_MSG_CHECK_BYTE_2 == chip::Encoding::Read8(p), BLE_ERROR_INVALID_MESSAGE);
     190              : 
     191              :     static_assert(kCapabilitiesRequestSupportedVersionsLength == sizeof(msg.mSupportedProtocolVersions),
     192              :                   "Expected capability sizes and storage must match");
     193           75 :     for (unsigned char & version : msg.mSupportedProtocolVersions)
     194              :     {
     195           60 :         version = chip::Encoding::Read8(p);
     196              :     }
     197              : 
     198           15 :     msg.mMtu        = chip::Encoding::LittleEndian::Read16(p);
     199           15 :     msg.mWindowSize = chip::Encoding::Read8(p);
     200              : 
     201           15 :     return CHIP_NO_ERROR;
     202              : }
     203              : 
     204              : // BleTransportCapabilitiesResponseMessage implementation:
     205              : 
     206           16 : CHIP_ERROR BleTransportCapabilitiesResponseMessage::Encode(const PacketBufferHandle & msgBuf) const
     207              : {
     208           16 :     uint8_t * p = msgBuf->Start();
     209              : 
     210              :     // Verify we can write the fixed-length request without running into the end of the buffer.
     211           16 :     VerifyOrReturnError(msgBuf->MaxDataLength() >= kCapabilitiesResponseLength, CHIP_ERROR_NO_MEMORY);
     212              : 
     213           16 :     chip::Encoding::Write8(p, CAPABILITIES_MSG_CHECK_BYTE_1);
     214           16 :     chip::Encoding::Write8(p, CAPABILITIES_MSG_CHECK_BYTE_2);
     215              : 
     216           16 :     chip::Encoding::Write8(p, mSelectedProtocolVersion);
     217           16 :     chip::Encoding::LittleEndian::Write16(p, mFragmentSize);
     218           16 :     chip::Encoding::Write8(p, mWindowSize);
     219              : 
     220           16 :     msgBuf->SetDataLength(kCapabilitiesResponseLength);
     221              : 
     222           16 :     return CHIP_NO_ERROR;
     223              : }
     224              : 
     225            3 : CHIP_ERROR BleTransportCapabilitiesResponseMessage::Decode(const PacketBufferHandle & msgBuf,
     226              :                                                            BleTransportCapabilitiesResponseMessage & msg)
     227              : {
     228            3 :     const uint8_t * p = msgBuf->Start();
     229              : 
     230              :     // Verify we can read the fixed-length response without running into the end of the buffer.
     231            3 :     VerifyOrReturnError(msgBuf->DataLength() >= kCapabilitiesResponseLength, CHIP_ERROR_MESSAGE_INCOMPLETE);
     232              : 
     233            3 :     VerifyOrReturnError(CAPABILITIES_MSG_CHECK_BYTE_1 == chip::Encoding::Read8(p), BLE_ERROR_INVALID_MESSAGE);
     234            3 :     VerifyOrReturnError(CAPABILITIES_MSG_CHECK_BYTE_2 == chip::Encoding::Read8(p), BLE_ERROR_INVALID_MESSAGE);
     235              : 
     236            3 :     msg.mSelectedProtocolVersion = chip::Encoding::Read8(p);
     237            3 :     msg.mFragmentSize            = chip::Encoding::LittleEndian::Read16(p);
     238            3 :     msg.mWindowSize              = chip::Encoding::Read8(p);
     239              : 
     240            3 :     return CHIP_NO_ERROR;
     241              : }
     242              : 
     243              : // BleLayer implementation:
     244              : 
     245          196 : BleLayer::BleLayer()
     246              : {
     247          196 :     mState = kState_NotInitialized;
     248          196 : }
     249              : 
     250           86 : CHIP_ERROR BleLayer::Init(BlePlatformDelegate * platformDelegate, BleConnectionDelegate * connDelegate,
     251              :                           BleApplicationDelegate * appDelegate, chip::System::Layer * systemLayer)
     252              : {
     253           86 :     Ble::RegisterLayerErrorFormatter();
     254              : 
     255              :     // It is totally valid to not have a connDelegate. In this case the client application
     256              :     // will take care of the connection steps.
     257           86 :     VerifyOrReturnError(platformDelegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     258           86 :     VerifyOrReturnError(appDelegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     259           86 :     VerifyOrReturnError(systemLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     260              : 
     261           86 :     if (mState != kState_NotInitialized)
     262              :     {
     263            0 :         return CHIP_ERROR_INCORRECT_STATE;
     264              :     }
     265              : 
     266           86 :     mConnectionDelegate  = connDelegate;
     267           86 :     mPlatformDelegate    = platformDelegate;
     268           86 :     mApplicationDelegate = appDelegate;
     269           86 :     mSystemLayer         = systemLayer;
     270              : 
     271           86 :     memset(&sBLEEndPointPool, 0, sizeof(sBLEEndPointPool));
     272              : 
     273           86 :     mState = kState_Initialized;
     274              : 
     275           86 :     return CHIP_NO_ERROR;
     276              : }
     277              : 
     278            3 : CHIP_ERROR BleLayer::Init(BlePlatformDelegate * platformDelegate, BleApplicationDelegate * appDelegate,
     279              :                           chip::System::Layer * systemLayer)
     280              : {
     281            3 :     return Init(platformDelegate, nullptr, appDelegate, systemLayer);
     282              : }
     283              : 
     284            0 : void BleLayer::IndicateBleClosing()
     285              : {
     286            0 :     mState = kState_Disconnecting;
     287            0 : }
     288              : 
     289           87 : void BleLayer::Shutdown()
     290              : {
     291           87 :     mState = kState_NotInitialized;
     292           87 :     CloseAllBleConnections();
     293           87 : }
     294              : 
     295           91 : void BleLayer::CloseAllBleConnections()
     296              : {
     297              :     // Close and free all BLE end points.
     298          182 :     for (size_t i = 0; i < BLE_LAYER_NUM_BLE_ENDPOINTS; i++)
     299              :     {
     300           91 :         BLEEndPoint * elem = sBLEEndPointPool.Get(i);
     301              : 
     302              :         // If end point was initialized, and has not since been freed...
     303           91 :         if (elem->mBle != nullptr)
     304              :         {
     305              :             // If end point hasn't already been closed...
     306           13 :             if (elem->mState != BLEEndPoint::kState_Closed)
     307              :             {
     308              :                 // Close end point such that callbacks are suppressed and pending transmissions aborted.
     309           11 :                 elem->Abort();
     310              :             }
     311              : 
     312              :             // If end point was closed, but is still waiting for GATT unsubscribe to complete, free it anyway.
     313              :             // This cancels the unsubscribe timer (plus all the end point's other timers).
     314           13 :             if (elem->IsUnsubscribePending())
     315              :             {
     316            2 :                 elem->Free();
     317              :             }
     318              :         }
     319              :     }
     320           91 : }
     321              : 
     322            2 : void BleLayer::CloseBleConnection(BLE_CONNECTION_OBJECT connObj)
     323              : {
     324              :     // Close and free all BLE endpoints.
     325            4 :     for (size_t i = 0; i < BLE_LAYER_NUM_BLE_ENDPOINTS; i++)
     326              :     {
     327            2 :         BLEEndPoint * elem = sBLEEndPointPool.Get(i);
     328              : 
     329              :         // If end point was initialized, and has not since been freed...
     330            2 :         if (elem->mBle != nullptr && elem->ConnectionObjectIs(connObj))
     331              :         {
     332              :             // If end point hasn't already been closed...
     333            1 :             if (elem->mState != BLEEndPoint::kState_Closed)
     334              :             {
     335              :                 // Close end point such that callbacks are suppressed and pending transmissions aborted.
     336            1 :                 elem->Abort();
     337              :             }
     338              : 
     339              :             // If end point was closed, but is still waiting for GATT unsubscribe to complete, free it anyway.
     340              :             // This cancels the unsubscribe timer (plus all the end point's other timers).
     341            1 :             if (elem->IsUnsubscribePending())
     342              :             {
     343            0 :                 elem->Free();
     344              :             }
     345              :         }
     346              :     }
     347            2 : }
     348              : 
     349            2 : CHIP_ERROR BleLayer::CancelBleIncompleteConnection()
     350              : {
     351            2 :     VerifyOrReturnError(mState == kState_Initialized, CHIP_ERROR_INCORRECT_STATE);
     352            1 :     VerifyOrReturnError(mConnectionDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE);
     353              : 
     354            1 :     CHIP_ERROR err = mConnectionDelegate->CancelConnection();
     355            1 :     if (err == CHIP_ERROR_NOT_IMPLEMENTED)
     356              :     {
     357            0 :         ChipLogError(Ble, "BleConnectionDelegate::CancelConnection is not implemented.");
     358              :     }
     359            1 :     return err;
     360              : }
     361              : 
     362            1 : CHIP_ERROR BleLayer::NewBleConnectionByDiscriminator(const SetupDiscriminator & connDiscriminator, void * appState,
     363              :                                                      BleConnectionDelegate::OnConnectionCompleteFunct onSuccess,
     364              :                                                      BleConnectionDelegate::OnConnectionErrorFunct onError)
     365              : {
     366            1 :     VerifyOrReturnError(mState == kState_Initialized, CHIP_ERROR_INCORRECT_STATE);
     367            1 :     VerifyOrReturnError(mConnectionDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE);
     368            1 :     VerifyOrReturnError(mBleTransport != nullptr, CHIP_ERROR_INCORRECT_STATE);
     369              : 
     370            1 :     mConnectionDelegate->OnConnectionComplete = onSuccess;
     371            1 :     mConnectionDelegate->OnConnectionError    = onError;
     372              : 
     373            1 :     mConnectionDelegate->NewConnection(this, appState == nullptr ? this : appState, connDiscriminator);
     374              : 
     375            1 :     return CHIP_NO_ERROR;
     376              : }
     377              : 
     378            1 : CHIP_ERROR BleLayer::NewBleConnectionByObject(BLE_CONNECTION_OBJECT connObj, void * appState,
     379              :                                               BleConnectionDelegate::OnConnectionCompleteFunct onSuccess,
     380              :                                               BleConnectionDelegate::OnConnectionErrorFunct onError)
     381              : {
     382            1 :     VerifyOrReturnError(mState == kState_Initialized, CHIP_ERROR_INCORRECT_STATE);
     383            1 :     VerifyOrReturnError(mConnectionDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE);
     384            1 :     VerifyOrReturnError(mBleTransport != nullptr, CHIP_ERROR_INCORRECT_STATE);
     385              : 
     386            1 :     mConnectionDelegate->OnConnectionComplete = onSuccess;
     387            1 :     mConnectionDelegate->OnConnectionError    = onError;
     388              : 
     389            1 :     mConnectionDelegate->NewConnection(this, appState == nullptr ? this : appState, connObj);
     390              : 
     391            1 :     return CHIP_NO_ERROR;
     392              : }
     393              : 
     394            2 : CHIP_ERROR BleLayer::NewBleConnectionByObject(BLE_CONNECTION_OBJECT connObj)
     395              : {
     396            2 :     VerifyOrReturnError(mState == kState_Initialized, CHIP_ERROR_INCORRECT_STATE);
     397            2 :     VerifyOrReturnError(mBleTransport != nullptr, CHIP_ERROR_INCORRECT_STATE);
     398              : 
     399            2 :     OnConnectionComplete(this, connObj);
     400              : 
     401            2 :     return CHIP_NO_ERROR;
     402              : }
     403              : 
     404            6 : CHIP_ERROR BleLayer::NewBleConnectionByDiscriminators(const Span<const SetupDiscriminator> & discriminators, void * appState,
     405              :                                                       BleConnectionDelegate::OnConnectionByDiscriminatorsCompleteFunct onSuccess,
     406              :                                                       BleConnectionDelegate::OnConnectionErrorFunct onError)
     407              : {
     408            6 :     VerifyOrReturnError(mState == kState_Initialized, CHIP_ERROR_INCORRECT_STATE);
     409            5 :     VerifyOrReturnError(mConnectionDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE);
     410            4 :     VerifyOrReturnError(mBleTransport != nullptr, CHIP_ERROR_INCORRECT_STATE);
     411              : 
     412            3 :     return mConnectionDelegate->NewConnection(this, appState, discriminators, onSuccess, onError);
     413              : }
     414              : 
     415           22 : CHIP_ERROR BleLayer::NewBleEndPoint(BLEEndPoint ** retEndPoint, BLE_CONNECTION_OBJECT connObj, BleRole role, bool autoClose)
     416              : {
     417           22 :     if (mState != kState_Initialized)
     418              :     {
     419            0 :         return CHIP_ERROR_INCORRECT_STATE;
     420              :     }
     421              : 
     422           22 :     if (connObj == BLE_CONNECTION_UNINITIALIZED)
     423              :     {
     424            1 :         return CHIP_ERROR_INVALID_ARGUMENT;
     425              :     }
     426              : 
     427           21 :     auto endPoint = sBLEEndPointPool.GetFree();
     428           21 :     if (endPoint == nullptr)
     429              :     {
     430            2 :         ChipLogError(Ble, "%s endpoint pool FULL", "Ble");
     431            2 :         return CHIP_ERROR_ENDPOINT_POOL_FULL;
     432              :     }
     433              : 
     434           19 :     endPoint->Init(this, connObj, role, autoClose);
     435           19 :     endPoint->mBleTransport = mBleTransport;
     436              : 
     437           19 :     *retEndPoint = endPoint;
     438           19 :     return CHIP_NO_ERROR;
     439              : }
     440              : 
     441              : // Handle remote central's initiation of CHIP over BLE protocol handshake.
     442           15 : CHIP_ERROR BleLayer::HandleBleTransportConnectionInitiated(BLE_CONNECTION_OBJECT connObj, PacketBufferHandle && pBuf)
     443              : {
     444           15 :     CHIP_ERROR err            = CHIP_NO_ERROR;
     445           15 :     BLEEndPoint * newEndPoint = nullptr;
     446              : 
     447              :     // Only BLE peripherals can receive GATT writes, so specify this role in our creation of the BLEEndPoint.
     448              :     // Set autoClose = false. Peripherals only notify the application when an end point releases a BLE connection.
     449           15 :     err = NewBleEndPoint(&newEndPoint, connObj, kBleRole_Peripheral, false);
     450           15 :     SuccessOrExit(err);
     451              : 
     452           13 :     newEndPoint->mBleTransport = mBleTransport;
     453              : 
     454           13 :     err = newEndPoint->Receive(std::move(pBuf));
     455           13 :     SuccessOrExit(err); // If we fail here, end point will have already released connection and freed itself.
     456              : 
     457           15 : exit:
     458              :     // If we failed to allocate a new end point, release underlying BLE connection. Central's handshake will time out
     459              :     // if the application decides to keep the BLE connection open.
     460           15 :     if (newEndPoint == nullptr)
     461              :     {
     462            2 :         mApplicationDelegate->NotifyChipConnectionClosed(connObj);
     463              :     }
     464              : 
     465           15 :     if (err != CHIP_NO_ERROR)
     466              :     {
     467            2 :         ChipLogError(Ble, "HandleChipConnectionReceived failed, err = %" CHIP_ERROR_FORMAT, err.Format());
     468              :     }
     469              : 
     470           15 :     return err;
     471              : }
     472              : 
     473           18 : bool BleLayer::HandleWriteReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId,
     474              :                                    PacketBufferHandle && pBuf)
     475              : {
     476           18 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Write received on unknown svc"));
     477           17 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_1_UUID, charId), false, ChipLogError(Ble, "Write received on unknown char"));
     478           16 :     VerifyOrReturnError(!pBuf.IsNull(), false, ChipLogError(Ble, "Write received null buffer"));
     479              : 
     480              :     // Find matching connection end point.
     481           16 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     482              : 
     483           16 :     if (endPoint != nullptr)
     484              :     {
     485            1 :         CHIP_ERROR err = endPoint->Receive(std::move(pBuf));
     486            1 :         VerifyOrReturnError(err == CHIP_NO_ERROR, false,
     487              :                             ChipLogError(Ble, "Receive failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
     488              :     }
     489              :     else
     490              :     {
     491           15 :         CHIP_ERROR err = HandleBleTransportConnectionInitiated(connObj, std::move(pBuf));
     492           15 :         VerifyOrReturnError(err == CHIP_NO_ERROR, false,
     493              :                             ChipLogError(Ble, "Handle new BLE connection failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
     494              :     }
     495              : 
     496           14 :     return true;
     497              : }
     498              : 
     499            3 : bool BleLayer::HandleIndicationReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId,
     500              :                                         PacketBufferHandle && pBuf)
     501              : {
     502            3 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Indication received on unknown svc"));
     503            2 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId), false, ChipLogError(Ble, "Indication received on unknown char"));
     504            1 :     VerifyOrReturnError(!pBuf.IsNull(), false, ChipLogError(Ble, "Indication received null buffer"));
     505              : 
     506              :     // Find matching connection end point.
     507            1 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     508            1 :     VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for received indication"));
     509              : 
     510            1 :     CHIP_ERROR err = endPoint->Receive(std::move(pBuf));
     511            1 :     VerifyOrReturnError(err == CHIP_NO_ERROR, false, ChipLogError(Ble, "Receive failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
     512              : 
     513            1 :     return true;
     514              : }
     515              : 
     516            5 : bool BleLayer::HandleWriteConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
     517              : {
     518            5 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Write confirmation on unknown svc"));
     519            4 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_1_UUID, charId), false, ChipLogError(Ble, "Write confirmation on unknown char"));
     520              : 
     521            3 :     HandleAckReceived(connObj);
     522            3 :     return true;
     523              : }
     524              : 
     525            3 : bool BleLayer::HandleIndicationConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
     526              : {
     527            3 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Indication confirmation on unknown svc"));
     528            2 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId), false,
     529              :                         ChipLogError(Ble, "Indication confirmation on unknown char"));
     530              : 
     531            1 :     HandleAckReceived(connObj);
     532            1 :     return true;
     533              : }
     534              : 
     535            4 : void BleLayer::HandleAckReceived(BLE_CONNECTION_OBJECT connObj)
     536              : {
     537              :     // Find matching connection end point.
     538            4 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     539            4 :     VerifyOrReturn(endPoint != nullptr, ChipLogDetail(Ble, "No endpoint for received ack"));
     540              : 
     541            4 :     CHIP_ERROR err = endPoint->HandleGattSendConfirmationReceived();
     542            4 :     VerifyOrReturn(err == CHIP_NO_ERROR,
     543              :                    ChipLogError(Ble, "Send ack confirmation failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
     544              : }
     545              : 
     546            8 : bool BleLayer::HandleSubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
     547              : {
     548            8 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Subscribe received on unknown svc"));
     549            7 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_UUID, charId), false,
     550              :                         ChipLogError(Ble, "Subscribe received on unknown char"));
     551              : 
     552              :     // Find end point already associated with BLE connection, if any.
     553            6 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     554            6 :     VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for received subscribe"));
     555              : 
     556            6 :     endPoint->HandleSubscribeReceived();
     557            6 :     return true;
     558              : }
     559              : 
     560            5 : bool BleLayer::HandleSubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
     561              : {
     562            5 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Subscribe complete on unknown svc"));
     563            4 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_UUID, charId), false,
     564              :                         ChipLogError(Ble, "Subscribe complete on unknown char"));
     565              : 
     566            3 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     567            3 :     VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for subscribe complete"));
     568              : 
     569            3 :     endPoint->HandleSubscribeComplete();
     570            3 :     return true;
     571              : }
     572              : 
     573            3 : bool BleLayer::HandleUnsubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
     574              : {
     575            3 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Unsubscribe received on unknown svc"));
     576            2 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_UUID, charId), false,
     577              :                         ChipLogError(Ble, "Unsubscribe received on unknown char"));
     578              : 
     579              :     // Find end point already associated with BLE connection, if any.
     580            1 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     581            1 :     VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for unsubscribe received"));
     582              : 
     583            1 :     endPoint->DoClose(kBleCloseFlag_AbortTransmission, BLE_ERROR_CENTRAL_UNSUBSCRIBED);
     584            1 :     return true;
     585              : }
     586              : 
     587            3 : bool BleLayer::HandleUnsubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
     588              : {
     589            3 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Unsubscribe complete on unknown svc"));
     590            2 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_UUID, charId), false,
     591              :                         ChipLogError(Ble, "Unsubscribe complete on unknown char"));
     592              : 
     593              :     // Find end point already associated with BLE connection, if any.
     594            1 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     595            1 :     VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for unsubscribe complete"));
     596              : 
     597            1 :     endPoint->HandleUnsubscribeComplete();
     598            1 :     return true;
     599              : }
     600              : 
     601            1 : void BleLayer::HandleConnectionError(BLE_CONNECTION_OBJECT connObj, CHIP_ERROR err)
     602              : {
     603              :     // BLE connection has failed somehow, we must find and abort matching connection end point.
     604            1 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     605            1 :     VerifyOrReturn(endPoint != nullptr, ChipLogDetail(Ble, "No endpoint for connection error"));
     606              : 
     607            1 :     if (err == BLE_ERROR_GATT_UNSUBSCRIBE_FAILED && endPoint->IsUnsubscribePending())
     608              :     {
     609              :         // If end point was already closed and just waiting for unsubscribe to complete, free it. Call to Free()
     610              :         // stops unsubscribe timer.
     611            0 :         endPoint->Free();
     612              :     }
     613              :     else
     614              :     {
     615            1 :         endPoint->DoClose(kBleCloseFlag_AbortTransmission, err);
     616              :     }
     617              : }
     618              : 
     619           13 : BleTransportProtocolVersion BleLayer::GetHighestSupportedProtocolVersion(const BleTransportCapabilitiesRequestMessage & reqMsg)
     620              : {
     621           13 :     BleTransportProtocolVersion retVersion = kBleTransportProtocolVersion_None;
     622              : 
     623           13 :     uint8_t shift_width = 4;
     624              : 
     625           39 :     for (int i = 0; i < NUM_SUPPORTED_PROTOCOL_VERSIONS; i++)
     626              :     {
     627           39 :         shift_width ^= 4;
     628              : 
     629           39 :         uint8_t version = reqMsg.mSupportedProtocolVersions[(i / 2)];
     630           39 :         version         = static_cast<uint8_t>((version >> shift_width) & 0x0F); // Grab just the nibble we want.
     631              : 
     632           39 :         if ((version >= CHIP_BLE_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION) &&
     633           13 :             (version <= CHIP_BLE_TRANSPORT_PROTOCOL_MAX_SUPPORTED_VERSION) && (version > retVersion))
     634              :         {
     635           13 :             retVersion = static_cast<BleTransportProtocolVersion>(version);
     636              :         }
     637           26 :         else if (version == kBleTransportProtocolVersion_None) // Signifies end of supported versions list
     638              :         {
     639           13 :             break;
     640              :         }
     641              :     }
     642              : 
     643           13 :     return retVersion;
     644              : }
     645              : 
     646            3 : void BleLayer::OnConnectionComplete(void * appState, BLE_CONNECTION_OBJECT connObj)
     647              : {
     648            3 :     BleLayer * layer       = reinterpret_cast<BleLayer *>(appState);
     649            3 :     BLEEndPoint * endPoint = nullptr;
     650            3 :     CHIP_ERROR err         = CHIP_NO_ERROR;
     651              : 
     652            3 :     SuccessOrExit(err = layer->NewBleEndPoint(&endPoint, connObj, kBleRole_Central, true));
     653            2 :     layer->mBleTransport->OnBleConnectionComplete(endPoint);
     654              : 
     655            3 : exit:
     656            3 :     if (err != CHIP_NO_ERROR)
     657              :     {
     658            1 :         OnConnectionError(layer, err);
     659              :     }
     660            3 : }
     661              : 
     662            3 : void BleLayer::OnConnectionError(void * appState, CHIP_ERROR err)
     663              : {
     664            3 :     BleLayer * layer = reinterpret_cast<BleLayer *>(appState);
     665            3 :     layer->mBleTransport->OnBleConnectionError(err);
     666            3 : }
     667              : 
     668              : } /* namespace Ble */
     669              : } /* namespace chip */
        

Generated by: LCOV version 2.0-1