Android 4G专网模块信号的上报过程

最近一直在调试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.
                          * Range: 44 to 140 dBm
                          * 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);

	response_v6.LTE_SignalStrength.rsrp = SignalStrengthTransform(out);
	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);

}


信号强度的解析在framework层是通过socket 和rild接口通信的;ServiceStateTracker.java文件中onSignalStrengthResult(AsyncResult ar, boolean isGsm)会验证ril层上报的信号强度范围是否正确;

 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;
            mSignalStrength.validateInput();	//验证上报的4G信号强度是否在正确范围内?
            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;
        mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? -mLteRsrp : SignalStrength.INVALID; //RSRP ril层上报的必须是正数;
        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;

    }


          



你可能感兴趣的:(Android)