OLD | NEW |
1 <h1>Bluetooth</h1> | 1 <h1>Bluetooth</h1> |
2 | 2 |
3 <p> | 3 <p> |
4 This document describes how to use the <a href="bluetooth.html">Bluetooth | 4 This document describes how to use the <a href="bluetooth.html">Bluetooth</a>, |
5 API</a> to communicate with Bluetooth and Bluetooth Low Energy devices. | 5 <a href="bluetoothSocket.html">Bluetooth Socket</a> and |
| 6 <a href="bluetoothLowEnergy.html">Bluetooth Low Energy</a> APIs to |
| 7 communicate with Bluetooth and Bluetooth Low Energy devices. |
6 </p> | 8 </p> |
7 | 9 |
8 <p> | 10 <p> |
9 For background information about Bluetooth, see the official | 11 For background information about Bluetooth, see the official |
10 <a href="http://www.bluetooth.org">Bluetooth specifications</a>. | 12 <a href="http://www.bluetooth.org">Bluetooth specifications</a>. |
11 </p> | 13 </p> |
12 | 14 |
13 <h2 id="manifest">Manifest requirements</h2> | 15 <h2 id="manifest">Manifest requirements</h2> |
14 | 16 |
15 <p> | 17 <p> |
16 For Chrome Apps that use Bluetooth, add the | 18 For Chrome Apps that use Bluetooth, add the |
17 <a href="manifest/bluetooth.html">bluetooth</a> entry to the manifest | 19 <a href="manifest/bluetooth.html">bluetooth</a> entry to the manifest |
18 and specify, if appropriate, the UUIDs of profiles, protocols or services | 20 and specify, if appropriate, the UUIDs of profiles, protocols or services |
19 you wish to implement. | 21 you wish to implement. |
20 For example: | 22 For example: |
21 </p> | 23 </p> |
22 | 24 |
23 <pre data-filename="manifest.json"> | 25 <pre data-filename="manifest.json"> |
24 "bluetooth": { | 26 "bluetooth": { |
25 "uuids": [ "1105", "1106" ] | 27 "uuids": [ "1105", "1106" ] |
26 } | 28 } |
27 </pre> | 29 </pre> |
28 | 30 |
29 <p> | 31 <p> |
30 To only access adapter state, discover nearby devices, and obtain basic | 32 To only access adapter state, discover nearby devices, and obtain basic |
31 information about devices, omit the <code>uuids</code> list. | 33 information about devices, omit the <code>uuids</code> list. |
32 </p> | 34 </p> |
33 | 35 |
34 <h2 id="adapter_state">Obtaining adapter state</h2> | 36 <h2 id="adapter_info">Adapter information</h2> |
| 37 |
| 38 <h3 id="adapter_state">Obtaining adapter state</h3> |
35 | 39 |
36 <p> | 40 <p> |
37 To obtain the state of the Bluetooth adapter, use the | 41 To obtain the state of the Bluetooth adapter, use the |
38 <code>chrome.bluetooth.getAdapterState</code> method: | 42 $(ref:bluetooth.getAdapterState) method: |
39 </p> | 43 </p> |
40 | 44 |
41 <pre> | 45 <pre> |
42 chrome.bluetooth.getAdapterState(function(adapter) { | 46 chrome.bluetooth.getAdapterState(function(adapter) { |
43 console.log("Adapter " + adapter.address + ": " + adapter.name); | 47 console.log("Adapter " + adapter.address + ": " + adapter.name); |
44 }); | 48 }); |
45 </pre> | 49 </pre> |
46 | 50 |
| 51 <h3 id="adapter_notifications">Adapter notifications</h3> |
| 52 |
47 <p> | 53 <p> |
48 The <code>chrome.bluetooth.onAdapterStateChanged</code> event is sent | 54 The $(ref:bluetooth.onAdapterStateChanged) event is sent |
49 whenever this state changes. This can be used, for example, to determine when | 55 whenever the adapter state changes. This can be used, for example, to |
50 the adapter radio is powered on or off. | 56 determine when the adapter radio is powered on or off. |
51 </p> | 57 </p> |
52 | 58 |
53 <pre> | 59 <pre> |
54 var powered = false; | 60 var powered = false; |
55 chrome.bluetooth.getAdapterState(function(adapter) { | 61 chrome.bluetooth.getAdapterState(function(adapter) { |
56 powered = adapter.powered; | 62 powered = adapter.powered; |
57 }); | 63 }); |
58 | 64 |
59 chrome.bluetooth.onAdapterStateChanged.addListener( | 65 chrome.bluetooth.onAdapterStateChanged.addListener( |
60 function(adapter) { | 66 function(adapter) { |
61 if (adapter.powered != powered) { | 67 if (adapter.powered != powered) { |
62 powered = adapter.powered; | 68 powered = adapter.powered; |
63 if (powered) { | 69 if (powered) { |
64 console.log("Adapter radio is on"); | 70 console.log("Adapter radio is on"); |
65 } else { | 71 } else { |
66 console.log("Adapter radio is off"); | 72 console.log("Adapter radio is off"); |
67 } | 73 } |
68 } | 74 } |
69 }); | 75 }); |
70 </pre> | 76 </pre> |
71 | 77 |
72 <h2 id="listing_devices">Listing known devices</h2> | 78 <h2 id="device_info">Device information</h2> |
| 79 |
| 80 <h3 id="listing_devices">Listing known devices</h3> |
73 | 81 |
74 <p> | 82 <p> |
75 To get a list of the devices known to the Bluetooth adapter, use the | 83 To get a list of the devices known to the Bluetooth adapter, use the |
76 <code>chrome.bluetooth.getDevices</code> method: | 84 $(ref:bluetooth.getDevices) method: |
77 </p> | 85 </p> |
78 | 86 |
79 <pre> | 87 <pre> |
80 chrome.bluetooth.getDevices(function(devices) { | 88 chrome.bluetooth.getDevices(function(devices) { |
81 for (var i = 0; i < devices.length; i++) { | 89 for (var i = 0; i < devices.length; i++) { |
82 console.log(devices[i].address); | 90 console.log(devices[i].address); |
83 } | 91 } |
84 }); | 92 }); |
85 </pre> | 93 </pre> |
86 | 94 |
87 <p> | 95 <p> |
88 All devices are returned, including paired devices and devices recently | 96 All devices are returned, including paired devices and devices recently |
89 discovered. It will not begin discovery of new devices (see | 97 discovered. It will not begin discovery of new devices (see |
90 <a href="#discovery">Discovering nearby devices</a>). | 98 <a href="#discovery">Discovering nearby devices</a>). |
91 </p> | 99 </p> |
92 | 100 |
93 <h2 id="device_notifications">Receiving device notifications</h2> | 101 <h3 id="device_notifications">Receiving device notifications</h3> |
94 | 102 |
95 <p> | 103 <p> |
96 Instead of repeatedly calling <code>chrome.bluetooth.getDevices</code>, you | 104 Instead of repeatedly calling $(ref:bluetooth.getDevices), you |
97 can use the <code>chrome.bluetooth.onDeviceAdded</code>, | 105 can use the $(ref:bluetooth.onDeviceAdded), $(ref:bluetooth.onDeviceChanged) |
98 <code>chrome.bluetooth.onDeviceChanged</code> and | 106 and $(ref:bluetooth.onDeviceRemoved) events to receive notifications. |
99 <code>chrome.bluetooth.onDeviceRemoved</code> events to receive notifications. | |
100 </p> | 107 </p> |
101 | 108 |
102 <p> | 109 <p> |
103 The <code>chrome.bluetooth.onDeviceAdded</code> event is sent whenever a | 110 The $(ref:bluetooth.onDeviceAdded) event is sent whenever a |
104 device is discovered by the adapter or makes a connection to the adapter: | 111 device is discovered by the adapter or makes a connection to the adapter: |
105 </p> | 112 </p> |
106 | 113 |
107 <pre> | 114 <pre> |
108 chrome.bluetooth.onDeviceAdded.addListener(function(device) { | 115 chrome.bluetooth.onDeviceAdded.addListener(function(device) { |
109 console.log(device.address); | 116 console.log(device.address); |
110 }); | 117 }); |
111 </pre> | 118 </pre> |
112 | 119 |
113 <p> | 120 <p> |
114 Adding a listener for this event does not begin discovery of devices | 121 Adding a listener for this event does not begin discovery of devices |
115 (see <a href="#discovery">Discovering nearby devices</a>). | 122 (see <a href="#discovery">Discovering nearby devices</a>). |
116 </p> | 123 </p> |
117 | 124 |
118 <p> | 125 <p> |
119 Changes to devices, including previously discovered devices becoming paired, | 126 Changes to devices, including previously discovered devices becoming paired, |
120 are notified by the <code>chrome.bluetooth.onDeviceChanged</code> event: | 127 are notified by the $(ref:bluetooth.onDeviceChanged) event: |
121 </p> | 128 </p> |
122 | 129 |
123 <pre> | 130 <pre> |
124 chrome.bluetooth.onDeviceChanged.addListener(function(device) { | 131 chrome.bluetooth.onDeviceChanged.addListener(function(device) { |
125 console.log(device.address); | 132 console.log(device.address); |
126 }); | 133 }); |
127 </pre> | 134 </pre> |
128 | 135 |
129 <p> | 136 <p> |
130 Finally the <code>chrome.bluetooth.onDeviceRemoved</code> event is sent | 137 Finally the $(ref:bluetooth.onDeviceRemoved) event is sent |
131 whenever a paired device is removed from the system, or a discovered device | 138 whenever a paired device is removed from the system, or a discovered device |
132 has not been seen recently: | 139 has not been seen recently: |
133 </p> | 140 </p> |
134 | 141 |
135 <pre> | 142 <pre> |
136 chrome.bluetooth.onDeviceRemoved.addListener(function(device) { | 143 chrome.bluetooth.onDeviceRemoved.addListener(function(device) { |
137 console.log(device.address); | 144 console.log(device.address); |
138 }); | 145 }); |
139 </pre> | 146 </pre> |
140 | 147 |
141 <h2 id="discovery">Discovering nearby devices</h2> | 148 <h3 id="discovery">Discovering nearby devices</h3> |
142 | 149 |
143 <p> | 150 <p> |
144 To begin discovery of nearby devices, use the | 151 To begin discovery of nearby devices, use the |
145 <code>chrome.bluetooth.startDiscovery</code> method. Discovery can be | 152 $(ref:bluetooth.startDiscovery) method. Discovery can be resource intensive |
146 resource intensive so you should call | 153 so you should call $(ref:bluetooth.stopDiscovery) when done. |
147 <code>chrome.bluetooth.stopDiscovery</code> when done. | |
148 </p> | 154 </p> |
149 | 155 |
150 <p> | 156 <p> |
151 You should call <code>chrome.bletooth.startDiscovery</code> whenever your | 157 You should call $(ref:bluetooth.startDiscovery) whenever your |
152 app needs to discover nearby devices. Do not check the | 158 app needs to discover nearby devices. Do not check the |
153 <code>discovering</code> property of <code>AdapterState</code>. The call | 159 <code>discovering</code> property of $(ref:bluetooth.AdapterState). The call |
154 to start discovery will succeed even if another app is discovering nearby | 160 to start discovery will succeed even if another app is discovering nearby |
155 devices, and will ensure the adapter continues to perform discovery after | 161 devices, and will ensure the adapter continues to perform discovery after |
156 that other app has stopped. | 162 that other app has stopped. |
157 </p> | 163 </p> |
158 | 164 |
159 <p> | 165 <p> |
160 Information about each newly discovered device is received using the | 166 Information about each newly discovered device is received using the |
161 <code>chrome.bluetooth.onDeviceAdded</code> event. For devices that have | 167 $(ref:bluetooth.onDeviceAdded) event. For devices that have |
162 already been discovered recently, or have been previously paired with or | 168 already been discovered recently, or have been previously paired with or |
163 connected to, the event will not be sent. Instead you should call | 169 connected to, the event will not be sent. Instead you should call |
164 <code>chrome.bluetooth.getDevices</code> to obtain the current information, | 170 $(ref:bluetooth.getDevices) to obtain the current information, |
165 and use the <code>chrome.bluetooth.onDeviceChanged</code> event to be notified
of changes to that information as a result of discovery. | 171 and use the $(ref:bluetooth.onDeviceChanged) event to be notified of changes |
| 172 to that information as a result of discovery. |
166 </p> | 173 </p> |
167 | 174 |
168 <p> | 175 <p> |
169 Example: | 176 Example: |
170 </p> | 177 </p> |
171 | 178 |
172 <pre> | 179 <pre> |
173 var device_names = {}; | 180 var device_names = {}; |
174 var updateDeviceName = function(device) { | 181 var updateDeviceName = function(device) { |
175 device_names[device.address] = device.name; | 182 device_names[device.address] = device.name; |
(...skipping 23 matching lines...) Expand all Loading... |
199 setTimeout(function() { | 206 setTimeout(function() { |
200 chrome.bluetooth.stopDiscovery(function() {}); | 207 chrome.bluetooth.stopDiscovery(function() {}); |
201 }, 30000); | 208 }, 30000); |
202 }); | 209 }); |
203 </pre> | 210 </pre> |
204 | 211 |
205 <p> | 212 <p> |
206 If the user turns off the Bluetooth radio, all discovery sessions will be | 213 If the user turns off the Bluetooth radio, all discovery sessions will be |
207 ended and not resumed automatically when the radio is switched on. If this | 214 ended and not resumed automatically when the radio is switched on. If this |
208 matters to your app, you should watch the | 215 matters to your app, you should watch the |
209 <code>chrome.bluetooth.onAdapterStateChanged</code> event. If the | 216 $(ref:bluetooth.onAdapterStateChanged) event. If the |
210 <code>discovering</code> property changes to <code>false</code>, then your app | 217 <code>discovering</code> property changes to <code>false</code>, then your app |
211 will need to call <code>chrome.bluetooth.startDiscovery</code> again to | 218 will need to call $(ref:bluetooth.startDiscovery) again to |
212 resume. Be cautious of the resource intensive nature of discovery. | 219 resume. Be cautious of the resource intensive nature of discovery. |
213 </p> | 220 </p> |
214 | 221 |
215 <h2 id="identifying_devices">Identifying devices</h2> | 222 <h3 id="identifying_devices">Identifying devices</h3> |
216 | 223 |
217 <p> | 224 <p> |
218 A number of different options are provided for identifying devices returned | 225 A number of different options are provided for identifying devices returned |
219 by <code>chrome.bluetooth.getDevices</code> and the related events. | 226 by $(ref:bluetooth.getDevices) and the related events. |
220 </p> | 227 </p> |
221 | 228 |
222 <p> | 229 <p> |
223 If the device supports the Bluetooth | 230 If the device supports the Bluetooth |
224 <a href="https://developer.bluetooth.org/TechnologyOverview/Pages/DI.aspx">Dev
ice ID specification</a>, | 231 <a href="https://developer.bluetooth.org/TechnologyOverview/Pages/DI.aspx">Dev
ice ID specification</a>, |
225 several properties are added to the Device object containing the fields | 232 several properties are added to the Device object containing the fields |
226 defined by that specification. Example: | 233 defined by that specification. Example: |
227 </p> | 234 </p> |
228 | 235 |
229 <pre> | 236 <pre> |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 <pre> | 283 <pre> |
277 chrome.bluetooth.getDevices(function(devices) { | 284 chrome.bluetooth.getDevices(function(devices) { |
278 for (var i = 0; i < devices.length; i++) { | 285 for (var i = 0; i < devices.length; i++) { |
279 if (devices[0].vendorIdSource != undefined) { | 286 if (devices[0].vendorIdSource != undefined) { |
280 console.log(devices[0].address + ' = ' + devices[0].type); | 287 console.log(devices[0].address + ' = ' + devices[0].type); |
281 } | 288 } |
282 } | 289 } |
283 }); | 290 }); |
284 </pre> | 291 </pre> |
285 | 292 |
| 293 <h2 id="using_rfcomm">Using RFCOMM and L2CAP</h2> |
| 294 |
| 295 <p> |
| 296 Chrome Apps may make connections to any device that supports RFCOMM or |
| 297 L2CAP services. This includes the majority of class Bluetooth devices on |
| 298 the market. |
| 299 </p> |
| 300 |
| 301 <h3 id="connecting">Connecting to a socket</h3> |
| 302 |
| 303 <p> |
| 304 In order to make a connection to a device you need three things. A socket |
| 305 to make the connection with, created using $(ref:bluetoothSocket.create); |
| 306 the address of the device you wish to connect to, and the UUID of the |
| 307 service itself. |
| 308 </p> |
| 309 |
| 310 <p> |
| 311 Before making the connection you should verify that the adapter is aware of |
| 312 the device by using $(ref:bluetooth.getDevice) or the device |
| 313 discovery APIs. |
| 314 </p> |
| 315 |
| 316 <p> |
| 317 The information necessary to establish the underlying connection, including |
| 318 whether the RFCOMM or L2CAP protocol should be used and which channel or PSM, |
| 319 is obtained using SDP discovery on the device. |
| 320 </p> |
| 321 |
| 322 <p> |
| 323 Example: |
| 324 </p> |
| 325 |
| 326 <pre> |
| 327 var uuid = '1105'; |
| 328 var onConnectedCallback = function() { |
| 329 if (chrome.runtime.lastError) { |
| 330 console.log("Connection failed: " + chrome.runtime.lastError); |
| 331 } else { |
| 332 // Profile implementation here. |
| 333 } |
| 334 }; |
| 335 |
| 336 chrome.bluetoothSocket.create(function(createInfo) { |
| 337 chrome.bluetoothSocket.connect(createInfo.socketId, |
| 338 device.address, uuid, onConnectedCallback); |
| 339 }); |
| 340 </pre> |
| 341 |
| 342 <p> |
| 343 Keep a handle to the socketId so that you can later send data |
| 344 ($(ref:bluetoothSocket.send)) to this socket. |
| 345 </p> |
| 346 |
| 347 <h3 id="receiving">Receiving from and sending to a socket</h3> |
| 348 |
| 349 <p> |
| 350 Receiving data from and sending to a socket uses <code>ArrayBuffer</code> |
| 351 objects. To learn about ArrayBuffers, check out the overview, |
| 352 <a href="https://developer.mozilla.org/en-US/docs/JavaScript_typed_arrays">Jav
aScript typed arrays</a>, |
| 353 and the tutorial, |
| 354 <a href="http://updates.html5rocks.com/2012/06/How-to-convert-ArrayBuffer-to-a
nd-from-String">How to convert ArrayBuffer to and from String</a>.\ |
| 355 </p> |
| 356 |
| 357 <p> |
| 358 To send data you have in <code>arrayBuffer</code> use |
| 359 $(ref:bluetoothSocket.send): |
| 360 </p> |
| 361 |
| 362 <pre> |
| 363 chrome.bluetoothSocket.send(socketId, arrayBuffer, function(bytes_sent) { |
| 364 if (chrome.runtime.lastError) { |
| 365 console.log("Send failed: " + chrome.runtime.lastError); |
| 366 } else { |
| 367 console.log("Sent " + bytes_sent + " bytes") |
| 368 } |
| 369 }) |
| 370 </pre> |
| 371 |
| 372 <p> |
| 373 In contrast to the method to send data, data is received in an event |
| 374 ($(ref:bluetoothSocket.onReceive). Sockets are created unpaused (see |
| 375 $(ref:bluetoothSocket.setPaused)) so the listener for this event is |
| 376 typically added between $(ref:bluetoothSocket.create) and |
| 377 $(ref:bluetoothSocket.connect). |
| 378 </p> |
| 379 |
| 380 <pre> |
| 381 chrome.bluetoothSocket.onRecieve.addListener(function(receiveInfo) { |
| 382 if (receiveInfo.socketId != socketId) |
| 383 return; |
| 384 // receiveInfo.data is an ArrayBuffer. |
| 385 }); |
| 386 </pre> |
| 387 |
| 388 <h3 id="errors">Receiving socket errors and disconnection</h3> |
| 389 |
| 390 <p> |
| 391 To be notified of socket errors, including disconnection, add a listener to |
| 392 the $(ref:bluetoothSocket.onReceiveError) event. |
| 393 </p> |
| 394 |
| 395 <pre> |
| 396 chrome.bluetoothSocket.onReceiveError.addListener(function(errorInfo) { |
| 397 // Cause is in errorInfo.error. |
| 398 console.log(errorInfo.errorMessage); |
| 399 }); |
| 400 </pre> |
| 401 |
| 402 <h3 id="disconnection">Disconnecting from a socket</h3> |
| 403 |
| 404 <p> |
| 405 To hang up the connection and disconnect the socket use |
| 406 $(ref:bluetoothSocket.disconnect). |
| 407 </p> |
| 408 |
| 409 <pre> |
| 410 chrome.bluetoothSocket.disconnect(socketId); |
| 411 </pre> |
| 412 |
| 413 <h2 id="using_rfcomm">Publishing services</h2> |
| 414 |
| 415 <p> |
| 416 In addition to making outbound connections to devices, Chrome Apps may |
| 417 publish services that may be used by any device that supports RFCOMM or |
| 418 L2CAP. |
| 419 </p> |
| 420 |
| 421 <h3 id="listening">Listening on a socket</h3> |
| 422 |
| 423 <p> |
| 424 Three types of published service are supported. RFCOMM is the most commonly |
| 425 used and covers the majority of devices and profiles: |
| 426 </p> |
| 427 |
| 428 <pre> |
| 429 var uuid = '1105'; |
| 430 var channel = 0; // Automatic channel selection. |
| 431 chrome.bluetoothSocket.create(function(createInfo) { |
| 432 chrome.bluetoothSocket.listenUsingRfcomm(createInfo.socketId, |
| 433 uuid, channel, onListenCallback); |
| 434 }); |
| 435 </pre> |
| 436 |
| 437 <p> |
| 438 Insecure RFCOMM is an option for Bluetooth 1.0 and Bluetooth 2.0 devices that |
| 439 do not support encryption. For all other device types this is no different |
| 440 to using $(ref:bluetoothSocket.listenUsingRfcomm). |
| 441 </p> |
| 442 |
| 443 <pre> |
| 444 chrome.bluetoothSocket.create(function(createInfo) { |
| 445 chrome.bluetoothSocket.listenUsingInsecureRfcomm(createInfo.socketId, |
| 446 uuid, channel, onListenCallback); |
| 447 }); |
| 448 </pre> |
| 449 |
| 450 <p> |
| 451 Finally L2CAP covers other device types and vendor-specific uses such as |
| 452 firmware uploading. |
| 453 </p> |
| 454 |
| 455 <pre> |
| 456 var uuid = '0b87367c-f188-47cd-bc20-a5f4f70973c6'; |
| 457 var psm = 0; // Automatic PSM selection. |
| 458 chrome.bluetoothSocket.create(function(createInfo) { |
| 459 chrome.bluetoothSocket.listenUsingL2cap(createInfo.socketId, |
| 460 uuid, psm, onListenCallback); |
| 461 }); |
| 462 </pre> |
| 463 |
| 464 <p> |
| 465 In all three cases the callback indicates error through |
| 466 <code>chrome.runtime.lastError</code> and success otherwise. |
| 467 Keep a handle to the socketId so that you can later accept connections |
| 468 ($(ref:bluetoothSocket.onAccept)) from this socket. |
| 469 </p> |
| 470 |
| 471 <h3 id="accepting">Accepting client connections</h3> |
| 472 |
| 473 <p> |
| 474 Client connections are accepted and passed to your application through the |
| 475 $(ref:bluetoothSocket.onAccept) event. |
| 476 </p> |
| 477 |
| 478 <pre> |
| 479 chrome.bluetoothSocket.onAccept.addListener(function(acceptInfo) { |
| 480 if (info.socketId != serverSocketId) |
| 481 return; |
| 482 |
| 483 // Say hello... |
| 484 chrome.bluetoothSocket.send(acceptInfo.clientSocketId, |
| 485 data, onSendCallback); |
| 486 |
| 487 // Accepted sockets are initially paused, |
| 488 // set the onReceive listener first. |
| 489 chrome.bluetoothSocket.onReceive.addListener(onReceive); |
| 490 chrome.bluetoothSocket.setPaused(false); |
| 491 }); |
| 492 </pre> |
| 493 |
| 494 <h3 id="stop-accepting">Stop accepting client connections</h3> |
| 495 |
| 496 <p> |
| 497 To stop accepting client connections and unpublish the service use |
| 498 $(ref:bluetoothSocket.disconnect). |
| 499 </p> |
| 500 |
| 501 <pre> |
| 502 chrome.bluetoothSocket.disconnect(serverSocketId); |
| 503 </pre> |
OLD | NEW |