commit 4ac28c77780f0d894dcaeadc944f5e4fad21a1f4 Author: DELL4 Date: Wed Mar 2 10:54:02 2022 +0100 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..db8141a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +apikey.txt +ptt_daemon \ No newline at end of file diff --git a/ClientQuery.js b/ClientQuery.js new file mode 100644 index 0000000..9156fdf --- /dev/null +++ b/ClientQuery.js @@ -0,0 +1,143 @@ +import { Socket } from 'net'; + +function ClientQuery() { + this.state = 0; /* <0 Not connected | 1 Connecting | 2 Connected no auth | 3 Connected and auth | 4 Connection Failed> */ + let actions = this.actions = {}; + this.actionsLastCall = {}; + this.debug = true; + this.onMessage = function (data) { }; + + this.log = function (msg) { + if (!this.debug) { console.log(msg) } + } + + this.parse = function (res) { + let rawStrings = res.toString().split("|") + let parsedObjects = []; + rawStrings.forEach(function (str) { + let tempobj = {}; + str.split('\n\r')[0].split(" ").forEach(function (vari) { + if (vari.indexOf("=") > -1) { + tempobj[vari.split("=")[0]] = vari.substring(vari.indexOf('=') + 1, vari.length).replaceAll("\\\\s", " "); + } + }) + if (rawStrings.length > 1) { + parsedObjects.push(tempobj) + } else { + parsedObjects = tempobj; + } + }, this); + return parsedObjects; + } + + this.handleMessage = function (msg) { + if (this.actions.hasOwnProperty(msg.toString().split(" ")[0])) { + if (this.actionsLastCall[msg.toString().split(" ")[0]] != msg.toString()) { + this.actionsLastCall[msg.toString().split(" ")[0]] = msg.toString(); + this.actions[msg.toString().split(" ")[0]](msg); + } + } else { + this.onMessage(msg); + } + }.bind(this) + + this.notifyOn = function (action, args, callback) { + console.log('Register notify ' + action) + this.actions[action] = callback; + this.send(`clientnotifyregister event=${action} ${args}`) + } + + this.notifyOff = function (action, args) { + console.log('Unregister notify ' + action) + this.send(`clientnotifyunregister event=${action} ${args}`) + .then(() => { + this.actions[action] = undefined; + }) + } + + this.request = function (data) { + this.log('Request: ' + data) + return new Promise(function (resolve, reject) { + this.sock.write(data + '\n', 'utf8', (res) => { + console.log('Sent: ' + data) + + let func = (data) => { + if (data.toString() != 'error id=0 msg=ok\n\r') { + resolve(data) + this.sock.removeListener('data', func) + this.sock.on('data', this.handleMessage) + } + } + + this.sock.removeListener('data', this.handleMessage) + this.sock.on('data', func) + }) + }.bind(this)); + } + + this.send = function (data) { + this.log('Send: ' + data) + this.sock.removeListener('data', this.handleMessage) + this.sock.on('data', this.handleMessage) + return new Promise(function (resolve, reject) { + this.sock.write(data + '\n', 'utf8', (res) => { + this.log('Sent: ' + data) + resolve(res) + }) + }.bind(this)); + } + + this.reInitActions = function () { + let act = this.actions; + console.log('actions', Object.keys(act)) + Object.keys(act).forEach(function (key) { + console.log('addNotifyMemes Lol', key, 'schandlerid=1', typeof (act[key])) + this.notifyOn(key, 'schandlerid=1', act[key]) + }.bind(this)); + } + + this.reconnects = 0; + + setInterval(() => { + this.reconnects--; + }, 1000); + + this.connect = function (host, port, apikey) { + return new Promise(function (resolve, reject) { + if (this.reconnects < 5) { + this.reconnects++; + this.state = 1; + let sock = this.sock = new Socket(); + + sock.connect(port, host); + + sock.on('connect', () => { + this.state = 2; + sock.setTimeout(0); + this.log('connected'); + this.send(`auth apikey=${apikey}`) + .then(() => { + resolve(this) + this.state = 3; + setTimeout(() => { + this.reInitActions(actions); + }, 100); + }) + }); + + + sock.on('close', () => { + console.log('Socket closed, reopening..'); + sock.destroy(); + this.connect(host, port, apikey); + }); + + sock.on('data', this.handleMessage); + } else { + setTimeout(() => { this.connect(host, port, apikey) }, 3000); + } + }.bind(this)); + } +} + +export default ClientQuery; diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/daemon.js b/daemon.js new file mode 100644 index 0000000..8c1339f --- /dev/null +++ b/daemon.js @@ -0,0 +1,30 @@ +import { spawn } from 'child_process'; +import * as fs from 'fs'; +import ClientQuery from "./ClientQuery.js"; + +const apikey = fs.readFileSync('./apikey.txt').toString(); +let client = new ClientQuery(); + +let socket = await client.connect('127.0.0.1', '25639', apikey); + +// client.request('sendtextmessage targetmode=2 msg=Node.JS').then( res =>{ console.log(res.toString()) }); +await new Promise(r => setTimeout(r, 50)); + +let speakingUsers = {}; + +let whoamiData = client.parse((await client.request('whoami')).toString()); + +client.notifyOn('notifytalkstatuschange', '', data => { + let args = client.parse(data.toString()); + if (args.clid === whoamiData.clid) + return; + + speakingUsers[args.clid] = parseInt(args.status) === 1; + if (Object.values(speakingUsers).find(el => el)) { + // someone is speaking + spawn('/home/omega/Documents/ts3_remote/ptt_daemon', ['/dev/mhuxd/fsk1', '1']); + } else { + // nobody is speaking + spawn('/home/omega/Documents/ts3_remote/ptt_daemon', ['/dev/mhuxd/fsk1', '0']); + } +}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..7b297a1 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,433 @@ +{ + "name": "ts3-remote", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "ts3-remote", + "version": "1.0.0", + "license": "GPL", + "dependencies": { + "ioctl": "^2.0.2", + "serialport": "^10.3.0" + } + }, + "node_modules/@serialport/binding-mock": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz", + "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==", + "dependencies": { + "@serialport/bindings-interface": "^1.2.1", + "debug": "^4.3.3" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@serialport/bindings-cpp": { + "version": "10.6.3", + "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-10.6.3.tgz", + "integrity": "sha512-jmALQ62JvIlCIx8osWifVXX1GoftlTPiX/HuEYeCYlRmtwXrbBzoD8dXu48YfGoZ/dwaYYKTsJarHqFoPq809Q==", + "hasInstallScript": true, + "dependencies": { + "@serialport/bindings-interface": "1.2.1", + "@serialport/parser-readline": "^10.2.1", + "debug": "^4.3.2", + "node-addon-api": "^4.3.0", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=12.17.0 <13.0 || >=14.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/bindings-interface": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.1.tgz", + "integrity": "sha512-63Dyqz2gtryRDDckFusOYqLYhR3Hq/M4sEdbF9i/VsvDb6T+tNVgoAKUZ+FMrXXKnCSu+hYbk+MTc0XQANszxw==", + "engines": { + "node": "^12.22 || ^14.13 || >=16" + } + }, + "node_modules/@serialport/parser-byte-length": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-10.3.0.tgz", + "integrity": "sha512-pJ/VoFemzKRRNDHLhFfPThwP40QrGaEnm9TtwL7o2GihEPwzBg3T0bN13ew5TpbbUYZdMpUtpm3CGfl6av9rUQ==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-cctalk": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-10.3.0.tgz", + "integrity": "sha512-8ujmk8EvVbDPrNF4mM33bWvUYJOZ0wXbY3WCRazHRWvyCdL0VO0DQvW81ZqgoTpiDQZm5r8wQu9rmuemahF6vQ==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-delimiter": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-10.3.0.tgz", + "integrity": "sha512-9E4Vj6s0UbbcCCTclwegHGPYjJhdm9qLCS0lowXQDEQC5naZnbsELemMHs93nD9jHPcyx1B4oXkMnVZLxX5TYw==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-inter-byte-timeout": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-10.3.0.tgz", + "integrity": "sha512-wKP0QK85NHgvT6BBB1qBfKBBU4pf8kespNXAZBUYmFT+P4n8r8IZE2mqigCD+AiZcfWNQoAizwOsT/Jx/qeVig==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-packet-length": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-10.3.0.tgz", + "integrity": "sha512-bj0cWzt8YSQj/E5fRQVYdi4TsfTlZQrXlXrUwjyTsCONv8IPOHzsz+yY0fw5SEMiJtaLyqvPkCHLsttOd/zFsg==", + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@serialport/parser-readline": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-10.3.0.tgz", + "integrity": "sha512-ki3ATZ3/RAqnqGROBKE7k+OeZ0DZXZ53GTca4q71OU5RazbbNhTOBQLKLXD3v9QZXCMJdg4hGW/2Y0DuMUqMQg==", + "dependencies": { + "@serialport/parser-delimiter": "10.3.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-ready": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-10.3.0.tgz", + "integrity": "sha512-1owywJ4p592dJyVrEJZPIh6pUZ3/y/LN6kGTDH2wxdewRUITo/sGvDy0er5i2+dJD3yuowiAz0dOHSdz8tevJA==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-10.3.0.tgz", + "integrity": "sha512-tIogTs7CvTH+UUFnsvE7i33MSISyTPTGPWlglWYH2/5coipXY503jlaYS1YGe818wWNcSx6YAjMZRdhTWwM39w==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-slip-encoder": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-10.3.0.tgz", + "integrity": "sha512-JI0ILF5sylWn8f0MuMzHFBix/iMUTa79/Z95KaPZYnVaEdA7h7hh/o21Jmon/26P3RJwL1SNJCjZ81zfan+LtQ==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-spacepacket": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-10.3.0.tgz", + "integrity": "sha512-PDF73ClEPsClD1FEJZHNuBevDKsJCkqy/XD5+S5eA6+tY5D4HLrVgSWsg+3qqB6+dlpwf2CzHe+uO8D3teuKHA==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/stream": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-10.3.0.tgz", + "integrity": "sha512-7sooi5fHogYNVEJwxVdg872xO6TuMgQd2E9iRmv+o8pk/1dbBnPkmH6Ka3st1mVE+0KnIJqVlgei+ncSsqXIGw==", + "dependencies": { + "@serialport/bindings-interface": "1.2.1", + "debug": "^4.3.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "node_modules/ioctl": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ioctl/-/ioctl-2.0.2.tgz", + "integrity": "sha512-GPEiU99bJb3Z50JDRujQ9t+q4JaRvc1UrD7F5/kHDVWlRA3L4TMwqbMw/XIu/BzqccFP8OfsK+JIXmlAvJDs1g==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.14.0" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" + }, + "node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, + "node_modules/node-gyp-build": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/serialport": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/serialport/-/serialport-10.3.0.tgz", + "integrity": "sha512-MZMRlQgWOG7boLkJwm200Z3W39GcFmGo3tWxQrvyrZpH7W1p3t16M1VBglVxR6wXRF8qm01VxXBA+rNV7fPMVA==", + "dependencies": { + "@serialport/binding-mock": "10.2.2", + "@serialport/bindings-cpp": "10.6.3", + "@serialport/parser-byte-length": "10.3.0", + "@serialport/parser-cctalk": "10.3.0", + "@serialport/parser-delimiter": "10.3.0", + "@serialport/parser-inter-byte-timeout": "10.3.0", + "@serialport/parser-packet-length": "10.3.0", + "@serialport/parser-readline": "10.3.0", + "@serialport/parser-ready": "10.3.0", + "@serialport/parser-regex": "10.3.0", + "@serialport/parser-slip-encoder": "10.3.0", + "@serialport/parser-spacepacket": "10.3.0", + "@serialport/stream": "10.3.0", + "debug": "^4.3.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + } + }, + "dependencies": { + "@serialport/binding-mock": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz", + "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==", + "requires": { + "@serialport/bindings-interface": "^1.2.1", + "debug": "^4.3.3" + } + }, + "@serialport/bindings-cpp": { + "version": "10.6.3", + "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-10.6.3.tgz", + "integrity": "sha512-jmALQ62JvIlCIx8osWifVXX1GoftlTPiX/HuEYeCYlRmtwXrbBzoD8dXu48YfGoZ/dwaYYKTsJarHqFoPq809Q==", + "requires": { + "@serialport/bindings-interface": "1.2.1", + "@serialport/parser-readline": "^10.2.1", + "debug": "^4.3.2", + "node-addon-api": "^4.3.0", + "node-gyp-build": "^4.3.0" + } + }, + "@serialport/bindings-interface": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.1.tgz", + "integrity": "sha512-63Dyqz2gtryRDDckFusOYqLYhR3Hq/M4sEdbF9i/VsvDb6T+tNVgoAKUZ+FMrXXKnCSu+hYbk+MTc0XQANszxw==" + }, + "@serialport/parser-byte-length": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-10.3.0.tgz", + "integrity": "sha512-pJ/VoFemzKRRNDHLhFfPThwP40QrGaEnm9TtwL7o2GihEPwzBg3T0bN13ew5TpbbUYZdMpUtpm3CGfl6av9rUQ==" + }, + "@serialport/parser-cctalk": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-10.3.0.tgz", + "integrity": "sha512-8ujmk8EvVbDPrNF4mM33bWvUYJOZ0wXbY3WCRazHRWvyCdL0VO0DQvW81ZqgoTpiDQZm5r8wQu9rmuemahF6vQ==" + }, + "@serialport/parser-delimiter": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-10.3.0.tgz", + "integrity": "sha512-9E4Vj6s0UbbcCCTclwegHGPYjJhdm9qLCS0lowXQDEQC5naZnbsELemMHs93nD9jHPcyx1B4oXkMnVZLxX5TYw==" + }, + "@serialport/parser-inter-byte-timeout": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-10.3.0.tgz", + "integrity": "sha512-wKP0QK85NHgvT6BBB1qBfKBBU4pf8kespNXAZBUYmFT+P4n8r8IZE2mqigCD+AiZcfWNQoAizwOsT/Jx/qeVig==" + }, + "@serialport/parser-packet-length": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-10.3.0.tgz", + "integrity": "sha512-bj0cWzt8YSQj/E5fRQVYdi4TsfTlZQrXlXrUwjyTsCONv8IPOHzsz+yY0fw5SEMiJtaLyqvPkCHLsttOd/zFsg==" + }, + "@serialport/parser-readline": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-10.3.0.tgz", + "integrity": "sha512-ki3ATZ3/RAqnqGROBKE7k+OeZ0DZXZ53GTca4q71OU5RazbbNhTOBQLKLXD3v9QZXCMJdg4hGW/2Y0DuMUqMQg==", + "requires": { + "@serialport/parser-delimiter": "10.3.0" + } + }, + "@serialport/parser-ready": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-10.3.0.tgz", + "integrity": "sha512-1owywJ4p592dJyVrEJZPIh6pUZ3/y/LN6kGTDH2wxdewRUITo/sGvDy0er5i2+dJD3yuowiAz0dOHSdz8tevJA==" + }, + "@serialport/parser-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-10.3.0.tgz", + "integrity": "sha512-tIogTs7CvTH+UUFnsvE7i33MSISyTPTGPWlglWYH2/5coipXY503jlaYS1YGe818wWNcSx6YAjMZRdhTWwM39w==" + }, + "@serialport/parser-slip-encoder": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-10.3.0.tgz", + "integrity": "sha512-JI0ILF5sylWn8f0MuMzHFBix/iMUTa79/Z95KaPZYnVaEdA7h7hh/o21Jmon/26P3RJwL1SNJCjZ81zfan+LtQ==" + }, + "@serialport/parser-spacepacket": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-10.3.0.tgz", + "integrity": "sha512-PDF73ClEPsClD1FEJZHNuBevDKsJCkqy/XD5+S5eA6+tY5D4HLrVgSWsg+3qqB6+dlpwf2CzHe+uO8D3teuKHA==" + }, + "@serialport/stream": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-10.3.0.tgz", + "integrity": "sha512-7sooi5fHogYNVEJwxVdg872xO6TuMgQd2E9iRmv+o8pk/1dbBnPkmH6Ka3st1mVE+0KnIJqVlgei+ncSsqXIGw==", + "requires": { + "@serialport/bindings-interface": "1.2.1", + "debug": "^4.3.2" + } + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "ioctl": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ioctl/-/ioctl-2.0.2.tgz", + "integrity": "sha512-GPEiU99bJb3Z50JDRujQ9t+q4JaRvc1UrD7F5/kHDVWlRA3L4TMwqbMw/XIu/BzqccFP8OfsK+JIXmlAvJDs1g==", + "requires": { + "bindings": "^1.5.0", + "nan": "^2.14.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" + }, + "node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, + "node-gyp-build": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" + }, + "serialport": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/serialport/-/serialport-10.3.0.tgz", + "integrity": "sha512-MZMRlQgWOG7boLkJwm200Z3W39GcFmGo3tWxQrvyrZpH7W1p3t16M1VBglVxR6wXRF8qm01VxXBA+rNV7fPMVA==", + "requires": { + "@serialport/binding-mock": "10.2.2", + "@serialport/bindings-cpp": "10.6.3", + "@serialport/parser-byte-length": "10.3.0", + "@serialport/parser-cctalk": "10.3.0", + "@serialport/parser-delimiter": "10.3.0", + "@serialport/parser-inter-byte-timeout": "10.3.0", + "@serialport/parser-packet-length": "10.3.0", + "@serialport/parser-readline": "10.3.0", + "@serialport/parser-ready": "10.3.0", + "@serialport/parser-regex": "10.3.0", + "@serialport/parser-slip-encoder": "10.3.0", + "@serialport/parser-spacepacket": "10.3.0", + "@serialport/stream": "10.3.0", + "debug": "^4.3.3" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..887a247 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "ts3-remote", + "version": "1.0.0", + "description": "TS3 remote client for MicroKeyer PTT.", + "main": "daemon.js", + "scripts": { + "start": "node daemon.js" + }, + "type": "module", + "author": "ericek111", + "license": "GPL", + "dependencies": { + "ioctl": "^2.0.2", + "serialport": "^10.3.0" + } +} diff --git a/ptt_daemon.c b/ptt_daemon.c new file mode 100644 index 0000000..c1ebe42 --- /dev/null +++ b/ptt_daemon.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + + if (argc < 2) { + fprintf(stderr, "Usage: ./ptt_daemon <1 or 0 (RTS high or low)>\n"); + exit(1); + } + + int fd = open(argv[1], O_RDWR | O_NDELAY); + if (fd < 0) { + exit(1); + } + + int rtsEnable; + sscanf(argv[2], "%d", &rtsEnable); + + int flags; + ioctl(fd, TIOCMGET, &flags); + + if (rtsEnable != 0) { + flags |= TIOCM_RTS; + } else { + flags &= ~TIOCM_RTS; + } + + ioctl(fd, TIOCMSET, &flags); + + close(fd); + +}