This commit is contained in:
Silent YANG 2024-07-01 22:23:30 +08:00
parent b5c8a6caaf
commit dbb1c3aeb3
2 changed files with 94 additions and 9 deletions

View file

@ -953,6 +953,74 @@ async function readPacket(port, expectedData, timeout = 1000) {
}
/**
* Waits for a packet from the radio. The packet data is returned as a Uint8Array.
* @param {SerialPort} port - The serial port to read from.
* @param {number} timeout - The timeout in milliseconds.
* @returns {Promise<Uint8Array>} - A promise that resolves with the received packet or gets rejected on timeout.
*/
async function readPacketNoVerify(port, timeout = 1000) {
// Create a reader to read data from the serial port
const reader = port.readable.getReader();
let buffer = new Uint8Array();
let timeoutId; // Store the timeout ID to clear it later
try {
return await new Promise((resolve, reject) => {
// Event listener to handle incoming data
function handleData({ value, done }) {
if (done) {
// If `done` is true, then the reader has been cancelled
reject('Reader has been cancelled.');
console.log('Reader has been cancelled. Current Buffer:', buffer, uint8ArrayToHexString(buffer));
return;
}
// Append the new data to the buffer
buffer = new Uint8Array([...buffer, ...value]);
// Strip the beginning of the buffer until the first 0xAB byte
// This is done to ensure that the buffer does not contain any incomplete packets
while (buffer.length > 0 && buffer.indexOf(0xAB) != -1 && buffer.indexOf(0xCD) != -1) {
resolve(true);
return;
}
// Continue reading data
reader.read().then(handleData).catch(error => {
console.error('Error reading data from the serial port:', error);
reject(error);
return;
});
}
// Subscribe to the data event to start listening for incoming data
reader.read().then(handleData).catch(error_1 => {
console.error('Error reading data from the serial port:', error_1);
reject(error_1);
return;
});
// Set the timeout to reject the Promise if the packet is not received within the specified time
timeoutId = setTimeout(() => {
reader.cancel().then(() => {
reject('Timeout: Packet not received within the specified time.');
return;
}).catch(error_2 => {
console.error('Error cancelling reader:', error_2);
reject(error_2);
return;
});
}, timeout);
});
} finally {
// Clear the timeout when the promise is settled (resolved or rejected)
clearTimeout(timeoutId);
// Release the reader in the finally block to ensure it is always released
reader.releaseLock();
}
}
/**
* Sends a packet to the radio.
* @param {SerialPort} port - The serial port to write to.
@ -1427,5 +1495,6 @@ export {
flash_flashFirmware,
flash_generateCommand,
unpackVersion,
unpack
unpack,
readPacketNoVerify
}

View file

@ -4,10 +4,20 @@
<a-row :gutter="20" align="stretch">
<a-col :span="24">
<a-card class="general-card" :title="$t('menu.flash') + $t('global.onBoot')">
<a-space>
<a-button @click="selectFile">{{ state.binaryFile ? state.binaryName : $t('tool.selectFirmware') }}</a-button>
<a-button type="primary" :disabled="!state.binaryFile" @click="flashIt">{{ $t('tool.flash') }}</a-button>
</a-space>
<div style="display: flex; justify-content: space-between; align-items: center;">
<div>
<a-space>
<a-button @click="selectFile">{{ state.binaryFile ? state.binaryName : $t('tool.selectFirmware') }}</a-button>
<a-button type="primary" :disabled="!state.binaryFile" @click="flashIt">{{ $t('tool.flash') }}</a-button>
</a-space>
</div>
<div>
<a-radio-group type="button" size="mini" v-model="state.protocol">
<a-radio value="Official">Official</a-radio>
<a-radio value="Losehu">Losehu</a-radio>
</a-radio-group>
</div>
</div>
<a-divider />
<div id="statusArea" style="height: 20em; background-color: azure; color: silver; overflow: auto; padding: 20px"
v-html="state.status"></div>
@ -21,18 +31,20 @@
import { reactive, nextTick, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { useAppStore } from '@/store';
import { disconnect, connect, readPacket, sendPacket, unpackVersion, unpack, flash_generateCommand } from '@/utils/serial.js';
import { disconnect, connect, readPacket, sendPacket, unpackVersion, unpack, flash_generateCommand, readPacketNoVerify } from '@/utils/serial.js';
const appStore = useAppStore();
const state : {
status: any,
binaryName: any,
binaryFile: any
binaryFile: any,
protocol: string
} = reactive({
status: "点击更新按钮更新固件到设备<br/><br/>",
binaryFile: undefined,
binaryName: ''
binaryName: '',
protocol: 'Official'
})
const route = useRoute();
@ -93,7 +105,11 @@ const flashIt = async () => {
try {
await sendPacket(_connect, command);
await readPacket(_connect, 0x1a);
if(state.protocol == 'Official'){
await readPacket(_connect, 0x1a);
}else{
await readPacketNoVerify(_connect);
}
} catch (e) {
console.log('Flash command rejected. Aborting.');
return Promise.reject(e);