@@ -325,35 +325,14 @@ void OperationalSessionSetup::EnqueueConnectionCallbacks(Callback::Callback<OnDe
325
325
Callback::Callback<OnDeviceConnectionFailure> * onFailure,
326
326
Callback::Callback<OnSetupFailure> * onSetupFailure)
327
327
{
328
- if (onConnection != nullptr )
329
- {
330
- mConnectionSuccess .Enqueue (onConnection->Cancel ());
331
- }
332
-
333
- if (onFailure != nullptr )
334
- {
335
- mConnectionFailure .Enqueue (onFailure->Cancel ());
336
- }
337
-
338
- if (onSetupFailure != nullptr )
339
- {
340
- mSetupFailure .Enqueue (onSetupFailure->Cancel ());
341
- }
328
+ mCallbacks .Enqueue (onConnection, onFailure, onSetupFailure);
342
329
}
343
330
344
331
void OperationalSessionSetup::DequeueConnectionCallbacks (CHIP_ERROR error, SessionEstablishmentStage stage,
345
332
ReleaseBehavior releaseBehavior)
346
333
{
347
- Cancelable failureReady, setupFailureReady, successReady;
348
-
349
- //
350
- // Dequeue both failure and success callback lists into temporary stack args before invoking either of them.
351
- // We do this since we may not have a valid 'this' pointer anymore upon invoking any of those callbacks
352
- // since the callee may destroy this object as part of that callback.
353
- //
354
- mConnectionFailure .DequeueAll (failureReady);
355
- mSetupFailure .DequeueAll (setupFailureReady);
356
- mConnectionSuccess .DequeueAll (successReady);
334
+ // We expect that we only have callbacks if we are not performing just address update.
335
+ VerifyOrDie (!mPerformingAddressUpdate || mCallbacks .IsEmpty ());
357
336
358
337
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
359
338
// Clear out mConnectionRetry, so that those cancelables are not holding
@@ -365,7 +344,8 @@ void OperationalSessionSetup::DequeueConnectionCallbacks(CHIP_ERROR error, Sessi
365
344
#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
366
345
367
346
// Gather up state we will need for our notifications.
368
- bool performingAddressUpdate = mPerformingAddressUpdate ;
347
+ SuccessFailureCallbackList readyCallbacks;
348
+ readyCallbacks.EnqueueTakeAll (mCallbacks );
369
349
auto * exchangeMgr = mInitParams .exchangeMgr ;
370
350
Optional<SessionHandle> optionalSessionHandle = mSecureSession .Get ();
371
351
ScopedNodeId peerId = mPeerId ;
@@ -383,71 +363,57 @@ void OperationalSessionSetup::DequeueConnectionCallbacks(CHIP_ERROR error, Sessi
383
363
}
384
364
385
365
// DO NOT touch any members of this object after this point. It's dead.
386
-
387
- NotifyConnectionCallbacks (failureReady, setupFailureReady, successReady, error, stage, peerId, performingAddressUpdate,
388
- exchangeMgr, optionalSessionHandle, requestedBusyDelay);
366
+ NotifyConnectionCallbacks (readyCallbacks, error, stage, peerId, exchangeMgr, optionalSessionHandle, requestedBusyDelay);
389
367
}
390
368
391
- void OperationalSessionSetup::NotifyConnectionCallbacks (Cancelable & failureReady, Cancelable & setupFailureReady,
392
- Cancelable & successReady, CHIP_ERROR error,
369
+ void OperationalSessionSetup::NotifyConnectionCallbacks (SuccessFailureCallbackList & ready, CHIP_ERROR error,
393
370
SessionEstablishmentStage stage, const ScopedNodeId & peerId,
394
- bool performingAddressUpdate, Messaging::ExchangeManager * exchangeMgr,
371
+ Messaging::ExchangeManager * exchangeMgr,
395
372
const Optional<SessionHandle> & optionalSessionHandle,
396
373
System::Clock::Milliseconds16 requestedBusyDelay)
397
374
{
398
- //
399
- // If we encountered no error, go ahead and call all success callbacks. Otherwise,
400
- // call the failure callbacks.
401
- //
402
- while (failureReady.mNext != &failureReady)
375
+ Callback::Callback<OnDeviceConnected> * onConnected;
376
+ Callback::Callback<OnDeviceConnectionFailure> * onConnectionFailure;
377
+ Callback::Callback<OnSetupFailure> * onSetupFailure;
378
+ while (ready.Take (onConnected, onConnectionFailure, onSetupFailure))
403
379
{
404
- // We expect that we only have callbacks if we are not performing just address update.
405
- VerifyOrDie (!performingAddressUpdate);
406
- Callback::Callback<OnDeviceConnectionFailure> * cb =
407
- Callback::Callback<OnDeviceConnectionFailure>::FromCancelable (failureReady.mNext );
408
-
409
- cb->Cancel ();
410
-
411
- if (error != CHIP_NO_ERROR)
380
+ if (error == CHIP_NO_ERROR)
412
381
{
413
- cb->mCall (cb->mContext , peerId, error);
382
+ VerifyOrDie (exchangeMgr);
383
+ VerifyOrDie (optionalSessionHandle.Value ()->AsSecureSession ()->IsActiveSession ());
384
+ if (onConnected != nullptr )
385
+ {
386
+ onConnected->mCall (onConnected->mContext , *exchangeMgr, optionalSessionHandle.Value ());
387
+
388
+ // That sucessful call might have made the session inactive. If it did, then we should
389
+ // not call any more success callbacks, since we do not in fact have an active session
390
+ // for them, and if they try to put the session in a holder that will fail, and then
391
+ // trying to use the holder as if it has a session will crash.
392
+ if (!optionalSessionHandle.Value ()->AsSecureSession ()->IsActiveSession ())
393
+ {
394
+ ChipLogError (Discovery, " Success callback for connection to " ChipLogFormatScopedNodeId " tore down session" ,
395
+ ChipLogValueScopedNodeId (peerId));
396
+ error = CHIP_ERROR_CONNECTION_ABORTED;
397
+ }
398
+ }
414
399
}
415
- }
416
-
417
- while (setupFailureReady.mNext != &setupFailureReady)
418
- {
419
- // We expect that we only have callbacks if we are not performing just address update.
420
- VerifyOrDie (!performingAddressUpdate);
421
- Callback::Callback<OnSetupFailure> * cb = Callback::Callback<OnSetupFailure>::FromCancelable (setupFailureReady.mNext );
422
-
423
- cb->Cancel ();
424
-
425
- if (error != CHIP_NO_ERROR)
400
+ else // error
426
401
{
427
- // Initialize the ConnnectionFailureInfo object
428
- ConnnectionFailureInfo failureInfo (peerId, error, stage);
429
- #if CHIP_CONFIG_ENABLE_BUSY_HANDLING_FOR_OPERATIONAL_SESSION_SETUP
430
- if (error == CHIP_ERROR_BUSY)
402
+ if (onConnectionFailure != nullptr )
431
403
{
432
- failureInfo. requestedBusyDelay . Emplace (requestedBusyDelay );
404
+ onConnectionFailure-> mCall (onConnectionFailure-> mContext , peerId, error );
433
405
}
406
+ if (onSetupFailure != nullptr )
407
+ {
408
+ ConnnectionFailureInfo failureInfo (peerId, error, stage);
409
+ #if CHIP_CONFIG_ENABLE_BUSY_HANDLING_FOR_OPERATIONAL_SESSION_SETUP
410
+ if (error == CHIP_ERROR_BUSY)
411
+ {
412
+ failureInfo.requestedBusyDelay .Emplace (requestedBusyDelay);
413
+ }
434
414
#endif // CHIP_CONFIG_ENABLE_BUSY_HANDLING_FOR_OPERATIONAL_SESSION_SETUP
435
- cb->mCall (cb->mContext , failureInfo);
436
- }
437
- }
438
-
439
- while (successReady.mNext != &successReady)
440
- {
441
- // We expect that we only have callbacks if we are not performing just address update.
442
- VerifyOrDie (!performingAddressUpdate);
443
- Callback::Callback<OnDeviceConnected> * cb = Callback::Callback<OnDeviceConnected>::FromCancelable (successReady.mNext );
444
-
445
- cb->Cancel ();
446
- if (error == CHIP_NO_ERROR)
447
- {
448
- VerifyOrDie (exchangeMgr);
449
- // We know that we for sure have the SessionHandle in the successful case.
450
- cb->mCall (cb->mContext , *exchangeMgr, optionalSessionHandle.Value ());
415
+ onSetupFailure->mCall (onSetupFailure->mContext , failureInfo);
416
+ }
451
417
}
452
418
}
453
419
}
0 commit comments