Skip to content

Added instructions on how to get fingerprint reader to work.#3

Open
jadegamesuk wants to merge 27 commits into
jdillon:mainfrom
jadegamesuk:main
Open

Added instructions on how to get fingerprint reader to work.#3
jadegamesuk wants to merge 27 commits into
jdillon:mainfrom
jadegamesuk:main

Conversation

@jadegamesuk
Copy link
Copy Markdown

@jadegamesuk jadegamesuk commented Jun 1, 2026

Made quite a few changes to ensure that libfprint works with this USB fingerprint as well as multiple fingerprints as well.

Summary by CodeRabbit

  • Documentation

    • Expanded README with step‑by‑step setup, build/install, testing instructions and an added Amazon UK hardware link
  • Bug Fixes

    • More robust enrollment slot handling with stricter limits and clearer failure handling during enroll/store operations
    • Improved verification flow to avoid spurious errors and more accurate match reporting
  • New Features

    • Added device identify action and a device deletion (erase all templates) workflow with clearer error reporting
  • Chores

    • Build/system packaging improvements: generated metadata, udev/installation targets and build helper utilities

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

Warning

Review limit reached

@jadegamesuk, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 50 minutes and 27 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 65062f61-0e00-4cd0-95eb-0e1f3950f73b

📥 Commits

Reviewing files that changed from the base of the PR and between eec0eb9 and a78d0a4.

📒 Files selected for processing (1)
  • src/microarray.c
📝 Walkthrough

Walkthrough

This PR updates README instructions and hardware links, adds a complete Meson build for libfprint including microarray driver registration, refactors USB framing/parsing and transfer wiring, rewrites enrollment slot logic, and adds identify/delete state machines plus class wiring.

Changes

Microarray Driver Integration with Build System and Documentation

Layer / File(s) Summary
Documentation and Hardware Support
README.md
Hardware compatibility date and links updated; replaces short build section with detailed numbered Instructions covering dependencies, cloning libfprint and this repo, copying driver/meson files, rebuilding, manual shared-library install, reloading udev rules, and revised testing guidance with explicit finger option list and build-rerun note.
Build: source lists, driver maps, enum & driver registration
meson.build
Defines top-level Meson source lists (SPI conditional, public/private core, NBIS), constructs driver/helper source maps (includes microarray), generates enum headers, and programmatically emits fpi-drivers.c with driver registrations.
Build: static/shared libs, helper targets, installs
meson.build
Builds static libs (nbis, fprint-private, fprint-drivers) and shared libfprint (version script/link deps), installs public headers, adds helper executables/custom targets for udev hwdb and metainfo, conditional udev rules install, hwdb sync alias, supported-devices executable, and optional GIR/typelib generation.
USB framed-packet helpers, parsing, and transfer callbacks
src/microarray.c
Adds endpoint documentation; refactors ma_build_cmd; replaces ma_parse_resp with stricter framing/checksum validation; centralizes ma_submit_cmd/ma_submit_recv; updates send/recv callbacks to pass SSM via user_data and use device cancellable.
Enrollment SSM: ENROLL_EMPTY, storage, and init
src/microarray.c
Rewrites enroll_run_state (ENROLL_EMPTY scans ReadIndex bitmap for first free slot 0–9 and jumps to image capture or issues MA_CMD_EMPTY), tightens ENROLL_STORE_CHAR failure handling, simplifies enroll_ssm_done error reporting, and resets enroll state on start.
Verify, Identify, Delete SSMs and class wiring
src/microarray.c
Reformats verify_run_state, ensures fpi-data is unref'd, reports verify results via fpi_device_verify_report (fetching FpPrint only on match), adds device-wide ma_identify to iterate stored templates, adds delete SSM using MA_CMD_EMPTY, and sets dev_class->identify = ma_identify and dev_class->delete = ma_delete.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped through README, build, and C,
Packets framed neat, checksums set with glee,
I counted slots from zero up to nine,
Taught verify, identify, and delete to align,
A tiny rabbit cheers: the driver hums fine!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'Added instructions on how to get fingerprint reader to work' is partially related to the changeset. While README.md does contain new instructions, the PR also includes significant code changes to src/microarray.c (272 lines changed) and a new meson.build file (425 lines added), which represent major implementations for identify and delete functionality, not just documentation updates. Revise the title to reflect the full scope of changes, such as 'Implement identify/delete operations and add setup instructions' or 'Add microarray identify/delete drivers and documentation.' This would better represent both the code additions and documentation updates.
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/microarray.c (1)

