Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tizen] Improve memory management in BLE module #33800

Merged
merged 6 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 65 additions & 62 deletions src/platform/Tizen/BLEManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,16 +401,16 @@ void BLEManagerImpl::NotifyBLEIndicationConfirmation(BLE_CONNECTION_OBJECT conId
PlatformMgr().PostEventOrDie(&event);
}

void BLEManagerImpl::NotifyBLEConnectionEstablished(BLE_CONNECTION_OBJECT conId, CHIP_ERROR error)
void BLEManagerImpl::NotifyBLEConnectionEstablished(BLE_CONNECTION_OBJECT conId)
{
ChipDeviceEvent event{ .Type = DeviceEventType::kCHIPoBLEConnectionEstablished };
PlatformMgr().PostEventOrDie(&event);
}

void BLEManagerImpl::NotifyBLEDisconnection(BLE_CONNECTION_OBJECT conId, CHIP_ERROR error)
void BLEManagerImpl::NotifyBLEDisconnection(BLE_CONNECTION_OBJECT conId)
{
ChipDeviceEvent event{ .Type = DeviceEventType::kCHIPoBLEConnectionError,
.CHIPoBLEConnectionError = { .ConId = conId, .Reason = error } };
.CHIPoBLEConnectionError = { .ConId = conId, .Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED } };
PlatformMgr().PostEventOrDie(&event);
}

Expand Down Expand Up @@ -479,44 +479,50 @@ CHIP_ERROR BLEManagerImpl::ConnectChipThing(const char * address)
return err;
}

void BLEManagerImpl::OnChipDeviceScanned(void * device, const Ble::ChipBLEDeviceIdentificationInfo & info)
void BLEManagerImpl::OnDeviceScanned(const bt_adapter_le_device_scan_result_info_s & scanInfo,
const Ble::ChipBLEDeviceIdentificationInfo & info)
{
auto deviceInfo = reinterpret_cast<bt_adapter_le_device_scan_result_info_s *>(device);
VerifyOrReturn(deviceInfo != nullptr, ChipLogError(DeviceLayer, "Invalid Device Info"));

ChipLogProgress(DeviceLayer, "New device scanned: %s", deviceInfo->remote_address);
ChipLogProgress(Ble, "New device scanned: %s", scanInfo.remote_address);

if (mBLEScanConfig.mBleScanState == BleScanState::kScanForDiscriminator)
{
if (!mBLEScanConfig.mDiscriminator.MatchesLongDiscriminator(info.GetDeviceDiscriminator()))
{
return;
}
ChipLogProgress(DeviceLayer, "Device discriminator match. Attempting to connect.");
auto isMatch = mBLEScanConfig.mDiscriminator.MatchesLongDiscriminator(info.GetDeviceDiscriminator());
VerifyOrReturn(
isMatch,
ChipLogError(Ble, "Skip connection: Device discriminator does not match: %u != %u", info.GetDeviceDiscriminator(),
mBLEScanConfig.mDiscriminator.IsShortDiscriminator() ? mBLEScanConfig.mDiscriminator.GetShortValue()
: mBLEScanConfig.mDiscriminator.GetLongValue()));
ChipLogProgress(Ble, "Device discriminator match. Attempting to connect.");
}
else if (mBLEScanConfig.mBleScanState == BleScanState::kScanForAddress)
{
if (strcmp(deviceInfo->remote_address, mBLEScanConfig.mAddress.c_str()) != 0)
{
return;
}
ChipLogProgress(DeviceLayer, "Device address match. Attempting to connect.");
auto isMatch = strcmp(scanInfo.remote_address, mBLEScanConfig.mAddress.c_str()) == 0;
VerifyOrReturn(isMatch,
ChipLogError(Ble, "Skip connection: Device address does not match: %s != %s", scanInfo.remote_address,
mBLEScanConfig.mAddress.c_str()));
ChipLogProgress(Ble, "Device address match. Attempting to connect.");
}
else
{
ChipLogError(DeviceLayer, "Unknown discovery type. Ignoring scanned device.");
ChipLogError(Ble, "Unknown discovery type. Ignoring scanned device.");
return;
}

/* Set CHIP Connecting state */
mBLEScanConfig.mBleScanState = BleScanState::kConnecting;

chip::DeviceLayer::PlatformMgr().LockChipStack();
// We StartScan in the ChipStack thread.
// StopScan should also be performed in the ChipStack thread.
// At the same time, the scan timer also needs to be canceled in the ChipStack thread.
DeviceLayer::SystemLayer().CancelTimer(HandleScanTimeout, this);
mDeviceScanner.StopScan();
// Stop scanning and then start connecting timer
DeviceLayer::SystemLayer().StartTimer(kConnectTimeout, HandleConnectionTimeout, this);
chip::DeviceLayer::PlatformMgr().UnlockChipStack();
mDeviceScanner->StopChipScan();

/* Initiate Connect */
auto params = std::make_pair(this, deviceInfo->remote_address);
auto params = std::make_pair(this, scanInfo.remote_address);
PlatformMgrImpl().GLibMatterContextInvokeSync(
+[](typeof(params) * aParams) { return aParams->first->ConnectChipThing(aParams->second); }, &params);
}
Expand All @@ -540,6 +546,7 @@ void BLEManagerImpl::OnScanComplete()

