1 /* 2 * Copyright (C) 2016 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 com.android.server.wifi; 18 19 import android.text.TextUtils; 20 21 /** 22 * Class for storing an IMSI (International Mobile Subscriber Identity) parameter. The IMSI 23 * contains number (up to 15) of numerical digits. When an IMSI ends with a '*', the specified 24 * IMSI is a prefix. 25 */ 26 public class IMSIParameter { 27 /** 28 * MCC (Mobile Country Code) is a 3 digit number and MNC (Mobile Network Code) is also a 3 29 * digit number. 30 */ 31 public static final int MCC_MNC_LENGTH = 6; 32 33 private static final int MAX_IMSI_LENGTH = 15; 34 35 private final String mImsi; 36 private final boolean mPrefix; 37 IMSIParameter(String imsi, boolean prefix)38 public IMSIParameter(String imsi, boolean prefix) { 39 mImsi = imsi; 40 mPrefix = prefix; 41 } 42 43 /** 44 * Build an IMSIParameter object from the given string. A null will be returned for a 45 * malformed string. 46 * 47 * @param imsi The IMSI string 48 * @return {@link IMSIParameter} 49 */ build(String imsi)50 public static IMSIParameter build(String imsi) { 51 if (TextUtils.isEmpty(imsi)) { 52 return null; 53 } 54 if (imsi.length() > MAX_IMSI_LENGTH) { 55 return null; 56 } 57 58 // Detect the first non-digit character. 59 int nonDigit; 60 char stopChar = '\0'; 61 for (nonDigit = 0; nonDigit < imsi.length(); nonDigit++) { 62 stopChar = imsi.charAt(nonDigit); 63 if (stopChar < '0' || stopChar > '9') { 64 break; 65 } 66 } 67 68 if (nonDigit == imsi.length()) { 69 // Full IMSI. 70 return new IMSIParameter(imsi, false); 71 } 72 else if (nonDigit == imsi.length()-1 && stopChar == '*') { 73 // IMSI prefix. 74 return new IMSIParameter(imsi.substring(0, nonDigit), true); 75 } 76 return null; 77 } 78 79 /** 80 * Perform matching against the given full IMSI. 81 * 82 * @param fullIMSI The full IMSI to match against 83 * @return true if matched 84 */ matchesImsi(String fullIMSI)85 public boolean matchesImsi(String fullIMSI) { 86 if (fullIMSI == null) { 87 return false; 88 } 89 90 if (mPrefix) { 91 // Prefix matching. 92 return mImsi.regionMatches(false, 0, fullIMSI, 0, mImsi.length()); 93 } else { 94 // Exact matching. 95 return mImsi.equals(fullIMSI); 96 } 97 } 98 99 /** 100 * Perform matching against the given MCC-MNC (Mobile Country Code and Mobile Network 101 * Code) combination. 102 * 103 * @param mccMnc The MCC-MNC to match against 104 * @return true if matched 105 */ matchesMccMnc(String mccMnc)106 public boolean matchesMccMnc(String mccMnc) { 107 if (mccMnc == null) { 108 return false; 109 } 110 if (mccMnc.length() != MCC_MNC_LENGTH) { 111 return false; 112 } 113 int checkLength = MCC_MNC_LENGTH; 114 if (mPrefix && mImsi.length() < MCC_MNC_LENGTH) { 115 checkLength = mImsi.length(); 116 } 117 return mImsi.regionMatches(false, 0, mccMnc, 0, checkLength); 118 } 119 120 @Override equals(Object thatObject)121 public boolean equals(Object thatObject) { 122 if (this == thatObject) { 123 return true; 124 } 125 if (!(thatObject instanceof IMSIParameter)) { 126 return false; 127 } 128 129 IMSIParameter that = (IMSIParameter) thatObject; 130 return mPrefix == that.mPrefix && TextUtils.equals(mImsi, that.mImsi); 131 } 132 133 @Override hashCode()134 public int hashCode() { 135 int result = mImsi != null ? mImsi.hashCode() : 0; 136 result = 31 * result + (mPrefix ? 1 : 0); 137 return result; 138 } 139 140 @Override toString()141 public String toString() { 142 if (mPrefix) { 143 return mImsi + '*'; 144 } 145 else { 146 return mImsi; 147 } 148 } 149 } 150