453-458: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Destructive template clearing when slots are full is a data-loss risk.

When slots 0–9 are fully occupied, the code unconditionally erases all stored templates (line 456–457) without warning the user or offering alternatives. This means attempting to enroll an 11th fingerprint silently destroys all 10 existing enrollments, which is unexpected and likely unacceptable for users.

Consider one of these alternatives:

  1. Return an error indicating storage is full, allowing the caller to decide next steps
  2. Prompt the user to select which slot to overwrite
  3. Implement a delete operation separate from enrollment, so users can explicitly free slots before enrolling new prints
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/microarray.c` around lines 453 - 458, The fallback in microarray.c
currently nukes all templates when slots 0–9 are full by setting self->fid=0 and
sending MA_CMD_EMPTY with ma_submit_cmd, which causes silent data loss; change
this behavior to return an explicit error to the caller instead of performing
MA_CMD_EMPTY: detect the full condition and return a meaningful error code/enum
(e.g., MA_ERR_STORAGE_FULL) from the enclosing function and remove or gate the
MA_CMD_EMPTY path; alternatively, if interactive flows exist, replace the
unconditional erase with a call to a new confirmation or slot-selection routine
so the caller can prompt/choose before calling ma_submit_cmd with MA_CMD_EMPTY
(referencing self->fid, MA_CMD_EMPTY, ma_submit_cmd, ssm, device).
🧹 Nitpick comments (4)
src/microarray.c (1)

428-444: ⚡ Quick win

Clarify loop termination when slot limit is reached.

The break on line 434 only exits the inner loop, so the outer loop continues iterating through remaining bytes even after reaching the slot 9 cap. While functionally safe (since candidate_slot will always exceed 9 for subsequent bytes, preventing self->fid from being set incorrectly), this results in unnecessary iterations and confusing control flow.

♻️ Proposed fix to cleanly exit both loops

Replace the inner break with a jump to the outer loop's exit:

     if (resp[0] == 0x00) {
+        gboolean done = FALSE;
-        for (int byte = 0; byte < 4 && self->fid < 0; byte++) {
+        for (int byte = 0; byte < 4 && self->fid < 0 && !done; byte++) {
             for (int bit = 0; bit < 8; bit++) {
                 int candidate_slot = byte * 8 + bit;
                 
                 /* STRICT CAP: Your chip only supports up to slot 9 (10 fingers total) */
                 if (candidate_slot > 9) {
-                    break; 
+                    done = TRUE;
+                    break;
                 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/microarray.c` around lines 428 - 444, The inner-loop break when
candidate_slot > 9 only exits the bit loop and lets the outer byte loop continue
unnecessarily; modify the logic to exit both loops as soon as the slot cap is
reached by adding a clear control transfer (e.g., set a boolean flag like
reached_slot_cap or use a goto to a labeled exit) and check it in the outer loop
condition so that once candidate_slot > 9 you immediately stop iterating; adjust
around the for loops that compute candidate_slot and set self->fid (using resp
and self->fid) to use this single immediate exit approach.
README.md (2)

88-99: ⚡ Quick win

Caution: pinned meson.build copied over upstream HEAD may drift.

