最近一直在调试Android的4G专网模块;一个困扰了我很久的问题昨天也解决了;就是4G信号强度是怎么报上来的?怎么在右上角通知栏显示的?现在也清楚了;
其实只修改reference-ril.c中的一个函数就解决问题了,只是牵扯到很多理解性的东西;
static void requestSignalStrength(void *data, size_t datalen, RIL_Token t)函数是上报信号强度的,是上层每隔一段时间主动请求下发的函数;注意这个函数中Android4.0(没有validateInput()对信号强度的验证)和Android4.4.3是通过RIL_SignalStrength_v6结构体上报的;framework解析信号强度4G优先解析的是RSRP;ril.h中有注释:RSRP的范围是 * Range: 44 to 140 dBm;注意44信号强度最大;140信号强度最小;几乎所有的专网模块都上报数据不是44~140范围;有的是0~31;有的是0~99;要做相应的转化;不然信号质量格格显示不准;
- typedef struct {
- int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */
- int rsrp; /* The current Reference Signal Receive Power in dBm multipled by -1.
- <span style="color:#ff0000;"> * Range: 44 to 140 dBm</span>
- * INT_MAX: 0x7FFFFFFF denotes invalid value.
- * Reference: 3GPP TS 36.133 9.1.4 */
- int rsrq; /* The current Reference Signal Receive Quality in dB multiplied by -1.
- * Range: 20 to 3 dB.
- * INT_MAX: 0x7FFFFFFF denotes invalid value.
- * Reference: 3GPP TS 36.133 9.1.7 */
- int rssnr; /* The current reference signal signal-to-noise ratio in 0.1 dB units.
- * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB).
- * INT_MAX : 0x7FFFFFFF denotes invalid value.
- * Reference: 3GPP TS 36.101 8.1.1 */
- int cqi; /* The current Channel Quality Indicator.
- * Range: 0 to 15.
- * INT_MAX : 0x7FFFFFFF denotes invalid value.
- * Reference: 3GPP TS 36.101 9.2, 9.3, A.4 */
- } RIL_LTE_SignalStrength;
- static int SignalStrengthTransform(int Signal)
- {
- if(Signal == 99){
- return 140;
- }
- return (Signal*3 - 140)*(-1); //为了RSRP(44~140)的范围这里要根据AT+CSQ上报的值做相应的转换;不然信号显示不准确;
- }
- static void requestSignalStrength(void *data, size_t datalen, RIL_Token t)
- {
- ATResponse *p_response = NULL;
- int err;
- char *line;
- int count =0;
- int numofElements;
- int *response;
- int out;
- RIL_SignalStrength_v6 response_v6;
- int modem_type;
- modem_type = runtime_3g_port_type();
- char signal_level[32];
- if ((HUAWEI_MODEM == modem_type) ||
- (AMAZON_MODEM == modem_type)){
- ALOGE("------------------%s@%d---------------------",__func__,__LINE__);
- /* Huawei EM770W response is in RIL_GW_SignalStrength form */
- //numofElements=sizeof(RIL_GW_SignalStrength)/sizeof(int);
- numofElements=sizeof(RIL_SignalStrength_v6)/sizeof(int);
- }else{
- ALOGE("------------------%s@%d---------------------",__func__,__LINE__);
- numofElements=sizeof(RIL_SignalStrength_v6)/sizeof(int);
- }
- response = (int *)calloc(numofElements, sizeof(int));
- if (!response) goto error;
- //int response[numofElements];
- if(sUnsolictedCREG_failed) {
- LOGW("Retry the AT+CREG event report setting");
- /* Network registration events */
- err = at_send_command("AT+CREG=2", &p_response);
- /* some handsets -- in tethered mode -- don't support CREG=2 */
- if (err < 0 || p_response->success == 0) {
- at_response_free(p_response);
- err = at_send_command("AT+CREG=1", &p_response);
- }
- if (err < 0 || p_response->success == 0) {
- LOGE("Warning!No network registration events reported");
- sUnsolictedCREG_failed = 1;
- }
- else {
- sUnsolictedCREG_failed = 0;
- }
- at_response_free(p_response);
- }
- if(sUnsolictedCGREG_failed) {
- LOGW("Retry the AT+CGREG event report setting");
- /* GPRS registration events */
- err = at_send_command("AT+CGREG=1", &p_response);
- if (err < 0 || p_response->success == 0) {
- LOGE("Warning!No GPRS registration events reported");
- sUnsolictedCGREG_failed = 1;
- }
- else {
- sUnsolictedCGREG_failed = 0;
- }
- at_response_free(p_response);
- }
- err = at_send_command_singleline("AT+CSQ", "+CSQ:", &p_response);
- if (err < 0 || p_response->success == 0) {
- RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
- goto error;
- }
- memset(&response_v6, 0, sizeof(RIL_SignalStrength_v6));
- line = p_response->p_intermediates->line;
- err = at_tok_start(&line);
- if (err < 0) goto error;
- #if 0
- for (count =0; count < numofElements; count ++) {
- err = at_tok_nextint(&line, &(response[count]));
- if (err < 0) goto error;
- }
- #else
- err = at_tok_nextint(&line, &out);
- <span style="color:#ff0000;">response_v6.LTE_SignalStrength.rsrp = SignalStrengthTransform(out);</span>
- if (err < 0) goto error;
- err = at_tok_nextint(&line, &(response_v6.GW_SignalStrength.bitErrorRate));
- if (err < 0) goto error;
- #if 1
- response_v6.GW_SignalStrength.signalStrength = 99;
- response_v6.GW_SignalStrength.bitErrorRate = -1;
- response_v6.CDMA_SignalStrength.dbm = -1;
- response_v6.CDMA_SignalStrength.ecio = -1;
- response_v6.EVDO_SignalStrength.dbm = -1;
- response_v6.EVDO_SignalStrength.ecio = -1;
- response_v6.EVDO_SignalStrength.signalNoiseRatio = -1;
- response_v6.LTE_SignalStrength.signalStrength = 99;
- response_v6.LTE_SignalStrength.rsrq = 0x7FFFFFFF;
- response_v6.LTE_SignalStrength.rssnr = 0x7FFFFFFF;
- response_v6.LTE_SignalStrength.cqi = 0x7FFFFFFF;
- #endif
- #endif
- ALOGE("------------------%s@%d---------------------out=%d,signalStrengt=%d,rsrp=%d,bitErrorRate=%d",__func__,__LINE__,out,response_v6.LTE_SignalStrength.signalStrength,response_v6.LTE_SignalStrength.rsrp,response_v6.GW_SignalStrength.bitErrorRate);
- RIL_onRequestComplete(t, RIL_E_SUCCESS, (int *)(&response_v6), sizeof(response_v6));
- at_response_free(p_response);
- free(response);
- //sprintf(signal_level, "link:%d,sig:%d", link_4g, response[0]);
- //WriteFile("/sdcard/tchtc/4g_signal_level.txt", signal_level);
- return;
- error:
- RLOGE("requestSignalStrength must never return an error when radio is on");
- RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
- at_response_free(p_response);
- free(response);
- }
- protected boolean onSignalStrengthResult(AsyncResult ar, boolean isGsm) {
- SignalStrength oldSignalStrength = mSignalStrength;
- // This signal is used for both voice and data radio signal so parse
- // all fields
- if ((ar.exception == null) && (ar.result != null)) {
- mSignalStrength = (SignalStrength) ar.result;
- <span style="color:#ff0000;"> mSignalStrength.validateInput(); //验证上报的4G信号强度是否在正确范围内?</span>
- mSignalStrength.setGsm(isGsm);
- } else {
- log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
- mSignalStrength = new SignalStrength(isGsm);
- }
- return notifySignalStrength();
- }
- public void validateInput() {
- if (DBG) log("Signal before validate=" + this);
- // TS 27.007 8.5
- mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99;
- // BER no change;
- mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120;
- mCdmaEcio = (mCdmaEcio > 0) ? -mCdmaEcio : -160;
- mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120;
- mEvdoEcio = (mEvdoEcio >= 0) ? -mEvdoEcio : -1;
- mEvdoSnr = ((mEvdoSnr > 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1;
- // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC
- mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99;
- <span style="color:#ff0000;">mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? </span><span style="color:#3333ff;">-mLteRsrp</span><span style="color:#ff0000;"> : SignalStrength.INVALID; //RSRP ril层上报的必须是正数;</span>
- mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
- mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
- : SignalStrength.INVALID;
- // Cqi no change
- if (DBG) log("Signal after validate=" + this);
- }
SignalStrength.java文件中getLevel() 是对信号的解析;4G信号解析就是getLteLevel() 函数;
- public int getLteLevel() {
- /*
- * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received
- * signal + noise RSRP = reference signal dBm RSRQ = quality of signal
- * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio
- * = -10log P1/P2 dB
- */
- int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1;
- if (mLteRsrp > -44) rsrpIconLevel = -1;
- //根据RSRP信号强度转化成UI通知栏的信号强度格格;
- else if (mLteRsrp >= -85) rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
- else if (mLteRsrp >= -95) rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
- else if (mLteRsrp >= -105) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
- else if (mLteRsrp >= -115) rsrpIconLevel = SIGNAL_STRENGTH_POOR;
- else if (mLteRsrp >= -140) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- /*
- * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
- * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
- * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
- * Icon Only
- */
- if (mLteRssnr > 300) snrIconLevel = -1;
- else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT;
- else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD;
- else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE;
- else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR;
- else if (mLteRssnr >= -200)
- snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:"
- + rsrpIconLevel + " snrIconLevel:" + snrIconLevel);
- /* Choose a measurement type to use for notification */
- if (snrIconLevel != -1 && rsrpIconLevel != -1) {
- /*
- * The number of bars displayed shall be the smaller of the bars
- * associated with LTE RSRP and the bars associated with the LTE
- * RS_SNR
- */
- return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
- }
- if (snrIconLevel != -1) return snrIconLevel;
- if (rsrpIconLevel != -1) return rsrpIconLevel;
- /* Valid values are (0-63, 99) as defined in TS 36.331 */
- if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT;
- else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
- else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
- else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR;
- if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:"
- + rssiIconLevel);
- return rssiIconLevel;
- }