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 android.telephony;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21import android.telephony.Rlog;
22
23/**
24 * Wcdma signal strength related information.
25 */
26public final class CellSignalStrengthWcdma extends CellSignalStrength implements Parcelable {
27
28    private static final String LOG_TAG = "CellSignalStrengthWcdma";
29    private static final boolean DBG = false;
30
31    private static final int WCDMA_SIGNAL_STRENGTH_GREAT = 12;
32    private static final int WCDMA_SIGNAL_STRENGTH_GOOD = 8;
33    private static final int WCDMA_SIGNAL_STRENGTH_MODERATE = 5;
34
35    private int mSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
36    private int mBitErrorRate;   // bit error rate (0-7, 99) as defined in TS 27.007 8.5
37
38    /**
39     * Empty constructor
40     *
41     * @hide
42     */
43    public CellSignalStrengthWcdma() {
44        setDefaultValues();
45    }
46
47    /**
48     * Constructor
49     *
50     * @hide
51     */
52    public CellSignalStrengthWcdma(int ss, int ber) {
53        initialize(ss, ber);
54    }
55
56    /**
57     * Copy constructors
58     *
59     * @param s Source SignalStrength
60     *
61     * @hide
62     */
63    public CellSignalStrengthWcdma(CellSignalStrengthWcdma s) {
64        copyFrom(s);
65    }
66
67    /**
68     * Initialize all the values
69     *
70     * @param ss SignalStrength as ASU value
71     * @param ber is Bit Error Rate
72     *
73     * @hide
74     */
75    public void initialize(int ss, int ber) {
76        mSignalStrength = ss;
77        mBitErrorRate = ber;
78    }
79
80    /**
81     * @hide
82     */
83    protected void copyFrom(CellSignalStrengthWcdma s) {
84        mSignalStrength = s.mSignalStrength;
85        mBitErrorRate = s.mBitErrorRate;
86    }
87
88    /**
89     * @hide
90     */
91    @Override
92    public CellSignalStrengthWcdma copy() {
93        return new CellSignalStrengthWcdma(this);
94    }
95
96    /** @hide */
97    @Override
98    public void setDefaultValues() {
99        mSignalStrength = Integer.MAX_VALUE;
100        mBitErrorRate = Integer.MAX_VALUE;
101    }
102
103    /**
104     * Get signal level as an int from 0..4
105     */
106    @Override
107    public int getLevel() {
108        int level;
109
110        // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
111        // asu = 0 (-113dB or less) is very weak
112        // signal, its better to show 0 bars to the user in such cases.
113        // asu = 99 is a special case, where the signal strength is unknown.
114        int asu = mSignalStrength;
115        if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
116        else if (asu >= WCDMA_SIGNAL_STRENGTH_GREAT) level = SIGNAL_STRENGTH_GREAT;
117        else if (asu >= WCDMA_SIGNAL_STRENGTH_GOOD)  level = SIGNAL_STRENGTH_GOOD;
118        else if (asu >= WCDMA_SIGNAL_STRENGTH_MODERATE)  level = SIGNAL_STRENGTH_MODERATE;
119        else level = SIGNAL_STRENGTH_POOR;
120        if (DBG) log("getLevel=" + level);
121        return level;
122    }
123
124    /**
125     * Get the signal strength as dBm
126     */
127    @Override
128    public int getDbm() {
129        int dBm;
130
131        int level = mSignalStrength;
132        int asu = (level == 99 ? Integer.MAX_VALUE : level);
133        if (asu != Integer.MAX_VALUE) {
134            dBm = -113 + (2 * asu);
135        } else {
136            dBm = Integer.MAX_VALUE;
137        }
138        if (DBG) log("getDbm=" + dBm);
139        return dBm;
140    }
141
142    /**
143     * Get the signal level as an asu value between 0..31, 99 is unknown
144     * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
145     */
146    @Override
147    public int getAsuLevel() {
148        // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
149        // asu = 0 (-113dB or less) is very weak
150        // signal, its better to show 0 bars to the user in such cases.
151        // asu = 99 is a special case, where the signal strength is unknown.
152        int level = mSignalStrength;
153        if (DBG) log("getAsuLevel=" + level);
154        return level;
155    }
156
157    @Override
158    public int hashCode() {
159        int primeNum = 31;
160        return (mSignalStrength * primeNum) + (mBitErrorRate * primeNum);
161    }
162
163    @Override
164    public boolean equals (Object o) {
165        CellSignalStrengthWcdma s;
166
167        try {
168            s = (CellSignalStrengthWcdma) o;
169        } catch (ClassCastException ex) {
170            return false;
171        }
172
173        if (o == null) {
174            return false;
175        }
176
177        return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate;
178    }
179
180    /**
181     * @return string representation.
182     */
183    @Override
184    public String toString() {
185        return "CellSignalStrengthWcdma:"
186                + " ss=" + mSignalStrength
187                + " ber=" + mBitErrorRate;
188    }
189
190    /** Implement the Parcelable interface */
191    @Override
192    public void writeToParcel(Parcel dest, int flags) {
193        if (DBG) log("writeToParcel(Parcel, int): " + toString());
194        dest.writeInt(mSignalStrength);
195        dest.writeInt(mBitErrorRate);
196    }
197
198    /**
199     * Construct a SignalStrength object from the given parcel
200     * where the token is already been processed.
201     */
202    private CellSignalStrengthWcdma(Parcel in) {
203        mSignalStrength = in.readInt();
204        mBitErrorRate = in.readInt();
205        if (DBG) log("CellSignalStrengthWcdma(Parcel): " + toString());
206    }
207
208    /** Implement the Parcelable interface */
209    @Override
210    public int describeContents() {
211        return 0;
212    }
213
214    /** Implement the Parcelable interface */
215    @SuppressWarnings("hiding")
216    public static final Parcelable.Creator<CellSignalStrengthWcdma> CREATOR =
217            new Parcelable.Creator<CellSignalStrengthWcdma>() {
218        @Override
219        public CellSignalStrengthWcdma createFromParcel(Parcel in) {
220            return new CellSignalStrengthWcdma(in);
221        }
222
223        @Override
224        public CellSignalStrengthWcdma[] newArray(int size) {
225            return new CellSignalStrengthWcdma[size];
226        }
227    };
228
229    /**
230     * log
231     */
232    private static void log(String s) {
233        Rlog.w(LOG_TAG, s);
234    }
235}
236