[Tizen] Use spec complaint BLE advertising intervals (#31790)
* [Tizen] Use spec complaint BLE advertising intervals
* Transition from fast adv to slow after timeout
* Refactor Tizen specific BLE initialization function
* Use ScheduleLambda instead of ScheduleWork
* Wrap C callbacks with lambda to make methods non-static
* Define BLE_CONNECTION_OBJECT for Tizen platform
* Get rid of another static method
* Update name to align with convention
* Do not use sInstance directly if possible
diff --git a/src/platform/Tizen/BLEManagerImpl.cpp b/src/platform/Tizen/BLEManagerImpl.cpp
index 500943f..a759b4e 100644
--- a/src/platform/Tizen/BLEManagerImpl.cpp
+++ b/src/platform/Tizen/BLEManagerImpl.cpp
@@ -73,6 +73,23 @@
namespace DeviceLayer {
namespace Internal {
+namespace {
+
+/* CHIPoBLE UUID strings */
+constexpr char chip_ble_service_uuid[] = "0000FFF6-0000-1000-8000-00805F9B34FB";
+constexpr char chip_ble_char_c1_tx_uuid[] = "18EE2EF5-263D-4559-959F-4F9C429F9D11";
+constexpr char chip_ble_char_c2_rx_uuid[] = "18EE2EF5-263D-4559-959F-4F9C429F9D12";
+
+constexpr char chip_ble_desc_uuid_short[] = "2902";
+constexpr char chip_ble_service_uuid_short[] = "FFF6";
+
+constexpr System::Clock::Timeout kNewConnectionScanTimeout = System::Clock::Seconds16(20);
+constexpr System::Clock::Timeout kConnectTimeout = System::Clock::Seconds16(20);
+constexpr System::Clock::Timeout kFastAdvertiseTimeout =
+ System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME);
+
+}; // namespace
+
BLEManagerImpl BLEManagerImpl::sInstance;
struct BLEConnection
@@ -85,20 +102,6 @@
bool isChipDevice;
};
-/* CHIPoBLE UUID strings */
-const char chip_ble_service_uuid[] = "0000FFF6-0000-1000-8000-00805F9B34FB";
-const char chip_ble_char_c1_tx_uuid[] = "18EE2EF5-263D-4559-959F-4F9C429F9D11";
-const char chip_ble_char_c2_rx_uuid[] = "18EE2EF5-263D-4559-959F-4F9C429F9D12";
-/* CCCD */
-const char desc_uuid_short[] = "2902";
-
-const char chip_ble_service_uuid_short[] = "FFF6";
-
-/* Tizen Default Scan Timeout */
-static constexpr System::Clock::Timeout kNewConnectionScanTimeout = System::Clock::Seconds16(10);
-/* Tizen Default Connect Timeout */
-static constexpr System::Clock::Timeout kConnectTimeout = System::Clock::Seconds16(10);
-
static void __BLEConnectionFree(BLEConnection * conn)
{
VerifyOrReturn(conn != nullptr);
@@ -106,58 +109,53 @@
g_free(conn);
}
-static void __AdapterStateChangedCb(int result, bt_adapter_state_e adapterState, void * userData)
+void BLEManagerImpl::AdapterStateChangedCb(int result, bt_adapter_state_e adapterState)
{
ChipLogProgress(DeviceLayer, "Adapter State Changed: %s", adapterState == BT_ADAPTER_ENABLED ? "Enabled" : "Disabled");
}
-void BLEManagerImpl::GattConnectionStateChangedCb(int result, bool connected, const char * remoteAddress, void * userData)
+void BLEManagerImpl::GattConnectionStateChangedCb(int result, bool connected, const char * remoteAddress)
{
switch (result)
{
case BT_ERROR_NONE:
case BT_ERROR_ALREADY_DONE:
ChipLogProgress(DeviceLayer, "GATT %s", connected ? "connected" : "disconnected");
- sInstance.HandleConnectionEvent(connected, remoteAddress);
+ HandleConnectionEvent(connected, remoteAddress);
break;
default:
ChipLogError(DeviceLayer, "GATT %s failed: %s", connected ? "connection" : "disconnection", get_error_message(result));
if (connected)
- sInstance.NotifyHandleConnectFailed(TizenToChipError(result));
+ NotifyHandleConnectFailed(TizenToChipError(result));
}
}
-CHIP_ERROR BLEManagerImpl::_BleInitialize(void * userData)
+CHIP_ERROR BLEManagerImpl::_InitImpl()
{
int ret;
- if (sInstance.mFlags.Has(Flags::kTizenBLELayerInitialized))
- {
- ChipLogProgress(DeviceLayer, "BLE Already Initialized");
- return CHIP_NO_ERROR;
- }
-
ret = bt_initialize();
VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_initialize() failed: %s", get_error_message(ret)));
- ret = bt_adapter_set_state_changed_cb(__AdapterStateChangedCb, nullptr);
+ ret = bt_adapter_set_state_changed_cb(
+ +[](int result, bt_adapter_state_e adapterState, void * self) {
+ return reinterpret_cast<BLEManagerImpl *>(self)->AdapterStateChangedCb(result, adapterState);
+ },
+ this);
VerifyOrExit(ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_adapter_set_state_changed_cb() failed: %s", get_error_message(ret)));
ret = bt_gatt_server_initialize();
VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_gatt_server_initialize() failed: %s", get_error_message(ret)));
- ret = bt_gatt_set_connection_state_changed_cb(GattConnectionStateChangedCb, nullptr);
+ ret = bt_gatt_set_connection_state_changed_cb(
+ +[](int result, bool connected, const char * remoteAddress, void * self) {
+ return reinterpret_cast<BLEManagerImpl *>(self)->GattConnectionStateChangedCb(result, connected, remoteAddress);
+ },
+ this);
VerifyOrExit(ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_adapter_set_state_changed_cb() failed: %s", get_error_message(ret)));
- // The hash table key is stored in the BLEConnection structure
- // and is freed by the __BLEConnectionFree() function.
- sInstance.mConnectionMap =
- g_hash_table_new_full(g_str_hash, g_str_equal, nullptr, reinterpret_cast<GDestroyNotify>(__BLEConnectionFree));
-
- sInstance.mFlags.Set(Flags::kTizenBLELayerInitialized);
- ChipLogProgress(DeviceLayer, "BLE Initialized");
return CHIP_NO_ERROR;
exit:
@@ -186,8 +184,24 @@
}
}
+void BLEManagerImpl::HandleAdvertisingTimeout(chip::System::Layer *, void * appState)
+{
+ auto * self = static_cast<BLEManagerImpl *>(appState);
+ VerifyOrReturn(self->mFlags.Has(Flags::kFastAdvertisingEnabled));
+
+ ChipLogDetail(DeviceLayer, "bleAdv Timeout : Start slow advertisement");
+ self->_SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising);
+}
+
+BLEManagerImpl::AdvertisingIntervals BLEManagerImpl::GetAdvertisingIntervals() const
+{
+ if (mFlags.Has(Flags::kFastAdvertisingEnabled))
+ return { CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN, CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX };
+ return { CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN, CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX };
+}
+
void BLEManagerImpl::ReadValueRequestedCb(const char * remoteAddress, int requestId, bt_gatt_server_h server, bt_gatt_h gattHandle,
- int offset, void * userData)
+ int offset)
{
int ret, len = 0;
bt_gatt_type_e type;
@@ -209,14 +223,14 @@
}
void BLEManagerImpl::WriteValueRequestedCb(const char * remoteAddress, int requestId, bt_gatt_server_h server, bt_gatt_h gattHandle,
- bool responseNeeded, int offset, const char * value, int len, void * userData)
+ bool responseNeeded, int offset, const char * value, int len)
{
int ret;
GAutoPtr<char> uuid;
- BLEConnection * conn = nullptr;
+ BLEConnection * conn;
bt_gatt_type_e type;
- conn = static_cast<BLEConnection *>(g_hash_table_lookup(sInstance.mConnectionMap, remoteAddress));
+ conn = static_cast<BLEConnection *>(g_hash_table_lookup(mConnectionMap, remoteAddress));
VerifyOrReturn(conn != nullptr, ChipLogError(DeviceLayer, "Failed to find connection info"));
VerifyOrReturn(__GetAttInfo(gattHandle, &MakeUniquePointerReceiver(uuid).Get(), &type) == BT_ERROR_NONE,
@@ -232,10 +246,10 @@
VerifyOrReturn(ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_gatt_server_send_response() failed: %s", get_error_message(ret)));
- sInstance.HandleC1CharWriteEvent(conn, Uint8::from_const_char(value), len);
+ HandleC1CharWriteEvent(conn, Uint8::from_const_char(value), len);
}
-void BLEManagerImpl::NotificationStateChangedCb(bool notify, bt_gatt_server_h server, bt_gatt_h charHandle, void * userData)
+void BLEManagerImpl::NotificationStateChangedCb(bool notify, bt_gatt_server_h server, bt_gatt_h charHandle)
{
GAutoPtr<char> uuid;
BLEConnection * conn = nullptr;
@@ -243,11 +257,11 @@
GHashTableIter iter;
gpointer key, value;
- g_hash_table_iter_init(&iter, sInstance.mConnectionMap);
+ g_hash_table_iter_init(&iter, mConnectionMap);
while (g_hash_table_iter_next(&iter, &key, &value))
{
/* NOTE: Currently Tizen Platform API does not return remote device address, which enables/disables
- * notification/Indication. Therefore, returning first Connection */
+ * notification/indication. Therefore, returning first connection. */
conn = static_cast<BLEConnection *>(value);
break;
}
@@ -260,7 +274,7 @@
ChipLogProgress(DeviceLayer, "Notification State Changed %d on %s: %s", notify, __ConvertAttTypeToStr(type),
StringOrNullMarker(uuid.get()));
- sInstance.NotifyBLESubscribed(notify ? true : false, conn);
+ NotifyBLESubscribed(notify ? true : false, conn);
}
void BLEManagerImpl::WriteCompletedCb(int result, bt_gatt_h gattHandle, void * userData)
@@ -288,44 +302,48 @@
}
void BLEManagerImpl::IndicationConfirmationCb(int result, const char * remoteAddress, bt_gatt_server_h server,
- bt_gatt_h characteristic, bool completed, void * userData)
+ bt_gatt_h characteristic, bool completed)
{
BLEConnection * conn = nullptr;
VerifyOrReturn(result == BT_ERROR_NONE, ChipLogError(DeviceLayer, "Failed to Get Indication Confirmation"));
- conn = static_cast<BLEConnection *>(g_hash_table_lookup(sInstance.mConnectionMap, remoteAddress));
+ conn = static_cast<BLEConnection *>(g_hash_table_lookup(mConnectionMap, remoteAddress));
VerifyOrReturn(conn != nullptr,
ChipLogError(DeviceLayer, "Could not find connection for [%s]", StringOrNullMarker(remoteAddress)));
- VerifyOrReturn(sInstance.mGattCharC2Handle == characteristic,
- ChipLogError(DeviceLayer, "Gatt characteristic handle did not match"));
+ VerifyOrReturn(mGattCharC2Handle == characteristic, ChipLogError(DeviceLayer, "Gatt characteristic handle did not match"));
- sInstance.NotifyBLEIndicationConfirmation(conn);
+ NotifyBLEIndicationConfirmation(conn);
}
-void BLEManagerImpl::AdvertisingStateChangedCb(int result, bt_advertiser_h advertiser, bt_adapter_le_advertising_state_e advState,
- void * userData)
+void BLEManagerImpl::AdvertisingStateChangedCb(int result, bt_advertiser_h advertiser, bt_adapter_le_advertising_state_e advState)
{
ChipLogProgress(DeviceLayer, "Advertising %s", advState == BT_ADAPTER_LE_ADVERTISING_STARTED ? "Started" : "Stopped");
if (advState == BT_ADAPTER_LE_ADVERTISING_STARTED)
{
- sInstance.mFlags.Set(Flags::kAdvertising);
- sInstance.NotifyBLEPeripheralAdvStartComplete(true, nullptr);
+ mFlags.Set(Flags::kAdvertising);
+ NotifyBLEPeripheralAdvStartComplete(true, nullptr);
+ DeviceLayer::SystemLayer().ScheduleLambda([this] {
+ // Start a timer to make sure that the fast advertising is stopped after specified timeout.
+ DeviceLayer::SystemLayer().StartTimer(kFastAdvertiseTimeout, HandleAdvertisingTimeout, this);
+ });
}
else
{
- sInstance.mFlags.Clear(Flags::kAdvertising);
- sInstance.NotifyBLEPeripheralAdvStopComplete(true, nullptr);
+ mFlags.Clear(Flags::kAdvertising);
+ NotifyBLEPeripheralAdvStopComplete(true, nullptr);
+ DeviceLayer::SystemLayer().ScheduleLambda(
+ [this] { DeviceLayer::SystemLayer().CancelTimer(HandleAdvertisingTimeout, this); });
}
- if (sInstance.mFlags.Has(Flags::kAdvertisingRefreshNeeded))
+ if (mFlags.Has(Flags::kAdvertisingRefreshNeeded))
{
- sInstance.mFlags.Clear(Flags::kAdvertisingRefreshNeeded);
- PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ mFlags.Clear(Flags::kAdvertisingRefreshNeeded);
+ DeviceLayer::SystemLayer().ScheduleLambda([this] { DriveBLEState(); });
}
- sInstance.mAdvReqInProgress = false;
+ mAdvReqInProgress = false;
}
// ====== Private Functions.
@@ -401,9 +419,9 @@
void BLEManagerImpl::NotifyBLEConnectionEstablished(BLE_CONNECTION_OBJECT conId, CHIP_ERROR error)
{
- ChipDeviceEvent connectionEvent;
- connectionEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished;
- PlatformMgr().PostEventOrDie(&connectionEvent);
+ ChipDeviceEvent event;
+ event.Type = DeviceEventType::kCHIPoBLEConnectionEstablished;
+ PlatformMgr().PostEventOrDie(&event);
}
void BLEManagerImpl::NotifyBLEDisconnection(BLE_CONNECTION_OBJECT conId, CHIP_ERROR error)
@@ -418,7 +436,7 @@
void BLEManagerImpl::NotifyHandleConnectFailed(CHIP_ERROR error)
{
ChipLogProgress(DeviceLayer, "Connection failed: %" CHIP_ERROR_FORMAT, error.Format());
- if (sInstance.mIsCentral)
+ if (mIsCentral)
{
ChipDeviceEvent event;
event.Type = DeviceEventType::kPlatformTizenBLECentralConnectFailed;
@@ -429,7 +447,7 @@
void BLEManagerImpl::NotifyHandleNewConnection(BLE_CONNECTION_OBJECT conId)
{
- if (sInstance.mIsCentral)
+ if (mIsCentral)
{
ChipDeviceEvent event;
event.Type = DeviceEventType::kPlatformTizenBLECentralConnected;
@@ -455,9 +473,10 @@
PlatformMgr().PostEventOrDie(&event);
}
-void BLEManagerImpl::HandleConnectionTimeout(System::Layer * layer, void * data)
+void BLEManagerImpl::HandleConnectionTimeout(System::Layer *, void * appState)
{
- sInstance.NotifyHandleConnectFailed(CHIP_ERROR_TIMEOUT);
+ auto * self = static_cast<BLEManagerImpl *>(appState);
+ self->NotifyHandleConnectFailed(CHIP_ERROR_TIMEOUT);
}
CHIP_ERROR BLEManagerImpl::ConnectChipThing(const char * address)
@@ -467,7 +486,7 @@
ChipLogProgress(DeviceLayer, "ConnectRequest: Addr [%s]", StringOrNullMarker(address));
- ret = bt_gatt_client_create(address, &sInstance.mGattClient);
+ ret = bt_gatt_client_create(address, &mGattClient);
VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "Failed to create GATT client: %s", get_error_message(ret));
err = TizenToChipError(ret));
@@ -480,7 +499,7 @@
exit:
if (err != CHIP_NO_ERROR)
- sInstance.NotifyHandleConnectFailed(err);
+ NotifyHandleConnectFailed(err);
return err;
}
@@ -516,12 +535,17 @@
/* Set CHIP Connecting state */
mBLEScanConfig.mBleScanState = BleScanState::kConnecting;
chip::DeviceLayer::PlatformMgr().LockChipStack();
- DeviceLayer::SystemLayer().StartTimer(kConnectTimeout, HandleConnectionTimeout, nullptr);
+ DeviceLayer::SystemLayer().StartTimer(kConnectTimeout, HandleConnectionTimeout, this);
chip::DeviceLayer::PlatformMgr().UnlockChipStack();
mDeviceScanner->StopChipScan();
/* Initiate Connect */
- PlatformMgrImpl().GLibMatterContextInvokeSync(ConnectChipThing, const_cast<const char *>(deviceInfo->remote_address));
+ auto params = std::make_pair(this, deviceInfo->remote_address);
+ PlatformMgrImpl().GLibMatterContextInvokeSync(
+ +[](typeof(params) * aParams) {
+ return reinterpret_cast<BLEManagerImpl *>(aParams->first)->ConnectChipThing(aParams->second);
+ },
+ ¶ms);
}
void BLEManagerImpl::OnScanComplete()
@@ -575,7 +599,14 @@
VerifyOrExit(ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_gatt_characteristic_create() failed: %s", get_error_message(ret)));
- ret = bt_gatt_server_set_write_value_requested_cb(char1, WriteValueRequestedCb, nullptr);
+ ret = bt_gatt_server_set_write_value_requested_cb(
+ char1,
+ +[](const char * remoteAddress, int requestId, bt_gatt_server_h gattServer, bt_gatt_h gattHandle, bool responseNeeded,
+ int offset, const char * value, int len, void * self) {
+ return reinterpret_cast<BLEManagerImpl *>(self)->WriteValueRequestedCb(remoteAddress, requestId, gattServer, gattHandle,
+ responseNeeded, offset, value, len);
+ },
+ this);
VerifyOrExit(ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_gatt_server_set_write_value_requested_cb() failed: %s", get_error_message(ret)));
@@ -590,16 +621,27 @@
VerifyOrExit(ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_gatt_characteristic_create() failed: %s", get_error_message(ret)));
- ret = bt_gatt_server_set_read_value_requested_cb(char2, ReadValueRequestedCb, nullptr);
+ ret = bt_gatt_server_set_read_value_requested_cb(
+ char2,
+ +[](const char * remoteAddress, int requestId, bt_gatt_server_h gattServer, bt_gatt_h gattHandle, int offset, void * self) {
+ return reinterpret_cast<BLEManagerImpl *>(self)->ReadValueRequestedCb(remoteAddress, requestId, gattServer, gattHandle,
+ offset);
+ },
+ this);
VerifyOrExit(ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_gatt_server_set_read_value_requested_cb() failed: %s", get_error_message(ret)));
- ret = bt_gatt_server_set_characteristic_notification_state_change_cb(char2, NotificationStateChangedCb, nullptr);
+ ret = bt_gatt_server_set_characteristic_notification_state_change_cb(
+ char2,
+ +[](bool notify, bt_gatt_server_h gattServer, bt_gatt_h charHandle, void * self) {
+ return reinterpret_cast<BLEManagerImpl *>(self)->NotificationStateChangedCb(notify, gattServer, charHandle);
+ },
+ this);
VerifyOrExit(ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_gatt_server_set_characteristic_notification_state_change_cb() failed: %s",
get_error_message(ret)));
// Create CCC Descriptor
- ret = bt_gatt_descriptor_create(desc_uuid_short, BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE, desc_value,
+ ret = bt_gatt_descriptor_create(chip_ble_desc_uuid_short, BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE, desc_value,
sizeof(desc_value), &desc);
VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_gatt_descriptor_create() failed: %s", get_error_message(ret)));
ret = bt_gatt_characteristic_add_descriptor(char2, desc);
@@ -635,11 +677,12 @@
CHIP_ERROR BLEManagerImpl::StartBLEAdvertising()
{
Ble::ChipBLEDeviceIdentificationInfo deviceIdInfo;
+ auto intervals = GetAdvertisingIntervals();
PlatformVersion version;
CHIP_ERROR err;
int ret;
- if (sInstance.mAdvReqInProgress)
+ if (mAdvReqInProgress)
{
ChipLogProgress(DeviceLayer, "Advertising Request In Progress");
return CHIP_NO_ERROR;
@@ -664,20 +707,9 @@
ChipLogError(DeviceLayer, "bt_adapter_le_clear_advertising_data() failed: %s", get_error_message(ret)));
}
- if (mFlags.Has(Flags::kFastAdvertisingEnabled))
- {
- ret = bt_adapter_le_set_advertising_mode(mAdvertiser, BT_ADAPTER_LE_ADVERTISING_MODE_LOW_LATENCY);
- VerifyOrExit(ret == BT_ERROR_NONE,
- ChipLogError(DeviceLayer, "bt_adapter_le_set_advertising_mode() failed: %s", get_error_message(ret)));
-
- // NOTE: Check specification for recommended Advertising Interval range for Fast Advertising
- // ret = bt_adapter_le_set_advertising_interval(mAdvertiser, BT_LE_ADV_INTERVAL_MIN, BT_LE_ADV_INTERVAL_MIN);
- }
- else
- {
- // NOTE: Check specification for recommended Advertising Interval range for Slow Advertising
- // ret = bt_adapter_le_set_advertising_interval(mAdvertiser, BT_LE_ADV_INTERVAL_MAX, BT_LE_ADV_INTERVAL_MAX);
- }
+ ret = bt_adapter_le_set_advertising_interval(mAdvertiser, intervals.first, intervals.second);
+ VerifyOrExit(ret == BT_ERROR_NONE,
+ ChipLogError(DeviceLayer, "bt_adapter_le_set_advertising_interval() failed: %s", get_error_message(ret)));
err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(deviceIdInfo);
VerifyOrExit(err == CHIP_NO_ERROR,
@@ -708,11 +740,16 @@
BLEManagerImpl::NotifyBLEPeripheralAdvConfiguredComplete(true, nullptr);
- ret = bt_adapter_le_start_advertising_new(mAdvertiser, AdvertisingStateChangedCb, nullptr);
+ ret = bt_adapter_le_start_advertising_new(
+ mAdvertiser,
+ +[](int result, bt_advertiser_h advertiser, bt_adapter_le_advertising_state_e advState, void * self) {
+ return reinterpret_cast<BLEManagerImpl *>(self)->AdvertisingStateChangedCb(result, advertiser, advState);
+ },
+ this);
VerifyOrExit(ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_adapter_le_start_advertising_new() failed: %s", get_error_message(ret)));
- sInstance.mAdvReqInProgress = true;
+ mAdvReqInProgress = true;
return CHIP_NO_ERROR;
exit:
@@ -728,7 +765,7 @@
VerifyOrExit(ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_adapter_le_stop_advertising() failed: %s", get_error_message(ret)));
- sInstance.mAdvReqInProgress = true;
+ mAdvReqInProgress = true;
return CHIP_NO_ERROR;
exit:
@@ -791,13 +828,10 @@
bool BLEManagerImpl::IsDeviceChipPeripheral(BLE_CONNECTION_OBJECT conId)
{
- auto conn = static_cast<BLEConnection *>(conId);
int ret;
-
- if ((ret = bt_gatt_client_foreach_services(sInstance.mGattClient, __GattClientForeachServiceCb, conn)) != BT_ERROR_NONE)
+ if ((ret = bt_gatt_client_foreach_services(mGattClient, __GattClientForeachServiceCb, conId)) != BT_ERROR_NONE)
ChipLogError(DeviceLayer, "Failed to browse GATT services: %s", get_error_message(ret));
-
- return (conn->isChipDevice ? true : false);
+ return (conId->isChipDevice ? true : false);
}
void BLEManagerImpl::AddConnectionData(const char * remoteAddr)
@@ -818,7 +852,7 @@
get_error_message(ret));
}
- if (sInstance.mIsCentral)
+ if (mIsCentral)
{
/* Local Device is BLE Central Role */
if (IsDeviceChipPeripheral(conn))
@@ -970,11 +1004,6 @@
}
}
-void BLEManagerImpl::DriveBLEState(intptr_t arg)
-{
- sInstance.DriveBLEState();
-}
-
CHIP_ERROR BLEManagerImpl::_Init()
{
CHIP_ERROR err;
@@ -983,12 +1012,21 @@
SuccessOrExit(err);
mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
+ mFlags.Set(Flags::kFastAdvertisingEnabled, true);
- ChipLogProgress(DeviceLayer, "Initialize BLE");
- err = PlatformMgrImpl().GLibMatterContextInvokeSync(_BleInitialize, static_cast<void *>(nullptr));
+ ChipLogProgress(DeviceLayer, "Initialize Tizen BLE Layer");
+
+ err = PlatformMgrImpl().GLibMatterContextInvokeSync(
+ +[](BLEManagerImpl * self) { return self->_InitImpl(); }, this);
SuccessOrExit(err);
- return PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ // The hash table key is stored in the BLEConnection structure
+ // and is freed by the __BLEConnectionFree() function.
+ mConnectionMap = g_hash_table_new_full(g_str_hash, g_str_equal, nullptr, reinterpret_cast<GDestroyNotify>(__BLEConnectionFree));
+
+ mFlags.Set(Flags::kTizenBLELayerInitialized);
+
+ err = DeviceLayer::SystemLayer().ScheduleLambda([this] { DriveBLEState(); });
exit:
return err;
@@ -1003,7 +1041,7 @@
CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val)
{
mFlags.Set(Flags::kAdvertisingEnabled, val);
- return PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ return DeviceLayer::SystemLayer().ScheduleLambda([this] { DriveBLEState(); });
}
CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode)
@@ -1020,7 +1058,7 @@
return CHIP_ERROR_INVALID_ARGUMENT;
}
mFlags.Set(Flags::kAdvertisingRefreshNeeded);
- return PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ return DeviceLayer::SystemLayer().ScheduleLambda([this] { DriveBLEState(); });
}
CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize)
@@ -1081,7 +1119,7 @@
void BLEManagerImpl::CleanScanConfig()
{
if (mBLEScanConfig.mBleScanState == BleScanState::kConnecting)
- DeviceLayer::SystemLayer().CancelTimer(HandleConnectionTimeout, nullptr);
+ DeviceLayer::SystemLayer().CancelTimer(HandleConnectionTimeout, this);
mBLEScanConfig.mBleScanState = BleScanState::kNotScanning;
}
@@ -1201,8 +1239,7 @@
uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const
{
- auto conn = static_cast<BLEConnection *>(conId);
- return (conn != nullptr) ? static_cast<uint16_t>(conn->mtu) : 0;
+ return (conId != nullptr) ? static_cast<uint16_t>(conId->mtu) : 0;
}
bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId,
@@ -1210,7 +1247,6 @@
{
Ble::ChipBleUUID service_uuid;
Ble::ChipBleUUID char_notif_uuid;
- auto conn = static_cast<BLEConnection *>(conId);
int ret;
ChipLogProgress(DeviceLayer, "SubscribeCharacteristic");
@@ -1218,21 +1254,21 @@
StringToUUID(chip_ble_service_uuid, service_uuid);
StringToUUID(chip_ble_char_c2_rx_uuid, char_notif_uuid);
- VerifyOrExit(conn != nullptr, ChipLogError(DeviceLayer, "Invalid Connection"));
+ VerifyOrExit(conId != nullptr, ChipLogError(DeviceLayer, "Invalid Connection"));
VerifyOrExit(Ble::UUIDsMatch(svcId, &service_uuid),
ChipLogError(DeviceLayer, "SubscribeCharacteristic() called with invalid service ID"));
VerifyOrExit(Ble::UUIDsMatch(charId, &char_notif_uuid),
ChipLogError(DeviceLayer, "SubscribeCharacteristic() called with invalid characteristic ID"));
- VerifyOrExit(conn->gattCharC2Handle != nullptr, ChipLogError(DeviceLayer, "Char C2 is null"));
+ VerifyOrExit(conId->gattCharC2Handle != nullptr, ChipLogError(DeviceLayer, "Char C2 is null"));
- ChipLogProgress(DeviceLayer, "Sending Notification Enable Request to CHIP Peripheral: %s", conn->peerAddr);
+ ChipLogProgress(DeviceLayer, "Sending Notification Enable Request to CHIP Peripheral: %s", conId->peerAddr);
- ret = bt_gatt_client_set_characteristic_value_changed_cb(conn->gattCharC2Handle, CharacteristicNotificationCb, conn);
+ ret = bt_gatt_client_set_characteristic_value_changed_cb(conId->gattCharC2Handle, CharacteristicNotificationCb, conId);
VerifyOrExit(
ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_gatt_client_set_characteristic_value_changed_cb() failed: %s", get_error_message(ret)));
- sInstance.NotifySubscribeOpComplete(conn, true);
+ NotifySubscribeOpComplete(conId, true);
return true;
exit:
@@ -1244,7 +1280,6 @@
{
Ble::ChipBleUUID service_uuid;
Ble::ChipBleUUID char_notif_uuid;
- auto conn = static_cast<BLEConnection *>(conId);
int ret;
ChipLogProgress(DeviceLayer, "UnSubscribeCharacteristic");
@@ -1252,21 +1287,21 @@
StringToUUID(chip_ble_service_uuid, service_uuid);
StringToUUID(chip_ble_char_c2_rx_uuid, char_notif_uuid);
- VerifyOrExit(conn != nullptr, ChipLogError(DeviceLayer, "Invalid Connection"));
+ VerifyOrExit(conId != nullptr, ChipLogError(DeviceLayer, "Invalid Connection"));
VerifyOrExit(Ble::UUIDsMatch(svcId, &service_uuid),
ChipLogError(DeviceLayer, "UnSubscribeCharacteristic() called with invalid service ID"));
VerifyOrExit(Ble::UUIDsMatch(charId, &char_notif_uuid),
ChipLogError(DeviceLayer, "UnSubscribeCharacteristic() called with invalid characteristic ID"));
- VerifyOrExit(conn->gattCharC2Handle != nullptr, ChipLogError(DeviceLayer, "Char C2 is null"));
+ VerifyOrExit(conId->gattCharC2Handle != nullptr, ChipLogError(DeviceLayer, "Char C2 is null"));
- ChipLogProgress(DeviceLayer, "Disable Notification Request to CHIP Peripheral: %s", conn->peerAddr);
+ ChipLogProgress(DeviceLayer, "Disable Notification Request to CHIP Peripheral: %s", conId->peerAddr);
- ret = bt_gatt_client_unset_characteristic_value_changed_cb(conn->gattCharC2Handle);
+ ret = bt_gatt_client_unset_characteristic_value_changed_cb(conId->gattCharC2Handle);
VerifyOrExit(
ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_gatt_client_unset_characteristic_value_changed_cb() failed: %s", get_error_message(ret)));
- sInstance.NotifySubscribeOpComplete(conn, false);
+ NotifySubscribeOpComplete(conId, false);
return true;
exit:
@@ -1275,19 +1310,18 @@
bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId)
{
- auto conn = static_cast<BLEConnection *>(conId);
int ret;
ChipLogProgress(DeviceLayer, "Close BLE Connection");
- conn = static_cast<BLEConnection *>(g_hash_table_lookup(sInstance.mConnectionMap, conn->peerAddr));
- VerifyOrExit(conn != nullptr, ChipLogError(DeviceLayer, "Failed to find connection info"));
+ conId = static_cast<BLEConnection *>(g_hash_table_lookup(mConnectionMap, conId->peerAddr));
+ VerifyOrExit(conId != nullptr, ChipLogError(DeviceLayer, "Failed to find connection info"));
- ChipLogProgress(DeviceLayer, "Send GATT disconnect to [%s]", conn->peerAddr);
- ret = bt_gatt_disconnect(conn->peerAddr);
+ ChipLogProgress(DeviceLayer, "Send GATT disconnect to [%s]", conId->peerAddr);
+ ret = bt_gatt_disconnect(conId->peerAddr);
VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_gatt_disconnect() failed: %s", get_error_message(ret)));
- RemoveConnectionData(conn->peerAddr);
+ RemoveConnectionData(conId->peerAddr);
return true;
exit:
@@ -1297,21 +1331,27 @@
bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
System::PacketBufferHandle pBuf)
{
- auto conn = static_cast<BLEConnection *>(conId);
int ret;
ChipLogProgress(DeviceLayer, "SendIndication");
- conn = static_cast<BLEConnection *>(g_hash_table_lookup(sInstance.mConnectionMap, conn->peerAddr));
- VerifyOrExit(conn != nullptr, ChipLogError(DeviceLayer, "Failed to find connection info"));
+ conId = static_cast<BLEConnection *>(g_hash_table_lookup(mConnectionMap, conId->peerAddr));
+ VerifyOrExit(conId != nullptr, ChipLogError(DeviceLayer, "Failed to find connection info"));
ret = bt_gatt_set_value(mGattCharC2Handle, Uint8::to_const_char(pBuf->Start()), pBuf->DataLength());
VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_gatt_set_value() failed: %s", get_error_message(ret)));
- ChipLogProgress(DeviceLayer, "Sending indication for CHIPoBLE RX characteristic (con %s, len %u)", conn->peerAddr,
+ ChipLogProgress(DeviceLayer, "Sending indication for CHIPoBLE RX characteristic (con %s, len %u)", conId->peerAddr,
pBuf->DataLength());
- ret = bt_gatt_server_notify_characteristic_changed_value(mGattCharC2Handle, IndicationConfirmationCb, conn->peerAddr, nullptr);
+ ret = bt_gatt_server_notify_characteristic_changed_value(
+ mGattCharC2Handle,
+ +[](int result, const char * remoteAddress, bt_gatt_server_h server, bt_gatt_h characteristic, bool completed,
+ void * self) {
+ return reinterpret_cast<BLEManagerImpl *>(self)->IndicationConfirmationCb(result, remoteAddress, server, characteristic,
+ completed);
+ },
+ conId->peerAddr, this);
VerifyOrExit(
ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_gatt_server_notify_characteristic_changed_value() failed: %s", get_error_message(ret)));
@@ -1326,7 +1366,6 @@
{
Ble::ChipBleUUID service_uuid;
Ble::ChipBleUUID char_write_uuid;
- auto conn = static_cast<BLEConnection *>(conId);
int ret;
ChipLogProgress(DeviceLayer, "SendWriteRequest");
@@ -1334,20 +1373,20 @@
StringToUUID(chip_ble_service_uuid, service_uuid);
StringToUUID(chip_ble_char_c1_tx_uuid, char_write_uuid);
- VerifyOrExit(conn != nullptr, ChipLogError(DeviceLayer, "Invalid Connection"));
+ VerifyOrExit(conId != nullptr, ChipLogError(DeviceLayer, "Invalid Connection"));
VerifyOrExit(Ble::UUIDsMatch(svcId, &service_uuid),
ChipLogError(DeviceLayer, "SendWriteRequest() called with invalid service ID"));
VerifyOrExit(Ble::UUIDsMatch(charId, &char_write_uuid),
ChipLogError(DeviceLayer, "SendWriteRequest() called with invalid characteristic ID"));
- VerifyOrExit(conn->gattCharC1Handle != nullptr, ChipLogError(DeviceLayer, "Char C1 is null"));
+ VerifyOrExit(conId->gattCharC1Handle != nullptr, ChipLogError(DeviceLayer, "Char C1 is null"));
- ret = bt_gatt_set_value(conn->gattCharC1Handle, Uint8::to_const_char(pBuf->Start()), pBuf->DataLength());
+ ret = bt_gatt_set_value(conId->gattCharC1Handle, Uint8::to_const_char(pBuf->Start()), pBuf->DataLength());
VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_gatt_set_value() failed: %s", get_error_message(ret)));
- ChipLogProgress(DeviceLayer, "Sending Write Request for CHIPoBLE TX characteristic (con %s, len %u)", conn->peerAddr,
+ ChipLogProgress(DeviceLayer, "Sending Write Request for CHIPoBLE TX characteristic (con %s, len %u)", conId->peerAddr,
pBuf->DataLength());
- ret = bt_gatt_client_write_value(conn->gattCharC1Handle, WriteCompletedCb, conn);
+ ret = bt_gatt_client_write_value(conId->gattCharC1Handle, WriteCompletedCb, conId);
VerifyOrExit(ret == BT_ERROR_NONE,
ChipLogError(DeviceLayer, "bt_gatt_client_write_value() failed: %s", get_error_message(ret)));
return true;
@@ -1382,8 +1421,8 @@
ChipLogProgress(DeviceLayer, "NewConnection: long discriminator value [%u]", connDiscriminator.GetLongValue());
}
- // Initiate Scan.
- PlatformMgr().ScheduleWork(InitiateScan, static_cast<intptr_t>(BleScanState::kScanForDiscriminator));
+ // Scan initiation performed async, to ensure that the BLE subsystem is initialized.
+ DeviceLayer::SystemLayer().ScheduleLambda([this] { InitiateScan(BleScanState::kScanForDiscriminator); });
}
void BLEManagerImpl::InitiateScan(BleScanState scanType)
@@ -1434,11 +1473,6 @@
BleConnectionDelegate::OnConnectionError(mBLEScanConfig.mAppState, err);
}
-void BLEManagerImpl::InitiateScan(intptr_t arg)
-{
- sInstance.InitiateScan(static_cast<BleScanState>(arg));
-}
-
CHIP_ERROR BLEManagerImpl::CancelConnection()
{
return CHIP_ERROR_NOT_IMPLEMENTED;
diff --git a/src/platform/Tizen/BLEManagerImpl.h b/src/platform/Tizen/BLEManagerImpl.h
index d0080ec..1a49b9d 100644
--- a/src/platform/Tizen/BLEManagerImpl.h
+++ b/src/platform/Tizen/BLEManagerImpl.h
@@ -150,6 +150,7 @@
static BLEManagerImpl sInstance;
// ===== Private members reserved for use by this class only.
+
enum class Flags : uint16_t
{
kAsyncInitCompleted = 0x0001, /**< One-time asynchronous initialization actions have been performed. */
@@ -164,25 +165,24 @@
kAdvertisingRefreshNeeded = 0x0200, /**< The advertising configuration/state in BLE layer needs to be updated. */
};
- static CHIP_ERROR _BleInitialize(void * userData);
+ // Minimum and maximum advertising intervals in units of 0.625ms.
+ using AdvertisingIntervals = std::pair<uint16_t, uint16_t>;
+
+ CHIP_ERROR _InitImpl();
+
void DriveBLEState();
- static void DriveBLEState(intptr_t arg);
void InitiateScan(BleScanState scanType);
- static void InitiateScan(intptr_t arg);
- static void AdvertisingStateChangedCb(int result, bt_advertiser_h advertiser, bt_adapter_le_advertising_state_e advState,
- void * userData);
- static void NotificationStateChangedCb(bool notify, bt_gatt_server_h server, bt_gatt_h gattHandle, void * userData);
- static void ReadValueRequestedCb(const char * remoteAddress, int requestId, bt_gatt_server_h server, bt_gatt_h gattHandle,
- int offset, void * userData);
- static void WriteValueRequestedCb(const char * remoteAddress, int requestId, bt_gatt_server_h server, bt_gatt_h gattHandle,
- bool responseNeeded, int offset, const char * value, int len, void * userData);
- static void IndicationConfirmationCb(int result, const char * remoteAddress, bt_gatt_server_h server, bt_gatt_h characteristic,
- bool completed, void * userData);
- static void IndicationConfirmationCb(bt_gatt_h characteristic, bt_gatt_server_notification_sent_cb callback,
- const char * device_address, void * userData);
- static void GattConnectionStateChangedCb(int result, bool connected, const char * remoteAddress, void * userData);
+ 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);
+ void ReadValueRequestedCb(const char * remoteAddress, int requestId, bt_gatt_server_h server, bt_gatt_h gattHandle, int offset);
+ void WriteValueRequestedCb(const char * remoteAddress, int requestId, bt_gatt_server_h server, bt_gatt_h gattHandle,
+ bool responseNeeded, int offset, const char * value, int len);
+ void IndicationConfirmationCb(int result, const char * remoteAddress, bt_gatt_server_h server, bt_gatt_h characteristic,
+ bool completed);
+ void GattConnectionStateChangedCb(int result, bool connected, const char * remoteAddress);
static void WriteCompletedCb(int result, bt_gatt_h gattHandle, void * userData);
static void CharacteristicNotificationCb(bt_gatt_h characteristic, char * value, int len, void * userData);
@@ -193,8 +193,8 @@
void HandleC1CharWriteEvent(BLE_CONNECTION_OBJECT conId, const uint8_t * value, size_t len);
void HandleRXCharChanged(BLE_CONNECTION_OBJECT conId, const uint8_t * value, size_t len);
void HandleConnectionEvent(bool connected, const char * remoteAddress);
- static void HandleConnectionTimeout(System::Layer * layer, void * data);
- static bool IsDeviceChipPeripheral(BLE_CONNECTION_OBJECT conId);
+ static void HandleConnectionTimeout(System::Layer * layer, void * appState);
+ bool IsDeviceChipPeripheral(BLE_CONNECTION_OBJECT conId);
// ==== BLE Adv & GATT Server.
void NotifyBLEPeripheralGATTServerRegisterComplete(bool aIsSuccess, void * apAppstate);
@@ -204,9 +204,11 @@
void NotifyBLESubscribed(bool indicationsEnabled, BLE_CONNECTION_OBJECT conId);
void NotifyBLEIndicationConfirmation(BLE_CONNECTION_OBJECT conId);
void NotifyBLEWriteReceived(System::PacketBufferHandle & buf, BLE_CONNECTION_OBJECT conId);
+ static void HandleAdvertisingTimeout(chip::System::Layer *, void * appState);
+ AdvertisingIntervals GetAdvertisingIntervals() const;
// ==== Connection.
- static CHIP_ERROR ConnectChipThing(const char * userData);
+ 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 NotifyHandleNewConnection(BLE_CONNECTION_OBJECT conId);
diff --git a/src/platform/Tizen/BlePlatformConfig.h b/src/platform/Tizen/BlePlatformConfig.h
index 7877788..f31ac71 100644
--- a/src/platform/Tizen/BlePlatformConfig.h
+++ b/src/platform/Tizen/BlePlatformConfig.h
@@ -24,7 +24,17 @@
#pragma once
+namespace chip {
+namespace DeviceLayer {
+namespace Internal {
+class BLEConnection;
+} // namespace Internal
+} // namespace DeviceLayer
+} // namespace chip
+
// ==================== Platform Adaptations ====================
+#define BLE_CONNECTION_OBJECT chip::DeviceLayer::Internal::BLEConnection *
+#define BLE_CONNECTION_UNINITIALIZED nullptr
// ========== Platform-specific Configuration Overrides =========