node-red-contrib-tak-registration 0.8.3 → 0.10.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 +5 -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-registration.html +9 -2
- package/tak-registration.js +110 -48
|
@@ -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.10.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-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 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,13 +145,36 @@ 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
|
+
|
|
170
|
+
mf += `<Content ignore="false" zipEntry="${hsh+'/'+hsh+'.cot'}"><Parameter name="uid" value="${UUID}"/></Content>\n`;
|
|
133
171
|
}
|
|
134
|
-
|
|
172
|
+
|
|
173
|
+
mf += `</Contents></MissionPackageManifest>`;
|
|
135
174
|
mf = mf.replace(/>\s+</g, "><");
|
|
136
|
-
zip.addFile('MANIFEST/manifest.xml', Buffer.from(mf,'utf8'), msg.topic);
|
|
175
|
+
zip.addFile('MANIFEST/manifest.xml', Buffer.from(mf, 'utf8'), msg.topic);
|
|
137
176
|
var zipbuff = zip.toBuffer();
|
|
138
|
-
|
|
177
|
+
zip.writeZip("/tmp/takfile.zip")
|
|
139
178
|
|
|
140
179
|
msg = {
|
|
141
180
|
from: node.callsign || msg.from || "Anonymous",
|
|
@@ -145,14 +184,14 @@ module.exports = function(RED) {
|
|
|
145
184
|
assetfile: fname,
|
|
146
185
|
len: zipbuff.length,
|
|
147
186
|
uid: node.uuid,
|
|
148
|
-
hash:
|
|
187
|
+
hash: crypto.createHash('sha256').update(zipbuff).digest('hex')
|
|
149
188
|
}
|
|
150
189
|
|
|
151
190
|
let formData = new FormData();
|
|
152
|
-
const opts = { filename:fname, contentType:'application/x-zip-compressed' };
|
|
191
|
+
const opts = { filename: fname, contentType: 'application/x-zip-compressed' };
|
|
153
192
|
formData.append('assetfile', zipbuff, opts);
|
|
154
193
|
|
|
155
|
-
const url = encodeURI(node.host+'/Marti/sync/missionupload?hash='+msg.hash+'&filename='+fname+'&creatorUid='+node.uuid);
|
|
194
|
+
const url = encodeURI(node.host + '/Marti/sync/missionupload?hash=' + msg.hash + '&filename=' + fname + '&creatorUid=' + node.uuid);
|
|
156
195
|
axios({
|
|
157
196
|
method: 'post',
|
|
158
197
|
url: url,
|
|
@@ -160,7 +199,7 @@ module.exports = function(RED) {
|
|
|
160
199
|
data: formData
|
|
161
200
|
})
|
|
162
201
|
.then(function (response) {
|
|
163
|
-
const urlp = encodeURI(node.host+'/Marti/api/sync/metadata/'+msg.hash+'/tool');
|
|
202
|
+
const urlp = encodeURI(node.host + '/Marti/api/sync/metadata/' + msg.hash + '/tool');
|
|
164
203
|
var priv = (msg.sendTo === "public") ? "public" : "private";
|
|
165
204
|
axios({
|
|
166
205
|
method: 'put',
|
|
@@ -173,31 +212,31 @@ module.exports = function(RED) {
|
|
|
173
212
|
const stale = new Date(new Date().getTime() + (10000)).toISOString();
|
|
174
213
|
|
|
175
214
|
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" />
|
|
215
|
+
<point lat="${msg.lat}" lon="${msg.lon}" hae="${msg.alt || 9999999.0}" ce="9999999.0" le="9999999.0" />
|
|
177
216
|
<detail>
|
|
178
217
|
<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
218
|
if (msg.sendTo !== "broadcast") {
|
|
180
219
|
var t = msg.sendTo;
|
|
181
|
-
if (!Array.isArray(t)) { t = [
|
|
182
|
-
m += '<marti>' + t.map(v => '<dest callsign="' + v +'"/>') + '</marti>';
|
|
220
|
+
if (!Array.isArray(t)) { t = [t]; }
|
|
221
|
+
m += '<marti>' + t.map(v => '<dest callsign="' + v + '"/>') + '</marti>';
|
|
183
222
|
}
|
|
184
223
|
m += '</detail></event>';
|
|
185
|
-
node.log(
|
|
224
|
+
node.log("DP: " + node.host + "/Marti/sync/content?hash=" + msg.hash);
|
|
186
225
|
msg.payload = m.replace(/>\s+</g, "><");
|
|
187
226
|
msg.topic = "b-f-t-r";
|
|
188
227
|
node.send(msg);
|
|
189
228
|
}
|
|
190
229
|
})
|
|
191
230
|
.catch(function (error) {
|
|
192
|
-
node.error(error.message,error);
|
|
231
|
+
node.error(error.message, error);
|
|
193
232
|
})
|
|
194
233
|
})
|
|
195
234
|
.catch(function (error) {
|
|
196
|
-
node.error(error.message,error);
|
|
235
|
+
node.error(error.message, error);
|
|
197
236
|
})
|
|
198
237
|
}
|
|
199
238
|
// 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"
|
|
239
|
+
else if (typeof msg.payload === "string") {
|
|
201
240
|
if (msg.payload.trim().startsWith('<') && msg.payload.trim().endsWith('>')) { // Assume it's proper XML event so pass straight through
|
|
202
241
|
msg.topic = msg.payload.split('type="')[1].split('"')[0];
|
|
203
242
|
node.send(msg);
|
|
@@ -206,9 +245,9 @@ module.exports = function(RED) {
|
|
|
206
245
|
// console.log("It's NMEA",msg.payload);
|
|
207
246
|
var nm = msg.payload.trim().split(',');
|
|
208
247
|
if (nm[0] === '$GPGGA' && nm[6] > 0) {
|
|
209
|
-
const la = parseInt(nm[2].substr(0,2)) + parseFloat(nm[2].substr(2))/60;
|
|
248
|
+
const la = parseInt(nm[2].substr(0, 2)) + parseFloat(nm[2].substr(2)) / 60;
|
|
210
249
|
node.lat = ((nm[3] === "N") ? la : -la).toFixed(6);
|
|
211
|
-
const lo = parseInt(nm[4].substr(0,3)) + parseFloat(nm[4].substr(3))/60;
|
|
250
|
+
const lo = parseInt(nm[4].substr(0, 3)) + parseFloat(nm[4].substr(3)) / 60;
|
|
212
251
|
node.lon = ((nm[5] === "E") ? lo : -lo).toFixed(6);
|
|
213
252
|
node.alt = nm[9];
|
|
214
253
|
}
|
|
@@ -223,14 +262,14 @@ module.exports = function(RED) {
|
|
|
223
262
|
var type = "a-f-G-I-B";
|
|
224
263
|
var par = '';
|
|
225
264
|
|
|
226
|
-
for (var t=0; t < msg.sendTo.length; t++) {
|
|
265
|
+
for (var t = 0; t < msg.sendTo.length; t++) {
|
|
227
266
|
var m = RED.util.cloneMessage(msg);
|
|
228
267
|
const to = m.sendTo[t];
|
|
229
268
|
m.sendTo = to;
|
|
230
269
|
const toid = globalContext.get("_takgatewaycs")[m.sendTo] || m.sendTo;
|
|
231
270
|
var ma = `<marti><dest callsign="${m.sendTo}"/></marti>`;
|
|
232
271
|
if (m.sendTo === "broadcast") { m.sendTo = "All Chat Rooms"; }
|
|
233
|
-
if (m.sendTo === "All Chat Rooms") {
|
|
272
|
+
if (m.sendTo === "All Chat Rooms") { ma = ""; }
|
|
234
273
|
if (teamList.includes(m.sendTo)) { par = 'parent="TeamGroups"'; }
|
|
235
274
|
|
|
236
275
|
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 +298,7 @@ module.exports = function(RED) {
|
|
|
259
298
|
if (msg.payload.hasOwnProperty("alt")) { node.alt = parseInt(msg.payload.alt); }
|
|
260
299
|
}
|
|
261
300
|
// Handle a generic worldmap style object
|
|
262
|
-
else if (typeof msg.payload === "object" && msg.payload.hasOwnProperty("name")
|
|
301
|
+
else if (typeof msg.payload === "object" && msg.payload.hasOwnProperty("name")) {
|
|
263
302
|
var shapeXML = ``;
|
|
264
303
|
var d = new Date();
|
|
265
304
|
var st = d.toISOString();
|
|
@@ -278,19 +317,19 @@ module.exports = function(RED) {
|
|
|
278
317
|
if (!msg.payload.cottype && msg.payload.SIDC) {
|
|
279
318
|
var s = msg.payload.SIDC.split('-')[0].toLowerCase();
|
|
280
319
|
if (s.startsWith('s')) {
|
|
281
|
-
type = s.split('').join('-').replace('s-','a-').replace('-p-','-');
|
|
320
|
+
type = s.split('').join('-').replace('s-', 'a-').replace('-p-', '-');
|
|
282
321
|
}
|
|
283
322
|
}
|
|
284
323
|
if (msg.payload.icon === 'fa-circle fa-fw') {
|
|
285
324
|
type = 'b-m-p-s-m';
|
|
286
325
|
shapeXML = '<color argb="' + convertWMtoCOTColour(msg.payload.iconColor.replace('#', '')) + '"/>';
|
|
287
|
-
shapeXML = shapeXML+'<usericon iconsetpath="COT_MAPPING_SPOTMAP/b-m-p-s-m/-16711681"/>';
|
|
326
|
+
shapeXML = shapeXML + '<usericon iconsetpath="COT_MAPPING_SPOTMAP/b-m-p-s-m/-16711681"/>';
|
|
288
327
|
}
|
|
289
328
|
}
|
|
290
329
|
|
|
291
330
|
// Handle Worldmap drawing shapes
|
|
292
331
|
if (msg.payload.hasOwnProperty("action") && msg.payload.action === "draw") {
|
|
293
|
-
ttl = 24*60*60*1000; /// set TTL to 1 day for shapes...
|
|
332
|
+
ttl = 24 * 60 * 60 * 1000; /// set TTL to 1 day for shapes...
|
|
294
333
|
|
|
295
334
|
var shape = {
|
|
296
335
|
"strokeColor": (msg.payload.options.color || "910000").replace('#', ''),
|
|
@@ -364,7 +403,7 @@ module.exports = function(RED) {
|
|
|
364
403
|
<width>${shape.weight || 2.0}</width>
|
|
365
404
|
</LineStyle>
|
|
366
405
|
<PolyStyle>
|
|
367
|
-
<color>${convertWMtoKMLColour(shape.fillColor,shape.fillOpacity)}</color>
|
|
406
|
+
<color>${convertWMtoKMLColour(shape.fillColor, shape.fillOpacity)}</color>
|
|
368
407
|
</PolyStyle>
|
|
369
408
|
</Style>
|
|
370
409
|
</link>
|
|
@@ -391,7 +430,7 @@ module.exports = function(RED) {
|
|
|
391
430
|
}
|
|
392
431
|
|
|
393
432
|
if (shape.type === 'poly') {
|
|
394
|
-
shapeXML += `<fillColor value="${convertWMtoCOTColour(shape.fillColor,shape.fillOpacity)}"/>`;
|
|
433
|
+
shapeXML += `<fillColor value="${convertWMtoCOTColour(shape.fillColor, shape.fillOpacity)}"/>`;
|
|
395
434
|
type = "u-d-f";
|
|
396
435
|
if (shape.points.length === 4) {
|
|
397
436
|
type = "u-d-r";
|
|
@@ -407,9 +446,9 @@ module.exports = function(RED) {
|
|
|
407
446
|
<point lat="${msg.payload.lat || 0}" lon="${msg.payload.lon || 0}" hae="${parseInt(msg.payload.alt || invalid)}" le="9999999.0" ce="9999999.0"/>
|
|
408
447
|
<detail>
|
|
409
448
|
<takv device="${os.hostname()}" os="${os.platform()}" platform="NRedTAK" version="${ver}"/>
|
|
410
|
-
<track course="${msg.payload.bearing || 0}" speed="${parseInt(msg.payload.speed) || 0}"/>
|
|
449
|
+
<track course="${msg.payload.bearing || 9999999.0}" speed="${parseInt(msg.payload.speed) || 0}"/>
|
|
411
450
|
<contact callsign="${msg.payload.name}"/>
|
|
412
|
-
<remarks source="
|
|
451
|
+
<remarks source="${node.callsign}">${tag}</remarks>
|
|
413
452
|
${shapeXML}
|
|
414
453
|
</detail>
|
|
415
454
|
</event>`
|
|
@@ -418,9 +457,32 @@ module.exports = function(RED) {
|
|
|
418
457
|
node.send(msg);
|
|
419
458
|
}
|
|
420
459
|
|
|
460
|
+
// Maybe a simple event json update (eg from an ingest - tweak and send back)
|
|
461
|
+
// Note this is not 100% reverse of the ingest... but seems to work mostly...
|
|
462
|
+
else if (typeof msg.payload === "object" && msg.payload.hasOwnProperty("event")) {
|
|
463
|
+
const ev = msg.payload.event;
|
|
464
|
+
msg.topic = ev.type;
|
|
465
|
+
msg.payload = `<event version="${ev.version}" uid="${ev.uid}" type="${ev.type}" time="${ev.time}" start="${ev.start}" stale="${ev.stale}" how="${ev.how}">
|
|
466
|
+
<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}"/>
|
|
467
|
+
<detail>
|
|
468
|
+
<takv device="${os.hostname()}" os="${os.platform()}" platform="NRedTAK" version="${ver}"/>`
|
|
469
|
+
if (ev.detail?.track) {
|
|
470
|
+
msg.payload += `<track speed="${ev.detail.track.speed}" course="${ev.detail.track.course}"/>`;
|
|
471
|
+
}
|
|
472
|
+
if (ev.detail?.color) {
|
|
473
|
+
msg.payload += `<color argb="${ev.detail.color.argb}"/>`;
|
|
474
|
+
}
|
|
475
|
+
msg.payload += `<contact callsign="${ev.detail?.contact?.callsign}"/>
|
|
476
|
+
<remarks source="${node.callsign}">${msg.remarks || ev.detail?.remarks}</remarks>
|
|
477
|
+
</detail>
|
|
478
|
+
</event>`
|
|
479
|
+
msg.payload = msg.payload.replace(/>\s+</g, "><");
|
|
480
|
+
node.send(msg);
|
|
481
|
+
}
|
|
482
|
+
|
|
421
483
|
// Drop anything we don't handle yet.
|
|
422
484
|
else {
|
|
423
|
-
node.log("Dropped: "+JSON.stringify(msg.payload));
|
|
485
|
+
node.log("Dropped: " + JSON.stringify(msg.payload));
|
|
424
486
|
}
|
|
425
487
|
});
|
|
426
488
|
|