| Index: chrome/common/extensions/docs/templates/articles/app_hardware.html
|
| diff --git a/chrome/common/extensions/docs/templates/articles/app_hardware.html b/chrome/common/extensions/docs/templates/articles/app_hardware.html
|
| deleted file mode 100644
|
| index 2eea329ea74987770f7547b2389621511d62d0bd..0000000000000000000000000000000000000000
|
| --- a/chrome/common/extensions/docs/templates/articles/app_hardware.html
|
| +++ /dev/null
|
| @@ -1,846 +0,0 @@
|
| -<h1>Accessing Hardware Devices</h1>
|
| -
|
| -<p>
|
| - This doc shows you how Chrome Apps can connect to USB devices and read from
|
| - and write to a user's serial ports. See also the reference docs for the <a
|
| - href="usb.html">USB API</a> and the <a href="serial.html">Serial API</a>.
|
| - The <a href="bluetooth.html">Bluetooth API</a> is also available; we've
|
| - included a link to a Bluetooth sample below.
|
| -</p>
|
| -
|
| -<p class="note">
|
| - <b>API Samples: </b> Want to play with the code? Check out the
|
| - <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/serial">serial</a>,
|
| - <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/servo">servo</a>,
|
| - <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/usb">usb</a>,
|
| - and
|
| - <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/zephyr_hxm">zephyr_hxm
|
| - Bluetooth</a> samples.
|
| -</p>
|
| -
|
| -<h2 id="usb">Accessing USB devices</h2>
|
| -
|
| -<p>
|
| - You can use the <a href="usb.html">USB API</a> to communicate with USB devices
|
| - using only JavaScript code. Some devices are not accessible through this API
|
| - – see <a href="#caveats">Caveats</a> below for details.
|
| -</p>
|
| -
|
| -<p>
|
| - For background information about USB, see the official
|
| - <a href="http://www.usb.org/home">USB specifications</a>. <br/>
|
| - <a href="http://www.beyondlogic.org/usbnutshell/usb1.shtml">
|
| - <i>USB in a NutShell</i></a>
|
| - is a reasonable crash course that you may find helpful.
|
| -</p>
|
| -
|
| -<h3 id="manifest">Manifest requirement</h3>
|
| -
|
| -<p>The USB API requires the "usb" permission in the manifest file:</p>
|
| -
|
| -<pre data-filename="manifest.json">
|
| -"permissions": [
|
| - "usb"
|
| -]
|
| -</pre>
|
| -
|
| -<p>In addition, in order to prevent
|
| - <a href="http://en.wikipedia.org/wiki/Device_fingerprint">finger-printing</a>,
|
| - you must declare all the device types you want to access in the manifest file.
|
| - Each type of USB device corresponds to a vendor id/product id (VID/PID) pair.
|
| - You can use $ref:usb.getDevices to enumerate devices by their VID/PID
|
| - pair.
|
| -</p>
|
| -<p>
|
| - You must declare the VID/PID pairs for each type of device you want to use
|
| - under the "usbDevices" permission in your app's manifest file, as shown in the
|
| - example below:</p>
|
| -
|
| -<pre data-filename="manifest.json">
|
| -"permissions": [
|
| - "usbDevices": [
|
| - {
|
| - "vendorId": 123,
|
| - "productId": 456
|
| - }
|
| - ]
|
| -]
|
| -</pre>
|
| -
|
| -<p class="note">Note that only decimal numbers are allowed in JSON format.
|
| - You cannot use hexadecimal numbers in these fields.</p>
|
| -
|
| -<h3 id="finding_device">Finding a device</h3>
|
| -
|
| -<p>
|
| - To determine whether one or more specific devices are connected to a user's
|
| - system, use the $ref:usb.getDevices method:
|
| -</p>
|
| -
|
| -<pre>
|
| -chrome.usb.getDevices(enumerateDevicesOptions, callback);
|
| -</pre>
|
| -
|
| -<br/>
|
| -
|
| -<table class="simple">
|
| - <tr>
|
| - <th scope="col">Parameter (type)</th>
|
| - <th scope="col">Description</th>
|
| - </tr>
|
| - <tr>
|
| - <td>EnumerateDevicesOptions (object)</td>
|
| - <td>An object specifying both a <code>vendorId</code> (long) and
|
| - <code>productId</code> (long) used to find the correct type of device on
|
| - the bus. Your manifest must declare the <code>usbDevices</code> permission
|
| - section listing all the <code>vendorId</code> and <code>deviceId</code>
|
| - pairs your app wants to access.
|
| - </td>
|
| - </tr>
|
| - <tr>
|
| - <td>callback (function)</td>
|
| - <td>Called when the device enumeration is finished. The callback will be
|
| - executed with one parameter, an array of <code>Device</code> objects with
|
| - three properties: <code>device</code>, <code>vendorId</code>,
|
| - <code>productId</code>. The device property is a stable identifier for a
|
| - connected device. It will not change until the device is unplugged. The
|
| - detail of the identifier is opaque and subject to change. Do not rely on
|
| - its current type. <br/>
|
| - If no devices are found, the array will be empty.
|
| - </td>
|
| - </tr>
|
| -</table>
|
| -
|
| -<p>Example:</p>
|
| -
|
| -<pre>
|
| -function onDeviceFound(devices) {
|
| - this.devices=devices;
|
| - if (devices) {
|
| - if (devices.length > 0) {
|
| - console.log("Device(s) found: "+devices.length);
|
| - } else {
|
| - console.log("Device could not be found");
|
| - }
|
| - } else {
|
| - console.log("Permission denied.");
|
| - }
|
| -}
|
| -
|
| -chrome.usb.getDevices({"vendorId": vendorId, "productId": productId}, onDeviceFound);
|
| -</pre>
|
| -
|
| -<h3 id="usb_open">Opening a device</h3>
|
| -<p>
|
| -Once the <code>Device</code> objects are returned, you can open a device using
|
| -usb.openDevice to obtain a connection handle. You can only
|
| -communicate with USB devices using connection handles.
|
| -</p>
|
| -
|
| -<table class="simple">
|
| - <tr>
|
| - <th scope="col">Property</th>
|
| - <th scope="col">Description</th>
|
| - </tr>
|
| - <tr>
|
| - <td>device</td>
|
| - <td>Object received in $ref:usb.getDevices callback.</td>
|
| - </tr>
|
| - <tr>
|
| - <td>data (arraybuffer)</td>
|
| - <td>Contains the data sent by the device if the transfer was inbound.</td>
|
| - </tr>
|
| -</table>
|
| -
|
| -<p>Example:</p>
|
| -
|
| -<pre>
|
| -var usbConnection = null;
|
| -var onOpenCallback = function(connection) {
|
| - if (connection) {
|
| - usbConnection = connection;
|
| - console.log("Device opened.");
|
| - } else {
|
| - console.log("Device failed to open.");
|
| - }
|
| -};
|
| -
|
| -chrome.usb.openDevice(device, onOpenCallback);
|
| -</pre>
|
| -
|
| -<p class="note">
|
| -Not every device can be opened successfully. In general, operating systems
|
| -lock down many types of USB interfaces (e.g. keyboards and mice, mass storage
|
| -devices, webcams, etc.) and they cannot be claimed by user applications.
|
| -On Linux (other than Chrome OS), once an interface of a device is locked down by
|
| -the OS, the whole device is locked down (because all the interfaces shares the
|
| -same device file), even if the other interfaces of the device can be used in
|
| -theory. On Chrome OS, you can request access to unlocked interfaces using the
|
| -$ref:usb.requestAccess method. If permitted, the permission broker will
|
| -unlock the device file for you.
|
| -</p>
|
| -
|
| -<p>
|
| -To simplify the opening process, you can use the $ref:usb.findDevices
|
| -method, which enumerates, requests access, and opens devices in one call:
|
| -</p>
|
| -
|
| -<pre>
|
| -chrome.usb.findDevices({"vendorId": vendorId, "productId": productId, "interfaceId": interfaceId}, callback);
|
| -</pre>
|
| -<p>which is equivalent to:</p>
|
| -<pre>
|
| -chrome.usb.getDevices({"vendorId": vendorId, "productId": productId}, function (devices) {
|
| - if (!devices) {
|
| - console.log("Error enumerating devices.");
|
| - callback();
|
| - return;
|
| - }
|
| - var connections = [], pendingAccessRequests = devices.length;
|
| - devices.forEach(function (device) {
|
| - chrome.usb.requestAccess(interfaceId, function () {
|
| - // No need to check for errors at this point.
|
| - // Nothing can be done if an error occurs anyway. You should always try
|
| - // to open the device.
|
| - chrome.usb.openDevices(device, function (connection) {
|
| - if (connection) connections.push(connection);
|
| - pendingAccessRequests--;
|
| - if (pendingAccessRequests == 0) {
|
| - callback(connections);
|
| - }
|
| - });
|
| - });
|
| - })
|
| -});
|
| -</pre>
|
| -
|
| -<h3 id="usb_transfers">USB transfers and receiving data from a device</h3>
|
| -
|
| -<p>
|
| - The USB protocol defines four types of transfers:
|
| - <a href="#control_transfers">control</a>,
|
| - <a href="#bulk_transfers">bulk</a>,
|
| - <a href="#isochronous_transfers">isochronous</a>
|
| - and <a href="#interrupt_transfers">interrupt</a>.
|
| - These transfers are described below.
|
| -</p>
|
| -
|
| -<p>
|
| - Transfers can occur in both directions: device-to-host (inbound), and
|
| - host-to-device (outbound). Due to the nature of the USB protocol,
|
| - both inbound and outbound messages must be initiated by the host (the
|
| - computer that runs the Chrome app).
|
| - For inbound (device-to-host) messages, the host (initiated by your JavaScript
|
| - code) sends a message flagged as "inbound" to the device.
|
| - The details of the message depend on the device, but usually will have
|
| - some identification of what you are requesting from it.
|
| - The device then responds with the requested data.
|
| - The device's response is handled by Chrome and delivered asynchronously to the
|
| - callback you specify in the transfer method.
|
| - An outbound (host-to-device) message is similar, but the response doesn't
|
| - contain data returned from the device.
|
| -</p>
|
| -
|
| -<p>
|
| - For each message from the device, the specified callback will receive an event
|
| - object with the following properties:
|
| -</p>
|
| -
|
| -<br>
|
| -
|
| -<table class="simple">
|
| - <tr>
|
| - <th scope="col">Property</th>
|
| - <th scope="col">Description</th>
|
| - </tr>
|
| - <tr>
|
| - <td>resultCode (integer)</td>
|
| - <td>0 is success; other values indicate failure. An error string can be<br/>
|
| - read from <code>chrome.extension.lastError</code> when a failure is<br/>
|
| - indicated.
|
| - </td>
|
| - </tr>
|
| - <tr>
|
| - <td>data (arraybuffer)</td>
|
| - <td>Contains the data sent by the device if the transfer was inbound.</td>
|
| - </tr>
|
| -</table>
|
| -
|
| -<p>Example:</p>
|
| -
|
| -<pre>
|
| -var onTransferCallback = function(event) {
|
| - if (event && event.resultCode === 0 && event.data) {
|
| - console.log("got " + event.data.byteLength + " bytes");
|
| - }
|
| -};
|
| -
|
| -chrome.usb.bulkTransfer(connectionHandle, transferInfo, onTransferCallback);
|
| -</pre>
|
| -
|
| -<h3 id="control_transfers">CONTROL transfers</h3>
|
| -
|
| -<p>Control transfers are generally used to send or receive configuration or
|
| - command parameters to a USB device. The controlTransfer method always sends
|
| - to/reads from endpoint 0, and no claimInterface is required.
|
| - The method is simple and receives three parameters:</p>
|
| -
|
| -<pre>
|
| -chrome.usb.controlTransfer(connectionHandle, transferInfo, transferCallback)
|
| -</pre>
|
| -
|
| -<br>
|
| -
|
| -<table class="simple">
|
| - <tr>
|
| - <th scope="col">Parameter (types)</th>
|
| - <th scope="col">Description</th>
|
| - </tr>
|
| - <tr>
|
| - <td>connectionHandle</td>
|
| - <td>Object received in $ref:usb.openDevice callback.
|
| - </td>
|
| - </tr>
|
| - <tr>
|
| - <td>transferInfo</td>
|
| - <td>Parameter object with values from the table below. Check your USB
|
| - device protocol specification for details.
|
| - </td>
|
| - </tr>
|
| - <tr>
|
| - <td>transferCallback()</td>
|
| - <td>Invoked when the transfer has completed.</td>
|
| - </tr>
|
| -</table>
|
| -
|
| -<p>
|
| - Values for
|
| - <code>transferInfo</code>
|
| - object:
|
| -</p>
|
| -
|
| -<table class="simple">
|
| - <tr>
|
| - <th scope="col">Value</th>
|
| - <th scope="col">Description</th>
|
| - </tr>
|
| - <tr>
|
| - <td>requestType (string)</td>
|
| - <td>"vendor", "standard", "class" or "reserved".</td>
|
| - </tr>
|
| - <tr>
|
| - <td>recipient (string)</td>
|
| - <td>"device", "interface", "endpoint" or "other".</td>
|
| - </tr>
|
| - <tr>
|
| - <td>direction (string)</td>
|
| - <td>"in" or "out". The "in" direction is used to notify the device that<br/>
|
| - it should send information to the host. All communication on a USB<br/>
|
| - bus is host-initiated, so use an "in" transfer to allow a device to<br/>
|
| - send information back.
|
| - </td>
|
| - </tr>
|
| - <tr>
|
| - <td>request (integer)</td>
|
| - <td>Defined by your device's protocol.</td>
|
| - </tr>
|
| - <tr>
|
| - <td>value (integer)</td>
|
| - <td>Defined by your device's protocol.</td>
|
| - </tr>
|
| - <tr>
|
| - <td>index (integer)</td>
|
| - <td>Defined by your device's protocol.</td>
|
| - </tr>
|
| - <tr>
|
| - <td>length (integer)</td>
|
| - <td>Only used when direction is "in". Notifies the device that this is
|
| - the amount of data the host is expecting in response.
|
| - </td>
|
| - </tr>
|
| - <tr>
|
| - <td>data (arraybuffer)</td>
|
| - <td>Defined by your device's protocol, required when direction is
|
| - "out".
|
| - </td>
|
| - </tr>
|
| -</table>
|
| -
|
| -<p>Example:</p>
|
| -
|
| -<pre>
|
| -var transferInfo = {
|
| - "requestType": "vendor",
|
| - "recipient": "device",
|
| - "direction": "out",
|
| - "request": 0x31,
|
| - "value": 120,
|
| - "index": 0,
|
| - // Note that the ArrayBuffer, not the TypedArray itself is used.
|
| - "data": new Uint8Array([4, 8, 15, 16, 23, 42]).buffer
|
| -};
|
| -chrome.usb.controlTransfer(connectionHandle, transferInfo, optionalCallback);
|
| -</pre>
|
| -
|
| -<h3 id="isochronous_transfers">ISOCHRONOUS transfers</h3>
|
| -
|
| -<p>Isochronous transfers are the most complex type of USB transfer. They are
|
| - commonly used for streams of data, like video and sound. To initiate an
|
| - isochronous transfer (either inbound or outbound), you must use
|
| - the $ref:usb.isochronousTransfer method:</p>
|
| -
|
| -<pre>
|
| -chrome.usb.isochronousTransfer(connectionHandle, isochronousTransferInfo, transferCallback)
|
| -</pre>
|
| -
|
| -<br/>
|
| -
|
| -<table class="simple">
|
| - <tr>
|
| - <th scope="col">Parameter</th>
|
| - <th scope="col">Description</th>
|
| - </tr>
|
| - <tr>
|
| - <td>connectionHandle</td>
|
| - <td>Object received in $ref:usb.openDevice callback.
|
| - </td>
|
| - </tr>
|
| - <tr>
|
| - <td>isochronousTransferInfo</td>
|
| - <td>Parameter object with the values in the table below.</td>
|
| - </tr>
|
| - <tr>
|
| - <td>transferCallback()</td>
|
| - <td>Invoked when the transfer has completed.</td>
|
| - </tr>
|
| -</table>
|
| -
|
| -<p>
|
| - Values for
|
| - <code>isochronousTransferInfo</code>
|
| - object:
|
| -</p>
|
| -
|
| -<table class="simple">
|
| - <tr>
|
| - <th scope="col">Value</th>
|
| - <th scope="col">Description</th>
|
| - </tr>
|
| - <tr>
|
| - <td>transferInfo (object)</td>
|
| - <td>An object with the following attributes:<br/>
|
| - <b>direction (string): </b>"in" or "out".<br/>
|
| - <b>endpoint (integer): </b>defined by your device. Usually can be found by
|
| - looking at an USB instrospection tool, like <code>lsusb -v</code><br/>
|
| - <b>length (integer): </b>only
|
| - used when direction is "in". Notifies the device that this is the amount
|
| - of data the host is expecting in response. <br/>
|
| -
|
| - Should be AT LEAST <code>packets</code> × <code>packetLength</code>.
|
| - <br/>
|
| - <b>data (arraybuffer): </b>defined by your device's protocol;
|
| - only used when direction is "out".
|
| - </td>
|
| - </tr>
|
| - <tr>
|
| - <td>packets (integer)</td>
|
| - <td>Total number of packets expected in this transfer.</td>
|
| - </tr>
|
| - <tr>
|
| - <td>packetLength (integer)</td>
|
| - <td>Expected length of each packet in this transfer.</td>
|
| - </tr>
|
| -</table>
|
| -
|
| -<p>Example:</p>
|
| -
|
| -<pre>
|
| -var transferInfo = {
|
| - "direction": "in",
|
| - "endpoint": 1,
|
| - "length": 2560
|
| -};
|
| -
|
| -var isoTransferInfo = {
|
| - "transferInfo": transferInfo,
|
| - "packets": 20,
|
| - "packetLength": 128
|
| -};
|
| -
|
| -chrome.usb.isochronousTransfer(connectionHandle, isoTransferInfo, optionalCallback);
|
| -</pre>
|
| -
|
| -<p class="note">
|
| - <b>Notes:</b> One isochronous transfer will contain
|
| - <code>isoTransferInfo.packets</code> packets of
|
| - <code>isoTransferInfo.packetLength</code> bytes.
|
| - If it is an inbound transfer (your code requested data from the device), the
|
| - <code>data</code> field in the onUsbEvent will be an ArrayBuffer of size
|
| - <code>transferInfo.length</code>. It is your duty to walk through this
|
| - ArrayBuffer and extract the different packets, each starting at a multiple of
|
| - <code>isoTransferInfo.packetLength</code> bytes. <br/>
|
| - <br/>
|
| - If you are expecting a stream of data from the device, remember that
|
| - you will have to send one "inbound" transfer for each transfer you expect
|
| - back. USB devices don't send transfers to the USB bus unless the host
|
| - explicitly requests them through "inbound" transfers.
|
| -</p>
|
| -
|
| -<h3 id="bulk_transfers">BULK transfers</h3>
|
| -
|
| -<p>Bulk transfers are commonly used to transfer a large amount of
|
| - non-time-sensitive data in a reliable way.
|
| - $ref:usb.bulkTransfer has three parameters:</p>
|
| -
|
| -<pre>
|
| -chrome.usb.bulkTransfer(connectionHandle, transferInfo, transferCallback);
|
| -</pre>
|
| -
|
| -<br>
|
| -
|
| -<table class="simple">
|
| - <tr>
|
| - <th scope="col">Parameter</th>
|
| - <th scope="col">Description</th>
|
| - </tr>
|
| - <tr>
|
| - <td>connectionHandle</td>
|
| - <td>Object received in $ref:usb.openDevice callback.
|
| - </td>
|
| - </tr>
|
| - <tr>
|
| - <td>transferInfo</td>
|
| - <td>Parameter object with the values in the table below.</td>
|
| - </tr>
|
| - <tr>
|
| - <td>transferCallback</td>
|
| - <td>Invoked when the transfer has completed.</td>
|
| - </tr>
|
| -</table>
|
| -
|
| -<p>
|
| - Values for
|
| - <code>transferInfo</code>
|
| - object:
|
| -</p>
|
| -
|
| -<table class="simple">
|
| - <tr>
|
| - <th scope="col">Value</th>
|
| - <th scope="col">Description</th>
|
| - </tr>
|
| - <tr>
|
| - <td>direction (string)</td>
|
| - <td>"in" or "out".</td>
|
| - </tr>
|
| - <tr>
|
| - <td>endpoint (integer)</td>
|
| - <td>Defined by your device's protocol.</td>
|
| - </tr>
|
| - <tr>
|
| - <td>length (integer)</td>
|
| - <td>Only used when direction is "in". Notifies the device that this is
|
| - the amount of data the host is expecting in response.
|
| - </td>
|
| - </tr>
|
| - <tr>
|
| - <td>data (ArrayBuffer)</td>
|
| - <td>Defined by your device's protocol; only used when direction is
|
| - "out".
|
| - </td>
|
| - </tr>
|
| -</table>
|
| -
|
| -<p>Example:</p>
|
| -
|
| -<pre>
|
| -var transferInfo = {
|
| - "direction": "out",
|
| - "endpoint": 1,
|
| - "data": new Uint8Array([4, 8, 15, 16, 23, 42]).buffer
|
| -};
|
| -</pre>
|
| -
|
| -<h3 id="interrupt_transfers">INTERRUPT transfers</h3>
|
| -
|
| -<p>Interrupt transfers are used to small amount of time sensitive data.
|
| - Since all USB communication is initiated by the host, host code usually polls
|
| - the device periodically, sending interrupt IN transfers that will make the
|
| - device send data back if there is anything in the interrupt queue (maintained
|
| - by the device).
|
| - $ref:usb.interruptTransfer has three parameters:</p>
|
| -
|
| -<pre>
|
| -chrome.usb.interruptTransfer(connectionHandle, transferInfo, transferCallback);
|
| -</pre>
|
| -
|
| -<br>
|
| -
|
| -<table class="simple">
|
| - <tr>
|
| - <th scope="col">Parameter</th>
|
| - <th scope="col">Description</th>
|
| - </tr>
|
| - <tr>
|
| - <td>connectionHandle</td>
|
| - <td>Object received in $ref:usb.openDevice callback.
|
| - </td>
|
| - </tr>
|
| - <tr>
|
| - <td>transferInfo</td>
|
| - <td>Parameter object with the values in the table below.</td>
|
| - </tr>
|
| - <tr>
|
| - <td>transferCallback</td>
|
| - <td>Invoked when the transfer has completed. Notice that this callback
|
| - doesn't contain the device's response. The purpose of the callback is
|
| - simply to notify your code that the asynchronous transfer requests has
|
| - been processed.
|
| - </td>
|
| - </tr>
|
| -</table>
|
| -
|
| -<p>
|
| - Values for <code>transferInfo</code> object:
|
| -</p>
|
| -
|
| -<table class="simple">
|
| -<tr>
|
| - <th scope="col">Value</th>
|
| - <th scope="col">Description</th>
|
| -</tr>
|
| -<tr>
|
| - <td>direction (string)</td>
|
| - <td>"in" or "out".</td>
|
| -</tr>
|
| -<tr>
|
| - <td>endpoint (integer)</td>
|
| - <td>Defined by your device's protocol.</td>
|
| -</tr>
|
| -<tr>
|
| - <td>length (integer)</td>
|
| - <td>Only used when direction is "in". Notifies the device that this is
|
| - the amount of data the host is expecting in response.
|
| - </td>
|
| -</tr>
|
| -<tr>
|
| - <td>data (ArrayBuffer)</td>
|
| - <td>Defined by your device's protocol; only used when direction is
|
| - "out".
|
| - </td>
|
| -</tr>
|
| -</table>
|
| -
|
| -<p>Example:</p>
|
| -
|
| -<pre>
|
| -var transferInfo = {
|
| - "direction": "in",
|
| - "endpoint": 1,
|
| - "length": 2
|
| -};
|
| -chrome.usb.interruptTransfer(connectionHandle, transferInfo, optionalCallback);
|
| -</pre>
|
| -
|
| -<h3 id="caveats">Caveats</h3>
|
| -
|
| -<p>Not all devices can be accessed through the USB API. In general, devices
|
| - are not accessible because either the Operating System's kernel or a native
|
| - driver holds them off from user space code. Some examples are devices with
|
| - HID profiles on OSX systems, and USB pen drives.</p>
|
| -
|
| -<p>
|
| - On most Linux systems, USB devices are mapped with read-only permissions by
|
| - default. To open a device through this API, your user will need to have
|
| - write access to it too.
|
| - A simple solution is to set a udev rule. Create a file
|
| - <code>/etc/udev/rules.d/50-yourdevicename.rules</code>
|
| - with the following content:
|
| -</p>
|
| -
|
| -<pre>
|
| -SUBSYSTEM=="usb", ATTR{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"
|
| -</pre>
|
| -
|
| -<p>
|
| - Then, just restart the udev daemon: <code>service udev restart</code>.
|
| - You can check if device permissions are set correctly by following these
|
| - steps:
|
| -</p>
|
| -
|
| -<ul>
|
| - <li>Run <code>lsusb</code> to find the bus and device numbers.</li>
|
| - <li>Run <code>ls -al /dev/bus/usb/[bus]/[device]</code>. This file should be
|
| - owned by group "plugdev" and have group write permissions.
|
| - </li>
|
| -</ul>
|
| -
|
| -<p>Your app cannot do this automatically since this this procedure requires root
|
| -access. We recommend that you provide instructions to end-users and link to the
|
| -<a href="#caveats">Caveats</a> section on this page for an explanation.</p>
|
| -
|
| -<p>On Chrome OS, simply call $ref:usb.requestAccess. The permission
|
| - broker does this for you.</p>
|
| -
|
| -<h2 id="serial">Accessing serial devices</h2>
|
| -
|
| -<p>
|
| -You can use the serial API to read
|
| -and write from a serial device.
|
| -</p>
|
| -
|
| -<h3 id="requirement">Manifest requirement</h3>
|
| -
|
| -<p>
|
| -You must add the "serial" permission to the manifest file:
|
| -</p>
|
| -<pre data-filename="manifest.json">
|
| -"permissions": [
|
| - "serial"
|
| -]
|
| -</pre>
|
| -
|
| -<h3 id="listing">Listing available serial ports</h3>
|
| -
|
| -<p>
|
| -To get a list of available serial ports,
|
| -use the <code>getPorts()</code> method. <b>Note:</b> not all serial ports are available. The API uses a heuristic based on the name of the port to only expose serial devices that are expected to be safe.
|
| -</p>
|
| -
|
| -<pre>
|
| -var onGetPorts = function(ports) {
|
| - for (var i=0; i<ports.length; i++) {
|
| - console.log(ports[i]);
|
| - }
|
| -}
|
| -chrome.serial.getPorts(onGetPorts);
|
| -</pre>
|
| -
|
| -<h3 id="opening">Opening a serial device</h3>
|
| -
|
| -<p>
|
| -If you know the serial port name, you can open it for read and write using the <code>open</code> method:
|
| -</p>
|
| -
|
| -<pre>
|
| -chrome.serial.open(portName, options, openCallback)
|
| -</pre>
|
| -
|
| -<table border="0">
|
| - <tr>
|
| - <th scope="col"> Parameter </th>
|
| - <th scope="col"> Description </th>
|
| - </tr>
|
| - <tr>
|
| - <td>portName (string)</td>
|
| - <td>If your device's port name is unknown, you can use the <code>getPorts</code> method.</td>
|
| - </tr>
|
| - <tr>
|
| - <td>options (object)</td>
|
| - <td>Parameter object with one single value: <code>bitrate</code>, an integer specifying the desired bitrate used to communicate with the serial port.</td>
|
| - </tr>
|
| - <tr>
|
| - <td>openCallback</td>
|
| - <td>Invoked when the port has been successfully opened. The callback will be called with one parameter, <code>openInfo</code>, that has one attribute, <code>connectionId</code>. Save this id, because you will need it to actually communicate with the port.
|
| - </td>
|
| - </tr>
|
| -</table>
|
| -
|
| -<p>A simple example:</p>
|
| -
|
| -<pre>
|
| -var onOpen = function(connectionInfo) {
|
| - // The serial port has been opened. Save its id to use later.
|
| - _this.connectionId = connectionInfo.connectionId;
|
| - // Do whatever you need to do with the opened port.
|
| -}
|
| -// Open the serial port /dev/ttyS01
|
| -chrome.serial.open("/dev/ttyS01", {bitrate: 115200}, onOpen);
|
| -</pre>
|
| -
|
| -<h3 id="closing">Closing a serial port</h3>
|
| -
|
| -<p>
|
| -Closing a serial port is simple but very important. See the example below:
|
| -</p>
|
| -
|
| -<pre>
|
| -var onClose = function(result) {
|
| - console.log("Serial port closed");
|
| -}
|
| -chrome.serial.close(connectionId, onClose);
|
| -</pre>
|
| -
|
| -<h3 id="reading">Reading from a serial port</h3>
|
| -
|
| -<p>
|
| -The serial API reads from the serial port and
|
| -delivers the read bytes as an ArrayBuffer.
|
| -There is no guarantee that all the requested bytes, even if available in the port, will be read in one chunk.
|
| -The following example can accumulate read bytes, at most 128 at a time, until a new line is read,
|
| -and then call a listener with the <code>ArrayBuffer</code> bytes converted to a String:
|
| -</p>
|
| -
|
| -<pre>
|
| -var dataRead='';
|
| -
|
| -var onCharRead=function(readInfo) {
|
| - if (!connectionInfo) {
|
| - return;
|
| - }
|
| - if (readInfo && readInfo.bytesRead>0 && readInfo.data) {
|
| - var str=ab2str(readInfo.data);
|
| - if (str[readInfo.bytesRead-1]==='\n') {
|
| - dataRead+=str.substring(0, readInfo.bytesRead-1);
|
| - onLineRead(dataRead);
|
| - dataRead="";
|
| - } else {
|
| - dataRead+=str;
|
| - }
|
| - }
|
| - chrome.serial.read(connectionId, 128, onCharRead);
|
| - }
|
| -
|
| -/* Convert an ArrayBuffer to a String, using UTF-8 as the encoding scheme.
|
| - This is consistent with how Arduino sends characters by default */
|
| - var ab2str=function(buf) {
|
| - return String.fromCharCode.apply(null, new Uint8Array(buf));
|
| - };
|
| -</pre>
|
| -
|
| -<h3 id="writing">Writing to a serial port</h3>
|
| -
|
| -<p>
|
| -The writing routine is simpler than reading,
|
| -since the writing can occur all at once.
|
| -The only catch is that if your data protocol is String based,
|
| -you have to convert your output string to an <code>ArrayBuffer</code>.
|
| -See the code example below:
|
| -</p>
|
| -
|
| -<pre>
|
| -var writeSerial=function(str) {
|
| - chrome.serial.write(connectionId, str2ab(str), onWrite);
|
| -}
|
| -// Convert string to ArrayBuffer
|
| -var str2ab=function(str) {
|
| - var buf=new ArrayBuffer(str.length);
|
| - var bufView=new Uint8Array(buf);
|
| - for (var i=0; i<str.length; i++) {
|
| - bufView[i]=str.charCodeAt(i);
|
| - }
|
| - return buf;
|
| -}
|
| -</pre>
|
| -
|
| -<h3 id="flushing">Flushing a serial port buffer</h3>
|
| -
|
| -<p>
|
| -You can flush your serial port buffer by issuing the flush command:
|
| -</p>
|
| -
|
| -<pre>
|
| - chrome.serial.flush(connectionId, onFlush);
|
| -</pre>
|
| -
|
| -<p class="backtotop"><a href="#top">Back to top</a></p>
|
|
|