mroczis / netmonster-core

Android Telephony SDK bridge with some additional features
Apache License 2.0
334 stars 71 forks source link

CONNECTION_SECONDARY_SERVING isn't reliable #53

Closed handymenny closed 1 year ago

handymenny commented 1 year ago

Description

Some devices, mainly those with a Samsung baseband, use CONNECTION_SECONDARY_SERVING even for cells that aren't used for data. In some cases all neighbor cells have connectionStatus = _CONNECTION_SECONDARYSERVING. This can be easily seen in the following examples, where multiple cells with the same ARFCN or even cells on different networks (ran sharing) are marked as primary/secondary serving. For NR take the following issue into account: CellIdentityNr#getNrarfcn() is ambigous: SSB or Carrier centre?

Suggestions

These are some ways to fix/mitigate this issue:

  1. Assume _CONNECTION_SECONDARYSERVING equivalent to _CONNECTIONNONE, i.e. ignore _CONNECTION_SECONDARYSERVING
  2. Ignore _CONNECTION_SECONDARYSERVING when there're multiple serving cells with same ARFCN or different RATs (i.e. LTE and WCDMA)
  3. Same as above, but permanently ignore until a new firmware update
  4. Ignore _CONNECTION_SECONDARYSERVING for devices known to report fake secondary serving cells (for example all devices with a Samsung baseband)

Examples

API Output

Google Pixel 7 (GVU6C) API 33

LTE:

[CellLte(network=Network(mcc=222, mnc=88, iso=IT), eci=XXXX, tac=XXXX, pci=8, band=BandLte(downlinkEarfcn=3350, number=7, name=2600), bandwidth=20000, signal=SignalLte(rssi=-69, rsrp=-106.0, rsrq=-7.0, cqi=11, snr=1.0, timingAdvance=23), connectionStatus=PrimaryConnection(), subscriptionId=4, timestamp=1888172),
CellLte(network=Network(mcc=222, mnc=88, iso=IT), eci=null, tac=null, pci=3, band=BandLte(downlinkEarfcn=1650, number=3, name=1800), bandwidth=null, signal=SignalLte(rssi=null, rsrp=-111.0, rsrq=-19.0, cqi=null, snr=-1.0, timingAdvance=0), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=4, timestamp=1888172),
CellLte(network=Network(mcc=222, mnc=88, iso=IT), eci=null, tac=null, pci=5, band=BandLte(downlinkEarfcn=1650, number=3, name=1800), bandwidth=null, signal=SignalLte(rssi=null, rsrp=-112.0, rsrq=-19.0, cqi=null, snr=-1.0, timingAdvance=0), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=4, timestamp=1888172),
CellLte(network=Network(mcc=222, mnc=88, iso=IT), eci=null, tac=null, pci=2, band=BandLte(downlinkEarfcn=6200, number=20, name=800), bandwidth=null, signal=SignalLte(rssi=null, rsrp=-91.0, rsrq=-16.0, cqi=null, snr=-1.0, timingAdvance=0), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=4, timestamp=1888172),
CellLte(network=Network(mcc=222, mnc=88, iso=IT), eci=null, tac=null, pci=9, band=BandLte(downlinkEarfcn=6200, number=20, name=800), bandwidth=null, signal=SignalLte(rssi=null, rsrp=-92.0, rsrq=-18.0, cqi=null, snr=-1.0, timingAdvance=0), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=4, timestamp=1888172)]

NR NSA:

[CellInfoNr:{ mRegistered=YES mTimeStamp=66070163213557ns mCellConnectionStatus=1 CellIdentityNr:{ mPci = 349 mTac = 16777215 mNrArfcn = 650666 mBands = [] mMcc = 222 mMnc = 01 mNci = 9223372036854775807 mAlphaLong =  mAlphaShort =  mAdditionalPlmns = {} } CellSignalStrengthNr:{ csiRsrp = 2147483647 csiRsrq = 2147483647 csiCqiTableIndex = 2147483647 csiCqiReport = [0] ssRsrp = -115 ssRsrq = -15 ssSinr = 0 level = 0 parametersUseForLevel = 0 } }
CellInfoNr:{ mRegistered=NO mTimeStamp=66070163213557ns mCellConnectionStatus=2 CellIdentityNr:{ mPci = 350 mTac = 2147483647 mNrArfcn = 648768 mBands = [] mMcc = null mMnc = null mNci = 9223372036854775807 mAlphaLong =  mAlphaShort =  mAdditionalPlmns = {} } CellSignalStrengthNr:{ csiRsrp = 2147483647 csiRsrq = 2147483647 csiCqiTableIndex = 2147483647 csiCqiReport = [0] ssRsrp = -117 ssRsrq = -15 ssSinr = 2147483647 level = 0 parametersUseForLevel = 0 } }]

