16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// found in the LICENSE file.
46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/**
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @fileoverview Interface for representing a low-level gnubby device.
76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) */
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)'use strict';
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/**
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * Low level gnubby 'driver'. One per physical USB device.
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @interface
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) */
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)function GnubbyDevice() {}
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Commands of the USB interface.
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Echo data through local processor only */
186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.CMD_PING = 0x81;
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Perform reset action and read ATR string */
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.CMD_ATR = 0x82;
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Send raw APDU */
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.CMD_APDU = 0x83;
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Send lock channel command */
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.CMD_LOCK = 0x84;
256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Obtain system information record */
266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.CMD_SYSINFO = 0x85;
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Obtain an unused channel ID */
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.CMD_INIT = 0x86;
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Control prompt flashing */
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.CMD_PROMPT = 0x87;
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Send device identification wink */
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.CMD_WINK = 0x88;
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** USB test */
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.CMD_USB_TEST = 0xb9;
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Device Firmware Upgrade */
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.CMD_DFU = 0xba;
376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Protocol resync command */
386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.CMD_SYNC = 0xbc;
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Error response */
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.CMD_ERROR = 0xbf;
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Low-level error codes.
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** No error */
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.OK = 0;
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Invalid command */
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.INVALID_CMD = 1;
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Invalid parameter */
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.INVALID_PAR = 2;
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Invalid message length */
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.INVALID_LEN = 3;
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Invalid message sequencing */
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.INVALID_SEQ = 4;
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Message has timed out */
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.TIMEOUT = 5;
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** CHannel is busy */
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.BUSY = 6;
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Access denied */
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.ACCESS_DENIED = 7;
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Device is gone */
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.GONE = 8;
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Verification error */
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.VERIFY_ERROR = 9;
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Command requires channel lock */
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.LOCK_REQUIRED = 10;
656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Sync error */
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.SYNC_FAIL = 11;
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Other unspecified error */
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.OTHER = 127;
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Remote helper errors.
716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Not a remote helper */
726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.NOTREMOTE = 263;
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Could not reach remote endpoint */
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.COULDNOTDIAL = 264;
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// chrome.usb-related errors.
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** No device */
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.NODEVICE = 512;
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Permission denied */
806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.NOPERMISSION = 666;
816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/** Destroys this low-level device instance. */
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.prototype.destroy = function() {};
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/**
866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * Register a client for this gnubby.
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @param {*} who The client.
886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) */
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.prototype.registerClient = function(who) {};
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/**
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * De-register a client.
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @param {*} who The client.
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @return {number} The number of remaining listeners for this device, or -1
956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *     if this had no clients to start with.
966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) */
976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.prototype.deregisterClient = function(who) {};
986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/**
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @param {*} who The client.
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @return {boolean} Whether this device has who as a client.
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) */
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.prototype.hasClient = function(who) {};
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/**
1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * Queue command to be sent.
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * If queue was empty, initiate the write.
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @param {number} cid The client's channel ID.
1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @param {number} cmd The command to send.
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @param {ArrayBuffer|Uint8Array} data Command data
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) */
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.prototype.queueCommand = function(cid, cmd, data) {};
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/**
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @typedef {{
1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *   vendorId: number,
1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *   productId: number
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * }}
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) */
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)var UsbDeviceSpec;
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/**
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * Gets the list of USB devices permitted by this app.
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @param {function(!Array.<!UsbDeviceSpec>)} cb Called back with a list of USB
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *     device specifiers.
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) */
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)GnubbyDevice.getPermittedUsbDevices = function(cb) {
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  chrome.permissions.getAll(function(perms) {
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!perms.hasOwnProperty('permissions')) {
1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      cb([]);
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      return;
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    var devs = [];
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    var permissions = perms['permissions'];
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    for (var i = 0; i < permissions.length; i++) {
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      var permission = permissions[i];
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (typeof permission === 'object' &&
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          permission.hasOwnProperty('usbDevices')) {
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        for (var j = 0; j < permission['usbDevices'].length; j++) {
1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          var dev = permission['usbDevices'][j];
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          devs.push(
1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              {'vendorId': dev['vendorId'], 'productId': dev['productId']});
1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        }
1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      }
1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    cb(devs);
1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  });
1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)};
149