omnt / OpenMobileNetworkToolkit

OpenMobileNetworkToolkit
BSD 3-Clause Clear License
28 stars 8 forks source link

Discrepancy between RSSNR values in DataProvider.getCellInformation() and DataProvider.getSignalStrengthInformation() #40

Closed RkShaRkz closed 2 weeks ago

RkShaRkz commented 3 weeks ago

Bug Report

Context

Description

While we're trying to get a constant (consistent?) measurement of the RSSNR parameter, we've noticed a discrepancy between the value in both the "Details" tab, and what is programatically returned as well. It may also be device/vendor specific, since I'm not seeing it on my test device but am clearly seeing it on my colleagues' devices.

How to Reproduce

While unclear, it falls down to something like this. Steps to reproduce the behavior:

  1. Go to Details panel
  2. Check RSSNR in both Cell Information and Signal Strength cards
  3. Depending on the device/vendor, they will either be the same, or the "Cell information" one will show null (or "N/A") while the "Signal Strength" one will show an actual number, e.g. -1

Expected Behavior

I'd expect both the registered CellInformation obtained by DataProvider.getCellInformation() and the DataProvider.getSignalStrengthInformation() to return the same value

Actual Behavior

Depending on the device, they do not always return the same value; while the one from Signal Strength always seems to have a RSSNR, the Cell Information card doesn't.

Screenshots

quick panel

image

details panel

image

Additional Context

This is better explained with code.

    private static NetworkDataModel getCloudCityData() {
        List<CellInformation> cellsInfo = dp.getCellInformation();
        List<CellInformation> signalInfo = dp.getSignalStrengthInformation();
        LocationInformation location = dp.getLocation();

        CellInformation currentCell = findRegisteredCell(cellsInfo);
        CellInformation currentSignal = null;
        // After testing on a real phone, apparently there's only one SignalStrengthInformation
        // CellInformation member in the list, so lets just take the first one if it's there
        if (!signalInfo.isEmpty()) {
            currentSignal = signalInfo.get(0);
        }

        String category = currentCell.getCellType().toString();

        NetworkDataModel dataModel = new NetworkDataModel();

        dataModel.setCategory(currentCell.getCellType().toString());
        dataModel.setLatitude(location.getLatitude());
        dataModel.setLongitude(location.getLongitude());
        dataModel.setAccuracy(location.getAccuracy());
        /* Convert to km/h */
        dataModel.setSpeed(location.getSpeed() * 3.6);

        dataModel.setCellData(getCellInfoModel(category, currentCell));

        // Lets initialize our MeasurementModel for sending from the registered cell model, then overwrite it's values
        // with what we found in the SignalInformation
        MeasurementsModel modelForSending = getMeasurementsModel(category, currentCell);
        updateMeasurementModelByCell(modelForSending, currentSignal);

        Log.d("currentCellMeasurements: "+currentCell);
        Log.d("signalStrengthMeasurements: "+currentSignal);
        Log.d("modelForSending: "+modelForSending);

        dataModel.setValues(modelForSending);

        return dataModel;
    }

    public static CellInformation findRegisteredCell(@NonNull List<CellInformation> cellList) {
        CellInformation retVal = null;

        for (CellInformation ci: cellList) {
            if (!ci.isRegistered()) {
                continue;
            }

            retVal = ci;
        }

        return retVal;
    }

And the logs will print out this:

currentCellMeasurements: MeasurementsModel{rsrp=-94, rsrq=-14, rssnr=null, csirsrp=null, csirsrq=null, csisinr=null, ssrsrp=null, ssrsrq=null, sssinr=null, dummy=null}

signalStrengthMeasurements: MeasurementsModel{rsrp=-98, rsrq=-15, rssnr=-1, csirsrp=null, csirsrq=null, csisinr=null, ssrsrp=null, ssrsrq=null, sssinr=null, dummy=null}

modelForSending: MeasurementsModel{rsrp=-98, rsrq=-15, rssnr=-1, csirsrp=null, csirsrq=null, csisinr=null, ssrsrp=null, ssrsrq=null, sssinr=null, dummy=null}

I'm also wondering why the CellInformation returned by DataProvider.getSignalStrengthInformation() isn't registered, but since it only had one entry in the list i just took that.

Possible Fix

no idea for a fix, but my workaround can also be seen in the posted code above.

RkShaRkz commented 3 weeks ago

While at it, I've noticed only LTEInformation has RSSNR, so I'm wondering whether this parameter is applicable to all possible networks (3G / 4G / 5G) since they're not all LTE networks? can this particular approach be used to verify the RSSNR of a 5g network?

hajoha commented 2 weeks ago

Hi @RkShaRkz, Android provides two APIs for querying signal data:

  1. onSignalStrengthsChanged
  2. onCellInfoChanged

We've observed that the second callback, onCellInfoChanged, updates more frequently. However, we’re not sure why there are differences in the values returned by each API. Additionally, both callbacks lack CSI-RSRP, CSI-RSRQ, and CSI-SINR for 5G NR SA cells.

We log data from both APIs to InfluxDB using either SignalStrength or CellInformation. If you're using our Dashboards, you can choose to display either CellInformation or SignalStrength.

image

Can this approach be used to verify the RSSNR of a 5G network?

No, RSSNR is not part of 5G, at least not for 5G SA (Standalone). In 5G SA, you should expect to see SS-RSRP, SS-RSRQ and SS-SINR instead. You can read more about this here or in the 3GPP specifications.

We have implemented logging for various cellular network standards.