Android4G专⽹模块信号的上报过程
最近⼀直在调试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;要做相应的转化;不然信号质量格格显⽰不准;
[cpp] view plain copy
1. typedef struct {
2.    int signalStrength;  /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */
3.    int rsrp;            /* The current Reference Signal Receive Power in dBm multipled by -1.
4.                          <span > * Range: 44 to 140 dBm</span>
5.                          * INT_MAX: 0x7FFFFFFF denotes invalid value.
6.                          * Reference: 3GPP TS 36.133 9.1.4 */
7.    int rsrq;            /* The current Reference Signal Receive Quality in dB multiplied by -1.
8.                          * Range: 20 to 3 dB.
9.                          * INT_MAX: 0x7FFFFFFF denotes invalid value.
10.                          * Reference: 3GPP TS 36.133 9.1.7 */
11.    int rssnr;          /* The current reference signal signal-to-noise ratio in 0.1 dB units.
12.                          * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB).
13.                          * INT_MAX : 0x7FFFFFFF denotes invalid value.
14.                          * Reference: 3GPP TS 36.101 8.1.1 */
15.    int cqi;            /* The current Channel Quality Indicator.
16.                          * Range: 0 to 15.
17.                          * INT_MAX : 0x7FFFFFFF denotes invalid value.
18.                          * Reference: 3GPP TS 36.101 9.2, 9.3, A.4 */
19. } RIL_LTE_SignalStrength;
[cpp] view plain copy
1. static int SignalStrengthTransform(int Signal)
2. {
3.    if(Signal == 99){
4.            return 140;
5.        }
6.
7.    return  (Signal*3 - 140)*(-1);  //为了RSRP(44~140)的范围这⾥要根据AT+CSQ上报的值做相应的转换;不然信号显⽰不准确;
8.
9. }
[cpp] view plain copy
1. static void requestSignalStrength(void *data, size_t datalen, RIL_Token t)
2. {
3.    ATResponse *p_response = NULL;
4.    int err;
5.    char *line;
6.    int count =0;
7.    int numofElements;
8.    int *response;
9.    int out;
10.    RIL_SignalStrength_v6 response_v6;
11.    int modem_type;
12.    modem_type = runtime_3g_port_type();
13.    char signal_level[32];
14.
15.    if ((HUAWEI_MODEM == modem_type) ||
16.        (AMAZON_MODEM == modem_type)){
17.        ALOGE("------------------%s@%d---------------------",__func__,__LINE__);
18.        /* Huawei EM770W response is in RIL_GW_SignalStrength form */
19.        //numofElements=sizeof(RIL_GW_SignalStrength)/sizeof(int);
20.        numofElements=sizeof(RIL_SignalStrength_v6)/sizeof(int);
21.    }else{
22.        ALOGE("------------------%s@%d---------------------",__func__,__LINE__);
23.        numofElements=sizeof(RIL_SignalStrength_v6)/sizeof(int);
24.    }
25.    response = (int *)calloc(numofElements, sizeof(int));
26.    if (!response) goto error;
27.    //int response[numofElements];
28.
29.    if(sUnsolictedCREG_failed) {
30.        LOGW("Retry the AT+CREG event report setting");
31.        /*  Network registration events */
32.        err = at_send_command("AT+CREG=2", &p_response);
33.parse error怎么解决
34.        /* some handsets -- in tethered mode -- don't support CREG=2 */
35.        if (err < 0 || p_response->success == 0) {
36.            at_response_free(p_response);
37.            err = at_send_command("AT+CREG=1", &p_response);
38.        }
39.
40.        if (err < 0 || p_response->success == 0) {
41.            LOGE("Warning!No network registration events reported");
42.            sUnsolictedCREG_failed = 1;
43.        }
44.        else {
45.            sUnsolictedCREG_failed = 0;
45.            sUnsolictedCREG_failed = 0;
46.        }
47.        at_response_free(p_response);
48.    }
49.
50.    if(sUnsolictedCGREG_failed) {
51.        LOGW("Retry the AT+CGREG event report setting");
52.        /*  GPRS registration events */
53.        err = at_send_command("AT+CGREG=1", &p_response);
54.        if (err < 0 || p_response->success == 0) {
55.          LOGE("Warning!No GPRS registration events reported");
56.          sUnsolictedCGREG_failed = 1;
57.        }
58.        else {
59.          sUnsolictedCGREG_failed = 0;
60.        }
61.
62.      at_response_free(p_response);
63.    }
64.
65.    err = at_send_command_singleline("AT+CSQ", "+CSQ:", &p_response);
66.
67.    if (err < 0 || p_response->success == 0) {
68.        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
69.        goto error;
70.    }
71.    memset(&response_v6, 0, sizeof(RIL_SignalStrength_v6));
72.
73.    line = p_response->p_intermediates->line;
74.
75.    err = at_tok_start(&line);
76.    if (err < 0) goto error;
77. #if 0
78.    for (count =0; count < numofElements; count ++) {
79.        err = at_tok_nextint(&line, &(response[count]));
80.        if (err < 0) goto error;
81.    }
82. #else
83.    err = at_tok_nextint(&line, &out);
84.
85.    <span >response_v6.LTE_SignalStrength.rsrp = SignalStrengthTransform(out);</span>
86.    if (err < 0) goto error;
87.    err = at_tok_nextint(&line, &(response_v6.GW_SignalStrength.bitErrorRate));
88.    if (err < 0) goto error;
89.      #if 1
90.        response_v6.GW_SignalStrength.signalStrength = 99;
91.        response_v6.GW_SignalStrength.bitErrorRate = -1;
92.        response_v6.CDMA_SignalStrength.dbm = -1;
93.        response_v6.io = -1;
94.        response_v6.EVDO_SignalStrength.dbm = -1;
95.        response_v6.io = -1;
96.        response_v6.EVDO_SignalStrength.signalNoiseRatio = -1;
97.        response_v6.LTE_SignalStrength.signalStrength = 99;
98.        response_v6.LTE_SignalStrength.rsrq = 0x7FFFFFFF;
99.        response_v6.LTE_SignalStrength.rssnr = 0x7FFFFFFF;
100.        response_v6.LTE_SignalStrength.cqi = 0x7FFFFFFF;
101.    #endif
102. #endif
103.    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.bitErro 104.
105.    RIL_onRequestComplete(t, RIL_E_SUCCESS, (int *)(&response_v6), sizeof(response_v6));
106.
107.    at_response_free(p_response);
108.    free(response);
109.
110.    //sprintf(signal_level, "link:%d,sig:%d", link_4g, response[0]);
111.    //WriteFile("/sdcard/tchtc/4g_", signal_level);
112.
113.    return;
114.
115. error:
116.    RLOGE("requestSignalStrength must never return an error when radio is on");
117.    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
118.    at_response_free(p_response);
119.    free(response);
120.
121. }
信号强度的解析在framework层是通过socket 和rild接⼝通信的;ServiceStateTracker.java⽂件中onSignalStrengthResult(AsyncResult ar, boolean isGsm)会验证ril层上报的信号强度范围是否正确;
[cpp] view plain copy
1. protected boolean onSignalStrengthResult(AsyncResult ar, boolean isGsm) {
2.        SignalStrength oldSignalStrength = mSignalStrength;
3.
4.        // This signal is used for both voice and data radio signal so parse
5.        // all fields
6.
7.        if ((ar.exception == null) && (ar.result != null)) {
7.        if ((ar.exception == null) && (ar.result != null)) {
8.            mSignalStrength = (SignalStrength) ar.result;
9.          <span > mSignalStrength.validateInput();  //验证上报的4G信号强度是否在正确范围内?</span>
10.            mSignalStrength.setGsm(isGsm);
11.        } else {
12.            log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
13.            mSignalStrength = new SignalStrength(isGsm);
14.        }
15.
16.        return notifySignalStrength();
17.    }
[cpp] view plain copy
1. public void validateInput() {
2.        if (DBG) log("Signal before validate=" + this);
3.        // TS 27.007 8.5
4.        mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99;
5.        // BER no change;
6.
7.        mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120;
8.        mCdmaEcio = (mCdmaEcio > 0) ? -mCdmaEcio : -160;
9.
10.        mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120;
11.        mEvdoEcio = (mEvdoEcio >= 0) ? -mEvdoEcio : -1;
12.        mEvdoSnr = ((mEvdoSnr > 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1;
13.
14.        // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC
15.        mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99;
16.        <span >mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? </span><span >-mLteRsrp</span><span > : SignalStrength.INVALID; //RSR
上报的必须是正数;</span>
17.        mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
18.        mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
19.                : SignalStrength.INVALID;
20.        // Cqi no change
21.        if (DBG) log("Signal after validate=" + this);
22.    }
SignalStrength.Java⽂件中getLevel() 是对信号的解析;4G信号解析就是getLteLevel() 函数;
[cpp] view plain copy
1. public int getLteLevel() {
2.        /*
3.          * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received
4.          * signal + noise RSRP = reference signal dBm RSRQ = quality of signal
5.          * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio
6.          * = -10log P1/P2 dB
7.          */
8.        int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1;
9.
10.        if (mLteRsrp > -44) rsrpIconLevel = -1;
11.        //根据RSRP信号强度转化成UI通知栏的信号强度格格;
12.        else if (mLteRsrp >= -85) rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
13.        else if (mLteRsrp >= -95) rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
14.        else if (mLteRsrp >= -105) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
15.        else if (mLteRsrp >= -115) rsrpIconLevel = SIGNAL_STRENGTH_POOR;
16.        else if (mLteRsrp >= -140) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
17.
18.        /*
19.          * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
20.          * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
21.          * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
22.          * Icon Only
23.          */
24.        if (mLteRssnr > 300) snrIconLevel = -1;
25.        else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT;
26.        else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD;
27.        else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE;
28.        else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR;
29.        else if (mLteRssnr >= -200)
30.            snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
31.
32.        if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:"
33.                + rsrpIconLevel + " snrIconLevel:" + snrIconLevel);
34.
35.        /* Choose a measurement type to use for notification */
36.        if (snrIconLevel != -1 && rsrpIconLevel != -1) {
37.            /*
38.              * The number of bars displayed shall be the smaller of the bars
39.              * associated with LTE RSRP and the bars associated with the LTE
40.              * RS_SNR
41.              */
42.            return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
43.        }
44.
45.        if (snrIconLevel != -1) return snrIconLevel;
46.
47.        if (rsrpIconLevel != -1) return rsrpIconLevel;
47.        if (rsrpIconLevel != -1) return rsrpIconLevel;
48.
49.        /* Valid values are (0-63, 99) as defined in TS 36.331 */
50.        if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
51.        else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT;
52.        else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
53.        else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
54.        else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR;
55.        if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:"
56.                + rssiIconLevel);
57.        return rssiIconLevel;
58.
59.    }

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。