Commit 3c45ade5 authored by martin hou's avatar martin hou

增加设备播放音和UAC的更新实现

parent 587cd7ac
......@@ -8,6 +8,15 @@ export type ReturnStruct = {
common: { result: 'failed' | 'success' };
};
export type ToneUpdateResponse = {
code: number;
result: string;
}
export type UACUpdateResponse = {
code: number;
result: string;
}
export type FileInfo = {
name: string;
createDate: string;
......@@ -138,6 +147,11 @@ declare class Jensen {
pauseRealtime: () => Promise<ReturnStruct['common']>;
stopRealtime: () => Promise<ReturnStruct['common']>;
getRealtime: (frames: number) => Promise<{ data: Uint8Array; rest: number }>;
readFile: (fname: string, offset: number, length: number) => Promise<Uint8Array>;
requestToneUpdate: (signature: string, size: number, seconds?: number) => Promise<ToneUpdateResponse>;
updateTone: (data: Uint8Array, seconds?: number) => Promise<ReturnStruct['common']>;
requestUACUpdate: (signature: string, size: number, seconds?: number) => Promise<UACUpdateResponse>;
updateUAC: (data: Uint8Array, seconds?: number) => Promise<ReturnStruct['common']>;
}
export = Jensen;
......@@ -80,7 +80,7 @@ export function Home() {
const listFiles = async () => {
let files = await jensen.listFiles();
console.log(files);
setFiles(files)
}
const getBluetoothStatus = async () => {
......@@ -88,6 +88,64 @@ export function Home() {
alert(JSON.stringify(info));
}
const readFilePartial = async() => {
if (files.length == 0) return alert('你没有录音文件,或是还没有查询过文件列表');
let s0 = prompt('请输入需要读取的文件序号,从0开始:', '0');
let s1 = prompt('请输入开始位置,从0开始:', '0');
let s2 = prompt('请输入读取字节数量', '32');
if (s0 && s1 && s2) console.log();
else return;
let index = parseInt(s0);
let offset = parseInt(s1);
let length = parseInt(s2);
if (isNaN(index) && isNaN(offset) || isNaN(length)) return;
if (index >= files.length) return alert('请输入正确的文件序号');
let file = files[index];
if (offset < 0 || offset > file.length) return alert('请输入正确的读取开始位置');
if (length <= 0) return alert('请输入正确的文件读取长度');
let data = await jensen.readFile(file.name, offset, length);
console.log(data);
}
const updateDeviceTone = async () => {
let resp = await jensen.requestToneUpdate('826d9bac0b535e7babe02b389327a9f2', 1050688);
if (resp.code != 0x00) return alert(resp.result);
// 下载文件并完成更新处理
let xhr = new XMLHttpRequest();
xhr.open('GET', '/sdfs.bin');
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.responseType = 'arraybuffer';
xhr.onload = function(e)
{
if (this.status != 200) return alert('Http Error: ' + this.status);
jensen.updateTone(new Uint8Array(this.response), 30).then((info) => {
alert(JSON.stringify(info));
});
}
xhr.send();
}
const updateUAC = async () => {
// 92e66fd8cfd36f09c83fc61491899307 1024
let resp = await jensen.requestUACUpdate('92e66fd8cfd36f09c83fc61491899307', 1024);
if (resp.code != 0x00) return alert(resp.result);
// 下载文件并完成更新处理
let xhr = new XMLHttpRequest();
xhr.open('GET', '/UAC.bin');
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.responseType = 'arraybuffer';
xhr.onload = function(e)
{
if (this.status != 200) return alert('Http Error: ' + this.status);
jensen.updateUAC(new Uint8Array(this.response), 30).then((info) => {
alert(JSON.stringify(info));
});
}
xhr.send();
}
return (
<>
<div style={{ display: 'flex', flexDirection: 'row', gap: '16px', padding: '16px', alignItems: 'center' }}>
......@@ -101,9 +159,20 @@ export function Home() {
Get Time
</button>
<button style={{ width: '200px', height: '50px' }} onClick={listFiles}>List Files</button>
<button style={{ width: '200px', height: '50px' }} onClick={getBluetoothStatus}>Bluetooth Status</button>
<button style={{ width : '200px', height : '50px' }} onClick={bluetoothScan}>Bluetooth Scan</button>
<button style={{ width : '200px', height : '50px' }} onClick={disconnectBTDevice}>Bluetooth Disconnect</button>
<button style={{ width: '200px', height: '50px' }} onClick={getBluetoothStatus}>蓝牙连接状态</button>
<button style={{ width : '200px', height : '50px' }} onClick={bluetoothScan}>蓝牙扫描</button>
<button style={{ width : '200px', height : '50px' }} onClick={disconnectBTDevice}>蓝牙断开</button>
<button style={{ width : '200px', height : '50px' }} onClick={readFilePartial}>Read File Partial</button>
<button style={{ width : '200px', height : '50px' }} onClick={updateDeviceTone}>更新提示音</button>
<button style={{ width : '200px', height : '50px' }} onClick={updateUAC}>更新UAC</button>
</div>
<div id="files" style={{ padding: '0px 0px 0px 30px', marginBottom: '20px' }}>
<h3>Files: </h3>
<ol style={{ padding: '0px 0px 0px 30px', 'listStyle': 'none' }}>
{ files.map((item, index) => {
return <li>{index} - {item.name}, {item.length}</li>
})}
</ol>
</div>
<div style={{ padding: '0px 0px 0px 30px', width: '500px' }}>
<h3>Bluetooth Device List: </h3>
......
......@@ -20,6 +20,11 @@ const BNC_DEMO_TEST = 0x0a;
const GET_SETTINGS = 0x0b;
const SET_SETTINGS = 0x0c;
const GET_FILE_BLOCK = 0x0d;
const TRANSFER_FILE_PARTIAL = 0x15;
const REQUEST_TONE_UPDATE = 0x16;
const TONE_UPDATE = 0x17;
const REQUEST_UAC_UPDATE = 0x18;
const UAC_UPDATE = 0x19;
const FACTORY_RESET = 0xf00b;
const REALTIME_READ_SETTING = 0x20;
......@@ -236,7 +241,7 @@ function Jensen(log) {
Logger.debug('jensen', 'sendNext', 'command: ' + COMMAND_NAMES[cmd.command] + ', data bytes: ' + data.byteLength);
self.timewait = cmd.command == TRANSFER_FILE || cmd.command == GET_FILE_BLOCK ? 1000 : 10;
console.log('Send', data);
await device.transferOut(1, data).catch((e) => crash('sendNext', e));
if (cmd.onprogress) cmd.onprogress(1, 1);
/*
......@@ -319,6 +324,7 @@ function Jensen(log) {
if (device)
device.transferIn(2, RECV_BUFF_SIZE).then((r) => {
Logger.save?.('jensen', 'tryReceive', r?.data);
console.log('Receive', r?.data);
receive(r);
});
};
......@@ -721,6 +727,21 @@ Jensen.prototype.deleteFile = async function (filename, seconds) {
return this.send(new Command(DELETE_FILE).body(fname), seconds);
};
Jensen.prototype.readFile = async function (filename, offset, length, seconds) {
// 如果确定支持的版本号
let data = [];
data.push((offset >> 24) & 0xff);
data.push((offset >> 16) & 0xff);
data.push((offset >> 8) & 0xff);
data.push((offset >> 0) & 0xff);
data.push((length >> 24) & 0xff);
data.push((length >> 16) & 0xff);
data.push((length >> 8) & 0xff);
data.push((length >> 0) & 0xff);
for (let i = 0; i < filename.length; i++) data.push(filename.charCodeAt(i));
return this.send(new Command(TRANSFER_FILE_PARTIAL).body(data), seconds);
}
Jensen.prototype.setTime = async function (time, seconds) {
let str =
time.getFullYear() +
......@@ -1039,7 +1060,38 @@ Jensen.prototype.getRealtime = async function (frames) {
let d = (frames >> 0) & 0xff;
return this.send(new Command(REALTIME_TRANSFER).body([a, b, c, d]));
};
Jensen.prototype.requestToneUpdate = async function(signature, size, seconds) {
let data = [];
for (let i = 0; i < signature.length; i+=2)
{
let b = signature.substring(i, i + 2);
data.push(parseInt(b, 16));
}
data.push((size >> 24) & 0xff);
data.push((size >> 16) & 0xff);
data.push((size >> 8) & 0xff);
data.push((size >> 0) & 0xff);
return this.send(new Command(REQUEST_TONE_UPDATE).body(data), seconds);
}
Jensen.prototype.updateTone = async function(toneFile, seconds) {
return this.send(new Command(TONE_UPDATE).body(toneFile), seconds);
}
Jensen.prototype.requestUACUpdate = async function(signature, size, seconds) {
let data = [];
for (let i = 0; i < signature.length; i+=2)
{
let b = signature.substring(i, i + 2);
data.push(parseInt(b, 16));
}
data.push((size >> 24) & 0xff);
data.push((size >> 16) & 0xff);
data.push((size >> 8) & 0xff);
data.push((size >> 0) & 0xff);
return this.send(new Command(REQUEST_UAC_UPDATE).body(data), seconds);
}
Jensen.prototype.updateUAC = async function(uacFile, seconds) {
return this.send(new Command(UAC_UPDATE).body(uacFile), seconds);
}
Jensen.registerHandler(REALTIME_CONTROL, commonMessageParser);
Jensen.registerHandler(REALTIME_READ_SETTING, (msg) => {
console.log(msg);
......@@ -1153,6 +1205,14 @@ Jensen.registerHandler(READ_CARD_INFO, (msg) => {
return { used: used, capacity: capacity, status: status.toString(16) };
});
Jensen.registerHandler(TRANSFER_FILE_PARTIAL, (msg) => {
let buf = new Uint8Array(msg.body.length);
for (let i = 0; i < msg.body.length; i++)
{
buf[i] = msg.body[i] & 0xff;
}
return buf;
});
Jensen.registerHandler(FORMAT_CARD, commonMessageParser);
Jensen.registerHandler(GET_RECORDING_FILE, (msg) => {
if (msg.body == null || msg.body.length === 0) return { recording: null };
......@@ -1252,5 +1312,26 @@ Jensen.registerHandler(GET_FILE_BLOCK, commonMessageParser);
Jensen.registerHandler(TEST_SN_WRITE, commonMessageParser);
Jensen.registerHandler(SCHEDULE_INFO, commonMessageParser);
Jensen.registerHandler(BLUETOOTH_CMD, commonMessageParser);
Jensen.registerHandler(REQUEST_TONE_UPDATE, (msg) => {
let rst = msg.body[0];
let txt = 'success';
if (rst == 0x01) txt = 'length-mismatch';
else if (rst == 0x02) txt = 'busy';
else if (rst == 0x03) txt = 'card-full';
else if (rst == 0x04) txt = 'card-error';
else txt = String(rst);
return { code : rst, result : txt };
});
Jensen.registerHandler(TONE_UPDATE, commonMessageParser);
Jensen.registerHandler(REQUEST_UAC_UPDATE, (msg) => {
let rst = msg.body[0];
let txt = 'success';
if (rst == 0x01) txt = 'length-mismatch';
else if (rst == 0x02) txt = 'busy';
else if (rst == 0x03) txt = 'card-full';
else if (rst == 0x04) txt = 'card-error';
else txt = String(rst);
return { code : rst, result : txt };
});
Jensen.registerHandler(UAC_UPDATE, commonMessageParser);
export { Jensen };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment