Cancelling connection while connecting to switch is problematic

Issue #1307 resolved
Chris created an issue

I’m writing a ASCOM driver for a Bluetooth LE controlled switch I’ve been working on. The driver supports multiple independent BLE switches. When connecting to the switch driver from NINA the bluetooth driver and OS can take around 1 second per BLE switch before connection is completed. So for 5 switches it may take 5 seconds.

The problem occurs when the user tries to cancel connection while the switch is still connecting.

If after clicking Connect in NINA, and the user clicks Connect again before connection has completed, then NINA does not send any commands to the switch driver via the ISwitchV2 interface. NINA will cancel the connection and no switches will be displayed on the NINA Equipment->Switch page, however, the ASCOM switch driver continues and completes the connection.

This results in an inconsistent state with the driver connected but NINA not showing it.

Is a change like this possible in SwitchVM.cs? Something like the example below? (referencing branch Master starting at line: 283)

                } catch (OperationCanceledException) {
                    if (SwitchInfo.Connected) 
                        await Disconnect(); 
                    else
                        switchHub?.Disconnect();

                    return false;

Sending Connected = false to the ASCOM ISwitchV2 interface effectively tells the driver that the connection has been cancelled.

Thanks

Comments (25)

  1. Dale Ghent

    You might note that there is no way for an app to cancel an ongoing action in an ASCOM driver. The Connected property, being a settable property, cannot be passed a cancellation token or anything of that nature. Aside from AbortExposure() in the ICamera interface, there is no general interface that allows an app to signal to the driver to stop whatever it is doing. Behavior of client apps is that, once an action is initiated, that action is expected to be completed.

    From an interface semantics standpoint, NINA is arguably doing the right thing here - setting Connected=true is not so much an act of the app connecting to the ASCOM driver, but rather the app telling the ASCOM driver to connect to its hardware. Since the action of connecting to the hardware cannot be cancelled (it must succeed or fail) your driver is doing the right thing, and NINA is also doing the right thing by no longer using the ASCOM driver as its switch device.

  2. Chris reporter

    From an interface semantics standpoint, NINA is arguably doing the right thing here - setting Connected=true is not so much an act of the app connecting to the ASCOM driver, but rather the app telling the ASCOM driver to connect to its hardware. Since the action of connecting to the hardware cannot be cancelled (it must succeed or fail) your driver is doing the right thing, and NINA is also doing the right thing by no longer using the ASCOM driver as its switch device.

    However, the logical conclusion of your statement, as it stands, is that NINA shows the switch disconnected, while the switch is connected. From the users perspective pressing the connected button while connecting is clearly a request not to connect the switch driver. The expected result of this use case is that the switch will not be connected, but it is.

    The ASCOM Switch API only exposes a bool, Connected. This only allows for 2 states. The app should set it to True if connection is required or to False if connection is not require. If the driver is in the process of connecting and the app sets Connected(false), the driver should be responsible for correctly co-ordinating this with its resources, not the app. This would maintain consistency for the user. Currently with NINA, if the user cancels the connection before the driver has completed connection, does not communicate to the API at all and leaves Connected set to True.

    I’ve tried my driver with this use case on SGPro, without a problem.

  3. Dale Ghent

    The definition of the Connected property is pretty clear:

    Set True to connect to the device hardware. Set False to disconnect from the device hardware. You can also read the property to check whether it is connected. This reports the current hardware state.

    So what if another app has already set Connected=true and a cancelled NINA use of the driver induces the driver to disconnect from its hardware while the other app is attempting to use it? NINA would be pulling the rug out from under it.

  4. Chris reporter

    So what if another app has already set Connected=true and a cancelled NINA use of the driver induces the driver to disconnect from its hardware while the other app is attempting to use it? NINA would be pulling the rug out from under it.

    Currently, when the switch driver has completed connection and is Connected == true, if the disconnect button is pressed on NINA Connect(false) is sent. Are you saying that this is incorrect as it will shut disconnect the switch driver for any other accessing apps?

  5. Dale Ghent

    A clearly unintentional connect in NINA (by virtue of the use being cancelled) can make the situation worse by just-as-unintentionally inducing the driver to drop its management of its connected hardware. Since NINA cannot know if another app is or started using the driver and its hardware at the same time, it would be dicey to order a disconnect following an unintentional use.

    Purposeful disconnects are a different story, either by clicking the disconnect button in NINA or via sequencer instruction such as the ones provided by the Connector plugin. NINA cannot construe use of these as anything but intentional. The modal disconnect confirmation when manually disusing the driver via pressing the disconnect button in the UI helps ensure this intention.

    This kind of dance is what needs to be done since the ASCOM drivers provide no sort of state or reference count cues to clients. Some drivers attempt to do some sort of reference counting based on Connect sets of true and false, but some don’t do this and take any order to disconnect literally.

  6. Chris reporter

    Currently there is no modal disconnect confirmation on Switches. I would support adding modal confirmation as a solution to this problem as long as a Connected(false) is sent to the driver on confirmation.

    Also I have thought about connect/disconnect counting on the driver side before, however, inconsistent use of Connected() (as with this problem) by NINA do not support this solution.

  7. Chris reporter

    Thanks Stefan, I’ve written a switch driver stub that does nothing but look like a switch and delay any connection by 5 seconds for testing. If it will speed things up I can send you a link.

  8. Chris reporter

    Here is the driver exe and also an installer if needed.

    Test Switch Driver

    Also, something I haven't mentioned before is that after you cancel the connection, the next connection attempt causes NINA to display 2 copies of the same switch. My tests show the 2 issues are related and can be fixed with the code is added in the first post. However, if you want I can open a new Issue for this.

  9. Chris reporter

    I’ve checked the 3.1 release and the 2 issues described here are still present.

    Failures still occur.

    Chris

  10. Stefan B repo owner

    Alright i got it to register.
    I click connect - then immediately cancel it. Takes a moment but is disconnected.
    Then i connect again - it connects immediately but shows two switches - which i suppose is the incorrect behavior.
    So only one of the described problems is still present, isn’t it?

  11. Stefan B repo owner

    And i found the problem for this one. Overlooked one code path. Will fix that one too then. Sorry for missing this one.

  12. Chris reporter

    The original problem was that if the user clicked disconnect the second time, before the driver had connected, then NINA would not send a Connected = false to the driver. This would mean that the driver would complete the connection but NINA would show disconnected. What is needed, from my perspective is that if the device is disconnected, even if connection has not been completed, a connected = false is sent to the driver.

    The double up switch indications did not happen if NINA sent a connected false to the driver.

    If you want me to check here you can send me your changes.

    Chris

  13. Stefan B repo owner

    You can grab the latest version on the develop branch. these changes there should work and fix both problems. Now a cancellation sends a disconnect signal to the switch in case it was connected and a duplication of switches won’t happen anymore.

    I’ve also applied this logic to the other device viewmodels so it is consistent.

  14. Chris reporter

    Yeah, I’ve tested the dev branch and the issue is fixed.

    Thanks Stefan for looking at this problem, and for NINA. 👍

    Chris

  15. Log in to comment