Step 6 overwrites the freshly-cloned upstream libfprint/meson.build with this repo's pinned copy. Because step 3 always clones the latest upstream, upstream changes to its build graph (added sources/drivers) will be lost and the build can break. The note on Line 134 partially covers this, but consider pinning a known-good upstream tag/commit in step 3 to keep the copied meson.build in sync.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 88 - 99, The README currently copies the repo's
pinned meson.build over the freshly-cloned upstream libfprint which can drift;
update the instructions so that the upstream clone in Step 3 is pinned to a
known-good tag or commit instead of always cloning HEAD and losing upstream
build changes—modify the Step 3 clone command to checkout a specific tag/commit
(referencing the cloned libfprint repo and the meson.build overwrite in Step 6)
and add a short note explaining to update the pinned upstream tag when adapting
the pinned meson.build.

98-99: ⚡ Quick win

Hardcoded soname and multiarch path are brittle.

libfprint-2.so.2.0.0 and /usr/lib/x86_64-linux-gnu are both hardcoded. Since step 3 clones the latest upstream libfprint, a future soversion/version bump will change the built filename (e.g. 2.x.y), making these cp commands silently copy a stale file or fail. The path also assumes an x86_64 Debian/Ubuntu multiarch layout. Consider deriving the produced filename and target dir dynamically.

♻️ Derive the built library and target path
LIB=$(ls libfprint/libfprint-2.so.2.* | head -n1)
DEST=$(dirname "$(ldconfig -p | grep -m1 libfprint-2.so.2 | awk '{print $NF}')")
sudo cp "$LIB" "$DEST/libfprint-2.so.2"
sudo ldconfig
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 98 - 99, Replace the hardcoded soname
"libfprint-2.so.2.0.0" and hardcoded multiarch path "/usr/lib/x86_64-linux-gnu"
with a dynamic lookup that: finds the produced library filename under libfprint
(matching libfprint-2.so.2.*), determines the system's current destination
directory for libfprint-2.so.2 via ldconfig/ldconfig -p, and then copies the
discovered file to the discovered destination and runs ldconfig; update the
README lines that reference libfprint/libfprint-2.so.2.0.0 and
/usr/lib/x86_64-linux-gnu accordingly so future version bumps and non-x86_64
multiarch layouts are handled automatically.
meson.build (1)

217-224: ⚡ Quick win

Guard supported_drivers += 'microarray' against pre-existing entries.

This repo’s meson.build only appends 'microarray' to supported_drivers (no other in-repo mutations), so duplicates won’t occur from within this file. Duplicate fpi_device_microarray_get_type() entries in the generated fpi-drivers.c are only possible if supported_drivers is provided/populated externally (e.g., by a parent Meson project) and already contains 'microarray'.

🛡️ Guard the append
-supported_drivers += 'microarray'
+if not supported_drivers.contains('microarray')
+    supported_drivers += 'microarray'
+endif
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@meson.build` around lines 217 - 224, Prevent duplicate entries by checking
supported_drivers before appending 'microarray': replace the unconditional
"supported_drivers += 'microarray'" with a guard that only appends if
'microarray' is not already present in supported_drivers (so you avoid duplicate
fpi_device_microarray_get_type() entries in the generated code); reference the
supported_drivers variable and the generated fpi_device_microarray_get_type
symbol when implementing the check.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/microarray.c`:
- Around line 427-444: The ReadIndex response parsing currently treats any
non-zero resp[0] as "all slots full" and later falls through to
template-clearing; instead, detect resp[0] != 0x00 as a command failure and bail
out explicitly: when parsing the ReadIndex response (using resp, candidate_slot,
bit/byte loops and self->fid), do not leave self->fid as -1 to signal "all full"
on error—either return an error code from the function or set a distinct error
flag/state on self (e.g., fid_error) and log/report the ReadIndex failure so the
later template-clearing fallback is skipped unless you truly know the bitmap
indicates no free slots. Ensure the new branch handles resp[0] != 0x00 before
any logic that assumes a valid bitmap.

---

