Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connecting to a device using the chrome.bluetooth API

I have been trying to create a Chrome App that uses the chrome.bluetooth API to connect to and communicate with the Texas Instruments CC2541 SensorTag device.

The code here detects the SensorTag and gets the device information, but the 'getProfiles' and 'getServices' methods called on the device both return empty, and the 'connect' method gives the error 'Profile not found: invalid uuid'.

I have tried multiple variations of UUIDs taken from the example SensorTag Android app (as can be seen in the code), but all give the same 'invalid uuid' error.

Even if you can't fix this particular problem it would be good to hear from anyone who has had any joy using the chrome.bluetooth API at all. My experience so far is that it is too much of a moving target to really use (yes, I do know it is 'Dev' only...), but I'd really like to get it working if possible.

Thanks for looking - any help or ideas much appreciated!

EDIT : Additional platform information
I first tried running this on Windows 7 with a CSR 4.0 Bluetooth dongle but this turns out to be completely futile: with the generic Windows 7 BT Driver Chrome can see the adapter and detect BT devices, but the driver doesn't support Low Energy so can't detect the device I want it to. Using the CSR Driver, which does support LE and which I can use in Windows "Bluetooth Devices" to connect to LE devices, Chrome.bluetooth cannot detect the Bluetooth adapter at all.

So now I'm working with an Acer C720 Chromebook, which looks like it should work, but I just get the "Invalid UUID" message whatever I try.

(Although the Chrome OS and Win/Mac/Linux 'Dev' versions of Chrome are out of step with updates - Chrome OS was behind the others for a while but has now caught up - so for a time required different format 'manifest.json' files to launch the app on the different platforms.)

main.js

// I have tried multiple variations of known UUIDS for device... all give "Profile not found: invalid uuid" 
var profiles = [
             // UUID_IRT_SERV from example Android app
                {uuid : 'f000aa00-0451-4000-b000-000000000000', name : 'SensorTag1-lc'},
                {uuid : 'F000AA00-0451-4000-B000-000000000000', name : 'SensorTag1-uc'},
                {uuid : 'f000aa00', name : 'SensorTag1-shortlc'},
                {uuid : 'F000AA00', name : 'SensorTag1-shortuc'},
             // UUID_IRT_DATA from example Android app
                {uuid : 'f000aa01-0451-4000-b000-000000000000', name : 'SensorTag2-lc'},
                {uuid : 'F000AA01-0451-4000-B000-000000000000', name : 'SensorTag2-uc'},
                {uuid : 'f000aa01', name : 'SensorTag2-shortlc'},
                {uuid : 'F000AA01', name : 'SensorTag2-shortuc'},
             // UUID_IRT_CONF from example Android app
                {uuid : 'f000aa02-0451-4000-b000-000000000000', name : 'SensorTag3-lc'},
                {uuid : 'F000AA02-0451-4000-B000-000000000000', name : 'SensorTag3-uc'},
                {uuid : 'f000aa02', name : 'SensorTag3-shortlc'},
                {uuid : 'F000AA02', name : 'SensorTag3-shortuc'},
             // UUID_IRT_PERI from example Android app
                {uuid : 'f000aa03-0451-4000-b000-000000000000', name : 'SensorTag4-lc'},
                {uuid : 'F000AA03-0451-4000-B000-000000000000', name : 'SensorTag4-uc'},
                {uuid : 'f000aa03', name : 'SensorTag4-shortlc'},
                {uuid : 'F000AA03', name : 'SensorTag4-shortuc'},
             // UUID_KEY_SERV from example Android app
                {uuid : '0000ffe0-0000-1000-8000-00805f9b34fb', name : 'SensorTag5-lc'},
                {uuid : '0000FFE0-0000-1000-8000-00805F9B34FB', name : 'SensorTag5-uc'},
                {uuid : '0000ffe0', name : 'SensorTag5-shortlc'},
                {uuid : '0000FFE0', name : 'SensorTag5-shortuc'},
             // UUID_KEY_DATA from example Android app
                {uuid : '0000ffe1-0000-1000-8000-00805f9b34fb', name : 'SensorTag6-lc'},
                {uuid : '0000FFE1-0000-1000-8000-00805F9B34FB', name : 'SensorTag6-uc'},
                {uuid : '0000ffe1', name : 'SensorTag6-shortlc'},
                {uuid : '0000FFE1', name : 'SensorTag6-shortuc'},
];

// Listener to deal with initial connection
chrome.bluetooth.onConnection.addListener(onConnected);

// onAdapterStateChanged callback - for debug only
chrome.bluetooth.onAdapterStateChanged.addListener(function(newStatus) {
    log('onAdapterStateChanged: ' + JSON.stringify(arguments));
});

// Logs debug messages to app window
function log(msg) {
  var msg_str = (typeof(msg) == 'object') ? JSON.stringify(msg) : msg;
  console.log(msg_str);
  var l = document.getElementById('log');
  if (l) {
    l.innerText += msg_str + '\n';
  }
}

