1
0
Fork 0
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:
Bruce Luckcuck 2017-02-06 16:39:55 -05:00
parent e6f60a5f06
commit 8a286bdeed
2 changed files with 911 additions and 892 deletions

View file

@ -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++) {

View file

@ -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) {