/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.telephony; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; import android.telephony.Annotation.NetworkType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.Objects; public final class PhysicalChannelConfig implements Parcelable { // TODO(b/72993578) consolidate these enums in a central location. /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef({CONNECTION_PRIMARY_SERVING, CONNECTION_SECONDARY_SERVING, CONNECTION_UNKNOWN}) public @interface ConnectionStatus {} /** * UE has connection to cell for signalling and possibly data (3GPP 36.331, 25.331). * * @deprecated Use {@link CellInfo#CONNECTION_PRIMARY_SERVING} instead. */ @Deprecated public static final int CONNECTION_PRIMARY_SERVING = 1; /** * UE has connection to cell for data (3GPP 36.331, 25.331). * * @deprecated Use {@link CellInfo#CONNECTION_SECONDARY_SERVING} instead. */ @Deprecated public static final int CONNECTION_SECONDARY_SERVING = 2; /** * Connection status is unknown. * * @deprecated Use {@link CellInfo#CONNECTION_UNKNOWN} instead. */ @Deprecated public static final int CONNECTION_UNKNOWN = -1; /** Channel number is unknown. */ public static final int CHANNEL_NUMBER_UNKNOWN = Integer.MAX_VALUE; /** Physical Cell Id is unknown. */ public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; /** Physical Cell Id's maximum value is 1007. */ public static final int PHYSICAL_CELL_ID_MAXIMUM_VALUE = 1007; /** Cell bandwidth is unknown. */ public static final int CELL_BANDWIDTH_UNKNOWN = 0; /** The frequency is unknown. */ public static final int FREQUENCY_UNKNOWN = -1; /** The band is unknown. */ public static final int BAND_UNKNOWN = 0; /** * Connection status of the cell. * *
One of {@link #CONNECTION_PRIMARY_SERVING}, {@link #CONNECTION_SECONDARY_SERVING}.
*/
@ConnectionStatus
private int mCellConnectionStatus;
/**
* Downlink cell bandwidth, in kHz.
*/
private int mCellBandwidthDownlinkKhz;
/**
* Uplink cell bandwidth, in kHz.
*/
private int mCellBandwidthUplinkKhz;
/**
* The radio technology for this physical channel.
*/
@NetworkType
private int mNetworkType;
/**
* The rough frequency range for this physical channel.
*/
@ServiceState.FrequencyRange
private int mFrequencyRange;
/**
* The frequency of Downlink.
*/
private int mDownlinkFrequency;
/**
* The frequency of Uplink.
*/
private int mUplinkFrequency;
/**
* Downlink Absolute Radio Frequency Channel Number
*/
private int mDownlinkChannelNumber;
/**
* Uplink Absolute Radio Frequency Channel Number
*/
private int mUplinkChannelNumber;
/**
* A list of data calls mapped to this physical channel. An empty list means the physical
* channel has no data call mapped to it.
*/
private int[] mContextIds;
/**
* The physical cell identifier for this cell - PCI, PSC, {@link #PHYSICAL_CELL_ID_UNKNOWN}
* if unknown.
*/
private int mPhysicalCellId;
/**
* This is the band which is being used.
*/
private int mBand;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mCellConnectionStatus);
dest.writeInt(mCellBandwidthDownlinkKhz);
dest.writeInt(mCellBandwidthUplinkKhz);
dest.writeInt(mNetworkType);
dest.writeInt(mDownlinkChannelNumber);
dest.writeInt(mUplinkChannelNumber);
dest.writeInt(mFrequencyRange);
dest.writeIntArray(mContextIds);
dest.writeInt(mPhysicalCellId);
dest.writeInt(mBand);
}
/**
* @return Downlink cell bandwidth in kHz, {@link #CELL_BANDWIDTH_UNKNOWN} if unknown.
*/
@IntRange(from = 1)
public int getCellBandwidthDownlinkKhz() {
return mCellBandwidthDownlinkKhz;
}
/**
* @return Uplink cell bandwidth in kHz, {@link #CELL_BANDWIDTH_UNKNOWN} if unknown.
*/
@IntRange(from = 1)
public int getCellBandwidthUplinkKhz() {
return mCellBandwidthUplinkKhz;
}
/**
* Get the list of data call ids mapped to this physical channel. This list is sorted into
* ascending numerical order. Each id in this list must match the id in
* {@link com.android.internal.telephony.dataconnection.DataConnection}. An empty list means the
* physical channel has no data call mapped to it.
*
* @return an integer list indicates the data call ids,
* @hide
*/
public int[] getContextIds() {
return mContextIds;
}
/**
* @return the rough frequency range for this physical channel,
* {@link ServiceState#FREQUENCY_RANGE_UNKNOWN} if unknown.
* @see {@link ServiceState#FREQUENCY_RANGE_LOW}
* @see {@link ServiceState#FREQUENCY_RANGE_MID}
* @see {@link ServiceState#FREQUENCY_RANGE_HIGH}
* @see {@link ServiceState#FREQUENCY_RANGE_MMWAVE}
* @hide
*/
@ServiceState.FrequencyRange
public int getFrequencyRange() {
return mFrequencyRange;
}
/**
* @return Downlink Absolute Radio Frequency Channel Number,
* {@link #CHANNEL_NUMBER_UNKNOWN} if unknown.
*/
@IntRange(from = 0)
public int getDownlinkChannelNumber() {
return mDownlinkChannelNumber;
}
/**
* @return Uplink Absolute Radio Frequency Channel Number,
* {@link #CHANNEL_NUMBER_UNKNOWN} if unknown.
*/
@IntRange(from = 0)
public int getUplinkChannelNumber() {
return mUplinkChannelNumber;
}
/**
* The valid bands are {@link AccessNetworkConstants.GeranBand},
* {@link AccessNetworkConstants.UtranBand}, {@link AccessNetworkConstants.EutranBand} and
* {@link AccessNetworkConstants.NgranBands}.
*
* @return the frequency band, {@link #BAND_UNKNOWN} if unknown. */
@IntRange(from = 1, to = 261)
public int getBand() {
return mBand;
}
/**
* @return The downlink frequency in kHz, {@link #FREQUENCY_UNKNOWN} if unknown.
*/
@IntRange(from = 0)
public int getDownlinkFrequencyKhz() {
return mDownlinkFrequency;
}
/**
* @return The uplink frequency in kHz, {@link #FREQUENCY_UNKNOWN} if unknown.
*/
@IntRange(from = 0)
public int getUplinkFrequencyKhz() {
return mUplinkFrequency;
}
/**
* The physical cell ID which differentiates cells using the same radio channel.
*
* In GERAN, this value is the BSIC. The range is [0-63].
* Reference: 3GPP TS 3.03 section 4.2.2.
*
* In UTRAN, this value is primary scrambling code. The range is [0, 511].
* Reference: 3GPP TS 25.213 section 5.2.2.
*
* In EUTRAN, this value is physical layer cell identity. The range is [0, 503].
* Reference: 3GPP TS 36.211 section 6.11.
*
* In 5G RAN, this value is physical layer cell identity. The range is [0, 1007].
* Reference: 3GPP TS 38.211 section 7.4.2.1.
*
* @return the physical cell identifier for this cell, {@link #PHYSICAL_CELL_ID_UNKNOWN}
* if {@link android.telephony.CellInfo#UNAVAILABLE}.
*/
@IntRange(from = 0, to = 1007)
public int getPhysicalCellId() {
return mPhysicalCellId;
}
/**
* @return The network type for this physical channel,
* {@link TelephonyManager#NETWORK_TYPE_UNKNOWN} if unknown.
*/
@NetworkType
public int getNetworkType() {
return mNetworkType;
}
/**
* Gets the connection status of the cell.
*
* @see #CONNECTION_PRIMARY_SERVING
* @see #CONNECTION_SECONDARY_SERVING
* @see #CONNECTION_UNKNOWN
*
* @return Connection status of the cell, {@link #CONNECTION_UNKNOWN} if unknown.
*/
@ConnectionStatus
public int getConnectionStatus() {
return mCellConnectionStatus;
}
/**
* Return a copy of this PhysicalChannelConfig object but redact all the location info.
* @hide
*/
public PhysicalChannelConfig createLocationInfoSanitizedCopy() {
return new Builder(this).setPhysicalCellId(PHYSICAL_CELL_ID_UNKNOWN).build();
}
/**
* @return String representation of the connection status
* @hide
*/
private String getConnectionStatusString() {
switch(mCellConnectionStatus) {
case CONNECTION_PRIMARY_SERVING:
return "PrimaryServing";
case CONNECTION_SECONDARY_SERVING:
return "SecondaryServing";
case CONNECTION_UNKNOWN:
return "Unknown";
default:
return "Invalid(" + mCellConnectionStatus + ")";
}
}
private void setDownlinkFrequency() {
switch (mNetworkType) {
case TelephonyManager.NETWORK_TYPE_NR:
mDownlinkFrequency = AccessNetworkUtils.getFrequencyFromNrArfcn(
mDownlinkChannelNumber);
break;
case TelephonyManager.NETWORK_TYPE_LTE:
mDownlinkFrequency = AccessNetworkUtils.getFrequencyFromEarfcn(
mBand, mDownlinkChannelNumber, false);
break;
case TelephonyManager.NETWORK_TYPE_HSPAP:
case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
mDownlinkFrequency = AccessNetworkUtils.getFrequencyFromUarfcn(
mBand, mDownlinkChannelNumber, false);
break;
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_GSM:
mDownlinkFrequency = AccessNetworkUtils.getFrequencyFromArfcn(
mBand, mDownlinkChannelNumber, false);
break;
}
}
private void setUplinkFrequency() {
switch (mNetworkType){
case TelephonyManager.NETWORK_TYPE_NR:
mUplinkFrequency = AccessNetworkUtils.getFrequencyFromNrArfcn(
mUplinkChannelNumber);
break;
case TelephonyManager.NETWORK_TYPE_LTE:
mUplinkFrequency = AccessNetworkUtils.getFrequencyFromEarfcn(
mBand, mUplinkChannelNumber, true);
break;
case TelephonyManager.NETWORK_TYPE_HSPAP:
case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
mUplinkFrequency = AccessNetworkUtils.getFrequencyFromUarfcn(
mBand, mUplinkChannelNumber, true);
break;
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_GSM:
mUplinkFrequency = AccessNetworkUtils.getFrequencyFromArfcn(
mBand, mUplinkChannelNumber, true);
break;
}
}
private void setFrequencyRange() {
if (mFrequencyRange != ServiceState.FREQUENCY_RANGE_UNKNOWN) {
return;
}
switch (mNetworkType) {
case TelephonyManager.NETWORK_TYPE_NR:
mFrequencyRange = AccessNetworkUtils.getFrequencyRangeGroupFromNrBand(mBand);
break;
case TelephonyManager.NETWORK_TYPE_LTE:
mFrequencyRange = AccessNetworkUtils.getFrequencyRangeGroupFromEutranBand(mBand);
break;
case TelephonyManager.NETWORK_TYPE_HSPAP:
case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
mFrequencyRange = AccessNetworkUtils.getFrequencyRangeGroupFromUtranBand(mBand);
break;
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_GSM:
mFrequencyRange = AccessNetworkUtils.getFrequencyRangeGroupFromGeranBand(mBand);
break;
default:
mFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN;
break;
}
if (mFrequencyRange == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
mFrequencyRange = AccessNetworkUtils.getFrequencyRangeFromArfcn(
mDownlinkFrequency);
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof PhysicalChannelConfig)) {
return false;
}
PhysicalChannelConfig config = (PhysicalChannelConfig) o;
return mCellConnectionStatus == config.mCellConnectionStatus
&& mCellBandwidthDownlinkKhz == config.mCellBandwidthDownlinkKhz
&& mCellBandwidthUplinkKhz == config.mCellBandwidthUplinkKhz
&& mNetworkType == config.mNetworkType
&& mFrequencyRange == config.mFrequencyRange
&& mDownlinkChannelNumber == config.mDownlinkChannelNumber
&& mUplinkChannelNumber == config.mUplinkChannelNumber
&& mPhysicalCellId == config.mPhysicalCellId
&& Arrays.equals(mContextIds, config.mContextIds)
&& mBand == config.mBand
&& mDownlinkFrequency == config.mDownlinkFrequency
&& mUplinkFrequency == config.mUplinkFrequency;
}
@Override
public int hashCode() {
return Objects.hash(
mCellConnectionStatus, mCellBandwidthDownlinkKhz, mCellBandwidthUplinkKhz,
mNetworkType, mFrequencyRange, mDownlinkChannelNumber, mUplinkChannelNumber,
Arrays.hashCode(mContextIds), mPhysicalCellId, mBand, mDownlinkFrequency,
mUplinkFrequency);
}
public static final
@android.annotation.NonNull Parcelable.Creator