Physical Web FatBeacons

I’ve been playing with Eddystone beacons (A Open BLE beacon technology backed by Google) for a while. Combined with things like WebBluetooth they make for a really nice way to interact with physical object from mobile devices.

Physical Web Logo

Recently there has been a suggested extension to the Physical Web specification to include something called a FatBeacon. A FatBeacon is one that rather than advertising a URL to load a web page from it actually hosts the web page on the device and services it up from the BLE characteristic. This means that it becomes possible to interact with a device when there is no network back haul to load the page.

This may sounds a little strange in the western world where cellular coverage is ubiquitous, but there are places where coverage is still spotty and it also allows for totally self contained solutions. For simple things like my Physical Web Light Switch this would work well.

A request went up on the Physical Web GitHub page asking if anybody wanted to have a go at implementing a software stack to allow people to have a play with the concept so I threw my hat into the ring to have a go.

My first thought was to make use of Sandeep Mistry‘s bleno library and I ran up a simple characteristic to serve up the HTML.

var bleno = require('bleno');
var util = require('util');

var html = "<html>" + 
			"<head>" +
			 "<title>Fat Beacon Demo</title>" +
			 "<meta name='description' content='FatBeacon Demo'/>" +
			"</head>" + 
			"<body>" +
			 "<h1>HelloWorld</h1>" +
                         "This is a test" +
			"</body>" + 
		   "</html>";

function HTMLCharacteristic() {
	bleno.Characteristic.call(this, {
		uuid: 'd1a517f0249946ca9ccc809bc1c966fa',
		properties: ['read'],
		descriptors: [
			new bleno.Descriptor({
				uuid: '2901',
				value: 'HTML'
			})
		]
	});
}

util.inherits(HTMLCharacteristic,bleno.Characteristic);

HTMLCharacteristic.prototype.onReadRequest = function(offset, callback) {
	console.log("read request");
	var buf = new Buffer(html, 'utf8');
	if (offset < buf.length) {
		var slice = buf.slice(offset);
		callback(this.RESULT_SUCCESS, slice);
	} else {
		//problem
	}

}

module.exports = HTMLCharacteristic;

I wrapped this in a simple service but I had missed the need to put the right bits in the advertisement packet, luckily Jacob Rosenthal spotted what needed doing and ported my code over to Don Coleman‘s node-eddystone-beacon project.

After a couple of tweaks I now have it all working (on Linux, iirc there are some limitation on OSx that mean you can’t connect to services with bleno). My code is available on GitHub here and I will be submitting a pull request to Don to get it included in the node-eddystone-beacon project soon.

The beacon shows up like this in the Physical Web android app

FatBeacon in Physical Web App

Which when loaded looks like this:

FatBeacon page

There are some interesting issues around security to be looked at but it’s still an interesting area.

2 thoughts on “Physical Web FatBeacons”

  1. Hello Ben,

    First of all thanks for your works and your code.

    I’ve a little problem on it because my phone, the Physical Web application doesn’t see the beacon provided by your service.

    If i use another tool like Beacon Toy, it’s ok but it’s just a sniffer on BLE beacon.

    Do you have an idea what to do ?

    Just in case, FatBeacon and physical Web are activated on Chrome parameters.

    Thx.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.