diff --git a/internal/platform/implementation/apple/ble_l2cap_server_socket.h b/internal/platform/implementation/apple/ble_l2cap_server_socket.h index 87a148ba..9a5b664c 100644 --- a/internal/platform/implementation/apple/ble_l2cap_server_socket.h +++ b/internal/platform/implementation/apple/ble_l2cap_server_socket.h @@ -30,7 +30,7 @@ class BleL2capServerSocket : public api::ble_v2::BleL2capServerSocket { // Gets PSM value has been published by the server. int GetPSM() const override; - + // Sets PSM value has been published by the server. void SetPSM(int psm); @@ -52,6 +52,12 @@ class BleL2capServerSocket : public api::ble_v2::BleL2capServerSocket { // Adds a pending socket to the server socket. bool AddPendingSocket(std::unique_ptr socket); + // Called by the server side of a connection before accessing the server + // socket pointer at the callback of l2cap channel creation, to track validity + // of a pointer to this server socket. + void SetCloseNotifier(absl::AnyInvocable notifier) + ABSL_LOCKS_EXCLUDED(mutex_); + private: Exception DoClose() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); diff --git a/internal/platform/implementation/apple/ble_l2cap_server_socket.mm b/internal/platform/implementation/apple/ble_l2cap_server_socket.mm index c03fca06..66c8a096 100644 --- a/internal/platform/implementation/apple/ble_l2cap_server_socket.mm +++ b/internal/platform/implementation/apple/ble_l2cap_server_socket.mm @@ -57,6 +57,11 @@ bool BleL2capServerSocket::AddPendingSocket(std::unique_ptr sock return !closed_; } +void BleL2capServerSocket::SetCloseNotifier(absl::AnyInvocable notifier) { + absl::MutexLock lock(&mutex_); + close_notifier_ = std::move(notifier); +} + Exception BleL2capServerSocket::Close() { absl::MutexLock lock(&mutex_); return DoClose(); diff --git a/internal/platform/implementation/apple/ble_medium.h b/internal/platform/implementation/apple/ble_medium.h index f5abc457..c4c8f509 100644 --- a/internal/platform/implementation/apple/ble_medium.h +++ b/internal/platform/implementation/apple/ble_medium.h @@ -29,7 +29,7 @@ #include "internal/platform/implementation/ble_v2.h" #include "internal/platform/implementation/bluetooth_adapter.h" #include "internal/platform/uuid.h" - +#import "internal/platform/implementation/apple/ble_l2cap_server_socket.h" #import "internal/platform/implementation/apple/ble_server_socket.h" #import "internal/platform/implementation/apple/bluetooth_adapter_v2.h" @@ -219,6 +219,9 @@ class BleMedium : public api::ble_v2::BleMedium { // Used for the async version of StartAdvertising and has both an advertisement found and result // callback. api::ble_v2::BleMedium::ScanningCallback scanning_cb_; + + absl::Mutex l2cap_server_socket_mutex_; + BleL2capServerSocket *l2cap_server_socket_ptr_ = nullptr; }; } // namespace apple diff --git a/internal/platform/implementation/apple/ble_medium.mm b/internal/platform/implementation/apple/ble_medium.mm index 08ac29ed..912c3c4b 100644 --- a/internal/platform/implementation/apple/ble_medium.mm +++ b/internal/platform/implementation/apple/ble_medium.mm @@ -423,7 +423,14 @@ std::unique_ptr BleMedium::OpenL2capServerSoc dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); __block NSError *blockPSMPublishedError = nil; auto l2cap_server_socket = std::make_unique(); - __block auto l2cap_server_socket_ptr = l2cap_server_socket.get(); + l2cap_server_socket->SetCloseNotifier([this]() { + absl::MutexLock lock(&l2cap_server_socket_mutex_); + l2cap_server_socket_ptr_ = nullptr; + }); + { + absl::MutexLock lock(&l2cap_server_socket_mutex_); + l2cap_server_socket_ptr_ = l2cap_server_socket.get(); + } std::string service_id_str = service_id; [medium_ openL2CAPServerWithPSMPublishedCompletionHandler:^(uint16_t PSM, NSError *_Nullable error) { @@ -432,7 +439,12 @@ std::unique_ptr BleMedium::OpenL2capServerSoc dispatch_semaphore_signal(semaphore); return; } - l2cap_server_socket_ptr->SetPSM(PSM); + { + absl::MutexLock lock(&l2cap_server_socket_mutex_); + if (l2cap_server_socket_ptr_) { + l2cap_server_socket_ptr_->SetPSM(PSM); + } + } dispatch_semaphore_signal(semaphore); } channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream, @@ -447,8 +459,11 @@ std::unique_ptr BleMedium::OpenL2capServerSoc incomingConnection:YES callbackQueue:dispatch_get_main_queue()]; auto socket = std::make_unique(connection); - if (l2cap_server_socket_ptr) { - l2cap_server_socket_ptr->AddPendingSocket(std::move(socket)); + { + absl::MutexLock lock(&l2cap_server_socket_mutex_); + if (l2cap_server_socket_ptr_) { + l2cap_server_socket_ptr_->AddPendingSocket(std::move(socket)); + } } } peripheralManager:nil];