From 5aa990b4210b15b9696470a50409ab29a4484c2d Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Mon, 8 Jul 2019 16:06:06 +0100
Subject: [PATCH] Use mqtt directly instead of simple-mqtt-client

---
 server/package-lock.json               | 116 ++++++++++++++++++++++---
 server/package.json                    |   1 +
 server/ttn-app-server/TTNAppServer.mjs |  49 ++++++-----
 3 files changed, 133 insertions(+), 33 deletions(-)

diff --git a/server/package-lock.json b/server/package-lock.json
index 7a49f9a..09ae0d5 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -29,6 +29,14 @@
       "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
       "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
     },
+    "async-mqtt": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/async-mqtt/-/async-mqtt-2.3.0.tgz",
+      "integrity": "sha512-4CopFTWjwgPMK0iG+xI+/cfmJ60U5dnRqaUpgMW6jE7x1PJgQAn0YnjKTUOCh4i54VLPZGX+YrRQ2mDrvZYnJQ==",
+      "requires": {
+        "mqtt": "^2.3.1"
+      }
+    },
     "awilix": {
       "version": "4.2.2",
       "resolved": "https://registry.npmjs.org/awilix/-/awilix-4.2.2.tgz",
@@ -129,11 +137,12 @@
       "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
     },
     "d": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
-      "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
       "requires": {
-        "es5-ext": "^0.10.9"
+        "es5-ext": "^0.10.50",
+        "type": "^1.0.1"
       }
     },
     "debug": {
@@ -422,10 +431,50 @@
             "ms": "^2.1.1"
           }
         },
+        "mqtt": {
+          "version": "2.18.8",
+          "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-2.18.8.tgz",
+          "integrity": "sha512-3h6oHlPY/yWwtC2J3geraYRtVVoRM6wdI+uchF4nvSSafXPZnaKqF8xnX+S22SU/FcgEAgockVIlOaAX3fkMpA==",
+          "requires": {
+            "commist": "^1.0.0",
+            "concat-stream": "^1.6.2",
+            "end-of-stream": "^1.4.1",
+            "es6-map": "^0.1.5",
+            "help-me": "^1.0.1",
+            "inherits": "^2.0.3",
+            "minimist": "^1.2.0",
+            "mqtt-packet": "^5.6.0",
+            "pump": "^3.0.0",
+            "readable-stream": "^2.3.6",
+            "reinterval": "^1.1.0",
+            "split2": "^2.1.1",
+            "websocket-stream": "^5.1.2",
+            "xtend": "^4.0.1"
+          }
+        },
+        "mqtt-packet": {
+          "version": "5.6.1",
+          "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-5.6.1.tgz",
+          "integrity": "sha512-eaF9rO2uFrIYEHomJxziuKTDkbWW5psLBaIGCazQSKqYsTaB3n4SpvJ1PexKaDBiPnMLPIFWBIiTYT3IfEJfww==",
+          "requires": {
+            "bl": "^1.2.1",
+            "inherits": "^2.0.3",
+            "process-nextick-args": "^2.0.0",
+            "safe-buffer": "^5.1.0"
+          }
+        },
         "ms": {
           "version": "2.1.2",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
           "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+        },
+        "split2": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz",
+          "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==",
+          "requires": {
+            "through2": "^2.0.2"
+          }
         }
       }
     },
@@ -551,9 +600,9 @@
       "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
     },
     "process-nextick-args": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-      "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
     },
     "pump": {
       "version": "3.0.0",
@@ -622,6 +671,48 @@
         "manuh": "^1.4.3",
         "manuh-bridge": "^0.0.2",
         "mqtt": "^2.18.8"
+      },
+      "dependencies": {
+        "mqtt": {
+          "version": "2.18.8",
+          "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-2.18.8.tgz",
+          "integrity": "sha512-3h6oHlPY/yWwtC2J3geraYRtVVoRM6wdI+uchF4nvSSafXPZnaKqF8xnX+S22SU/FcgEAgockVIlOaAX3fkMpA==",
+          "requires": {
+            "commist": "^1.0.0",
+            "concat-stream": "^1.6.2",
+            "end-of-stream": "^1.4.1",
+            "es6-map": "^0.1.5",
+            "help-me": "^1.0.1",
+            "inherits": "^2.0.3",
+            "minimist": "^1.2.0",
+            "mqtt-packet": "^5.6.0",
+            "pump": "^3.0.0",
+            "readable-stream": "^2.3.6",
+            "reinterval": "^1.1.0",
+            "split2": "^2.1.1",
+            "websocket-stream": "^5.1.2",
+            "xtend": "^4.0.1"
+          }
+        },
+        "mqtt-packet": {
+          "version": "5.6.1",
+          "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-5.6.1.tgz",
+          "integrity": "sha512-eaF9rO2uFrIYEHomJxziuKTDkbWW5psLBaIGCazQSKqYsTaB3n4SpvJ1PexKaDBiPnMLPIFWBIiTYT3IfEJfww==",
+          "requires": {
+            "bl": "^1.2.1",
+            "inherits": "^2.0.3",
+            "process-nextick-args": "^2.0.0",
+            "safe-buffer": "^5.1.0"
+          }
+        },
+        "split2": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz",
+          "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==",
+          "requires": {
+            "through2": "^2.0.2"
+          }
+        }
       }
     },
     "split2": {
@@ -686,6 +777,11 @@
         "is-negated-glob": "^1.0.0"
       }
     },