void BLEManagerImpl::OnScanError(CHIP_ERROR err)
{
BleConnectionDelegate::OnConnectionError(mBLEScanConfig.mAppState, err);
ChipLogDetail(Ble, "BLE scan error: %" CHIP_ERROR_FORMAT, err.Format());
}

Expand Down Expand Up @@ -866,6 +873,7 @@ void BLEManagerImpl::RemoveConnectionData(const char * remoteAddr)
VerifyOrReturn(conn != nullptr,
ChipLogError(DeviceLayer, "Connection does not exist for [%s]", StringOrNullMarker(remoteAddr)));

BLEManagerImpl::NotifyBLEDisconnection(conn);
g_hash_table_remove(mConnectionMap, remoteAddr);

ChipLogProgress(DeviceLayer, "Connection Removed");
Expand Down Expand Up @@ -918,7 +926,7 @@ void BLEManagerImpl::HandleConnectionEvent(bool connected, const char * remoteAd
}
else
{
ChipLogProgress(DeviceLayer, "Device DisConnected [%s]", StringOrNullMarker(remoteAddress));
ChipLogProgress(DeviceLayer, "Device Disconnected [%s]", StringOrNullMarker(remoteAddress));
RemoveConnectionData(remoteAddress);
}
}
Expand Down Expand Up @@ -1008,6 +1016,11 @@ CHIP_ERROR BLEManagerImpl::_Init()

void BLEManagerImpl::_Shutdown()
{
// Make sure that timers are stopped before shutting down the BLE layer.
DeviceLayer::SystemLayer().CancelTimer(HandleScanTimeout, this);
DeviceLayer::SystemLayer().CancelTimer(HandleAdvertisingTimeout, this);
DeviceLayer::SystemLayer().CancelTimer(HandleConnectionTimeout, this);

int ret = bt_deinitialize();
VerifyOrReturn(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_deinitialize() failed: %s", get_error_message(ret)));
}
Expand Down Expand Up @@ -1119,25 +1132,22 @@ void BLEManagerImpl::HandlePlatformSpecificBLEEvent(const ChipDeviceEvent * apEv
CleanScanConfig();
}
break;
case DeviceEventType::kPlatformTizenBLEWriteComplete: {
case DeviceEventType::kPlatformTizenBLEWriteComplete:
HandleWriteConfirmation(apEvent->Platform.BLEWriteComplete.mConnection, &Ble::CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_1_UUID);
break;
}
case DeviceEventType::kPlatformTizenBLESubscribeOpComplete: {
case DeviceEventType::kPlatformTizenBLESubscribeOpComplete:
if (apEvent->Platform.BLESubscribeOpComplete.mIsSubscribed)
HandleSubscribeComplete(apEvent->Platform.BLESubscribeOpComplete.mConnection, &Ble::CHIP_BLE_SVC_ID,
&chip::Ble::CHIP_BLE_CHAR_2_UUID);
else
HandleUnsubscribeComplete(apEvent->Platform.BLESubscribeOpComplete.mConnection, &Ble::CHIP_BLE_SVC_ID,
&chip::Ble::CHIP_BLE_CHAR_2_UUID);
break;
}
case DeviceEventType::kPlatformTizenBLEIndicationReceived: {
case DeviceEventType::kPlatformTizenBLEIndicationReceived:
HandleIndicationReceived(apEvent->Platform.BLEIndicationReceived.mConnection, &Ble::CHIP_BLE_SVC_ID,
&chip::Ble::CHIP_BLE_CHAR_2_UUID,
System::PacketBufferHandle::Adopt(apEvent->Platform.BLEIndicationReceived.mData));
break;
}
default:
break;
}
Expand All @@ -1151,7 +1161,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
ChipLogProgress(DeviceLayer, "CHIPoBLESubscribe");

HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &Ble::CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_2_UUID);
NotifyBLEConnectionEstablished(event->CHIPoBLESubscribe.ConId, CHIP_NO_ERROR);
NotifyBLEConnectionEstablished(event->CHIPoBLESubscribe.ConId);
break;
case DeviceEventType::kCHIPoBLEUnsubscribe:
ChipLogProgress(DeviceLayer, "CHIPoBLEUnsubscribe");
Expand Down Expand Up @@ -1357,55 +1367,48 @@ void BLEManagerImpl::NewConnection(BleLayer * bleLayer, void * appState, const S

void BLEManagerImpl::InitiateScan(BleScanState scanType)
{
CHIP_ERROR err = CHIP_NO_ERROR;
CHIP_ERROR err = CHIP_ERROR_INCORRECT_STATE;
ScanFilterData data = {};

ChipLogProgress(DeviceLayer, "Initiate scan");

/* Check Scanning state */
if (scanType == BleScanState::kNotScanning)
{
err = CHIP_ERROR_INCORRECT_STATE;
ChipLogError(DeviceLayer, "Invalid scan type requested");
goto exit;
}
/* Check Tizen BLE layer is initialized or not */
if (!mFlags.Has(Flags::kTizenBLELayerInitialized))
{
err = CHIP_ERROR_INCORRECT_STATE;
ChipLogError(DeviceLayer, "Tizen BLE layer is not yet initialized");
goto exit;
}

/* Acquire Chip Device Scanner */
if (!mDeviceScanner)
mDeviceScanner = Internal::ChipDeviceScanner::Create(this);
VerifyOrExit(scanType != BleScanState::kNotScanning,
ChipLogError(Ble, "Invalid scan type requested: %d", to_underlying(scanType)));
VerifyOrExit(mFlags.Has(Flags::kTizenBLELayerInitialized), ChipLogError(Ble, "Tizen BLE layer is not yet initialized"));

if (!mDeviceScanner)
{
err = CHIP_ERROR_INTERNAL;
ChipLogError(DeviceLayer, "Failed to create BLE device scanner");
goto exit;
}
ChipLogProgress(Ble, "Start CHIP BLE scan: timeout=%ums", System::Clock::Milliseconds32(kNewConnectionScanTimeout).count());

/* Send StartChipScan Request to Scanner Class */
/* Send StartScan Request to Scanner Class */
strcpy(data.service_uuid, Ble::CHIP_BLE_SERVICE_SHORT_UUID_STR);
err = mDeviceScanner->StartChipScan(kNewConnectionScanTimeout, ScanFilterType::kServiceData, data);
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(DeviceLayer, "Failed to start BLE scan"));
err = mDeviceScanner.StartScan(ScanFilterType::kServiceData, data);
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Ble, "Failed to start BLE scan: %" CHIP_ERROR_FORMAT, err.Format()));

err = DeviceLayer::SystemLayer().StartTimer(kNewConnectionScanTimeout, HandleScanTimeout, this);
VerifyOrExit(err == CHIP_NO_ERROR, mDeviceScanner.StopScan();
ChipLogError(Ble, "Failed to start BLE scan timeout: %" CHIP_ERROR_FORMAT, err.Format()));

ChipLogProgress(DeviceLayer, "BLE scan initiation successful");
mBLEScanConfig.mBleScanState = scanType;
return;

exit:
ChipLogError(DeviceLayer, "BLE scan initiation failed: %" CHIP_ERROR_FORMAT, err.Format());
mBLEScanConfig.mBleScanState = BleScanState::kNotScanning;
BleConnectionDelegate::OnConnectionError(mBLEScanConfig.mAppState, err);
}