// Function that is called on connection to device
var onConnected = function(socket) {
    log("Success - Connected to SensorTag!");
    log("Socket: " + JSON.stringify(socket));
}

function recordDevice(device) {
    log("Found BT Device: " + JSON.stringify(device));
    if (device.name == "SensorTag") {
        log("Got SensorTag...");
        // Stop discovery and then connect to SensorTag
        chrome.bluetooth.stopDiscovery(connectToSensorTag(device));
    }
}

function connectToSensorTag(device) {
    log("Getting profiles of SensorTag...");
    chrome.bluetooth.getProfiles({device: device}, function(profiles) { 
        log('Got profiles: ' + JSON.stringify(profiles));
    });
    chrome.bluetooth.getServices({deviceAddress: device.address}, function(services) { 
        log('Got services: ' + JSON.stringify(services));
    });
    for (var i = 0; i < profiles.length; i++) {
        chrome.bluetooth.connect({ device: device, profile: profiles[i] }, function() {
            log('Connect called: ' + JSON.stringify(arguments));
            if (chrome.runtime.lastError) {
                  log("Connection error: " + chrome.runtime.lastError.message);
            }
        });
    }
}

function findDevices() {
    log("Finding devices...");
    chrome.bluetooth.startDiscovery({deviceCallback: recordDevice});
}

// App execution begins here.
// Add all profiles to try connection later
for (var i = 0; i < profiles.length; i++) {
    log("Adding profile: " + profiles[i]);
    chrome.bluetooth.addProfile(profiles[i], function() {
        log("SensorTag profile added."));
    });
}

chrome.bluetooth.getAdapterState( function(result) {
      if (result.powered == false || result.available == false ) {
        log("Error: No bluetooth adapter available.");
      } else {
        log("Bluetooth adapter enabled.");
        findDevices();
      }   
});

index.html

<html>
<head></head>
<body>
    <div id="log"></div>
</body>
<script src="main.js"></script>
</html>

manifest.json

{
  "manifest_version": 2,
  "name": "Connect to SensorTag",
  "description": "Connects to TI SensorTag",
  "version": "1.0",
  "minimum_chrome_version": "30",
  "app": {
    "background": {
      "scripts": ["background.js"]
    }
  },
  "bluetooth": {}
}

background.js

chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('index.html', {
    id: "window1",
    bounds: {
      width: 640,
      height: 480
    }
  });
});
like image 776
Kev K Avatar asked Feb 21 '14 16:02

Kev K


People also ask

What is API in Bluetooth?

These APIs let apps connect to other Bluetooth devices, enabling point-to-point and multipoint wireless features. Using the Bluetooth APIs, an app can perform the following: Scan for other Bluetooth devices. Query the local Bluetooth adapter for paired Bluetooth devices. Establish RFCOMM channels.

How do I connect my Bluetooth device?

Make sure Bluetooth is turned on. Touch and hold Bluetooth . In the list of paired devices, tap a paired but unconnected device. When your phone and the Bluetooth device are connected, the device shows as "Connected."

Why is my Chrome Bluetooth not working?

Fix Bluetooth problemsCheck for system updates. If any updates are available, install them. Turn Bluetooth off, then back on. Turn your Chromebook off, then back on.


2 Answers

I ran into this same problem. After a fair bit of digging I was able to pin down two issues with the pattern I was using.

The first issue is that it turns out, from what I can tell, an empty "bluetooth" object in the manifest is not actually valid despite the fact that there are examples around that use it and chrome does not complain:

"bluetooth": {}

Rather your bluetooth manifest entry should look something like this:

"bluetooth":{
"profiles":
    [
        "00001101-0000-1000-8000-00805f9b34fb" // array of uuids
    ]
},

The documentation for this, such that it is, can be found in this chrome commit from two weeks ago: https://codereview.chromium.org/145663004/patch/760001/770016

The other idiosyncrasy of this API that I discovered while tracking this issue down is that it is not only the connect call that can leave errors in "chrome.runtime.lastError", any of these calls may leave messages behind for you. If you check lastError after your addProfile call, you will likely see chrome complain about permissions: "Permission to add profile denied."

Going back and reading the chrome.bluetooth api documentation it actually says this in the description near the top (although I missed it just like you did)

Use the chrome.bluetooth API to connect to a Bluetooth device. All functions report failures via chrome.runtime.lastError.

(emphasis added) http://developer.chrome.com/apps/bluetooth#type-Profile

Hope this helps.

like image 96
Jesse S Avatar answered Oct 10 '22 02:10

Jesse S


The CSR tag you're using is a Low Energy device? In that case you'd want to use the chrome.bluetoothLowEnergy API instead: https://developer.chrome.com/apps/bluetoothLowEnergy

For an example see: https://github.com/armansito/ble-battery-service-demo/blob/master/script.js

like image 42
Scott James Remnant Avatar answered Oct 10 '22 03:10

Scott James Remnant