Skip to content

mazda: VIN and engine-firmware fingerprint fallback - #5

Merged
zephleggett merged 2 commits into
zoompilot:mazda-devfrom
mzdnick:mazda-vin-fingerprint
Aug 24, 2026
Merged

mazda: VIN and engine-firmware fingerprint fallback#5
zephleggett merged 2 commits into
zoompilot:mazda-devfrom
mzdnick:mazda-vin-fingerprint

Conversation

@mzdnick

@mzdnick mzdnick commented Aug 23, 2026

Copy link
Copy Markdown

Problem

Mazda fingerprints by firmware only: exact match, or generic fuzzy. An EPS swap breaks exact matching for every platform. Generic fuzzy ignores the EPS but needs two chassis ECUs with firmware unique to one platform, and Mazda shares transmission firmware across CX-9 models. EPS swapped cars land on "Unrecognized Vehicle" and need manual selection; unknown fingerprints cause the same failure.

Fix

A brand fuzzy hook, shaped like the Rivian and Volkswagen matchers, runs only after exact and generic fuzzy matching fail.

VIN decode: once is_valid_vin accepts the VIN, the WMI allowlist (JM1, JM3, 3MZ), model line (positions 4–5), and model year code (position 10) decode to one platform:

Chassis Years Platform
KF 2017–21 CX-5
KF 2022–25 CX-5 2022
TC 2016–20 CX-9
TC 2021–23 CX-9 2021
BN 2017–18 Mazda 3
GL 2017–21 Mazda 6

Engine-firmware fallback: if the VIN can't decode (non-North-American export VINs, e.g. Oceania's JM0, encode no model year), engine firmware names the platform instead. It's unique per platform, verified by a disjointness test, so it survives EPS swaps and market differences in every other ECU. Two guards keep it from over-reaching:

  • A lone responding ECU address declines to match.
  • A VIN carrying a known Mazda WMI that names no platform (an unsupported model, e.g. a 2019+ Mazda 3) declines to manual selection rather than taking an engine guess.

Steering stays keyed on EPS firmware (STEER_TO_ZERO_EPS_FW) regardless of which path names the chassis, so a swapped EPS keeps steer-to-zero on the chassis's own specs.

Validation

  • 24 real listing VINs pin every supported model line and year, both platform splits, and every WMI in the allowlist (JM3, JM1, Salamanca-built 3MZ).
  • Unsupported BP/DM VINs correctly produce no match.
  • The engine disjointness invariant (zero shared engine firmware across the six platforms) is pinned by test.
  • VIN decode takes priority over a contradicting engine match.
  • A lone responding ECU address declines to match rather than naming a car off one signal.
  • Unsupported-model suppression is pinned: a 2019+ Mazda 3 VIN whose engine firmware collides with the database still returns nothing, since the VIN already identified an unsupported chassis.
  • The open gap for off-table WMIs is pinned intentionally: a CX-50's 7MM VIN with the same colliding firmware still matches today, so extending the WMI allowlist remains a conscious decision.
  • The reported Oceania case is tested end to end ( JM0 VIN, donor EPS, database-unknown ABS/transmission ) resolving to CX-9 2021 by engine firmware.
  • The EPS-swap scenario is tested through the full match_fw_to_car path for the VIN branch, not just the isolated hook.
  • Full opendbc car suite passes host-side; the shared fingerprint tests are untouched.

By design

  • The hook only fires when exact and generic fuzzy matching both find nothing, so stock, correctly-matched cars are untouched.
  • A known Mazda WMI that names no supported platform declines to manual selection instead of guessing off the engine.

AI Usage

Disclaimer: GLM-5.3 by Z.ai was used to help develop, debug, and document this submission. All changes were reviewed and validated by a human.

@mzdnick

mzdnick commented Aug 23, 2026

Copy link
Copy Markdown
Author

Validated in my CX-5 by corrupting Mazda FW fingerprints to force VIN-based fingerprinting.

@maxzzznz

Copy link
Copy Markdown

Hi @mzdnick thanks for working on this VIN fallback, it could be very useful for some Mazda EPS-swap cases.

I have a NZ-market 2022 Mazda CX-9 with a newer CX-5 EPS swap. Its VIN is JM0TC4WLA00****** (I can provide the full VIN privately if useful for testing).