Outside diff comments:
In `@src/microarray.c`:
- Around line 453-458: The fallback in microarray.c currently nukes all
templates when slots 0–9 are full by setting self->fid=0 and sending
MA_CMD_EMPTY with ma_submit_cmd, which causes silent data loss; change this
behavior to return an explicit error to the caller instead of performing
MA_CMD_EMPTY: detect the full condition and return a meaningful error code/enum
(e.g., MA_ERR_STORAGE_FULL) from the enclosing function and remove or gate the
MA_CMD_EMPTY path; alternatively, if interactive flows exist, replace the
unconditional erase with a call to a new confirmation or slot-selection routine
so the caller can prompt/choose before calling ma_submit_cmd with MA_CMD_EMPTY
(referencing self->fid, MA_CMD_EMPTY, ma_submit_cmd, ssm, device).

---

Nitpick comments:
In `@meson.build`:
- Around line 217-224: Prevent duplicate entries by checking supported_drivers
before appending 'microarray': replace the unconditional "supported_drivers +=
'microarray'" with a guard that only appends if 'microarray' is not already
present in supported_drivers (so you avoid duplicate
fpi_device_microarray_get_type() entries in the generated code); reference the
supported_drivers variable and the generated fpi_device_microarray_get_type
symbol when implementing the check.

In `@README.md`:
- Around line 88-99: The README currently copies the repo's pinned meson.build
over the freshly-cloned upstream libfprint which can drift; update the
instructions so that the upstream clone in Step 3 is pinned to a known-good tag
or commit instead of always cloning HEAD and losing upstream build
changes—modify the Step 3 clone command to checkout a specific tag/commit
(referencing the cloned libfprint repo and the meson.build overwrite in Step 6)
and add a short note explaining to update the pinned upstream tag when adapting
the pinned meson.build.
- Around line 98-99: Replace the hardcoded soname "libfprint-2.so.2.0.0" and
hardcoded multiarch path "/usr/lib/x86_64-linux-gnu" with a dynamic lookup that:
finds the produced library filename under libfprint (matching
libfprint-2.so.2.*), determines the system's current destination directory for
libfprint-2.so.2 via ldconfig/ldconfig -p, and then copies the discovered file
to the discovered destination and runs ldconfig; update the README lines that
reference libfprint/libfprint-2.so.2.0.0 and /usr/lib/x86_64-linux-gnu
accordingly so future version bumps and non-x86_64 multiarch layouts are handled
automatically.

In `@src/microarray.c`:
- Around line 428-444: The inner-loop break when candidate_slot > 9 only exits
the bit loop and lets the outer byte loop continue unnecessarily; modify the
logic to exit both loops as soon as the slot cap is reached by adding a clear
control transfer (e.g., set a boolean flag like reached_slot_cap or use a goto
to a labeled exit) and check it in the outer loop condition so that once
candidate_slot > 9 you immediately stop iterating; adjust around the for loops
that compute candidate_slot and set self->fid (using resp and self->fid) to use
this single immediate exit approach.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6268dda3-139f-405c-9d6d-2bbab19cd96f

📥 Commits

Reviewing files that changed from the base of the PR and between 82cd97e and 9aff905.

📒 Files selected for processing (3)
  • README.md
  • meson.build
  • src/microarray.c

