From ca8e70f6131982de53c6fb48c4fc41720dd4746b Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Thu, 3 Jul 2025 10:04:27 -0700 Subject: [PATCH] Apply real PSM value in DCT advertising PiperOrigin-RevId: 778914950 --- .../advertisements/dct_advertisement.cc | 6 +- .../advertisements/dct_advertisement_test.cc | 10 +++ connections/implementation/mediums/ble_v2.cc | 83 ++++++++++--------- connections/implementation/mediums/ble_v2.h | 7 +- .../implementation/p2p_cluster_pcp_handler.cc | 7 +- 5 files changed, 65 insertions(+), 48 deletions(-) diff --git a/connections/implementation/mediums/advertisements/dct_advertisement.cc b/connections/implementation/mediums/advertisements/dct_advertisement.cc index 1d782ac2..77cbf0ed 100644 --- a/connections/implementation/mediums/advertisements/dct_advertisement.cc +++ b/connections/implementation/mediums/advertisements/dct_advertisement.cc @@ -117,9 +117,9 @@ std::optional DctAdvertisement::Parse( LOG(WARNING) << "Invalid PSM."; return std::nullopt; } - std::string psm_str = psm->value().data(); - dct_advertisement.psm_ = - (static_cast(psm_str[0]) << 8) | psm_str[1]; + + StreamReader psm_reader(ByteArray(psm->value())); + dct_advertisement.psm_ = psm_reader.ReadUint16().value_or(0); // Read device information std::optional device_information = diff --git a/connections/implementation/mediums/advertisements/dct_advertisement_test.cc b/connections/implementation/mediums/advertisements/dct_advertisement_test.cc index 4a293c17..eabf10d2 100644 --- a/connections/implementation/mediums/advertisements/dct_advertisement_test.cc +++ b/connections/implementation/mediums/advertisements/dct_advertisement_test.cc @@ -103,5 +103,15 @@ TEST(DctAdvertisementTest, GenerateEndpointIdWithInvalidParameters) { DctAdvertisement::GenerateEndpointId(0x10, "device\xff").has_value()); } +TEST(DctAdvertisementTest, ParseData) { + std::optional dct_advertisement = + DctAdvertisement::Parse(std::string("\x20\x25\x6d\xfd\x24\x00\xc0\x88\x07" + "\x96\x74\x65\x73\x74\x64\x65\x76", + 17)); + EXPECT_TRUE(dct_advertisement.has_value()); + EXPECT_EQ(dct_advertisement->GetDeviceName(), "testdev"); + EXPECT_EQ(dct_advertisement->GetPsm(), 192); +} + } // namespace } // namespace nearby::connections::advertisements::ble diff --git a/connections/implementation/mediums/ble_v2.cc b/connections/implementation/mediums/ble_v2.cc index bc8a1254..30f997c8 100644 --- a/connections/implementation/mediums/ble_v2.cc +++ b/connections/implementation/mediums/ble_v2.cc @@ -663,7 +663,7 @@ ErrorOr BleV2::StartAcceptingConnections( } // TODO(mingshiouwu): Add unit test for ble_l2cap flow -ErrorOr BleV2::StartAcceptingL2capConnections( +ErrorOr BleV2::StartAcceptingL2capConnections( const std::string& service_id, AcceptedL2capConnectionCallback callback) { MutexLock lock(&mutex_); if (service_id.empty()) { @@ -696,50 +696,55 @@ ErrorOr BleV2::StartAcceptingL2capConnections( BleL2capServerSocket server_socket = medium_.OpenL2capServerSocket(service_id); - if (server_socket.IsValid()) { - // Mark the fact that there's an in-progress Ble server accepting - // connections. - auto owned_server_socket = - l2cap_server_sockets_.insert({service_id, std::move(server_socket)}) - .first->second; - // Start the accept loop on a dedicated thread - this stays alive and - // listening for new incoming connections until StopAcceptingConnections() - // is invoked. - accept_loops_runner_.Execute( - "ble-l2cap-accept", - [this, service_id, callback = std::move(callback), - server_socket = std::move(owned_server_socket)]() mutable { - while (true) { - BleL2capSocket client_socket = server_socket.Accept(); - if (!client_socket.IsValid()) { - LOG(WARNING) << "The client L2CAP socket to accept is invalid."; - server_socket.Close(); - break; - } else { - LOG(INFO) << "The client L2CAP socket has been accepted."; - } - { - MutexLock lock(&mutex_); - client_socket.SetCloseNotifier([this, service_id]() { - MutexLock lock(&mutex_); - incoming_sockets_.erase(service_id); - }); - l2cap_incoming_service_id_to_sockets_.insert( - {service_id, client_socket}); - } - if (callback) { - callback(std::move(client_socket), service_id); - } - } - }); - } else { + if (!server_socket.IsValid()) { LOG(INFO) << "Failed to start accepting Ble L2CAP connections for service_id=" << service_id; + return {Error(OperationResultCode:: + CONNECTIVITY_L2CAP_SERVER_SOCKET_CREATION_FAILURE)}; } + + int psm = server_socket.GetPSM(); + + // Mark the fact that there's an in-progress Ble server accepting + // connections. + auto owned_server_socket = + l2cap_server_sockets_.insert({service_id, std::move(server_socket)}) + .first->second; + // Start the accept loop on a dedicated thread - this stays alive and + // listening for new incoming connections until StopAcceptingConnections() + // is invoked. + accept_loops_runner_.Execute( + "ble-l2cap-accept", + [this, service_id, callback = std::move(callback), + server_socket = std::move(owned_server_socket)]() mutable { + while (true) { + BleL2capSocket client_socket = server_socket.Accept(); + if (!client_socket.IsValid()) { + LOG(WARNING) << "The client L2CAP socket to accept is invalid."; + server_socket.Close(); + break; + } else { + LOG(INFO) << "The client L2CAP socket has been accepted."; + } + { + MutexLock lock(&mutex_); + client_socket.SetCloseNotifier([this, service_id]() { + MutexLock lock(&mutex_); + incoming_sockets_.erase(service_id); + }); + l2cap_incoming_service_id_to_sockets_.insert( + {service_id, client_socket}); + } + if (callback) { + callback(std::move(client_socket), service_id); + } + } + }); + LOG(INFO) << "Start accepting Ble L2CAP connections for service_id=" << service_id; - return {true}; + return {psm}; } bool BleV2::StopAcceptingConnections(const std::string& service_id) { diff --git a/connections/implementation/mediums/ble_v2.h b/connections/implementation/mediums/ble_v2.h index f22846a9..263033d9 100644 --- a/connections/implementation/mediums/ble_v2.h +++ b/connections/implementation/mediums/ble_v2.h @@ -121,8 +121,7 @@ class BleV2 final { // service UUID16 may be used to trigger a GATT connection to retrieve GATT // characteristics for the Nearby service // These alternate uuids are active until the next call to `StopScanning`. - void AddAlternateUuidForService( - uint16_t uuid, const std::string& service_id); + void AddAlternateUuidForService(uint16_t uuid, const std::string& service_id); // Enables BLE scanning for a service ID. Will report any discoverable // advertisement data through a callback. @@ -163,7 +162,9 @@ class BleV2 final { // Starts a worker thread, creates a Ble L2CAP socket, associates it with a // service id. - ErrorOr StartAcceptingL2capConnections( + // Returns the PSM of the L2CAP channel on success, or an error code on + // failure. + ErrorOr StartAcceptingL2capConnections( const std::string& service_id, AcceptedL2capConnectionCallback l2cap_callback) ABSL_LOCKS_EXCLUDED(mutex_); diff --git a/connections/implementation/p2p_cluster_pcp_handler.cc b/connections/implementation/p2p_cluster_pcp_handler.cc index 1dda6743..882dea8b 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.cc +++ b/connections/implementation/p2p_cluster_pcp_handler.cc @@ -2737,6 +2737,9 @@ ErrorOr P2pClusterPcpHandler::StartBleV2Advertising( // Bluetooth Classic. LOG(INFO) << "P2pClusterPcpHandler::StartBleV2Advertising: service_id=" << service_id << " : start"; + + ErrorOr ble_l2cap_result = 0; + if (!ble_v2_medium_.IsAcceptingConnections(service_id)) { // TODO(b/380411884): Remove this check since we shouldn't enable radio by // NC. @@ -2750,7 +2753,6 @@ ErrorOr P2pClusterPcpHandler::StartBleV2Advertising( << service_id; return {Error(OperationResultCode::DEVICE_STATE_RADIO_ENABLING_FAILURE)}; } - ErrorOr ble_l2cap_result = true; if (NearbyFlags::GetInstance().GetBoolFlag( config_package_nearby::nearby_connections_feature:: kEnableBleL2cap)) { @@ -2864,8 +2866,7 @@ ErrorOr P2pClusterPcpHandler::StartBleV2Advertising( // Try to read device name from local_endpoint_info. std::optional device_name = advertisements::ReadDeviceName(local_endpoint_info); - // TODO(b/399740422): Get the real PSM from the L2CAP medium. - uint16_t psm = 0x11; + uint16_t psm = ble_l2cap_result.value(); if (device_name.has_value()) { std::optional dct_advertisement = advertisements::ble::DctAdvertisement::Create(