void BLEManagerImpl::HandleScanTimeout(chip::System::Layer *, void * appState)
{
auto * manager = static_cast<BLEManagerImpl *>(appState);
manager->OnScanError(CHIP_ERROR_TIMEOUT);
manager->mDeviceScanner.StopScan();
}

CHIP_ERROR BLEManagerImpl::CancelConnection()
{
return CHIP_ERROR_NOT_IMPLEMENTED;
// If in discovery mode, stop scan.
if (mBLEScanConfig.mBleScanState != BleScanState::kNotScanning)
{
DeviceLayer::SystemLayer().CancelTimer(HandleScanTimeout, this);
mDeviceScanner.StopScan();
}
return CHIP_NO_ERROR;
}

} // namespace Internal
Expand Down
19 changes: 13 additions & 6 deletions src/platform/Tizen/BLEManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ class BLEManagerImpl final : public BLEManager,
friend BLEManager;

public:
BLEManagerImpl() : mDeviceScanner(this) {}
~BLEManagerImpl() = default;

CHIP_ERROR ConfigureBle(uint32_t aAdapterId, bool aIsCentral);

private:
Expand Down Expand Up @@ -137,7 +140,8 @@ class BLEManagerImpl final : public BLEManager,
CHIP_ERROR CancelConnection() override;

// ===== Members that implement virtual methods on ChipDeviceScannerDelegate
void OnChipDeviceScanned(void * device, const Ble::ChipBLEDeviceIdentificationInfo & info) override;
void OnDeviceScanned(const bt_adapter_le_device_scan_result_info_s & scanInfo,
const Ble::ChipBLEDeviceIdentificationInfo & info) override;
void OnScanComplete() override;
void OnScanError(CHIP_ERROR err) override;

Expand Down Expand Up @@ -171,8 +175,6 @@ class BLEManagerImpl final : public BLEManager,

void DriveBLEState();

void InitiateScan(BleScanState scanType);

void AdapterStateChangedCb(int result, bt_adapter_state_e adapterState);
void AdvertisingStateChangedCb(int result, bt_advertiser_h advertiser, bt_adapter_le_advertising_state_e advState);
void NotificationStateChangedCb(bool notify, bt_gatt_server_h server, bt_gatt_h gattHandle);
Expand All @@ -185,6 +187,10 @@ class BLEManagerImpl final : public BLEManager,
static void WriteCompletedCb(int result, bt_gatt_h gattHandle, void * userData);
static void CharacteristicNotificationCb(bt_gatt_h characteristic, char * value, int len, void * userData);

// ==== BLE Scan.
void InitiateScan(BleScanState scanType);
static void HandleScanTimeout(chip::System::Layer *, void * appState);

// ==== Connection.
void AddConnectionData(const char * remoteAddr);
void RemoveConnectionData(const char * remoteAddr);
Expand All @@ -208,8 +214,8 @@ class BLEManagerImpl final : public BLEManager,

// ==== Connection.
CHIP_ERROR ConnectChipThing(const char * address);
void NotifyBLEConnectionEstablished(BLE_CONNECTION_OBJECT conId, CHIP_ERROR error);
void NotifyBLEDisconnection(BLE_CONNECTION_OBJECT conId, CHIP_ERROR error);
void NotifyBLEConnectionEstablished(BLE_CONNECTION_OBJECT conId);
void NotifyBLEDisconnection(BLE_CONNECTION_OBJECT conId);
void NotifyHandleNewConnection(BLE_CONNECTION_OBJECT conId);
void NotifyHandleConnectFailed(CHIP_ERROR error);
void NotifyHandleWriteComplete(BLE_CONNECTION_OBJECT conId);
Expand All @@ -232,8 +238,9 @@ class BLEManagerImpl final : public BLEManager,
/* Connection Hash Table Map */
GHashTable * mConnectionMap = nullptr;

ChipDeviceScanner mDeviceScanner;
BLEScanConfig mBLEScanConfig;
std::unique_ptr<ChipDeviceScanner> mDeviceScanner;

bt_gatt_client_h mGattClient = nullptr;
};

Expand Down
Loading
Loading