Comment thread src/microarray.c
Comment on lines 427 to 444
if (resp[0] == 0x00) {
for (int byte = 0; byte < 4 && self->fid < 0; byte++) {
for (int bit = 0; bit < 8; bit++) {
int candidate_slot = byte * 8 + bit;

/* STRICT CAP: Your chip only supports up to slot 9 (10 fingers total) */
if (candidate_slot > 9) {
break;
}

/* If this bit is 0, the slot is empty! Let's claim it. */
if (!(resp[1 + byte] & (1 << bit))) {
self->fid = byte * 8 + bit;
self->fid = candidate_slot;
break;
}
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Missing error handling for ReadIndex command failure.

If resp[0] != 0x00 (indicating the ReadIndex command failed), the code skips bitmap parsing, leaving self->fid = -1. It then falls through to the template-clearing fallback (lines 453–458), treating a command failure the same as "all slots full." This conflation could trigger an unintended data wipe when the real problem is a transient device error.

🛡️ Proposed fix to handle command failure explicitly
     if (resp[0] == 0x00) {
         for (int byte = 0; byte < 4 && self->fid < 0; byte++) {
             for (int bit = 0; bit < 8; bit++) {
                 int candidate_slot = byte * 8 + bit;
                 
                 /* STRICT CAP: Your chip only supports up to slot 9 (10 fingers total) */
                 if (candidate_slot > 9) {
                     break; 
                 }
                 
                 /* If this bit is 0, the slot is empty! Let's claim it. */
                 if (!(resp[1 + byte] & (1 << bit))) {
                     self->fid = candidate_slot;
                     break;
                 }
             }
         }
+    } else {
+        /* ReadIndex command failed */
+        fp_warn ("ReadIndex command failed with status 0x%02x", resp[0]);
+        fpi_ssm_mark_failed (ssm,
+            fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
+                                      "Failed to read enrollment index: 0x%02x",
+                                      resp[0]));
+        return;
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/microarray.c` around lines 427 - 444, The ReadIndex response parsing
currently treats any non-zero resp[0] as "all slots full" and later falls
through to template-clearing; instead, detect resp[0] != 0x00 as a command
failure and bail out explicitly: when parsing the ReadIndex response (using
resp, candidate_slot, bit/byte loops and self->fid), do not leave self->fid as
-1 to signal "all full" on error—either return an error code from the function
or set a distinct error flag/state on self (e.g., fid_error) and log/report the
ReadIndex failure so the later template-clearing fallback is skipped unless you
truly know the bitmap indicates no free slots. Ensure the new branch handles
resp[0] != 0x00 before any logic that assumes a valid bitmap.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/microarray.c (1)

446-459: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Silent full-storage wipe destroys all enrolled fingerprints.

When slots 0–9 are genuinely full, the driver erases every stored template (MA_CMD_EMPTY) and reuses slot 0, instead of reporting that storage is full. For a device meant to hold multiple fingerprints this is unexpected data loss: enrolling one new finger silently deletes the other nine. Prefer failing with FP_DEVICE_ERROR_DATA_FULL and letting the caller decide.

🛡️ Proposed change to fail instead of wiping
-        /* FALLBACK: If slots 0-9 are completely full, nuke the chip to start fresh */
-        fp_dbg ("Storage slots 0-9 are completely full! Clearing all templates.");
-        self->fid = 0;
-        cmd[0] = MA_CMD_EMPTY;
-        ma_submit_cmd (ssm, device, cmd, 1);
-        break;
+        /* Slots 0-9 are all in use; do not destroy existing enrollments. */
+        fp_dbg ("Storage slots 0-9 are full; reporting data-full.");
+        fpi_ssm_mark_failed (ssm,
+            fpi_device_error_new (FP_DEVICE_ERROR_DATA_FULL));
+        return;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/microarray.c` around lines 446 - 459, When storage slots 0-9 are full the
code currently sends MA_CMD_EMPTY and nukes all templates; instead, stop erasing
and return a data-full error to the caller: remove the MA_CMD_EMPTY /
ma_submit_cmd call and the fid reset, and replace the fallback branch with logic
that reports FP_DEVICE_ERROR_DATA_FULL (e.g. call the state-machine failure path
such as fpi_ssm_fail or otherwise set the ssm error) so the enroll attempt fails
cleanly rather than wiping stored fingerprints; locate the fallback by the
symbols self->fid, MA_CMD_EMPTY, ma_submit_cmd, and the surrounding
fpi_ssm_jump_to_state / ENROLL_GET_IMAGE to make this change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/microarray.c`:
- Around line 782-787: ma_delete currently starts delete_run_state which
unconditionally issues MA_CMD_EMPTY (erase all templates) and ignores any
per-FID/per-slot delete request; update the delete path so ma_delete uses the
requested FID/slot (retrieve via fpi_device_get_delete_data or the equivalent
delete payload) and pass that into the state machine (or into delete_run_state)
so the per-slot delete opcode is used instead of MA_CMD_EMPTY; if the MAFP
protocol lacks per-slot delete, change dev_class->delete's
contract/documentation to clearly perform “erase all” and make callers use the
appropriate API to avoid accidental single-delete-to-all behavior.

---

Outside diff comments:
In `@src/microarray.c`:
- Around line 446-459: When storage slots 0-9 are full the code currently sends
MA_CMD_EMPTY and nukes all templates; instead, stop erasing and return a
data-full error to the caller: remove the MA_CMD_EMPTY / ma_submit_cmd call and
the fid reset, and replace the fallback branch with logic that reports
FP_DEVICE_ERROR_DATA_FULL (e.g. call the state-machine failure path such as
fpi_ssm_fail or otherwise set the ssm error) so the enroll attempt fails cleanly
rather than wiping stored fingerprints; locate the fallback by the symbols
self->fid, MA_CMD_EMPTY, ma_submit_cmd, and the surrounding
fpi_ssm_jump_to_state / ENROLL_GET_IMAGE to make this change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aed15fb9-b5c7-446d-9172-01d4642ab1e4

📥 Commits

Reviewing files that changed from the base of the PR and between 9aff905 and cafe335.

📒 Files selected for processing (1)
  • src/microarray.c

Comment thread src/microarray.c
Comment on lines +782 to +787
static void
ma_delete (FpDevice *device)
{
FpiSsm *ssm = fpi_ssm_new (device, delete_run_state, DELETE_NUM_STATES);
fpi_ssm_start (ssm, delete_ssm_done);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

🧩 Analysis chain

🌐 Web query:

FPC GROW R30X fingerprint protocol DeleteChar command 0x0C delete single template

💡 Result:

In the GROW R30X fingerprint module protocol, the command to delete templates is DeletChar, which uses the instruction code 0x0C [1][2][3]. Although the command is typically used to delete a segment (a range) of templates [1][4][5], you can delete a single template by setting the number of templates to delete (N) to 1 [1][6]. Command Details: Instruction Code: 0x0C [1][3] Input Parameters: 1. PageID (2 bytes): The starting template ID (location) in the flash library [1][6][7]. 2. N (2 bytes): The number of templates to delete [1][6][4]. To delete a single template, set N = 0x0001 [1][6]. Command Package Format: The command package follows the standard GROW/R30X communication protocol [1][3]: - Header: 2 bytes (0xEF01) [1][6][4] - Module Address: 4 bytes [1][6][4] - Package Identifier: 1 byte (0x01 for command packet) [1][6][4] - Package Length: 2 bytes (0x0007) [4][3] - Instruction Code: 1 byte (0x0C) [1][6][4] - PageID: 2 bytes [1][6][4] - N: 2 bytes (set to 0x0001 for a single template) [1][6][4] - Checksum: 2 bytes [1][6][4] Response: The module will return an acknowledgment package with a confirmation code [1][6][3]: - 0x00: Delete success [1][6][3] - 0x01: Error receiving package [1][6][3] - 0x10: Failed to delete template [1][6][3] For example, to delete the template at index 0x0005, the command parameters would be PageID = 0x0005 and N = 0x0001 [1][6].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the ma_delete function and nearby context
sed -n '740,840p' src/microarray.c | cat -n

# Find definition / uses of delete_run_state in this file
rg -n "delete_run_state|delete_ssm_done|delete_data|fpi_device_get_delete_data|MA_CMD_EMPTY|0x0D|DELETE_NUM_STATES|ma_delete" src/microarray.c

# Show where delete_run_state is defined (if in this file)
rg -n "delete_run_state" -n src/microarray.c && true

# Extract surrounding code blocks for any matched lines (small windows)
for ln in $(rg -n "delete_run_state|MA_CMD_EMPTY|fpi_device_get_delete_data" src/microarray.c | cut -d: -f1 | sort -n | uniq); do
  start=$((ln-20)); end=$((ln+30));
  echo "----- context around line $ln -----"
  sed -n "${start},${end}p" src/microarray.c | cat -n
done

Repository: jdillon/libfprint-microarray

Length of output: 14742


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Search for delete-data access in this driver
rg -n "fpi_device_get_delete_data|delete_data|delete.*FID|FID.*delete|dev_class->delete|FP_DELETE" src/microarray.c

# 2) Search entire repo for fpi_device_get_delete_data usage (to confirm typical pattern)
rg -n "fpi_device_get_delete_data" .

# 3) Search for any per-slot delete opcode (0x0C / DeleteChar) mention in repo
rg -n "0x0C|DeleteChar|delete char|MA_CMD_.*DELETE" .

# 4) List any other delete-related state machine or commands in microarray.c
rg -n "Delete state machine|ma_delete|delete_run_state|MA_CMD_EMPTY|erase ALL" src/microarray.c

# 5) Show tail of delete state machine / any additional delete command handling
sed -n '730,820p' src/microarray.c | cat -n

Repository: jdillon/libfprint-microarray

Length of output: 111


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# microarray.c specifically: check whether any per-fingerprint delete data is consumed
echo "---- fpi_device_get_delete_data in microarray.c ----"
rg -n "fpi_device_get_delete_data" src/microarray.c || true

echo "---- MA_CMD_.*DELETE / DeleteChar / 0x0C in microarray.c ----"
rg -n "MA_CMD_.*DELETE|DeleteChar|0x0C" src/microarray.c || true

echo "---- delete command implementations in microarray.c ----"
rg -n "ma_delete|delete_run_state|delete_ssm_done|MA_CMD_EMPTY|erase ALL" src/microarray.c

# whole repo: check for any per-FID delete usage
echo "---- fpi_device_get_delete_data in repo ----"
rg -n "fpi_device_get_delete_data" . || true

echo "---- 0x0C / DeleteChar / MA_CMD_.*DELETE in repo ----"
rg -n "0x0C|DeleteChar|MA_CMD_.*DELETE" . || true

echo "---- dev_class->delete assignments in repo ----"
rg -n "dev_class->delete\s*=" . || true

Repository: jdillon/libfprint-microarray

Length of output: 920


ma_delete currently erases ALL stored templates (not the requested single fingerprint).

ma_delete() runs delete_run_state(), which unconditionally sends MA_CMD_EMPTY (0x0D), defined as “erase ALL stored templates”. The delete path does not use any per-FID/per-print delete data (no fpi_device_get_delete_data or any FID/slot parameter is consumed), so mapping this to dev_class->delete makes every “delete one fingerprint” request destructive to the entire template store.

If the MicroarrayTechnology MAFP protocol supports deleting a single template slot, wire dev_class->delete to that per-slot opcode using the requested FID/slot; otherwise this API behavior needs to be reconsidered to match “erase all”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/microarray.c` around lines 782 - 787, ma_delete currently starts
delete_run_state which unconditionally issues MA_CMD_EMPTY (erase all templates)
and ignores any per-FID/per-slot delete request; update the delete path so
ma_delete uses the requested FID/slot (retrieve via fpi_device_get_delete_data
or the equivalent delete payload) and pass that into the state machine (or into
delete_run_state) so the per-slot delete opcode is used instead of MA_CMD_EMPTY;
if the MAFP protocol lacks per-slot delete, change dev_class->delete's
contract/documentation to clearly perform “erase all” and make callers use the
appropriate API to avoid accidental single-delete-to-all behavior.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 39fe5a33-10c1-4b77-8504-310a5332793f

📥 Commits

Reviewing files that changed from the base of the PR and between cafe335 and 3203812.

📒 Files selected for processing (1)
  • src/microarray.c

Comment thread src/microarray.c Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant