Skip to content

Commit

Permalink
Merge pull request #243 from Ueland/SignalStrengthMonitor
Browse files Browse the repository at this point in the history
Implemented Signal Strength Monitor
  • Loading branch information
SecUpwN committed Dec 29, 2014
2 parents a6e4c48 + 9793fdf commit 819b246
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.SecUpwN.AIMSICD.R;
import com.SecUpwN.AIMSICD.service.AimsicdService;
import com.SecUpwN.AIMSICD.utils.Icon;
import com.SecUpwN.AIMSICD.utils.Status;

/**
* Base activity class, handles code that is shared between all activites
Expand Down Expand Up @@ -39,8 +40,8 @@ protected void onResume() {
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "StatusWatcher recieved status change, updating icon");
updateIcon(context);
Log.d(TAG, "StatusWatcher recieved status change to " + Status.getStatus().name()+", updating icon");
updateIcon(context);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class AIMSICDDbAdapter {
private final String OPENCELLID_TABLE = "opencellid";
private final String DEFAULT_MCC_TABLE = "defaultlocation";
private final String SILENT_SMS_TABLE = "silentsms";
private final String CELL_SIGNAL_TABLE = "cellSignal";
// E:V:A private final String DB_NAME = "myCellInfo";
private final String DB_NAME = "aimsicd.db"; // old name: "myCellInfo"

Expand Down Expand Up @@ -644,6 +645,31 @@ private void backup(String tableName) {
Log.i(TAG, "exporting database complete");
}

public void cleanseCellStrengthTables(long maxTime) {
Log.d(TAG, "Cleaning "+CELL_SIGNAL_TABLE+" WHERE timestamp < "+maxTime);
mDb.execSQL("DELETE FROM "+CELL_SIGNAL_TABLE+" WHERE timestamp < "+maxTime);
}

public void addSignalStrength(int cellID, int signal, Long timestamp) {
ContentValues row = new ContentValues();
row.put("cellID", cellID);
row.put("signal", signal);
row.put("timestamp", timestamp);
mDb.insert(CELL_SIGNAL_TABLE, null, row);
}

public int countSignalMeasurements(int cellID) {
Cursor c = mDb.rawQuery("SELECT COUNT(cellID) FROM " + CELL_SIGNAL_TABLE +" WHERE cellID="+cellID, new String[0]);
c.moveToFirst();
return c.getInt(0);
}

public int getAverageSignalStrength(int cellID) {
Cursor c = mDb.rawQuery("SELECT AVG(signal) FROM " + CELL_SIGNAL_TABLE +" WHERE cellID="+cellID, new String[0]);
c.moveToFirst();
return c.getInt(0);
}

/**
* DbHelper class for the SQLite Database functions
*/
Expand All @@ -656,6 +682,13 @@ public class DbHelper extends SQLiteOpenHelper {
@Override
public void onCreate(SQLiteDatabase database) {

/*
* Cell Signal Measurements
*/
database.execSQL("create table " + CELL_SIGNAL_TABLE + " (" + COLUMN_ID + " integer primary key autoincrement, cellID INTEGER, signal INTEGER, timestamp INTEGER);");
database.execSQL("create index cellID_index ON "+CELL_SIGNAL_TABLE+" (cellID);");
database.execSQL("create index cellID_timestamp ON "+CELL_SIGNAL_TABLE+" (timestamp);");

/*
* Silent Sms Database
*/
Expand Down Expand Up @@ -724,6 +757,7 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + OPENCELLID_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + SILENT_SMS_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + DEFAULT_MCC_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + CELL_SIGNAL_TABLE);

onCreate(db);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public class AimsicdService extends Service {

private CellTracker mCellTracker;
private AccelerometerMonitor mAccelerometerMonitor;
private SignalStrengthTracker signalStrengthTracker;
private LocationTracker mLocationTracker;
private RilExecutor mRilExecutor;

Expand All @@ -114,11 +115,16 @@ public AimsicdService getService() {
}

public void onCreate() {

signalStrengthTracker = new SignalStrengthTracker(getBaseContext());

mAccelerometerMonitor = new AccelerometerMonitor(this, new Runnable() {
@Override
public void run() {
// movement detected, so enable GPS
mLocationTracker.start();
signalStrengthTracker.onSensorChanged();


// check again in a while to see if GPS should be disabled
// this runnable also re-enables this movement sensor
Expand All @@ -128,7 +134,7 @@ public void run() {

mLocationTracker = new LocationTracker(this, mLocationListener);
mRilExecutor = new RilExecutor(this);
mCellTracker = new CellTracker(this);
mCellTracker = new CellTracker(this, signalStrengthTracker);

Log.i(TAG, "Service launched successfully.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public class CellTracker implements SharedPreferences.OnSharedPreferenceChangeLi
private final int NOTIFICATION_ID = 1;

private static TelephonyManager tm;
private final SignalStrengthTracker signalStrengthTracker;
private PhoneStateListener mPhoneStateListener;
private SharedPreferences prefs;

Expand Down Expand Up @@ -87,8 +88,9 @@ public class CellTracker implements SharedPreferences.OnSharedPreferenceChangeLi
private Context context;
private final Handler timerHandler = new Handler();

public CellTracker(Context context) {
public CellTracker(Context context, SignalStrengthTracker sst) {
this.context = context;
this.signalStrengthTracker = sst;
// TelephonyManager provides system details
tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
prefs = context.getSharedPreferences(
Expand Down Expand Up @@ -486,6 +488,8 @@ public void onSignalStrengthsChanged(SignalStrength signalStrength) {
}

//Send it to signal tracker
signalStrengthTracker.registerSignalStrength(mDevice.mCell.getCID(), mDevice.getSignalDBm());
//signalStrengthTracker.isMysterious(mDevice.mCell.getCID(), mDevice.getSignalDBm());
}

public void onDataActivity(int direction) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package com.SecUpwN.AIMSICD.service;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.util.Log;

import com.SecUpwN.AIMSICD.adapters.AIMSICDDbAdapter;

import java.util.ArrayList;
import java.util.HashMap;

/**
*
* Class that calculates cell signal strength averages and decides if a given cell + strength
* appears to be mysteriously (low or high)
*
* https://cloud.githubusercontent.com/assets/2507905/4428863/c85c8366-45d4-11e4-89da-c650cdb56caf.jpg
*
* @author Tor Henning Ueland
*/
public class SignalStrengthTracker {

public static final String TAG = "SignalStrengthMonitor";
private static int sleepTimeBetweenSignalRegistration = 30; //seconds
private static int sleepTimeBetweenPersistation = 900; //seconds
private static int minimumIdleTime = 30; //seconds
private static int maximumNumberOfDaysSaved = 60; //days
private static int mysteriousSignalDifference = 10; //DB

private HashMap<Integer, Long> lastRegistration = new HashMap<>();
private HashMap<Integer, ArrayList<Integer>> toCalculate = new HashMap<>();
private HashMap<Integer, Integer> averageSignalCache = new HashMap<>();
private long lastPersistTime = 0;
private long lastMovementDetected = 0l;
private AIMSICDDbAdapter mDbHelper;

public SignalStrengthTracker(Context context) {
lastMovementDetected = System.currentTimeMillis();
lastPersistTime = System.currentTimeMillis();
mDbHelper = new AIMSICDDbAdapter(context);
}

/**
* Registers a new cell signal strength for future calculation,
* only values older than $sleepTimeBetweenSignalRegistration seconds
* since last registration is saved for processing.
* @param cellID
* @param signalStrength
*/
public void registerSignalStrength(int cellID, int signalStrength) {

long now = System.currentTimeMillis();

if(deviceIsMoving()) {
Log.i(TAG, "Ignored signal strength sample for cell ID #"+cellID+" as the device is currently moving around, will not accept anything for another "+((minimumIdleTime*1000) - (now - lastMovementDetected))+"ms");
return;
}

if(!lastRegistration.containsKey(cellID) || now-(sleepTimeBetweenSignalRegistration*1000) > lastRegistration.get(cellID)) {
long diff = -1;
if(lastRegistration.get(cellID) != null) {
diff = now - lastRegistration.get(cellID);
}
lastRegistration.put(cellID, now);
if(toCalculate.get(cellID) == null) {
toCalculate.put(cellID, new ArrayList<Integer>(1));
}
Log.i(TAG, "Scheduling signal strength calculation from cell #" + cellID + " @ " + signalStrength + "DB, last registration was "+diff+"ms ago");
toCalculate.get(cellID).add(signalStrength);
lastRegistration.put(cellID, now);
}

if(now-(sleepTimeBetweenPersistation*1000) > lastPersistTime) {
Log.i(TAG, "Saving cell signal data, last save was "+(now-lastPersistTime)+"ms ago");
cleanupOldData();
persistData();
lastPersistTime = now;
}
}

/*
Move data from temp cache into DB
*/
private void persistData() {
mDbHelper.open();
for(int cellID : toCalculate.keySet()) {
for(int signal : toCalculate.get(cellID)) {
mDbHelper.addSignalStrength(cellID, signal, lastRegistration.get(cellID));
}
}
mDbHelper.close();
toCalculate.clear();
}

/*
Remove data from DB older than N days (days * number of seconds in a day)*seconds to milliseconds
*/
private void cleanupOldData() {
long maxTime = (System.currentTimeMillis() - ((maximumNumberOfDaysSaved*86400))*1000);
mDbHelper.open();
mDbHelper.cleanseCellStrengthTables(maxTime);
mDbHelper.close();
averageSignalCache.clear();
}

private boolean deviceIsMoving() {
return System.currentTimeMillis() - lastMovementDetected < minimumIdleTime*1000;
}

/**
* Uses previously saved calculations and signal measurements to guesstimate if a given signal
* strength for a given cell ID looks mysterious or not.
* @param cellID
* @param signalStrength
*/
public boolean isMysterious(int cellID, int signalStrength) {

//If moving, return false
if(deviceIsMoving()) {
Log.i(TAG, "Cannot check if the signal strength for cell ID #"+cellID+" as the device is currently moving around.");
return false;
}

int storedAvg;

//Cached?
if(averageSignalCache.get(cellID) != null) {
storedAvg = averageSignalCache.get(cellID);
Log.d(TAG, "Cached average for cell ID #"+cellID+" is "+storedAvg);
} else {
//Not cached, check DB
mDbHelper.open();
storedAvg = mDbHelper.getAverageSignalStrength(cellID);
averageSignalCache.put(cellID, storedAvg);
Log.d(TAG, "Cached average in DB for cell ID #"+cellID+" is "+storedAvg);
mDbHelper.close();
}

boolean result;
if(storedAvg > signalStrength) {
result = storedAvg - signalStrength > mysteriousSignalDifference;
} else {
result = signalStrength- storedAvg > mysteriousSignalDifference;
}
Log.d(TAG, "Signal strength mystery check for cell ID #"+cellID+" is "+result+", avg:"+storedAvg+", this signal: "+signalStrength);
return result;
}

public void onSensorChanged() {
//Log.d(TAG, "We are moving...");
lastMovementDetected = System.currentTimeMillis();
}
}

0 comments on commit 819b246

Please sign in to comment.