Google Pixel 7 Pro (GP4BC) / API 33

[CellInfoLte:{mRegistered=YES mTimeStamp=75439291239966ns mCellConnectionStatus=1 CellIdentityLte:{ mCi=XXX mPci=3 mTac=XXXX mEarfcn=1350 mBands=[3] mBandwidth=20000 mMcc=222 mMnc=01 mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=2147483647 rsrp=-98 rsrq=-12 rssnr=0 cqiTableIndex=2147483647 cqi=12 ta=2 level=2 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=75439291239966ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=2147483647 mPci=432 mTac=2147483647 mEarfcn=1350 mBands=[] mBandwidth=0 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=2147483647 rsrp=-103 rsrq=-14 rssnr=-1 cqiTableIndex=2147483647 cqi=0 ta=0 level=2 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}]

Google Pixel 6a (G1AZG) / API 32

[CellNr(network=Network(mcc=222, mnc=50, iso=IT), nci=null, tac=null, pci=299, band=BandNr(downlinkArfcn=642000, downlinkFrequency=3630000, number=77, name=3700), signal=SignalNr(csiRsrp=null, csiRsrq=null, csiSinr=null, ssRsrp=-84, ssRsrq=-10, ssSinr=null), connectionStatus=PrimaryConnection(), subscriptionId=1, timestamp=189575682),
CellNr(network=Network(mcc=222, mnc=50, iso=IT), nci=null, tac=null, pci=298, band=BandNr(downlinkArfcn=641664, downlinkFrequency=3624960, number=null, name=null), signal=SignalNr(csiRsrp=null, csiRsrq=null, csiSinr=null, ssRsrp=-102, ssRsrq=-12, ssSinr=null), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=1, timestamp=189575682)]

Samsung S22 Ultra 5G (SM-S908B) / API 33

[CellInfoLte:{mRegistered=YES mTimeStamp=650041382678013ns mCellConnectionStatus=1 CellIdentityLte:{ mCi=****** mPci=499 mTac=*** mEarfcn=37900 mBands=[38] mBandwidth=2147483647 mMcc=222 mMnc=88 mAlphaLong=FASTWEB mAlphaShort=VERY mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=-57 rsrp=-112 rsrq=-8 rssnr=1 cqiTableIndex=1 cqi=2147483647 ta=0 level=1 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=650041382678013ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=0 mPci=9 mTac=0 mEarfcn=1650 mBands=[3] mBandwidth=2147483647 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=2147483647 rsrp=-116 rsrq=-19 rssnr=0 cqiTableIndex=2147483647 cqi=0 ta=0 level=0 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=650041382678013ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=0 mPci=0 mTac=0 mEarfcn=1650 mBands=[3] mBandwidth=2147483647 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=2147483647 rsrp=-113 rsrq=-17 rssnr=0 cqiTableIndex=2147483647 cqi=0 ta=0 level=1 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=650041382678013ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=0 mPci=5 mTac=0 mEarfcn=1650 mBands=[3] mBandwidth=2147483647 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=2147483647 rsrp=-116 rsrq=-19 rssnr=0 cqiTableIndex=2147483647 cqi=0 ta=0 level=0 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=650041382678013ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=0 mPci=6 mTac=0 mEarfcn=125 mBands=[1] mBandwidth=2147483647 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=2147483647 rsrp=-113 rsrq=-16 rssnr=0 cqiTableIndex=2147483647 cqi=0 ta=0 level=1 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=650041382678013ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=0 mPci=9 mTac=0 mEarfcn=125 mBands=[1] mBandwidth=2147483647 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=2147483647 rsrp=-117 rsrq=-20 rssnr=0 cqiTableIndex=2147483647 cqi=0 ta=0 level=0 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=650041382678013ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=0 mPci=0 mTac=0 mEarfcn=6200 mBands=[20] mBandwidth=2147483647 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=2147483647 rsrp=-102 rsrq=-15 rssnr=0 cqiTableIndex=2147483647 cqi=0 ta=0 level=2 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=650041382678013ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=0 mPci=1 mTac=0 mEarfcn=6200 mBands=[20] mBandwidth=2147483647 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=2147483647 rsrp=-105 rsrq=-18 rssnr=0 cqiTableIndex=2147483647 cqi=0 ta=0 level=2 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=650041382678013ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=0 mPci=7 mTac=0 mEarfcn=6200 mBands=[20] mBandwidth=2147483647 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=2147483647 rsrp=-104 rsrq=-18 rssnr=0 cqiTableIndex=2147483647 cqi=0 ta=0 level=2 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=650041382678013ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=0 mPci=4 mTac=0 mEarfcn=3350 mBands=[7] mBandwidth=2147483647 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=-65 rsrp=-123 rsrq=-15 rssnr=0 cqiTableIndex=2147483647 cqi=0 ta=0 level=0 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=650041382678013ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=0 mPci=7 mTac=0 mEarfcn=3350 mBands=[7] mBandwidth=2147483647 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=-65 rsrp=-127 rsrq=-20 rssnr=0 cqiTableIndex=2147483647 cqi=0 ta=0 level=0 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=650041382678013ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=0 mPci=19 mTac=0 mEarfcn=3350 mBands=[7] mBandwidth=2147483647 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=-65 rsrp=-125 rsrq=-17 rssnr=0 cqiTableIndex=2147483647 cqi=0 ta=0 level=0 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=650041382678013ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=0 mPci=5 mTac=0 mEarfcn=10563 mBands=[] mBandwidth=2147483647 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=-69 rsrp=-113 rsrq=-24 rssnr=0 cqiTableIndex=2147483647 cqi=0 ta=0 level=1 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}
CellInfoLte:{mRegistered=NO mTimeStamp=650041382678013ns mCellConnectionStatus=2 CellIdentityLte:{ mCi=0 mPci=1 mTac=0 mEarfcn=3063 mBands=[7] mBandwidth=2147483647 mMcc=null mMnc=null mAlphaLong= mAlphaShort= mAdditionalPlmns={} mCsgInfo=null} CellSignalStrengthLte: rssi=2147483647 rsrp=-102 rsrq=-24 rssnr=0 cqiTableIndex=2147483647 cqi=0 ta=0 level=2 parametersUseForLevel=0 android.telephony.CellConfigLte :{ isEndcAvailable = false }}]

Netmonster Screenshots

Pixel 6

image image

Pixel 7

image

S22 Ultra

image

mroczis commented 1 year ago

Looks like Samsung modem surprises are now bubbling up to Pixels. I also bumped into this on Pixel 7 Pro, should be fixed with the latest commits.

BTW - I reported this issue directly to Google via bug tracker but for some reason that issue is not longer accessible for public... https://issuetracker.google.com/issues/254843949

handymenny commented 1 year ago

Oh well, good timing :) Are these changes already included in the netmonster APP? Some of the reports above are quite recent

mroczis commented 1 year ago

Included in version 2.21.7

handymenny commented 1 year ago

Included in version 2.21.7

Ok well, then I found a corner case where it doesn't work.

Pixel 7 Pro.

Netmonster w/o postprocessing:

CellLte(network=Network(mcc=222, mnc=01, iso=IT), eci=1***2, tac=9**3, pci=null, band=null, aggregatedBands=[], bandwidth=null, signal=SignalLte(rssi=-71, rsrp=-87.0, rsrq=-7.0, cqi=10, snr=5.0, timingAdvance=3), connectionStatus=PrimaryConnection(), subscriptionId=1, timestamp=null)
CellNr(network=null, nci=null, tac=null, pci=8, band=BandNr(downlinkArfcn=648768, downlinkFrequency=3731520, number=null, name=null), signal=SignalNr(csiRsrp=null, csiRsrq=null, csiSinr=null, ssRsrp=-114, ssRsrq=-15, ssSinr=null), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=1, timestamp=62013560)
CellNr(network=null, nci=null, tac=null, pci=9, band=BandNr(downlinkArfcn=648768, downlinkFrequency=3731520, number=null, name=null), signal=SignalNr(csiRsrp=null, csiRsrq=null, csiSinr=null, ssRsrp=-115, ssRsrq=-16, ssSinr=null), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=1, timestamp=62013560)
CellNr(network=Network(mcc=222, mnc=01, iso=IT), nci=null, tac=null, pci=0, band=BandNr(downlinkArfcn=650666, downlinkFrequency=3759990, number=null, name=null), signal=SignalNr(csiRsrp=null, csiRsrq=null, csiSinr=null, ssRsrp=-115, ssRsrq=-16, ssSinr=-3), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=1, timestamp=62013560)

Netmonster with postprocessing:

CellLte(network=Network(mcc=222, mnc=01, iso=IT), eci=1***2, tac=9**3, pci=null, band=null, aggregatedBands=[], bandwidth=null, signal=SignalLte(rssi=-71, rsrp=-87.0, rsrq=-7.0, cqi=10, snr=5.0, timingAdvance=3), connectionStatus=PrimaryConnection(), subscriptionId=1, timestamp=null)
CellNr(network=Network(mcc=222, mnc=01, iso=IT), nci=null, tac=null, pci=9, band=BandNr(downlinkArfcn=648768, downlinkFrequency=3731520, number=null, name=null), signal=SignalNr(csiRsrp=null, csiRsrq=null, csiSinr=null, ssRsrp=-113, ssRsrq=-15, ssSinr=null), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=1, timestamp=62010706)
CellNr(network=Network(mcc=222, mnc=01, iso=IT), nci=null, tac=null, pci=8, band=BandNr(downlinkArfcn=648768, downlinkFrequency=3731520, number=null, name=null), signal=SignalNr(csiRsrp=null, csiRsrq=null, csiSinr=null, ssRsrp=-114, ssRsrq=-15, ssSinr=null), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=1, timestamp=62010706)
CellNr(network=Network(mcc=222, mnc=01, iso=IT), nci=null, tac=null, pci=0, band=BandNr(downlinkArfcn=650666, downlinkFrequency=3759990, number=null, name=null), signal=SignalNr(csiRsrp=null, csiRsrq=null, csiSinr=null, ssRsrp=-115, ssRsrq=-16, ssSinr=-3), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=1, timestamp=62010706)

CellSource.ALL_CELL_INFO:

CellNr(network=Network(mcc=222, mnc=01, iso=IT), nci=null, tac=null, pci=0, band=BandNr(downlinkArfcn=650666, downlinkFrequency=3759990, number=null, name=null), signal=SignalNr(csiRsrp=null, csiRsrq=null, csiSinr=null, ssRsrp=-112, ssRsrq=-15, ssSinr=5), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=2147483647, timestamp=62013560)
CellNr(network=null, nci=null, tac=null, pci=8, band=BandNr(downlinkArfcn=648768, downlinkFrequency=3731520, number=null, name=null), signal=SignalNr(csiRsrp=null, csiRsrq=null, csiSinr=null, ssRsrp=-114, ssRsrq=-15, ssSinr=null), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=2147483647, timestamp=62013560)
CellNr(network=null, nci=null, tac=null, pci=9, band=BandNr(downlinkArfcn=648768, downlinkFrequency=3731520, number=null, name=null), signal=SignalNr(csiRsrp=null, csiRsrq=null, csiSinr=null, ssRsrp=-115, ssRsrq=-16, ssSinr=null), connectionStatus=SecondaryConnection(isGuess=false), subscriptionId=2147483647, timestamp=62013560)

CellSource.CELL_LOCATION:

CellLte(network=Network(mcc=222, mnc=01, iso=IT), eci=1***2, tac=9**3, pci=null, band=null, aggregatedBands=[], bandwidth=null, signal=SignalLte(rssi=-71, rsrp=-87.0, rsrq=-7.0, cqi=10, snr=5.0, timingAdvance=3), connectionStatus=PrimaryConnection(), subscriptionId=2147483647, timestamp=null)

After some debugging, I figured out that has_primary check is false because postprocessing is done before merging the sources: https://github.com/mroczis/netmonster-core/blob/dadc56aac244ecacd85b205779baf0001b794093/library/src/main/java/cz/mroczis/netmonster/core/feature/postprocess/InvalidSecondaryCellsPostprocessor.kt#L20 https://github.com/mroczis/netmonster-core/blob/dadc56aac244ecacd85b205779baf0001b794093/library/src/main/java/cz/mroczis/netmonster/core/NetMonster.kt#L118

The problem is that solving this issue will break the NR NSA detection... We would need to run this postprocessor before PLMN guess, so we can do something like:

if ((cell.connectionStatus as? SecondaryConnection)?.isGuess == false && (hasPrimary || cell.network == null)) {
    cell.let(CellConnectionSwitcher)
} else {
    cell
}

Or alternatively a new check here (nci == null && network == null && connection is SecondaryConnection): https://github.com/mroczis/netmonster-core/blob/8d4a8c967ade8245dbbdd7297c9a8120e95cc4a3/library/src/main/java/cz/mroczis/netmonster/core/telephony/mapper/cell/CellMapperNr.kt#L47-L54 Or a new postprocessor