node-red-contrib-tak-registration 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/async_hooks.d.ts +2 -0
- package/node_modules/@types/node/fs.d.ts +12 -7
- package/node_modules/@types/node/http.d.ts +40 -8
- package/node_modules/@types/node/index.d.ts +1 -1
- package/node_modules/@types/node/inspector.d.ts +2 -2
- package/node_modules/@types/node/module.d.ts +29 -4
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/process.d.ts +3 -2
- package/node_modules/@types/node/ts4.8/async_hooks.d.ts +2 -0
- package/node_modules/@types/node/ts4.8/fs.d.ts +12 -7
- package/node_modules/@types/node/ts4.8/http.d.ts +40 -8
- package/node_modules/@types/node/ts4.8/inspector.d.ts +2 -2
- package/node_modules/@types/node/ts4.8/module.d.ts +29 -4
- package/node_modules/@types/node/ts4.8/process.d.ts +3 -2
- package/node_modules/@types/node/ts4.8/worker_threads.d.ts +2 -1
- package/node_modules/@types/node/worker_threads.d.ts +2 -1
- package/node_modules/define-data-property/.eslintrc +24 -0
- package/node_modules/define-data-property/.github/FUNDING.yml +12 -0
- package/node_modules/define-data-property/.nycrc +13 -0
- package/node_modules/define-data-property/CHANGELOG.md +31 -0
- package/node_modules/define-data-property/LICENSE +21 -0
- package/node_modules/define-data-property/README.md +67 -0
- package/node_modules/define-data-property/index.d.ts +3 -0
- package/node_modules/define-data-property/index.d.ts.map +1 -0
- package/node_modules/define-data-property/index.js +60 -0
- package/node_modules/define-data-property/package.json +111 -0
- package/node_modules/define-data-property/test/index.js +397 -0
- package/node_modules/define-data-property/tsconfig.json +58 -0
- package/node_modules/define-data-property/tsinit +109 -0
- package/node_modules/define-properties/CHANGELOG.md +8 -0
- package/node_modules/define-properties/index.js +5 -11
- package/node_modules/define-properties/package.json +5 -4
- package/node_modules/gopd/.eslintrc +16 -0
- package/node_modules/gopd/.github/FUNDING.yml +12 -0
- package/node_modules/gopd/CHANGELOG.md +25 -0
- package/node_modules/gopd/LICENSE +21 -0
- package/node_modules/gopd/README.md +40 -0
- package/node_modules/gopd/index.js +16 -0
- package/node_modules/gopd/package.json +71 -0
- package/node_modules/gopd/test/index.js +35 -0
- package/node_modules/regexp.prototype.flags/.eslintrc +1 -0
- package/node_modules/regexp.prototype.flags/CHANGELOG.md +8 -0
- package/node_modules/regexp.prototype.flags/implementation.js +3 -6
- package/node_modules/regexp.prototype.flags/package.json +8 -7
- package/node_modules/set-function-name/.eslintrc +20 -0
- package/node_modules/set-function-name/.github/FUNDING.yml +12 -0
- package/node_modules/set-function-name/CHANGELOG.md +39 -0
- package/node_modules/set-function-name/LICENSE +21 -0
- package/node_modules/set-function-name/README.md +61 -0
- package/node_modules/set-function-name/index.js +22 -0
- package/node_modules/set-function-name/package.json +80 -0
- package/node_modules/uuid/CHANGELOG.md +6 -0
- package/node_modules/uuid/README.md +9 -5
- package/node_modules/uuid/dist/commonjs-browser/stringify.js +1 -1
- package/node_modules/uuid/dist/esm-browser/stringify.js +1 -1
- package/node_modules/uuid/dist/esm-node/stringify.js +1 -1
- package/node_modules/uuid/dist/stringify.js +1 -1
- package/node_modules/uuid/package.json +7 -3
- package/package.json +2 -2
- package/tak-ingest.html +3 -0
- package/tak-ingest.js +21 -1
- package/tak-registration.html +9 -2
- package/tak-registration.js +95 -57
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
-- This file is auto-generated from README_js.md. Changes should be made there.
|
|
3
3
|
-->
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
# uuid [](https://github.com/uuidjs/uuid/actions?query=workflow%3ACI) [](https://github.com/uuidjs/uuid/actions?query=workflow%3ABrowser)
|
|
6
7
|
|
|
7
8
|
For the creation of [RFC4122](https://www.ietf.org/rfc/rfc4122.txt) UUIDs
|
|
@@ -9,7 +10,7 @@ For the creation of [RFC4122](https://www.ietf.org/rfc/rfc4122.txt) UUIDs
|
|
|
9
10
|
- **Complete** - Support for RFC4122 version 1, 3, 4, and 5 UUIDs
|
|
10
11
|
- **Cross-platform** - Support for ...
|
|
11
12
|
- CommonJS, [ECMAScript Modules](#ecmascript-modules) and [CDN builds](#cdn-builds)
|
|
12
|
-
-
|
|
13
|
+
- NodeJS 12+ ([LTS releases](https://github.com/nodejs/Release))
|
|
13
14
|
- Chrome, Safari, Firefox, Edge browsers
|
|
14
15
|
- Webpack and rollup.js module bundlers
|
|
15
16
|
- [React Native / Expo](#react-native--expo)
|
|
@@ -17,7 +18,9 @@ For the creation of [RFC4122](https://www.ietf.org/rfc/rfc4122.txt) UUIDs
|
|
|
17
18
|
- **Small** - Zero-dependency, small footprint, plays nice with "tree shaking" packagers
|
|
18
19
|
- **CLI** - Includes the [`uuid` command line](#command-line) utility
|
|
19
20
|
|
|
20
|
-
**Upgrading from `uuid@3
|
|
21
|
+
> **Note** Upgrading from `uuid@3`? Your code is probably okay, but check out [Upgrading From `uuid@3`](#upgrading-from-uuid3) for details.
|
|
22
|
+
|
|
23
|
+
> **Note** Only interested in creating a version 4 UUID? You might be able to use [`crypto.randomUUID()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID), eliminating the need to install this library.
|
|
21
24
|
|
|
22
25
|
## Quickstart
|
|
23
26
|
|
|
@@ -138,7 +141,7 @@ Create an RFC version 1 (timestamp) UUID
|
|
|
138
141
|
| [`options.node` ] | RFC "node" field as an `Array[6]` of byte values (per 4.1.6) |
|
|
139
142
|
| [`options.clockseq`] | RFC "clock sequence" as a `Number` between 0 - 0x3fff |
|
|
140
143
|
| [`options.msecs`] | RFC "timestamp" field (`Number` of milliseconds, unix epoch) |
|
|
141
|
-
| [`options.nsecs`] | RFC "timestamp" field (`Number` of
|
|
144
|
+
| [`options.nsecs`] | RFC "timestamp" field (`Number` of nanoseconds to add to `msecs`, should be 0-10,000) |
|
|
142
145
|
| [`options.random`] | `Array` of 16 random bytes (0-255) |
|
|
143
146
|
| [`options.rng`] | Alternative to `options.random`, a `Function` that returns an `Array` of 16 random bytes (0-255) |
|
|
144
147
|
| [`buffer`] | `Array \| Buffer` If specified, uuid will be written here in byte-form, starting at `offset` |
|
|
@@ -458,5 +461,6 @@ const uuid = require('uuid'); // <== REMOVED!
|
|
|
458
461
|
|
|
459
462
|
This usage pattern was already discouraged in `uuid@3` and has been removed in `uuid@7`.
|
|
460
463
|
|
|
461
|
-
|
|
462
|
-
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
Markdown generated from [README_js.md](README_js.md) by <a href="https://github.com/broofa/runmd"><image height="12px" src="https://camo.githubusercontent.com/5c7c603cd1e6a43370b0a5063d457e0dabb74cf317adc7baba183acb686ee8d0/687474703a2f2f692e696d6775722e636f6d2f634a4b6f3662552e706e67" /></a>
|
|
@@ -23,7 +23,7 @@ for (let i = 0; i < 256; ++i) {
|
|
|
23
23
|
function unsafeStringify(arr, offset = 0) {
|
|
24
24
|
// Note: Be careful editing this code! It's been tuned for performance
|
|
25
25
|
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
|
|
26
|
-
return
|
|
26
|
+
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
function stringify(arr, offset = 0) {
|
|
@@ -13,7 +13,7 @@ for (let i = 0; i < 256; ++i) {
|
|
|
13
13
|
export function unsafeStringify(arr, offset = 0) {
|
|
14
14
|
// Note: Be careful editing this code! It's been tuned for performance
|
|
15
15
|
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
|
|
16
|
-
return
|
|
16
|
+
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function stringify(arr, offset = 0) {
|
|
@@ -13,7 +13,7 @@ for (let i = 0; i < 256; ++i) {
|
|
|
13
13
|
export function unsafeStringify(arr, offset = 0) {
|
|
14
14
|
// Note: Be careful editing this code! It's been tuned for performance
|
|
15
15
|
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
|
|
16
|
-
return
|
|
16
|
+
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function stringify(arr, offset = 0) {
|
|
@@ -23,7 +23,7 @@ for (let i = 0; i < 256; ++i) {
|
|
|
23
23
|
function unsafeStringify(arr, offset = 0) {
|
|
24
24
|
// Note: Be careful editing this code! It's been tuned for performance
|
|
25
25
|
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
|
|
26
|
-
return
|
|
26
|
+
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
function stringify(arr, offset = 0) {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uuid",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.1",
|
|
4
4
|
"description": "RFC4122 (v1, v4, and v5) UUIDs",
|
|
5
|
+
"funding": [
|
|
6
|
+
"https://github.com/sponsors/broofa",
|
|
7
|
+
"https://github.com/sponsors/ctavan"
|
|
8
|
+
],
|
|
5
9
|
"commitlint": {
|
|
6
10
|
"extends": [
|
|
7
11
|
"@commitlint/config-conventional"
|
|
@@ -71,7 +75,7 @@
|
|
|
71
75
|
"optional-dev-dependency": "2.0.1",
|
|
72
76
|
"prettier": "2.7.1",
|
|
73
77
|
"random-seed": "0.3.0",
|
|
74
|
-
"runmd": "1.3.
|
|
78
|
+
"runmd": "1.3.9",
|
|
75
79
|
"standard-version": "9.5.0"
|
|
76
80
|
},
|
|
77
81
|
"optionalDevDependencies": {
|
|
@@ -105,7 +109,7 @@
|
|
|
105
109
|
"prettier:fix": "prettier --write '**/*.{js,jsx,json,md}'",
|
|
106
110
|
"bundlewatch": "npm run pretest:browser && bundlewatch --config bundlewatch.config.json",
|
|
107
111
|
"md": "runmd --watch --output=README.md README_js.md",
|
|
108
|
-
"docs": "( node --version | grep -q '
|
|
112
|
+
"docs": "( node --version | grep -q 'v18' ) && ( npm run build && npx runmd --output=README.md README_js.md )",
|
|
109
113
|
"docs:diff": "npm run docs && git diff --quiet README.md",
|
|
110
114
|
"build": "./scripts/build.sh",
|
|
111
115
|
"prepack": "npm run build",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-tak-registration",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "A Node-RED node to register to TAK and to help wrap files as datapackages to send to TAK",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@turf/turf": "6.5.0",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"form-data": "4.0.0",
|
|
11
11
|
"long": "5.2.3",
|
|
12
12
|
"protobufjs": "7.2.5",
|
|
13
|
-
"uuid": "9.0.
|
|
13
|
+
"uuid": "9.0.1"
|
|
14
14
|
},
|
|
15
15
|
"bundledDependencies": [
|
|
16
16
|
"@turf/turf",
|
package/tak-ingest.html
CHANGED
|
@@ -37,4 +37,7 @@
|
|
|
37
37
|
<code>_takgatewaycs</code> and <code>_takgatewayId</code> that can be used
|
|
38
38
|
as look ups for other messages.</p>
|
|
39
39
|
<p>It also sets <code>msg.topic</code> to the event type to make switching easier.</p>
|
|
40
|
+
<p>If an event arrives with a <i>fileshare</i> link, it will fetch the file and add
|
|
41
|
+
<code>msg.filename</code> and <code>msg.datapackage</code> to the output msg.
|
|
42
|
+
The datapackage will be a buffer.</p>
|
|
40
43
|
</script>
|
package/tak-ingest.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { XMLParser, XMLBuilder, XMLValidator} = require("fast-xml-parser");
|
|
2
|
+
const axios = require('axios').default;
|
|
2
3
|
var Long = require('long').Long;
|
|
3
4
|
var protobuf = require('protobufjs');
|
|
4
5
|
var path = require('path');
|
|
@@ -86,7 +87,26 @@ module.exports = function(RED) {
|
|
|
86
87
|
global.set("_takgatewayid", b);
|
|
87
88
|
}
|
|
88
89
|
if (msg.payload?.event?.type) { msg.topic = msg.payload?.event?.type; }
|
|
89
|
-
|
|
90
|
+
if (msg.payload?.event?.detail?.fileshare) {
|
|
91
|
+
msg.filename = msg.payload.event.detail.fileshare.filename;
|
|
92
|
+
axios({
|
|
93
|
+
method: 'get',
|
|
94
|
+
url: msg.payload.event.detail.fileshare.senderUrl,
|
|
95
|
+
headers: { 'Accept': 'application/zip' },
|
|
96
|
+
responseType: 'arraybuffer'
|
|
97
|
+
})
|
|
98
|
+
.then(function (response) {
|
|
99
|
+
msg.datapackage = Buffer.from(response.data);
|
|
100
|
+
node.send(msg);
|
|
101
|
+
})
|
|
102
|
+
.catch(function (error) {
|
|
103
|
+
node.error(error.message, error);
|
|
104
|
+
node.send(msg);
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
node.send(msg);
|
|
109
|
+
}
|
|
90
110
|
});
|
|
91
111
|
|
|
92
112
|
node.on("close", function() {
|
package/tak-registration.html
CHANGED
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
</div>
|
|
59
59
|
<div class="form-row">
|
|
60
60
|
<label for="node-input-dphost"><i class="fa fa-globe"></i> DP-Host url:port</label>
|
|
61
|
-
<input type="text" id="node-input-dphost" placeholder="Data package url http://server:port">
|
|
61
|
+
<input type="text" id="node-input-dphost" placeholder="Data package server url http://server:port">
|
|
62
62
|
</div>
|
|
63
63
|
<div class="form-row">
|
|
64
64
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
</div>
|
|
67
67
|
<div class="form-tips" id="pin-tip"><b>Note</b>: This node MUST be used in conjunction with a TCP request node,
|
|
68
68
|
configured to point to your TAK server tcp address and port (usually 8087 or 8089), set to return strings,
|
|
69
|
-
<i>keep connection open</i> mode, and split on
|
|
69
|
+
<i>keep connection open</i> mode, and split on <code></event></code></div>
|
|
70
70
|
</script>
|
|
71
71
|
<style>
|
|
72
72
|
.inject-time-count {
|
|
@@ -138,7 +138,14 @@
|
|
|
138
138
|
<dt>attachments <span class="property-type">array of objects</span></dt>
|
|
139
139
|
<dd>each object must contain at least a <b>filename</b> (string) and <b>content</b> a buffer of the file/data.
|
|
140
140
|
eg <code>[{filename:"foo.kml", content: <buffer of the file>}]</code></dd>
|
|
141
|
+
<dt>from <span class="property-type">string</span></dt>
|
|
142
|
+
<dd>(optional) callsign of the person sending the file - defaults to the gateway node callsign.</dd>
|
|
143
|
+
<dt>lat <span class="property-type">number | (string)</span></dt>
|
|
144
|
+
<dd>(optional) latitude of the marker for the file.</dd>
|
|
145
|
+
<dt>lon <span class="property-type">number | (string)</span></dt>
|
|
146
|
+
<dd>(optional) longitude of the marker for the file.</dd>
|
|
141
147
|
</dl>
|
|
148
|
+
If you just need to send a single file then you can use <code>msg.filename</code> to set the filename and the <code>msg.payload</code> should be a binary buffer.
|
|
142
149
|
|
|
143
150
|
<h3>Sending simple GeoChat messages...</h3>
|
|
144
151
|
<dl class="message-properties">
|
package/tak-registration.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { methodToString } = require('adm-zip/util');
|
|
2
2
|
const { isArray } = require('util');
|
|
3
3
|
|
|
4
|
-
module.exports = function(RED) {
|
|
4
|
+
module.exports = function (RED) {
|
|
5
5
|
"use strict";
|
|
6
6
|
const os = require('os');
|
|
7
7
|
const AdmZip = require('adm-zip');
|
|
@@ -12,10 +12,10 @@ module.exports = function(RED) {
|
|
|
12
12
|
const uuid = require('uuid');
|
|
13
13
|
const turf = require("@turf/turf");
|
|
14
14
|
const ver = require('./package.json').version;
|
|
15
|
-
const teamList = ["Cyan","Red","Green","Blue","Magenta","Yellow","Orange","Maroon","Purple","Dark Blue","Dark Green","Teal","Brown"];
|
|
15
|
+
const teamList = ["Cyan", "Red", "Green", "Blue", "Magenta", "Yellow", "Orange", "Maroon", "Purple", "Dark Blue", "Dark Green", "Teal", "Brown"];
|
|
16
16
|
|
|
17
17
|
function TakRegistrationNode(n) {
|
|
18
|
-
RED.nodes.createNode(this,n);
|
|
18
|
+
RED.nodes.createNode(this, n);
|
|
19
19
|
const invalid = "9999999.0";
|
|
20
20
|
this.group = n.group;
|
|
21
21
|
this.role = n.role || "Gateway";
|
|
@@ -25,17 +25,17 @@ module.exports = function(RED) {
|
|
|
25
25
|
this.callsign = n.callsign;
|
|
26
26
|
this.repeat = n.repeat;
|
|
27
27
|
this.host = n.dphost;
|
|
28
|
-
this.uuid = "GATEWAY-"+(crypto.createHash('md5').update(Buffer.from(this.id)).digest('hex')).slice(0,16);
|
|
28
|
+
this.uuid = "GATEWAY-" + (crypto.createHash('md5').update(Buffer.from(this.id)).digest('hex')).slice(0, 16);
|
|
29
29
|
var node = this;
|
|
30
30
|
node.alt = invalid;
|
|
31
31
|
var globalContext = this.context().global;
|
|
32
32
|
var g = {};
|
|
33
33
|
g[node.uuid] = node.callsign;
|
|
34
|
-
globalContext.set("_takgatewayid",g);
|
|
34
|
+
globalContext.set("_takgatewayid", g);
|
|
35
35
|
var gr = {};
|
|
36
36
|
gr[node.callsign] = node.uuid;
|
|
37
|
-
globalContext.set("_takgatewaycs",gr);
|
|
38
|
-
globalContext.set("_takdphost",node.host);
|
|
37
|
+
globalContext.set("_takgatewaycs", gr);
|
|
38
|
+
globalContext.set("_takdphost", node.host);
|
|
39
39
|
|
|
40
40
|
if (node.role !== "Gateway") { node.ntype = "a-f-G-U-C" }
|
|
41
41
|
|
|
@@ -44,13 +44,13 @@ module.exports = function(RED) {
|
|
|
44
44
|
delete node.repeat;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
var convertWMtoKMLColour = function(colour,opacity) {
|
|
47
|
+
var convertWMtoKMLColour = function (colour, opacity) {
|
|
48
48
|
if (opacity == undefined) { opacity = 100; }
|
|
49
49
|
var alfa = parseInt(opacity * 255 / 100).toString(16);
|
|
50
50
|
return alfa + colour;
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
var convertWMtoCOTColour = function(colour,opacity) {
|
|
53
|
+
var convertWMtoCOTColour = function (colour, opacity) {
|
|
54
54
|
var c;
|
|
55
55
|
if (opacity != undefined) {
|
|
56
56
|
c = Buffer.from(parseInt(opacity * 255 / 100).toString(16) + colour, "hex");
|
|
@@ -61,7 +61,7 @@ module.exports = function(RED) {
|
|
|
61
61
|
return c.readInt32BE()
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
var findCentroidOfPoints = function(points) {
|
|
64
|
+
var findCentroidOfPoints = function (points) {
|
|
65
65
|
if (points.length < 4) { // pad if necessary (needs 4 points minimum)
|
|
66
66
|
points.push(points[2]);
|
|
67
67
|
points.unshift(points[0]);
|
|
@@ -71,7 +71,7 @@ module.exports = function(RED) {
|
|
|
71
71
|
return centroid;
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
-
var sendIt = function() {
|
|
74
|
+
var sendIt = function () {
|
|
75
75
|
node.emit("input", {
|
|
76
76
|
time: new Date().toISOString(),
|
|
77
77
|
etime: new Date(Date.now() + (2 * node.repeat)).toISOString(),
|
|
@@ -97,25 +97,41 @@ module.exports = function(RED) {
|
|
|
97
97
|
node.repeaterSetup();
|
|
98
98
|
setTimeout(sendIt, 2500);
|
|
99
99
|
|
|
100
|
-
node.on("input",function(msg) {
|
|
100
|
+
node.on("input", function (msg) {
|
|
101
101
|
if (msg.heartbeat) { // Register gateway and do the heartbeats
|
|
102
|
-
var template = `<event version="2.0" uid="${node.uuid}" type="${msg.type}" how="h-e" time="${msg.time}" start="${msg.time}" stale="${msg.etime}"><point lat="${msg.lat}" lon="${msg.lon}" hae="${msg.alt}" ce="9999999" le="9999999"/><detail><takv device="${os.hostname()}" os="${os.platform()}" platform="NRedTAK" version="${ver}"/><contact endpoint="*:-1:stcp" callsign="${msg.callsign}"/><uid Droid="${msg.callsign}"/><__group name="${msg.group}" role="${msg.role}"/><status battery="99"/><track course="0
|
|
103
|
-
node.send({payload:template, topic:
|
|
104
|
-
node.status({fill:"green", shape:"dot", text:node.repeat/1000+"s - "+node.callsign});
|
|
102
|
+
var template = `<event version="2.0" uid="${node.uuid}" type="${msg.type}" how="h-e" time="${msg.time}" start="${msg.time}" stale="${msg.etime}"><point lat="${msg.lat}" lon="${msg.lon}" hae="${msg.alt}" ce="9999999" le="9999999"/><detail><takv device="${os.hostname()}" os="${os.platform()}" platform="NRedTAK" version="${ver}"/><contact endpoint="*:-1:stcp" callsign="${msg.callsign}"/><uid Droid="${msg.callsign}"/><__group name="${msg.group}" role="${msg.role}"/><status battery="99"/><track course="9999999.0" speed="0"/></detail></event>`;
|
|
103
|
+
node.send({ payload: template, topic: "TAKreg" });
|
|
104
|
+
node.status({ fill: "green", shape: "dot", text: node.repeat / 1000 + "s - " + node.callsign });
|
|
105
105
|
return;
|
|
106
106
|
}
|
|
107
|
+
// if it's just a simple filename and buffer payload then make it look like an attachment etc...
|
|
108
|
+
if (msg.hasOwnProperty("filename") && Buffer.isBuffer(msg.payload) && !msg.hasOwnProperty("attachments")) {
|
|
109
|
+
msg.attachments = [{
|
|
110
|
+
filename: msg.filename.split('/').pop(),
|
|
111
|
+
content: msg.payload
|
|
112
|
+
}]
|
|
113
|
+
if (!msg.hasOwnProperty("topic")) { msg.topic = "File - " + msg.filename.split('/').pop(); }
|
|
114
|
+
delete msg.filename;
|
|
115
|
+
delete msg.payload;
|
|
116
|
+
}
|
|
107
117
|
// If there are attachments handle them first. (Datapackage)
|
|
108
118
|
if (msg.hasOwnProperty("attachments") && Array.isArray(msg.attachments) && msg.attachments.length > 0) {
|
|
109
|
-
if (!msg.sendTo) { node.error("Missing 'sendTo' user TAK callsign property.",msg); return; }
|
|
110
|
-
var UUID = uuid.v5(msg.topic,'d5d4a57d-48fb-58b6-93b8-d9fde658481a');
|
|
119
|
+
if (!msg.sendTo) { node.error("Missing 'sendTo' user TAK callsign property.", msg); return; }
|
|
120
|
+
var UUID = uuid.v5(msg.topic, 'd5d4a57d-48fb-58b6-93b8-d9fde658481a');
|
|
111
121
|
var fnam = msg.topic;
|
|
112
|
-
var fname = msg.topic+'.zip';
|
|
122
|
+
var fname = msg.topic + '.zip';
|
|
123
|
+
var da = new Date();
|
|
124
|
+
var dn = da.toISOString().split('-')[2].split('.')[0];
|
|
125
|
+
var calls = msg.from || node.callsign;
|
|
126
|
+
calls = calls + '.' + dn.split('T')[0] + '.' + dn.split('T')[1].split(':').join('');
|
|
113
127
|
var mf = `<MissionPackageManifest version="2"><Configuration>
|
|
114
128
|
<Parameter name="uid" value="${UUID}"/>
|
|
115
129
|
<Parameter name="name" value="${msg.topic}"/>
|
|
116
|
-
|
|
130
|
+
<Parameter name="onReceiveImport" value="true"/>
|
|
131
|
+
<Parameter name="callsign" value="${calls}"/>
|
|
132
|
+
</Configuration><Contents>\n`;
|
|
117
133
|
var zip = new AdmZip();
|
|
118
|
-
for (var i=0; i < msg.attachments.length; i++) {
|
|
134
|
+
for (var i = 0; i < msg.attachments.length; i++) {
|
|
119
135
|
var data;
|
|
120
136
|
if (Buffer.isBuffer(msg.attachments[i].content)) {
|
|
121
137
|
data = msg.attachments[i].content;
|
|
@@ -129,30 +145,52 @@ module.exports = function(RED) {
|
|
|
129
145
|
var hash = crypto.createHash('md5').update(data).digest('hex');
|
|
130
146
|
var fhash = hash + '/' + msg.attachments[i].filename;
|
|
131
147
|
zip.addFile(fhash, data, "Added by Node-RED");
|
|
132
|
-
mf
|
|
148
|
+
mf += `<Content ignore="false" zipEntry="${fhash}"><Parameter name="uid" value="${UUID}"/></Content>\n`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (msg.hasOwnProperty("lat") && msg.hasOwnProperty("lon")) {
|
|
152
|
+
var timeo = new Date(Date.now() + (1000*60*60*4)).toISOString(); // stale time to 4 hours
|
|
153
|
+
var cott = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
154
|
+
<event version="2.0" uid="${UUID}" type="b-i-x-i" time="${da.toISOString()}" start="${da.toISOString()}" stale="${timeo}" how="h-g-i-g-o">
|
|
155
|
+
<point lat="${msg.lat}" lon="${msg.lon}" hae="${msg.alt || "9999999.0"}" ce="9999999.0" le="9999999.0" />
|
|
156
|
+
<detail>
|
|
157
|
+
<status readiness="true" />
|
|
158
|
+
<contact callsign="${calls}" />
|
|
159
|
+
<remarks>${msg.remarks || ''}</remarks>
|
|
160
|
+
<color argb="-1" />
|
|
161
|
+
<link uid="${node.uuid}" production_time="${da.toISOString()}" type="a-f-G-U-C" parent_callsign="${msg.from || node.callsign}" relation="p-p" />
|
|
162
|
+
<archive />
|
|
163
|
+
</detail>
|
|
164
|
+
</event>`
|
|
165
|
+
|
|
166
|
+
cott = cott.replace(/>\s+</g, "><");
|
|
167
|
+
var hsh = crypto.createHash('md5').update(cott).digest('hex');
|
|
168
|
+
zip.addFile(hsh+'/'+hsh+'.cot', cott, "Added by Node-RED");
|
|
169
|
+
mf += `<Content ignore="false" zipEntry="${hsh+'/'+hsh+'.cot'}"><Parameter name="uid" value="${UUID}"/></Content>\n`;
|
|
133
170
|
}
|
|
134
|
-
|
|
171
|
+
|
|
172
|
+
mf += `</Contents></MissionPackageManifest>`;
|
|
135
173
|
mf = mf.replace(/>\s+</g, "><");
|
|
136
|
-
zip.addFile('MANIFEST/manifest.xml', Buffer.from(mf,'utf8'), msg.topic);
|
|
174
|
+
zip.addFile('MANIFEST/manifest.xml', Buffer.from(mf, 'utf8'), msg.topic);
|
|
137
175
|
var zipbuff = zip.toBuffer();
|
|
138
|
-
|
|
176
|
+
zip.writeZip("/tmp/takfile.zip")
|
|
139
177
|
|
|
140
178
|
msg = {
|
|
141
|
-
from:
|
|
179
|
+
from: msg.from || node.callsign || "Anonymous",
|
|
142
180
|
sendTo: msg.sendTo,
|
|
143
|
-
lat:
|
|
144
|
-
lon:
|
|
181
|
+
lat: msg.lat || node.lat || 0,
|
|
182
|
+
lon: msg.lon || node.lon || 0,
|
|
145
183
|
assetfile: fname,
|
|
146
184
|
len: zipbuff.length,
|
|
147
185
|
uid: node.uuid,
|
|
148
|
-
hash:
|
|
186
|
+
hash: crypto.createHash('sha256').update(zipbuff).digest('hex')
|
|
149
187
|
}
|
|
150
188
|
|
|
151
189
|
let formData = new FormData();
|
|
152
|
-
const opts = { filename:fname, contentType:'application/x-zip-compressed' };
|
|
190
|
+
const opts = { filename: fname, contentType: 'application/x-zip-compressed' };
|
|
153
191
|
formData.append('assetfile', zipbuff, opts);
|
|
154
192
|
|
|
155
|
-
const url = encodeURI(node.host+'/Marti/sync/missionupload?hash='+msg.hash+'&filename='+fname+'&creatorUid='+node.uuid);
|
|
193
|
+
const url = encodeURI(node.host + '/Marti/sync/missionupload?hash=' + msg.hash + '&filename=' + fname + '&creatorUid=' + node.uuid);
|
|
156
194
|
axios({
|
|
157
195
|
method: 'post',
|
|
158
196
|
url: url,
|
|
@@ -160,7 +198,7 @@ module.exports = function(RED) {
|
|
|
160
198
|
data: formData
|
|
161
199
|
})
|
|
162
200
|
.then(function (response) {
|
|
163
|
-
const urlp = encodeURI(node.host+'/Marti/api/sync/metadata/'+msg.hash+'/tool');
|
|
201
|
+
const urlp = encodeURI(node.host + '/Marti/api/sync/metadata/' + msg.hash + '/tool');
|
|
164
202
|
var priv = (msg.sendTo === "public") ? "public" : "private";
|
|
165
203
|
axios({
|
|
166
204
|
method: 'put',
|
|
@@ -173,31 +211,31 @@ module.exports = function(RED) {
|
|
|
173
211
|
const stale = new Date(new Date().getTime() + (10000)).toISOString();
|
|
174
212
|
|
|
175
213
|
var m = `<event version="2.0" uid="${uuidv4()}" type="b-f-t-r" how="h-e" time="${start}" start="${start}" stale="${stale}">
|
|
176
|
-
<point lat="${msg.lat}" lon="${msg.lon}" hae="9999999.0" ce="9999999.0" le="9999999.0" />
|
|
214
|
+
<point lat="${msg.lat}" lon="${msg.lon}" hae="${msg.alt || 9999999.0}" ce="9999999.0" le="9999999.0" />
|
|
177
215
|
<detail>
|
|
178
216
|
<fileshare filename="${fname}" senderUrl="${node.host}/Marti/sync/content?hash=${msg.hash}" sizeInBytes="${msg.len}" sha256="${msg.hash}" senderUid="${msg.uid}" senderCallsign="${msg.from}" name="${fnam}" />`
|
|
179
217
|
if (msg.sendTo !== "broadcast") {
|
|
180
218
|
var t = msg.sendTo;
|
|
181
|
-
if (!Array.isArray(t)) { t = [
|
|
182
|
-
m += '<marti>' + t.map(v => '<dest callsign="' + v +'"/>') + '</marti>';
|
|
219
|
+
if (!Array.isArray(t)) { t = [t]; }
|
|
220
|
+
m += '<marti>' + t.map(v => '<dest callsign="' + v + '"/>') + '</marti>';
|
|
183
221
|
}
|
|
184
222
|
m += '</detail></event>';
|
|
185
|
-
node.log(
|
|
223
|
+
node.log("DP: " + node.host + "/Marti/sync/content?hash=" + msg.hash);
|
|
186
224
|
msg.payload = m.replace(/>\s+</g, "><");
|
|
187
225
|
msg.topic = "b-f-t-r";
|
|
188
226
|
node.send(msg);
|
|
189
227
|
}
|
|
190
228
|
})
|
|
191
229
|
.catch(function (error) {
|
|
192
|
-
node.error(error.message,error);
|
|
230
|
+
node.error(error.message, error);
|
|
193
231
|
})
|
|
194
232
|
})
|
|
195
233
|
.catch(function (error) {
|
|
196
|
-
node.error(error.message,error);
|
|
234
|
+
node.error(error.message, error);
|
|
197
235
|
})
|
|
198
236
|
}
|
|
199
237
|
// Otherwise if it's a string maybe it's raw cot xml - or NMEA from GPS - or maybe a simple chat message
|
|
200
|
-
else if (typeof msg.payload === "string"
|
|
238
|
+
else if (typeof msg.payload === "string") {
|
|
201
239
|
if (msg.payload.trim().startsWith('<') && msg.payload.trim().endsWith('>')) { // Assume it's proper XML event so pass straight through
|
|
202
240
|
msg.topic = msg.payload.split('type="')[1].split('"')[0];
|
|
203
241
|
node.send(msg);
|
|
@@ -206,9 +244,9 @@ module.exports = function(RED) {
|
|
|
206
244
|
// console.log("It's NMEA",msg.payload);
|
|
207
245
|
var nm = msg.payload.trim().split(',');
|
|
208
246
|
if (nm[0] === '$GPGGA' && nm[6] > 0) {
|
|
209
|
-
const la = parseInt(nm[2].substr(0,2)) + parseFloat(nm[2].substr(2))/60;
|
|
247
|
+
const la = parseInt(nm[2].substr(0, 2)) + parseFloat(nm[2].substr(2)) / 60;
|
|
210
248
|
node.lat = ((nm[3] === "N") ? la : -la).toFixed(6);
|
|
211
|
-
const lo = parseInt(nm[4].substr(0,3)) + parseFloat(nm[4].substr(3))/60;
|
|
249
|
+
const lo = parseInt(nm[4].substr(0, 3)) + parseFloat(nm[4].substr(3)) / 60;
|
|
212
250
|
node.lon = ((nm[5] === "E") ? lo : -lo).toFixed(6);
|
|
213
251
|
node.alt = nm[9];
|
|
214
252
|
}
|
|
@@ -223,14 +261,14 @@ module.exports = function(RED) {
|
|
|
223
261
|
var type = "a-f-G-I-B";
|
|
224
262
|
var par = '';
|
|
225
263
|
|
|
226
|
-
for (var t=0; t < msg.sendTo.length; t++) {
|
|
264
|
+
for (var t = 0; t < msg.sendTo.length; t++) {
|
|
227
265
|
var m = RED.util.cloneMessage(msg);
|
|
228
266
|
const to = m.sendTo[t];
|
|
229
267
|
m.sendTo = to;
|
|
230
268
|
const toid = globalContext.get("_takgatewaycs")[m.sendTo] || m.sendTo;
|
|
231
269
|
var ma = `<marti><dest callsign="${m.sendTo}"/></marti>`;
|
|
232
270
|
if (m.sendTo === "broadcast") { m.sendTo = "All Chat Rooms"; }
|
|
233
|
-
if (m.sendTo === "All Chat Rooms") {
|
|
271
|
+
if (m.sendTo === "All Chat Rooms") { ma = ""; }
|
|
234
272
|
if (teamList.includes(m.sendTo)) { par = 'parent="TeamGroups"'; }
|
|
235
273
|
|
|
236
274
|
var xm = `<event version="2.0" uid="GeoChat.${node.uuid}.${toid}.${mid}" type="b-t-f" time="${start}" start="${start}" stale="${stale}" how="h-g-i-g-o">
|
|
@@ -259,7 +297,7 @@ module.exports = function(RED) {
|
|
|
259
297
|
if (msg.payload.hasOwnProperty("alt")) { node.alt = parseInt(msg.payload.alt); }
|
|
260
298
|
}
|
|
261
299
|
// Handle a generic worldmap style object
|
|
262
|
-
else if (typeof msg.payload === "object" && msg.payload.hasOwnProperty("name")
|
|
300
|
+
else if (typeof msg.payload === "object" && msg.payload.hasOwnProperty("name")) {
|
|
263
301
|
var shapeXML = ``;
|
|
264
302
|
var d = new Date();
|
|
265
303
|
var st = d.toISOString();
|
|
@@ -278,19 +316,19 @@ module.exports = function(RED) {
|
|
|
278
316
|
if (!msg.payload.cottype && msg.payload.SIDC) {
|
|
279
317
|
var s = msg.payload.SIDC.split('-')[0].toLowerCase();
|
|
280
318
|
if (s.startsWith('s')) {
|
|
281
|
-
type = s.split('').join('-').replace('s-','a-').replace('-p-','-');
|
|
319
|
+
type = s.split('').join('-').replace('s-', 'a-').replace('-p-', '-');
|
|
282
320
|
}
|
|
283
321
|
}
|
|
284
322
|
if (msg.payload.icon === 'fa-circle fa-fw') {
|
|
285
323
|
type = 'b-m-p-s-m';
|
|
286
324
|
shapeXML = '<color argb="' + convertWMtoCOTColour(msg.payload.iconColor.replace('#', '')) + '"/>';
|
|
287
|
-
shapeXML = shapeXML+'<usericon iconsetpath="COT_MAPPING_SPOTMAP/b-m-p-s-m/-16711681"/>';
|
|
325
|
+
shapeXML = shapeXML + '<usericon iconsetpath="COT_MAPPING_SPOTMAP/b-m-p-s-m/-16711681"/>';
|
|
288
326
|
}
|
|
289
327
|
}
|
|
290
328
|
|
|
291
329
|
// Handle Worldmap drawing shapes
|
|
292
330
|
if (msg.payload.hasOwnProperty("action") && msg.payload.action === "draw") {
|
|
293
|
-
ttl = 24*60*60*1000; /// set TTL to 1 day for shapes...
|
|
331
|
+
ttl = 24 * 60 * 60 * 1000; /// set TTL to 1 day for shapes...
|
|
294
332
|
|
|
295
333
|
var shape = {
|
|
296
334
|
"strokeColor": (msg.payload.options.color || "910000").replace('#', ''),
|
|
@@ -364,7 +402,7 @@ module.exports = function(RED) {
|
|
|
364
402
|
<width>${shape.weight || 2.0}</width>
|
|
365
403
|
</LineStyle>
|
|
366
404
|
<PolyStyle>
|
|
367
|
-
<color>${convertWMtoKMLColour(shape.fillColor,shape.fillOpacity)}</color>
|
|
405
|
+
<color>${convertWMtoKMLColour(shape.fillColor, shape.fillOpacity)}</color>
|
|
368
406
|
</PolyStyle>
|
|
369
407
|
</Style>
|
|
370
408
|
</link>
|
|
@@ -391,7 +429,7 @@ module.exports = function(RED) {
|
|
|
391
429
|
}
|
|
392
430
|
|
|
393
431
|
if (shape.type === 'poly') {
|
|
394
|
-
shapeXML += `<fillColor value="${convertWMtoCOTColour(shape.fillColor,shape.fillOpacity)}"/>`;
|
|
432
|
+
shapeXML += `<fillColor value="${convertWMtoCOTColour(shape.fillColor, shape.fillOpacity)}"/>`;
|
|
395
433
|
type = "u-d-f";
|
|
396
434
|
if (shape.points.length === 4) {
|
|
397
435
|
type = "u-d-r";
|
|
@@ -409,7 +447,7 @@ module.exports = function(RED) {
|
|
|
409
447
|
<takv device="${os.hostname()}" os="${os.platform()}" platform="NRedTAK" version="${ver}"/>
|
|
410
448
|
<track course="${msg.payload.bearing || 9999999.0}" speed="${parseInt(msg.payload.speed) || 0}"/>
|
|
411
449
|
<contact callsign="${msg.payload.name}"/>
|
|
412
|
-
<remarks source="
|
|
450
|
+
<remarks source="${node.callsign}">${tag}</remarks>
|
|
413
451
|
${shapeXML}
|
|
414
452
|
</detail>
|
|
415
453
|
</event>`
|
|
@@ -420,19 +458,19 @@ module.exports = function(RED) {
|
|
|
420
458
|
|
|
421
459
|
// Maybe a simple event json update (eg from an ingest - tweak and send back)
|
|
422
460
|
// Note this is not 100% reverse of the ingest... but seems to work mostly...
|
|
423
|
-
else if (typeof msg.payload === "object" && msg.payload.hasOwnProperty("event")
|
|
461
|
+
else if (typeof msg.payload === "object" && msg.payload.hasOwnProperty("event")) {
|
|
424
462
|
const ev = msg.payload.event;
|
|
425
463
|
msg.topic = ev.type;
|
|
426
464
|
msg.payload = `<event version="${ev.version}" uid="${ev.uid}" type="${ev.type}" time="${ev.time}" start="${ev.start}" stale="${ev.stale}" how="${ev.how}">
|
|
427
465
|
<point lat="${ev.point.lat || 0}" lon="${ev.point.lon || 0}" hae="${ev.detail?.height?.value || ev.point.hae || 9999999.0}" le="${ev.point.le}" ce="${ev.point.ce}"/>
|
|
428
466
|
<detail>
|
|
429
467
|
<takv device="${os.hostname()}" os="${os.platform()}" platform="NRedTAK" version="${ver}"/>`
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
468
|
+
if (ev.detail?.track) {
|
|
469
|
+
msg.payload += `<track speed="${ev.detail.track.speed}" course="${ev.detail.track.course}"/>`;
|
|
470
|
+
}
|
|
471
|
+
if (ev.detail?.color) {
|
|
472
|
+
msg.payload += `<color argb="${ev.detail.color.argb}"/>`;
|
|
473
|
+
}
|
|
436
474
|
msg.payload += `<contact callsign="${ev.detail?.contact?.callsign}"/>
|
|
437
475
|
<remarks source="${node.callsign}">${msg.remarks || ev.detail?.remarks}</remarks>
|
|
438
476
|
</detail>
|
|
@@ -443,7 +481,7 @@ module.exports = function(RED) {
|
|
|
443
481
|
|
|
444
482
|
// Drop anything we don't handle yet.
|
|
445
483
|
else {
|
|
446
|
-
node.log("Dropped: "+JSON.stringify(msg.payload));
|
|
484
|
+
node.log("Dropped: " + JSON.stringify(msg.payload));
|
|
447
485
|
}
|
|
448
486
|
});
|
|
449
487
|
|