Matter SDK Coverage Report
Current view: top level - ble - BleLayer.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 81.4 % 263 214
Test Date: 2025-01-17 19:00:11 Functions: 82.4 % 34 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          113 :     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          113 :         if (i < BLE_LAYER_NUM_BLE_ENDPOINTS)
      97              :         {
      98          113 :             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          131 : BleLayer::BleLayer()
     254              : {
     255          131 :     mState = kState_NotInitialized;
     256          131 : }
     257              : 
     258           67 : CHIP_ERROR BleLayer::Init(BlePlatformDelegate * platformDelegate, BleConnectionDelegate * connDelegate,
     259              :                           BleApplicationDelegate * appDelegate, chip::System::Layer * systemLayer)
     260              : {
     261           67 :     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           67 :     VerifyOrReturnError(platformDelegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     266           67 :     VerifyOrReturnError(appDelegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     267           67 :     VerifyOrReturnError(systemLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     268              : 
     269           67 :     if (mState != kState_NotInitialized)
     270              :     {
     271            0 :         return CHIP_ERROR_INCORRECT_STATE;
     272              :     }
     273              : 
     274           67 :     mConnectionDelegate  = connDelegate;
     275           67 :     mPlatformDelegate    = platformDelegate;
     276           67 :     mApplicationDelegate = appDelegate;
     277           67 :     mSystemLayer         = systemLayer;
     278              : 
     279           67 :     memset(&sBLEEndPointPool, 0, sizeof(sBLEEndPointPool));
     280              : 
     281           67 :     mState = kState_Initialized;
     282              : 
     283           67 :     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           67 : void BleLayer::Shutdown()
     298              : {
     299           67 :     mState = kState_NotInitialized;
     300           67 :     CloseAllBleConnections();
     301           67 : }
     302              : 
     303           71 : void BleLayer::CloseAllBleConnections()
     304              : {
     305              :     // Close and free all BLE end points.
     306          142 :     for (size_t i = 0; i < BLE_LAYER_NUM_BLE_ENDPOINTS; i++)
     307              :     {
     308           71 :         BLEEndPoint * elem = sBLEEndPointPool.Get(i);
     309              : 
     310              :         // If end point was initialized, and has not since been freed...
     311           71 :         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           71 : }
     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           14 : CHIP_ERROR BleLayer::NewBleEndPoint(BLEEndPoint ** retEndPoint, BLE_CONNECTION_OBJECT connObj, BleRole role, bool autoClose)
     413              : {
     414           14 :     *retEndPoint = nullptr;
     415              : 
     416           14 :     if (mState != kState_Initialized)
     417              :     {
     418            0 :         return CHIP_ERROR_INCORRECT_STATE;
     419              :     }
     420              : 
     421           14 :     if (connObj == BLE_CONNECTION_UNINITIALIZED)
     422              :     {
     423            1 :         return CHIP_ERROR_INVALID_ARGUMENT;
     424              :     }
     425              : 
     426           13 :     *retEndPoint = sBLEEndPointPool.GetFree();
     427           13 :     if (*retEndPoint == nullptr)
     428              :     {
     429            1 :         ChipLogError(Ble, "%s endpoint pool FULL", "Ble");
     430            1 :         return CHIP_ERROR_ENDPOINT_POOL_FULL;
     431              :     }
     432              : 
     433           12 :     (*retEndPoint)->Init(this, connObj, role, autoClose);
     434           12 :     (*retEndPoint)->mBleTransport = mBleTransport;
     435              : 
     436           12 :     return CHIP_NO_ERROR;
     437              : }
     438              : 
     439              : // Handle remote central's initiation of CHIP over BLE protocol handshake.
     440           14 : CHIP_ERROR BleLayer::HandleBleTransportConnectionInitiated(BLE_CONNECTION_OBJECT connObj, PacketBufferHandle && pBuf)
     441              : {
     442           14 :     CHIP_ERROR err            = CHIP_NO_ERROR;
     443           14 :     BLEEndPoint * newEndPoint = nullptr;
     444              : 
     445              :     // Only BLE peripherals can receive GATT writes, so specify this role in our creation of the BLEEndPoint.
     446              :     // Set autoClose = false. Peripherals only notify the application when an end point releases a BLE connection.
     447           14 :     err = NewBleEndPoint(&newEndPoint, connObj, kBleRole_Peripheral, false);
     448           14 :     SuccessOrExit(err);
     449              : 
     450           12 :     newEndPoint->mBleTransport = mBleTransport;
     451              : 
     452           12 :     err = newEndPoint->Receive(std::move(pBuf));
     453           12 :     SuccessOrExit(err); // If we fail here, end point will have already released connection and freed itself.
     454              : 
     455           14 : exit:
     456              :     // If we failed to allocate a new end point, release underlying BLE connection. Central's handshake will time out
     457              :     // if the application decides to keep the BLE connection open.
     458           14 :     if (newEndPoint == nullptr)
     459              :     {
     460            2 :         mApplicationDelegate->NotifyChipConnectionClosed(connObj);
     461              :     }
     462              : 
     463           14 :     if (err != CHIP_NO_ERROR)
     464              :     {
     465            2 :         ChipLogError(Ble, "HandleChipConnectionReceived failed, err = %" CHIP_ERROR_FORMAT, err.Format());
     466              :     }
     467              : 
     468           14 :     return err;
     469              : }
     470              : 
     471           17 : bool BleLayer::HandleWriteReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId,
     472              :                                    PacketBufferHandle && pBuf)
     473              : {
     474           17 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Write received on unknown svc"));
     475           16 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_1_UUID, charId), false, ChipLogError(Ble, "Write received on unknown char"));
     476           15 :     VerifyOrReturnError(!pBuf.IsNull(), false, ChipLogError(Ble, "Write received null buffer"));
     477              : 
     478              :     // Find matching connection end point.
     479           15 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     480              : 
     481           15 :     if (endPoint != nullptr)
     482              :     {
     483            1 :         CHIP_ERROR err = endPoint->Receive(std::move(pBuf));
     484            1 :         VerifyOrReturnError(err == CHIP_NO_ERROR, false,
     485              :                             ChipLogError(Ble, "Receive failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
     486              :     }
     487              :     else
     488              :     {
     489           14 :         CHIP_ERROR err = HandleBleTransportConnectionInitiated(connObj, std::move(pBuf));
     490           14 :         VerifyOrReturnError(err == CHIP_NO_ERROR, false,
     491              :                             ChipLogError(Ble, "Handle new BLE connection failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
     492              :     }
     493              : 
     494           13 :     return true;
     495              : }
     496              : 
     497            3 : bool BleLayer::HandleIndicationReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId,
     498              :                                         PacketBufferHandle && pBuf)
     499              : {
     500            3 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Indication received on unknown svc"));
     501            2 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId), false, ChipLogError(Ble, "Indication received on unknown char"));
     502            1 :     VerifyOrReturnError(!pBuf.IsNull(), false, ChipLogError(Ble, "Indication received null buffer"));
     503              : 
     504              :     // Find matching connection end point.
     505            1 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     506            1 :     VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for received indication"));
     507              : 
     508            1 :     CHIP_ERROR err = endPoint->Receive(std::move(pBuf));
     509            1 :     VerifyOrReturnError(err == CHIP_NO_ERROR, false, ChipLogError(Ble, "Receive failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
     510              : 
     511            1 :     return true;
     512              : }
     513              : 
     514            3 : bool BleLayer::HandleWriteConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
     515              : {
     516            3 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Write confirmation on unknown svc"));
     517            2 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_1_UUID, charId), false, ChipLogError(Ble, "Write confirmation on unknown char"));
     518              : 
     519            1 :     HandleAckReceived(connObj);
     520            1 :     return true;
     521              : }
     522              : 
     523            3 : bool BleLayer::HandleIndicationConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
     524              : {
     525            3 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Indication confirmation on unknown svc"));
     526            2 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId), false,
     527              :                         ChipLogError(Ble, "Indication confirmation on unknown char"));
     528              : 
     529            1 :     HandleAckReceived(connObj);
     530            1 :     return true;
     531              : }
     532              : 
     533            2 : void BleLayer::HandleAckReceived(BLE_CONNECTION_OBJECT connObj)
     534              : {
     535              :     // Find matching connection end point.
     536            2 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     537            2 :     VerifyOrReturn(endPoint != nullptr, ChipLogDetail(Ble, "No endpoint for received ack"));
     538              : 
     539            2 :     CHIP_ERROR err = endPoint->HandleGattSendConfirmationReceived();
     540            2 :     VerifyOrReturn(err == CHIP_NO_ERROR,
     541              :                    ChipLogError(Ble, "Send ack confirmation failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
     542              : }
     543              : 
     544            8 : bool BleLayer::HandleSubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
     545              : {
     546            8 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Subscribe received on unknown svc"));
     547            7 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_UUID, charId), false,
     548              :                         ChipLogError(Ble, "Subscribe received on unknown char"));
     549              : 
     550              :     // Find end point already associated with BLE connection, if any.
     551            6 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     552            6 :     VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for received subscribe"));
     553              : 
     554            6 :     endPoint->HandleSubscribeReceived();
     555            6 :     return true;
     556              : }
     557              : 
     558            3 : bool BleLayer::HandleSubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
     559              : {
     560            3 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Subscribe complete on unknown svc"));
     561            2 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_UUID, charId), false,
     562              :                         ChipLogError(Ble, "Subscribe complete on unknown char"));
     563              : 
     564            1 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     565            1 :     VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for subscribe complete"));
     566              : 
     567            1 :     endPoint->HandleSubscribeComplete();
     568            1 :     return true;
     569              : }
     570              : 
     571            3 : bool BleLayer::HandleUnsubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
     572              : {
     573            3 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Unsubscribe received on unknown svc"));
     574            2 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_UUID, charId), false,
     575              :                         ChipLogError(Ble, "Unsubscribe received on unknown char"));
     576              : 
     577              :     // Find end point already associated with BLE connection, if any.
     578            1 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     579            1 :     VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for unsubscribe received"));
     580              : 
     581            1 :     endPoint->DoClose(kBleCloseFlag_AbortTransmission, BLE_ERROR_CENTRAL_UNSUBSCRIBED);
     582            1 :     return true;
     583              : }
     584              : 
     585            3 : bool BleLayer::HandleUnsubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
     586              : {
     587            3 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Unsubscribe complete on unknown svc"));
     588            2 :     VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_UUID, charId), false,
     589              :                         ChipLogError(Ble, "Unsubscribe complete on unknown char"));
     590              : 
     591              :     // Find end point already associated with BLE connection, if any.
     592            1 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     593            1 :     VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for unsubscribe complete"));
     594              : 
     595            1 :     endPoint->HandleUnsubscribeComplete();
     596            1 :     return true;
     597              : }
     598              : 
     599            1 : void BleLayer::HandleConnectionError(BLE_CONNECTION_OBJECT connObj, CHIP_ERROR err)
     600              : {
     601              :     // BLE connection has failed somehow, we must find and abort matching connection end point.
     602            1 :     BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
     603            1 :     VerifyOrReturn(endPoint != nullptr, ChipLogDetail(Ble, "No endpoint for connection error"));
     604              : 
     605            1 :     if (err == BLE_ERROR_GATT_UNSUBSCRIBE_FAILED && endPoint->IsUnsubscribePending())
     606              :     {
     607              :         // If end point was already closed and just waiting for unsubscribe to complete, free it. Call to Free()
     608              :         // stops unsubscribe timer.
     609            0 :         endPoint->Free();
     610              :     }
     611              :     else
     612              :     {
     613            1 :         endPoint->DoClose(kBleCloseFlag_AbortTransmission, err);
     614              :     }
     615              : }
     616              : 
     617           12 : BleTransportProtocolVersion BleLayer::GetHighestSupportedProtocolVersion(const BleTransportCapabilitiesRequestMessage & reqMsg)
     618              : {
     619           12 :     BleTransportProtocolVersion retVersion = kBleTransportProtocolVersion_None;
     620              : 
     621           12 :     uint8_t shift_width = 4;
     622              : 
     623           36 :     for (int i = 0; i < NUM_SUPPORTED_PROTOCOL_VERSIONS; i++)
     624              :     {
     625           36 :         shift_width ^= 4;
     626              : 
     627           36 :         uint8_t version = reqMsg.mSupportedProtocolVersions[(i / 2)];
     628           36 :         version         = static_cast<uint8_t>((version >> shift_width) & 0x0F); // Grab just the nibble we want.
     629              : 
     630           36 :         if ((version >= CHIP_BLE_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION) &&
     631           12 :             (version <= CHIP_BLE_TRANSPORT_PROTOCOL_MAX_SUPPORTED_VERSION) && (version > retVersion))
     632              :         {
     633           12 :             retVersion = static_cast<BleTransportProtocolVersion>(version);
     634              :         }
     635           24 :         else if (version == kBleTransportProtocolVersion_None) // Signifies end of supported versions list
     636              :         {
     637           12 :             break;
     638              :         }
     639              :     }
     640              : 
     641           12 :     return retVersion;
     642              : }
     643              : 
     644            0 : void BleLayer::OnConnectionComplete(void * appState, BLE_CONNECTION_OBJECT connObj)
     645              : {
     646            0 :     BleLayer * layer       = reinterpret_cast<BleLayer *>(appState);
     647            0 :     BLEEndPoint * endPoint = nullptr;
     648            0 :     CHIP_ERROR err         = CHIP_NO_ERROR;
     649              : 
     650            0 :     SuccessOrExit(err = layer->NewBleEndPoint(&endPoint, connObj, kBleRole_Central, true));
     651            0 :     layer->mBleTransport->OnBleConnectionComplete(endPoint);
     652              : 
     653            0 : exit:
     654            0 :     if (err != CHIP_NO_ERROR)
     655              :     {
     656            0 :         OnConnectionError(layer, err);
     657              :     }
     658            0 : }
     659              : 
     660            0 : void BleLayer::OnConnectionError(void * appState, CHIP_ERROR err)
     661              : {
     662            0 :     BleLayer * layer = reinterpret_cast<BleLayer *>(appState);
     663            0 :     layer->mBleTransport->OnBleConnectionError(err);
     664            0 : }
     665              : 
     666              : } /* namespace Ble */
     667              : } /* namespace chip */
        

Generated by: LCOV version 2.0-1