]> git.basschouten.com Git - pithrottler.git/commitdiff
Initial commit.
authorBas Schouten <bschouten@mozilla.com>
Sun, 21 Apr 2024 10:14:43 +0000 (10:14 +0000)
committerBas Schouten <bschouten@mozilla.com>
Sun, 21 Apr 2024 10:14:43 +0000 (10:14 +0000)
html/index.html [new file with mode: 0644]
pithrottler.js [new file with mode: 0644]

diff --git a/html/index.html b/html/index.html
new file mode 100644 (file)
index 0000000..d82b11d
--- /dev/null
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <title>PiThrottler Configuration</title>
+  <script>
+    const presets = {
+      Unlimited: {
+        label: "Unlimited",
+        latency: 0,
+        ploss: 0,
+        throughput: 0
+      },
+      F4G: {
+        label: "4G Fast",
+        latency: 30,
+        ploss: 0,
+        throughput: 20000
+      },
+      S4G: {
+        label: "4G Slow",
+        latency: 150,
+        ploss: 1,
+        throughput: 10000
+      },
+      F3G: {
+        label: "3G Fast",
+        latency: 110,
+        ploss: 0,
+        throughput: 5000
+      },
+      S3G: {
+        label: "3G Slow",
+        latency: 200,
+        ploss: 3,
+        throughput: 1000
+        }
+    };
+    function saveSettings() {
+      fetch("/set?latency=" + document.getElementById("latencyRange").value + "&ploss=" + document.getElementById("plossRange").value + "&throughput=" + document.getElementById("tpRange").value);
+    }
+
+    function loadPresets() {
+      let innerhtml = "";
+      for (type in presets) {
+        innerhtml += "<option value='" + type + "'>" + presets[type].label + "</option>";
+      }
+      document.getElementById("preset").innerHTML = innerhtml;
+    }
+
+    function changePreset() {
+      var preset = document.getElementById("preset").value;
+      document.getElementById("latencyRange").value = presets[preset].latency;
+      document.getElementById("latency").innerHTML = presets[preset].latency;
+      document.getElementById("plossRange").value = presets[preset].ploss;
+      document.getElementById("ploss").innerHTML = presets[preset].ploss;
+      document.getElementById("tpRange").value = presets[preset].throughput;
+      document.getElementById("tp").innerHTML = presets[preset].throughput;
+    }
+  </script>
+</head>
+<body onload="loadPresets();">
+  <select id="preset" onchange="changePreset();">
+
+  </select>
+<div class="slidecontainer">
+  Latency<br />
+  <input type="range" min="0" max="1000" style="width:400px;" value="0" class="slider" id="latencyRange" oninput="document.getElementById('latency').innerHTML = this.value;"> <span id="latency">0</span> ms
+</div>
+<div class="slidecontainer">
+  Packet Loss<br />
+  <input type="range" min="0" max="95" style="width:400px;" value="0" class="slider" id="plossRange" oninput="document.getElementById('ploss').innerHTML = this.value;"> <span id="ploss">0</span> %
+</div>
+<div class="slidecontainer">
+  Throughput Limitation (0 for unlimited)<br />
+  <input type="range" min="0" max="20000" style="width:400px;" value="0" class="slider" id="tpRange" oninput="document.getElementById('tp').innerHTML = this.value;"> <span id="tp">0</span> kb/s
+</div>
+<button onclick="saveSettings();">Save Settings</button>
+</body>
+</html>
\ No newline at end of file
diff --git a/pithrottler.js b/pithrottler.js
new file mode 100644 (file)
index 0000000..c8a01ac
--- /dev/null
@@ -0,0 +1,73 @@
+const http = require('http');
+const serveStatic = require('serve-static');
+const finalhandler = require('finalhandler');
+const { exec } = require("node:child_process");
+
+var serve = serveStatic("./html");
+
+const app = (req, res) => {
+  console.log(new Date(), req.url);
+
+  if (req.url.startsWith("/set")) {
+    let searchParams = new URL("http://localhost:2121" + req.url).searchParams;
+
+    var latency = searchParams.get("latency");
+    var ploss = searchParams.get("ploss");
+    var throughput = searchParams.get("throughput");
+
+    if (!latency) {
+      latency = 0;
+    }
+    if (!ploss) {
+      ploss = 0;
+    }
+    if (!throughput) {
+      throughput = 0;
+    }
+
+    res.statusCode = 200;
+    res.setHeader('Content-Type', 'text/plain');
+    res.setHeader('Access-Control-Allow-Origin', '*');
+    res.end("Setting parameters, latency: " + latency + " ms, packet loss: " + ploss + "%, Throughput: " + throughput + " kbit/s");
+
+    exec("sudo tc qdisc del dev wlan0 root");
+    exec("sudo tc qdisc del dev wlan0 root");
+
+    if (latency > 0 || ploss > 0) {
+      let command = "sudo tc qdisc add dev wlan0 root handle 30: netem";
+
+      if (latency > 0) {
+        command += " delay " + latency + "ms";
+      }
+      if (ploss > 0) {
+        command += " loss " + ploss + "%";
+      }
+
+      exec(command);
+      console.log("Setting lattency and packet loss");
+    }
+
+    if (throughput > 0) {
+      let command = "sudo tc qdisc add dev wlan0 ";
+
+      if (latency > 0 || ploss > 0) {
+        command += "parent 30:1";
+      } else {
+        command += "root";
+      }
+
+      command += " tbf rate " + throughput + "kbit burst 32kbit latency 500ms";
+      exec(command);
+      console.log("Setting bandwidth limitation");
+    }
+    
+    return;
+  }
+
+  var done = finalhandler(req, res);
+  serve(req, res, done);
+};
+
+const server = http.createServer(app)
+server.listen(2121, "0.0.0.0", () => {
+});