/** * Global flag that indicates if any bits should be transmitted. This flag * is used to stop the transmission of bits. * * @type {Boolean} */ let isTransmitting = false; /** * Array that contains all currently running web workers. * * @type {Worker[]} */ let workers = []; /** * @type {HTMLInputElement} */ const textInput = document.getElementById("textInput"); /** * @type {HTMLButtonElement} */ const startSendingButton = document.getElementById("start-sending-button"); /** * @type {HTMLButtonElement} */ const stopSendingButton = document.getElementById("stop-sending-button"); /** * @type {HTMLButtonElement} */ const startCalibrationButton = document.getElementById("start-calibration-button"); /** * @type {HTMLButtonElement} */ const stopCalibrationButton = document.getElementById("stop-calibration-button"); // Add event listeners to the buttons startCalibrationButton.addEventListener("click", startCalibration); stopCalibrationButton.addEventListener("click", stopCalibration); startSendingButton.addEventListener("click", startSending); stopSendingButton.addEventListener("click", stopSending); /** * Starts the web workers and add them to the global worker array. */ function startWorkers() { for (let i = 0; i < Constants.NUMBER_OF_WORKERS; i++) { workers.push(new Worker("./scripts/Worker.js")); } } /** * Terminates all currently running workers and clear out the worker array. */ function stopWorkers() { for (const worker of workers) { worker.terminate(); } workers = []; } /** * Starts the calibration process by simply starting all web workers. */ async function startCalibration() { Utility.setMessage("Calibration currently ongoing."); startCalibrationButton.classList.add(Constants.HIDE_CLASS); stopCalibrationButton.classList.remove(Constants.HIDE_CLASS); isTransmitting = true; while (isTransmitting) { for (let i = 0; i < Constants.CALIBRATION_SIGNAL.length; i++) { if (!isTransmitting) { stopWorkers(); return; } await transmitBit(Constants.CALIBRATION_SIGNAL[i], Constants.CLOCK_TIME); } } } /** * Stops the calibration process by stopping all currently running web workers. */ function stopCalibration() { Utility.setMessage(""); stopCalibrationButton.classList.add(Constants.HIDE_CLASS); startCalibrationButton.classList.remove(Constants.HIDE_CLASS); isTransmitting = false; } /** * Starts sending the message in the input after validating that the input is * valid. */ function startSending() { // Validate the input textInput.setCustomValidity(""); if (!textInput.checkValidity()) { if (textInput.validity.valueMissing) { textInput.setCustomValidity("Please enter between 1 and 16 characters."); } if (textInput.validity.patternMismatch) { textInput.setCustomValidity("Please only enter valid ASCII characters."); } textInput.reportValidity(); return; } Utility.setMessage(`Sending message: ${textInput.value}`); console.log(`Start sending message: ${textInput.value}`); startSendingButton.classList.add(Constants.HIDE_CLASS); stopSendingButton.classList.remove(Constants.HIDE_CLASS); const packet = new Packet(textInput.value); console.log(packet); const signal = Utility.manchesterEncode(packet.getData()); isTransmitting = true; transmitSignal(signal); } /** * Stop the sending process. */ function stopSending() { console.log("Stop Sending"); Utility.setMessage(""); stopSendingButton.classList.add(Constants.HIDE_CLASS); startSendingButton.classList.remove(Constants.HIDE_CLASS); isTransmitting = false; } /** * Transmits the given bit array until the sending is stopped. The transmission * is stopped when the global isTransmitting flag is set to false. * * @param {Number[]} signal */ async function transmitSignal(signal) { while (isTransmitting) { // Send the preamble for (const bit of Constants.PREAMBLE) { if (!isTransmitting) { stopWorkers(); return; } console.log(`Sending preamble: ${bit}`); await transmitBit(bit, Constants.PREAMBLE_CLOCK_TIME); } for (let i = 0; i < signal.length; i++) { if (!isTransmitting) { stopWorkers(); return; } console.log(`Sending symbol ${i + 1} of ${signal.length} of packet: ${signal[i]}`); await transmitBit(signal[i], Constants.CLOCK_TIME); } } } /** * Starts or stops the web workers depending on the bit value and then waits * for a duration of clockTime. * * @param {Number} bit */ function transmitBit(bit, clockTime) { if (bit === 1) { startWorkers(); return new Promise((resolve) => setTimeout(resolve, clockTime)); } stopWorkers(); return new Promise((resolve) => setTimeout(resolve, clockTime)); }