mgth/LittleBigMouse · error · System.Security.Authentication.AuthenticationException
The C1 requires the VIDAA client certificate. Extract the…
Error message
The C1 requires the VIDAA client certificate. Extract the .p12 from the official Android APK and copy it to {DefaultPath}. What it means
During VIDAA MQTT ConnectAsync, the TCP read of the CONNACK packet can surface an IOException. The filter `when (certificates.Count == 0)` distinguishes a TLS handshake failure caused by an absent client certificate from other IO faults, and rethrows it as VidaaCertificate.MissingException(e). The message tells the user to extract the .p12 from the official Android APK and copy it to the default path.
Solutions
- Extract the .p12 from the official Hisense Android APK and place it at the DefaultPath, then retry the connection.
- Point ClientCertificatePath in HisenseVidaaConfiguration at the actual .p12 file and confirm File.Exists passes.
- Check file permissions on the .p12 (must be readable by the daemon user).
- Confirm the certificate loaded successfully before connecting (e.g. inspect certificates.Count / certificate load logs) to rule out a load-time failure rather than a missing file.
Example fix
// before
await OpenMqttAsync(config, ct); // throws MissingException
// after
var certPath = VidaaCertificate.Resolve(config.ClientCertificatePath);
if (string.IsNullOrWhiteSpace(certPath) || !File.Exists(certPath))
throw new InvalidOperationException($"Copy the extracted .p12 to {VidaaCertificate.DefaultPath} before connecting."); Defensive patterns
Strategy: try-catch
Validate before calling
// before connecting
var certPath = VidaaCertificate.Resolve(config.ClientCertificatePath);
if (string.IsNullOrWhiteSpace(certPath) || !File.Exists(certPath))
throw new InvalidOperationException($"Copy the extracted .p12 to {VidaaCertificate.DefaultPath} before connecting."); Try / catch
try { await connection.OpenMqttAsync(config, ct); }
catch (Exception e) when (e.Message.Contains("VIDAA client certificate")) {
// cert absent -> surface setup instructions, do not retry blind
ui.PromptCertificateInstall(VidaaCertificate.DefaultPath);
} Prevention
- Pre-validate the certificate file exists and loads (X509Certificate2 constructor) before every connection attempt.
- Mount/copy the .p12 into containers and CI environments as part of environment provisioning.
- Distinguish missing-cert IOException from other IO faults with a pre-flight load check rather than relying on the catch filter.
When it happens
Trigger: Calling ConnectAsync (via OpenMqttAsync) when the TLS client-hello carries no client certificate (certificates.Count == 0) and the device/stack aborts the handshake with an IOException — i.e. the .p12 was never loaded because it is missing at the configured path.
Common situations: Same as the pre-flight MissingException but detected later: certificate file deleted after configuration was saved; path points to an unreadable/empty file so no certificate loaded; container without the cert mounted; stale config after app reinstall.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- The C1 requires the VIDAA client certificate. Extract the…
- Enter a platform action name containing only letters…
- Enter a test level between 0 and 10.
- Enter the four-digit PIN displayed by the Hisense device.
- Enter the projector Wi-Fi MAC address first.
AI-assisted analysis of mgth/LittleBigMouse@7a42f01d47 (2026-09-16).
Data as JSON: /api/errors/506d186f194e9108.
Report an issue: GitHub.
Appendix: source
Thrown at LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/VidaaMqttConnection.cs:83
}, cancellationToken).ConfigureAwait(false);
}
catch (AuthenticationException e) when (certificates.Count == 0)
{
throw new AuthenticationException(
"VIDAA rejected TLS. Select the PKCS#12 client certificate extracted from the official app.", e);
}
_stream = ssl;
await WritePacketAsync(BuildConnectPacket(clientId, username, password), cancellationToken)
.ConfigureAwait(false);
(byte Header, byte[] Payload) connack;
try
{
connack = await ReadPacketAsync(_stream, cancellationToken).ConfigureAwait(false);
}
catch (IOException e) when (certificates.Count == 0)
{
throw VidaaCertificate.MissingException(e);
}
if ((connack.Header >> 4) != 2 || connack.Payload.Length < 2)
throw new IOException("VIDAA returned an invalid MQTT connection response.");
if (connack.Payload[1] != 0)
throw new UnauthorizedAccessException(MqttError(connack.Payload[1]));
_connected = true;
// The caller token limits the handshake only. Once established, MQTT has
// its own lifetime so a completed UI command cannot tear down the session.
_lifetime = new CancellationTokenSource();
_readerTask = ReadLoopAsync(_lifetime.Token);
_pingTask = PingLoopAsync(_lifetime.Token);
}
public async Task SubscribeAsync(IEnumerable<string> topics, CancellationToken cancellationToken)
{
foreach (var topic in topics)
{View on GitHub (pinned to 7a42f01d47)