ASCOMInitiative / ASCOMPlatform

The ASCOM Platform implements the ASCOM interface standards and provides development and runtime components to ease driver and application development.
http://www.ascom-standards.org
Other
99 stars 32 forks source link

The ALPACA Dynamic Driver crashes or doesn't work correctly in several situations #76

Closed marcocipriani01 closed 2 months ago

marcocipriani01 commented 2 months ago

Today I've been constantly getting the following error when trying to access the ALPACA properties of my custom Dome Control System:

image

After I click OK on the error box, I can edit the properties and set the IP address or host name in the "Remote Device Host Name or IP Address" box. When I click OK to save, however:

image

I believe the issue first appeared when I set domecontrolsystem.local in the IP address box. Until yesterday, I was just using the IPv4 address, but today I decided to set up mDNS and use the `.local' address. Now, unfortunately, the ALPACA properties don't let me set the IPv4 address anymore, because clicking "Continue" on the error message doesn't save the settings.

Here's the full log:

See the end of this message for details on invoking 
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.NullReferenceException: Object reference not set to an instance of an object.
   at ASCOM.DynamicRemoteClients.SetupDialogForm.BtnOK_Click(Object sender, EventArgs e)
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

************** Loaded Assemblies **************
mscorlib
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.9261.0 built by: NET481REL1LAST_C
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
ASCOM.AlpacaClientLocalServer
    Assembly Version: 6.0.0.0
    Win32 Version: 6.6.2.4195
    CodeBase: file:///C:/Program%20Files%20(x86)/Common%20Files/ASCOM/AlpacaDynamicClients/ASCOM.AlpacaClientLocalServer.exe
----------------------------------------
ASCOM.Utilities
    Assembly Version: 6.0.0.0
    Win32 Version: 6.6.2.4195
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/ASCOM.Utilities/6.0.0.0__565de7938946fba7/ASCOM.Utilities.dll
----------------------------------------
System.Windows.Forms
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.9251.0 built by: NET481REL1LAST_C
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.9261.0 built by: NET481REL1LAST_C
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Drawing
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.9032.0 built by: NET481REL1
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
Microsoft.VisualBasic
    Assembly Version: 10.0.0.0
    Win32 Version: 14.8.9032.0 built by: NET481REL1
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Microsoft.VisualBasic/v4.0_10.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualBasic.dll
----------------------------------------
ASCOM.Attributes
    Assembly Version: 6.0.0.0
    Win32 Version: 6.6.2.4195
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/ASCOM.Attributes/6.0.0.0__565de7938946fba7/ASCOM.Attributes.dll
----------------------------------------
ASCOM.Alpaca
    Assembly Version: 1.0.109.0
    Win32 Version: 1.0.109.0
    CodeBase: file:///C:/Program%20Files%20(x86)/Common%20Files/ASCOM/AlpacaDynamicClients/ASCOM.Alpaca.DLL
----------------------------------------
netstandard
    Assembly Version: 2.0.0.0
    Win32 Version: 4.8.9032.0
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/netstandard/v4.0_2.0.0.0__cc7b13ffcd2ddd51/netstandard.dll
----------------------------------------
ASCOM.Common
    Assembly Version: 1.0.109.0
    Win32 Version: 1.0.109.0
    CodeBase: file:///C:/Program%20Files%20(x86)/Common%20Files/ASCOM/AlpacaDynamicClients/ASCOM.Common.DLL
----------------------------------------
ASCOM.AlpacaClientDeviceBaseClasses
    Assembly Version: 6.0.0.0
    Win32 Version: 6.6.2.4195
    CodeBase: file:///C:/Program%20Files%20(x86)/Common%20Files/ASCOM/AlpacaDynamicClients/ASCOM.AlpacaClientDeviceBaseClasses.DLL
----------------------------------------
ASCOM.DeviceInterfaces
    Assembly Version: 6.0.0.0
    Win32 Version: 6.6.2.4195
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/ASCOM.DeviceInterfaces/6.0.0.0__565de7938946fba7/ASCOM.DeviceInterfaces.dll
----------------------------------------
ASCOM.AlpacaDynamic1.Dome
    Assembly Version: 0.0.0.0
    Win32 Version: 0.0.0.0
    CodeBase: file:///C:/Program%20Files%20(x86)/Common%20Files/ASCOM/AlpacaDynamicClients/ASCOM.AlpacaDynamic1.Dome.DLL
----------------------------------------
RestSharp
    Assembly Version: 106.15.0.0
    Win32 Version: 106.15.0
    CodeBase: file:///C:/Program%20Files%20(x86)/Common%20Files/ASCOM/AlpacaDynamicClients/RestSharp.DLL
----------------------------------------
System.Core
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.9261.0 built by: NET481REL1LAST_C
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
System.Configuration
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.9032.0 built by: NET481REL1
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.9032.0 built by: NET481REL1
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
Accessibility
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.9032.0 built by: NET481REL1
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Accessibility/v4.0_4.0.0.0__b03f5f7f11d50a3a/Accessibility.dll
----------------------------------------
ASCOM.Exceptions
    Assembly Version: 6.0.0.0
    Win32 Version: 6.6.2.4195
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/ASCOM.Exceptions/6.0.0.0__565de7938946fba7/ASCOM.Exceptions.dll
----------------------------------------
System.Web
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.9261.0 built by: NET481REL1LAST_C
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_32/System.Web/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Web.dll
----------------------------------------
System.Numerics
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.9032.0 built by: NET481REL1
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Numerics/v4.0_4.0.0.0__b77a5c561934e089/System.Numerics.dll
----------------------------------------
System.Security
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.9032.0 built by: NET481REL1
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Security/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Security.dll
----------------------------------------

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.

For example:

<configuration>
    <system.windows.forms jitDebugging="true" />
</configuration>

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.
marcocipriani01 commented 2 months ago

I attempted to delete the Dome Control System ALPACA device, but got this:

image

Looking into Task Manager, indeed, the Dynamic Client is running even though I closed every program than could be using it. The only program I currently have open is the ASCOM Device Hub, which I haven't yet connected to the dome.

I suppose the Dynamic Client has stayed open after I disconnected and closed NINA (Nighttime Imaging 'N' Astronomy) a few minutes ago. I've had this exact issue other times when using "local server" ASCOM drivers, for example the OnStep telescope driver. They sometimes remain open in the background long after the astronomy program that was using them is closed.

Anyway, this was not the issue causing the errors, but it's definitely something to look into.

image

marcocipriani01 commented 2 months ago

Well, now that I was able to delete the ALPACA device, I can't add it again using ALPACA discovery! 😂

I get this strange error:

image

I manually created the ALPACA device (with the IPv4 address, this time), but now I'm getting another error:

image

What's odd about this error is that the Dynamic Client is only sending three requests to my server, then the Device Hub UI freezes for a few seconds and shows the error above. I can see in Wireshark that only three /management URLs are queried, and no request for /api/v1/dome/0/connected is ever made. I can see the same thing in my server logs. I only get those three requests and nothing more.

I manually verified that the responses from my server are valid. Moreover, I just ran ConformU and verified that my ALPACA driver is in fact working as it should and can connect! Conformance was 100% successful, as I was expecing.

image

marcocipriani01 commented 2 months ago

Forgot to mention I'm using ASCOM 6.6 SP2 on Windows 11 23H2:

image

Peter-Simpson commented 2 months ago

Hi Marco,

Thanks for providing lots of information but I suspect that we aren't going to get very far with this until I can re-create what you are seeing, the diagnostics from the unhandled exception aren't very specific.

The Dynamic Clients have never been tested with mDNS so we're in uncharted territory!

How did you enable mDNS on Windows? Presumably you also needed to do this on your controller too?

Best wishes, Peter

marcocipriani01 commented 2 months ago

Hi Peter, mDNS works out-of-the-box in Windows. My controller is a custom STM32-based board and mDNS is provided by its network stack. Anyway, it works very reliably. In Chrome, I can access the web interface of my server, and I can test ALPACA requests with curl using the .local address.

You don't need to implement anything specific in ASCOM for mDNS to work. DNS resolution is handled by Windows. For example, in PowerShell:

PS C:\Users\marco> Resolve-DnsName domecontrolsystem.local

Name                                           Type   TTL   Section    IPAddress
----                                           ----   ---   -------    ---------
DomeControlSystem.local                        AAAA   60    Answer     fe80::80:e100:0
DomeControlSystem.local                        A      60    Answer     192.168.1.6
DomeControlSystem.local                        A      60    Additional 192.168.1.6

Do you suggest any kind of test or debugging I could do to give your more info?

I'm testing Platform 7 RC 7 right now. I'll keep you updated. Marco

marcocipriani01 commented 2 months ago

I didn't manage to go very far with Platform 7. I did a clean install and used ALPACA discovery to add my Dome Control System again. Then, I clicked "Properties" and this happened:

image

It keeps saying that the Dynamic Client is connected and a tiny window appears in the bottom-left of the screen. I tried deleting and creating the ALPACA device multiple times but every time I click on "Properties" I get the tiny window and the "Already connected" message shown above...

Device Hub isn't connected, since I didn't even try to connect. If I can't access the properties and set the username and password for my server, I will never be able to connect anyway 😅

Peter-Simpson commented 2 months ago

Hi Marco,

The "Dynamic Client is Connected" dialogue appears when the device reports that it is Connected. Trying configuring your controller so it is on the network but not in the connected state, does the expected dialogue then appear?

I'll see what I can do with mDNS here.

Regards, Peter

marcocipriani01 commented 2 months ago

You're right, if I manually set connected to false with

curl -H "Content-Type: application/json" -d "Connected=false&ClientID=1&ClientTransactionID=1" -X PUT http://domecontrolsystem.local/api/v1/dome/0/connected

I can indeed open the Properties correctly. However, for my usecase, this is very undesirable. The STM32-based board will stay powered 24/7, and when it's powered on, it is - by definition - connected. It is also always accessible via its web interface.

As a workaround to pass ALPACA conformance, I did implement the connected property, and I do correctly throw a "not connected" exception if any command (move, sync, park, ...) or status query (get azimuth, slewing, ...) is received in the non-connected state.

Since it's a device on the network, however, it is very likely that an ALPACA client might disconnect from the server without setting connected to false. In such scenario, attempting to connect again will yield the "Dynamic Client is not connected" error I was seeing.

I propose to remove that error completely, since it creates problems for every device which is also its own server. ALPACA clients shall be able to connect to a client even if it is already connected. This is especially true when a server has multiple clients that want to connect at the same time!


In other news, I think I understood why I get the "Unable to write Dome.Connected property". This is what my server received from the Dynamic Client:

GET /api/v1/dome/0/connected?ClientID=33096&ClientTransactionID=5 HTTP/1.1
Connection: keep-alive,Keep-Alive
Authorization: Basic QVFBQUFOQ01uZDhCRmRFUmpIb0F3RS9DbCtzQkFBQUFPRWtLNFdZbW9VeXVCTGZjZnlVa3J3UUFBQUFDQUFBQUFBQVFaZ0FBQUFFQUFDQUFBQUJTRHFjb2NFRGN4RTRSQ3MrS0pSOXpvQSswTE5nQlVmR1p2OTNmOEdGMWlnQUFBQUFPZ0FBQUFBSUFBQ0FBQUFCUjB4VkdWZVIybHFQWWN3NzZJUzVKN2RaeHB1LzIwTk42UFJGM295NWNtQ0FBQUFCMUV6a1BwQzR6MnBXTGZUTEpTWmNYUDBZVmt1OVZQUmtxcGJSbjFKY09yMEFBQUFCTFF2OWtkeEFwMStLN0RlNHhsMzVKeFhWWmx0d1hiT2dvY3gyRXg5Smh5OHYrWXhaby9YdGpzWmhwMWxHUzJ3OTk5Q2dwdXl1bXZqeWFFbzExa3d4MzpBUUFBQU5DTW5kOEJGZEVSakhvQXdFL0NsK3NCQUFBQU9Fa0s0V1ltb1V5dUJMZmNmeVVrcndRQUFBQUNBQUFBQUFBUVpnQUFBQUVBQUNBQUFBQlkrVW4wS0VZWWhlNkROcm5DcklQOW1IaVp2ODcwZVZ0OFh4c3N4aEM5aFFBQUFBQU9nQUFBQUFJQUFDQUFBQURCTGRFZi8yTkVtcmJZY3VpT2FLcGZvY1RGaDdxYUJzeFZUdDhrRC9Lc0loQUFBQUMyTW90eXR4bDVrSXJvdldnK0Zzdi9RQUFBQVBkV3c1Qll5TlRBaG5hYUo3RXVhcUg4T0lUWG5MaWU2UGwvYVlxNHE0cEVLblJERzBLM0l0TlVEdkk4ZUMvVDk5cEM0NThLLzdwd1Fyd256cnNLUnM4PQ==
Accept: application/json
User-Agent: ASCOMAlpacaClient/2.0.0.0
Host: 192.168.1.6

The Base64-encoded authorization sent by the Dynamic Client is complete rubbish. The correct Base64 encoding of domecontrolsystem:admin is ZG9tZWNvbnRyb2xzeXN0ZW06YWRtaW4=, not... whatever that long thing is.

See the RFC 7617 standard for more info on Basic Authorization. I can correctly login using Chrome so my server isn't to blame.

Peter-Simpson commented 2 months ago

I'm only capable of working on one thing at a time so the "complete rubbish" issue is going to have to wait until I've sorted out the issue you first reported. I'm glad there is no "blame" associated with your server.

Peter-Simpson commented 2 months ago

Based on your feedback about access to the full setup dialogue, I have made this accessible for Dynamic Clients even when the device reports itself as connected. I've also fixed a parsing issue for text host names that was introduced by the automated VB to C# conversion tool that I used last year.

The attachment below contains a revised dynamic client local server executable that you need to extract and place in C:\Program Files (x86)\Common Files\ASCOM\AlpacaDynamicClients. You may need to "Unblock" it since it has arrived over an Internet connection.

I have tried the updated client with my Raspberry Pi server hosting the OmniSimulators and can access them using the mDNS host name pi5.local. Please can you confirm whether mDNS is now working?

DynamicClientServer.zip

marcocipriani01 commented 2 months ago

I'm only capable of working on one thing at a time

I'm sorry if I've been overloading this thread with too many issues 🤣

Thank you very much, now mDNS works and I can access the properties even if already in the connected state. I also no longer get the unhandled exception in the first message of this issue.

marcocipriani01 commented 2 months ago

The "rubbish" Base64 string from before encodes another Base64 string, which encodes a bunch of raw bytes I can't understand. What I think it's happening is that the combination of username and password is getting Base64-encoded multiple times.

I had a look at the DynamicClientDriver code and I can see that you correctly set Basic Authentication at this line. I created a simple C# test program from a mix of examples online and your code and, as expected, my server receives valid authentication:

using System.Net.Http.Headers;
using System.Text;

var client = new HttpClient {
    BaseAddress = new Uri("http://domecontrolsystem.local")
};
var request = new HttpRequestMessage(HttpMethod.Post, "/api/v1/dome/0/connected");

var userName = "domecontrolsystem";
var password = "admin";

byte[] authenticationBytes = Encoding.ASCII.GetBytes($"{userName}:{password}");

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authenticationBytes));

var _ = await client.SendAsync(request);

I was also able to compile ASCOMLibrary and the following C# test program authenticates correctly!

using ASCOM.Alpaca.Clients;

var dome = new AlpacaDome(ASCOM.Common.Alpaca.ServiceType.Http,
    "domecontrolsystem.local", 80, 0, 5, 10, 100, 1,
    "domecontrolsystem", "admin",
    false, null, null, null, false);

dome.Connect();

Sooo the problem isn't in the ALPACA client code, but somewhere else...

Peter-Simpson commented 2 months ago

The username and password are stored in encrypted form in the ASCOM Profile to keep them from prying eyes. I've traced the issue to the Dynamic Client not decrypting the strings before using them, hence the very large authorisation string. This must have occurred in the extensive re-factoring I undertook as part of Platform 7.

I have been able to use basic authentication from my PC to the OmniSims running on my Pi so hopefully this is now fixed. Please let me know how you get on.

DynamicClientServer2.zip

marcocipriani01 commented 2 months ago

Everything works correctly now, thank you!

Regarding the "tiny window", expanding it reveals the following:

image

I can see the tiny window every time I open the proprties of the ALPACA driver. If I close it, the ALPACA server dies, the properties window closes and any astro-software connected to the driver shows an error.

If the intent of the tiny window is to show that a "local server" driver is running, I propose to replace it with an icon in the system tray. That way, users can clearly see when a local server is still running. Right-clicking the tray icon should allow users to terminate the local server. This will fix the issue I was having before with the "ASCOM Dynamic Client Local Server" process running in the background forever.

I don't really know if this is something you can control in the ASCOM platform itself, or if it's something driver developers need to implement manually. The OnStep ASCOM driver (which is a local server driver) often remains in the background until killed, and it's quite frustrating.

By the way, making an ALPACA + web server in good old C, on a microcontroller with 300kB of RAM, and only TCP sockets to begin with, really proved my programming skills. The amount of complexity to make simple things like HTTP and REST API work is amazing!

Peter-Simpson commented 2 months ago

Thanks for letting me know, I'm glad it's working correctly now.

I've done minimising to the system tray for ASCOM Remote and it was quite an effort so I'd rather avoid that here, so close to release. My intention was that the form be invisible when running, like most other local servers.

I'm surprised that the window is visible because it includes the code below. It looks like these settings have to be in effect before the program runs, so I've changed the values in the VS Form Properties dialogue and the window no longer appears on my PC.

Please can you try this new version and let me know how you get on.

DynamicClientServer3.zip

SetupForm Initialiser public LocalServerForm() { InitializeComponent(); this.ShowInTaskbar = false; this.Visible = false; }

marcocipriani01 commented 2 months ago

I can confirm that the tiny window is gone! We can consider this issue as closed. Regards, Marco

Peter-Simpson commented 2 months ago

Good news, thanks for letting me know Marco.