xreal-webxr/js_light/manager.js

462 lines
12 KiB
JavaScript

import Glasses from './glasses.js';
import * as Protocol from './protocol.js';
import * as ProtocolYmodem from './protocolYmodem.js';
import * as common from './../common.js'
// let devices = [];
const DEBUG = true;
// progress bar
let current
let total
/** check browser whether hid support */
// todo move to common
export function hidSupported() {
return !(navigator.hid === undefined);
}
/** check browser whether serial support */
// export function serialSupported() {
// return !(navigator.serial === undefined);
// }
// check glasses is open?
export function canCommand(device) {
if (device) {
let glasses = new Glasses(device);
return glasses.connect().then(() => {
return glasses.isMcu();
});
}
return false;
}
function getGlasses() {
return common.curGlasses;
}
export async function hasActivated(glasses) {
let activationReport = await glasses.sendReportTimeout(Protocol.MESSAGES.R_ACTIVATION_TIME);
if (!reportSuccess(activationReport) && activationReport.payload.length > 0) {
let time = Protocol.bytes2Time(activationReport.payload);
return time > 0;
}
return false;
}
/** activate the glasses */
export async function activate(timeStamp, flag) {
let glasses = await common.connectDevice();
if (!glasses) {
return false;
}
// if (await hasActivated(glasses)) {
// return true;
// }
// hardcode value = 300
// const time = new Uint8Array([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x01]);
let time
if (flag == 1) {
time = new Uint8Array([0xff, 0xff]);
} else {
let timeHex = Number(timeStamp).toString(16)
time = new Uint8Array(timeHex.toString().length);
for (let i = 0; i < timeHex.toString().length; i++) {
time[i] = Asc2Hex(timeHex.toString().slice(i, i + 1))
}
}
return glasses.sendReportTimeout(Protocol.MESSAGES.W_ACTIVATION_TIME, time, 1)
.then(report => {
return reportSuccess;
});
}
/** deactivate the glasses */
export async function deactivate() {
let glasses = await common.connectDevice();
if (!glasses) {
return false;
}
// 时间清除
activate('ff', 1)
const deactiveMessage = new Uint8Array([0x31]);
return glasses.sendReportTimeout(Protocol.MESSAGES.W_CANCEL_ACTIVATION, deactiveMessage, 1)
.then(report => {
return reportSuccess(report);
});
}
// Conversion from decimal to hexadecimal
function Asc2Hex(value) {
return ('0x' + value.charCodeAt().toString(16));
}
/** read firmware version MCU*/
export async function getFirmwareVersionInMcu() {
let glasses = await common.connectDevice();
if (!glasses) {
return 'not found device';
}
return glasses.sendReportTimeout(Protocol.MESSAGES.R_MCU_APP_FW_VERSION)
.then(report => {
if (reportSuccess) {
return String.fromCharCode.apply(null, report.payload);
}
});
}
/** read firmware version AUDIO*/
export async function getFirmwareVersionInAudio() {
let glasses = await common.connectDevice();
if (!glasses) {
return 'not found device';
}
return glasses.sendReportTimeout(Protocol.MESSAGES.R_AUDIO_APP_FW_VERSION)
.then(report => {
if (reportSuccess) {
return String.fromCharCode.apply(null, report.payload);
}
});
}
/** read firmware version OV580*/
export async function getFirmwareVersionInOv580() {
let glasses = await common.connectDevice();
if (!glasses) {
return 'not found device';
}
return glasses.sendReportTimeout(Protocol.MESSAGES.R_OV580_APP_FW_VERSION)
.then(report => {
if (reportSuccess) {
return String.fromCharCode.apply(null, report.payload);
}
});
}
export async function selectBinFile() {
const pickerOpts = {
types: [
{
description: 'firmware image',
accept: {
'bin/*': ['.bin']
}
},
],
excludeAcceptAllOption: true,
multiple: false
};
let filePaths = await window.showOpenFilePicker(pickerOpts);
if (filePaths.length > 0) {
return filePaths[0].getFile();
}
return null;
}
// function isBootDevice(device) {
// return device.vendorId === ProtocolYmodem.NREAL_VENDOR_ID
// && device.productId === ProtocolYmodem.BOOT_PRODUCT_ID;
// }
// 通过hid识别设备
// async function waitBootDevice() {
// let devices = await navigator.hid.getDevices().then(devices => {
// return devices.filter(isBootDevice);
// });
// if (devices.length > 0) {
// return devices[0];
// }
// navigator.hid.requestDevice({
// filters: [{ vendorId: Protocol.NREAL_VENDOR_ID, productId: Protocol.BOOT_PRODUCT_ID }]
// });
// const time = new Date().getTime();
// while ((new Date().getTime() - time) < 2000) {
// await new Promise(resolve => setTimeout(resolve, 20));
// devices = await navigator.hid.getDevices().then(devices => {
// return devices.filter(isBootDevice);
// });
// if (devices.length > 0) {
// return devices[0];
// }
// }
// }
export async function getSerialPort() {
if ('serial' in navigator) {
console.log('当前浏览器支持serial')
}
return navigator.serial.requestPort({
filters: [{ usbVendorId: ProtocolYmodem.NREAL_VENDOR_ID, usbProductId: ProtocolYmodem.BOOT_PRODUCT_ID }]
});
}
// NREAL GLASSES
// function isBootport(port){
// return port.serialNumber === "00000000001A"
// }
// 通过USB虚拟串口识别
async function waitSerialPort() {
let port = await navigator.serial.getPorts().then(port => {
return port;
});
if (port.length > 0) {
return port[0];
}
// MCU + AUDIO + 580
// Prompt user to select any serial port.
port = await getSerialPort()
return port
}
export async function upgradeInMcuForSerial(data){
let port = await waitSerialPort();
// let device = await waitBootDevice();
if (port) {
// open serial port
await port.open({ baudRate: 115200 }); //串口波特率
return sendFirmwareInMcu(port, data);
}
}
export async function upgradeInMcu(data) {
let glasses = await common.connectDevice();
if (!glasses) {
return false;
}
return glasses.sendReportTimeout(Protocol.MESSAGES.W_MCU_SUPER_B_JUMP_TO_A)
// .then(report => {
// if (reportSuccess) {
// return glasses.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_MCU_SUPER_A_FW_START);
// }
// })
.then(async (report) => {
if (reportSuccess) {
let port = await waitSerialPort();
// let device = await waitBootDevice();
if (port) {
// open serial port
await port.open({ baudRate: 115200 }); //串口波特率
return sendFirmwareInMcu(port, data);
}
}
});
}
// Delay synchronization program execution
function sleep(delay) {
return new Promise((resolve) => setTimeout(resolve, delay))
}
export async function upgradeInDp() {
let glasses = await common.connectDevice();
if (!glasses) {
return false;
}
// upgrade DP
if (DEBUG) console.log("send fw to upgrade the DP");
return glasses.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_DP, [], 1)
.then(async report => {
if (!reportSuccess(report)) {
if (glasses._reports.has(68)) {
glasses._reports.delete(68)
}
// wait for light dp upgrade completed
while (!glasses._reports.has(68)) {
await sleep(500)
}
return glasses._reports.get(68).payload[0] == 49
}
return false
});
}
// check glasses is air or light?
// export async function isAirOrLight(){
// let glasses = await common.connectDevice();
// if (!glasses) {
// return 'not found device';
// }
// if(glasses.device.productId == 1059 || glasses.device.productId == 1060){
// return 1
// }
// if(glasses.device.productId == 22332 || glasses.device.productId == 22336){
// return 2
// }
// }
// Listening for serial port response
async function listenSerial(reader, port) {
while (port.readable) {
try {
while (true) {
const { value, done } = await reader.read();
if (value) {
return value
}
}
} catch (error) {
// TODO: Handle non-fatal read error.
// console.log(error)
}
}
}
// Parameters required for the progress bar
function progress(cur, all) {
current = cur
total = all
}
async function sendFirmwareInMcu(port, data) {
data = new Uint8Array(data)
let ofs = 0;
const firstPackLen = 1024;
const fwLen = data.byteLength;
const writer = port.writable.getWriter();
const reader = port.readable.getReader();
// Write upgrade command
await writer.write(Protocol.cmd_build(Protocol.MESSAGES.W_UPDATE_MCU_SUPER_A_FW_START))
console.log(await listenSerial(reader, port))
// Transmission over serial port
// Ymodem
while (ofs < fwLen) {
progress(ofs, fwLen)
if ((ofs + 1024) > fwLen) {
let DATNB = ProtocolYmodem.cmd_build(data.slice(ofs, fwLen))
await writer.write(DATNB)
// console.log(await listenSerial(reader, port))
break;
}
let DATNB = ProtocolYmodem.cmd_build(data.slice(ofs, ofs + firstPackLen))
await writer.write(DATNB)
// console.log(await listenSerial(reader, port))
// .then(async (report)=>{
// while (port.readable) {
// const reader = port.readable.getReader();
// try {
// while (true) {
// const { value, done } = await reader.read();
// if (done) {
// // Allow the serial port to be closed later.
// reader.releaseLock();
// break;
// }
// if (value) {
// console.log(value);
// }
// }
// } catch (error) {
// // TODO: Handle non-fatal read error.
// }
// }
// })
ofs += 1024;
}
/* send finish */
// if (!reportSuccess(report)) {
// console.error('send fw data failed');
// return false;
// }
let EOT_FIRST = ProtocolYmodem.cmd_build_EOT()
await writer.write(EOT_FIRST)
// console.log(await listenSerial(reader, port))
let EOT_SECOND = ProtocolYmodem.cmd_build_EOT()
await writer.write(EOT_SECOND)
// console.log(await listenSerial(reader, port))
// let SOH = ProtocolYmodem.cmd_build_SOH()
// await writer.write(SOH)
// console.log(await listenSerial(reader, port))
/* jump to B */
await writer.write(Protocol.cmd_build(Protocol.MESSAGES.W_MCU_SUPER_A_JUMP_TO_B))
// Send the command to upgrade the DP
// await writer.write(Protocol.cmd_build(Protocol.MESSAGES.W_UPDATE_DP, [], 1))
// report = await bootDevice.sendReportTimeout(Protocol.MESSAGES.W_MCU_SUPER_A_JUMP_TO_B);
// if (!reportSuccess(report)) {
// console.error('send fw data failed');
// return false;
// }
// close serial port
// reader.releaseLock();
// await port.close();
return true;
}
/** read Glasses SN*/
export async function getSN() {
let glasses = await common.connectDevice();
if (!glasses) {
return 'not found device';
}
return glasses.sendReportTimeout(Protocol.MESSAGES.R_GLASSID)
.then(report => {
if (reportSuccess) {
return String.fromCharCode.apply(null, report.payload);
}
});
}
function reportSuccess(report) {
return (report && report.payload.length === 0);
}
export {
current,
total,
}