我在Mac和PC上都运行了相同的基本测试,但是当我尝试在PC上运行时似乎失败了。这令人难以置信,因为我在chrome上构建的全部原因是因为我假设是跨平台的HID API。该API的Windows端口是否存在错误?
COMMS.transmitting = true;
console.log("Sending...");
chrome.hid.send(connection_, REPORT_ID, arrayBuffer, function() {
if (chrome.runtime.lastError) {
throw chrome.runtime.lastError.message;
COMMS.transmitting = false;
return;
}
console.log("done sending.");
COMMS.transmitting = false;
console.log("Receiving...");
COMMS.receiving = true;
chrome.hid.receive(connection_, function(reportId, data) {
if (chrome.runtime.lastError) {
throw chrome.runtime.lastError.message;
COMMS.receiving = false;
return;
}
console.log("done receiving.");
COMMS.receiving = false;
responseHandler(data);
});
});
完整的comms.js文件:
//
// Description: Communication abstractions. This is currently built on the
// chrome.hid API.
//
var COMMS = (function() {
// -------------------------------------------------------------------------------------------------------------------
// Private Constants
// -------------------------------------------------------------------------------------------------------------------
var REPORT_ID = 0;
var MAX_NUM_RX_BYTES = 64;
var MAX_NUM_TX_BYTES = 64;
// -------------------------------------------------------------------------------------------------------------------
// Private Properties
// -------------------------------------------------------------------------------------------------------------------
var connection_;
var onDeviceConnected_;
// -------------------------------------------------------------------------------------------------------------------
// Private Methods
// -------------------------------------------------------------------------------------------------------------------
var enumerateDevices = function() {
var deviceIds = [];
var permissions = chrome.runtime.getManifest().permissions;
for (var i = 0; i < permissions.length; i++) {
var p = permissions[i];
if (p.hasOwnProperty('usbDevices')) {
deviceIds = deviceIds.concat(p.usbDevices);
}
}
// REMOVE AFTER TESING
deviceFilter = {
vendorId: 1234, // replace with your own VID/PID combo, should match permissions values
productId: 5678
};
// Only search for the first VID/PID device specified in the permissions
//chrome.hid.getDevices(deviceIds[0], onDevicesEnumerated);
chrome.hid.getDevices(deviceFilter, onDevicesEnumerated);
};
var onDevicesEnumerated = function(devices) {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError.message);
return;
}
if (1 !== devices.length) {
console.log("Ensure one (and only one) device is inserted.");
// Schedule the next attempt
window.setTimeout(enumerateDevices, 2000);
} else {
console.log("Found a device");
connectDevice(devices[0].deviceId);
}
};
var connectDevice = function(deviceId) {
chrome.hid.connect(deviceId, function(connectInfo) {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError.message);
return;
}
if (!connectInfo) {
console.log("Failed to connect to device.");
this.transmitting = false;
this.receiving = false;
return;
}
connection_ = connectInfo.connectionId;
console.log("connection: " + connection_);
onDeviceConnected_();
});
};
var byteToHex = function(value) {
if (value < 16) {
return '0' + value.toString(16);
}
return value.toString(16);
};
return {
// -----------------------------------------------------------------------------------------------------------------
// Public Properties
// -----------------------------------------------------------------------------------------------------------------
transmitting: false,
receiving: false,
// -----------------------------------------------------------------------------------------------------------------
// Public Methods
// -----------------------------------------------------------------------------------------------------------------
init: function(onConnectedHandler) {
// Initialize module memory
connection_ = -1;
onDeviceConnected_ = onConnectedHandler;
// Begin the search for a single, predetermined device
enumerateDevices();
},
isConnected: function() {
return (-1 !== connection_);
},
send: function(arrayBuffer, responseHandler) {
if (-1 === connection_) {
throw "Attempted to send data with no device connected.";
return;
}
if (true === COMMS.receiving) {
throw "Waiting for a response to a previous message. Aborting.";
return;
}
if (true === COMMS.transmitting) {
throw "Still waiting to finish sending a previous message.";
return;
}
if (-1 === connection_) {
throw "Attempted to send without a device connected.";
return;
}
if (MAX_NUM_TX_BYTES < arrayBuffer.byteLength) {
throw "Given data is too long to send as a single message.";
return;
}
if (0 === arrayBuffer.byteLength) {
throw "Given data to transmit is empty";
return;
}
COMMS.transmitting = true;
console.log("Sending...");
chrome.hid.send(connection_, REPORT_ID, arrayBuffer, function() {
if (chrome.runtime.lastError) {
throw chrome.runtime.lastError.message;
COMMS.transmitting = false;
return;
}
console.log("done sending.");
COMMS.transmitting = false;
console.log("Receiving...");
COMMS.receiving = true;
chrome.hid.receive(connection_, function(reportId, data) {
if (chrome.runtime.lastError) {
throw chrome.runtime.lastError.message;
COMMS.receiving = false;
return;
}
console.log("done receiving.");
COMMS.receiving = false;
responseHandler(data);
});
});
},
disconnectDevice: function() {
if (-1 === connection_) {
console.log("Attempted to disconnect device with no device connected");
COMMS.transmitting = false;
COMMS.receiving = false;
return;
}
chrome.hid.disconnect(connection_, function() {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError.message);
return;
}
// TODO: how to check that successfully disconnected?
console.log("Finished disconnecting device. Success?");
COMMS.transmitting = false;
COMMS.receiving = false;
});
},
hexStringToArrayBuffer: function(s) {
var bytes = new Uint8Array(s.length);
for (var i = 0; i < s.length; i += 3) {
if (' ' === s[i]) {
console.log('Error parsing hex string');
return;
}
bytes[i] = parseInt(s.substring(i, (i + 2)), 16);
}
return bytes.buffer;
},
byteArrayToFormattedString: function(byteArray) {
var s = '';
for (var i = 0; i < byteArray.length; i += 16) {
var sliceLength = Math.min(byteArray.length - i, 16);
var lineBytes = new Uint8Array(byteArray.buffer, i, sliceLength);
for (var j = 0; j < lineBytes.length; ++j) {
s += byteToHex(lineBytes[j]) + ' ';
}
for (var j = 0; j < lineBytes.length; ++j) {
var ch = String.fromCharCode(lineBytes[j]);
if (lineBytes[j] < 32 || lineBytes[j] > 126)
ch = '.';
s += ch;
}
s += '\n';
}
return s;
}
}
})();
最佳答案
OP再次询问了这个问题here。抱歉,我没有注意到对最初问题的回答,请在此处进行后续操作。问题是Windows要求缓冲区必须是设备期望的完整报告大小。我已针对Chromium提交了a bug,以跟踪添加变通办法或至少找到更好的错误消息以查明问题。
通常,通过使用--enable-logging --v=1
命令行选项启用详细日志记录,您可以从chrome.hid API中获取更详细的错误消息。 Chrome日志记录的完整文档为here。