/* Android IMSI-Catcher Detector | (c) AIMSICD Privacy Project * ----------------------------------------------------------- * LICENSE: http://git.io/vki47 | TERMS: http://git.io/vki4o * ----------------------------------------------------------- */ package com.secupwn.aimsicd.utils; import android.content.Context; import android.location.Location; import android.os.Build; import android.support.annotation.Nullable; import android.telephony.TelephonyManager; import android.telephony.cdma.CdmaCellLocation; import android.telephony.gsm.GsmCellLocation; import io.freefair.android.util.function.Optional; import io.freefair.android.util.function.Supplier; import io.freefair.android.util.logging.AndroidLogger; import io.freefair.android.util.logging.Logger; import lombok.Getter; import lombok.Setter; @Getter public class Device { private static final Logger log = AndroidLogger.forClass(Device.class); public Cell cell; /** * integer representation of Phone Type */ private int phoneId = -1; @Setter private String cellInfo; @Setter private String dataState; @Setter private String dataStateShort; /** * Network Operator Name */ @Setter private String networkName; private String mncMcc; private Optional<String> simCountry; private String phoneType; /** * Device IMEI */ private String iMEI; /** * Device IMEI Version */ private String iMEIv; private Optional<String> simOperator; private Optional<String> simOperatorName; private Optional<String> simSerial; private Optional<String> simSubs; @Setter private String dataActivityType; @Setter private String dataActivityTypeShort; private boolean roaming; /** * Cell object representing last known location */ @Setter private Location lastLocation; /** * Refreshes all device specific details */ public void refreshDeviceInfo(TelephonyManager tm, Context context) { //Phone type and associated details iMEI = tm.getDeviceId(); iMEIv = tm.getDeviceSoftwareVersion(); phoneId = tm.getPhoneType(); roaming = tm.isNetworkRoaming(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { DeviceApi18.loadCellInfo(tm, this); } if (cell == null) { cell = new Cell(); } switch (phoneId) { case TelephonyManager.PHONE_TYPE_NONE: case TelephonyManager.PHONE_TYPE_SIP: case TelephonyManager.PHONE_TYPE_GSM: phoneType = "GSM"; mncMcc = tm.getNetworkOperator(); if (mncMcc != null && mncMcc.length() >= 5) { try { if (cell.getMobileCountryCode() == Integer.MAX_VALUE) { cell.setMobileCountryCode(Integer.parseInt(tm.getNetworkOperator().substring(0, 3))); } if (cell.getMobileNetworkCode() == Integer.MAX_VALUE) { cell.setMobileNetworkCode(Integer.parseInt(tm.getNetworkOperator().substring(3, 5))); } } catch (Exception e) { log.info("MncMcc parse exception: ", e); } } networkName = tm.getNetworkOperatorName(); if (!cell.isValid()) { GsmCellLocation gsmCellLocation = (GsmCellLocation) tm.getCellLocation(); if (gsmCellLocation != null) { cell.setCellId(gsmCellLocation.getCid()); cell.setLocationAreaCode(gsmCellLocation.getLac()); cell.setPrimaryScramblingCode(gsmCellLocation.getPsc()); } } break; case TelephonyManager.PHONE_TYPE_CDMA: phoneType = "CDMA"; if (!cell.isValid()) { CdmaCellLocation cdmaCellLocation = (CdmaCellLocation) tm.getCellLocation(); if (cdmaCellLocation != null) { cell.setCellId(cdmaCellLocation.getBaseStationId()); cell.setLocationAreaCode(cdmaCellLocation.getNetworkId()); cell.setSid(cdmaCellLocation.getSystemId()); // one of these must be a bug !! // See: http://stackoverflow.com/questions/8088046/android-how-to-identify-carrier-on-cdma-network // and: https://github.com/klinker41/android-smsmms/issues/26 cell.setMobileNetworkCode(cdmaCellLocation.getSystemId()); // todo: check! (Also CellTracker.java) //Retrieve MCC through System Property String homeOperator = Helpers.getSystemProp(context, "ro.cdma.home.operator.numeric", "UNKNOWN"); if (!homeOperator.contains("UNKNOWN")) { try { if (cell.getMobileCountryCode() == Integer.MAX_VALUE) { cell.setMobileCountryCode(Integer.valueOf(homeOperator.substring(0, 3))); } if (cell.getMobileNetworkCode() == Integer.MAX_VALUE) { cell.setMobileNetworkCode(Integer.valueOf(homeOperator.substring(3, 5))); } } catch (Exception e) { log.info("HomeOperator parse exception - " + e.getMessage(), e); } } } } break; } // SIM Information simCountry = getSimCountry(tm); // Get the operator code of the active SIM (MCC + MNC) simOperator = getSimOperator(tm); simOperatorName = getSimOperatorName(tm); simSerial = getSimSerial(tm); simSubs = getSimSubs(tm); dataActivityType = getDataActivityType(tm); dataState = getDataState(tm); } private Optional<String> getSimInformation(Supplier<String> simInfoSupplier) { try { return Optional.ofNullable(simInfoSupplier.get()); } catch (Exception e) { // SIM methods can cause Exceptions on some devices log.error("Failed to get SIM-Information", e); } return Optional.empty(); } /** * SIM Country * * @return string of SIM Country data */ Optional<String> getSimCountry(final TelephonyManager tm) { return getSimInformation(new Supplier<String>() { @Nullable @Override public String get() { return tm.getSimCountryIso(); } }); } /** * SIM Operator * * @return string of SIM Operator data */ public Optional<String> getSimOperator(final TelephonyManager tm) { return getSimInformation(new Supplier<String>() { @Nullable @Override public String get() { return tm.getSimOperator(); } }); } /** * SIM Operator Name * * @return string of SIM Operator Name */ Optional<String> getSimOperatorName(final TelephonyManager tm) { return getSimInformation(new Supplier<String>() { @Nullable @Override public String get() { return tm.getSimOperatorName(); } }); } /** * SIM Subscriber ID * * @return string of SIM Subscriber ID data */ Optional<String> getSimSubs(final TelephonyManager tm) { return getSimInformation(new Supplier<String>() { @Nullable @Override public String get() { return tm.getSubscriberId(); } }); } /** * SIM Serial Number * * @return string of SIM Serial Number data */ Optional<String> getSimSerial(final TelephonyManager tm) { return getSimInformation(new Supplier<String>() { @Nullable @Override public String get() { return tm.getSimSerialNumber(); } }); } /** * Network Type * * @return string representing device Network Type */ public String getNetworkTypeName() { if (cell == null) { return "Unknown"; } return cell.getRat(); } String getDataActivityType(TelephonyManager tm) { int direction = tm.getDataActivity(); dataActivityTypeShort = "un"; dataActivityType = "undef"; switch (direction) { case TelephonyManager.DATA_ACTIVITY_NONE: dataActivityTypeShort = "No"; dataActivityType = "None"; break; case TelephonyManager.DATA_ACTIVITY_IN: dataActivityTypeShort = "In"; dataActivityType = "In"; break; case TelephonyManager.DATA_ACTIVITY_OUT: dataActivityTypeShort = "Ou"; dataActivityType = "Out"; break; case TelephonyManager.DATA_ACTIVITY_INOUT: dataActivityTypeShort = "IO"; dataActivityType = "In-Out"; break; case TelephonyManager.DATA_ACTIVITY_DORMANT: dataActivityTypeShort = "Do"; dataActivityType = "Dormant"; break; } return dataActivityType; } String getDataState(TelephonyManager tm) { int state = tm.getDataState(); dataState = "undef"; dataStateShort = "un"; switch (state) { case TelephonyManager.DATA_DISCONNECTED: dataState = "Disconnected"; dataStateShort = "Di"; break; case TelephonyManager.DATA_CONNECTING: dataState = "Connecting"; dataStateShort = "Ct"; break; case TelephonyManager.DATA_CONNECTED: dataState = "Connected"; dataStateShort = "Cd"; break; case TelephonyManager.DATA_SUSPENDED: dataState = "Suspended"; dataStateShort = "Su"; break; } return dataState; } public void setSignalDbm(int signalDbm) { cell.setDbm(signalDbm); } public int getSignalDBm() { return cell.getDbm(); } /** * Update Network Type */ public void setNetID(TelephonyManager tm) { cell.setNetType(tm.getNetworkType()); } }