package org.microg.networklocation.platform; import android.content.Context; import android.os.Build; import android.telephony.CellLocation; import android.telephony.NeighboringCellInfo; import android.telephony.TelephonyManager; import android.telephony.cdma.CdmaCellLocation; import android.telephony.gsm.GsmCellLocation; import android.util.Log; import org.microg.networklocation.MainService; import org.microg.networklocation.data.CellSpec; import org.microg.networklocation.data.Radio; import java.util.ArrayList; import java.util.Collection; import java.util.List; class CellSpecRetriever implements org.microg.networklocation.retriever.CellSpecRetriever { private static final String TAG = "nlp.CellSpecRetriever"; private TelephonyManager telephonyManager; public CellSpecRetriever(TelephonyManager telephonyManager) { this.telephonyManager = telephonyManager; } public CellSpecRetriever(Context context) { this((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)); } private void addCellSpecFromCellLocation(Collection<CellSpec> cellSpecs, int mcc, int mnc, CellLocation cellLocation) { if (cellLocation instanceof GsmCellLocation) { GsmCellLocation gsmCellLocation = (GsmCellLocation) cellLocation; int cid = gsmCellLocation.getCid(); int lac = gsmCellLocation.getLac(); int psc = gsmCellLocation.getPsc(); if (psc == -1) { cellSpecs.add(new CellSpec(Radio.GSM, mcc, mnc, lac, cid)); } else if ((cid != -1) && (lac != -1)) { CellSpec cellSpec = new CellSpec(Radio.UMTS, mcc, mnc, lac, cid); cellSpec.setPsc(psc); cellSpecs.add(cellSpec); } } else if (cellLocation instanceof CdmaCellLocation) { CdmaCellLocation cdmaCellLocation = (CdmaCellLocation) cellLocation; int sid = cdmaCellLocation.getSystemId(); // as mnc int nid = cdmaCellLocation.getNetworkId(); // as lac int bid = cdmaCellLocation.getBaseStationId(); // as cid cellSpecs.add(new CellSpec(Radio.CDMA, mcc, sid, nid, bid)); } else { if (MainService.DEBUG) { Log.d(TAG, "Not connected to network or using LTE, which is not supported for SDK <= 16"); } } } private void addCellSpecsFromNeighboringCellInfo(Collection<CellSpec> cellSpecs, int mcc, int mnc, List<NeighboringCellInfo> neighboringCellInfo) { if (neighboringCellInfo == null) { return; } for (NeighboringCellInfo cellInfo : neighboringCellInfo) { int lac = cellInfo.getLac(); int cid = cellInfo.getCid(); int psc = cellInfo.getPsc(); // TODO handle rssi: int rssi = cellInfo.getRssi(); if ((lac != NeighboringCellInfo.UNKNOWN_CID) && (cid != NeighboringCellInfo.UNKNOWN_CID)) { if (psc != NeighboringCellInfo.UNKNOWN_CID) { CellSpec cellSpec = new CellSpec(Radio.UMTS, mcc, mnc, lac, cid); cellSpec.setPsc(psc); cellSpecs.add(cellSpec); } else { cellSpecs.add(new CellSpec(Radio.GSM, mcc, mnc, lac, cid)); } } } } public Collection<CellSpec> retrieveCellSpecs() { Collection<CellSpec> cellSpecs = new ArrayList<CellSpec>(); if (telephonyManager == null) { return cellSpecs; } CellLocation.requestLocationUpdate(); String mncString = telephonyManager.getNetworkOperator(); if ((mncString == null) || (mncString.length() < 5) || (mncString.length() > 6)) return cellSpecs; int mcc = Integer.parseInt(mncString.substring(0,3)); int mnc = Integer.parseInt(mncString.substring(3)); addCellSpecFromCellLocation(cellSpecs, mcc, mnc, telephonyManager.getCellLocation()); addCellSpecsFromNeighboringCellInfo(cellSpecs, mcc, mnc, telephonyManager.getNeighboringCellInfo()); if ((Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) && MainService.DEBUG) { Log.d(TAG, "Android SDK > 16 features are not used yet (but would be good here!)"); } if (MainService.DEBUG) { Log.d(TAG, "Found "+cellSpecs.size()+" Cells"); } return cellSpecs; } }