//package indoor.java; package android.net.wifi; import android.app.Activity; import android.util.Log; import android.content.Context; import java.lang.System; import java.util.List; import java.util.ArrayList; import android.net.wifi.ScanResult; import android.net.wifi.rtt.RangingRequest; import android.net.wifi.rtt.RangingResult; import android.net.wifi.rtt.RangingResultCallback; import android.net.wifi.rtt.WifiRttManager; import java.util.concurrent.Executor; import android.net.MacAddress; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Array; import indoor.java.MyActivity; import java.io.ByteArrayOutputStream; public class RTT { private static Activity act; private static WifiRttManager rttManager; private static Executor mainExecutor; private static Thread ftmThread; private static boolean ftmRunning; public static native void onRttData(int success, final byte[] mac, long timeMS, int distMM, int distStdDevMM, int numAttemptedMeas, int numSuccessfullMeas, int rssi); // result callback private static final RangingResultCallback callback = new RangingResultCallback() { @Override public void onRangingFailure(final int i) { //emitter.onError(new RuntimeException("The WiFi-Ranging failed with error code: " + i)); Log.d("RTT", "onRangingFailure: " + i); } @Override public void onRangingResults(final List list) { //emitter.onSuccess(list); Log.d("RTT", "onRangingResults: " + list.size()); for (final RangingResult res : list) { int success = 0; long timeStampInMS = 0; MacAddress mac = res.getMacAddress(); int dist = 0; int stdDevDist = 0; int rssi = 0; int numAttemptedMeas = 0; int numSuccessfulMeas = 0; if (res.getStatus() == RangingResult.STATUS_SUCCESS) { success = 1; timeStampInMS = res.getRangingTimestampMillis(); dist = res.getDistanceMm(); stdDevDist = res.getDistanceStdDevMm(); rssi = res.getRssi(); numAttemptedMeas = res.getNumAttemptedMeasurements(); numSuccessfulMeas = res.getNumSuccessfulMeasurements(); //Log.d("RTT", mac.toString() + " " + dist + " " + stdDevDist + " " + rssi); } else { //Log.d("RTT", mac.toString() + " FAILED"); } onRttData(success, mac.toString().getBytes(), timeStampInMS, dist, stdDevDist, numAttemptedMeas, numSuccessfulMeas, rssi); } } }; public static int start() { if (ftmRunning) return 0; Log.d("RTT", "start()"); MyActivity act = MyActivity.act; rttManager = (WifiRttManager) act.getSystemService(Context.WIFI_RTT_RANGING_SERVICE); mainExecutor = act.getMainExecutor(); final ArrayList macs = new ArrayList<>(); macs.add(MacAddress.fromString("38:de:ad:6d:77:25")); // NUC 1 macs.add(MacAddress.fromString("38:de:ad:6d:60:ff")); // NUC 2 macs.add(MacAddress.fromString("1c:1b:b5:ef:a2:9a")); // NUC 3 macs.add(MacAddress.fromString("1c:1b:b5:ec:d1:82")); // NUC 4 macs.add(MacAddress.fromString("d0:c6:37:bc:5c:41")); // NUC 5 ftmRunning = true; ftmThread = new Thread() { public void run() { while(ftmRunning) { try { Thread.sleep(200); } catch (Exception e) {;} startRangingOnMacs(macs); } } }; ftmThread.start(); return 1337; } public static int stop() { Log.d("RTT", "stop()"); if (ftmRunning) { ftmRunning = false; } return 1337*2; } public static void startRangingOnMacs(final ArrayList macs) { Log.d("RTT", "startRangingOnMac()"); RangingRequest.Builder builder = new RangingRequest.Builder(); for (final MacAddress mac : macs) { ScanResult sr = new ScanResult(); sr.BSSID = mac.toString(); sr.SSID = "tof_test"; sr.frequency = 2447; sr.capabilities = "[ESS]"; try { Class clazz = Class.forName("android.net.wifi.ScanResult$InformationElement"); Object[] ies = (Object[]) Array.newInstance(clazz, 1); Object ie = clazz.getDeclaredConstructor().newInstance(); ies[0] = ie; Field f1 = sr.getClass().getDeclaredField("flags"); f1.setAccessible(true); f1.set(sr, 2); Field f2 = sr.getClass().getDeclaredField("informationElements"); f2.setAccessible(true); f2.set(sr, ies); builder.addAccessPoint(sr); } catch (final Exception e) { e.printStackTrace(); } } Log.d("RTT", "startRanging() on " + macs.size()); if (macs.size() == 0) {return;} // fire# final RangingRequest request = builder.build(); rttManager.startRanging(request, mainExecutor, callback); } public static void startRangingOnScanResult(final List scanResults) { Log.d("RTT", "startRangingOnScanResult()"); // build the request int cnt = 0; RangingRequest.Builder builder = new RangingRequest.Builder(); for (final ScanResult r : scanResults) { if (r.is80211mcResponder()) { Log.d("RTT", "- " + r.BSSID + " [supported]"); builder.addAccessPoint(r); ++cnt; } else { Log.d("RTT", "- " + r.BSSID + " [NO!]"); } } Log.d("RTT", "startRanging on " + cnt + " devices"); if (cnt == 0) {return;} // fire final RangingRequest request = builder.build(); rttManager.startRanging(request, mainExecutor, callback); } }