From 0484b8437e62201e86ae0d39033fa607ceaf13b5 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Wed, 2 Sep 2026 19:32:08 +0200 Subject: [PATCH] Acknowledge the event state after reporting, not only before A correct-finger run matched on frame 1 -- twice, on both the touch and the image-ready event, with the right gid and fid -- and then answered "not identified yet" for the remaining 39 frames without ever producing another verdict. The matcher was never the problem; our loop wedged after the first result. The reference frame loop is {QUERY_EVENT_STATUS, CAPTURE_IMAGE, REPORT_EVENT, QUERY_EVENT_STATUS, REPORT_EVENT}. Ours queried only at the top of the frame. QUERY_EVENT_STATUS answers in rc -- 5 while an event is pending, 0 once REPORT_EVENT has consumed it -- so the trailing query is what acknowledges the trustlet's event state before the next frame. Without it the state is never cleared and every later frame is refused. Both status values are now printed per frame, so the state machine is visible rather than inferred. This also explains the wrong-finger control reading as 40 rescans and no rejection: a session that never resolves has nothing to acknowledge, so it looked the same either way and told us less than it appeared to. --- implementations/main.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/implementations/main.cpp b/implementations/main.cpp index 4671f44..e82bdf6 100644 --- a/implementations/main.cpp +++ b/implementations/main.cpp @@ -1106,9 +1106,15 @@ int Probe() { en::TouchTracker tracker; en::AuthTally tally; + // The reference frame loop is {QUERY, CAPTURE, REPORT, QUERY, REPORT}. + // QUERY_EVENT_STATUS returns its answer in rc -- 5 while an event is + // pending, 0 once REPORT_EVENT has consumed it -- and the trailing + // query is not decoration: without it the trustlet's event state is + // never acknowledged, and after the first verdict every later frame + // answers "not identified yet" forever. for (int i = 0; i < g_frames; i++) { std::vector q(0x10, std::byte{0}); - SendCommand(app, ta::Cmd::QueryEventStatus, q); + auto q0 = SendCommand(app, ta::Cmd::QueryEventStatus, q); std::vector cap(ta::CaptureDeclaredLen); ta::BuildCapturePayload(cap); @@ -1148,8 +1154,12 @@ int Probe() { return std::string("?"); }()); } - std::println(" frame {:2}/{}: metric={:<4}{}{}", i + 1, g_frames, c.metric, - finger ? " FINGER" : " ", verdicts); + // Acknowledge the event state before the next frame. + auto q1 = SendCommand(app, ta::Cmd::QueryEventStatus, q); + + std::println(" frame {:2}/{}: metric={:<4}{} evst {}->{}{}", i + 1, g_frames, + c.metric, finger ? " FINGER" : " ", + q0.invoked ? q0.rc : -999, q1.invoked ? q1.rc : -999, verdicts); std::this_thread::sleep_for(std::chrono::milliseconds(g_frameGapMs)); } // Only a terminal verdict is an attempt. Counting rescan frames as