191 lines
4.7 KiB
JavaScript
191 lines
4.7 KiB
JavaScript
/**
|
|
* 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));
|
|
}
|