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