Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix WeDo2.send sends empty message #192

Merged
merged 2 commits into from
Feb 10, 2024

Conversation

tpsnt
Copy link

@tpsnt tpsnt commented Feb 8, 2024

WeDo2.send invokes Base64Util.uint8ArrayToBase64(message). However message.arrayLength === undefined. This causes Base64Util.uint8ArrayToBase64 always returning empty string ''.

Resolves

WeDo2.send invokes Base64Util.uint8ArrayToBase64(message). However message.arrayLength === undefined. This causes Base64Util.uint8ArrayToBase64 always returning empty string ''.
This causes motors not functioning, and other devices not functioning.

Proposed Changes

replace Base64Util.uint8ArrayToBase64(message) with Base64Util.uint8ArrayToBase64(new Uint8Array(message))

Reason for Changes

WeDo2.send invokes Base64Util.uint8ArrayToBase64(message). However message.arrayLength === undefined. This causes Base64Util.uint8ArrayToBase64 always returning empty string ''.
This causes motors not functioning, and other devices not functioning.

Test Coverage

Wedo 2.0 Block: turn motor on for 1 seconds.

WeDo2.send invokes Base64Util.uint8ArrayToBase64(message). However message.arrayLength === undefined. This causes Base64Util.uint8ArrayToBase64 always returning empty string ''.
@tpsnt
Copy link
Author

tpsnt commented Feb 8, 2024

@GarboMuffin
Copy link
Member

do you know if that affects the other scratch link extensions too?

@tpsnt
Copy link
Author

tpsnt commented Feb 9, 2024

do you know if that affects the other scratch link extensions too?

no, i only have wedo2. If i get plenty time i will probably review other scratch link extensions codes. But I don't have hardware other than wedo2.

@tpsnt
Copy link
Author

tpsnt commented Feb 9, 2024

do you know if that affects the other scratch link extensions too?

I just reviewed ev3 entension code.
https://github.com/TurboWarp/scratch-vm/blob/develop/src/extensions/scratch3_ev3/index.js Line 659

/**
 * Send a message to the peripheral BT socket.
 * @param {Uint8Array} message - the message to send.
 * @param {boolean} [useLimiter=true] - if true, use the rate limiter
 * @return {Promise} - a promise result of the send operation.
 */
send (message, useLimiter = true) {
    if (!this.isConnected()) return Promise.resolve();

    if (useLimiter) {
        if (!this._rateLimiter.okayToSend()) return Promise.resolve();
    }

    return this._bt.sendMessage({
        message: Base64Util.uint8ArrayToBase64(message),
        encoding: 'base64'
    });
}

Line 678

    /**
     * Genrates direct commands that are sent to the EV3 as a single or compounded byte arrays.
     * See 'EV3 Communication Developer Kit', section 4, page 24 at
     * https://education.lego.com/en-us/support/mindstorms-ev3/developer-kits.
     *
     * Direct commands are one of two types:
     * DIRECT_COMMAND_NO_REPLY = a direct command where no reply is expected
     * DIRECT_COMMAND_REPLY = a direct command where a reply is expected, and the
     * number and length of returned values needs to be specified.
     *
     * The direct command byte array sent takes the following format:
     * Byte 0 - 1: Command size, Little Endian. Command size not including these 2 bytes
     * Byte 2 - 3: Message counter, Little Endian. Forth running counter
     * Byte 4:     Command type. Either DIRECT_COMMAND_REPLY or DIRECT_COMMAND_NO_REPLY
     * Byte 5 - 6: Reservation (allocation) of global and local variables using a compressed format
     *             (globals reserved in byte 5 and the 2 lsb of byte 6, locals reserved in the upper
     *             6 bits of byte 6) – see documentation for more details.
     * Byte 7 - n: Byte codes as a single command or compound commands (I.e. more commands composed
     *             as a small program)
     *
     * @param {number} type - the direct command type.
     * @param {string} byteCommands - a compound array of EV3 Opcode + arguments.
     * @param {number} allocation - the allocation of global and local vars needed for replies.
     * @return {array} - generated complete command byte array, with header and compounded commands.
     */
    generateCommand (type, byteCommands, allocation = 0) {

        // Header (Bytes 0 - 6)
        let command = [];
        command[2] = 0; // Message counter unused for now
        command[3] = 0; // Message counter unused for now
        command[4] = type;
        command[5] = allocation & 0xFF;
        command[6] = allocation >> 8 && 0xFF;

        // Bytecodes (Bytes 7 - n)
        command = command.concat(byteCommands);

        // Calculate command length minus first two header bytes
        const len = command.length - 2;
        command[0] = len & 0xFF;
        command[1] = len >> 8 && 0xFF;

        return command;
    }

generateCommand returns array, not Uint8Array, so it is the same with wedo2, message sent will always be empty.
If i have time, i will perhaps review other extensions.

@GarboMuffin GarboMuffin merged commit 845c374 into TurboWarp:develop Feb 10, 2024
1 check passed
@GarboMuffin
Copy link
Member

This is supposed to be fixed on the live https://turbowarp.org/editor -- have you been able to test it with real hardware?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants