CPR decoding surface positions, impossible without reference location?

So here is a trace, it’s not jumping around but i’ve found an MLAT position in the json while view1090-fa shows it as a synthetic MLAT message.
cpr-debugging/A0D98D-with-mlat-input at master · wiedehopf/cpr-debugging · GitHub

now: 910.0   seen_pos: 6.5         mlat: [track  baro_rate]         lon:-122.219497   lat:37.716111

*92a0d98d900544b99ac421a5eefc;
CRC: 000000
This is a synthetic MLAT message.
DF:18 AA:A0D98D CF:2 ME:900544B99AC421
 Extended Squitter (Non-Transponder) Airborne position (barometric altitude) (18) 
  ICAO Address:  A0D98D (TIS-B)
  Baro altitude: -100 ft
  CPR type:      Airborne
  CPR odd flag:  odd  
  CPR latitude:  37.71611 (23757)
  CPR longitude: -122.21950 (50209)                                                                                                    
  CPR decoding:  local
  NIC:           8    
  Rc:            0.186 km / 0.1 NM

To create these traces i’ve used view1090-fa and pointed it at the dump1090-fa out with forward-mlat enabled and used show-only to avoid the noise of the other planes.
In the webinterface i was logging the data it got from the aircraft json for the same plane.
New line is written whenever the position in the json changes.

This is the same trace without any MLAT input:
cpr-debugging/A0D98D-no-mlat-input at master · wiedehopf/cpr-debugging · GitHub

Note that the position changing to undefined also shows some problem.
The position goes to undefined while the dump1090-fa without the MLAT data decodes the position just fine.
Or rather the position is decoded in both cases but the dump1090-fa with the MLAT input doesn’t use the position in the json?

@obj
So i’ve maybe found a logic error:

maybe this is needed? · wiedehopf/dump1090@ba492ee · GitHub

    // CPR, even
    if (mm->cpr_valid && !mm->cpr_odd && accept_data(&a->cpr_even_valid, mm->source)) {
        a->cpr_even_type = mm->cpr_type;
        a->cpr_even_lat = mm->cpr_lat;
        a->cpr_even_lon = mm->cpr_lon;
        compute_nic_rc_from_message(mm, a, &a->cpr_even_nic, &a->cpr_even_rc);
    }
    
    // CPR, odd
    if (mm->cpr_valid && mm->cpr_odd && accept_data(&a->cpr_odd_valid, mm->source)) {
        a->cpr_odd_type = mm->cpr_type;
        a->cpr_odd_lat = mm->cpr_lat;
        a->cpr_odd_lon = mm->cpr_lon;
        compute_nic_rc_from_message(mm, a, &a->cpr_odd_nic, &a->cpr_odd_rc);
    }

[...]

    // If we've got a new cprlat or cprlon
    if (mm->cpr_valid) {                                                                                                               
        updatePosition(a, mm); 
    }

If i understand this code correctly we should only call updatePosition if we have actually changed the a->cpr variables.
Right now updatePosition is called for every CPR even if we don’t want to use it.

Then this check:

    // If we have enough recent data, try global CPR
    if (trackDataValid(&a->cpr_odd_valid) && trackDataValid(&a->cpr_even_valid) &&
        a->cpr_odd_valid.source == a->cpr_even_valid.source &&
        a->cpr_odd_type == a->cpr_even_type &&
        time_between(a->cpr_odd_valid.updated, a->cpr_even_valid.updated) <= max_elapsed)

This code is then ineffective because it’s checking the old a->cpr data while the actual mm->source might be MLAT.