mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-17 21:35:33 +03:00
Revise handling of msp CRC errors to prevent referencing undefined objects and allow blackbox packets to retry
This commit is contained in:
parent
e6f60a5f06
commit
8a286bdeed
2 changed files with 911 additions and 892 deletions
14
js/msp.js
14
js/msp.js
|
@ -11,6 +11,7 @@ var MSP = {
|
||||||
message_buffer_uint8_view: null,
|
message_buffer_uint8_view: null,
|
||||||
message_checksum: 0,
|
message_checksum: 0,
|
||||||
messageIsJumboFrame: false,
|
messageIsJumboFrame: false,
|
||||||
|
crcError: false,
|
||||||
|
|
||||||
callbacks: [],
|
callbacks: [],
|
||||||
packet_error: 0,
|
packet_error: 0,
|
||||||
|
@ -114,14 +115,16 @@ var MSP = {
|
||||||
this.dataView = new DataView(this.message_buffer, 0, this.message_length_expected);
|
this.dataView = new DataView(this.message_buffer, 0, this.message_length_expected);
|
||||||
} else {
|
} else {
|
||||||
console.log('code: ' + this.code + ' - crc failed');
|
console.log('code: ' + this.code + ' - crc failed');
|
||||||
this.dataView = null;
|
|
||||||
this.packet_error++;
|
this.packet_error++;
|
||||||
|
this.crcError = true;
|
||||||
|
this.dataView = new DataView(new ArrayBuffer(0));
|
||||||
}
|
}
|
||||||
// Reset variables
|
// Reset variables
|
||||||
this.message_length_received = 0;
|
this.message_length_received = 0;
|
||||||
this.state = 0;
|
this.state = 0;
|
||||||
this.messageIsJumboFrame = false;
|
this.messageIsJumboFrame = false;
|
||||||
this.notify();
|
this.notify();
|
||||||
|
this.crcError = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -144,10 +147,15 @@ var MSP = {
|
||||||
clearListeners: function() {
|
clearListeners: function() {
|
||||||
this.listeners = [];
|
this.listeners = [];
|
||||||
},
|
},
|
||||||
send_message: function (code, data, callback_sent, callback_msp) {
|
send_message: function (code, data, callback_sent, callback_msp, callback_onerror) {
|
||||||
var bufferOut,
|
var bufferOut,
|
||||||
bufView;
|
bufView;
|
||||||
|
|
||||||
|
if (callback_onerror === undefined) {
|
||||||
|
var callbackOnError = false;
|
||||||
|
} else {
|
||||||
|
var callbackOnError = true;
|
||||||
|
}
|
||||||
// always reserve 6 bytes for protocol overhead !
|
// always reserve 6 bytes for protocol overhead !
|
||||||
if (data) {
|
if (data) {
|
||||||
var size = data.length + 6,
|
var size = data.length + 6,
|
||||||
|
@ -183,7 +191,7 @@ var MSP = {
|
||||||
bufView[5] = bufView[3] ^ bufView[4]; // checksum
|
bufView[5] = bufView[3] ^ bufView[4]; // checksum
|
||||||
}
|
}
|
||||||
|
|
||||||
var obj = {'code': code, 'requestBuffer': bufferOut, 'callback': (callback_msp) ? callback_msp : false, 'timer': false};
|
var obj = {'code': code, 'requestBuffer': bufferOut, 'callback': (callback_msp) ? callback_msp : false, 'timer': false, 'callbackOnError': callbackOnError};
|
||||||
|
|
||||||
var requestExists = false;
|
var requestExists = false;
|
||||||
for (var i = 0; i < MSP.callbacks.length; i++) {
|
for (var i = 0; i < MSP.callbacks.length; i++) {
|
||||||
|
|
|
@ -52,6 +52,8 @@ MspHelper.prototype.process_data = function(dataHandler) {
|
||||||
|
|
||||||
var data = dataHandler.dataView; // DataView (allowing us to view arrayBuffer as struct/union)
|
var data = dataHandler.dataView; // DataView (allowing us to view arrayBuffer as struct/union)
|
||||||
var code = dataHandler.code;
|
var code = dataHandler.code;
|
||||||
|
var crcError = dataHandler.crcError;
|
||||||
|
if (!crcError) {
|
||||||
if (!dataHandler.unsupported) switch (code) {
|
if (!dataHandler.unsupported) switch (code) {
|
||||||
case MSPCodes.MSP_STATUS:
|
case MSPCodes.MSP_STATUS:
|
||||||
CONFIG.cycleTime = data.readU16();
|
CONFIG.cycleTime = data.readU16();
|
||||||
|
@ -943,21 +945,23 @@ MspHelper.prototype.process_data = function(dataHandler) {
|
||||||
} else {
|
} else {
|
||||||
console.log('FC reports unsupported message error: ' + code);
|
console.log('FC reports unsupported message error: ' + code);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// trigger callbacks, cleanup/remove callback after trigger
|
// trigger callbacks, cleanup/remove callback after trigger
|
||||||
for (var i = dataHandler.callbacks.length - 1; i >= 0; i--) { // itterating in reverse because we use .splice which modifies array length
|
for (var i = dataHandler.callbacks.length - 1; i >= 0; i--) { // itterating in reverse because we use .splice which modifies array length
|
||||||
if (dataHandler.callbacks[i].code == code) {
|
if (dataHandler.callbacks[i].code == code) {
|
||||||
// save callback reference
|
// save callback reference
|
||||||
var callback = dataHandler.callbacks[i].callback;
|
var callback = dataHandler.callbacks[i].callback;
|
||||||
|
var callbackOnError = dataHandler.callbacks[i].callbackOnError;
|
||||||
|
|
||||||
// remove timeout
|
// remove timeout
|
||||||
clearInterval(dataHandler.callbacks[i].timer);
|
clearInterval(dataHandler.callbacks[i].timer);
|
||||||
|
|
||||||
// remove object from array
|
// remove object from array
|
||||||
dataHandler.callbacks.splice(i, 1);
|
dataHandler.callbacks.splice(i, 1);
|
||||||
|
if (!crcError || callbackOnError) {
|
||||||
// fire callback
|
// fire callback
|
||||||
if (callback) callback({'command': code, 'data': data, 'length': data.byteLength});
|
if (callback) callback({'command': code, 'data': data, 'length': data.byteLength, 'crcError': crcError});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1268,6 +1272,7 @@ MspHelper.prototype.dataflashRead = function(address, blockSize, onDataCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_DATAFLASH_READ, outData, false, function(response) {
|
MSP.send_message(MSPCodes.MSP_DATAFLASH_READ, outData, false, function(response) {
|
||||||
|
if (!response.crcError) {
|
||||||
var chunkAddress = response.data.readU32();
|
var chunkAddress = response.data.readU32();
|
||||||
|
|
||||||
var headerSize = 4;
|
var headerSize = 4;
|
||||||
|
@ -1279,17 +1284,23 @@ MspHelper.prototype.dataflashRead = function(address, blockSize, onDataCallback)
|
||||||
dataCompressionType = response.data.readU8();
|
dataCompressionType = response.data.readU8();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that the address of the memory returned matches what the caller asked for
|
// Verify that the address of the memory returned matches what the caller asked for and there was not a CRC error
|
||||||
if (chunkAddress == address) {
|
if (chunkAddress == address) {
|
||||||
/* Strip that address off the front of the reply and deliver it separately so the caller doesn't have to
|
/* Strip that address off the front of the reply and deliver it separately so the caller doesn't have to
|
||||||
* figure out the reply format:
|
* figure out the reply format:
|
||||||
*/
|
*/
|
||||||
onDataCallback(address, new DataView(response.data.buffer, response.data.byteOffset + headerSize, dataSize));
|
onDataCallback(address, new DataView(response.data.buffer, response.data.byteOffset + headerSize, dataSize));
|
||||||
} else {
|
} else {
|
||||||
// Report error
|
// Report address error
|
||||||
onDataCallback(address, null);
|
console.log('Expected address ' + address + ' but received ' + chunkAddress + ' - retrying');
|
||||||
|
onDataCallback(address, null); // returning null to the callback forces a retry
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
|
// Report crc error
|
||||||
|
console.log('CRC error for address ' + address + ' - retrying');
|
||||||
|
onDataCallback(address, null); // returning null to the callback forces a retry
|
||||||
|
}
|
||||||
|
},true);
|
||||||
};
|
};
|
||||||
|
|
||||||
MspHelper.prototype.sendServoConfigurations = function(onCompleteCallback) {
|
MspHelper.prototype.sendServoConfigurations = function(onCompleteCallback) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue