{"record":{"id":"febac1e125a7f992","repo":"mgth/LittleBigMouse","slug":"the-c1-requires-the-vidaa-client-certificate-extract-the-p12","errorCode":null,"errorMessage":"The C1 requires the VIDAA client certificate. Extract the .p12 from the official Android APK and copy it to {DefaultPath}.","messagePattern":"The C1 requires the VIDAA client certificate\\. Extract the \\.p12 from the official Android APK and copy it to (.+?)\\.","errorType":"exception","errorClass":"System.Security.Authentication.AuthenticationException","httpStatus":null,"severity":"error","filePath":"LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/HisenseVidaaService.cs","lineNumber":158,"sourceCode":"                // The projector can generate a PIN from its own Remote Control\n                // settings. Connect without asking it to replace that PIN.\n                await replacement.StartPairingAsync(ct, requestPin: false).ConfigureAwait(false);\n            }\n            catch\n            {\n                await replacement.DisposeAsync();\n                throw;\n            }\n            await ReplaceClientAsync(id, replacement).ConfigureAwait(false);\n            client = replacement;\n        }\n        await client.AuthenticateAsync(pin, ct); _store.Save(client.Configuration);\n    }\n\n    async Task PreparePairingAsync(HisenseVidaaConfiguration c, CancellationToken ct)\n    {\n        c.ClientCertificatePath = VidaaCertificate.Resolve(c.ClientCertificatePath);\n        if (string.IsNullOrWhiteSpace(c.ClientCertificatePath)) throw VidaaCertificate.MissingException();\n        if (string.IsNullOrWhiteSpace(c.ClientCertificatePassword))\n            c.ClientCertificatePassword = VidaaCertificate.DefaultPassword;\n        c.ControllerMacAddress = NetworkIdentity.ControllerMacFor(c.IpAddress);\n        try\n        {\n            var device = await _discovery.FindAsync(c.IpAddress, ct).ConfigureAwait(false);\n            c.IpAddress = device.IpAddress;\n            c.ProtocolVersion = device.ProtocolVersion;\n            c.Brand = device.Brand;\n        }\n        catch (HttpRequestException) when (c.ProtocolVersion is null\n                                           && c.MonitorId.StartsWith(\"HEC002F\", StringComparison.OrdinalIgnoreCase))\n        {\n            // Hisense C1 EDID. Its descriptor advertises RemoteNOW protocol 2160,\n            // but the UPnP HTTP endpoint can disappear while MQTT remains usable.\n            c.ProtocolVersion = 2160;\n            c.Brand = \"his\";\n        }","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/mgth/LittleBigMouse/blob/7a42f01d47d99d223b8ee33ba4019af82adf1c48/LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/HisenseVidaaService.cs#L140-L176","documentation":"PreparePairingAsync resolves the Hisense VIDAA client certificate path via VidaaCertificate.Resolve and throws VidaaCertificate.MissingException() when the resolved path is null/whitespace. The VIDAA protocol (a C1-protected MQTT/TLS service) requires a client certificate that is not distributable with the app, so it must be extracted from the official Android APK and placed at the default path.","triggerScenarios":"Calling PreparePairingAsync (directly or through RequestPinAsync/PairAsync) when the configuration's ClientCertificatePath is unset and VidaaCertificate.Resolve cannot find the .p12 at the DefaultPath on disk.","commonSituations":"Fresh installation where the certificate was never extracted; user moved or deleted the .p12; configuration points at a stale path after reinstall; running in CI/container where the APK extraction step was skipped.","solutions":["Extract the .p12 certificate from the official Hisense remote Android APK and copy it to the DefaultPath reported in the exception message.","Set ClientCertificatePath in HisenseVidaaConfiguration to the full path of the extracted .p12 file.","Verify the file exists and is readable at the configured path before pairing (File.Exists).","If the password prompt follows, leave ClientCertificatePassword unset so the DefaultPassword is applied, or set it to the APK's known password."],"exampleFix":"// before\nc.ClientCertificatePath = null; // never extracted\n// after\nc.ClientCertificatePath = \"/home/user/.littlebigmouse/vidaa/client.p12\"; // extracted from official APK\nif (!File.Exists(c.ClientCertificatePath)) throw new InvalidOperationException(\"Extract the .p12 from the Hisense APK first.\");","handlingStrategy":"validation","validationCode":"// before PreparePairingAsync\nvar resolved = VidaaCertificate.Resolve(c.ClientCertificatePath);\nif (string.IsNullOrWhiteSpace(resolved) || !File.Exists(resolved))\n    throw new InvalidOperationException(\n        $\"VIDAA client certificate missing. Extract the .p12 from the official Android APK and copy it to {VidaaCertificate.DefaultPath}.\");","typeGuard":null,"tryCatchPattern":"try { await service.RequestPinAsync(config, ct); }\ncatch (Exception e) when (e.Message.Contains(\"VIDAA client certificate\")) {\n    ui.ShowSetupStep(\"Extract the .p12 from the Hisense remote APK and place it at \" + VidaaCertificate.DefaultPath);\n}","preventionTips":["Run the APK-extraction step as part of installation/setup, not at first pairing attempt.","Check File.Exists on the resolved cert path at app startup when VIDAA support is enabled.","Keep the cert out of the repo but document DefaultPath in setup docs."],"tags":["tls","client-certificate","hisense","vidaa","smart-tv"],"backgroundTag":"missing-credentials","analyzedSha":"7a42f01d47d99d223b8ee33ba4019af82adf1c48","analyzedAt":"2026-09-16T00:35:00.514Z","contentChangedAt":"2026-09-16T00:35:00.514Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}