The chassis code at positions 4–5 is TC, but position 10 is 0, not M, N, or P. With the current implementation, it therefore does not return MAZDA_CX9_2021, even though the vehicle is a 2022 CX-9.

This appears to be a normal AU/NZ export VIN pattern, not a typo. The official Australian government VIN list for a CX-9 (TC) recall contains many VINs with the same JM0TC4WLA00... structure:
https://www.vehiclerecalls.gov.au/sites/default/files/recall-files/REC-000893-VIN-List-1.pdf

It seems that matching TC alone may not be entirely safe, since it spans both the 2016–2020 and 2021–2023 CX-9 platforms. I am not proposing a VIN-only rule here, I mainly wanted to flag that the current position-10 year mapping does not cover at least the JM0 AU/NZ export CX-9 VINs (and it could be the same for CX-5 in AU/NZ).

I can provide the full firmware set and full VIN privately if that would be helpful to design a more robust VIN fallback rule that would also work for models outside the US market.

@mzdnick

mzdnick commented Aug 23, 2026

Copy link
Copy Markdown
Author

Hi @mzdnick thanks for working on this VIN fallback, it could be very useful for some Mazda EPS-swap cases.

I have a NZ-market 2022 Mazda CX-9 with a newer CX-5 EPS swap. Its VIN is JM0TC4WLA00****** (I can provide the full VIN privately if useful for testing).

The chassis code at positions 4–5 is TC, but position 10 is 0, not M, N, or P. With the current implementation, it therefore does not return MAZDA_CX9_2021, even though the vehicle is a 2022 CX-9.

This appears to be a normal AU/NZ export VIN pattern, not a typo. The official Australian government VIN list for a CX-9 (TC) recall contains many VINs with the same JM0TC4WLA00... structure: https://www.vehiclerecalls.gov.au/sites/default/files/recall-files/REC-000893-VIN-List-1.pdf

It seems that matching TC alone may not be entirely safe, since it spans both the 2016–2020 and 2021–2023 CX-9 platforms. I am not proposing a VIN-only rule here, I mainly wanted to flag that the current position-10 year mapping does not cover at least the JM0 AU/NZ export CX-9 VINs (and it could be the same for CX-5 in AU/NZ).

I can provide the full firmware set and full VIN privately if that would be helpful to design a more robust VIN fallback rule that would also work for models outside the US market.

Hey @maxzzznz !

Thanks, that's useful information. This PR is for a VIN-fallback in case firmware fingerprinting fails, so shouldn't cause issues if it also fails to match. Unfortunately it does seem like this approach will only work for North America style VINs as the VIN format for JM0 (Mazda for Oceania export) doesn't appear to expose the year of manufacture. I'll have to keep looking for a solution there.

If you'd like you can send me your cars fingerprints, but I did look over your PR and the firmware you submitted is already present in the Mazda fingerprint list for a CX-9. For clarity: I noticed your code said 'HYBRID_CX9_FW', was the intent to imply a 'hybrid fingerprint' and not that your CX-9 is a hybrid vehicle? Just wanted to be sure.

@maxzzznz

Copy link
Copy Markdown

Hi @mzdnick thanks for working on this VIN fallback, it could be very useful for some Mazda EPS-swap cases.
I have a NZ-market 2022 Mazda CX-9 with a newer CX-5 EPS swap. Its VIN is JM0TC4WLA00****** (I can provide the full VIN privately if useful for testing).
The chassis code at positions 4–5 is TC, but position 10 is 0, not M, N, or P. With the current implementation, it therefore does not return MAZDA_CX9_2021, even though the vehicle is a 2022 CX-9.
This appears to be a normal AU/NZ export VIN pattern, not a typo. The official Australian government VIN list for a CX-9 (TC) recall contains many VINs with the same JM0TC4WLA00... structure: https://www.vehiclerecalls.gov.au/sites/default/files/recall-files/REC-000893-VIN-List-1.pdf
It seems that matching TC alone may not be entirely safe, since it spans both the 2016–2020 and 2021–2023 CX-9 platforms. I am not proposing a VIN-only rule here, I mainly wanted to flag that the current position-10 year mapping does not cover at least the JM0 AU/NZ export CX-9 VINs (and it could be the same for CX-5 in AU/NZ).
I can provide the full firmware set and full VIN privately if that would be helpful to design a more robust VIN fallback rule that would also work for models outside the US market.

