9

I was wondering if anyone knew how to programmatically get the SNR or signal to noise ratio of LTE/WCDMA signals in Android phones. The SNR can be viewed from a secret code *#0011# in Samsung models but not in other phones such as Nexus 5. I was thinking if there isn't an actual API, maybe a calculation from existing APIs?

I know for a fact you can get detailed information on signals with the SignalStrength API but I've parsed the parts I saw and can't seem to find any SNR readings.

Any help or suggestions is greatly appreciated!

Thanks!

Additional Information:

I should add that I've been tinkering around with Signal Strength from this thread [link] How to get LTE signal strength in Android? and so that's my starting point for my question.

My results are for the following are:

LteSignalStrength -> fluctuates between around 15-30 depending on location, no idea what this is..

LteRsrp -> shows the dBm, I guess this is how phones determine signal quality (roughly anyway).

LteRsrq -> shows -7 to -11, not sure

LteRssnr -> always 300 for some reason, no idea why...

LteCqi -> Channel Quality Indicator? some huge number that seems to be the max 32-bit integer value, not sure

Is there a way to get to SNR from this API or am I looking for a nonexistent needle in a haystack?

Screenshot of Samsung GalaxyNote2 with SNR reading from *#0011# secret code: enter image description here

Community
  • 1
  • 1
publicknowledge
  • 634
  • 1
  • 9
  • 17
  • SNR = Signal/Noise. Strengths of signals are measured in dbm. Which are always in negative as Signal gets weaker as it moves away from its source. The thing is you get LTE Signal Strength but there is no way (AFAIK) you can measure noise strength on your phone. I think its not possible, maybe there is way but not according to my knowledge. – Atif Farrukh Oct 21 '14 at 04:34
  • Hmm... I'm sure the phone sees it somehow because the Samsung variants are able to show it via secret code. Just wish the API was more available. – publicknowledge Oct 21 '14 at 04:51
  • thats interesting, can you please post the current SNR value, if possible? – Atif Farrukh Oct 21 '14 at 04:54
  • 1
    I would but unfortunately I don't have enough reputation to post it yet... =( – publicknowledge Oct 21 '14 at 05:13
  • you can post the link at any or just write the value of SNR; here Now you can upload images. – Atif Farrukh Oct 21 '14 at 05:17
  • Well, the SNR is around 14-15 where I am right now. – publicknowledge Oct 21 '14 at 05:24
  • Thanks for the upvote. Screenshot attached now. – publicknowledge Oct 21 '14 at 05:29
  • can you please take new screenshot and post it with exact value `LteSignalStrength` I just did some calculation and I am getting SNR of 18. I just assumed `LteSignalStrength ` 20. I would like to use exact values instead of assumptions. – Atif Farrukh Oct 21 '14 at 05:46
  • You might find something useful [here](https://android.googlesource.com/platform/frameworks/base/+/b267554/telephony/java/android/telephony/CellSignalStrengthLte.java) – gilonm Oct 21 '14 at 05:50
  • my LteSignalStrength on another device side by side fluctuates from 29-31 while on the Samsung SNR fluctuates from 16-20. Do you know what the relation between the 2 of them is? – publicknowledge Oct 21 '14 at 05:52

2 Answers2

12

I'm researching this subject intensively since Aug-2014. Firstly, I hope that you're familiar with some telecom knowledge and Android Open Source Project (AOSP). Well, based on my researches, I state that:

  1. By looking at AOSP internal native classes, it seems that Android gives SignalStrength values by parceling returned values from AT+CSQ command (please, check AOSP native class reference-ril.c) over the modem. And only from it. The problem is that this command only gives the signal quality coupled with block error rate (BLER), and do not inform anything about other incoming signals; In LTE modem it seems to be OK in some devices, but when you change to UMTS network, things become unclear/inconsistent;
  2. You may calculate incoming interference (SNR and others) by using some derivations from telecom formulas (relating RSSI, RSCP, EcNo, and so on...) by yourself with received signal strengths from other cells, or with the AT+CGREG and AT+CREG (again, please check reference-ril.c class).;
  3. I digged all AOSP internal classes, tracing and diagraming method calls related with telephony. I've looked all from the SDK layer (where we use TelephonyManager and PhoneStateListener API classes), over to the native radio interface layers classes written in c/c++. In any moment I have found a SNQ calculation truly based in other cells, but only passed as a value obtained from the modem with AT+CSQ (this command gives only signal quality and BLER). It sounds strange for me, because interference is a value calculated with other received signals, inclusively those ones that are not from GSM. So, for me, the incoming SNR got from Android API is somewhat lame or incomplete.

Based on the above, I suppose that:

  1. Google is not 3GPP. And 3GPP is not Google. Android is a huge and complex project with more than 12 million lines of code. It is very plausible that communication/theoretical informations may be missed among Android and telecom;
  2. In particular I'm searching for CQI, and I suspect that CQI is in the context of LQR (Link Quality Report), calculated in the L2 PPP (Point-to-Point Protocol);
  3. The subject of this thread is really problematic. There will be no holy grail, because different devices owns different (maybe closed) hardware drivers. We'll need to support different softwares for each different device. Maybe, you'll need to recompile an entire Android ROM for each device, if you need to have a correct value for all device.

I hope that it brings some light to you. If you have any additional information, please share it here.

Marcelo
  • 2,075
  • 5
  • 21
  • 38
3

I use the following to get the SNR:

public class PhoneStateListener extends android.telephony.PhoneStateListener
{
    @Override
    public void onSignalStrengthsChanged(SignalStrength signalStrength)
    {
        double snr = (double) SignalStrength.class.getMethod("getLteRssnr").invoke(signalStrength)/10D;
    }
}

You just need to register for signal events:

TelephonyManager mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
PhoneStateListener mPhoneStateListener = new PhoneStateListener();
mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
noam
  • 94
  • 2
  • 1
    Note that starting from Android Q it was changed to `CellSignalStrengthLte.getRssi()` https://developer.android.com/about/versions/10/non-sdk-q – Keselme Nov 19 '19 at 15:47
  • How to find SNR for Wcdma? – Mercy Angel Dec 17 '19 at 12:54
  • @MercyAngel You can use the type casting procedure by getting all possible cellInfolist :- `val telephonyManager: TelephonyManager = this.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager cellInfoList = telephonyManager.allCellInfo` and then you can simply check the item of cell info list that you got is of wcdma or not! like below: `if (cellInfo is CellInfoWcdma) { ... }` Hope this will be helpful. – A S M Sayem Jul 18 '22 at 09:30