603 lines
17 KiB
JavaScript
603 lines
17 KiB
JavaScript
|
||
import Glasses from './glasses.js';
|
||
import * as Protocol from './protocol.js';
|
||
import * as common from './../common.js'
|
||
|
||
|
||
// let devices = [];
|
||
const DEBUG = true;
|
||
// progress bar
|
||
let current
|
||
let total
|
||
// DP progress
|
||
let dpCurrent
|
||
// DSP progress
|
||
let DspSecond
|
||
let DspThrid
|
||
|
||
/** check browser whether hid support */
|
||
// todo move to common
|
||
export function hidSupported() {
|
||
return !(navigator.hid === undefined);
|
||
}
|
||
|
||
|
||
// check glasses is open?
|
||
// note we filter out things that arent the master control unit
|
||
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() {
|
||
let glasses = await common.connectDevice();
|
||
if (!glasses) {
|
||
return false;
|
||
}
|
||
|
||
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) {
|
||
|
||
// let glasses = await common.connectDevice();
|
||
// if (!glasses) {
|
||
// return false;
|
||
// }
|
||
|
||
// // hardcode value = 300
|
||
// // 3C 4B 46 52 54 41 01
|
||
// const time = Protocol.time2Bytes(timeStamp);
|
||
// return glasses.sendReportTimeout(Protocol.MESSAGES.W_ACTIVATION_TIME, time)
|
||
// .then(report => {
|
||
// return reportSuccess;
|
||
// });
|
||
// }
|
||
|
||
// /** deactivate the glasses */
|
||
// export async function deactivate() {
|
||
// let glasses = await common.connectDevice();
|
||
// if (!glasses) {
|
||
// return false;
|
||
// }
|
||
// return glasses.sendReportTimeout(Protocol.MESSAGES.W_CANCEL_ACTIVATION)
|
||
// .then(report => {
|
||
// return reportSuccess;
|
||
// });
|
||
// }
|
||
|
||
// Conversion from decimal to hexadecimal
|
||
function Decimal2Hex(value) {
|
||
if (value.toString(16).length == 1) {
|
||
return ('0x0' + value.toString(16))
|
||
} else {
|
||
return ('0x' + value.toString(16))
|
||
}
|
||
}
|
||
|
||
/** read firmware MCU version*/
|
||
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(report)) {
|
||
return String.fromCharCode.apply(null, report.payload);
|
||
}
|
||
});
|
||
}
|
||
|
||
/** read firmware DP version*/
|
||
export async function getFirmwareVersionInDp() {
|
||
let glasses = await common.connectDevice();
|
||
if (!glasses) {
|
||
return 'not found device';
|
||
}
|
||
return glasses.sendReportTimeout(Protocol.MESSAGES.R_DP7911_FW_VERSION)
|
||
.then(report => {
|
||
if (reportSuccess(report)) {
|
||
return String.fromCharCode.apply(null, report.payload);
|
||
}
|
||
});
|
||
}
|
||
|
||
/** read firmware DSP version*/
|
||
export async function getFirmwareVersionInDsp() {
|
||
let glasses = await common.connectDevice();
|
||
if (!glasses) {
|
||
return 'not found device';
|
||
}
|
||
return glasses.sendReportTimeout(Protocol.MESSAGES.R_DSP_VERSION)
|
||
.then(report => {
|
||
if (reportSuccess(report)) {
|
||
return String.fromCharCode.apply(null, report.payload);
|
||
}
|
||
});
|
||
}
|
||
|
||
// Parameters required for the progress bar
|
||
// function progress(cur, all) {
|
||
// current = cur
|
||
// total = all
|
||
// document.getElementById('progress').innerText = parseInt((current / total) * 100) + 1 + '%'
|
||
// }
|
||
|
||
// function progressInDp(cur) {
|
||
// current = cur
|
||
// document.getElementById('progressDp').innerText = current + '%'
|
||
// }
|
||
|
||
// 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 === Protocol.NREAL_VENDOR_ID
|
||
&& device.productId === Protocol.BOOT_PRODUCT_ID;
|
||
}
|
||
|
||
async function waitBootDevice() {
|
||
let devices = await navigator.hid.getDevices().then(devices => {
|
||
return devices.filter(isBootDevice);
|
||
});
|
||
|
||
if (devices.length > 0) {
|
||
return devices[0];
|
||
}
|
||
// await requestDevice()
|
||
|
||
await navigator.hid.requestDevice({
|
||
filters: [{ vendorId: Protocol.NREAL_VENDOR_ID, productId: Protocol.NREAL_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 upgradeInMcu(data) {
|
||
// let glasses = await common.connectDevice();
|
||
// if (!glasses) {
|
||
// return false;
|
||
// }
|
||
// return glasses.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_MCU_APP_FW_PREPARE)
|
||
// .then(report => {
|
||
// if (reportSuccess(report)) {
|
||
// return glasses.sendReportTimeout(Protocol.MESSAGES.W_MCU_APP_JUMP_TO_BOOT);
|
||
// }
|
||
// }).then(async (report) => {
|
||
// if (reportSuccess(report)) {
|
||
// let device = await waitBootDevice();
|
||
// if (await canCommand(device)) {
|
||
// return sendFirmwareInMcu(new Glasses(device), data);
|
||
// }
|
||
// }
|
||
|
||
// });
|
||
// }
|
||
|
||
export function Asc2Hex(value) {
|
||
return ('0x' + value.charCodeAt().toString(16));
|
||
}
|
||
|
||
/** need to upgrade firmware DSP version? */
|
||
// export async function isNeedUpgradeInDsp(version) {
|
||
// let glasses = await common.connectDevice();
|
||
// if (!glasses) {
|
||
// return 'not found device';
|
||
// }
|
||
// let HexVersion = version.split('').map((item, index) => {
|
||
// return Asc2Hex(item)
|
||
// })
|
||
// return glasses.sendReportTimeout(Protocol.MESSAGES.R_IS_NEED_UPGRADE_DSP_FW, HexVersion)
|
||
// .then(report => {
|
||
// if (reportSuccess(report)) {
|
||
// return report.payload[0]
|
||
// }
|
||
// });
|
||
// }
|
||
|
||
export async function upgradeInDsp(data) {
|
||
let glasses = await common.connectDevice();
|
||
if (!glasses) {
|
||
return false;
|
||
}
|
||
return sendFirmwareInDsp(glasses, data);
|
||
}
|
||
|
||
/** need to upgrade firmware DP version? */
|
||
export async function isNeedUpgradeInDp() {
|
||
let glasses = await common.connectDevice();
|
||
if (!glasses) {
|
||
return 'not found device';
|
||
}
|
||
return glasses.sendReportTimeout(Protocol.MESSAGES.R_DP7911_FW_IS_UPDATE)
|
||
.then(report => {
|
||
if (reportSuccess(report)) {
|
||
return report.payload[0]
|
||
}
|
||
});
|
||
}
|
||
|
||
export async function upgradeInDp() {
|
||
let glasses = await common.connectDevice();
|
||
if (!glasses) {
|
||
return false;
|
||
}
|
||
// 添加眼镜休眠时间
|
||
const time = Protocol.time2Bytes('600');
|
||
return glasses.sendReportTimeout(Protocol.MESSAGES.W_SLEEP_TIME, time)
|
||
.then(report => {
|
||
if (reportSuccess(report)) {
|
||
return glasses.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_DP)
|
||
.then(async report => {
|
||
if (reportSuccess(report)) {
|
||
// wait for air dp upgrade completed
|
||
while(!glasses._reports.has(27661) && common.curGlasses){
|
||
await sleep(500)
|
||
dpCurrent = glasses._reports.get(27660) ? glasses._reports.get(27660).status : 0
|
||
progressInDp(dpCurrent)
|
||
}
|
||
|
||
return glasses._reports.get(27661) ? glasses._reports.get(27661).status == 0 : false
|
||
}
|
||
|
||
return false
|
||
});
|
||
}
|
||
});
|
||
|
||
}
|
||
|
||
|
||
async function sendFirmwareInMcu(bootDevice, data) {
|
||
|
||
let ofs = 0;
|
||
const firstPackLen = 24;
|
||
const fwLen = data.byteLength;
|
||
|
||
|
||
|
||
|
||
let report = await bootDevice.sendReportTimeout(
|
||
Protocol.MESSAGES.W_UPDATE_MCU_APP_FW_START,
|
||
data.slice(ofs, ofs + firstPackLen));
|
||
if (!reportSuccess(report)) {
|
||
console.error('send fw data failed');
|
||
return false;
|
||
}
|
||
ofs += firstPackLen;
|
||
|
||
while (ofs < fwLen) {
|
||
progress(ofs, fwLen)
|
||
if ((ofs + 42) > fwLen) {
|
||
report = await bootDevice.sendReportTimeout(
|
||
Protocol.MESSAGES.W_UPDATE_MCU_APP_FW_TRANSMIT,
|
||
data.slice(ofs, fwLen));
|
||
if (!reportSuccess(report)) {
|
||
console.error('send fw data failed');
|
||
return false;
|
||
}
|
||
}
|
||
report = await bootDevice.sendReportTimeout(
|
||
Protocol.MESSAGES.W_UPDATE_MCU_APP_FW_TRANSMIT,
|
||
data.slice(ofs, ofs + 42));
|
||
|
||
if (!reportSuccess(report)) {
|
||
console.error('send fw data failed');
|
||
return false;
|
||
}
|
||
ofs += 42;
|
||
}
|
||
|
||
/* send finish */
|
||
report = await bootDevice.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_MCU_APP_FW_FINISH);
|
||
// if (!reportSuccess(report)) {
|
||
// console.error('send fw data failed');
|
||
// return false;
|
||
// }
|
||
/* jump to app */
|
||
report = await bootDevice.sendReportTimeout(Protocol.MESSAGES.W_BOOT_JUMP_TO_APP);
|
||
// if (!reportSuccess(report)) {
|
||
// console.error('send fw data failed');
|
||
// return false;
|
||
// }
|
||
|
||
// Send the command to upgrade the DP
|
||
// report = await bootDevice.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_DP);
|
||
|
||
|
||
current = 0
|
||
total = 0
|
||
return true;
|
||
|
||
|
||
}
|
||
|
||
|
||
async function sendFirmwareInDsp(glasses, data) {
|
||
|
||
let ofs = 0;
|
||
let sendBufferLength = 0
|
||
const firstPackLen = 24;
|
||
const fwLen = data.byteLength;
|
||
|
||
|
||
// prepare upgrade dsp
|
||
await glasses.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_DSP_APP_FW_PREPARE);
|
||
|
||
// wait for air dsp upgrade boot
|
||
while (!glasses._reports.has(27663)) {
|
||
await sleep(100)
|
||
}
|
||
|
||
// await sleep(30000)
|
||
|
||
let report = await glasses.sendReportTimeout(
|
||
Protocol.MESSAGES.W_UPDATE_DSP_APP_FW_START,
|
||
data.slice(ofs, ofs + firstPackLen));
|
||
if (!reportSuccess(report)) {
|
||
console.error('send fw data failed');
|
||
return false;
|
||
}
|
||
ofs += firstPackLen;
|
||
|
||
while (ofs < fwLen) {
|
||
if ((ofs + 42) <= fwLen) {
|
||
progress(ofs, fwLen)
|
||
}
|
||
if ((ofs + 42) > fwLen) {
|
||
report = await glasses.sendReportTimeout(
|
||
Protocol.MESSAGES.W_UPDATE_DSP_APP_FW_TRANSMIT,
|
||
data.slice(ofs, fwLen));
|
||
if (!reportSuccess(report)) {
|
||
console.error('send fw data failed');
|
||
return false;
|
||
}
|
||
|
||
// 最后一包4K发送
|
||
|
||
// air DSP one package write finish, wait a while
|
||
// while(!glasses._reports.has(27662)){
|
||
// await sleep(100)
|
||
// }
|
||
// glasses._reports.delete(27662)
|
||
await sleep(300)
|
||
|
||
sendBufferLength = 0
|
||
|
||
break
|
||
}
|
||
report = await glasses.sendReportTimeout(
|
||
Protocol.MESSAGES.W_UPDATE_DSP_APP_FW_TRANSMIT,
|
||
data.slice(ofs, ofs + 42));
|
||
|
||
|
||
if (!reportSuccess(report)) {
|
||
console.error('send fw data failed');
|
||
return false;
|
||
}
|
||
ofs += 42;
|
||
sendBufferLength += 42
|
||
|
||
if (sendBufferLength >= 4096) {
|
||
// 等待4K包传完回送消息
|
||
|
||
// air DSP one package write finish, wait a while
|
||
while (!(glasses._reports.has(27662) && (glasses._reports.get(27662).status == 0 || glasses._reports.get(27662).status == 1))) {
|
||
// while(!glasses._reports.has(27662)){
|
||
await sleep(100)
|
||
}
|
||
glasses._reports.delete(27662)
|
||
|
||
// await sleep(300)
|
||
|
||
|
||
sendBufferLength -= 4096
|
||
}
|
||
}
|
||
|
||
/* send finish */
|
||
report = await glasses.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_DSP_APP_FW_FINISH);
|
||
// if (!reportSuccess(report)) {
|
||
// console.error('send fw data failed');
|
||
// return false;
|
||
// }
|
||
// dsp write bin ==> first 100%
|
||
progress(ofs,fwLen)
|
||
/* Check whether the upgrade is complete */
|
||
// air DSP judge for flash&boot
|
||
// 删除之前刷新boot的过程,dsp重新刷新
|
||
glasses._reports.delete(27664)
|
||
while(!(glasses._reports.has(27664) && (glasses._reports.get(27664).status == 100))){
|
||
if(common.curGlasses){
|
||
await sleep(100)
|
||
DspSecond = glasses._reports.has(27664) ? glasses._reports.get(27664).status : 0
|
||
}else{
|
||
return false
|
||
}
|
||
}
|
||
DspSecond = 100
|
||
|
||
while(!(glasses._reports.has(27667) && (glasses._reports.get(27667).status == 100))){
|
||
if(common.curGlasses){
|
||
await sleep(100)
|
||
DspThrid = glasses._reports.has(27667) ? glasses._reports.get(27667).status : 0
|
||
}else{
|
||
return false
|
||
}
|
||
}
|
||
DspThrid = 100
|
||
|
||
while (!(glasses._reports.has(27668) && (glasses._reports.get(27668).status == 0))) {
|
||
await sleep(100)
|
||
}
|
||
|
||
// report = await glasses.sendReportTimeout(Protocol.MESSAGES.E_DSP_UPDATE_ENDING);
|
||
|
||
current = 0
|
||
total = 0
|
||
DspSecond = 0
|
||
DspThrid = 0
|
||
return true;
|
||
|
||
|
||
}
|
||
|
||
// Delay synchronization program execution
|
||
function sleep(delay) {
|
||
return new Promise((resolve) => setTimeout(resolve, delay))
|
||
}
|
||
|
||
|
||
/** read air 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(report)) {
|
||
return String.fromCharCode.apply(null, report.payload);
|
||
}
|
||
});
|
||
}
|
||
|
||
/** init air IMU tracking mode */
|
||
export async function startIMU() {
|
||
if(!glasses){
|
||
return Promise.reject('no device connected')
|
||
}
|
||
|
||
// kick off polling
|
||
glasses.startIMUPolling();
|
||
|
||
return glasses.sendReportTimeout(Protocol.MESSAGES.W_TOGGLE_IMU, [0x1])
|
||
.then(report => {
|
||
console.warn('startIMU -> report',report);
|
||
if (reportSuccess(report)){
|
||
return String.fromCharCode.apply(null, report.payload);
|
||
}else{
|
||
console.error('error w/ report',report)
|
||
}
|
||
})
|
||
}
|
||
|
||
export async function stopIMU() {
|
||
if(!glasses){
|
||
return 'no device connected'
|
||
}
|
||
// arg 2: 0 is what turns "off" the stream
|
||
return glasses.sendReportTimeout(Protocol.MESSAGES.W_TOGGLE_IMU, [0x0])
|
||
.then(report => {
|
||
console.warn('stopIMU -> report',report);
|
||
if (reportSuccess(report)){
|
||
return String.fromCharCode.apply(null, report.payload);
|
||
}else{
|
||
console.error('error w/ report',report)
|
||
}
|
||
})
|
||
}
|
||
|
||
/** read air glassess Brightness */
|
||
export async function getBrightness() {
|
||
let glasses = await common.connectDevice();
|
||
if (!glasses) {
|
||
return 'not found device';
|
||
}
|
||
// what's the chance the getBrightness is the same as setBrightness?
|
||
return glasses.sendReportTimeout(Protocol.MESSAGES.W_BRIGHTNESS)
|
||
.then(report => {
|
||
if (reportSuccess(report)) {
|
||
return report.payload;
|
||
// return String.fromCharCode.apply(null, report.payload);
|
||
}
|
||
});
|
||
}
|
||
|
||
/** write air glassess Brightness */
|
||
export async function setBrightness(brightness_int) {
|
||
let glasses = await common.connectDevice();
|
||
if (!glasses) {
|
||
return 'not found device';
|
||
}
|
||
const payload = Protocol.brightInt2Bytes(brightness_int-1);
|
||
return glasses.sendReportTimeout(Protocol.MESSAGES.W_BRIGHTNESS, payload)
|
||
.then(report => {
|
||
if (reportSuccess(report)) {
|
||
return report.payload;
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
|
||
|
||
// 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
|
||
// }
|
||
// }
|
||
|
||
|
||
function reportSuccess(report) {
|
||
return report && report.status === 0;
|
||
}
|
||
|
||
export {
|
||
current,
|
||
total,
|
||
dpCurrent
|
||
} |