1 package android.telephony; 2 3 import static android.telephony.ServiceState.DUPLEX_MODE_FDD; 4 import static android.telephony.ServiceState.DUPLEX_MODE_TDD; 5 import static android.telephony.ServiceState.DUPLEX_MODE_UNKNOWN; 6 7 import android.telephony.AccessNetworkConstants.EutranBand; 8 import android.telephony.AccessNetworkConstants.EutranBandArfcnFrequency; 9 import android.telephony.AccessNetworkConstants.GeranBand; 10 import android.telephony.AccessNetworkConstants.GeranBandArfcnFrequency; 11 import android.telephony.AccessNetworkConstants.NgranArfcnFrequency; 12 import android.telephony.AccessNetworkConstants.NgranBands; 13 import android.telephony.AccessNetworkConstants.UtranBand; 14 import android.telephony.AccessNetworkConstants.UtranBandArfcnFrequency; 15 import android.telephony.ServiceState.DuplexMode; 16 17 import java.util.Arrays; 18 import java.util.HashSet; 19 import java.util.Set; 20 21 /** 22 * Utilities to map between radio constants. 23 * 24 * @hide 25 */ 26 public class AccessNetworkUtils { 27 28 // do not instantiate AccessNetworkUtils()29 private AccessNetworkUtils() {} 30 31 public static final int INVALID_BAND = -1; 32 public static final int INVALID_FREQUENCY = -1; 33 34 /** ISO country code of Japan. */ 35 private static final String JAPAN_ISO_COUNTRY_CODE = "jp"; 36 private static final String TAG = "AccessNetworkUtils"; 37 38 private static final int FREQUENCY_KHZ = 1000; 39 private static final int FREQUENCY_RANGE_LOW_KHZ = 1000000; 40 private static final int FREQUENCY_RANGE_MID_KHZ = 3000000; 41 private static final int FREQUENCY_RANGE_HIGH_KHZ = 6000000; 42 43 private static final Set<Integer> UARFCN_NOT_GENERAL_BAND; 44 static { 45 UARFCN_NOT_GENERAL_BAND = new HashSet<Integer>(); 46 UARFCN_NOT_GENERAL_BAND.add(UtranBand.BAND_A); 47 UARFCN_NOT_GENERAL_BAND.add(UtranBand.BAND_B); 48 UARFCN_NOT_GENERAL_BAND.add(UtranBand.BAND_C); 49 UARFCN_NOT_GENERAL_BAND.add(UtranBand.BAND_D); 50 UARFCN_NOT_GENERAL_BAND.add(UtranBand.BAND_E); 51 UARFCN_NOT_GENERAL_BAND.add(UtranBand.BAND_F); 52 } 53 54 /** 55 * Gets the duplex mode for the given EUTRAN operating band. 56 * 57 * <p>See 3GPP 36.101 sec 5.5-1 for calculation 58 * 59 * @param band The EUTRAN band number 60 * @return The duplex mode of the given EUTRAN band 61 */ 62 @DuplexMode getDuplexModeForEutranBand(int band)63 public static int getDuplexModeForEutranBand(int band) { 64 if (band == INVALID_BAND) { 65 return DUPLEX_MODE_UNKNOWN; 66 } 67 68 if (band > EutranBand.BAND_88) { 69 return DUPLEX_MODE_UNKNOWN; 70 } else if (band >= EutranBand.BAND_65) { 71 return DUPLEX_MODE_FDD; 72 } else if (band >= EutranBand.BAND_33) { 73 return DUPLEX_MODE_TDD; 74 } else if (band >= EutranBand.BAND_1) { 75 return DUPLEX_MODE_FDD; 76 } 77 78 return DUPLEX_MODE_UNKNOWN; 79 } 80 81 /** 82 * Gets the EUTRAN Operating band for a given downlink EARFCN. 83 * 84 * <p>See 3GPP TS 36.101 clause 5.7.3-1 for calculation. 85 * 86 * @param earfcn The downlink EARFCN 87 * @return Operating band number, or {@link #INVALID_BAND} if no corresponding band exists 88 */ getOperatingBandForEarfcn(int earfcn)89 public static int getOperatingBandForEarfcn(int earfcn) { 90 if (earfcn > 70645) { 91 return INVALID_BAND; 92 } else if (earfcn >= 70596) { 93 return EutranBand.BAND_88; 94 } else if (earfcn >= 70546) { 95 return EutranBand.BAND_87; 96 } else if (earfcn >= 70366) { 97 return EutranBand.BAND_85; 98 } else if (earfcn > 69465) { 99 return INVALID_BAND; 100 } else if (earfcn >= 69036) { 101 return EutranBand.BAND_74; 102 } else if (earfcn >= 68986) { 103 return EutranBand.BAND_73; 104 } else if (earfcn >= 68936) { 105 return EutranBand.BAND_72; 106 } else if (earfcn >= 68586) { 107 return EutranBand.BAND_71; 108 } else if (earfcn >= 68336) { 109 return EutranBand.BAND_70; 110 } else if (earfcn > 67835) { 111 return INVALID_BAND; 112 } else if (earfcn >= 67536) { 113 return EutranBand.BAND_68; 114 } else if (earfcn >= 67366) { 115 return INVALID_BAND; // band 67 only for CarrierAgg 116 } else if (earfcn >= 66436) { 117 return EutranBand.BAND_66; 118 } else if (earfcn >= 65536) { 119 return EutranBand.BAND_65; 120 } else if (earfcn > 60254) { 121 return INVALID_BAND; 122 } else if (earfcn >= 60140) { 123 return EutranBand.BAND_53; 124 } else if (earfcn >= 59140) { 125 return EutranBand.BAND_52; 126 } else if (earfcn >= 59090) { 127 return EutranBand.BAND_51; 128 } else if (earfcn >= 58240) { 129 return EutranBand.BAND_50; 130 } else if (earfcn >= 56740) { 131 return EutranBand.BAND_49; 132 } else if (earfcn >= 55240) { 133 return EutranBand.BAND_48; 134 } else if (earfcn >= 54540) { 135 return EutranBand.BAND_47; 136 } else if (earfcn >= 46790) { 137 return EutranBand.BAND_46; 138 } else if (earfcn >= 46590) { 139 return EutranBand.BAND_45; 140 } else if (earfcn >= 45590) { 141 return EutranBand.BAND_44; 142 } else if (earfcn >= 43590) { 143 return EutranBand.BAND_43; 144 } else if (earfcn >= 41590) { 145 return EutranBand.BAND_42; 146 } else if (earfcn >= 39650) { 147 return EutranBand.BAND_41; 148 } else if (earfcn >= 38650) { 149 return EutranBand.BAND_40; 150 } else if (earfcn >= 38250) { 151 return EutranBand.BAND_39; 152 } else if (earfcn >= 37750) { 153 return EutranBand.BAND_38; 154 } else if (earfcn >= 37550) { 155 return EutranBand.BAND_37; 156 } else if (earfcn >= 36950) { 157 return EutranBand.BAND_36; 158 } else if (earfcn >= 36350) { 159 return EutranBand.BAND_35; 160 } else if (earfcn >= 36200) { 161 return EutranBand.BAND_34; 162 } else if (earfcn >= 36000) { 163 return EutranBand.BAND_33; 164 } else if (earfcn > 10359) { 165 return INVALID_BAND; 166 } else if (earfcn >= 9920) { 167 return INVALID_BAND; // band 32 only for CarrierAgg 168 } else if (earfcn >= 9870) { 169 return EutranBand.BAND_31; 170 } else if (earfcn >= 9770) { 171 return EutranBand.BAND_30; 172 } else if (earfcn >= 9660) { 173 return INVALID_BAND; // band 29 only for CarrierAgg 174 } else if (earfcn >= 9210) { 175 return EutranBand.BAND_28; 176 } else if (earfcn >= 9040) { 177 return EutranBand.BAND_27; 178 } else if (earfcn >= 8690) { 179 return EutranBand.BAND_26; 180 } else if (earfcn >= 8040) { 181 return EutranBand.BAND_25; 182 } else if (earfcn >= 7700) { 183 return EutranBand.BAND_24; 184 } else if (earfcn >= 7500) { 185 return EutranBand.BAND_23; 186 } else if (earfcn >= 6600) { 187 return EutranBand.BAND_22; 188 } else if (earfcn >= 6450) { 189 return EutranBand.BAND_21; 190 } else if (earfcn >= 6150) { 191 return EutranBand.BAND_20; 192 } else if (earfcn >= 6000) { 193 return EutranBand.BAND_19; 194 } else if (earfcn >= 5850) { 195 return EutranBand.BAND_18; 196 } else if (earfcn >= 5730) { 197 return EutranBand.BAND_17; 198 } else if (earfcn > 5379) { 199 return INVALID_BAND; 200 } else if (earfcn >= 5280) { 201 return EutranBand.BAND_14; 202 } else if (earfcn >= 5180) { 203 return EutranBand.BAND_13; 204 } else if (earfcn >= 5010) { 205 return EutranBand.BAND_12; 206 } else if (earfcn >= 4750) { 207 return EutranBand.BAND_11; 208 } else if (earfcn >= 4150) { 209 return EutranBand.BAND_10; 210 } else if (earfcn >= 3800) { 211 return EutranBand.BAND_9; 212 } else if (earfcn >= 3450) { 213 return EutranBand.BAND_8; 214 } else if (earfcn >= 2750) { 215 return EutranBand.BAND_7; 216 } else if (earfcn >= 2650) { 217 return EutranBand.BAND_6; 218 } else if (earfcn >= 2400) { 219 return EutranBand.BAND_5; 220 } else if (earfcn >= 1950) { 221 return EutranBand.BAND_4; 222 } else if (earfcn >= 1200) { 223 return EutranBand.BAND_3; 224 } else if (earfcn >= 600) { 225 return EutranBand.BAND_2; 226 } else if (earfcn >= 0) { 227 return EutranBand.BAND_1; 228 } 229 230 return INVALID_BAND; 231 } 232 233 /** 234 * Gets the NR Operating band for a given downlink NRARFCN. 235 * 236 * <p>See 3GPP TS 38.104 Table 5.2-1 NR operating bands in FR1 and 237 * Table 5.2-2 NR operating bands in FR2 238 * 239 * @param nrarfcn The downlink NRARFCN 240 * @return Operating band number, or {@link #INVALID_BAND} if no corresponding band exists 241 */ getOperatingBandForNrarfcn(int nrarfcn)242 public static int getOperatingBandForNrarfcn(int nrarfcn) { 243 if (nrarfcn >= 422000 && nrarfcn <= 434000) { 244 return NgranBands.BAND_1; 245 } else if (nrarfcn >= 386000 && nrarfcn <= 398000) { 246 return NgranBands.BAND_2; 247 } else if (nrarfcn >= 361000 && nrarfcn <= 376000) { 248 return NgranBands.BAND_3; 249 } else if (nrarfcn >= 173800 && nrarfcn <= 178800) { 250 return NgranBands.BAND_5; 251 } else if (nrarfcn >= 524000 && nrarfcn <= 538000) { 252 return NgranBands.BAND_7; 253 } else if (nrarfcn >= 185000 && nrarfcn <= 192000) { 254 return NgranBands.BAND_8; 255 } else if (nrarfcn >= 145800 && nrarfcn <= 149200) { 256 return NgranBands.BAND_12; 257 } else if (nrarfcn >= 151600 && nrarfcn <= 153600) { 258 return NgranBands.BAND_14; 259 } else if (nrarfcn >= 172000 && nrarfcn <= 175000) { 260 return NgranBands.BAND_18; 261 } else if (nrarfcn >= 158200 && nrarfcn <= 164200) { 262 return NgranBands.BAND_20; 263 } else if (nrarfcn >= 386000 && nrarfcn <= 399000) { 264 return NgranBands.BAND_25; 265 } else if (nrarfcn >= 171800 && nrarfcn <= 178800) { 266 return NgranBands.BAND_26; 267 } else if (nrarfcn >= 151600 && nrarfcn <= 160600) { 268 return NgranBands.BAND_28; 269 } else if (nrarfcn >= 143400 && nrarfcn <= 145600) { 270 return NgranBands.BAND_29; 271 } else if (nrarfcn >= 470000 && nrarfcn <= 472000) { 272 return NgranBands.BAND_30; 273 } else if (nrarfcn >= 402000 && nrarfcn <= 405000) { 274 return NgranBands.BAND_34; 275 } else if (nrarfcn >= 514000 && nrarfcn <= 524000) { 276 return NgranBands.BAND_38; 277 } else if (nrarfcn >= 376000 && nrarfcn <= 384000) { 278 return NgranBands.BAND_39; 279 } else if (nrarfcn >= 460000 && nrarfcn <= 480000) { 280 return NgranBands.BAND_40; 281 } else if (nrarfcn >= 499200 && nrarfcn <= 537999) { 282 return NgranBands.BAND_41; 283 } else if (nrarfcn >= 743334 && nrarfcn <= 795000) { 284 return NgranBands.BAND_46; 285 } else if (nrarfcn >= 636667 && nrarfcn <= 646666) { 286 return NgranBands.BAND_48; 287 } else if (nrarfcn >= 286400 && nrarfcn <= 303400) { 288 return NgranBands.BAND_50; 289 } else if (nrarfcn >= 285400 && nrarfcn <= 286400) { 290 return NgranBands.BAND_51; 291 } else if (nrarfcn >= 496700 && nrarfcn <= 499000) { 292 return NgranBands.BAND_53; 293 } else if (nrarfcn >= 422000 && nrarfcn <= 440000) { 294 return NgranBands.BAND_65; // BAND_66 has the same channels 295 } else if (nrarfcn >= 399000 && nrarfcn <= 404000) { 296 return NgranBands.BAND_70; 297 } else if (nrarfcn >= 123400 && nrarfcn <= 130400) { 298 return NgranBands.BAND_71; 299 } else if (nrarfcn >= 295000 && nrarfcn <= 303600) { 300 return NgranBands.BAND_74; 301 } else if (nrarfcn >= 286400 && nrarfcn <= 303400) { 302 return NgranBands.BAND_75; 303 } else if (nrarfcn >= 285400 && nrarfcn <= 286400) { 304 return NgranBands.BAND_76; 305 } else if (nrarfcn >= 620000 && nrarfcn <= 680000) { 306 return NgranBands.BAND_77; 307 } else if (nrarfcn >= 620000 && nrarfcn <= 653333) { 308 return NgranBands.BAND_78; 309 } else if (nrarfcn >= 693334 && nrarfcn <= 733333) { 310 return NgranBands.BAND_79; 311 } else if (nrarfcn >= 499200 && nrarfcn <= 538000) { 312 return NgranBands.BAND_90; 313 } else if (nrarfcn >= 285400 && nrarfcn <= 286400) { 314 return NgranBands.BAND_91; 315 } else if (nrarfcn >= 286400 && nrarfcn <= 303400) { 316 return NgranBands.BAND_92; 317 } else if (nrarfcn >= 285400 && nrarfcn <= 286400) { 318 return NgranBands.BAND_93; 319 } else if (nrarfcn >= 286400 && nrarfcn <= 303400) { 320 return NgranBands.BAND_94; 321 } else if (nrarfcn >= 795000 && nrarfcn <= 875000) { 322 return NgranBands.BAND_96; 323 } else if (nrarfcn >= 2054166 && nrarfcn <= 2104165) { 324 return NgranBands.BAND_257; 325 } else if (nrarfcn >= 2016667 && nrarfcn <= 2070832) { 326 return NgranBands.BAND_258; 327 } else if (nrarfcn >= 2229166 && nrarfcn <= 2279165) { 328 return NgranBands.BAND_260; 329 } else if (nrarfcn >= 2070833 && nrarfcn <= 2084999) { 330 return NgranBands.BAND_261; 331 } 332 return INVALID_BAND; 333 } 334 335 /** 336 * Gets the GERAN Operating band for a given ARFCN. 337 * 338 * <p>See 3GPP TS 45.005 clause 2 for calculation. 339 * 340 * @param arfcn The ARFCN 341 * @return Operating band number, or {@link #INVALID_BAND} if no corresponding band exists 342 */ getOperatingBandForArfcn(int arfcn)343 public static int getOperatingBandForArfcn(int arfcn) { 344 if (arfcn >= 0 && arfcn <= 124) { 345 return GeranBand.BAND_E900; 346 } else if (arfcn >= 128 && arfcn <= 251) { 347 return GeranBand.BAND_850; 348 } else if (arfcn >= 259 && arfcn <= 293) { 349 return GeranBand.BAND_450; 350 } else if (arfcn >= 306 && arfcn <= 340) { 351 return GeranBand.BAND_480; 352 } else if (arfcn >= 438 && arfcn <= 511) { 353 return GeranBand.BAND_750; 354 } else if (arfcn >= 512 && arfcn <= 885) { 355 // ARFCN between 512 and 810 are also part of BAND_PCS1900. 356 // Returning BAND_DCS1800 in both cases. 357 return GeranBand.BAND_DCS1800; 358 } else if (arfcn >= 940 && arfcn <= 974) { 359 return GeranBand.BAND_ER900; 360 } else if (arfcn >= 975 && arfcn <= 1023) { 361 return GeranBand.BAND_E900; 362 } 363 return INVALID_BAND; 364 } 365 366 /** 367 * Gets the UTRAN Operating band for a given downlink UARFCN. 368 * 369 * <p>See 3GPP TS 25.101 clause 5.4.4 for calculation. 370 * 371 * @param uarfcn The downlink UARFCN 372 * @return Operating band number, or {@link #INVALID_BAND} if no corresponding band exists 373 */ getOperatingBandForUarfcn(int uarfcn)374 public static int getOperatingBandForUarfcn(int uarfcn) { 375 // List of additional bands defined in TS 25.101. 376 int[] addlBand2 = {412, 437, 462, 487, 512, 537, 562, 587, 612, 637, 662, 687}; 377 int[] addlBand4 = {1887, 1912, 1937, 1962, 1987, 2012, 2037, 2062, 2087}; 378 int[] addlBand5 = {1007, 1012, 1032, 1037, 1062, 1087}; 379 int[] addlBand6 = {1037, 1062}; 380 int[] addlBand7 = 381 {2587, 2612, 2637, 2662, 2687, 2712, 2737, 2762, 2787, 2812, 2837, 2862, 382 2887, 2912}; 383 int[] addlBand10 = 384 {3412, 3437, 3462, 3487, 3512, 3537, 3562, 3587, 3612, 3637, 3662, 3687}; 385 int[] addlBand12 = {3932, 3957, 3962, 3987, 3992}; 386 int[] addlBand13 = {4067, 4092}; 387 int[] addlBand14 = {4167, 4192}; 388 int[] addlBand19 = {787, 812, 837}; 389 int[] addlBand25 = 390 {6292, 6317, 6342, 6367, 6392, 6417, 6442, 6467, 6492, 6517, 6542, 6567, 6592}; 391 int[] addlBand26 = {5937, 5962, 5987, 5992, 6012, 6017, 6037, 6042, 6062, 6067, 6087}; 392 393 if (uarfcn >= 10562 && uarfcn <= 10838) { 394 return UtranBand.BAND_1; 395 } else if ((uarfcn >= 9662 && uarfcn <= 9938) 396 || Arrays.binarySearch(addlBand2, uarfcn) >= 0) { 397 return UtranBand.BAND_2; 398 } else if (uarfcn >= 1162 && uarfcn <= 1513) { 399 return UtranBand.BAND_3; 400 } else if ((uarfcn >= 1537 && uarfcn <= 1738) 401 || Arrays.binarySearch(addlBand4, uarfcn) >= 0) { 402 return UtranBand.BAND_4; 403 } else if (uarfcn >= 4387 && uarfcn <= 4413) { 404 // Band 6 is a subset of band 5. Only Japan uses band 6 and Japan does not have band 5. 405 String country = TelephonyManager.getDefault().getNetworkCountryIso(); 406 if (JAPAN_ISO_COUNTRY_CODE.compareToIgnoreCase(country) == 0) { 407 return UtranBand.BAND_6; 408 } else { 409 return UtranBand.BAND_5; 410 } 411 } else if ((uarfcn >= 4357 && uarfcn <= 4458) 412 || Arrays.binarySearch(addlBand5, uarfcn) >= 0) { 413 return UtranBand.BAND_5; 414 } else if (Arrays.binarySearch(addlBand6, uarfcn) >= 0) { 415 return UtranBand.BAND_6; 416 } else if ((uarfcn >= 2237 && uarfcn <= 2563) 417 || Arrays.binarySearch(addlBand7, uarfcn) >= 0) { 418 return UtranBand.BAND_7; 419 } else if (uarfcn >= 2937 && uarfcn <= 3088) { 420 return UtranBand.BAND_8; 421 } else if (uarfcn >= 9237 && uarfcn <= 9387) { 422 return UtranBand.BAND_9; 423 } else if ((uarfcn >= 3112 && uarfcn <= 3388) 424 || Arrays.binarySearch(addlBand10, uarfcn) >= 0) { 425 return UtranBand.BAND_10; 426 } else if (uarfcn >= 3712 && uarfcn <= 3787) { 427 return UtranBand.BAND_11; 428 } else if ((uarfcn >= 3842 && uarfcn <= 3903) 429 || Arrays.binarySearch(addlBand12, uarfcn) >= 0) { 430 return UtranBand.BAND_12; 431 } else if ((uarfcn >= 4017 && uarfcn <= 4043) 432 || Arrays.binarySearch(addlBand13, uarfcn) >= 0) { 433 return UtranBand.BAND_13; 434 } else if ((uarfcn >= 4117 && uarfcn <= 4143) 435 || Arrays.binarySearch(addlBand14, uarfcn) >= 0) { 436 return UtranBand.BAND_14; 437 } else if ((uarfcn >= 712 && uarfcn <= 763) 438 || Arrays.binarySearch(addlBand19, uarfcn) >= 0) { 439 return UtranBand.BAND_19; 440 } else if (uarfcn >= 4512 && uarfcn <= 4638) { 441 return UtranBand.BAND_20; 442 } else if (uarfcn >= 862 && uarfcn <= 912) { 443 return UtranBand.BAND_21; 444 } else if (uarfcn >= 4662 && uarfcn <= 5038) { 445 return UtranBand.BAND_22; 446 } else if ((uarfcn >= 5112 && uarfcn <= 5413) 447 || Arrays.binarySearch(addlBand25, uarfcn) >= 0) { 448 return UtranBand.BAND_25; 449 } else if ((uarfcn >= 5762 && uarfcn <= 5913) 450 || Arrays.binarySearch(addlBand26, uarfcn) >= 0) { 451 return UtranBand.BAND_26; 452 } 453 return INVALID_BAND; 454 } 455 456 /** 457 * Get geran bands from {@link PhysicalChannelConfig#getBand()} 458 */ getFrequencyRangeGroupFromGeranBand(@eranBand.GeranBands int band)459 public static int getFrequencyRangeGroupFromGeranBand(@GeranBand.GeranBands int band) { 460 switch (band) { 461 case GeranBand.BAND_T380: 462 case GeranBand.BAND_T410: 463 case GeranBand.BAND_450: 464 case GeranBand.BAND_480: 465 case GeranBand.BAND_710: 466 case GeranBand.BAND_750: 467 case GeranBand.BAND_T810: 468 case GeranBand.BAND_850: 469 case GeranBand.BAND_P900: 470 case GeranBand.BAND_E900: 471 case GeranBand.BAND_R900: 472 case GeranBand.BAND_ER900: 473 return ServiceState.FREQUENCY_RANGE_LOW; 474 case GeranBand.BAND_DCS1800: 475 case GeranBand.BAND_PCS1900: 476 return ServiceState.FREQUENCY_RANGE_MID; 477 default: 478 return ServiceState.FREQUENCY_RANGE_UNKNOWN; 479 } 480 } 481 482 /** 483 * Get utran bands from {@link PhysicalChannelConfig#getBand()} 484 */ getFrequencyRangeGroupFromUtranBand(@tranBand.UtranBands int band)485 public static int getFrequencyRangeGroupFromUtranBand(@UtranBand.UtranBands int band) { 486 switch (band) { 487 case UtranBand.BAND_5: 488 case UtranBand.BAND_6: 489 case UtranBand.BAND_8: 490 case UtranBand.BAND_12: 491 case UtranBand.BAND_13: 492 case UtranBand.BAND_14: 493 case UtranBand.BAND_19: 494 case UtranBand.BAND_20: 495 case UtranBand.BAND_26: 496 return ServiceState.FREQUENCY_RANGE_LOW; 497 case UtranBand.BAND_1: 498 case UtranBand.BAND_2: 499 case UtranBand.BAND_3: 500 case UtranBand.BAND_4: 501 case UtranBand.BAND_7: 502 case UtranBand.BAND_9: 503 case UtranBand.BAND_10: 504 case UtranBand.BAND_11: 505 case UtranBand.BAND_21: 506 case UtranBand.BAND_25: 507 case UtranBand.BAND_A: 508 case UtranBand.BAND_B: 509 case UtranBand.BAND_C: 510 case UtranBand.BAND_D: 511 case UtranBand.BAND_E: 512 case UtranBand.BAND_F: 513 return ServiceState.FREQUENCY_RANGE_MID; 514 case UtranBand.BAND_22: 515 return ServiceState.FREQUENCY_RANGE_HIGH; 516 default: 517 return ServiceState.FREQUENCY_RANGE_UNKNOWN; 518 } 519 } 520 521 /** 522 * Get eutran bands from {@link PhysicalChannelConfig#getBand()} 523 * 3GPP TS 36.101 Table 5.5 EUTRA operating bands 524 */ getFrequencyRangeGroupFromEutranBand(@utranBand.EutranBands int band)525 public static int getFrequencyRangeGroupFromEutranBand(@EutranBand.EutranBands int band) { 526 switch (band) { 527 case EutranBand.BAND_5: 528 case EutranBand.BAND_6: 529 case EutranBand.BAND_8: 530 case EutranBand.BAND_12: 531 case EutranBand.BAND_13: 532 case EutranBand.BAND_14: 533 case EutranBand.BAND_17: 534 case EutranBand.BAND_18: 535 case EutranBand.BAND_19: 536 case EutranBand.BAND_20: 537 case EutranBand.BAND_26: 538 case EutranBand.BAND_27: 539 case EutranBand.BAND_28: 540 case EutranBand.BAND_31: 541 case EutranBand.BAND_44: 542 case EutranBand.BAND_50: 543 case EutranBand.BAND_51: 544 case EutranBand.BAND_68: 545 case EutranBand.BAND_71: 546 case EutranBand.BAND_72: 547 case EutranBand.BAND_73: 548 case EutranBand.BAND_85: 549 case EutranBand.BAND_87: 550 case EutranBand.BAND_88: 551 return ServiceState.FREQUENCY_RANGE_LOW; 552 case EutranBand.BAND_1: 553 case EutranBand.BAND_2: 554 case EutranBand.BAND_3: 555 case EutranBand.BAND_4: 556 case EutranBand.BAND_7: 557 case EutranBand.BAND_9: 558 case EutranBand.BAND_10: 559 case EutranBand.BAND_11: 560 case EutranBand.BAND_21: 561 case EutranBand.BAND_23: 562 case EutranBand.BAND_24: 563 case EutranBand.BAND_25: 564 case EutranBand.BAND_30: 565 case EutranBand.BAND_33: 566 case EutranBand.BAND_34: 567 case EutranBand.BAND_35: 568 case EutranBand.BAND_36: 569 case EutranBand.BAND_37: 570 case EutranBand.BAND_38: 571 case EutranBand.BAND_39: 572 case EutranBand.BAND_40: 573 case EutranBand.BAND_41: 574 case EutranBand.BAND_45: 575 case EutranBand.BAND_53: 576 case EutranBand.BAND_65: 577 case EutranBand.BAND_66: 578 case EutranBand.BAND_70: 579 case EutranBand.BAND_74: 580 return ServiceState.FREQUENCY_RANGE_MID; 581 case EutranBand.BAND_22: 582 case EutranBand.BAND_42: 583 case EutranBand.BAND_43: 584 case EutranBand.BAND_46: 585 case EutranBand.BAND_47: 586 case EutranBand.BAND_48: 587 case EutranBand.BAND_49: 588 case EutranBand.BAND_52: 589 return ServiceState.FREQUENCY_RANGE_HIGH; 590 default: 591 return ServiceState.FREQUENCY_RANGE_UNKNOWN; 592 } 593 } 594 595 /** 596 * Get ngran band from {@link PhysicalChannelConfig#getBand()} 597 * 3GPP TS 38.104 Table 5.2-1 NR operating bands in FR1 598 * 3GPP TS 38.104 Table 5.2-2 NR operating bands in FR2 599 */ getFrequencyRangeGroupFromNrBand(@granBands.NgranBand int band)600 public static int getFrequencyRangeGroupFromNrBand(@NgranBands.NgranBand int band) { 601 switch (band) { 602 case NgranBands.BAND_5: 603 case NgranBands.BAND_8: 604 case NgranBands.BAND_12: 605 case NgranBands.BAND_14: 606 case NgranBands.BAND_18: 607 case NgranBands.BAND_20: 608 case NgranBands.BAND_26: 609 case NgranBands.BAND_28: 610 case NgranBands.BAND_29: 611 case NgranBands.BAND_71: 612 case NgranBands.BAND_81: 613 case NgranBands.BAND_82: 614 case NgranBands.BAND_83: 615 case NgranBands.BAND_89: 616 return ServiceState.FREQUENCY_RANGE_LOW; 617 case NgranBands.BAND_1: 618 case NgranBands.BAND_2: 619 case NgranBands.BAND_3: 620 case NgranBands.BAND_7: 621 case NgranBands.BAND_25: 622 case NgranBands.BAND_30: 623 case NgranBands.BAND_34: 624 case NgranBands.BAND_38: 625 case NgranBands.BAND_39: 626 case NgranBands.BAND_40: 627 case NgranBands.BAND_41: 628 case NgranBands.BAND_50: 629 case NgranBands.BAND_51: 630 case NgranBands.BAND_53: 631 case NgranBands.BAND_65: 632 case NgranBands.BAND_66: 633 case NgranBands.BAND_70: 634 case NgranBands.BAND_74: 635 case NgranBands.BAND_75: 636 case NgranBands.BAND_76: 637 case NgranBands.BAND_80: 638 case NgranBands.BAND_84: 639 case NgranBands.BAND_86: 640 case NgranBands.BAND_90: 641 case NgranBands.BAND_91: 642 case NgranBands.BAND_92: 643 case NgranBands.BAND_93: 644 case NgranBands.BAND_94: 645 case NgranBands.BAND_95: 646 return ServiceState.FREQUENCY_RANGE_MID; 647 case NgranBands.BAND_46: 648 case NgranBands.BAND_48: 649 case NgranBands.BAND_77: 650 case NgranBands.BAND_78: 651 case NgranBands.BAND_79: 652 return ServiceState.FREQUENCY_RANGE_HIGH; 653 case NgranBands.BAND_96: 654 case NgranBands.BAND_257: 655 case NgranBands.BAND_258: 656 case NgranBands.BAND_260: 657 case NgranBands.BAND_261: 658 return ServiceState.FREQUENCY_RANGE_MMWAVE; 659 default: 660 return ServiceState.FREQUENCY_RANGE_UNKNOWN; 661 } 662 } 663 664 /** 665 * 3GPP TS 38.104 Table 5.4.2.1-1 NR-ARFCN parameters for the global frequency raster. 666 * Formula of NR-ARFCN convert to actual frequency: 667 * Actual frequency(kHz) = (RANGE_OFFSET + GLOBAL_KHZ * (ARFCN - ARFCN_OFFSET)) 668 */ getFrequencyFromNrArfcn(int nrArfcn)669 public static int getFrequencyFromNrArfcn(int nrArfcn) { 670 671 if (nrArfcn == PhysicalChannelConfig.CHANNEL_NUMBER_UNKNOWN) { 672 return PhysicalChannelConfig.FREQUENCY_UNKNOWN; 673 } 674 675 int globalKhz = 0; 676 int rangeOffset = 0; 677 int arfcnOffset = 0; 678 for (NgranArfcnFrequency nrArfcnFrequency : AccessNetworkConstants. 679 NgranArfcnFrequency.values()) { 680 if (nrArfcn >= nrArfcnFrequency.rangeFirst 681 && nrArfcn <= nrArfcnFrequency.rangeLast) { 682 globalKhz = nrArfcnFrequency.globalKhz; 683 rangeOffset = nrArfcnFrequency.rangeOffset; 684 arfcnOffset = nrArfcnFrequency.arfcnOffset; 685 break; 686 } 687 } 688 return rangeOffset + globalKhz * (nrArfcn - arfcnOffset); 689 } 690 691 /** 692 * Get actual frequency from E-UTRA ARFCN. 693 */ getFrequencyFromEarfcn(int band, int earfcn, boolean isUplink)694 public static int getFrequencyFromEarfcn(int band, int earfcn, boolean isUplink) { 695 696 int low = 0; 697 int offset = 0; 698 for (EutranBandArfcnFrequency earfcnFrequency : EutranBandArfcnFrequency.values()) { 699 if (band == earfcnFrequency.band) { 700 if (isInEarfcnRange(earfcn, earfcnFrequency, isUplink)) { 701 low = isUplink ? earfcnFrequency.uplinkLowKhz : earfcnFrequency.downlinkLowKhz; 702 offset = isUplink ? earfcnFrequency.uplinkOffset 703 : earfcnFrequency.downlinkOffset; 704 break; 705 } else { 706 Rlog.w(TAG,"Band and the range of EARFCN are not consistent: band = " + band 707 + " ,earfcn = " + earfcn + " ,isUplink = " + isUplink); 708 return INVALID_FREQUENCY; 709 } 710 } 711 } 712 return convertEarfcnToFrequency(low, earfcn, offset); 713 } 714 715 /** 716 * 3GPP TS 36.101 Table 5.7.3-1 E-UTRA channel numbers. 717 * Formula of E-UTRA ARFCN convert to actual frequency: 718 * Actual frequency(kHz) = (DOWNLINK_LOW + 0.1 * (ARFCN - DOWNLINK_OFFSET)) * FREQUENCY_KHZ 719 * Actual frequency(kHz) = (UPLINK_LOW + 0.1 * (ARFCN - UPLINK_OFFSET)) * FREQUENCY_KHZ 720 */ convertEarfcnToFrequency(int low, int earfcn, int offset)721 private static int convertEarfcnToFrequency(int low, int earfcn, int offset) { 722 return low + 100 * (earfcn - offset); 723 } 724 isInEarfcnRange(int earfcn, EutranBandArfcnFrequency earfcnFrequency, boolean isUplink)725 private static boolean isInEarfcnRange(int earfcn, EutranBandArfcnFrequency earfcnFrequency, 726 boolean isUplink) { 727 if (isUplink) { 728 return earfcn >= earfcnFrequency.uplinkOffset && earfcn <= earfcnFrequency.uplinkRange; 729 } else { 730 return earfcn >= earfcnFrequency.downlinkOffset 731 && earfcn <= earfcnFrequency.downlinkRange; 732 } 733 } 734 735 /** 736 * Get actual frequency from UTRA ARFCN. 737 */ getFrequencyFromUarfcn(int band, int uarfcn, boolean isUplink)738 public static int getFrequencyFromUarfcn(int band, int uarfcn, boolean isUplink) { 739 740 if (uarfcn == PhysicalChannelConfig.CHANNEL_NUMBER_UNKNOWN) { 741 return PhysicalChannelConfig.FREQUENCY_UNKNOWN; 742 } 743 744 int offsetKhz = 0; 745 for (UtranBandArfcnFrequency uarfcnFrequency : AccessNetworkConstants. 746 UtranBandArfcnFrequency.values()) { 747 if (band == uarfcnFrequency.band) { 748 if (isInUarfcnRange(uarfcn, uarfcnFrequency, isUplink)) { 749 offsetKhz = isUplink ? uarfcnFrequency.uplinkOffset 750 : uarfcnFrequency.downlinkOffset; 751 break; 752 } else { 753 Rlog.w(TAG,"Band and the range of UARFCN are not consistent: band = " + band 754 + " ,uarfcn = " + uarfcn + " ,isUplink = " + isUplink); 755 return INVALID_FREQUENCY; 756 } 757 } 758 } 759 760 if (!UARFCN_NOT_GENERAL_BAND.contains(band)) { 761 return convertUarfcnToFrequency(offsetKhz, uarfcn); 762 } else { 763 return convertUarfcnTddToFrequency(band, uarfcn); 764 } 765 } 766 767 /** 768 * 3GPP TS 25.101, Table 5.1 UARFCN definition (general). 769 * Formula of UTRA ARFCN convert to actual frequency: 770 * For general bands: 771 * Downlink actual frequency(kHz) = (DOWNLINK_OFFSET + 0.2 * ARFCN) * FREQUENCY_KHZ 772 * Uplink actual frequency(kHz) = (UPLINK_OFFSET + 0.2 * ARFCN) * FREQUENCY_KHZ 773 */ convertUarfcnToFrequency(int offsetKhz, int uarfcn)774 private static int convertUarfcnToFrequency(int offsetKhz, int uarfcn) { 775 return offsetKhz + (200 * uarfcn); 776 } 777 778 /** 779 * 3GPP TS 25.102, Table 5.2 UTRA Absolute Radio Frequency Channel Number 1.28 Mcps TDD Option. 780 * For FDD bands A, B, C, E, F: 781 * Actual frequency(kHz) = 5 * ARFCN * FREQUENCY_KHZ 782 * For TDD bands D: 783 * Actual frequency(kHz) = (5 * (ARFCN - 2150.1MHz)) * FREQUENCY_KHZ 784 */ convertUarfcnTddToFrequency(int band, int uarfcn)785 private static int convertUarfcnTddToFrequency(int band, int uarfcn) { 786 if (band != UtranBand.BAND_D) { 787 return 5 * uarfcn * FREQUENCY_KHZ; 788 } else { 789 return 5 * ((FREQUENCY_KHZ * uarfcn) - 2150100); 790 } 791 } 792 isInUarfcnRange(int uarfcn, UtranBandArfcnFrequency uarfcnFrequency, boolean isUplink)793 private static boolean isInUarfcnRange(int uarfcn, UtranBandArfcnFrequency uarfcnFrequency, 794 boolean isUplink) { 795 if (isUplink) { 796 return uarfcn >= uarfcnFrequency.uplinkRangeFirst 797 && uarfcn <= uarfcnFrequency.uplinkRangeLast; 798 } else { 799 if (uarfcnFrequency.downlinkRangeFirst != 0 && uarfcnFrequency.downlinkRangeLast != 0) { 800 return uarfcn >= uarfcnFrequency.downlinkRangeFirst 801 && uarfcn <= uarfcnFrequency.downlinkRangeLast; 802 } else { 803 // BAND_C, BAND_D, BAND_E and BAND_F do not have the downlink range. 804 return true; 805 } 806 } 807 } 808 809 /** 810 * Get actual frequency from GERAN ARFCN. 811 */ getFrequencyFromArfcn(int band, int arfcn, boolean isUplink)812 public static int getFrequencyFromArfcn(int band, int arfcn, boolean isUplink) { 813 814 if (arfcn == PhysicalChannelConfig.CHANNEL_NUMBER_UNKNOWN) { 815 return PhysicalChannelConfig.FREQUENCY_UNKNOWN; 816 } 817 818 int uplinkFrequencyFirst = 0; 819 int arfcnOffset = 0; 820 int downlinkOffset = 0; 821 int frequency = 0; 822 for (GeranBandArfcnFrequency arfcnFrequency : AccessNetworkConstants. 823 GeranBandArfcnFrequency.values()) { 824 if (band == arfcnFrequency.band) { 825 if (arfcn >= arfcnFrequency.arfcnRangeFirst 826 && arfcn <= arfcnFrequency.arfcnRangeLast) { 827 uplinkFrequencyFirst = arfcnFrequency.uplinkFrequencyFirst; 828 downlinkOffset = arfcnFrequency.downlinkOffset; 829 arfcnOffset = arfcnFrequency.arfcnOffset; 830 frequency = convertArfcnToFrequency(arfcn, uplinkFrequencyFirst, 831 arfcnOffset); 832 break; 833 } else { 834 Rlog.w(TAG,"Band and the range of ARFCN are not consistent: band = " + band 835 + " ,arfcn = " + arfcn + " ,isUplink = " + isUplink); 836 return INVALID_FREQUENCY; 837 } 838 } 839 } 840 841 return isUplink ? frequency : frequency + downlinkOffset; 842 } 843 844 /** 845 * 3GPP TS 45.005 Table 2-1 Dynamically mapped ARFCN 846 * Formula of Geran ARFCN convert to actual frequency: 847 * Uplink actual frequency(kHz) = 848 * (UPLINK_FREQUENCY_FIRST + 0.2 * (ARFCN - ARFCN_RANGE_FIRST)) * FREQUENCY_KHZ 849 * Downlink actual frequency(kHz) = Uplink actual frequency + 10 850 */ convertArfcnToFrequency(int arfcn, int uplinkFrequencyFirstKhz, int arfcnOffset)851 private static int convertArfcnToFrequency(int arfcn, int uplinkFrequencyFirstKhz, 852 int arfcnOffset) { 853 return uplinkFrequencyFirstKhz + 200 * (arfcn - arfcnOffset); 854 } 855 getFrequencyRangeFromArfcn(int frequency)856 public static int getFrequencyRangeFromArfcn(int frequency) { 857 if (frequency < FREQUENCY_RANGE_LOW_KHZ) { 858 return ServiceState.FREQUENCY_RANGE_LOW; 859 } else if (frequency < FREQUENCY_RANGE_MID_KHZ 860 && frequency >= FREQUENCY_RANGE_LOW_KHZ) { 861 return ServiceState.FREQUENCY_RANGE_MID; 862 } else if (frequency < FREQUENCY_RANGE_HIGH_KHZ 863 && frequency >= FREQUENCY_RANGE_MID_KHZ) { 864 return ServiceState.FREQUENCY_RANGE_HIGH; 865 } else { 866 return ServiceState.FREQUENCY_RANGE_MMWAVE; 867 } 868 } 869 } 870