title: Unlock Linux with Bluetooth low energy
body: <p>Have you ever seen the apple watch unlock a Mac? The idea is amazing, but I don't want a smart watch because I already have a phone which has similar capabilities AFAIK. 
  Also, I moved from OSX to Linux recently :)</p>
  
  <p>I don't know how the Apple watch manages to unlock the Mac. But I know what would be desirable from a user experience point of view:</p>
  
  <ol>
  <li>Needs to unlock quicker than I type my password</li>
  <li>Should work in absence of wifi/4G</li>
  <li>Should be power efficient</li>
  </ol>
  
  <h3>RFID</h3>
  
  <p>RFID would be nice, but no laptops that I know embed RFID readers.</p>
  
  <h3>Bluetooth based proximity detection</h3>
  
  <p>The challenge with classic Bluetooth is the requirement to constantly scan for near devices to measure the signal strenght (RSSI) from which we can infer the proximity.</p>
  
  <p>Unfortunately discovery hops and listens 40 channels. And anyway the phones stop broadcasting when screen is off for a while. This is not good enough. I know because I tried:</p>
  
  <pre class="lang-scala prettyprint-override"><code>import collection.JavaConverters._
  import tinyb._
  
  object Listener extends App {
  
    var running = true
  
    val BT_ADDR = sys.env.getOrElse("BT_ADDR", "XX:XX:XX:XX:XX:XX")
    val BT_RSSI_DBM_THRESHOLD = Integer.parseInt(sys.env.getOrElse("BT_RSSI_DBM_THRESHOLD", "-65")).toShort
  
    val manager = BluetoothManager.getBluetoothManager
    val lock = new Object
  
    while (true) {
      manager.getAdapters.forEach(a =&gt; {
        a.setRssiDiscoveryFilter(BT_RSSI_DBM_THRESHOLD)
        a.removeDevices()
      })
  
      System.err.println("scanning for " + BT_ADDR + " at minimum " + BT_RSSI_DBM_THRESHOLD + " dBm RSSI...")
  
      manager.startNearbyDiscovery(
        (device: BluetoothDevice) =&gt; {
          if (BT_ADDR.equals(device.getAddress)) {
            onProximity(device)
            manager.stopNearbyDiscovery()
            lock.synchronized(lock.notify())
  
          }
          else println(device.getName)
        }
        , 1000
        , false
      )
      lock.synchronized(lock.wait())
    }
  
  
  }
  
  </code></pre>
  
  <p>I was looking at BTLE (Bluetooth Low Energy), and I'm having difficulty to understand the following:</p>
  
  <p>Is there a way to establish from Linux a single low energy bluetooth connection to the Android phone which we can leave dormant all the time, and use it to wake the phone up and make it transmit some packets (so we can measure its RSSI power and infer proximity) <strong>on demand</strong>, only when strictly needed. </p>
  
  <p>I.e. we'd limit transmissions to only these rare occasions:  </p>
  
  <ul>
  <li>Check when the user is away if we detect inactive mouse &amp; keyboard for 1 minute,</li>
  <li>Check if the user is near enough when GDM is active</li>
  <li>No BT activity whatsoever otherwise</li>
  </ul>
  
  <p>This approach is quick, energy efficient, and does not require network protocol, only some rare BT transmission.</p>
  
  <p>But is this possible with Bluetooth LE? Any pointers to examples?</p>