Matter SDK Coverage Report
Current view: top level - ble - BleLayer.cpp (source / functions) Coverage Total Hit
Test: SHA:09f6fdf93a7e847a42518c076e487f336877a722 Lines: 79.9 % 268 214
Test Date: 2025-06-07 07:10:33 Functions: 80.0 % 35 28

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

Generated by: LCOV version 2.0-1