From c2d440c5f5c1b5409cc40ec90ccbf294800c9927 Mon Sep 17 00:00:00 2001 From: Jim Kroon Date: Tue, 12 Jun 2018 08:46:50 +0200 Subject: [PATCH 01/12] Add package.json --- package.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..287b6e2 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "xbox-smartglass-core-node", + "version": "0.1.0", + "description": "NodeJS smartglass library for controlling a Xbox", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git@git.traphix.nl:xboxone/xbox-smartglass-core-node.git" + }, + "author": "", + "license": "ISC" +} From 51c55e6f8adab3abba7d60b9e153292124738f49 Mon Sep 17 00:00:00 2001 From: Jim Kroon Date: Tue, 12 Jun 2018 08:58:08 +0200 Subject: [PATCH 02/12] Added skeleton for package --- bin/discover.js | 5 +++++ index.js | 8 ++++++++ package-lock.json | 5 +++++ package.json | 7 +++++-- 4 files changed, 23 insertions(+), 2 deletions(-) create mode 100755 bin/discover.js create mode 100644 index.js create mode 100644 package-lock.json diff --git a/bin/discover.js b/bin/discover.js new file mode 100755 index 0000000..66aed3d --- /dev/null +++ b/bin/discover.js @@ -0,0 +1,5 @@ +#!/usr/bin/env node +var smartglass = require('../') + +consoles = smartglass.discovery() +console.log(consoles); diff --git a/index.js b/index.js new file mode 100644 index 0000000..69fa997 --- /dev/null +++ b/index.js @@ -0,0 +1,8 @@ +const ADDR_BROADCAST = '255.255.255.0' + +module.exports = { + discovery: function(addr = ADDR_BROADCAST) + { + return []; + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..81b568d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5 @@ +{ + "name": "xbox-smartglass-core-node", + "version": "0.1.0", + "lockfileVersion": 1 +} diff --git a/package.json b/package.json index 287b6e2..c6c0759 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,11 @@ }, "repository": { "type": "git", - "url": "git@git.traphix.nl:xboxone/xbox-smartglass-core-node.git" + "url": "git@github.com:unknownskl/xbox-smartglass-core-node.git" }, "author": "", - "license": "ISC" + "license": "ISC", + "bin": { + "smartglass-discover": "./bin/discover.js" + } } From 617b448ecf4fe8c6c54ae71e459ad6ea41f63ac8 Mon Sep 17 00:00:00 2001 From: Jim Kroon Date: Tue, 12 Jun 2018 09:52:24 +0200 Subject: [PATCH 03/12] Added some base udp code --- bin/discover.js | 1 + index.js | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/bin/discover.js b/bin/discover.js index 66aed3d..34b4434 100755 --- a/bin/discover.js +++ b/bin/discover.js @@ -2,4 +2,5 @@ var smartglass = require('../') consoles = smartglass.discovery() +console.log(smartglass); console.log(consoles); diff --git a/index.js b/index.js index 69fa997..c87fd2a 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,25 @@ -const ADDR_BROADCAST = '255.255.255.0' +const dgram = require('dgram'); +const client = dgram.createSocket('udp4'); +//var buffer = require('buffer'); + +const ADDR_BROADCAST = '255.255.255.0'; module.exports = { + _consoles: [], + discovery: function(addr = ADDR_BROADCAST) { - return []; + client.on('message',function(msg,info){ + console.log('Data received from server : ' + msg.toString()); + console.log('Received %d bytes from %s:%d\n',msg.length, info.address, info.port); + }); + + var message = Buffer.from('yess'); + client.send(message, 5050, addr, (err) => { + console.log('Error: '+err); + client.close(); + }); + + return this._consoles; } } From fcbce3defb8822021dc61959dc25e5af302511ee Mon Sep 17 00:00:00 2001 From: Jim Kroon Date: Tue, 12 Jun 2018 10:11:14 +0200 Subject: [PATCH 04/12] Add basic test --- .gitignore | 1 + package-lock.json | 169 +++++++++++++++++++++++++++++++++++++++++++- package.json | 5 +- tests/smartglass.js | 7 ++ 4 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 tests/smartglass.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/package-lock.json b/package-lock.json index 81b568d..ab9e240 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,172 @@ { "name": "xbox-smartglass-core-node", "version": "0.1.0", - "lockfileVersion": 1 + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } } diff --git a/package.json b/package.json index c6c0759..4bf76c7 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "NodeJS smartglass library for controlling a Xbox", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "./node_modules/mocha/bin/mocha tests/" }, "repository": { "type": "git", @@ -14,5 +14,8 @@ "license": "ISC", "bin": { "smartglass-discover": "./bin/discover.js" + }, + "dependencies": { + "mocha": "^5.2.0" } } diff --git a/tests/smartglass.js b/tests/smartglass.js new file mode 100644 index 0000000..89cc7f9 --- /dev/null +++ b/tests/smartglass.js @@ -0,0 +1,7 @@ +var assert = require('assert'); + +describe('String#split', function(){ + it('should return an array', function(){ + assert(Array.isArray('a,b,c'.split(','))); + }); +}) From 9c20716b39357bbcb585ca915af016f47db08d76 Mon Sep 17 00:00:00 2001 From: Jim Kroon Date: Tue, 12 Jun 2018 11:22:54 +0200 Subject: [PATCH 05/12] Replaced dockerimage --- Dockerfile | 12 ++++++++++++ Makefile | 8 ++++++++ bin/client.js | 20 ++++++++++++++++++++ index.js | 16 +++++++++++++--- package.json | 3 ++- tests/smartglass.js | 20 ++++++++++++++++---- 6 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 bin/client.js diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d0a9a36 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM node:alpine + +WORKDIR /app + +ADD package.json ./ +RUN npm install + +ADD index.js ./ +ADD bin/* ./bin/ +RUN npm link + +ENTRYPOINT [ "node", "bin/client.js" ] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a0313ec --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +run: build + docker run xbox-smartglass-core-node + +run_discovery: build + docker run xbox-smartglass-core-node discovery + +build: + docker build -t xbox-smartglass-core-node . diff --git a/bin/client.js b/bin/client.js new file mode 100644 index 0000000..3f18b3d --- /dev/null +++ b/bin/client.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node +var smartglass = require('../'); + +if(process.argv.length <= 2) +{ + console.log('xbox-smartglass-core-node client v0.1.0'); + console.log('Arguments:'); + console.log('- discovery'); +} else { + console.log('xbox-smartglass-core-node client v0.1.0'); + var command = process.argv[2] + if(command == 'discovery') + { + console.log('Do discovery'); + } +} + +// process.argv.forEach(function (val, index, array) { +// console.log(index + ': ' + val); +// }); diff --git a/index.js b/index.js index c87fd2a..b2e6c85 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,4 @@ const dgram = require('dgram'); -const client = dgram.createSocket('udp4'); //var buffer = require('buffer'); const ADDR_BROADCAST = '255.255.255.0'; @@ -7,19 +6,30 @@ const ADDR_BROADCAST = '255.255.255.0'; module.exports = { _consoles: [], - discovery: function(addr = ADDR_BROADCAST) + discovery: function(addr = ADDR_BROADCAST, callback = null) { + var client = dgram.createSocket('udp4'); client.on('message',function(msg,info){ console.log('Data received from server : ' + msg.toString()); console.log('Received %d bytes from %s:%d\n',msg.length, info.address, info.port); + + if(callback !== null) + callback(console); }); var message = Buffer.from('yess'); client.send(message, 5050, addr, (err) => { - console.log('Error: '+err); + if(err != null) + console.log('Error: '+err); + client.close(); }); + return this._consoles; + }, + + getConsoles: function() + { return this._consoles; } } diff --git a/package.json b/package.json index 4bf76c7..dc23960 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "author": "", "license": "ISC", "bin": { - "smartglass-discover": "./bin/discover.js" + "smartglass-discover": "./bin/discover.js", + "smartglass-client": "./bin/client.js" }, "dependencies": { "mocha": "^5.2.0" diff --git a/tests/smartglass.js b/tests/smartglass.js index 89cc7f9..5945d5b 100644 --- a/tests/smartglass.js +++ b/tests/smartglass.js @@ -1,7 +1,19 @@ var assert = require('assert'); +var Smartglass = require('../'); -describe('String#split', function(){ - it('should return an array', function(){ - assert(Array.isArray('a,b,c'.split(','))); - }); +describe('smartglass', function(){ + describe('getConsoles()', function(){ + it('should return an ampty array on init', function(){ + assert(Smartglass.getConsoles().length == 0); + }); + it('should return an array after discovery', function(){ + Smartglass.discovery(); + assert(Array.isArray(Smartglass.getConsoles())); + }); + }); + describe('discovery()', function(){ + it('should return an array', function(){ + assert(Array.isArray(Smartglass.discovery())); + }); + }); }) From 475fe0c26fce221730a45d20e7820d6baf8b25e6 Mon Sep 17 00:00:00 2001 From: Jim Kroon Date: Tue, 12 Jun 2018 13:26:38 +0200 Subject: [PATCH 06/12] Add .codeclimate.yml file --- .codeclimate.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .codeclimate.yml diff --git a/.codeclimate.yml b/.codeclimate.yml new file mode 100644 index 0000000..71efec2 --- /dev/null +++ b/.codeclimate.yml @@ -0,0 +1,17 @@ +engines: + eslint: + enabled: true + duplication: + enabled: true + config: + languages: + javascript: + mass_threshold: 65 + shellcheck: + enabled: true +checks: + method-count: + enabled: false +ratings: + paths: + - "*.js" From cb19732e867e2b40f80b59b30d0947afe915d420 Mon Sep 17 00:00:00 2001 From: Jim Kroon Date: Tue, 12 Jun 2018 20:55:48 +0200 Subject: [PATCH 07/12] Add license Updated packages.json --- LICENSE | 21 +++++++++++++++++++++ package.json | 13 +++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ee134cd --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 UnknownSKL (Jim Kroon) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package.json b/package.json index dc23960..32ffd15 100644 --- a/package.json +++ b/package.json @@ -10,12 +10,21 @@ "type": "git", "url": "git@github.com:unknownskl/xbox-smartglass-core-node.git" }, - "author": "", - "license": "ISC", + "author": "UnknownSKL (Jim Kroon)", + "license": "MIT", "bin": { "smartglass-discover": "./bin/discover.js", "smartglass-client": "./bin/client.js" }, + "bugs": { + "url": "https://github.com/unknownskl/xbox-smartglass-core-node/issues" + }, + "homepage": "https://github.com/unknownskl/xbox-smartglass-core-node", + "keywords": [ + "xbox", + "xbox one", + "smartglass" + ], "dependencies": { "mocha": "^5.2.0" } From d4f7ec59bb01f1b1abd91076c2ffad9c6225c6cf Mon Sep 17 00:00:00 2001 From: Jim Kroon Date: Fri, 15 Jun 2018 16:32:09 +0200 Subject: [PATCH 08/12] Added ability to discover devices --- Dockerfile | 2 +- Makefile | 6 ++ bin/client.js | 59 +++++++++++++++---- bin/discover.js | 2 +- index.js | 35 ----------- package-lock.json | 13 ++++ package.json | 4 +- src/packet/structure.js | 81 +++++++++++++++++++++++++ src/simplepacket.js | 92 +++++++++++++++++++++++++++++ src/smartglass.js | 121 ++++++++++++++++++++++++++++++++++++++ tests/packet_structure.js | 62 +++++++++++++++++++ tests/simplepacket.js | 34 +++++++++++ tests/smartglass.js | 20 +++---- 13 files changed, 473 insertions(+), 58 deletions(-) mode change 100644 => 100755 bin/client.js create mode 100644 src/packet/structure.js create mode 100644 src/simplepacket.js create mode 100644 src/smartglass.js create mode 100644 tests/packet_structure.js create mode 100644 tests/simplepacket.js diff --git a/Dockerfile b/Dockerfile index d0a9a36..f3ed49c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ WORKDIR /app ADD package.json ./ RUN npm install -ADD index.js ./ +ADD src/* ./src/ ADD bin/* ./bin/ RUN npm link diff --git a/Makefile b/Makefile index a0313ec..925e193 100644 --- a/Makefile +++ b/Makefile @@ -4,5 +4,11 @@ run: build run_discovery: build docker run xbox-smartglass-core-node discovery +run_boot: build + docker run xbox-smartglass-core-node -b -i 127.0.0.1 -l FD000000000000 + +run_help: build + docker run xbox-smartglass-core-node --help + build: docker build -t xbox-smartglass-core-node . diff --git a/bin/client.js b/bin/client.js old mode 100644 new mode 100755 index 3f18b3d..ccf396e --- a/bin/client.js +++ b/bin/client.js @@ -1,18 +1,57 @@ #!/usr/bin/env node -var smartglass = require('../'); +var Smartglass = require('../src/smartglass'); +var commander = require('commander'); +var assert = require('assert'); +var pkgInfo = require('../package.json'); + +const ADDR_BROADCAST = '255.255.255.255'; + +console.log('Xbox-Smartglass v'+pkgInfo['version']+' ('+pkgInfo['homepage']+')'); + +commander + .usage('[-b -d -s] -i -l [-t ]') + .option('-b, --boot', 'Boot Xbox console') + .option('-d, --discover', 'Discover Xbox on the network') + //.option('-s, --shutdown', 'Shutdown Xbox console') + .option('-i, --ip ', 'Xbox One IP address', ADDR_BROADCAST) + .option('-l, --live_id ', 'Xbox One live id (Example: FD000000000000)') + .option('-t, --tries ', 'Timeout inn seconds (Default: 4)', 4) + .version(pkgInfo['version']) + .parse(process.argv); if(process.argv.length <= 2) + commander.help(); + +if(commander.boot == true) { - console.log('xbox-smartglass-core-node client v0.1.0'); - console.log('Arguments:'); - console.log('- discovery'); -} else { - console.log('xbox-smartglass-core-node client v0.1.0'); - var command = process.argv[2] - if(command == 'discovery') - { - console.log('Do discovery'); + if(commander.live_id == undefined) + console.error('--live_id parameter required'); + else { + console.log('Trying to boot device...'); + Smartglass.power_on({ + live_id: commander.live_id, + tries: commander.tries, + ip: commander.ip + }, function(result){ + if(result) + console.log('Device booted successfully'); + else + console.log('Failed to boot device'); + }); } + +} else if(commander.discover) +{ + console.log('Trying to discover devices...'); + Smartglass.discovery({ + ip: commander.ip + }, function(device){ + console.log('Device found: ' + device.device_name); + console.log(device); + }); +} else if(commander.shutdown) +{ + } // process.argv.forEach(function (val, index, array) { diff --git a/bin/discover.js b/bin/discover.js index 34b4434..91f2f9f 100755 --- a/bin/discover.js +++ b/bin/discover.js @@ -1,5 +1,5 @@ #!/usr/bin/env node -var smartglass = require('../') +var smartglass = require('../src/smartglass') consoles = smartglass.discovery() console.log(smartglass); diff --git a/index.js b/index.js index b2e6c85..e69de29 100644 --- a/index.js +++ b/index.js @@ -1,35 +0,0 @@ -const dgram = require('dgram'); -//var buffer = require('buffer'); - -const ADDR_BROADCAST = '255.255.255.0'; - -module.exports = { - _consoles: [], - - discovery: function(addr = ADDR_BROADCAST, callback = null) - { - var client = dgram.createSocket('udp4'); - client.on('message',function(msg,info){ - console.log('Data received from server : ' + msg.toString()); - console.log('Received %d bytes from %s:%d\n',msg.length, info.address, info.port); - - if(callback !== null) - callback(console); - }); - - var message = Buffer.from('yess'); - client.send(message, 5050, addr, (err) => { - if(err != null) - console.log('Error: '+err); - - client.close(); - }); - - return this._consoles; - }, - - getConsoles: function() - { - return this._consoles; - } -} diff --git a/package-lock.json b/package-lock.json index ab9e240..fe06fb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -142,6 +142,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "nan": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.2.0.tgz", + "integrity": "sha1-d5wHE1YpUDz2p7fmqrMwSbPDhTw=" + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -167,6 +172,14 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "x509": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/x509/-/x509-0.3.3.tgz", + "integrity": "sha512-03sJu1FxG3cKM6xHqDiZqD2Y4yaf50ylPAT0yYpu2TFQ6SFdmiqK7v8pA3koXX8YV6Zdys8/AHCt2wwHGVS8Cg==", + "requires": { + "nan": "2.2.0" + } } } } diff --git a/package.json b/package.json index 32ffd15..fa8600c 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "smartglass" ], "dependencies": { - "mocha": "^5.2.0" + "commander": "^2.15.1", + "mocha": "^5.2.0", + "x509": "^0.3.3" } } diff --git a/src/packet/structure.js b/src/packet/structure.js new file mode 100644 index 0000000..fcd7ca9 --- /dev/null +++ b/src/packet/structure.js @@ -0,0 +1,81 @@ +module.exports = function(packet) +{ + if(packet == undefined) + packet = new Buffer(''); + + return { + _packet: packet, + _offset: 0, + + writeSGString: function(data) + { + var lengthBuffer = Buffer.allocUnsafe(2); + lengthBuffer.writeUInt16BE(data.length, 0); + + var dataBuffer = new Buffer(data + '\x00'); + + this._add(Buffer.concat([ + lengthBuffer, + dataBuffer + ])); + }, + + readSGString: function(buffer = false) + { + var dataLength = this._packet.readUInt16BE(this._offset); + var data = this._packet.slice(this._offset+2, this._offset+2+dataLength); + + this._offset = (this._offset+3+dataLength); + + if(buffer == false) + return data.toString(); + else + return data; + }, + + writeUInt16: function(data) + { + var tempBuffer = Buffer.allocUnsafe(2); + tempBuffer.writeUInt16BE(data, 0); + this._add(tempBuffer); + }, + + readUInt16: function() + { + var data = this._packet.readUInt16BE(this._offset); + this._offset = (this._offset+2); + + return data; + }, + + writeUInt32: function(data) + { + var tempBuffer = Buffer.allocUnsafe(4); + tempBuffer.writeUInt32BE(data, 0); + this._add(tempBuffer); + }, + + readUInt32: function() + { + var data = this._packet.readUInt32BE(this._offset); + this._offset = (this._offset+4); + + return data; + }, + + toBuffer: function() + { + return new Buffer(this._packet); + }, + + /* Private functions */ + + _add(data) + { + this._packet = new Buffer.concat([ + this._packet, + data + ]); + } + }; +} diff --git a/src/simplepacket.js b/src/simplepacket.js new file mode 100644 index 0000000..08d6d06 --- /dev/null +++ b/src/simplepacket.js @@ -0,0 +1,92 @@ +const x509 = require('x509'); +var EOL = require('os').EOL; +var PacketStructure = require('./packet/structure.js'); + +const PACKET_TYPE_DISCOVERY_REQUEST = new Buffer('dd00', 'hex'); +const PACKET_TYPE_DISCOVERY_RESPONSE = new Buffer('dd01', 'hex'); + +module.exports = { + + power_on: function(live_id) + { + var payload = PacketStructure(); + payload.writeSGString(live_id); + var packet = this._pack(new Buffer('dd02', 'hex'), payload.toBuffer(), new Buffer('0000', 'hex')) + + return packet; + }, + + discovery: function() + { + var payload = PacketStructure(); + + payload.writeUInt32(0x00000000); + payload.writeUInt16('6'); + payload.writeUInt16('0'); + payload.writeUInt16('2'); + + var packet = this._pack(PACKET_TYPE_DISCOVERY_REQUEST, payload.toBuffer(), new Buffer('0000', 'hex')) + + return packet; + }, + + unpack: function(payload) + { + return this._unpack(payload); + }, + + /* Private functions */ + + _pack: function(type, payload, version = 0) + { + var payloadLength = Buffer.concat([ + new Buffer('00', 'hex'), + new Buffer(String.fromCharCode(payload.length)) + ]); + + return Buffer.concat([type, payloadLength, new Buffer('\x00' + String.fromCharCode(version)), payload]) + }, + + _unpack: function(payload) + { + var type = payload.slice(0,2).toString('hex'); + var payloadLength = payload.readUInt16BE(2); + var version = payload.readUInt16BE(4); + var unpackedPayload = payload.slice(6); + + // console.log('type: '+type); + // console.log('payloadLength: '+payloadLength); + // console.log('version: '+version); + + if(type = PACKET_TYPE_DISCOVERY_RESPONSE) + { + var recvPayload = PacketStructure(unpackedPayload); + + var deviceFlags = recvPayload.readUInt32(); + var clientType = recvPayload.readUInt16(); + var consoleName = recvPayload.readSGString(); + var udid = recvPayload.readSGString(); + var lastError = recvPayload.readUInt32(); + var certificate = recvPayload.readSGString(true); + + var certInfo = x509.parseCert('-----BEGIN CERTIFICATE-----'+EOL+certificate.toString('base64').match(/.{0,64}/g).join('\n')+'-----END CERTIFICATE-----'); + //console.log(certInfo); + + var data = { + device_flags: deviceFlags, + device_type: clientType, + device_name: consoleName, + device_udid: udid, + device_certificate: certInfo, + device_certificate_raw: '-----BEGIN CERTIFICATE-----'+EOL+certificate.toString('base64').match(/.{0,64}/g).join('\n')+'-----END CERTIFICATE-----', + last_error: deviceFlags, + } + + return { + type: 'DISCOVERY_RESPONSE', + payload: data + }; + } + return false; + } +} diff --git a/src/smartglass.js b/src/smartglass.js new file mode 100644 index 0000000..883e3bf --- /dev/null +++ b/src/smartglass.js @@ -0,0 +1,121 @@ +const dgram = require('dgram'); +const SimplePacket = require('./simplepacket'); + +module.exports = { + _consoles: [], + _client: false, + + _on_discovery_response: [], + + discovery: function(options, callback) + { + var client = this._init_client(); + var message = SimplePacket.discovery(); + + this._on_discovery_response.push(function(response){ + callback(response.payload) + }.bind(callback)); + + this._send({ + ip: options.ip, + port: 5050 + }, message); + + setTimeout(function(client){ + client._close_client(); + }, 1000, this); + }, + + power_on: function(options, callback) + { + var client = this._init_client(); + var message = SimplePacket.power_on(options.live_id); + + var try_num = 0; + + var sendBoot = function(client, callback) + { + client._send({ + ip: options.ip, + port: 5050 + }, message); + + try_num = try_num+1; + if(try_num <= options.tries) + { + setTimeout(sendBoot, 500, client, callback); + } else { + console.log('@TODO: Check if console is booted... return true'); + callback(true); + client._close_client(); + } + } + setTimeout(sendBoot, 1000, this, callback); + }, + + getConsoles: function() + { + return this._consoles; + }, + + /* Private functions */ + _receive: function(message, remote, client) + { + var type = message.slice(0,2).toString('hex'); + if(type != 'd00d') + { + // Discovery Response + var response = SimplePacket.unpack(message); + if(response == false) + { + console.log('Warning: UNKNOWN PACKET RECEIVED'); + } else { + //console.log(response); + var func = '_on_' + response.type.toLowerCase(); + if(this[func] != undefined) + { + for (trigger in this[func]){ + this[func][trigger](response); + } + } else { + console.log('Error: UNKNOWN CALLBACK: ' + func); + } + } + } else { + console.log('Encrypted packet not implemented yet'); + } + }, + + _send: function(options, message) + { + if(options.ip == undefined) + console.log('smartglass._send: ip missing'); + + if(options.port == undefined) + console.log('smartglass._send: port missing'); + + this._client.send(message, 0, message.length, options.port, options.ip, function(err, bytes) { + //console.log('Sending packet...'); + }); + }, + + _init_client: function() + { + this._client = dgram.createSocket('udp4'); + this._client.bind(); + // this._client.on("listening", function () { + // //this._client_info = this._client.address(); + // }); + + this._client.on('message', function(message, remote){ + this._receive(message, remote, this); + }.bind(this)); + + return this._client; + }, + + _close_client: function() + { + this._client.close(); + } +} diff --git a/tests/packet_structure.js b/tests/packet_structure.js new file mode 100644 index 0000000..eef8122 --- /dev/null +++ b/tests/packet_structure.js @@ -0,0 +1,62 @@ +var assert = require('assert'); +var PacketStructure = require('../src/packet/structure'); + +describe('packet/structure', function(){ + it('obj._packet should be empty on new instance without parameters', function(){ + var packet = PacketStructure(); + assert.deepStrictEqual(packet._packet, new Buffer('')); + }); + it('obj._packet should be not empty on new instance with parameters', function(){ + var packet = PacketStructure(new Buffer('0x0001')); + assert.deepStrictEqual(packet._packet, new Buffer('0x0001')); + }); + + var testValues = { + '1': '\x00\x01', + '2': '\x00\x02', + '10': '\x00\x10', + '100': '\x00\x64' + }; + + for (testValue in testValues) + { + describe('test writeUInt16 & readUInt16 with value ('+testValue+')', function(){ + var packet = PacketStructure(); + + it('should write packet', function(){ + packet.writeUInt16(testValue); + assert.deepStrictEqual(packet._packet, new Buffer(testValues[testValue])); + }.bind(packet, testValue, testValues)); + + it('should read from packet ('+testValue+')', function(){ + var value = packet.readUInt16(); + assert.equal(value, testValue); + }.bind(packet, testValue, testValues)); + }); + + describe('test writeUInt32 & readUInt32 with value ('+testValue+')', function(){ + var packet = PacketStructure(); + + it('should write packet', function(){ + packet.writeUInt32(testValue); + assert.deepStrictEqual(packet._packet, new Buffer(Buffer.concat([ + new Buffer('\x00\x00'), + new Buffer(testValues[testValue]) + ]))); + }.bind(packet, testValue, testValues)); + + it('should read from packet ('+testValue+')', function(){ + var value = packet.readUInt32(); + assert.equal(value, testValue); + }.bind(packet, testValue, testValues)); + }); + } + + // it('obj._offset should be set to 2 when reading UInt16 and return 1', function(){ + // var packet = PacketStructure(new Buffer('0x0001')); + // var returnValue = packet.readUInt16(); + // console.log(returnValue); + // assert.strictEqual(packet._offset, 2); + // assert.strictEqual(returnValue, 1); + // }); +}) diff --git a/tests/simplepacket.js b/tests/simplepacket.js new file mode 100644 index 0000000..a9af9ee --- /dev/null +++ b/tests/simplepacket.js @@ -0,0 +1,34 @@ +var assert = require('assert'); +var SimplePacket = require('../src/simplepacket'); + +describe('simplepacket', function(){ + describe('power_on()', function(){ + it('should return a poweron packet (FD000000000000)', function(){ + var packet = SimplePacket.power_on('FD000000000000'); + assert.deepStrictEqual(packet, Buffer('dd0200110000000e464430303030303030303030303000', 'hex')); + }); + it('should return a poweron packet (FD123456789123)', function(){ + var packet = SimplePacket.power_on('FD123456789123'); + assert.deepStrictEqual(packet, Buffer('dd0200110000000e464431323334353637383931323300', 'hex')); + }); + it('should return a poweron packet (FD9999999999)', function(){ + var packet = SimplePacket.power_on('FD9999999999'); + assert.deepStrictEqual(packet, Buffer('dd02000f0000000c46443939393939393939393900', 'hex')); + }); + }); + + describe('discovery()', function(){ + it('should return a discovery request packet', function(){ + var packet = SimplePacket.discovery(); + assert.deepStrictEqual(packet, Buffer('dd00000a000000000000000600000002', 'hex')); + }); + }); + + // describe('unpack()', function(){ + // it('should return SimplePacket object', function(){ + // var packet = SimplePacket.discovery(); + // console.log(packet); + // assert.deepStrictEqual(packet, Buffer('dd00000a000000000000000600000002', 'hex')); + // }); + // }); +}) diff --git a/tests/smartglass.js b/tests/smartglass.js index 5945d5b..d47f0d2 100644 --- a/tests/smartglass.js +++ b/tests/smartglass.js @@ -1,19 +1,19 @@ var assert = require('assert'); -var Smartglass = require('../'); +var Smartglass = require('../src/smartglass'); describe('smartglass', function(){ describe('getConsoles()', function(){ it('should return an ampty array on init', function(){ assert(Smartglass.getConsoles().length == 0); }); - it('should return an array after discovery', function(){ - Smartglass.discovery(); - assert(Array.isArray(Smartglass.getConsoles())); - }); - }); - describe('discovery()', function(){ - it('should return an array', function(){ - assert(Array.isArray(Smartglass.discovery())); - }); + // it('should return an array after discovery', function(){ + // Smartglass.discovery(); + // assert(Array.isArray(Smartglass.getConsoles())); + // }); }); + // describe('discovery()', function(){ + // it('should return an array', function(){ + // assert(Array.isArray(Smartglass.discovery())); + // }); + // }); }) From 01e0aad338eb8e72657ee22b4bc2abcf682a4255 Mon Sep 17 00:00:00 2001 From: Jim Kroon Date: Fri, 15 Jun 2018 16:39:18 +0200 Subject: [PATCH 09/12] Update dockerfile --- Dockerfile | 8 +++++--- Makefile | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index f3ed49c..4eb1a23 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,14 @@ -FROM node:alpine +FROM node:9-alpine WORKDIR /app +RUN apk add python make g++ --update + ADD package.json ./ RUN npm install -ADD src/* ./src/ -ADD bin/* ./bin/ +ADD src ./src +ADD bin ./bin RUN npm link ENTRYPOINT [ "node", "bin/client.js" ] diff --git a/Makefile b/Makefile index 925e193..ca8ab17 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ run: build docker run xbox-smartglass-core-node run_discovery: build - docker run xbox-smartglass-core-node discovery + docker run xbox-smartglass-core-node -d run_boot: build docker run xbox-smartglass-core-node -b -i 127.0.0.1 -l FD000000000000 From b64eb5ffe797a7f6b322d6fad63daa18ccd2f5ee Mon Sep 17 00:00:00 2001 From: Jim Kroon Date: Fri, 15 Jun 2018 21:29:55 +0200 Subject: [PATCH 10/12] Added smartglass tests Code cleanup Updated readme --- README.md | 38 +++++++++++++++++ bin/client.js | 16 +++----- bin/discover.js | 6 --- index.js | 0 src/packet/structure.js | 7 ++-- src/simplepacket.js | 19 ++++++--- src/smartglass.js | 11 +++-- tests/packet_structure.js | 85 +++++++++++++++++---------------------- tests/simplepacket.js | 10 +---- tests/smartglass.js | 40 +++++++++++++----- 10 files changed, 134 insertions(+), 98 deletions(-) delete mode 100755 bin/discover.js delete mode 100644 index.js diff --git a/README.md b/README.md index d38573a..d30270c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,41 @@ # Xbox-Smartglass-Core-Node NodeJS smartglass library for controlling a Xbox + +## Dependencies + +- NodeJS 9 (X509 package is not compatible with Node 10 yet) +- NPM +- + +## How to use + +### Boot the Xbox console + + Smartglass.power_on({ + live_id: 'FD000000000000', // Put your console's live id here (Required) + tries: 4, // Number of packets too issue the boot command (Optional) + ip: '127.0.0.1' // Your consoles ip address (Optional) + }, function(result){ + if(result) + console.log('Device booted successfully'); + else + console.log('Failed to boot device'); + }); + +### Discover consoles on network + + Smartglass.discovery({ + ip: '127.0.0.1' // Your consoles ip address (Optional) + }, function(device, address){ + console.log('- Device found: ' + device.device_name); + console.log('Address: '+ address.address + ':' + address.port); + console.log('LiveID: ' + device.device_certificate.subject.commonName); + console.log('Certificate valid: ' + device.device_certificate.notBefore + ' - ' + device.device_certificate.notAfter); + console.log('Certificate fingerprint: ' + device.device_certificate.fingerPrint); + }); + +## Known Issues + +- Broadcasting does not work properly yet +- Callback when sending a power_on command always returns true for now. diff --git a/bin/client.js b/bin/client.js index ccf396e..f0098bb 100755 --- a/bin/client.js +++ b/bin/client.js @@ -45,15 +45,11 @@ if(commander.boot == true) console.log('Trying to discover devices...'); Smartglass.discovery({ ip: commander.ip - }, function(device){ - console.log('Device found: ' + device.device_name); - console.log(device); + }, function(device, address){ + console.log('- Device found: ' + device.device_name); + console.log('Address: '+ address.address + ':' + address.port); + console.log('LiveID: ' + device.device_certificate.subject.commonName); + console.log('Certificate valid: ' + device.device_certificate.notBefore + ' - ' + device.device_certificate.notAfter); + console.log('Certificate fingerprint: ' + device.device_certificate.fingerPrint); }); -} else if(commander.shutdown) -{ - } - -// process.argv.forEach(function (val, index, array) { -// console.log(index + ': ' + val); -// }); diff --git a/bin/discover.js b/bin/discover.js deleted file mode 100755 index 91f2f9f..0000000 --- a/bin/discover.js +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env node -var smartglass = require('../src/smartglass') - -consoles = smartglass.discovery() -console.log(smartglass); -console.log(consoles); diff --git a/index.js b/index.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/packet/structure.js b/src/packet/structure.js index fcd7ca9..1fec873 100644 --- a/src/packet/structure.js +++ b/src/packet/structure.js @@ -22,10 +22,10 @@ module.exports = function(packet) readSGString: function(buffer = false) { - var dataLength = this._packet.readUInt16BE(this._offset); - var data = this._packet.slice(this._offset+2, this._offset+2+dataLength); + var dataLength = this.readUInt16(); + var data = this._packet.slice(this._offset, this._offset+dataLength); - this._offset = (this._offset+3+dataLength); + this._offset = (this._offset+1+dataLength); if(buffer == false) return data.toString(); @@ -69,7 +69,6 @@ module.exports = function(packet) }, /* Private functions */ - _add(data) { this._packet = new Buffer.concat([ diff --git a/src/simplepacket.js b/src/simplepacket.js index 08d6d06..7e1eb91 100644 --- a/src/simplepacket.js +++ b/src/simplepacket.js @@ -1,6 +1,7 @@ +var PacketStructure = require('./packet/structure.js'); + const x509 = require('x509'); var EOL = require('os').EOL; -var PacketStructure = require('./packet/structure.js'); const PACKET_TYPE_DISCOVERY_REQUEST = new Buffer('dd00', 'hex'); const PACKET_TYPE_DISCOVERY_RESPONSE = new Buffer('dd01', 'hex'); @@ -21,7 +22,7 @@ module.exports = { var payload = PacketStructure(); payload.writeUInt32(0x00000000); - payload.writeUInt16('6'); + payload.writeUInt16('3'); // Client Type: Windows Desktop payload.writeUInt16('0'); payload.writeUInt16('2'); @@ -58,7 +59,7 @@ module.exports = { // console.log('payloadLength: '+payloadLength); // console.log('version: '+version); - if(type = PACKET_TYPE_DISCOVERY_RESPONSE) + if(type == PACKET_TYPE_DISCOVERY_RESPONSE.toString('hex')) { var recvPayload = PacketStructure(unpackedPayload); @@ -69,8 +70,13 @@ module.exports = { var lastError = recvPayload.readUInt32(); var certificate = recvPayload.readSGString(true); - var certInfo = x509.parseCert('-----BEGIN CERTIFICATE-----'+EOL+certificate.toString('base64').match(/.{0,64}/g).join('\n')+'-----END CERTIFICATE-----'); - //console.log(certInfo); + try { + var certInfo = x509.parseCert('-----BEGIN CERTIFICATE-----'+EOL+certificate.toString('base64').match(/.{0,64}/g).join('\n')+'-----END CERTIFICATE-----'); + } + catch(error) + { + var certInfo = { 'error:': error }; + } var data = { device_flags: deviceFlags, @@ -78,7 +84,8 @@ module.exports = { device_name: consoleName, device_udid: udid, device_certificate: certInfo, - device_certificate_raw: '-----BEGIN CERTIFICATE-----'+EOL+certificate.toString('base64').match(/.{0,64}/g).join('\n')+'-----END CERTIFICATE-----', + device_certificate_pem: '-----BEGIN CERTIFICATE-----'+EOL+certificate.toString('base64').match(/.{0,64}/g).join('\n')+'-----END CERTIFICATE-----', + device_certificate_raw: certificate, last_error: deviceFlags, } diff --git a/src/smartglass.js b/src/smartglass.js index 883e3bf..dd67c83 100644 --- a/src/smartglass.js +++ b/src/smartglass.js @@ -12,8 +12,8 @@ module.exports = { var client = this._init_client(); var message = SimplePacket.discovery(); - this._on_discovery_response.push(function(response){ - callback(response.payload) + this._on_discovery_response.push(function(response, device, smartglass){ + callback(response.payload, device, smartglass); }.bind(callback)); this._send({ @@ -45,7 +45,7 @@ module.exports = { { setTimeout(sendBoot, 500, client, callback); } else { - console.log('@TODO: Check if console is booted... return true'); + // console.log('@TODO: Check if console is booted... return true'); callback(true); client._close_client(); } @@ -70,12 +70,11 @@ module.exports = { { console.log('Warning: UNKNOWN PACKET RECEIVED'); } else { - //console.log(response); var func = '_on_' + response.type.toLowerCase(); if(this[func] != undefined) { for (trigger in this[func]){ - this[func][trigger](response); + this[func][trigger](response, remote, client); } } else { console.log('Error: UNKNOWN CALLBACK: ' + func); @@ -95,7 +94,7 @@ module.exports = { console.log('smartglass._send: port missing'); this._client.send(message, 0, message.length, options.port, options.ip, function(err, bytes) { - //console.log('Sending packet...'); + // console.log('Sending packet...'); }); }, diff --git a/tests/packet_structure.js b/tests/packet_structure.js index eef8122..442c9dd 100644 --- a/tests/packet_structure.js +++ b/tests/packet_structure.js @@ -11,52 +11,41 @@ describe('packet/structure', function(){ assert.deepStrictEqual(packet._packet, new Buffer('0x0001')); }); - var testValues = { - '1': '\x00\x01', - '2': '\x00\x02', - '10': '\x00\x10', - '100': '\x00\x64' - }; - - for (testValue in testValues) - { - describe('test writeUInt16 & readUInt16 with value ('+testValue+')', function(){ - var packet = PacketStructure(); - - it('should write packet', function(){ - packet.writeUInt16(testValue); - assert.deepStrictEqual(packet._packet, new Buffer(testValues[testValue])); - }.bind(packet, testValue, testValues)); - - it('should read from packet ('+testValue+')', function(){ - var value = packet.readUInt16(); - assert.equal(value, testValue); - }.bind(packet, testValue, testValues)); - }); - - describe('test writeUInt32 & readUInt32 with value ('+testValue+')', function(){ - var packet = PacketStructure(); - - it('should write packet', function(){ - packet.writeUInt32(testValue); - assert.deepStrictEqual(packet._packet, new Buffer(Buffer.concat([ - new Buffer('\x00\x00'), - new Buffer(testValues[testValue]) - ]))); - }.bind(packet, testValue, testValues)); - - it('should read from packet ('+testValue+')', function(){ - var value = packet.readUInt32(); - assert.equal(value, testValue); - }.bind(packet, testValue, testValues)); - }); - } - - // it('obj._offset should be set to 2 when reading UInt16 and return 1', function(){ - // var packet = PacketStructure(new Buffer('0x0001')); - // var returnValue = packet.readUInt16(); - // console.log(returnValue); - // assert.strictEqual(packet._offset, 2); - // assert.strictEqual(returnValue, 1); - // }); + + describe('test write and read types', function(){ + var lPacket = PacketStructure(); + + it('should write UInt16 to the packet and check packet', function(){ + lPacket.writeUInt16(10); + assert.deepEqual(lPacket._packet, new Buffer('\x00\x0a')); + }.bind(lPacket)); + + it('should write UInt32 to the packet and check packet', function(){ + lPacket.writeUInt32(10); + assert.deepEqual(lPacket._packet, new Buffer('\x00\x0a\x00\x00\x00\x0a')); + }.bind(lPacket)); + + it('should write SGString to the packet and check packet', function(){ + lPacket.writeSGString('test'); + assert.deepEqual(lPacket._packet, new Buffer('\x00\x0a\x00\x00\x00\x0a\x00\x04\x74\x65\x73\x74\x00')); + }.bind(lPacket)); + + it('should read UInt16 from the packet and check value and offset', function(){ + var uint16 = lPacket.readUInt16(10); + assert.equal(uint16, 10); + assert.equal(lPacket._offset, 2); + }.bind(lPacket)); + + it('should read UInt32 from the packet and check value and offset', function(){ + var uint32 = lPacket.readUInt32(10); + assert.equal(uint32, 10); + assert.equal(lPacket._offset, 6); + }.bind(lPacket)); + + it('should read SGString from the packet and check value and offset', function(){ + var sgstring = lPacket.readSGString('test'); + assert.equal(sgstring, 'test'); + assert.equal(lPacket._offset, 13); + }.bind(lPacket)); + }); }) diff --git a/tests/simplepacket.js b/tests/simplepacket.js index a9af9ee..033bc5e 100644 --- a/tests/simplepacket.js +++ b/tests/simplepacket.js @@ -20,15 +20,7 @@ describe('simplepacket', function(){ describe('discovery()', function(){ it('should return a discovery request packet', function(){ var packet = SimplePacket.discovery(); - assert.deepStrictEqual(packet, Buffer('dd00000a000000000000000600000002', 'hex')); + assert.deepStrictEqual(packet, Buffer('dd00000a000000000000000300000002', 'hex')); }); }); - - // describe('unpack()', function(){ - // it('should return SimplePacket object', function(){ - // var packet = SimplePacket.discovery(); - // console.log(packet); - // assert.deepStrictEqual(packet, Buffer('dd00000a000000000000000600000002', 'hex')); - // }); - // }); }) diff --git a/tests/smartglass.js b/tests/smartglass.js index d47f0d2..845cbac 100644 --- a/tests/smartglass.js +++ b/tests/smartglass.js @@ -1,19 +1,41 @@ var assert = require('assert'); var Smartglass = require('../src/smartglass'); +var SimplePacket = require('../src/simplepacket'); +var PacketStructure = require('../src/packet/structure'); describe('smartglass', function(){ describe('getConsoles()', function(){ it('should return an ampty array on init', function(){ assert(Smartglass.getConsoles().length == 0); }); - // it('should return an array after discovery', function(){ - // Smartglass.discovery(); - // assert(Array.isArray(Smartglass.getConsoles())); - // }); }); - // describe('discovery()', function(){ - // it('should return an array', function(){ - // assert(Array.isArray(Smartglass.discovery())); - // }); - // }); + describe('_on_discovery_response()', function(){ + it('should test callback on DISCOVERY_REQUEST packet', function(done){ + var smartglass = Smartglass._on_discovery_response.push(function(payload, device, smartglass){ + assert.equal(payload.payload.device_name, 'Xbox-Smartglass-Test'); + assert.equal(payload.payload.device_udid, 'UUID_TEST'); + assert.equal(payload.payload.device_certificate_raw, 'MOCK_TEST_CERT'); + + done(); + }); + + var remote = { + 'address': '127.0.0.1', + 'port': 5050 + } + + var payload = PacketStructure(); + payload.writeUInt32('6'); + payload.writeUInt16('1'); + payload.writeSGString('Xbox-Smartglass-Test'); + payload.writeSGString('UUID_TEST'); + payload.writeUInt32('0'); + payload.writeSGString('MOCK_TEST_CERT'); + + var message = SimplePacket._pack(new Buffer('dd01', 'hex'), payload.toBuffer()); + + Smartglass._receive(message, remote, smartglass); + + }); + }); }) From 2423310be500b54c14d2bc9a0dd38d4a483aadaf Mon Sep 17 00:00:00 2001 From: Jim Kroon Date: Fri, 15 Jun 2018 21:32:07 +0200 Subject: [PATCH 11/12] Remove discover from package.json --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index fa8600c..3f697ea 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "author": "UnknownSKL (Jim Kroon)", "license": "MIT", "bin": { - "smartglass-discover": "./bin/discover.js", "smartglass-client": "./bin/client.js" }, "bugs": { From 4161af174b90d7dd2bb38bcd13599067b6ec5242 Mon Sep 17 00:00:00 2001 From: Jim Kroon Date: Fri, 15 Jun 2018 21:40:29 +0200 Subject: [PATCH 12/12] Updated readme --- README.md | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index d30270c..b3e2c53 100644 --- a/README.md +++ b/README.md @@ -6,34 +6,41 @@ NodeJS smartglass library for controlling a Xbox - NodeJS 9 (X509 package is not compatible with Node 10 yet) - NPM -- + +## How to install + +```npm install xbox-smartglass-core-node --save``` ## How to use ### Boot the Xbox console - Smartglass.power_on({ - live_id: 'FD000000000000', // Put your console's live id here (Required) - tries: 4, // Number of packets too issue the boot command (Optional) - ip: '127.0.0.1' // Your consoles ip address (Optional) - }, function(result){ - if(result) - console.log('Device booted successfully'); - else - console.log('Failed to boot device'); - }); +``` +Smartglass.power_on({ + live_id: 'FD000000000000', // Put your console's live id here (Required) + tries: 4, // Number of packets too issue the boot command (Optional) + ip: '127.0.0.1' // Your consoles ip address (Optional) +}, function(result){ + if(result) + console.log('Device booted successfully'); + else + console.log('Failed to boot device'); +}); +``` ### Discover consoles on network - Smartglass.discovery({ - ip: '127.0.0.1' // Your consoles ip address (Optional) - }, function(device, address){ - console.log('- Device found: ' + device.device_name); - console.log('Address: '+ address.address + ':' + address.port); - console.log('LiveID: ' + device.device_certificate.subject.commonName); - console.log('Certificate valid: ' + device.device_certificate.notBefore + ' - ' + device.device_certificate.notAfter); - console.log('Certificate fingerprint: ' + device.device_certificate.fingerPrint); - }); +``` +Smartglass.discovery({ + ip: '127.0.0.1' // Your consoles ip address (Optional) +}, function(device, address){ + console.log('- Device found: ' + device.device_name); + console.log('Address: '+ address.address + ':' + address.port); + console.log('LiveID: ' + device.device_certificate.subject.commonName); + console.log('Certificate valid: ' + device.device_certificate.notBefore + ' - ' + device.device_certificate.notAfter); + console.log('Certificate fingerprint: ' + device.device_certificate.fingerPrint); +}); +``` ## Known Issues