Hey @maxzzznz !

Thanks, that's useful information. This PR is for a VIN-fallback in case firmware fingerprinting fails, so shouldn't cause issues if it also fails to match. Unfortunately it does seem like this approach will only work for North America style VINs as the VIN format for JM0 (Mazda for Oceania export) doesn't appear to expose the year of manufacture. I'll have to keep looking for a solution there.

If you'd like you can send me your cars fingerprints, but I did look over your PR and the firmware you submitted is already present in the Mazda fingerprint list for a CX-9. For clarity: I noticed your code said 'HYBRID_CX9_FW', was the intent to imply a 'hybrid fingerprint' and not that your CX-9 is a hybrid vehicle? Just wanted to be sure.

Thanks for your response. Yes all the car fingerprints were already included except for the EPS from 2022+ CX-5, 'HYBRID_CX9_FW' was probably a poor naming choice as I mainly meant a CX-9 car hybrid with a CX-5 part (EPS) but certainly not Hybrid in terms of powertrain.

@mzdnick
mzdnick force-pushed the mazda-vin-fingerprint branch from 098fafb to b7ec4d0 Compare August 24, 2026 00:24
@mzdnick

mzdnick commented Aug 24, 2026

Copy link
Copy Markdown
Author

@maxzzznz I added engine fingerprinting as a final fallback if exact, fuzzy, and VIN were to fail. As it stands, engine firmware is unique to the platform (no two platforms share an engine firmware) so I believe this should be effective.

@mzdnick
mzdnick force-pushed the mazda-vin-fingerprint branch from b7ec4d0 to 4d94bc0 Compare August 24, 2026 00:37
@mzdnick mzdnick changed the title mazda: fingerprint by VIN when firmware matching fails mazda: VIN and Engine-firmware fingerprint fallback Aug 24, 2026
@mzdnick mzdnick changed the title mazda: VIN and Engine-firmware fingerprint fallback mazda: VIN and engine-firmware fingerprint fallback Aug 24, 2026
A donor EPS (steer-to-zero swaps) breaks exact firmware matching, and shared
or updated chassis firmware breaks generic fuzzy matching, so these cars fall
to manual selection. Decode the WMI, model line (VIN positions 4-5) and model
year code (position 10) to name the chassis platform, the same shape as the
Rivian and Volkswagen fuzzy matchers. The WMI allowlist (JM1, JM3, 3MZ)
rejects a charset-valid VIN from the wrong manufacturer. Steering behavior
stays keyed on the EPS firmware (STEER_TO_ZERO_EPS_FW), so a swapped EPS
keeps full-speed steering.

The decode table is pinned by 24 real listing VINs covering every supported
model line and model year, plus unsupported-model negatives (BP, DM).
Oceania export VINs encode no model year and never decode, leaving those
cars on manual selection no matter what else matches. Engine firmware is
unique per platform (57 recorded versions, zero shared across the six
platforms, asserted by test), so a responding engine names the chassis
regardless of what else was swapped or differs by market. It runs below
the VIN decode and declines a lone responding address.

A known-WMI VIN that decodes to no platform positively identified a car
outside the supported platforms (BP, DM, KE, out-of-range years): those
decline to manual selection rather than an engine guess, so a 2019 Mazda 3
whose PCM carried a BN-era calibration cannot silently become MAZDA_3.
WMIs outside the allowlist (JM0 Oceania, 7MM CX-50) keep the engine
fallback and its collision risk; documented in the code comment and
pinned by an intentional test.
@mzdnick
mzdnick force-pushed the mazda-vin-fingerprint branch from 5468a85 to 197878f Compare August 24, 2026 02:00
@zephleggett
zephleggett marked this pull request as ready for review August 24, 2026 14:25
@zephleggett
zephleggett merged commit c96950f into zoompilot:mazda-dev Aug 24, 2026
6 checks passed
@maxzzznz

Copy link
Copy Markdown

@maxzzznz I added engine fingerprinting as a final fallback if exact, fuzzy, and VIN were to fail. As it stands, engine firmware is unique to the platform (no two platforms share an engine firmware) so I believe this should be effective.

Yes this is a good idea I have just tested it on your branch and it works, you rock! Thanks Nick :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants