mirror of
https://github.com/iNavFlight/inav-configurator.git
synced 2025-07-13 11:29:53 +03:00
Add support for MSPv2
MWC side detection is done by sending an MSPv1 message for MSP_API_VERSION. If the MSP_VERSION supports MSPv2 (>= 2.0.0), then the rest of the messages for the session will be MSPv2 only.
This commit is contained in:
parent
dbf4fa164d
commit
acd455d6da
3 changed files with 296 additions and 142 deletions
219
build/script.js
219
build/script.js
|
@ -10612,8 +10612,13 @@ function onOpen(openInfo) {
|
||||||
|
|
||||||
FC.resetState();
|
FC.resetState();
|
||||||
|
|
||||||
// request configuration data
|
// request configuration data. Start with MSPv1 and
|
||||||
|
// upgrade to MSPv2 if possible.
|
||||||
|
MSP.protocolVersion = MSP.constants.PROTOCOL_V1;
|
||||||
MSP.send_message(MSPCodes.MSP_API_VERSION, false, false, function () {
|
MSP.send_message(MSPCodes.MSP_API_VERSION, false, false, function () {
|
||||||
|
if (CONFIG.apiVersion && semver.gte(CONFIG.apiVersion, "2.0.0")) {
|
||||||
|
MSP.protocolVersion = MSP.constants.PROTOCOL_V2;
|
||||||
|
}
|
||||||
GUI.log(chrome.i18n.getMessage('apiVersionReceived', [CONFIG.apiVersion]));
|
GUI.log(chrome.i18n.getMessage('apiVersionReceived', [CONFIG.apiVersion]));
|
||||||
|
|
||||||
if (semver.gte(CONFIG.apiVersion, CONFIGURATOR.apiVersionAccepted)) {
|
if (semver.gte(CONFIG.apiVersion, CONFIGURATOR.apiVersionAccepted)) {
|
||||||
|
@ -11787,6 +11792,8 @@ var MSP = {
|
||||||
UNSUPPORTED: '!'.charCodeAt(0),
|
UNSUPPORTED: '!'.charCodeAt(0),
|
||||||
},
|
},
|
||||||
constants: {
|
constants: {
|
||||||
|
PROTOCOL_V1: 1,
|
||||||
|
PROTOCOL_V2: 2,
|
||||||
JUMBO_FRAME_MIN_SIZE: 255,
|
JUMBO_FRAME_MIN_SIZE: 255,
|
||||||
},
|
},
|
||||||
decoder_states: {
|
decoder_states: {
|
||||||
|
@ -11794,20 +11801,22 @@ var MSP = {
|
||||||
PROTO_IDENTIFIER: 1,
|
PROTO_IDENTIFIER: 1,
|
||||||
DIRECTION_V1: 2,
|
DIRECTION_V1: 2,
|
||||||
DIRECTION_V2: 3,
|
DIRECTION_V2: 3,
|
||||||
PAYLOAD_LENGTH_V1: 4,
|
FLAG_V2: 4,
|
||||||
PAYLOAD_LENGTH_JUMBO_LOW: 5,
|
PAYLOAD_LENGTH_V1: 5,
|
||||||
PAYLOAD_LENGTH_JUMBO_HIGH: 6,
|
PAYLOAD_LENGTH_JUMBO_LOW: 6,
|
||||||
PAYLOAD_LENGTH_V2_LOW: 7,
|
PAYLOAD_LENGTH_JUMBO_HIGH: 7,
|
||||||
PAYLOAD_LENGTH_V2_HIGH: 8,
|
PAYLOAD_LENGTH_V2_LOW: 8,
|
||||||
CODE_V1: 9,
|
PAYLOAD_LENGTH_V2_HIGH: 9,
|
||||||
CODE_JUMBO_V1: 10,
|
CODE_V1: 10,
|
||||||
CODE_V2_LOW: 11,
|
CODE_JUMBO_V1: 11,
|
||||||
CODE_V2_HIGH: 12,
|
CODE_V2_LOW: 12,
|
||||||
PAYLOAD_V1: 13,
|
CODE_V2_HIGH: 13,
|
||||||
PAYLOAD_V2: 14,
|
PAYLOAD_V1: 14,
|
||||||
CHECKSUM_V1: 15,
|
PAYLOAD_V2: 15,
|
||||||
CHECKSUM_V2: 16,
|
CHECKSUM_V1: 16,
|
||||||
|
CHECKSUM_V2: 17,
|
||||||
},
|
},
|
||||||
|
protocolVersion: 1, // this.constants.PROTOCOL_V1
|
||||||
state: 0, // this.decoder_states.IDLE
|
state: 0, // this.decoder_states.IDLE
|
||||||
message_direction: 1,
|
message_direction: 1,
|
||||||
code: 0,
|
code: 0,
|
||||||
|
@ -11844,12 +11853,15 @@ var MSP = {
|
||||||
this.state = this.decoder_states.DIRECTION_V1;
|
this.state = this.decoder_states.DIRECTION_V1;
|
||||||
break;
|
break;
|
||||||
case this.symbols.PROTO_V2:
|
case this.symbols.PROTO_V2:
|
||||||
// eventually, MSPv2
|
this.state = this.decoder_states.DIRECTION_V2;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
console.log("Unknown protocol char " + String.fromCharCode(data[i]));
|
||||||
this.state = this.decoder_states.IDLE;
|
this.state = this.decoder_states.IDLE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case this.decoder_states.DIRECTION_V1: // direction (should be >)
|
case this.decoder_states.DIRECTION_V1: // direction (should be >)
|
||||||
|
case this.decoder_states.DIRECTION_V2:
|
||||||
this.unsupported = 0;
|
this.unsupported = 0;
|
||||||
switch (data[i]) {
|
switch (data[i]) {
|
||||||
case this.symbols.FROM_MWC:
|
case this.symbols.FROM_MWC:
|
||||||
|
@ -11862,7 +11874,13 @@ var MSP = {
|
||||||
this.unsupported = 1;
|
this.unsupported = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.state = this.decoder_states.PAYLOAD_LENGTH_V1;
|
this.state = this.state == this.decoder_states.DIRECTION_V1 ?
|
||||||
|
this.decoder_states.PAYLOAD_LENGTH_V1 :
|
||||||
|
this.decoder_states.FLAG_V2;
|
||||||
|
break;
|
||||||
|
case this.decoder_states.FLAG_V2:
|
||||||
|
// Ignored for now
|
||||||
|
this.state = this.decoder_states.CODE_V2_LOW;
|
||||||
break;
|
break;
|
||||||
case this.decoder_states.PAYLOAD_LENGTH_V1:
|
case this.decoder_states.PAYLOAD_LENGTH_V1:
|
||||||
this.message_length_expected = data[i];
|
this.message_length_expected = data[i];
|
||||||
|
@ -11875,6 +11893,17 @@ var MSP = {
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case this.decoder_states.PAYLOAD_LENGTH_V2_LOW:
|
||||||
|
this.message_length_expected = data[i];
|
||||||
|
this.state = this.decoder_states.PAYLOAD_LENGTH_V2_HIGH;
|
||||||
|
break;
|
||||||
|
case this.decoder_states.PAYLOAD_LENGTH_V2_HIGH:
|
||||||
|
this.message_length_expected |= data[i] << 8;
|
||||||
|
this._initialize_read_buffer();
|
||||||
|
this.state = this.message_length_expected > 0 ?
|
||||||
|
this.decoder_states.PAYLOAD_V2 :
|
||||||
|
this.state = this.decoder_states.CHECKSUM_V2;
|
||||||
|
break;
|
||||||
case this.decoder_states.CODE_V1:
|
case this.decoder_states.CODE_V1:
|
||||||
case this.decoder_states.CODE_JUMBO_V1:
|
case this.decoder_states.CODE_JUMBO_V1:
|
||||||
this.code = data[i];
|
this.code = data[i];
|
||||||
|
@ -11890,6 +11919,14 @@ var MSP = {
|
||||||
this.state = this.decoder_states.CHECKSUM_V1;
|
this.state = this.decoder_states.CHECKSUM_V1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case this.decoder_states.CODE_V2_LOW:
|
||||||
|
this.code = data[i];
|
||||||
|
this.state = this.decoder_states.CODE_V2_HIGH;
|
||||||
|
break;
|
||||||
|
case this.decoder_states.CODE_V2_HIGH:
|
||||||
|
this.message_length_expected |= data[i] << 8;
|
||||||
|
this.state = this.decoder_states.PAYLOAD_LENGTH_V2_LOW;
|
||||||
|
break;
|
||||||
case this.decoder_states.PAYLOAD_LENGTH_JUMBO_LOW:
|
case this.decoder_states.PAYLOAD_LENGTH_JUMBO_LOW:
|
||||||
this.message_length_expected = data[i];
|
this.message_length_expected = data[i];
|
||||||
this.state = this.decoder_states.PAYLOAD_LENGTH_JUMBO_HIGH;
|
this.state = this.decoder_states.PAYLOAD_LENGTH_JUMBO_HIGH;
|
||||||
|
@ -11900,11 +11937,14 @@ var MSP = {
|
||||||
this.state = this.decoder_states.PAYLOAD_V1;
|
this.state = this.decoder_states.PAYLOAD_V1;
|
||||||
break;
|
break;
|
||||||
case this.decoder_states.PAYLOAD_V1:
|
case this.decoder_states.PAYLOAD_V1:
|
||||||
|
case this.decoder_states.PAYLOAD_V2:
|
||||||
this.message_buffer_uint8_view[this.message_length_received] = data[i];
|
this.message_buffer_uint8_view[this.message_length_received] = data[i];
|
||||||
this.message_length_received++;
|
this.message_length_received++;
|
||||||
|
|
||||||
if (this.message_length_received >= this.message_length_expected) {
|
if (this.message_length_received >= this.message_length_expected) {
|
||||||
this.state = this.decoder_states.CHECKSUM_V1;
|
this.state = this.state == this.decoder_states.PAYLOAD_V1 ?
|
||||||
|
this.decoder_states.CHECKSUM_V1 :
|
||||||
|
this.decoder_states.CHECKSUM_V2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case this.decoder_states.CHECKSUM_V1:
|
case this.decoder_states.CHECKSUM_V1:
|
||||||
|
@ -11921,26 +11961,20 @@ var MSP = {
|
||||||
for (var ii = 0; ii < this.message_length_received; ii++) {
|
for (var ii = 0; ii < this.message_length_received; ii++) {
|
||||||
this.message_checksum ^= this.message_buffer_uint8_view[ii];
|
this.message_checksum ^= this.message_buffer_uint8_view[ii];
|
||||||
}
|
}
|
||||||
if (this.message_checksum == data[i]) {
|
this._dispatch_message(data[i]);
|
||||||
// message received, process
|
break;
|
||||||
mspHelper.processData(this);
|
case this.decoder_states.CHECKSUM_V2:
|
||||||
} else {
|
this.message_checksum = 0;
|
||||||
console.log('code: ' + this.code + ' - crc failed');
|
this.message_checksum = this._crc8_dvb_s2(this.message_checksum, 0); // flag
|
||||||
|
this.message_checksum = this._crc8_dvb_s2(this.message_checksum, this.code & 0xFF);
|
||||||
this.packet_error++;
|
this.message_checksum = this._crc8_dvb_s2(this.message_checksum, (this.code & 0xFF00) >> 8);
|
||||||
$('span.packet-error').html(this.packet_error);
|
this.message_checksum = this._crc8_dvb_s2(this.message_checksum, this.message_length_expected & 0xFF);
|
||||||
}
|
this.message_checksum = this._crc8_dvb_s2(this.message_checksum, (this.message_length_expected & 0xFF00) >> 8);
|
||||||
|
for (var ii = 0; ii < this.message_length_received; ii++) {
|
||||||
/*
|
this.message_checksum = this._crc8_dvb_s2(this.message_checksum, this.message_buffer_uint8_view[ii]);
|
||||||
* Free port
|
}
|
||||||
*/
|
this._dispatch_message(data[i]);
|
||||||
helper.mspQueue.freeHardLock();
|
|
||||||
|
|
||||||
// Reset variables
|
|
||||||
this.message_length_received = 0;
|
|
||||||
this.state = this.decoder_states.IDLE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
* Free port
|
* Free port
|
||||||
|
@ -11957,6 +11991,26 @@ var MSP = {
|
||||||
this.message_buffer_uint8_view = new Uint8Array(this.message_buffer);
|
this.message_buffer_uint8_view = new Uint8Array(this.message_buffer);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_dispatch_message: function(expected_checksum) {
|
||||||
|
if (this.message_checksum == expected_checksum) {
|
||||||
|
// message received, process
|
||||||
|
mspHelper.processData(this);
|
||||||
|
} else {
|
||||||
|
console.log('code: ' + this.code + ' - crc failed');
|
||||||
|
this.packet_error++;
|
||||||
|
$('span.packet-error').html(this.packet_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free port
|
||||||
|
*/
|
||||||
|
helper.mspQueue.freeHardLock();
|
||||||
|
|
||||||
|
// Reset variables
|
||||||
|
this.message_length_received = 0;
|
||||||
|
this.state = this.decoder_states.IDLE;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {MSP} mspData
|
* @param {MSP} mspData
|
||||||
|
@ -11979,48 +12033,60 @@ var MSP = {
|
||||||
},
|
},
|
||||||
|
|
||||||
send_message: function (code, data, callback_sent, callback_msp) {
|
send_message: function (code, data, callback_sent, callback_msp) {
|
||||||
var bufferOut,
|
var payloadLength = data && data.length ? data.length : 0;
|
||||||
bufView,
|
var length;
|
||||||
i;
|
var buffer;
|
||||||
|
var view;
|
||||||
|
var checksum;
|
||||||
|
var ii;
|
||||||
|
|
||||||
// always reserve 6 bytes for protocol overhead !
|
switch (this.protocolVersion) {
|
||||||
if (data) {
|
case this.constants.PROTOCOL_V1:
|
||||||
var size = data.length + 6,
|
length = payloadLength + 6;
|
||||||
checksum;
|
buffer = new ArrayBuffer(length);
|
||||||
|
view = new Uint8Array(buffer);
|
||||||
|
view[0] = this.symbols.BEGIN;
|
||||||
|
view[1] = this.symbols.PROTO_V1;
|
||||||
|
view[2] = this.symbols.TO_MWC;
|
||||||
|
view[3] = payloadLength;
|
||||||
|
view[4] = code;
|
||||||
|
|
||||||
bufferOut = new ArrayBuffer(size);
|
checksum = view[3] ^ view[4];
|
||||||
bufView = new Uint8Array(bufferOut);
|
for (ii = 0; ii < payloadLength; ii++) {
|
||||||
|
view[ii + 5] = data[ii];
|
||||||
|
checksum ^= data[ii];
|
||||||
|
}
|
||||||
|
view[length-1] = checksum;
|
||||||
|
break;
|
||||||
|
case this.constants.PROTOCOL_V2:
|
||||||
|
length = payloadLength + 9;
|
||||||
|
buffer = new ArrayBuffer(length);
|
||||||
|
view = new Uint8Array(buffer);
|
||||||
|
view[0] = this.symbols.BEGIN;
|
||||||
|
view[1] = this.symbols.PROTO_V2;
|
||||||
|
view[2] = this.symbols.TO_MWC;
|
||||||
|
view[3] = 0; // flag: reserved, set to 0
|
||||||
|
view[4] = code & 0xFF; // code lower byte
|
||||||
|
view[5] = (code & 0xFF00) >> 8; // code upper byte
|
||||||
|
view[6] = payloadLength & 0xFF; // payloadLength lower byte
|
||||||
|
view[7] = (payloadLength & 0xFF00) >> 8; // payloadLength upper byte
|
||||||
|
for (ii = 0; ii < payloadLength; ii++) {
|
||||||
|
view[8+ii] = data[ii];
|
||||||
|
}
|
||||||
|
checksum = 0;
|
||||||
|
for (ii = 3; ii < length-1; ii++) {
|
||||||
|
checksum = this._crc8_dvb_s2(checksum, view[ii]);
|
||||||
|
}
|
||||||
|
view[length-1] = checksum;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw "Invalid MSP protocol version " + this.protocolVersion;
|
||||||
|
|
||||||
bufView[0] = 36; // $
|
|
||||||
bufView[1] = 77; // M
|
|
||||||
bufView[2] = 60; // <
|
|
||||||
bufView[3] = data.length;
|
|
||||||
bufView[4] = code;
|
|
||||||
|
|
||||||
checksum = bufView[3] ^ bufView[4];
|
|
||||||
|
|
||||||
for (i = 0; i < data.length; i++) {
|
|
||||||
bufView[i + 5] = data[i];
|
|
||||||
|
|
||||||
checksum ^= bufView[i + 5];
|
|
||||||
}
|
|
||||||
|
|
||||||
bufView[5 + data.length] = checksum;
|
|
||||||
} else {
|
|
||||||
bufferOut = new ArrayBuffer(6);
|
|
||||||
bufView = new Uint8Array(bufferOut);
|
|
||||||
|
|
||||||
bufView[0] = 36; // $
|
|
||||||
bufView[1] = 77; // M
|
|
||||||
bufView[2] = 60; // <
|
|
||||||
bufView[3] = 0; // data length
|
|
||||||
bufView[4] = code; // code
|
|
||||||
bufView[5] = bufView[3] ^ bufView[4]; // checksum
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var message = new MspMessageClass();
|
var message = new MspMessageClass();
|
||||||
message.code = code;
|
message.code = code;
|
||||||
message.messageBody = bufferOut;
|
message.messageBody = buffer;
|
||||||
message.onFinish = callback_msp;
|
message.onFinish = callback_msp;
|
||||||
message.onSend = callback_sent;
|
message.onSend = callback_sent;
|
||||||
|
|
||||||
|
@ -12034,6 +12100,17 @@ var MSP = {
|
||||||
helper.mspQueue.put(message);
|
helper.mspQueue.put(message);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
},
|
||||||
|
_crc8_dvb_s2: function(crc, ch) {
|
||||||
|
crc ^= ch;
|
||||||
|
for (var ii = 0; ii < 8; ++ii) {
|
||||||
|
if (crc & 0x80) {
|
||||||
|
crc = ((crc << 1) & 0xFF) ^ 0xD5;
|
||||||
|
} else {
|
||||||
|
crc = (crc << 1) & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
},
|
},
|
||||||
promise: function(code, data) {
|
promise: function(code, data) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
212
js/msp.js
212
js/msp.js
|
@ -33,6 +33,8 @@ var MSP = {
|
||||||
UNSUPPORTED: '!'.charCodeAt(0),
|
UNSUPPORTED: '!'.charCodeAt(0),
|
||||||
},
|
},
|
||||||
constants: {
|
constants: {
|
||||||
|
PROTOCOL_V1: 1,
|
||||||
|
PROTOCOL_V2: 2,
|
||||||
JUMBO_FRAME_MIN_SIZE: 255,
|
JUMBO_FRAME_MIN_SIZE: 255,
|
||||||
},
|
},
|
||||||
decoder_states: {
|
decoder_states: {
|
||||||
|
@ -40,20 +42,22 @@ var MSP = {
|
||||||
PROTO_IDENTIFIER: 1,
|
PROTO_IDENTIFIER: 1,
|
||||||
DIRECTION_V1: 2,
|
DIRECTION_V1: 2,
|
||||||
DIRECTION_V2: 3,
|
DIRECTION_V2: 3,
|
||||||
PAYLOAD_LENGTH_V1: 4,
|
FLAG_V2: 4,
|
||||||
PAYLOAD_LENGTH_JUMBO_LOW: 5,
|
PAYLOAD_LENGTH_V1: 5,
|
||||||
PAYLOAD_LENGTH_JUMBO_HIGH: 6,
|
PAYLOAD_LENGTH_JUMBO_LOW: 6,
|
||||||
PAYLOAD_LENGTH_V2_LOW: 7,
|
PAYLOAD_LENGTH_JUMBO_HIGH: 7,
|
||||||
PAYLOAD_LENGTH_V2_HIGH: 8,
|
PAYLOAD_LENGTH_V2_LOW: 8,
|
||||||
CODE_V1: 9,
|
PAYLOAD_LENGTH_V2_HIGH: 9,
|
||||||
CODE_JUMBO_V1: 10,
|
CODE_V1: 10,
|
||||||
CODE_V2_LOW: 11,
|
CODE_JUMBO_V1: 11,
|
||||||
CODE_V2_HIGH: 12,
|
CODE_V2_LOW: 12,
|
||||||
PAYLOAD_V1: 13,
|
CODE_V2_HIGH: 13,
|
||||||
PAYLOAD_V2: 14,
|
PAYLOAD_V1: 14,
|
||||||
CHECKSUM_V1: 15,
|
PAYLOAD_V2: 15,
|
||||||
CHECKSUM_V2: 16,
|
CHECKSUM_V1: 16,
|
||||||
|
CHECKSUM_V2: 17,
|
||||||
},
|
},
|
||||||
|
protocolVersion: 1, // this.constants.PROTOCOL_V1
|
||||||
state: 0, // this.decoder_states.IDLE
|
state: 0, // this.decoder_states.IDLE
|
||||||
message_direction: 1,
|
message_direction: 1,
|
||||||
code: 0,
|
code: 0,
|
||||||
|
@ -90,12 +94,15 @@ var MSP = {
|
||||||
this.state = this.decoder_states.DIRECTION_V1;
|
this.state = this.decoder_states.DIRECTION_V1;
|
||||||
break;
|
break;
|
||||||
case this.symbols.PROTO_V2:
|
case this.symbols.PROTO_V2:
|
||||||
// eventually, MSPv2
|
this.state = this.decoder_states.DIRECTION_V2;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
console.log("Unknown protocol char " + String.fromCharCode(data[i]));
|
||||||
this.state = this.decoder_states.IDLE;
|
this.state = this.decoder_states.IDLE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case this.decoder_states.DIRECTION_V1: // direction (should be >)
|
case this.decoder_states.DIRECTION_V1: // direction (should be >)
|
||||||
|
case this.decoder_states.DIRECTION_V2:
|
||||||
this.unsupported = 0;
|
this.unsupported = 0;
|
||||||
switch (data[i]) {
|
switch (data[i]) {
|
||||||
case this.symbols.FROM_MWC:
|
case this.symbols.FROM_MWC:
|
||||||
|
@ -108,7 +115,13 @@ var MSP = {
|
||||||
this.unsupported = 1;
|
this.unsupported = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.state = this.decoder_states.PAYLOAD_LENGTH_V1;
|
this.state = this.state == this.decoder_states.DIRECTION_V1 ?
|
||||||
|
this.decoder_states.PAYLOAD_LENGTH_V1 :
|
||||||
|
this.decoder_states.FLAG_V2;
|
||||||
|
break;
|
||||||
|
case this.decoder_states.FLAG_V2:
|
||||||
|
// Ignored for now
|
||||||
|
this.state = this.decoder_states.CODE_V2_LOW;
|
||||||
break;
|
break;
|
||||||
case this.decoder_states.PAYLOAD_LENGTH_V1:
|
case this.decoder_states.PAYLOAD_LENGTH_V1:
|
||||||
this.message_length_expected = data[i];
|
this.message_length_expected = data[i];
|
||||||
|
@ -121,6 +134,17 @@ var MSP = {
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case this.decoder_states.PAYLOAD_LENGTH_V2_LOW:
|
||||||
|
this.message_length_expected = data[i];
|
||||||
|
this.state = this.decoder_states.PAYLOAD_LENGTH_V2_HIGH;
|
||||||
|
break;
|
||||||
|
case this.decoder_states.PAYLOAD_LENGTH_V2_HIGH:
|
||||||
|
this.message_length_expected |= data[i] << 8;
|
||||||
|
this._initialize_read_buffer();
|
||||||
|
this.state = this.message_length_expected > 0 ?
|
||||||
|
this.decoder_states.PAYLOAD_V2 :
|
||||||
|
this.state = this.decoder_states.CHECKSUM_V2;
|
||||||
|
break;
|
||||||
case this.decoder_states.CODE_V1:
|
case this.decoder_states.CODE_V1:
|
||||||
case this.decoder_states.CODE_JUMBO_V1:
|
case this.decoder_states.CODE_JUMBO_V1:
|
||||||
this.code = data[i];
|
this.code = data[i];
|
||||||
|
@ -136,6 +160,14 @@ var MSP = {
|
||||||
this.state = this.decoder_states.CHECKSUM_V1;
|
this.state = this.decoder_states.CHECKSUM_V1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case this.decoder_states.CODE_V2_LOW:
|
||||||
|
this.code = data[i];
|
||||||
|
this.state = this.decoder_states.CODE_V2_HIGH;
|
||||||
|
break;
|
||||||
|
case this.decoder_states.CODE_V2_HIGH:
|
||||||
|
this.message_length_expected |= data[i] << 8;
|
||||||
|
this.state = this.decoder_states.PAYLOAD_LENGTH_V2_LOW;
|
||||||
|
break;
|
||||||
case this.decoder_states.PAYLOAD_LENGTH_JUMBO_LOW:
|
case this.decoder_states.PAYLOAD_LENGTH_JUMBO_LOW:
|
||||||
this.message_length_expected = data[i];
|
this.message_length_expected = data[i];
|
||||||
this.state = this.decoder_states.PAYLOAD_LENGTH_JUMBO_HIGH;
|
this.state = this.decoder_states.PAYLOAD_LENGTH_JUMBO_HIGH;
|
||||||
|
@ -146,11 +178,14 @@ var MSP = {
|
||||||
this.state = this.decoder_states.PAYLOAD_V1;
|
this.state = this.decoder_states.PAYLOAD_V1;
|
||||||
break;
|
break;
|
||||||
case this.decoder_states.PAYLOAD_V1:
|
case this.decoder_states.PAYLOAD_V1:
|
||||||
|
case this.decoder_states.PAYLOAD_V2:
|
||||||
this.message_buffer_uint8_view[this.message_length_received] = data[i];
|
this.message_buffer_uint8_view[this.message_length_received] = data[i];
|
||||||
this.message_length_received++;
|
this.message_length_received++;
|
||||||
|
|
||||||
if (this.message_length_received >= this.message_length_expected) {
|
if (this.message_length_received >= this.message_length_expected) {
|
||||||
this.state = this.decoder_states.CHECKSUM_V1;
|
this.state = this.state == this.decoder_states.PAYLOAD_V1 ?
|
||||||
|
this.decoder_states.CHECKSUM_V1 :
|
||||||
|
this.decoder_states.CHECKSUM_V2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case this.decoder_states.CHECKSUM_V1:
|
case this.decoder_states.CHECKSUM_V1:
|
||||||
|
@ -167,26 +202,20 @@ var MSP = {
|
||||||
for (var ii = 0; ii < this.message_length_received; ii++) {
|
for (var ii = 0; ii < this.message_length_received; ii++) {
|
||||||
this.message_checksum ^= this.message_buffer_uint8_view[ii];
|
this.message_checksum ^= this.message_buffer_uint8_view[ii];
|
||||||
}
|
}
|
||||||
if (this.message_checksum == data[i]) {
|
this._dispatch_message(data[i]);
|
||||||
// message received, process
|
break;
|
||||||
mspHelper.processData(this);
|
case this.decoder_states.CHECKSUM_V2:
|
||||||
} else {
|
this.message_checksum = 0;
|
||||||
console.log('code: ' + this.code + ' - crc failed');
|
this.message_checksum = this._crc8_dvb_s2(this.message_checksum, 0); // flag
|
||||||
|
this.message_checksum = this._crc8_dvb_s2(this.message_checksum, this.code & 0xFF);
|
||||||
this.packet_error++;
|
this.message_checksum = this._crc8_dvb_s2(this.message_checksum, (this.code & 0xFF00) >> 8);
|
||||||
$('span.packet-error').html(this.packet_error);
|
this.message_checksum = this._crc8_dvb_s2(this.message_checksum, this.message_length_expected & 0xFF);
|
||||||
}
|
this.message_checksum = this._crc8_dvb_s2(this.message_checksum, (this.message_length_expected & 0xFF00) >> 8);
|
||||||
|
for (var ii = 0; ii < this.message_length_received; ii++) {
|
||||||
/*
|
this.message_checksum = this._crc8_dvb_s2(this.message_checksum, this.message_buffer_uint8_view[ii]);
|
||||||
* Free port
|
}
|
||||||
*/
|
this._dispatch_message(data[i]);
|
||||||
helper.mspQueue.freeHardLock();
|
|
||||||
|
|
||||||
// Reset variables
|
|
||||||
this.message_length_received = 0;
|
|
||||||
this.state = this.decoder_states.IDLE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
* Free port
|
* Free port
|
||||||
|
@ -203,6 +232,26 @@ var MSP = {
|
||||||
this.message_buffer_uint8_view = new Uint8Array(this.message_buffer);
|
this.message_buffer_uint8_view = new Uint8Array(this.message_buffer);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_dispatch_message: function(expected_checksum) {
|
||||||
|
if (this.message_checksum == expected_checksum) {
|
||||||
|
// message received, process
|
||||||
|
mspHelper.processData(this);
|
||||||
|
} else {
|
||||||
|
console.log('code: ' + this.code + ' - crc failed');
|
||||||
|
this.packet_error++;
|
||||||
|
$('span.packet-error').html(this.packet_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free port
|
||||||
|
*/
|
||||||
|
helper.mspQueue.freeHardLock();
|
||||||
|
|
||||||
|
// Reset variables
|
||||||
|
this.message_length_received = 0;
|
||||||
|
this.state = this.decoder_states.IDLE;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {MSP} mspData
|
* @param {MSP} mspData
|
||||||
|
@ -225,48 +274,60 @@ var MSP = {
|
||||||
},
|
},
|
||||||
|
|
||||||
send_message: function (code, data, callback_sent, callback_msp) {
|
send_message: function (code, data, callback_sent, callback_msp) {
|
||||||
var bufferOut,
|
var payloadLength = data && data.length ? data.length : 0;
|
||||||
bufView,
|
var length;
|
||||||
i;
|
var buffer;
|
||||||
|
var view;
|
||||||
|
var checksum;
|
||||||
|
var ii;
|
||||||
|
|
||||||
// always reserve 6 bytes for protocol overhead !
|
switch (this.protocolVersion) {
|
||||||
if (data) {
|
case this.constants.PROTOCOL_V1:
|
||||||
var size = data.length + 6,
|
length = payloadLength + 6;
|
||||||
checksum;
|
buffer = new ArrayBuffer(length);
|
||||||
|
view = new Uint8Array(buffer);
|
||||||
|
view[0] = this.symbols.BEGIN;
|
||||||
|
view[1] = this.symbols.PROTO_V1;
|
||||||
|
view[2] = this.symbols.TO_MWC;
|
||||||
|
view[3] = payloadLength;
|
||||||
|
view[4] = code;
|
||||||
|
|
||||||
bufferOut = new ArrayBuffer(size);
|
checksum = view[3] ^ view[4];
|
||||||
bufView = new Uint8Array(bufferOut);
|
for (ii = 0; ii < payloadLength; ii++) {
|
||||||
|
view[ii + 5] = data[ii];
|
||||||
|
checksum ^= data[ii];
|
||||||
|
}
|
||||||
|
view[length-1] = checksum;
|
||||||
|
break;
|
||||||
|
case this.constants.PROTOCOL_V2:
|
||||||
|
length = payloadLength + 9;
|
||||||
|
buffer = new ArrayBuffer(length);
|
||||||
|
view = new Uint8Array(buffer);
|
||||||
|
view[0] = this.symbols.BEGIN;
|
||||||
|
view[1] = this.symbols.PROTO_V2;
|
||||||
|
view[2] = this.symbols.TO_MWC;
|
||||||
|
view[3] = 0; // flag: reserved, set to 0
|
||||||
|
view[4] = code & 0xFF; // code lower byte
|
||||||
|
view[5] = (code & 0xFF00) >> 8; // code upper byte
|
||||||
|
view[6] = payloadLength & 0xFF; // payloadLength lower byte
|
||||||
|
view[7] = (payloadLength & 0xFF00) >> 8; // payloadLength upper byte
|
||||||
|
for (ii = 0; ii < payloadLength; ii++) {
|
||||||
|
view[8+ii] = data[ii];
|
||||||
|
}
|
||||||
|
checksum = 0;
|
||||||
|
for (ii = 3; ii < length-1; ii++) {
|
||||||
|
checksum = this._crc8_dvb_s2(checksum, view[ii]);
|
||||||
|
}
|
||||||
|
view[length-1] = checksum;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw "Invalid MSP protocol version " + this.protocolVersion;
|
||||||
|
|
||||||
bufView[0] = 36; // $
|
|
||||||
bufView[1] = 77; // M
|
|
||||||
bufView[2] = 60; // <
|
|
||||||
bufView[3] = data.length;
|
|
||||||
bufView[4] = code;
|
|
||||||
|
|
||||||
checksum = bufView[3] ^ bufView[4];
|
|
||||||
|
|
||||||
for (i = 0; i < data.length; i++) {
|
|
||||||
bufView[i + 5] = data[i];
|
|
||||||
|
|
||||||
checksum ^= bufView[i + 5];
|
|
||||||
}
|
|
||||||
|
|
||||||
bufView[5 + data.length] = checksum;
|
|
||||||
} else {
|
|
||||||
bufferOut = new ArrayBuffer(6);
|
|
||||||
bufView = new Uint8Array(bufferOut);
|
|
||||||
|
|
||||||
bufView[0] = 36; // $
|
|
||||||
bufView[1] = 77; // M
|
|
||||||
bufView[2] = 60; // <
|
|
||||||
bufView[3] = 0; // data length
|
|
||||||
bufView[4] = code; // code
|
|
||||||
bufView[5] = bufView[3] ^ bufView[4]; // checksum
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var message = new MspMessageClass();
|
var message = new MspMessageClass();
|
||||||
message.code = code;
|
message.code = code;
|
||||||
message.messageBody = bufferOut;
|
message.messageBody = buffer;
|
||||||
message.onFinish = callback_msp;
|
message.onFinish = callback_msp;
|
||||||
message.onSend = callback_sent;
|
message.onSend = callback_sent;
|
||||||
|
|
||||||
|
@ -280,6 +341,17 @@ var MSP = {
|
||||||
helper.mspQueue.put(message);
|
helper.mspQueue.put(message);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
},
|
||||||
|
_crc8_dvb_s2: function(crc, ch) {
|
||||||
|
crc ^= ch;
|
||||||
|
for (var ii = 0; ii < 8; ++ii) {
|
||||||
|
if (crc & 0x80) {
|
||||||
|
crc = ((crc << 1) & 0xFF) ^ 0xD5;
|
||||||
|
} else {
|
||||||
|
crc = (crc << 1) & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
},
|
},
|
||||||
promise: function(code, data) {
|
promise: function(code, data) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
|
@ -246,8 +246,13 @@ function onOpen(openInfo) {
|
||||||
|
|
||||||
FC.resetState();
|
FC.resetState();
|
||||||
|
|
||||||
// request configuration data
|
// request configuration data. Start with MSPv1 and
|
||||||
|
// upgrade to MSPv2 if possible.
|
||||||
|
MSP.protocolVersion = MSP.constants.PROTOCOL_V1;
|
||||||
MSP.send_message(MSPCodes.MSP_API_VERSION, false, false, function () {
|
MSP.send_message(MSPCodes.MSP_API_VERSION, false, false, function () {
|
||||||
|
if (CONFIG.apiVersion && semver.gte(CONFIG.apiVersion, "2.0.0")) {
|
||||||
|
MSP.protocolVersion = MSP.constants.PROTOCOL_V2;
|
||||||
|
}
|
||||||
GUI.log(chrome.i18n.getMessage('apiVersionReceived', [CONFIG.apiVersion]));
|
GUI.log(chrome.i18n.getMessage('apiVersionReceived', [CONFIG.apiVersion]));
|
||||||
|
|
||||||
if (semver.gte(CONFIG.apiVersion, CONFIGURATOR.apiVersionAccepted)) {
|
if (semver.gte(CONFIG.apiVersion, CONFIGURATOR.apiVersionAccepted)) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue