diff --git a/generator/mavgen_javascript.py b/generator/mavgen_javascript.py index 79dbcfb1d..1e1cd608c 100644 --- a/generator/mavgen_javascript.py +++ b/generator/mavgen_javascript.py @@ -35,17 +35,9 @@ def generate_preamble(outf, msgs, args, xml): */ jspack = require("jspack").jspack, - _ = require("underscore"), events = require("events"), // for .emit(..), MAVLink20Processor inherits from events.EventEmitter util = require("util"); -var Buffer = require('buffer').Buffer; // required in react - no impact in node -var Long = require('long'); - -// Add a convenience method to Buffer -Buffer.prototype.toByteArray = function () { - return Array.prototype.slice.call(this, 0) -} ${MAVHEAD} = function(){}; @@ -54,7 +46,7 @@ def generate_preamble(outf, msgs, args, xml): var bytes = buffer; var crcOUT = crcIN === undefined ? 0xffff : crcIN; - _.each(bytes, function(e) { + bytes.forEach(function(e) { var tmp = e ^ (crcOUT & 0xff); tmp = (tmp ^ (tmp << 4)) & 0xff; crcOUT = (crcOUT >> 8) ^ (tmp << 8) ^ (tmp << 3) ^ (tmp >> 4); @@ -111,7 +103,7 @@ def generate_preamble(outf, msgs, args, xml): ${MAVHEAD}.header.prototype.pack = function() { return jspack.Pack('BBBBBBBHB', [${PROTOCOL_MARKER}, this.mlen, this.incompat_flags, this.compat_flags, this.seq, this.srcSystem, this.srcComponent, ((this.msgId & 0xFF) << 8) | ((this.msgId >> 8) & 0xFF), this.msgId>>16]); } - """, {'PROTOCOL_MARKER' : xml.protocol_marker, +""", {'PROTOCOL_MARKER' : xml.protocol_marker, 'MAVHEAD': get_mavhead(xml)}) # Mavlink1 else: @@ -120,7 +112,7 @@ def generate_preamble(outf, msgs, args, xml): ${MAVHEAD}.header.prototype.pack = function() { return jspack.Pack('BBBBBB', [${PROTOCOL_MARKER}, this.mlen, this.seq, this.srcSystem, this.srcComponent, this.msgId]); } - """, {'PROTOCOL_MARKER' : xml.protocol_marker, +""", {'PROTOCOL_MARKER' : xml.protocol_marker, 'MAVHEAD': get_mavhead(xml)}) t.write(outf, """ @@ -131,16 +123,16 @@ def generate_preamble(outf, msgs, args, xml): // Convenience setter to facilitate turning the unpacked array of data into member properties ${MAVHEAD}.message.prototype.set = function(args,verbose) { -// inspect - _.each(this.fieldnames, function(e, i) { + // inspect + this.fieldnames.forEach(function(e, i) { var num = parseInt(i,10); if (this.hasOwnProperty(e) && isNaN(num) ){ // asking for an attribute that's non-numeric is ok unless its already an attribute we have if ( verbose >= 1) { console.log("WARNING, overwriting an existing property is DANGEROUS:"+e+" ==>"+i+"==>"+args[i]+" -> "+JSON.stringify(this)); } } }, this); - //console.log(this.fieldnames); -// then modify - _.each(this.fieldnames, function(e, i) { + + // then modify + this.fieldnames.forEach(function(e, i) { this[e] = args[i]; }, this); }; @@ -166,11 +158,11 @@ def generate_preamble(outf, msgs, args, xml): // first add the linkid(1 byte) and timestamp(6 bytes) that start the signature this._msgbuf = this._msgbuf.concat(jspack.Pack('= 3 ) { - var unpacked = jspack.Unpack('BBB', this.buf.slice(0, 3)); - var magic = unpacked[0]; // stx ie fd or fe etc - this.expected_length = unpacked[1] + ${MAVHEAD}.HEADER_LEN + 2 // length of message + header + CRC (ie non-signed length) - this.incompat_flags = unpacked[2]; - // mavlink2 only.. in mavlink1, incompat_flags var above is actually the 'seq', but for this test its ok. - if ((magic == ${MAVHEAD}.PROTOCOL_MARKER_V2 ) && ( this.incompat_flags & ${MAVHEAD}.MAVLINK_IFLAG_SIGNED )){ - this.expected_length += ${MAVHEAD}.MAVLINK_SIGNATURE_BLOCK_LEN; - } + + if( this.buf.length >= 3 ) { + var unpacked = jspack.Unpack('BBB', this.buf.slice(0, 3)); + var magic = unpacked[0]; // stx ie fd or fe etc + this.expected_length = unpacked[1] + ${MAVHEAD}.HEADER_LEN + 2 // length of message + header + CRC (ie non-signed length) + this.incompat_flags = unpacked[2]; + // mavlink2 only.. in mavlink1, incompat_flags var above is actually the 'seq', but for this test its ok. + if ((magic == ${MAVHEAD}.PROTOCOL_MARKER_V2 ) && ( this.incompat_flags & ${MAVHEAD}.MAVLINK_IFLAG_SIGNED )){ + this.expected_length += ${MAVHEAD}.MAVLINK_SIGNATURE_BLOCK_LEN; + } } } @@ -513,22 +511,24 @@ def generate_mavlink_class(outf, msgs, xml): // input some data bytes, possibly returning a new message - python equiv function is called parse_char / __parse_char_legacy ${MAVPROCESSOR}.prototype.parseChar = function(c) { + if (c == null) { + return + } + var m = null; try { - this.pushBuffer(c); this.parsePrefix(); this.parseLength(); m = this.parsePayload(); } catch(e) { - this.log('error', e.message); this.total_receive_errors += 1; m = new ${MAVHEAD}.messages.bad_data(this.bufInError, e.message); - this.bufInError = new Buffer.from([]); - + this.bufInError = new Uint8Array(); + } // emit a packet-specific message as well as a generic message, user/s can choose to use either or both of these. @@ -579,7 +579,7 @@ def generate_mavlink_class(outf, msgs, xml): // input some data bytes, possibly returning an array of new messages ${MAVPROCESSOR}.prototype.parseBuffer = function(s) { - + // Get a message, if one is available in the stream. var m = this.parseChar(s); @@ -587,7 +587,7 @@ def generate_mavlink_class(outf, msgs, xml): if ( null === m ) { return null; } - + // While more valid messages can be read from the existing buffer, add // them to the array of new messages and return them. var ret = [m]; @@ -602,113 +602,87 @@ def generate_mavlink_class(outf, msgs, xml): } -// from Buffer to ArrayBuffer -function toArrayBuffer(buf) { - var ab = new ArrayBuffer(buf.length); - var view = new Uint8Array(ab); - for (var i = 0; i < buf.length; ++i) { - view[i] = buf[i]; - } - return ab; -} -// and back -function toBuffer(ab) { - var buf = Buffer.alloc(ab.byteLength); - var view = new Uint8Array(ab); - for (var i = 0; i < buf.length; ++i) { - buf[i] = view[i]; - } - return buf; -} - //check signature on incoming message , many of the comments in this file come from the python impl -${MAVPROCESSOR}.prototype.check_signature = function(msgbuf, srcSystem, srcComponent) { +${MAVPROCESSOR}.prototype.check_signature = function(msgbuf, srcSystem, srcComponent) { - //if (isinstance(msgbuf, array.array)){ - // msgbuf = msgbuf.tostring() - //} - if ( Buffer.isBuffer(msgbuf) ) { - msgbuf = toArrayBuffer(msgbuf); - } - - //timestamp_buf = msgbuf[-12:-6] - var timestamp_buf= msgbuf.slice(-12,-6); - - //link_id = msgbuf[-13] - var link_id= new Buffer.from(msgbuf.slice(-13,-12)); // just a single byte really, but returned as a buffer + //timestamp_buf = msgbuf[-12:-6] + var timestamp_buf= msgbuf.slice(-12,-6); + + //link_id = msgbuf[-13] + var link_id = new Uint8Array.from(msgbuf.slice(-13,-12)); // just a single byte really, but returned as a buffer link_id = link_id[0]; // get the first byte. - - //self.mav_sign_unpacker = jspack.Unpack(' 0)){ - var len_if_signed = mlen+signature_len; - //console.log("Packet appears signed && labeled as signed, OK. msgId=" + msgId); - - } else if ((mlen == actual_len_nosign) && (signature_len > 0)){ - - var len_if_signed = mlen+signature_len; + // is packet supposed to be signed? + if ( incompat_flags & ${MAVHEAD}.MAVLINK_IFLAG_SIGNED ){ + signature_len = ${MAVHEAD}.MAVLINK_SIGNATURE_BLOCK_LEN; + } else { + signature_len = 0; + } + + // header's declared len compared to packets actual len + var actual_len = (msgbuf.length - (${MAVHEAD}.HEADER_LEN + 2 + signature_len)); + var actual_len_nosign = (msgbuf.length - (${MAVHEAD}.HEADER_LEN + 2 )); + + if ((mlen == actual_len) && (signature_len > 0)){ + var len_if_signed = mlen+signature_len; + //console.log("Packet appears signed && labeled as signed, OK. msgId=" + msgId); + + } else if ((mlen == actual_len_nosign) && (signature_len > 0)){ + + var len_if_signed = mlen+signature_len; throw new Error("Packet appears unsigned when labeled as signed. Got actual_len "+actual_len_nosign+" expected " + len_if_signed + ", msgId=" + msgId); - - } else if( mlen != actual_len) { + + } else if( mlen != actual_len) { throw new Error("Invalid MAVLink message length. Got " + (msgbuf.length - (${MAVHEAD}.HEADER_LEN + 2)) + " expected " + mlen + ", msgId=" + msgId); - } - - if( false === _.has(${MAVHEAD}.map, msgId) ) { + } + + if (!(msgId in ${MAVHEAD}.map)) { throw new Error("Unknown MAVLink message ID (" + msgId + ")"); } - // here's the common chunks of packet we want to work with below.. - var headerBuf= msgbuf.slice(${MAVHEAD}.HEADER_LEN); // first10 - var sigBuf = msgbuf.slice(-signature_len); // last 13 or nothing - var crcBuf1 = msgbuf.slice(-2); // either last-2 or last-2-prior-to-signature - var crcBuf2 = msgbuf.slice(-15,-13); // either last-2 or last-2-prior-to-signature - var payloadBuf = msgbuf.slice(${MAVHEAD}.HEADER_LEN, -(signature_len+2)); // the remaining bit between the header and the crc - var crcCheckBuf = msgbuf.slice(1, -(signature_len+2)); // the part uses to calculate the crc - ie between the magic and signature, + // here's the common chunks of packet we want to work with below.. + //var headerBuf= msgbuf.slice(${MAVHEAD}.HEADER_LEN); // first10 + //var sigBuf = msgbuf.slice(-signature_len); // last 13 or nothing + var crcBuf1 = msgbuf.slice(-2); // either last-2 or last-2-prior-to-signature + var crcBuf2 = msgbuf.slice(-15,-13); // either last-2 or last-2-prior-to-signature + var payloadBuf = msgbuf.slice(${MAVHEAD}.HEADER_LEN, -(signature_len+2)); // the remaining bit between the header and the crc + var crcCheckBuf = msgbuf.slice(1, -(signature_len+2)); // the part uses to calculate the crc - ie between the magic and signature, // decode the payload // refs: (fmt, type, order_map, crc_extra) = ${MAVHEAD}.map[msgId] var decoder = ${MAVHEAD}.map[msgId]; // decode the checksum - var receivedChecksum = undefined; - if ( signature_len == 0 ) { // unsigned - try { - receivedChecksum = jspack.Unpack(' payloadBuf.length) { - payloadBuf = Buffer.concat([payloadBuf, Buffer.alloc(paylen - payloadBuf.length)]); + payloadBuf = this.concat_buffer(payloadBuf, new Uint8Array(paylen - payloadBuf.length).fill(0)); } """) @@ -916,7 +890,7 @@ def generate_mavlink_class(outf, msgs, xml): if (elementsInMsg == actualElementsInMsg) { // Reorder the fields to match the order map - _.each(t, function(e, i, l) { + t.forEach(function(e, i, l) { args[i] = t[decoder.order_map[i]] }); } else { @@ -960,13 +934,11 @@ def generate_mavlink_class(outf, msgs, xml): } // Finally reorder the fields to match the order map - _.each(t, function(e, i, l) { + t.forEach(function(e, i, l) { args[i] = tempArgs[decoder.order_map[i]] }); } - - // construct the message object try { // args at this point might look like: { '0': 6, '1': 8, '2': 0, '3': 0, '4': 3, '5': 3 } @@ -977,11 +949,11 @@ def generate_mavlink_class(outf, msgs, xml): throw new Error('Unable to instantiate MAVLink message of type '+decoder.type+' : ' + e.message); } - m._signed = sig_ok; - if (m._signed) { m._link_id = msgbuf[-13]; } + m._signed = sig_ok; + if (m._signed) { m._link_id = msgbuf[-13]; } m._msgbuf = msgbuf; - m._payload = payloadBuf + m._payload = payloadBuf; m.crc = receivedChecksum; m._header = new ${MAVHEAD}.header(msgId, mlen, seq, srcSystem, srcComponent, incompat_flags, compat_flags); this.log(m);