CdmaLteServiceStateTracker.java revision a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0a
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.telephony.cdma;
18
19import com.android.internal.telephony.TelephonyProperties;
20import com.android.internal.telephony.MccTable;
21import com.android.internal.telephony.EventLogTags;
22import com.android.internal.telephony.uicc.RuimRecords;
23import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
24
25import android.telephony.CellInfo;
26import android.telephony.CellInfoLte;
27import android.telephony.CellSignalStrengthLte;
28import android.telephony.CellIdentityLte;
29import android.telephony.SignalStrength;
30import android.telephony.ServiceState;
31import android.telephony.cdma.CdmaCellLocation;
32import android.text.TextUtils;
33import android.os.AsyncResult;
34import android.os.Message;
35import android.os.SystemClock;
36import android.os.SystemProperties;
37
38import android.telephony.Rlog;
39import android.util.EventLog;
40
41import java.io.FileDescriptor;
42import java.io.PrintWriter;
43import java.util.ArrayList;
44import java.util.List;
45
46public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
47    private CDMALTEPhone mCdmaLtePhone;
48    private final CellInfoLte mCellInfoLte;
49
50    private CellIdentityLte mNewCellIdentityLte = new CellIdentityLte();
51    private CellIdentityLte mLasteCellIdentityLte = new CellIdentityLte();
52
53    public CdmaLteServiceStateTracker(CDMALTEPhone phone) {
54        super(phone, new CellInfoLte());
55        mCdmaLtePhone = phone;
56        mCellInfoLte = (CellInfoLte) mCellInfo;
57
58        ((CellInfoLte)mCellInfo).setCellSignalStrength(new CellSignalStrengthLte());
59        ((CellInfoLte)mCellInfo).setCellIdentity(new CellIdentityLte());
60
61        if (DBG) log("CdmaLteServiceStateTracker Constructors");
62    }
63
64    @Override
65    public void handleMessage(Message msg) {
66        AsyncResult ar;
67        int[] ints;
68        String[] strings;
69        switch (msg.what) {
70        case EVENT_POLL_STATE_GPRS:
71            if (DBG) log("handleMessage EVENT_POLL_STATE_GPRS");
72            ar = (AsyncResult)msg.obj;
73            handlePollStateResult(msg.what, ar);
74            break;
75        case EVENT_RUIM_RECORDS_LOADED:
76            RuimRecords ruim = (RuimRecords)mIccRecords;
77            if ((ruim != null) && ruim.isProvisioned()) {
78                mMdn = ruim.getMdn();
79                mMin = ruim.getMin();
80                parseSidNid(ruim.getSid(), ruim.getNid());
81                mPrlVersion = ruim.getPrlVersion();
82                mIsMinInfoReady = true;
83                updateOtaspState();
84            }
85            // SID/NID/PRL is loaded. Poll service state
86            // again to update to the roaming state with
87            // the latest variables.
88            pollState();
89            break;
90        default:
91            super.handleMessage(msg);
92        }
93    }
94
95    /**
96     * Handle the result of one of the pollState()-related requests
97     */
98    @Override
99    protected void handlePollStateResultMessage(int what, AsyncResult ar) {
100        if (what == EVENT_POLL_STATE_GPRS) {
101            String states[] = (String[])ar.result;
102            if (DBG) {
103                log("handlePollStateResultMessage: EVENT_POLL_STATE_GPRS states.length=" +
104                        states.length + " states=" + states);
105            }
106
107            int type = 0;
108            int regState = -1;
109            if (states.length > 0) {
110                try {
111                    regState = Integer.parseInt(states[0]);
112
113                    // states[3] (if present) is the current radio technology
114                    if (states.length >= 4 && states[3] != null) {
115                        type = Integer.parseInt(states[3]);
116                    }
117                } catch (NumberFormatException ex) {
118                    loge("handlePollStateResultMessage: error parsing GprsRegistrationState: "
119                                    + ex);
120                }
121                if (states.length >= 10) {
122                    int mcc;
123                    int mnc;
124                    int tac;
125                    int pci;
126                    int eci;
127                    int csgid;
128                    String operatorNumeric = null;
129
130                    try {
131                        operatorNumeric = mNewSS.getOperatorNumeric();
132                        mcc = Integer.parseInt(operatorNumeric.substring(0,3));
133                    } catch (Exception e) {
134                        try {
135                            operatorNumeric = mSS.getOperatorNumeric();
136                            mcc = Integer.parseInt(operatorNumeric.substring(0,3));
137                        } catch (Exception ex) {
138                            loge("handlePollStateResultMessage: bad mcc operatorNumeric=" +
139                                    operatorNumeric + " ex=" + ex);
140                            operatorNumeric = "";
141                            mcc = Integer.MAX_VALUE;
142                        }
143                    }
144                    try {
145                        mnc = Integer.parseInt(operatorNumeric.substring(3));
146                    } catch (Exception e) {
147                        loge("handlePollStateResultMessage: bad mnc operatorNumeric=" +
148                                operatorNumeric + " e=" + e);
149                        mnc = Integer.MAX_VALUE;
150                    }
151
152                    // Use Integer#decode to be generous in what we receive and allow
153                    // decimal, hex or octal values.
154                    try {
155                        tac = Integer.decode(states[6]);
156                    } catch (Exception e) {
157                        loge("handlePollStateResultMessage: bad tac states[6]=" +
158                                states[6] + " e=" + e);
159                        tac = Integer.MAX_VALUE;
160                    }
161                    try {
162                        pci = Integer.decode(states[7]);
163                    } catch (Exception e) {
164                        loge("handlePollStateResultMessage: bad pci states[7]=" +
165                                states[7] + " e=" + e);
166                        pci = Integer.MAX_VALUE;
167                    }
168                    try {
169                        eci = Integer.decode(states[8]);
170                    } catch (Exception e) {
171                        loge("handlePollStateResultMessage: bad eci states[8]=" +
172                                states[8] + " e=" + e);
173                        eci = Integer.MAX_VALUE;
174                    }
175                    try {
176                        csgid = Integer.decode(states[9]);
177                    } catch (Exception e) {
178                        // FIX: Always bad so don't pollute the logs
179                        // loge("handlePollStateResultMessage: bad csgid states[9]=" +
180                        //        states[9] + " e=" + e);
181                        csgid = Integer.MAX_VALUE;
182                    }
183                    mNewCellIdentityLte = new CellIdentityLte(mcc, mnc, eci, pci, tac);
184                    if (DBG) {
185                        log("handlePollStateResultMessage: mNewLteCellIdentity=" +
186                                mNewCellIdentityLte);
187                    }
188                }
189            }
190
191            mNewSS.setRilDataRadioTechnology(type);
192            int dataRegState = regCodeToServiceState(regState);
193            mNewSS.setDataRegState(dataRegState);
194            if (DBG) {
195                log("handlPollStateResultMessage: CdmaLteSST setDataRegState=" + dataRegState
196                        + " regState=" + regState
197                        + " dataRadioTechnology=" + type);
198            }
199        } else {
200            super.handlePollStateResultMessage(what, ar);
201        }
202    }
203
204    @Override
205    protected void pollState() {
206        mPollingContext = new int[1];
207        mPollingContext[0] = 0;
208
209        switch (mCi.getRadioState()) {
210            case RADIO_UNAVAILABLE:
211                mNewSS.setStateOutOfService();
212                mNewCellLoc.setStateInvalid();
213                setSignalStrengthDefaultValues();
214                mGotCountryCode = false;
215
216                pollStateDone();
217                break;
218
219            case RADIO_OFF:
220                mNewSS.setStateOff();
221                mNewCellLoc.setStateInvalid();
222                setSignalStrengthDefaultValues();
223                mGotCountryCode = false;
224
225                pollStateDone();
226                break;
227
228            default:
229                // Issue all poll-related commands at once, then count
230                // down the responses which are allowed to arrive
231                // out-of-order.
232
233                mPollingContext[0]++;
234                // RIL_REQUEST_OPERATOR is necessary for CDMA
235                mCi.getOperator(obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, mPollingContext));
236
237                mPollingContext[0]++;
238                // RIL_REQUEST_VOICE_REGISTRATION_STATE is necessary for CDMA
239                mCi.getVoiceRegistrationState(obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA,
240                        mPollingContext));
241
242                mPollingContext[0]++;
243                // RIL_REQUEST_DATA_REGISTRATION_STATE
244                mCi.getDataRegistrationState(obtainMessage(EVENT_POLL_STATE_GPRS,
245                                            mPollingContext));
246                break;
247        }
248    }
249
250    @Override
251    protected void pollStateDone() {
252        log("pollStateDone: lte 1 ss=[" + mSS + "] newSS=[" + mNewSS + "]");
253
254        useDataRegStateForDataOnlyDevices();
255
256        boolean hasRegistered = mSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE
257                && mNewSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE;
258
259        boolean hasDeregistered = mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
260                && mNewSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE;
261
262        boolean hasCdmaDataConnectionAttached =
263            mSS.getDataRegState() != ServiceState.STATE_IN_SERVICE
264                && mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE;
265
266        boolean hasCdmaDataConnectionDetached =
267                mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE
268                && mNewSS.getDataRegState() != ServiceState.STATE_IN_SERVICE;
269
270        boolean hasCdmaDataConnectionChanged =
271            mSS.getDataRegState() != mNewSS.getDataRegState();
272
273        boolean hasVoiceRadioTechnologyChanged = mSS.getRilVoiceRadioTechnology()
274                != mNewSS.getRilVoiceRadioTechnology();
275
276        boolean hasDataRadioTechnologyChanged = mSS.getRilDataRadioTechnology()
277                != mNewSS.getRilDataRadioTechnology();
278
279        boolean hasChanged = !mNewSS.equals(mSS);
280
281        boolean hasRoamingOn = !mSS.getRoaming() && mNewSS.getRoaming();
282
283        boolean hasRoamingOff = mSS.getRoaming() && !mNewSS.getRoaming();
284
285        boolean hasLocationChanged = !mNewCellLoc.equals(mCellLoc);
286
287        boolean has4gHandoff =
288                mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE &&
289                (((mSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
290                  (mNewSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) ||
291                 ((mSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD) &&
292                  (mNewSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_LTE)));
293
294        boolean hasMultiApnSupport =
295                (((mNewSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) ||
296                  (mNewSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) &&
297                 ((mSS.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
298                  (mSS.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)));
299
300        boolean hasLostMultiApnSupport =
301            ((mNewSS.getRilDataRadioTechnology() >= ServiceState.RIL_RADIO_TECHNOLOGY_IS95A) &&
302             (mNewSS.getRilDataRadioTechnology() <= ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A));
303
304        if (DBG) {
305            log("pollStateDone:"
306                + " hasRegistered=" + hasRegistered
307                + " hasDeegistered=" + hasDeregistered
308                + " hasCdmaDataConnectionAttached=" + hasCdmaDataConnectionAttached
309                + " hasCdmaDataConnectionDetached=" + hasCdmaDataConnectionDetached
310                + " hasCdmaDataConnectionChanged=" + hasCdmaDataConnectionChanged
311                + " hasVoiceRadioTechnologyChanged= " + hasVoiceRadioTechnologyChanged
312                + " hasDataRadioTechnologyChanged=" + hasDataRadioTechnologyChanged
313                + " hasChanged=" + hasChanged
314                + " hasRoamingOn=" + hasRoamingOn
315                + " hasRoamingOff=" + hasRoamingOff
316                + " hasLocationChanged=" + hasLocationChanged
317                + " has4gHandoff = " + has4gHandoff
318                + " hasMultiApnSupport=" + hasMultiApnSupport
319                + " hasLostMultiApnSupport=" + hasLostMultiApnSupport);
320        }
321        // Add an event log when connection state changes
322        if (mSS.getVoiceRegState() != mNewSS.getVoiceRegState()
323                || mSS.getDataRegState() != mNewSS.getDataRegState()) {
324            EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE, mSS.getVoiceRegState(),
325                    mSS.getDataRegState(), mNewSS.getVoiceRegState(), mNewSS.getDataRegState());
326        }
327
328        ServiceState tss;
329        tss = mSS;
330        mSS = mNewSS;
331        mNewSS = tss;
332        // clean slate for next time
333        mNewSS.setStateOutOfService();
334
335        CdmaCellLocation tcl = mCellLoc;
336        mCellLoc = mNewCellLoc;
337        mNewCellLoc = tcl;
338
339        mNewSS.setStateOutOfService(); // clean slate for next time
340
341        if (hasDataRadioTechnologyChanged) {
342            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
343                    ServiceState.rilRadioTechnologyToString(mSS.getRilDataRadioTechnology()));
344        }
345
346        if (hasRegistered) {
347            mNetworkAttachedRegistrants.notifyRegistrants();
348        }
349
350        if (hasChanged) {
351            if (mPhone.isEriFileLoaded()) {
352                String eriText;
353                // Now the CDMAPhone sees the new ServiceState so it can get the
354                // new ERI text
355                if (mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE) {
356                    eriText = mPhone.getCdmaEriText();
357                } else if (mSS.getVoiceRegState() == ServiceState.STATE_POWER_OFF) {
358                    eriText = (mIccRecords != null) ? mIccRecords.getServiceProviderName() : null;
359                    if (TextUtils.isEmpty(eriText)) {
360                        // Sets operator alpha property by retrieving from
361                        // build-time system property
362                        eriText = SystemProperties.get("ro.cdma.home.operator.alpha");
363                    }
364                } else {
365                    // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used
366                    // for mRegistrationState 0,2,3 and 4
367                    eriText = mPhone.getContext()
368                            .getText(com.android.internal.R.string.roamingTextSearching).toString();
369                }
370                mSS.setOperatorAlphaLong(eriText);
371            }
372
373            if (mUiccApplcation != null && mUiccApplcation.getState() == AppState.APPSTATE_READY &&
374                    mIccRecords != null) {
375                // SIM is found on the device. If ERI roaming is OFF, and SID/NID matches
376                // one configured in SIM, use operator name  from CSIM record.
377                boolean showSpn =
378                    ((RuimRecords)mIccRecords).getCsimSpnDisplayCondition();
379                int iconIndex = mSS.getCdmaEriIconIndex();
380
381                if (showSpn && (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) &&
382                    isInHomeSidNid(mSS.getSystemId(), mSS.getNetworkId()) &&
383                    mIccRecords != null) {
384                    mSS.setOperatorAlphaLong(mIccRecords.getServiceProviderName());
385                }
386            }
387
388            String operatorNumeric;
389
390            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
391                    mSS.getOperatorAlphaLong());
392
393            String prevOperatorNumeric =
394                    SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
395            operatorNumeric = mSS.getOperatorNumeric();
396            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
397
398            if (operatorNumeric == null) {
399                if (DBG) log("operatorNumeric is null");
400                mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
401                mGotCountryCode = false;
402            } else {
403                String isoCountryCode = "";
404                String mcc = operatorNumeric.substring(0, 3);
405                try {
406                    isoCountryCode = MccTable.countryCodeForMcc(Integer.parseInt(operatorNumeric
407                            .substring(0, 3)));
408                } catch (NumberFormatException ex) {
409                    loge("countryCodeForMcc error" + ex);
410                } catch (StringIndexOutOfBoundsException ex) {
411                    loge("countryCodeForMcc error" + ex);
412                }
413
414                mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY,
415                        isoCountryCode);
416                mGotCountryCode = true;
417
418                if (shouldFixTimeZoneNow(mPhone, operatorNumeric, prevOperatorNumeric,
419                        mNeedFixZone)) {
420                    fixTimeZone(isoCountryCode);
421                }
422            }
423
424            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
425                    mSS.getRoaming() ? "true" : "false");
426
427            updateSpnDisplay();
428            mPhone.notifyServiceStateChanged(mSS);
429        }
430
431        if (hasCdmaDataConnectionAttached || has4gHandoff) {
432            mAttachedRegistrants.notifyRegistrants();
433        }
434
435        if (hasCdmaDataConnectionDetached) {
436            mDetachedRegistrants.notifyRegistrants();
437        }
438
439        if ((hasCdmaDataConnectionChanged || hasDataRadioTechnologyChanged)) {
440            log("pollStateDone: call notifyDataConnection");
441            mPhone.notifyDataConnection(null);
442        }
443
444        if (hasRoamingOn) {
445            mRoamingOnRegistrants.notifyRegistrants();
446        }
447
448        if (hasRoamingOff) {
449            mRoamingOffRegistrants.notifyRegistrants();
450        }
451
452        if (hasLocationChanged) {
453            mPhone.notifyLocationChanged();
454        }
455
456        ArrayList<CellInfo> arrayCi = new ArrayList<CellInfo>();
457        synchronized(mCellInfo) {
458            CellInfoLte cil = (CellInfoLte)mCellInfo;
459
460            boolean cidChanged = ! mNewCellIdentityLte.equals(mLasteCellIdentityLte);
461            if (hasRegistered || hasDeregistered || cidChanged) {
462                // TODO: Handle the absence of LteCellIdentity
463                long timeStamp = SystemClock.elapsedRealtime() * 1000;
464                boolean registered = mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE;
465                mLasteCellIdentityLte = mNewCellIdentityLte;
466
467                cil.setRegisterd(registered);
468                cil.setCellIdentity(mLasteCellIdentityLte);
469                if (DBG) {
470                    log("pollStateDone: hasRegistered=" + hasRegistered +
471                            " hasDeregistered=" + hasDeregistered +
472                            " cidChanged=" + cidChanged +
473                            " mCellInfo=" + mCellInfo);
474                }
475                arrayCi.add(mCellInfo);
476            }
477            mPhoneBase.notifyCellInfo(arrayCi);
478        }
479    }
480
481    @Override
482    protected boolean onSignalStrengthResult(AsyncResult ar, boolean isGsm) {
483        if (mSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
484            isGsm = true;
485        }
486        boolean ssChanged = super.onSignalStrengthResult(ar, isGsm);
487
488        synchronized (mCellInfo) {
489            if (mSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
490                mCellInfoLte.setTimeStamp(SystemClock.elapsedRealtime() * 1000);
491                mCellInfoLte.setTimeStampType(CellInfo.TIMESTAMP_TYPE_JAVA_RIL);
492                mCellInfoLte.getCellSignalStrength()
493                                .initialize(mSignalStrength,SignalStrength.INVALID);
494            }
495            if (mCellInfoLte.getCellIdentity() != null) {
496                ArrayList<CellInfo> arrayCi = new ArrayList<CellInfo>();
497                arrayCi.add(mCellInfoLte);
498                mPhoneBase.notifyCellInfo(arrayCi);
499            }
500        }
501        return ssChanged;
502    }
503
504    @Override
505    public boolean isConcurrentVoiceAndDataAllowed() {
506        // For non-LTE, look at the CSS indicator to check on Concurrent V & D capability
507        if (mSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
508            return true;
509        } else {
510            return mSS.getCssIndicator() == 1;
511        }
512    }
513
514    /**
515     * Check whether the specified SID and NID pair appears in the HOME SID/NID list
516     * read from NV or SIM.
517     *
518     * @return true if provided sid/nid pair belongs to operator's home network.
519     */
520    private boolean isInHomeSidNid(int sid, int nid) {
521        // if SID/NID is not available, assume this is home network.
522        if (isSidsAllZeros()) return true;
523
524        // length of SID/NID shold be same
525        if (mHomeSystemId.length != mHomeNetworkId.length) return true;
526
527        if (sid == 0) return true;
528
529        for (int i = 0; i < mHomeSystemId.length; i++) {
530            // Use SID only if NID is a reserved value.
531            // SID 0 and NID 0 and 65535 are reserved. (C.0005 2.6.5.2)
532            if ((mHomeSystemId[i] == sid) &&
533                ((mHomeNetworkId[i] == 0) || (mHomeNetworkId[i] == 65535) ||
534                 (nid == 0) || (nid == 65535) || (mHomeNetworkId[i] == nid))) {
535                return true;
536            }
537        }
538        // SID/NID are not in the list. So device is not in home network
539        return false;
540    }
541
542    /**
543     * TODO: Remove when we get new ril/modem for Galaxy Nexus.
544     *
545     * @return all available cell information, the returned List maybe empty but never null.
546     */
547    @Override
548    public List<CellInfo> getAllCellInfo() {
549        if (mCi.getRilVersion() >= 8) {
550            return super.getAllCellInfo();
551        } else {
552            ArrayList<CellInfo> arrayList = new ArrayList<CellInfo>();
553            CellInfo ci;
554            synchronized(mCellInfo) {
555                arrayList.add(mCellInfoLte);
556            }
557            if (DBG) log ("getAllCellInfo: arrayList=" + arrayList);
558            return arrayList;
559        }
560    }
561
562    @Override
563    protected void log(String s) {
564        Rlog.d(LOG_TAG, "[CdmaLteSST] " + s);
565    }
566
567    @Override
568    protected void loge(String s) {
569        Rlog.e(LOG_TAG, "[CdmaLteSST] " + s);
570    }
571
572    @Override
573    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
574        pw.println("CdmaLteServiceStateTracker extends:");
575        super.dump(fd, pw, args);
576        pw.println(" mCdmaLtePhone=" + mCdmaLtePhone);
577    }
578}
579