LCOV - code coverage report
Current view: top level - ble - BleLayer.cpp (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 30 292 10.3 %
Date: 2024-02-15 08:20:41 Functions: 6 34 17.6 %

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

Generated by: LCOV version 1.14