• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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 
17 package android.telephony;
18 
19 import static android.text.TextUtils.formatSimple;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.os.Parcel;
24 import android.telephony.gsm.GsmCellLocation;
25 import android.util.ArraySet;
26 
27 import java.util.Collection;
28 import java.util.Collections;
29 import java.util.Objects;
30 import java.util.Set;
31 
32 /**
33  * CellIdentity is to represent a unique TD-SCDMA cell
34  */
35 public final class CellIdentityTdscdma extends CellIdentity {
36     private static final String TAG = CellIdentityTdscdma.class.getSimpleName();
37     private static final boolean DBG = false;
38 
39     private static final int MAX_LAC = 65535;
40     private static final int MAX_CID = 268435455;
41     private static final int MAX_CPID = 127;
42     private static final int MAX_UARFCN = 65535;
43 
44     // 16-bit Location Area Code, 0..65535, CellInfo.UNAVAILABLE if unknown.
45     private final int mLac;
46     // 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, CellInfo.UNAVAILABLE
47     // if unknown.
48     private final int mCid;
49     // 8-bit Cell Parameters ID described in TS 25.331 sec 10.3.6.9,
50     // 0..127, CellInfo.UNAVAILABLE if unknown.
51     private final int mCpid;
52     // 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.3
53     private final int mUarfcn;
54 
55     // a list of additional PLMN-IDs reported for this cell
56     private final ArraySet<String> mAdditionalPlmns;
57 
58     private ClosedSubscriberGroupInfo mCsgInfo;
59 
60     /**
61      * @hide
62      */
CellIdentityTdscdma()63     public CellIdentityTdscdma() {
64         super(TAG, CellInfo.TYPE_TDSCDMA, null, null, null, null);
65         mLac = CellInfo.UNAVAILABLE;
66         mCid = CellInfo.UNAVAILABLE;
67         mCpid = CellInfo.UNAVAILABLE;
68         mUarfcn = CellInfo.UNAVAILABLE;
69         mAdditionalPlmns = new ArraySet<>();
70         mCsgInfo = null;
71         mGlobalCellId = null;
72     }
73 
74     /**
75      * @param mcc 3-digit Mobile Country Code in string format
76      * @param mnc 2 or 3-digit Mobile Network Code in string format
77      * @param lac 16-bit Location Area Code, 0..65535, CellInfo.UNAVAILABLE if unknown
78      * @param cid 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455,
79      *        CellInfo.UNAVAILABLE if unknown
80      * @param cpid 8-bit Cell Parameters ID described in TS 25.331, 0..127,
81      *        CellInfo.UNAVAILABLE if unknown
82      * @param uarfcn 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.3
83      * @param alphal long alpha Operator Name String or Enhanced Operator Name String
84      * @param alphas short alpha Operator Name String or Enhanced Operator Name String
85      * @param additionalPlmns a list of additional PLMN IDs broadcast by the cell
86      * @param csgInfo info about the closed subscriber group broadcast by the cell
87      *
88      * @hide
89      */
CellIdentityTdscdma(@ullable String mcc, @Nullable String mnc, int lac, int cid, int cpid, int uarfcn, @Nullable String alphal, @Nullable String alphas, @NonNull Collection<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo)90     public CellIdentityTdscdma(@Nullable String mcc, @Nullable String mnc, int lac, int cid,
91             int cpid, int uarfcn, @Nullable String alphal, @Nullable String alphas,
92             @NonNull Collection<String> additionalPlmns,
93             @Nullable ClosedSubscriberGroupInfo csgInfo) {
94         super(TAG, CellInfo.TYPE_TDSCDMA, mcc, mnc, alphal, alphas);
95         mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
96         mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
97         mCpid = inRangeOrUnavailable(cpid, 0, MAX_CPID);
98         mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN);
99         mAdditionalPlmns = new ArraySet<>(additionalPlmns.size());
100         for (String plmn : additionalPlmns) {
101             if (isValidPlmn(plmn)) {
102                 mAdditionalPlmns.add(plmn);
103             }
104         }
105         mCsgInfo = csgInfo;
106         updateGlobalCellId();
107     }
108 
CellIdentityTdscdma(@onNull CellIdentityTdscdma cid)109     private CellIdentityTdscdma(@NonNull CellIdentityTdscdma cid) {
110         this(cid.mMccStr, cid.mMncStr, cid.mLac, cid.mCid,
111                 cid.mCpid, cid.mUarfcn, cid.mAlphaLong,
112                 cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo);
113     }
114 
115     /** @hide */
116     @Override
sanitizeLocationInfo()117     public @NonNull CellIdentityTdscdma sanitizeLocationInfo() {
118         return new CellIdentityTdscdma(mMccStr, mMncStr, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
119                 CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, mAlphaLong, mAlphaShort,
120                 mAdditionalPlmns, null);
121     }
122 
copy()123     @NonNull CellIdentityTdscdma copy() {
124         return new CellIdentityTdscdma(this);
125     }
126 
127     /** @hide */
128     @Override
updateGlobalCellId()129     protected void updateGlobalCellId() {
130         mGlobalCellId = null;
131         String plmn = getPlmn();
132         if (plmn == null) return;
133 
134         if (mLac == CellInfo.UNAVAILABLE || mCid == CellInfo.UNAVAILABLE) return;
135 
136         mGlobalCellId = plmn + formatSimple("%04x%04x", mLac, mCid);
137     }
138 
139     /**
140      * Get Mobile Country Code in string format
141      * @return Mobile Country Code in string format, null if unknown
142      */
143     @Nullable
getMccString()144     public String getMccString() {
145         return mMccStr;
146     }
147 
148     /**
149      * Get Mobile Network Code in string format
150      * @return Mobile Network Code in string format, null if unknown
151      */
152     @Nullable
getMncString()153     public String getMncString() {
154         return mMncStr;
155     }
156 
157     /**
158      * @return a 5 or 6 character string (MCC+MNC), null if any field is unknown
159      */
160     @Nullable
getMobileNetworkOperator()161     public String getMobileNetworkOperator() {
162         return (mMccStr == null || mMncStr == null) ? null : mMccStr + mMncStr;
163     }
164 
165     /**
166      * @return 16-bit Location Area Code, 0..65535,
167      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
168      */
getLac()169     public int getLac() {
170         return mLac;
171     }
172 
173     /**
174      * @return 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455,
175      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
176      */
getCid()177     public int getCid() {
178         return mCid;
179     }
180 
181     /**
182      * @return 8-bit Cell Parameters ID described in TS 25.331, 0..127,
183      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
184      */
getCpid()185     public int getCpid() {
186         return mCpid;
187     }
188 
189     /**
190      * @return 16-bit UMTS Absolute RF Channel Number,
191      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
192      */
getUarfcn()193     public int getUarfcn() {
194         return mUarfcn;
195     }
196 
197     /** @hide */
198     @Override
getChannelNumber()199     public int getChannelNumber() {
200         return mUarfcn;
201     }
202 
203     /**
204      * @return a list of additional PLMN IDs supported by this cell.
205      */
206     @NonNull
getAdditionalPlmns()207     public Set<String> getAdditionalPlmns() {
208         return Collections.unmodifiableSet(mAdditionalPlmns);
209     }
210 
211     /**
212      * @return closed subscriber group information about the cell if available, otherwise null.
213      */
214     @Nullable
getClosedSubscriberGroupInfo()215     public ClosedSubscriberGroupInfo getClosedSubscriberGroupInfo() {
216         return mCsgInfo;
217     }
218 
219     /** @hide */
220     @NonNull
221     @Override
asCellLocation()222     public GsmCellLocation asCellLocation() {
223         GsmCellLocation cl = new GsmCellLocation();
224         int lac = mLac != CellInfo.UNAVAILABLE ? mLac : -1;
225         int cid = mCid != CellInfo.UNAVAILABLE ? mCid : -1;
226         cl.setLacAndCid(lac, cid);
227         cl.setPsc(-1); // There is no PSC for TD-SCDMA; not using this for CPI to stem shenanigans
228         return cl;
229     }
230 
231     @Override
equals(Object other)232     public boolean equals(Object other) {
233         if (this == other) {
234             return true;
235         }
236 
237         if (!(other instanceof CellIdentityTdscdma)) {
238             return false;
239         }
240 
241         CellIdentityTdscdma o = (CellIdentityTdscdma) other;
242         return  mLac == o.mLac
243                 && mCid == o.mCid
244                 && mCpid == o.mCpid
245                 && mUarfcn == o.mUarfcn
246                 && mAdditionalPlmns.equals(o.mAdditionalPlmns)
247                 && Objects.equals(mCsgInfo, o.mCsgInfo)
248                 && super.equals(other);
249     }
250 
251     @Override
hashCode()252     public int hashCode() {
253         return Objects.hash(mLac, mCid, mCpid, mUarfcn,
254                 mAdditionalPlmns.hashCode(), mCsgInfo, super.hashCode());
255     }
256 
257     @Override
toString()258     public String toString() {
259         return new StringBuilder(TAG)
260         .append(":{ mMcc=").append(mMccStr)
261         .append(" mMnc=").append(mMncStr)
262         .append(" mAlphaLong=").append(mAlphaLong)
263         .append(" mAlphaShort=").append(mAlphaShort)
264         .append(" mLac=").append(mLac)
265         .append(" mCid=").append(mCid)
266         .append(" mCpid=").append(mCpid)
267         .append(" mUarfcn=").append(mUarfcn)
268         .append(" mAdditionalPlmns=").append(mAdditionalPlmns)
269         .append(" mCsgInfo=").append(mCsgInfo)
270         .append("}").toString();
271     }
272 
273     /** Implement the Parcelable interface */
274     @Override
describeContents()275     public int describeContents() {
276         return 0;
277     }
278 
279     /** Implement the Parcelable interface */
280     @Override
writeToParcel(Parcel dest, int flags)281     public void writeToParcel(Parcel dest, int flags) {
282         if (DBG) log("writeToParcel(Parcel, int): " + toString());
283         super.writeToParcel(dest, CellInfo.TYPE_TDSCDMA);
284         dest.writeInt(mLac);
285         dest.writeInt(mCid);
286         dest.writeInt(mCpid);
287         dest.writeInt(mUarfcn);
288         dest.writeArraySet(mAdditionalPlmns);
289         dest.writeParcelable(mCsgInfo, flags);
290     }
291 
292     /** Construct from Parcel, type has already been processed */
CellIdentityTdscdma(Parcel in)293     private CellIdentityTdscdma(Parcel in) {
294         super(TAG, CellInfo.TYPE_TDSCDMA, in);
295         mLac = in.readInt();
296         mCid = in.readInt();
297         mCpid = in.readInt();
298         mUarfcn = in.readInt();
299         mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
300         mCsgInfo = in.readParcelable(null, android.telephony.ClosedSubscriberGroupInfo.class);
301 
302         updateGlobalCellId();
303         if (DBG) log(toString());
304     }
305 
306     /** Implement the Parcelable interface */
307     @SuppressWarnings("hiding")
308     @NonNull
309     public static final Creator<CellIdentityTdscdma> CREATOR =
310             new Creator<CellIdentityTdscdma>() {
311                 @Override
312                 public @NonNull CellIdentityTdscdma createFromParcel(Parcel in) {
313                     in.readInt();   // skip
314                     return createFromParcelBody(in);
315                 }
316 
317                 @Override
318                 public @NonNull CellIdentityTdscdma[] newArray(int size) {
319                     return new CellIdentityTdscdma[size];
320                 }
321             };
322 
323     /** @hide */
createFromParcelBody(Parcel in)324     protected static CellIdentityTdscdma createFromParcelBody(Parcel in) {
325         return new CellIdentityTdscdma(in);
326     }
327 }
328