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:chrome.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 o you should call $(ref:bluetooth.stopDiscovery) when done. |
armansito
2014/05/13 20:24:46
s/o you should/so you should/
keybuk
2014/05/20 18:09:14
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: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 connecting, including | |
armansito
2014/05/13 20:24:46
s/underlying connecting/underlying connection/ ?
keybuk
2014/05/20 18:09:14
Done.
| |
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 ArrayBuffer objects. To | |
351 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 arrayBuffer use $(ref:bluetoothSocket.send): | |
armansito
2014/05/13 20:24:46
should this be <code>arrayBuffer</code>?
keybuk
2014/05/20 18:09:14
Done.
| |
359 </p> | |
360 | |
361 <pre> | |
362 chrome.bluetoothSocket.send(socketId, arrayBuffer, function(bytes_sent) { | |
363 if (chrome.runtime.lastError) { | |
364 console.log("Send failed: " + chrome.runtime.lastError); | |
365 } else { | |
366 console.log("Sent " + bytes_sent + " bytes") | |
367 } | |
368 }) | |
369 </pre> | |
370 | |
371 <p> | |
372 In contrast to the method to send data, data is received in an event | |
373 ($(ref:bluetoothSocket.onRecieve). Sockets are created unpaused (see | |
374 $(ref:bluetoothSocket.setPaused)) so the listener for this event is | |
375 typically added between $(ref:bluetoothSocket.create) and | |
376 $(ref:bluetoothSocket.connect). | |
377 </p> | |
378 | |
379 <pre> | |
380 chrome.bluetoothSocket.onRecieve.addListener(function(receiveInfo) { | |
381 if (receiveInfo.socketId != socketId) | |
382 return; | |
383 // receiveInfo.data is an ArrayBuffer. | |
384 }); | |
385 </pre> | |
386 | |
387 <h3 id="errors">Receiving socket errors and disconnection</h3> | |
388 | |
389 <p> | |
390 To be notified of socket errors, including disconnection, add a listener to | |
391 the $(ref:bluetoothSocket.onReceiveError) event. | |
392 </p> | |
393 | |
394 <pre> | |
395 chrome.bluetoothSocket.onReceiveError.addListener(function(errorInfo) { | |
396 // Cause is in errorInfo.error. | |
397 console.log(errorInfo.errorMessage); | |
398 }); | |
399 </pre> | |
400 | |
401 <h3 id="disconnection">Disconnecting from a socket</h3> | |
402 | |
403 <p> | |
404 To hang up the connection and disconnect the socket use | |
405 $(ref:bluetoothSocket.disconnect). | |
406 </p> | |
407 | |
408 <pre> | |
409 chrome.bluetoothSocket.disconnect(socketId); | |
410 </pre> | |
411 | |
412 <h2 id="using_rfcomm">Publishing services</h2> | |
413 | |
414 <p> | |
415 In addition to making outbound connections to devices, Chrome Apps may | |
416 publish services that may be used by any device that supports RFCOMM or | |
417 L2CAP. | |
418 </p> | |
419 | |
420 <h3 id="listening">Listening on a socket</h3> | |
421 | |
422 <p> | |
423 Three types of published service are supported. RFCOMM is the most commonly | |
424 used and covers the majority of devices and profiles: | |
425 </p> | |
426 | |
427 <pre> | |
428 var uuid = '1105'; | |
429 var channel = 0; // Automatic channel selection. | |
430 chrome.bluetoothSocket.create(function(createInfo) { | |
431 chrome.bluetoothSocket.listenUsingRfcomm(createInfo.socketId, | |
432 uuid, channel, onListenCallback); | |
433 }); | |
434 </pre> | |
435 | |
436 <p> | |
437 Insecure RFCOMM is an option for Bluetooth 1.0 and Bluetooth 2.0 devices that | |
438 do not support encryption. For all other device types this is no different | |
439 to using $(ref:bluetoothSocket.listenUsingRfcomm). | |
440 </p> | |
441 | |
442 <pre> | |
443 chrome.bluetoothSocket.create(function(createInfo) { | |
444 chrome.bluetoothSocket.listenUsingInsecureRfcomm(createInfo.socketId, | |
445 uuid, channel, onListenCallback); | |
446 }); | |
447 </pre> | |
448 | |
449 <p> | |
450 Finally L2CAP covers other device types and vendor-specific uses such as | |
451 firmware uploading. | |
452 </p> | |
453 | |
454 <pre> | |
455 var uuid = '0b87367c-f188-47cd-bc20-a5f4f70973c6'; | |
456 var psm = 0; // Automatic PSM selection. | |
457 chrome.bluetoothSocket.create(function(createInfo) { | |
458 chrome.bluetoothSocket.listenUsingL2cap(createInfo.socketId, | |
459 uuid, psm, onListenCallback); | |
460 }); | |
461 </pre> | |
462 | |
463 <p> | |
464 In all three cases the callback indicates error through | |
465 <code>chrome.runtime.lastError</code> and success otherwise. | |
466 Keep a handle to the socketId so that you can later accept connections | |
467 ($(ref:bluetoothSocket.onAccept)) from this socket. | |
468 </p> | |
469 | |
470 <h3 id="accepting">Accepting client connections</h3> | |
471 | |
472 <p> | |
473 Client connections are accepted and passed to your application through the | |
474 $(ref:bluetoothSocket.onAccept) event. | |
475 </p> | |
476 | |
477 <pre> | |
478 chrome.bluetoothSocket.onAccept.addListener(function(acceptInfo) { | |
479 if (info.socketId != serverSocketId) | |
480 return; | |
481 | |
482 // Say hello... | |
483 chrome.bluetoothSocket.send(acceptInfo.clientSocketId, | |
484 data, onSendCallback); | |
485 | |
486 // Accepted sockets are initially paused, | |
487 // set the onReceive listener first. | |
488 chrome.bluetoothSocket.onReceive.addListener(onReceive); | |
489 chrome.bluetoothSocket.setPaused(false); | |
490 }); | |
491 </pre> | |
492 | |
493 <h3 id="stop-accepting">Stop accepting client connections</h3> | |
494 | |
495 <p> | |
496 To stop accepting client connections and unpublish the service use | |
497 $(ref:bluetoothSocket.disconnect). | |
498 </p> | |
499 | |
500 <pre> | |
501 chrome.bluetoothSocket.disconnect(serverSocketId); | |
502 </pre> | |
OLD | NEW |