Successfully reported this slideshow.
Your SlideShare is downloading. ×

Eddystone beacons demo

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
Implementing cast in android
Implementing cast in android
Loading in …3
×

Check these out next

1 of 69 Ad
Advertisement

More Related Content

Slideshows for you (20)

Similar to Eddystone beacons demo (20)

Advertisement

Eddystone beacons demo

  1. 1. Eddystone Beacons Demo Lecture on Eddystone, an open Bluetooth Smart Beacon format from Google +Angelo Rüggeberg @s3xy4ngyc
  2. 2. agenda - Introductions to Beacons - Introduction to Eddystone - Coding Session
  3. 3. Introduction to Beacons
  4. 4. Image: Google Context or exact Location
  5. 5. Location, Accuracy, Range, and alike Image: Google …
  6. 6. Use Cases Image: Estimote
  7. 7. Opportunities Presence (e.g. sights) Image: Google
  8. 8. Opportunities Tracking and Securing Image: Google
  9. 9. Opportunities • Contextual fencing (aka Geo-fence) • Contextual content (e.g. reader circle) • … Image: Bundesarchiv
  10. 10. Landscape • AltBeacon • Apple‘s property: iBeacon™ • Estimote • Gimbal™ • PayPal™ Beacon • yoints • … • Bluetooth® SIG (Special Interest Group) • Bluetooth® Smart Beacon • Eddystone™ • https://github. com/google/eddystone/tree/mast er/branding
  11. 11. Introduction to Eddystone
  12. 12. Eddystone™, what’s so special? Openness • It is an open Bluetooth 4.0 protocol • While iBeacon™ is officially supported by iOS devices only, Eddystone™ has official support for both iOS and Android Packet types / frames • Eddystone-UID (identifier) • Namespace as UUID • Instance (6 bytes), much like Major and Minor • Eddystone-URL • Eddystone-TLM (telemetry) • battery voltage • temperature • number of packets since last reboot • beacon uptime since last reboot
  13. 13. Hardware Phones can become Smart Beacons themselves • TxEddystone-UID (Android Lollipop 5.0) Almost all devices with BLE can become Smart Beacons themselves • BlueGiga BLED112 Dongle • Cambridge Silicon Radio CSR1010 (Beacon Development Board) • Rfduino • Linux (bluez) • ARM mbed (Nordic nRF51-dongle, nRF51-DK) • Node.js (node-eddystone-beacon using bleno) • Arduino (BLEPeripheral), using Nordic Semiconductor's nRF8001 or nR51822 https://github. com/google/eddystone/tree/master/eddyst one-uid/tools/txeddystone-uid
  14. 14. Some Bluetooth® Facts • Bluetooth / BLE is a wireless protocol • Bluetooth uses UHF radio waves in the ISM band from 2.4 to 2.485 GHz divided into channels with frequency hopping • Signal strength is an indicator for proximity (RSSI, received signal strength indicator) • BLE has reduced power consumption • Bluetooth SIG predicts more than 90% of Bluetooth-enabled smartphones will support the low energy standard by 2018.
  15. 15. Coding a Simple BLE Scanner
  16. 16. Prerequisites • Real device with BLE (emulator has no Bluetooth™ support) • Alternative emulator http: //stackoverflow. com/questions/20348743/blue tooth-low-energy-on-android- emulator/27712017 • Android 4.3 (Jelly Bean, API Level 18) • Android 4.4.4 (KitKat, API Level 19) fixes some issues (e.g. https://code.google. com/p/android/issues/detail? id=67272) • Android 5.0 (Lollipop, API Level 21) recommended due to some API changes (e.g. Advertisement and LE Scanner)
  17. 17. BLE Permissions for an App • <!– Allow any Bluetooth communication --> <uses-permission android:name="android.permission.BLUETOOTH"/> <!– Allow device discovery --> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> • <uses-feature android:name="android.hardware.bluetooth_le" android:required="true“ />
  18. 18. • • • • • •
  19. 19. public class MainActivity extends AppCompatActivity { // Declare Bluetooth adapter private BluetoothManager bluetoothManager; private BluetoothAdapter bluetoothAdapter;
  20. 20. public class MainActivity extends AppCompatActivity { // Declare Bluetooth adapter private BluetoothManager bluetoothManager; private BluetoothAdapter bluetoothAdapter;
  21. 21. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize Bluetooth adapter bluetoothManager = (BluetoothManager) getSystemService(Context. BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); …
  22. 22. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize Bluetooth adapter bluetoothManager = (BluetoothManager) getSystemService(Context. BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); …
  23. 23. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize Bluetooth adapter bluetoothManager = (BluetoothManager) getSystemService(Context. BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); …
  24. 24. bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { Log.d(TAG, "Device-Adress: " + device.getAddress()); Log.d(TAG, "RSSI: " + rssi); } });
  25. 25. bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { Log.d(TAG, "Device-Adress: " + device.getAddress()); Log.d(TAG, "RSSI: " + rssi); } });
  26. 26. bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { Log.d(TAG, "Device-Adress: " + device.getAddress()); Log.d(TAG, "RSSI: " + rssi); } });
  27. 27. bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { Log.d(TAG, "Device-Adress: " + device.getAddress()); Log.d(TAG, "RSSI: " + rssi); } });
  28. 28. bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { if(device.getAddress().equals("C1:4F:F1:FF:9B:90")) { Log.d(TAG, "Device-Adress: " + device.getAddress()); Log.d(TAG, "RSSI: " + rssi); } } });
  29. 29. bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { if(device.getAddress().equals("C1:4F:F1:FF:9B:90")) { Log.d(TAG, "Device-Adress: " + device.getAddress()); Log.d(TAG, "RSSI: " + rssi); } } });
  30. 30. Move away from deprecated Methods
  31. 31. bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); bluetoothLeScanner.startScan(new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); } });
  32. 32. bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); bluetoothLeScanner.startScan(new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); } });
  33. 33. bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); bluetoothLeScanner.startScan(new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); } });
  34. 34. bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); bluetoothLeScanner.startScan(new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); } });
  35. 35. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } });
  36. 36. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } });
  37. 37. ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); List<ScanFilter> filters = new ArrayList<>(); ScanFilter filter = new ScanFilter.Builder() .setDeviceAddress("C1:4F:F1:FF:9B:90") .build(); filters.add(filter);
  38. 38. ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); List<ScanFilter> filters = new ArrayList<>(); ScanFilter filter = new ScanFilter.Builder() .setDeviceAddress("C1:4F:F1:FF:9B:90") .build(); filters.add(filter);
  39. 39. ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); List<ScanFilter> filters = new ArrayList<>(); ScanFilter filter = new ScanFilter.Builder() .setDeviceAddress("C1:4F:F1:FF:9B:90") .build(); filters.add(filter);
  40. 40. ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); List<ScanFilter> filters = new ArrayList<>(); ScanFilter filter = new ScanFilter.Builder() .setDeviceAddress("C1:4F:F1:FF:9B:90") .build(); filters.add(filter);
  41. 41. ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); List<ScanFilter> filters = new ArrayList<>(); ScanFilter filter = new ScanFilter.Builder() .setDeviceAddress("C1:4F:F1:FF:9B:90") .build(); filters.add(filter);
  42. 42. Coding Proximity and Presence
  43. 43. There is only one packet format for BLE which
  44. 44. Payload consists of 2 Bytes Header, 6 Bytes Mac Address and up to 31 Bytes data.
  45. 45. Image: Google
  46. 46. Fixed: 02 01 06 03 03 aa fe Length: 15 Fixed: 16 aa fe Frame Type: 00 TX Power: ed Namespace: ed d1 eb ea c0 4e 5d ef a0 17 Instance: c5 61 2a 8c c2 53 ... 04 09 ... 45 53 54 03 03 Bat. Service: 0f 18 0e ... 16 0a 18 Mac: 53 c2 8c 2a 61 c5 ... 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  47. 47. Fixed: 02 01 06 03 03 aa fe Length: 11 Fixed: 16 aa fe Frame Type: 20 Version: 00 Volt: 0c 06 Temo: 13 00 Adv. Count: 00 0f 70 77 Sec. Count: 00 14 4e 70 ... 04 09 ... 45 53 54 03 03 Bat. Service: 0f 18 0e ... 16 0a 18 Mac: 53 c2 8c 2a 61 c5 ... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  48. 48. // The Eddystone Service UUID, 0xFEAA. private static final ParcelUuid EDDYSTONE_SERVICE_UUID = ParcelUuid.fromString("0000FEAA-0000-1000-8000- 00805F9B34FB"); // Eddystone frame types private static final byte TYPE_UID = 0x00; private static final byte TYPE_URL = 0x10; private static final byte TYPE_TLM = 0x20;
  49. 49. // The Eddystone Service UUID, 0xFEAA. private static final ParcelUuid EDDYSTONE_SERVICE_UUID = ParcelUuid.fromString("0000FEAA-0000-1000-8000- 00805F9B34FB"); // Eddystone frame types private static final byte TYPE_UID = 0x00; private static final byte TYPE_URL = 0x10; private static final byte TYPE_TLM = 0x20;
  50. 50. // The Eddystone Service UUID, 0xFEAA. private static final ParcelUuid EDDYSTONE_SERVICE_UUID = ParcelUuid.fromString("0000FEAA-0000-1000-8000- 00805F9B34FB"); // Eddystone frame types private static final byte TYPE_UID = 0x00; private static final byte TYPE_URL = 0x10; private static final byte TYPE_TLM = 0x20;
  51. 51. // The Eddystone Service UUID, 0xFEAA. private static final ParcelUuid EDDYSTONE_SERVICE_UUID = ParcelUuid.fromString("0000FEAA-0000-1000-8000- 00805F9B34FB"); // Eddystone frame types private static final byte TYPE_UID = 0x00; private static final byte TYPE_URL = 0x10; private static final byte TYPE_TLM = 0x20;
  52. 52. // The Eddystone Service UUID, 0xFEAA. private static final ParcelUuid EDDYSTONE_SERVICE_UUID = ParcelUuid.fromString("0000FEAA-0000-1000-8000- 00805F9B34FB"); // Eddystone frame types private static final byte TYPE_UID = 0x00; private static final byte TYPE_URL = 0x10; private static final byte TYPE_TLM = 0x20;
  53. 53. • • Image: Estimote
  54. 54. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  55. 55. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  56. 56. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  57. 57. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  58. 58. Fixed: 02 01 06 03 03 aa fe Length: 11 Fixed: 16 aa fe Frame Type: 20 Version: 00 Volt: 0c 06 Temo: 13 00 Adv. Count: 00 0f 70 77 Sec. Count: 00 14 4e 70 ... 04 09 ... 45 53 54 03 03 Bat. Service: 0f 18 0e ... 16 0a 18 Mac: 53 c2 8c 2a 61 c5 ... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  59. 59. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  60. 60. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  61. 61. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  62. 62. Outlook and helpers
  63. 63. , etc. http://on.google.com/hub/
  64. 64. • • • … • • • • • …
  65. 65. Image: https://commons.wikimedia.org/wiki/File:Zinkh%C3%BCtter_Hof_Messing_Werkzeuge.jpg

×