@@ -270,6 +270,7 @@ async def _ensure_connected(self):
270270 ble_device_callback = lambda : self ._device ,
271271 )
272272 _LOGGER .debug ("%s: Connected; RSSI: %s" , self .name , self .rssi )
273+ self ._client = client
273274
274275 try :
275276 self ._resolve_characteristics (client .services )
@@ -282,10 +283,10 @@ async def _ensure_connected(self):
282283 exc_info = True ,
283284 )
284285 await client .clear_cache ()
285- await self ._execute_forced_disconnect ()
286+ self ._cancel_disconnect_timer ()
287+ await self ._execute_disconnect_with_lock ()
286288 raise
287289
288- self ._client = client
289290 self ._reset_disconnect_timer ()
290291 await self ._start_notify ()
291292
@@ -358,18 +359,28 @@ async def _execute_timed_disconnect(self) -> None:
358359
359360 async def _execute_disconnect (self ) -> None :
360361 """Execute disconnection."""
362+ _LOGGER .debug ("%s: Executing disconnect" , self .name )
361363 async with self ._connect_lock :
362- if self ._disconnect_timer : # If the timer was reset, don't disconnect
363- return
364- client = self ._client
365- self ._expected_disconnect = True
366- self ._client = None
367- self ._read_char = None
368- self ._write_char = None
369- if client and client .is_connected :
370- _LOGGER .debug ("%s: Disconnecting" , self .name )
371- await client .disconnect ()
372- _LOGGER .debug ("%s: Disconnect completed" , self .name )
364+ await self ._execute_disconnect_with_lock ()
365+
366+ async def _execute_disconnect_with_lock (self ) -> None :
367+ """Execute disconnection while holding the lock."""
368+ assert self ._connect_lock .locked (), "Lock not held"
369+ _LOGGER .debug ("%s: Executing disconnect with lock" , self .name )
370+ if self ._disconnect_timer : # If the timer was reset, don't disconnect
371+ _LOGGER .debug ("%s: Skipping disconnect as timer reset" , self .name )
372+ return
373+ client = self ._client
374+ self ._expected_disconnect = True
375+ self ._client = None
376+ self ._read_char = None
377+ self ._write_char = None
378+ if client and client .is_connected :
379+ _LOGGER .debug ("%s: Disconnecting" , self .name )
380+ await client .disconnect ()
381+ _LOGGER .debug ("%s: Disconnect completed" , self .name )
382+ else :
383+ _LOGGER .debug ("%s: Already disconnected" , self .name )
373384
374385 async def _send_command_locked (self , key : str , command : bytes ) -> bytes :
375386 """Send command to device and read response."""
0 commit comments