OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview Implements a low-level gnubby driver based on chrome.usb. | 6 * @fileoverview Implements a low-level gnubby driver based on chrome.usb. |
7 */ | 7 */ |
8 'use strict'; | 8 'use strict'; |
9 | 9 |
10 /** | 10 /** |
(...skipping 28 matching lines...) Expand all Loading... |
39 /** | 39 /** |
40 * Namespace for the llUsbGnubby implementation. | 40 * Namespace for the llUsbGnubby implementation. |
41 * @const | 41 * @const |
42 */ | 42 */ |
43 llUsbGnubby.NAMESPACE = 'usb'; | 43 llUsbGnubby.NAMESPACE = 'usb'; |
44 | 44 |
45 /** Destroys this low-level device instance. */ | 45 /** Destroys this low-level device instance. */ |
46 llUsbGnubby.prototype.destroy = function() { | 46 llUsbGnubby.prototype.destroy = function() { |
47 if (!this.dev) return; // Already dead. | 47 if (!this.dev) return; // Already dead. |
48 | 48 |
| 49 this.gnubbies_.removeOpenDevice( |
| 50 {namespace: llUsbGnubby.NAMESPACE, device: this.id}); |
49 this.closing = true; | 51 this.closing = true; |
50 | 52 |
51 console.log(UTIL_fmt('llUsbGnubby.destroy()')); | 53 console.log(UTIL_fmt('llUsbGnubby.destroy()')); |
52 | 54 |
53 // Synthesize a close error frame to alert all clients, | 55 // Synthesize a close error frame to alert all clients, |
54 // some of which might be in read state. | 56 // some of which might be in read state. |
55 // | 57 // |
56 // Use magic CID 0 to address all. | 58 // Use magic CID 0 to address all. |
57 this.publishFrame_(new Uint8Array([ | 59 this.publishFrame_(new Uint8Array([ |
58 0, 0, 0, 0, // broadcast CID | 60 0, 0, 0, 0, // broadcast CID |
59 llGnubby.CMD_ERROR, | 61 llGnubby.CMD_ERROR, |
60 0, 1, // length | 62 0, 1, // length |
61 llGnubby.GONE]).buffer); | 63 llGnubby.GONE]).buffer); |
62 | 64 |
63 // Set all clients to closed status and remove them. | 65 // Set all clients to closed status and remove them. |
64 while (this.clients.length != 0) { | 66 while (this.clients.length != 0) { |
65 var client = this.clients.shift(); | 67 var client = this.clients.shift(); |
66 if (client) client.closed = true; | 68 if (client) client.closed = true; |
67 } | 69 } |
68 | 70 |
69 if (this.lockTID) { | 71 if (this.lockTID) { |
70 window.clearTimeout(this.lockTID); | 72 window.clearTimeout(this.lockTID); |
71 this.lockTID = null; | 73 this.lockTID = null; |
72 } | 74 } |
73 | 75 |
74 var dev = this.dev; | 76 var dev = this.dev; |
75 this.dev = null; | 77 this.dev = null; |
76 | 78 |
77 var self = this; | |
78 | |
79 function onClosed() { | |
80 console.log(UTIL_fmt('Device ' + dev.handle + ' closed')); | |
81 self.gnubbies_.removeOpenDevice( | |
82 {namespace: llUsbGnubby.NAMESPACE, device: self.id}); | |
83 } | |
84 | |
85 // Release first. | |
86 chrome.usb.releaseInterface(dev, 0, function() { | 79 chrome.usb.releaseInterface(dev, 0, function() { |
87 console.log(UTIL_fmt('Device ' + dev.handle + ' released')); | 80 console.log(UTIL_fmt('Device ' + dev.handle + ' released')); |
88 chrome.usb.closeDevice(dev, onClosed); | 81 chrome.usb.closeDevice(dev, function() { |
| 82 console.log(UTIL_fmt('Device ' + dev.handle + ' closed')); |
| 83 }); |
89 }); | 84 }); |
90 }; | 85 }; |
91 | 86 |
92 /** | 87 /** |
93 * Push frame to all clients. | 88 * Push frame to all clients. |
94 * @param {ArrayBuffer} f Data frame | 89 * @param {ArrayBuffer} f Data frame |
95 * @private | 90 * @private |
96 */ | 91 */ |
97 llUsbGnubby.prototype.publishFrame_ = function(f) { | 92 llUsbGnubby.prototype.publishFrame_ = function(f) { |
98 var old = this.clients; | 93 var old = this.clients; |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 this.lockMillis); | 331 this.lockMillis); |
337 } | 332 } |
338 } | 333 } |
339 }; | 334 }; |
340 | 335 |
341 /** | 336 /** |
342 * Queue command to be sent. | 337 * Queue command to be sent. |
343 * If queue was empty, initiate the write. | 338 * If queue was empty, initiate the write. |
344 * @param {number} cid The client's channel ID. | 339 * @param {number} cid The client's channel ID. |
345 * @param {number} cmd The command to send. | 340 * @param {number} cmd The command to send. |
346 * @param {ArrayBuffer} data Command argument data | 341 * @param {ArrayBuffer|Uint8Array} data Command argument data |
347 */ | 342 */ |
348 llUsbGnubby.prototype.queueCommand = function(cid, cmd, data) { | 343 llUsbGnubby.prototype.queueCommand = function(cid, cmd, data) { |
349 if (!this.dev) return; | 344 if (!this.dev) return; |
350 if (!this.checkLock_(cid, cmd)) return; | 345 if (!this.checkLock_(cid, cmd)) return; |
351 | 346 |
352 var u8 = new Uint8Array(data); | 347 var u8 = new Uint8Array(data); |
353 var frame = new Uint8Array(u8.length + 7); | 348 var frame = new Uint8Array(u8.length + 7); |
354 | 349 |
355 frame[0] = cid >>> 24; | 350 frame[0] = cid >>> 24; |
356 frame[1] = cid >>> 16; | 351 frame[1] = cid >>> 16; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 * @param {Gnubbies} gnubbies Gnubbies singleton instance | 466 * @param {Gnubbies} gnubbies Gnubbies singleton instance |
472 */ | 467 */ |
473 llUsbGnubby.register = function(gnubbies) { | 468 llUsbGnubby.register = function(gnubbies) { |
474 var USB_GNUBBY_IMPL = { | 469 var USB_GNUBBY_IMPL = { |
475 enumerate: llUsbGnubby.enumerate, | 470 enumerate: llUsbGnubby.enumerate, |
476 deviceToDeviceId: llUsbGnubby.deviceToDeviceId, | 471 deviceToDeviceId: llUsbGnubby.deviceToDeviceId, |
477 open: llUsbGnubby.open | 472 open: llUsbGnubby.open |
478 }; | 473 }; |
479 gnubbies.registerNamespace(llUsbGnubby.NAMESPACE, USB_GNUBBY_IMPL); | 474 gnubbies.registerNamespace(llUsbGnubby.NAMESPACE, USB_GNUBBY_IMPL); |
480 }; | 475 }; |
OLD | NEW |