Using the Web Bluetooth API

This article needs a technical review. How you can help.

Draft
This page is not complete.

Non-standard
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

This API is available on Firefox OS for internal applications only.

The WebBluetooth API is a Firefox OS-only API created to allow control of a device's low-level Bluetooth functionality via JavaScript. This article explains the basics of how to use the API in a Firefox OS app.

Permissions

Certified/internal applications that want to use the Web Bluetooth API must request the relevant permission within their app manifest.

"permission": {
  "bluetooth":{}
}

It is also recommended to ask for the settings permission, because currently, enabling and disabling Bluetooth has to be done by changing the value of a navigator.mozSettings setting named "bluetooth.enabled". The code to accomplish this would look something like this:

var lock = navigator.mozSettings.createLock();
var lockCompleteReq = lock.set({
  'bluetooth.enabled': true
});

result.onsuccess = function() {
  /* do what you need to do now that Bluetooth is on */
}

result.onerror = function() {
  /* deal with the error; Bluetooth was not enabled successfully */
}

Pairing Bluetooth devices

The most important step when dealing with a Bluetooth environment is pairing devices to build a secure Bluetooth micro-network. Pairing is a procedure by which two Bluetooth devices come to share a common "key", called the "Link Key". After two devices have been paired, it is possible to set up more advanced connections, using profiles to access specific features of the devices.

The pairing procedure depends on the I/O capabilities of each device.

Each time a remote device wants to be paired with a Firefox OS device, a system message called bluetooth-pairing-request is sent. To intercept that system message, the application in charge of handling the pairing must register the message within its application manifest:

"messages": [
  { "bluetooth-pairing-request": "/pairing.html" }
]

It must also register a message handler for that message:

navigator.mozSetMessageHandler("bluetooth-pairing-request", function (message) {
  // Get the information about the pairing request
  var request = message.detail;

  // Handle the pairing request. For this simple example, we're just logging
  // the name of the remote device that wants to be paired with your device

  console.log(request.name);
});

The message's detail property contains all the information needed to start pairing the two devices:

  • address: The address of the remote device on the Bluetooth micro-network (see: BluetoothDevice.address).
  • name   : The name of the remote device (see: BluetoothDevice.name).
  • icon   : An icon name to use (see: BluetoothDevice.icon).
  • passkey: A pass key the user has to type if the remote device is an input device.
  • method : The pairing method to use, one of confirmation, pincode or passkey.

Finalizing the pairing request depends on the specified method. Each method provides a mechanism for ensuring that both devices are controlled by the same user, to prevent unauthorized usage.

confirmation
Both devices display a 6-digit number on their screens; the user must confirm that both devices show the same number to initiate the connection.
pincode
The remote device does not have a screen (for example, it might be a headset or a mouse). The device's manufacturer provides a PIN code which must be entered on the other device to complete pairing.
passkey
If the remote device is a text input device (such as a keyboard), a 6-digit number may be shown, and the user must enter the key using that remote device.

So an application managing pairing must handle three different pairing methods. To send the user answer to the remote device, the Bluetooth API provides the following methods: BluetoothAdapter.setPairingConfirmation(), BluetoothAdapter.setPinCode(), and BluetoothAdapter.setPasskey()

var adapter;

// Retreving the local device adapter is asynchronous, handle this carefully.
navigator.mozBluetooth.getDefaultAdapter().success = function(evt) {
  adapter = evt.target.result;
}

function onPairing(message) {
  var reponse,
      request = message.detail,
      passkey = request.passkey;

  switch (request.method) {
    case 'confirmation':
      // Make sure the passkey is a string
      passkey = String(passkey);
      // Make sure the string is 6 characters long (pad with 0 if necessary)
      passkey = (new Array((6 - passkey.length) + 1)).join('0') + passkey;
      // Let's prompt the user
      response = confirm('Is that same number visible on the remote device screen: ' + passkey)
      // Let's send the confirmation
      adapter.setPairingConfirmation(request.address, response);
      break;

    case 'pincode':
      // Let's prompt the user
      response = prompt('Thanks to provide the remote device PIN code');
      // Let's send the pin code
      adapter.setPinCode(request.address, response);
      break;

    case 'passkey':
      // Let's prompt the user
      response = alert('Thanks to type the following code on the remote device');
      // Let's send back the passkey
      adapter.setPasskey(request.address, response);
      break;
  }
}

navigator.mozSetMessageHandler("bluetooth-pairing-request", onPairing);

When the pairing operation is complete on both sides, the application is notified of the success or failure of the operation through the pairedstatuschanged event where the callback handler is getting a BluetoothStatusChangedEvent.

adapter.onpairedstatuschanged = function (evt) {
  if (evt.status) {
    alert("The pairing operation has been successfully completed");
  } else {
    alert("The pairing operation has failed. Please, try again");
  }
}

Document Tags and Contributors

 Contributors to this page: chrisdavidmills, rolfedh
 Last updated by: chrisdavidmills,