// Location Listener Required Methods
 @Override
 public void onLocationChanged(Location location) {
   // TODO Auto-generated method stub
   last_location = location;
   // Log locations to file
   Local.appendExternalFileFromString(
       "xfinity", LOCATION_LOG_FILE, (new Gson()).toJson(location), this);
 }
  /**
   * Each experiment consists of the following: - a gps recording (or enabling location listeners) -
   * running NDT to closest (Chicago) server. - running iPerf to Northwestern servers. - ** not
   * implemented ** (A speedtest run) -- not sure if we need to do this. Check if we are using speed
   * tests in the paper
   */
  public void startNewExperiment() {

    setStatus("Starting Experiment...");

    // get partial wake lock
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
    // PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
    wakeLock.acquire();

    for (; ; ) {

      // sleep for 5 seconds just because
      try {
        Thread.sleep(5000);
      } catch (InterruptedException ie) {
        // do nothing
      }

      currentResult = new XfinityExperimentResult();
      currentResult.startLocation = last_location;
      currentResult.starttime = System.currentTimeMillis();

      // check wifi and turn on
      WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
      if (!wm.isWifiEnabled()) wm.setWifiEnabled(true);

      // add latest scan to
      WifiScanResponse wifi_scan_result = conductWifiScan();
      currentResult.scan_result = wifi_scan_result;

      appendDebug(
          "Wifi Scan Completed - " + currentResult.scan_result.scan_results.size() + " APs Found");
      // setStatus("Wifi Scan Complete");

      // iterate through sorted list to find un-attempted access points -- sorts in place
      Collections.sort(
          wifi_scan_result.scan_results,
          new Comparator<WifiScanResult>() {
            @Override
            public int compare(WifiScanResult lhs, WifiScanResult rhs) {
              // TODO Auto-generated method stub
              return (rhs.level - lhs.level);
            }
          });
      WifiScanResult selectedAccessPoint = null;
      boolean isbestXfinityAP = true;
      int countxfinity = 0;
      int countxfinity5 = 0;
      int countxfinity2 = 0;
      for (WifiScanResult wsr : wifi_scan_result.scan_results) {
        // we only care about xfinitywifi
        if (!wsr.SSID.equals("xfinitywifi")) continue;
        if (completedAccessPoints.containsKey(wsr.BSSID)) continue;
        countxfinity += 1;

        if (countxfinity2 != 0 && countxfinity5 != 0) break;
        else if (countxfinity2 != 0 && wsr.frequency < 5000) continue;
        else if (countxfinity5 != 0 && wsr.frequency > 5000) continue;

        if (wsr.frequency > 5000) countxfinity5 += 1;
        else countxfinity2 += 1;

        appendDebug(
            "\n"
                + Integer.toString(countxfinity)
                + " Found xfinitywifi AP: "
                + wsr.BSSID
                + "with signal: "
                + Integer.toString(wsr.level)
                + " frequency:"
                + Integer.toString(wsr.frequency)
                + (System.currentTimeMillis() / 1000));
        selectedAccessPoint = wsr;

        // run the experiments here
        // this is not the best structure -- to be perfectly honest...
        boolean ret = connectToAccessPoint(selectedAccessPoint);
        if (!ret) {

          appendDebug("Unable to connect.");
          continue;
        }
        appendDebug("Connected to xfinitywifi AP:" + wsr.BSSID);
        currentResult.available_bssids.add(selectedAccessPoint.BSSID);
        if (!isbestXfinityAP) {
          wm.disconnect();
          continue;
        }
        completedAccessPoints.put(selectedAccessPoint.BSSID, true);
        authenticated = true;
        isbestXfinityAP = false;
        // Vibrate to indicate the need for authentication
        Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
        vibrator.vibrate(1000);
        // block until successful or unsuccessful
        /*
        while(authenticated == null) {
        	appendDebug("Waiting on authentication: " + String.valueOf(authenticated));
        	try {
        		Thread.sleep(1000);
        	} catch (InterruptedException e) {
        		// TODO Auto-generated catch block
        		e.printStackTrace();
        	}
        }
        */
        // appendDebug("Authentication Successful");
        if (authenticated) {
          currentResult.measured_bssid = selectedAccessPoint.BSSID;
          // now run the bandwidth tests
          // runBandwidthTests();
          // appendDebug("back to scan.... "+ currentResult.connected_bssid);

        } else {
          // log the authentication error
          // currentResult.error = "Error authenticating XfinityWifi";

          // currentResult.endLocation = last_location;
          // currentResult.endtime = System.currentTimeMillis();

          // appendDebug((new Gson()).toJson(currentResult));

          // Local.appendExternalFileFromString("xfinity", EXPERIMENT_LOG_FILE, (new
          // Gson()).toJson(currentResult), this);

        }

        // vibrator.vibrate(1000);
        break;
      }

      currentResult.endLocation = last_location;
      currentResult.endtime = System.currentTimeMillis();
      WifiScanResponse wifi_scan_result2 = conductWifiScan();
      currentResult.end_scan_result = wifi_scan_result2;

      String json_result = (new Gson()).toJson(currentResult);
      // appendDebug("\nWriting to file:"+ currentResult.measured_bssid +
      // currentResult.available_bssids.toString() );
      // try{
      //	appendDebug("\\nNDT results written: "+ currentResult.ndt.toString());
      // }catch(Exception e)
      // {
      //	appendDebug("Problem with NDT");
      // }

      // appendDebug("\nAll results written:"+json_result);
      Local.appendExternalFileFromString("xfinity", EXPERIMENT_LOG_FILE, json_result, this);
      continue;
    } // end of event loop
  }