Eddystone beacons demo

69
Eddystone Beacons Demo Lecture on Eddystone, an open Bluetooth Smart Beacon format from Google +Angelo Rüggeberg @s3xy4ngyc

Transcript of Eddystone beacons demo

Page 1: Eddystone beacons demo

Eddystone Beacons DemoLecture on Eddystone, an open Bluetooth Smart Beacon format from Google

+Angelo Rüggeberg@s3xy4ngyc

Page 2: Eddystone beacons demo

agenda- Introductions to Beacons

- Introduction to Eddystone

- Coding Session

Page 3: Eddystone beacons demo

Introduction to Beacons

Page 4: Eddystone beacons demo

Image: Google

Context orexact Location

Page 5: Eddystone beacons demo

Location, Accuracy, Range, and alike

Image: Google…

Page 6: Eddystone beacons demo

Use Cases

Image: Estimote

Page 7: Eddystone beacons demo

Opportunities

Presence (e.g. sights)

Image: Google

Page 8: Eddystone beacons demo

Opportunities

Tracking and Securing

Image: Google

Page 9: Eddystone beacons demo

Opportunities

• Contextual fencing(aka Geo-fence)

• Contextual content(e.g. reader circle)

• …

Image: Bundesarchiv

Page 10: Eddystone beacons demo

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/master/branding

Page 11: Eddystone beacons demo

Introduction to Eddystone

Page 12: Eddystone beacons demo

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

Page 14: Eddystone beacons demo

HardwarePhones 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/eddystone-uid/tools/txeddystone-uid

Page 15: Eddystone beacons demo

Some Bluetooth® Facts

• Bluetooth / BLEis 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.

Page 16: Eddystone beacons demo
Page 17: Eddystone beacons demo
Page 18: Eddystone beacons demo

Coding a Simple BLE Scanner

Page 20: Eddystone beacons demo

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“

/>

Page 22: Eddystone beacons demo

public class MainActivity extends AppCompatActivity {

// Declare Bluetooth adapter private BluetoothManager bluetoothManager; private BluetoothAdapter bluetoothAdapter;

Page 23: Eddystone beacons demo

public class MainActivity extends AppCompatActivity {

// Declare Bluetooth adapter private BluetoothManager bluetoothManager; private BluetoothAdapter bluetoothAdapter;

Page 24: Eddystone beacons demo

@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

// Initialize Bluetooth adapter bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); …

Page 25: Eddystone beacons demo

@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

// Initialize Bluetooth adapter bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); …

Page 26: Eddystone beacons demo

@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

// Initialize Bluetooth adapter bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); …

Page 27: Eddystone beacons demo

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); }});

Page 28: Eddystone beacons demo

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); }});

Page 29: Eddystone beacons demo

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); }});

Page 30: Eddystone beacons demo

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); }});

Page 31: Eddystone beacons demo

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); } }});

Page 32: Eddystone beacons demo

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); } }});

Page 33: Eddystone beacons demo

Move away from deprecated Methods

Page 34: Eddystone beacons demo

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); }});

Page 35: Eddystone beacons demo

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); }});

Page 36: Eddystone beacons demo

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); }});

Page 37: Eddystone beacons demo

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); }});

Page 38: Eddystone beacons demo

bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); }});

Page 39: Eddystone beacons demo

bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); }});

Page 40: Eddystone beacons demo

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);

Page 41: Eddystone beacons demo

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);

Page 42: Eddystone beacons demo

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);

Page 43: Eddystone beacons demo

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);

Page 44: Eddystone beacons demo

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);

Page 46: Eddystone beacons demo

Coding Proximity and Presence

Page 47: Eddystone beacons demo

There is only one packet format for BLE which

Page 48: Eddystone beacons demo

Payload consists of 2 Bytes Header, 6 Bytes Mac Address and up to 31 Bytes data.

Page 49: Eddystone beacons demo

Image: Google

Page 50: Eddystone beacons demo

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

Page 51: Eddystone beacons demo

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

Page 52: Eddystone beacons demo

// 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;

Page 53: Eddystone beacons demo

// 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;

Page 54: Eddystone beacons demo

// 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;

Page 55: Eddystone beacons demo

// 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;

Page 56: Eddystone beacons demo

// 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;

Page 57: Eddystone beacons demo

••

Image: Estimote

Page 58: Eddystone beacons demo

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)); }});

Page 59: Eddystone beacons demo

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)); }});

Page 60: Eddystone beacons demo

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)); }});

Page 61: Eddystone beacons demo

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)); }});

Page 62: Eddystone beacons demo

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

Page 63: Eddystone beacons demo

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)); }});

Page 64: Eddystone beacons demo

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)); }});

Page 65: Eddystone beacons demo

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)); }});

Page 66: Eddystone beacons demo

Outlook and helpers

Page 67: Eddystone beacons demo

, etc.http://on.google.com/hub/

Page 69: Eddystone beacons demo

Image: https://commons.wikimedia.org/wiki/File:Zinkh%C3%BCtter_Hof_Messing_Werkzeuge.jpg