Skip to content

Commit

Permalink
[NXP][platform][rw61x] Switch to using BLE mgr impl files from common…
Browse files Browse the repository at this point in the history
… nxp folder (#34349)

Signed-off-by: Martin Girardot <[email protected]>
  • Loading branch information
Martin-NXP authored and pull[bot] committed Oct 24, 2024
1 parent 58b59c1 commit 3753538
Show file tree
Hide file tree
Showing 5 changed files with 1,271 additions and 11 deletions.
138 changes: 138 additions & 0 deletions src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
*
* Copyright (c) 2023-2024 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "BLEAdvertisingArbiter.h"

#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <system/SystemError.h>

namespace chip {
namespace DeviceLayer {
namespace BLEAdvertisingArbiter {
namespace {

// List of advertising requests ordered by priority
sys_slist_t sRequests;

// Cast an intrusive list node to the containing request object
const BLEAdvertisingArbiter::Request & ToRequest(const sys_snode_t * node)
{
return *static_cast<const BLEAdvertisingArbiter::Request *>(node);
}

// Notify application about stopped advertising if the callback has been provided
void NotifyAdvertisingStopped(const sys_snode_t * node)
{
VerifyOrReturn(node);

const Request & request = ToRequest(node);

if (request.onStopped != nullptr)
{
request.onStopped();
}
}

// Restart advertising using the top-priority request
CHIP_ERROR RestartAdvertising()
{
// Note: bt_le_adv_stop() returns success when the advertising was not started
ReturnErrorOnFailure(MapErrorZephyr(bt_le_adv_stop()));
ReturnErrorCodeIf(sys_slist_is_empty(&sRequests), CHIP_NO_ERROR);

const Request & top = ToRequest(sys_slist_peek_head(&sRequests));
const bt_le_adv_param params = BT_LE_ADV_PARAM_INIT(top.options, top.minInterval, top.maxInterval, nullptr);
const int result = bt_le_adv_start(&params, top.advertisingData.data(), top.advertisingData.size(), top.scanResponseData.data(),
top.scanResponseData.size());

if (top.onStarted != nullptr)
{
top.onStarted(result);
}

return MapErrorZephyr(result);
}

} // namespace

CHIP_ERROR InsertRequest(Request & request)
{
CancelRequest(request);

sys_snode_t * prev = nullptr;
sys_snode_t * node = nullptr;

// Find position of the request in the list that preserves ordering by priority
SYS_SLIST_FOR_EACH_NODE(&sRequests, node)
{
if (request.priority < ToRequest(node).priority)
{
break;
}

prev = node;
}

if (prev == nullptr)
{
NotifyAdvertisingStopped(sys_slist_peek_head(&sRequests));
sys_slist_prepend(&sRequests, &request);
}
else
{
sys_slist_insert(&sRequests, prev, &request);
}

// If the request is top-priority, restart the advertising
if (sys_slist_peek_head(&sRequests) == &request)
{
return RestartAdvertising();
}

return CHIP_NO_ERROR;
}

void CancelRequest(Request & request)
{
const bool isTopPriority = (sys_slist_peek_head(&sRequests) == &request);
VerifyOrReturn(sys_slist_find_and_remove(&sRequests, &request));

// If cancelled request was top-priority, restart the advertising.
if (isTopPriority)
{
RestartAdvertising();
}
}

} // namespace BLEAdvertisingArbiter

/**
* This implements a mapping function for CHIP System Layer errors that allows mapping integers in the number space of the
* Zephyr OS user API stack errors into the POSIX range.
*
* @param[in] aError The native Zephyr API error to map.
*
* @return The mapped POSIX error.
*/
DLL_EXPORT CHIP_ERROR MapErrorZephyr(int aError)
{
return chip::System::Internal::MapErrorPOSIX(-aError);
}

} // namespace DeviceLayer
} // namespace chip
107 changes: 107 additions & 0 deletions src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
*
* Copyright (c) 2023-2024 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <lib/support/Span.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/sys/slist.h>

#include <cstdint>

/**
* @file
* Bluetooth LE advertising arbiter.
*
* The purpose for this module is to coordinate BLE advertising between
* different application components.
*
* An application component that wants to advertise BLE services is expected to
* define a request with a desired priority, and pass it to the BLE advertising
* arbiter. If there are multiple components that request BLE advertising at the
* same time, the arbiter selects the one with the highest priority (represented
* by the lowest numeric value) and starts the BLE advertising using parameters
* defined in the winning request.
*
* The BLE arbiter does not take ownership of a submitted request, so the
* request object must be sustained until it is cancelled by the application.
*/

namespace chip {
namespace DeviceLayer {
namespace BLEAdvertisingArbiter {

using OnAdvertisingStarted = void (*)(int result);
using OnAdvertisingStopped = void (*)();

struct Request : public sys_snode_t
{
uint8_t priority; ///< Advertising request priority. Lower value means higher priority
uint32_t options; ///< Advertising options: bitmask of BT_LE_ADV_OPT_XXX constants from Zephyr
uint16_t minInterval; ///< Minimum advertising interval in 0.625 ms units
uint16_t maxInterval; ///< Maximum advertising interval in 0.625 ms units
Span<const bt_data> advertisingData; ///< Advertising data fields
Span<const bt_data> scanResponseData; ///< Scan response data fields
OnAdvertisingStarted onStarted; ///< (Optional) Callback invoked when the request becomes top-priority.
OnAdvertisingStopped onStopped; ///< (Optional) Callback invoked when the request stops being top-priority.
};

/**
* @brief Request BLE advertising
*
* Add the request to the internal list of competing requests. If the request
* has higher priority than other requests in the list, restart the BLE
* advertising immediately using parameters defined in the new request.
*
* Inserting a request object that is already registered at the advertising
* arbiter automatically cancels the previous request.
*
* @note This method does not take ownership of the request object so the object
* must not get destroyed before it is cancelled.
*
* @param request Reference to advertising request that contains priority and
* other advertising parameters.
* @return error If the request is top-priority and failed to restart the
* advertising.
* @return success Otherwise.
*/
CHIP_ERROR InsertRequest(Request & request);

/**
* @brief Cancel BLE advertising request
*
* Remove the request from the internal list of competing requests. If the
* request is the winning (top-priority) one at the time of calling this
* function, restart the BLE advertising using parameters defined in the 2nd
* top-priority request in the list, or stop the BLE advertising completely if
* this is the last request in the list.
*
* An attempt to cancel a request that has not been registered at the
* advertising arbiter is a no-op. That is, it returns immediately.
*
* @param request Reference to advertising request that contains priority and
* other advertising parameters.
*/
void CancelRequest(Request & request);

} // namespace BLEAdvertisingArbiter

extern CHIP_ERROR MapErrorZephyr(int code);

} // namespace DeviceLayer
} // namespace chip
Loading

0 comments on commit 3753538

Please sign in to comment.