+    "type": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/type/-/type-1.0.1.tgz",
+      "integrity": "sha512-MAM5dBMJCJNKs9E7JXo4CXRAansRfG0nlJxW7Wf6GZzSOvH31zClSaHdIMWLehe/EGMBkqeC55rrkaOr5Oo7Nw=="
+    },
     "typedarray": {
       "version": "0.0.6",
       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
@@ -749,9 +845,9 @@
       }
     },
     "xtend": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
-      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
     },
     "yallist": {
       "version": "3.0.3",
diff --git a/server/package.json b/server/package.json
index 99e8485..3c66a0a 100644
--- a/server/package.json
+++ b/server/package.json
@@ -20,6 +20,7 @@
 	"license": "MPL-2.0",
 	"dependencies": {
 		"@iarna/toml": "^2.2.3",
+		"async-mqtt": "^2.3.0",
 		"awilix": "^4.2.2",
 		"better-sqlite3": "^5.4.0",
 		"debug": "^4.1.1",
diff --git a/server/ttn-app-server/TTNAppServer.mjs b/server/ttn-app-server/TTNAppServer.mjs
index b9115cc..082e958 100644
--- a/server/ttn-app-server/TTNAppServer.mjs
+++ b/server/ttn-app-server/TTNAppServer.mjs
@@ -1,6 +1,6 @@
 "use strict";
 
-import MqttClient from 'simple-mqtt-client';
+import mqtt from 'async-mqtt';
 
 class TTNAppServer {
 	get connection_string() {
@@ -19,42 +19,45 @@ class TTNAppServer {
 	}
 	
 	async run() {
+		// 1: Sanity checks
 		if(this.settings.ttn.app_id == "CHANGE_THIS" || this.settings.ttn.access_key == "CHANGE_THIS") {
 			this.log.error(`Error: No TTN app id specified. Try filling in the required values in settings.toml. If they don't exist yet, try using server/settings.default.toml as a reference.`);
 			return false;
 		}
 		
-		this.ttn_client = await this.connect();
-		
-		for(let device_name of this.settings.ttn.devices) {
-			if(device_name == "CHANGE_THIS") {
-				this.log.error(`Error: No device names specified. Try filling in the required values in settings.toml. If they don't exist yet, try using server/settings.default.toml as a reference.`);
-				return false;
-			}
-			this.ttn_client.subscribe(`${device_name}/up`, this.handle_message.bind(this));
+		if(this.settings.ttn.devices.includes("CHANGE_THIS")) {
+			this.log.error(`Error: No device names specified. Try filling in the required values in settings.toml. If they don't exist yet, try using server/settings.default.toml as a reference.`);
+			return false;
 		}
 		
+		
+		// 2: Connect
+		this.ttn_client = await this.connect();
+		this.ttn_client.on("message", this.handle_message.bind(this));
 		this.log.log(`Connected to ${this.connection_string}`);
+		
+		
+		// 3: Subscribe
+		let result = await this.ttn_client.subscribe(this.settings.ttn.devices.map(
+			(device_name) => `${this.settings.ttn.app_id}/devices/${device_name}/up`
+		));
+		
+		this.log.log(`Subscribed to ${result.map((el) => el.topic).join(", ")}`);
 	}
 	
 	connect() {
 		return new Promise((resolve, _reject) => {
-			this.log.log(`Connecting to ${this.connection_string}`);
-			MqttClient.new().init(
-				this.connection_string,
-				this.settings.ttn.app_id,		// Username
-				this.settings.ttn.access_key,	// Password
-				`${this.settings.ttn.app_id}/devices`,	// Base topic
-				(client) => {
-					client;
-					resolve(client);
-				}
-			);
-		})
+			let client = mqtt.connect(this.connection_string, {
+				username: this.settings.ttn.app_id,
+				password: this.settings.ttn.access_key
+			});
+			client.once("connect", () => resolve(client));
+		});
 	}
 	
-	async handle_message(payload) {
-		await this.message_handler.handle(payload);
+	async handle_message(topic, message_buffer) {
+		console.log(arguments);
+		// await this.message_handler.handle(payload);
 	}
 }
 
