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