title: Private vs public addresses in Bluetooth low energy on Android
body: <p>A Bluetooth low energy device is uniquely identified by it's address (in the Android API they call this the MAC address and denote it as colon separated hex values e.g. 11:aa:22:bb:33:cc).</p>
  
  <p>But to uniquely identify a BLE address you need to know if it's a public or a private address. In essence, 49 bits are necessary to identify an address, not 48.</p>
  
  <p>Random addresses can be either static random, non-resolvable private or resolvable private and these types are separated by a bit pattern in the two most significant bytes (11, 00 and 10 respectively).</p>
  
  <p>But I don't see anywhere that you can separate public and random addresses just by looking at the 48 bits in the address.</p>
  
  <p>So how does this work in the Android API? How do they know what device to connect to when they don't know if the address you've specified are public or random?</p>
  
  <p>The API in question is for instance the <a href="http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#getRemoteDevice%28java.lang.String%29">getRemoteDevice</a> function. It says:</p>
  
  <pre><code>Valid Bluetooth hardware addresses must be upper case, in a format such as
  "00:11:22:33:AA:BB". The helper checkBluetoothAddress(String) is available
  to validate a Bluetooth address.
  
  A BluetoothDevice will always be returned for a valid hardware address,
  even if this adapter has never seen that device.
  </code></pre>
  
  <p>So you give the function 48 bits of data and there is no way to tell it if the address is public or private. This means the device is <em>not</em> uniquely identified.</p>