-
Notifications
You must be signed in to change notification settings - Fork 0
/
port.js
105 lines (89 loc) · 2.41 KB
/
port.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
class Port {
static async getPorts() {
const devices = await navigator.usb.getDevices();
return devices.map(device => new Port(device));
};
static async requestPort() {
const filters = [
{ 'vendorId': 0x2341, 'productId': 0x8036 },
{ 'vendorId': 0x2341, 'productId': 0x8037 },
{ 'vendorId': 0x2341, 'productId': 0x804d },
{ 'vendorId': 0x2341, 'productId': 0x804e },
{ 'vendorId': 0x2341, 'productId': 0x804f },
{ 'vendorId': 0x2341, 'productId': 0x8050 },
];
const device = await navigator.usb.requestDevice({ filters });
return new Port(device);
}
constructor(device) {
this.device_ = device
}
async open() {
await this.device_.open()
if(this.device_.configuration === null) {
await this.device_.selectConfiguration(1);
}
console.log(this.device_.configurations);
for(const iface of this.device_.configuration.interfaces) {
console.log('Interface %d:', iface.interfaceNumber, iface);
for(const alt of iface.alternates) {
const matches = alt.interfaceClass === 0xff;
console.log('Alternate:', alt);
if(matches) {
this.interfaceNumber_ = iface.interfaceNumber;
}
for(const endpoint of alt.endpoints) {
console.log('Endpoint %d:', endpoint.endpointNumber, endpoint);
if(matches && endpoint.direction == 'out') {
this.endpointOut_ = endpoint.endpointNumber;
}
if(matches && endpoint.direction == 'in') {
this.endpointIn_ = endpoint.endpointNumber;
}
}
}
}
await this.device_.claimInterface(this.interfaceNumber_);
await this.device_.selectAlternateInterface(this.interfaceNumber_, 0);
await this.device_.controlTransferOut({
requestType: 'class',
recipient: 'interface',
request: 0x22,
value: 0x01,
index: this.interfaceNumber_
});
}
read(cb) {
let reading = true;
function stop() {
reading = false;
}
const loop = async () => {
while(reading) {
try {
const result = await this.device_.transferIn(this.endpointIn_, 64);
cb(null, result.data);
} catch(e) {
cb(e);
break;
}
}
};
loop();
return stop;
}
async close() {
await this.device_.controlTransferOut({
requestType: 'class',
recipient: 'interface',
request: 0x22,
value: 0x00,
index: this.interfaceNumber_
});
await this.device_.close();
}
async send(data) {
const buffer = Uint8Array.from(data);
return this.device_.transferOut(this.endpointOut_, buffer);
}
}