slides 535220160905 16896 1cb6wlx


3MB Größe 12 Downloads 299 Ansichten
Let’s get physical

grandcentrix.net @grandcentrix

+Albrecht Noll @UhrArt

+Pascal Welsch @passsy

Agenda ● Physical Web ● Beacons (iBeacon vs. Eddystone) ● Google Nearby API ● More about beacons

Physical Web ● ●



Idea: Walk up and use anything. What? ○ Open standard that everyone can use ○ No proactive notifications ○ Open Source ○ BLE energy efficient & widespread ○ Built on web and urls Why? ○ Context is king ○ Bridge digital and real world

physical-web.org

Physical Web - technical overview ●



● ●

Broadcast only approach ○ BLE broadcast the URL in the advertising packet ○ Sender does not know receiver Format ○ 16 bit Service-UUID and 0xFEAA ○ 0x10 Service-Data ○ Url shorteners are recommended Client ○ lists meta information to URL: title, description, url, favicon. Ranking ○ Signal strength ○

Later ranking algorithms based on user preference, spamming etc.

Physical Web - Chrome opt-in

Physical Web - examples Chromecast setup CHF Payment via Beacon (Twint) Vending Machines Museums: Audio guides Conference: Spaces links at Google I/O 16 ● Drones ● … everything ● ● ● ● ●

Beacons Estimote 30$/unit (10$) ● ● ●

● ● ● ●

iBeacon & Eddystone Configuration with Estimote App 41 months battery life ○ at 950ms ○ Tx=-12dBm = 15m Tx_min = - 30 dBm 1.5m TX_max = + 4 dBm 70m Accelerometer Thermometer

Beacon Prototyping ● ● ●

Beacon Toy (Find & Simulate) Node.js npmjs.com/package/eddystone-beacon Mac App github.com/dermike/electron-slide-beaco

Beacon Provisioning ● Claim beacon with the beacon manufacturer app via bluetooth ● Adjust interval ● Change protocol if support for multiple protocols ○ ○ ○

iBeacon Eddystone AltBeacon

● Change IDs

iBeacon vs. Eddystone ● ● ● ● ● ● 1A

iBeacon developed by Apple (2014) BLE beacons private deployment use-case only searched for by a specific app ̴ 100 ms interval (fixed) ̴ 31 bytes FF

... 16 bytes UUID

Major 2 bytes

Minor 2 bytes

Tx

iBeacon vs. Eddystone ● ● ● ● ●

...

Beacon protocol by Google (2015) ̴ 1-2 s (custom) open standard / open source (github.com/google/eddystone) private deployment Eddystone UID e.g. Service UID: 0000feaa-0000-1000-8000-00805f9b34fb Service Data: 00.df.edd1ebeac04e5defa017.e360c7526c00

FEAA

00

Tx

Namespace ID 10 bytes

Instance ID 6 bytes

iBeacon vs. Eddystone ●

...

Eddystone-URL: A compressed URL that, once parsed and decompressed, is directly usable by the client. FEAA

10

Tx

18 bytes URL

10.df.03.74776974746572.00.7568726172742f https://

twitter

.com/

uhrart/

iBeacon vs. Eddystone ●

● ...

Eddystone-TLM: Beacon status data that is useful for beacon fleet maintenance, and powers Google Proximity Beacon API's diagnostics endpoint. No identifying data FEAA

20

...

BATT

TEMP

AD_COUNT...

iBeacon vs. Eddystone ●



...

Eddystone-EID: A time-varying beacon frame that can be resolved to a stable identifier by a linked resolver, such as Proximity Beacon API. ○ Time rotating 8 byte values ○ Registered via Web Service ○ Web service resolves EIDs Secure or Private use-cases

FEAA

30 EID[0] 8 bytes

EID[1] 8 bytes

EID[2] 8 bytes

...

Manual Bluetooth // Eddystone service uid (0xfeaa) private static ParcelUuid UID_SERVICE = ParcelUuid .fromString("0000feaa-0000-1000-8000-00805f9b34fb"); // namespace filter private static final byte[] NAMESPACE_FILTER = {}; /*0x0000d89bed6e130ee5cf1ba1000000000000*/; // namespace filter private static final byte[] NAMESPACE_FILTER_MASK = {}; /*0xff00ffffffffffffffffffff000000000000*/

Manual Bluetooth ScanFilter beaconfilter = new ScanFilter.Builder() .setServiceUuid(UID_SERVICE) .setServiceData(UID_SERVICE, NAMESPACE_FILTER, NAMESPACE_FILTER_MASK) .build(); List filters = Collections.singletonList(beaconfilter); ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build();

Manual Bluetooth BluetoothManager manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE); mScanner = manager.getAdapter().getBluetoothLeScanner(); mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord() .getServiceData(UID_SERIVCE); } }; mScanner.startScan(filters, settings, mScanCallback);

Beacons Dashboard ● ● ●

● ●

Register beacons to Google API project Use Eddystone UUID Attach information ○ Key-value pairs ○ Messages ○ Notifications* (Not ready yet) Disable Beacons Decommission Beacons (Be careful!)

Google Nearby Connect devices which are close to each other No manual pairing between users required Google Play Services required and an internet connection

Nearby Messages

Google Play Services e37c2

- broadcast messages publish() - subscribe to broadcasted messages subscribe()

e37c2

Hello World e37c2

Hello World Hello World e37c2

- Internet connection required

Hello World

e37c2

Benefits of a server connection ● Messages are smaller for Bluetooth and sound transmission ● Security, data can only be read by your app ○

Server-side validation (device pairing code & app API token)



Everybody is able to read the pairing codes but not the actual message

Let’s implement Nearby Messages...

Google API client @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(Nearby.MESSAGES_API) .addConnectionCallbacks(this) .enableAutoManage(this, this) .build(); }

Publish Nearby.Messages.publish(mGooglePlayClient, message, options) .setResultCallback { status: Status -> if (status.isSuccess) { Timber.v("Published successfully") Do not Make error } else { forget codes readable val code = status.statusCode val statusName = NearbyMessagesStatusCodes .getStatusCodeString(code) Timber.v("publish status: $statusName ($code)") }

}

// publish status: FORBIDDEN (2806)

Publish Message ● Message can be anything (plain text, JSON, Flatbuffers, ...) ● up to 100KB (recommended 4KB) ● Sending the same message twice doesn’t work when both messages are alive val message = Message("Hello Droidcon".toByteArray())

Subscribe

Called for every message

Nearby.Messages.subscribe(gClient, messageListener, options) .setResultCallback { status: Status -> if (status.isSuccess) { Timber.v("Subscribed to Nearby Messages") } else { val code = status.statusCode val statusName = NearbyMessagesStatusCodes .getStatusCodeString(code) Timber.v("subscribe status: $statusName ($code)") } }

Message Listener val messageListener = object : MessageListener() { override fun onFound(message: Message?) { Timber.d("found $message") }

}

override fun onLost(message: Message?) { Timber.d("lost $message") } onLost is optional, don’t forget it

Subscribe/Publish Options Nearby.Messages .subscribe(mGooglePlayClient, messageListener, options) Nearby.Messages .publish(mGooglePlayClient, message, options)

Options are created with builders. A lot of them...

Subscribe/Publish Options ● Discovery Method = {DEFAULT, SCAN, BROADCAST} ● Distance = {DEFAULT, EARSHOT} ● Time to Live = {seconds} ○