node-red-contrib-ntrip 0.2.0 → 0.2.1
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/CHANGELOG.md +4 -0
- package/ntrip/99-ntrip.html +23 -3
- package/ntrip/lib/ntrip-client.js +30 -11
- package/ntrip/nodes/ntrip-client-node.js +25 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
|
3
3
|
|
|
4
|
+
## [0.2.1]
|
|
5
|
+
### Added several auth modes for uploading data to the caster.
|
|
6
|
+
### added pass through mode - [#10](https://github.com/windkh/node-red-contrib-ntrip/issues/10)
|
|
7
|
+
|
|
4
8
|
## [0.2.0]
|
|
5
9
|
### Refactored nodes: data can be forwarded to NTRIP caster now.
|
|
6
10
|
|
package/ntrip/99-ntrip.html
CHANGED
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
defaults: {
|
|
10
10
|
description: { value:"" },
|
|
11
11
|
mode: { value: "download", required: true },
|
|
12
|
+
authmode: { value: "legacy", required: true },
|
|
13
|
+
passthrough: { value: false, required: false },
|
|
14
|
+
|
|
12
15
|
port: { value: 2101, required: false, validate:function(v) { return ((v === "") || (RED.validators.number(v) && (v >= 0) && (v <= 65535))) }},
|
|
13
16
|
host: { value:"" },
|
|
14
17
|
mountpoint: { value:"" },
|
|
@@ -36,11 +39,11 @@
|
|
|
36
39
|
var updateMode = function() {
|
|
37
40
|
var mode = $("#node-input-mode").val();
|
|
38
41
|
if (mode == "download") {
|
|
39
|
-
|
|
42
|
+
$("#uploadoptions").hide();
|
|
40
43
|
} else if (mode == "upload"){
|
|
41
|
-
|
|
44
|
+
$("#uploadoptions").show();
|
|
42
45
|
} else {
|
|
43
|
-
|
|
46
|
+
$("#uploadoptions").hide();
|
|
44
47
|
}
|
|
45
48
|
};
|
|
46
49
|
updateMode();
|
|
@@ -70,6 +73,23 @@
|
|
|
70
73
|
</select>
|
|
71
74
|
</div>
|
|
72
75
|
|
|
76
|
+
<div class="form-row" id="uploadoptions" style="background: var(--red-ui-tertiary-background)">
|
|
77
|
+
<div class="form-row">
|
|
78
|
+
<label for="node-input-authmode"><i class="fa fa-id-card-o"></i> Authentication Mode</label>
|
|
79
|
+
<select id="node-input-authmode" style="width:70%">
|
|
80
|
+
<option value="legacy">Legacy (Plain Text)</option>
|
|
81
|
+
<option value="hybrid">Legacy (Basic Auth)</option>
|
|
82
|
+
<option value="ntripv1">NTRIP V1</option>
|
|
83
|
+
<option value="ntripv2">NTRIP V2</option>
|
|
84
|
+
</select>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<div class="form-row">
|
|
88
|
+
<label for="node-input-passthrough"><i class="fa fa-long-arrow-right"></i> Pass through data to output.</label>
|
|
89
|
+
<input type="checkbox" id="node-input-passthrough" style="display: inline-block; width: auto; vertical-align: top;">
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
|
|
73
93
|
<hr align="middle"/>
|
|
74
94
|
|
|
75
95
|
<div class="form-row">
|
|
@@ -8,6 +8,7 @@ const net = require('net');
|
|
|
8
8
|
class NtripClientUploader extends NtripClient {
|
|
9
9
|
constructor(options) {
|
|
10
10
|
super(options);
|
|
11
|
+
this.authmode = options.authmode || 'legacy';
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
_connect() {
|
|
@@ -29,20 +30,38 @@ class NtripClientUploader extends NtripClient {
|
|
|
29
30
|
// on connect event
|
|
30
31
|
this.client.on('connect', () => {
|
|
31
32
|
const mountpoint = this.mountpoint;
|
|
33
|
+
const userAgent = this.userAgent;
|
|
32
34
|
const username = this.username;
|
|
33
35
|
const password = this.password;
|
|
34
|
-
|
|
36
|
+
const host = this.host;
|
|
37
|
+
const port = this.port;
|
|
38
|
+
const authmode = this.authmode;
|
|
39
|
+
const authorization = Buffer.from(
|
|
40
|
+
username + ':' + password,
|
|
41
|
+
'utf8'
|
|
42
|
+
).toString('base64');
|
|
43
|
+
|
|
35
44
|
let data;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
switch (authmode) {
|
|
46
|
+
case 'legacy': // Legacy --> rtk2Go accepts this.
|
|
47
|
+
if (username === '' && password === '') {
|
|
48
|
+
data = `SOURCE ${mountpoint}\r\n\r\n`;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
data = `SOURCE ${password} /${mountpoint}\r\nSource-Agent: NTRIP ${username}\r\n\r\n`;
|
|
52
|
+
}
|
|
53
|
+
break;
|
|
54
|
+
case 'hybrid': // hybrid (legacy + http auth) --> SNIP accepts this.
|
|
55
|
+
data = `SOURCE ${mountpoint}\r\nAuthorization: Basic ${authorization}\r\n\r\n`;
|
|
56
|
+
break;
|
|
57
|
+
case 'ntripv1': // NTRIP V1 POST
|
|
58
|
+
data = `POST /${mountpoint} HTTP/1.0\r\nUser-Agent: NTRIP ${userAgent}\r\nAuthorization: Basic ${authorization}\r\nContent-Type: gnss/data\r\n\r\n`;
|
|
59
|
+
break;
|
|
60
|
+
case 'ntripv2': // NTRIP V2 POST
|
|
61
|
+
data = `POST /${mountpoint} HTTP/1.1\r\nHost: ${host}:${port}\r\nUser-Agent: NTRIP ${userAgent}\r\nAuthorization: Basic ${authorization}\r\nNtrip-Version: Ntrip/2.0\r\nContent-Type: gnss/data\r\nConnection: keep-alive\r\n\r\n`;
|
|
62
|
+
break;
|
|
63
|
+
default:
|
|
64
|
+
throw new Error("Auth mode is not supported " + authmode);
|
|
46
65
|
}
|
|
47
66
|
|
|
48
67
|
this.client.write(data);
|
|
@@ -3,6 +3,7 @@ module.exports = function (RED) {
|
|
|
3
3
|
|
|
4
4
|
const NtripClient = require("../lib/ntrip-client.js");
|
|
5
5
|
const NtripServerOkReply = 'ICY 200 OK';
|
|
6
|
+
const NtripServerNotOkReply = 'ICY 406';
|
|
6
7
|
const NtripServerMissingMountpoint = 'SOURCETABLE 200 OK';
|
|
7
8
|
|
|
8
9
|
function NtripClientNode(config) {
|
|
@@ -12,7 +13,9 @@ module.exports = function (RED) {
|
|
|
12
13
|
let host = config.host;
|
|
13
14
|
let port = config.port || 2101;
|
|
14
15
|
let mountpoint = config.mountpoint;
|
|
15
|
-
let mode = config.mode ||
|
|
16
|
+
let mode = config.mode || 'download';
|
|
17
|
+
let authmode = config.authmode || 'legacy';
|
|
18
|
+
node.passthrough = config.passthrough || false;
|
|
16
19
|
|
|
17
20
|
let client;
|
|
18
21
|
if(host !== undefined ) {
|
|
@@ -43,6 +46,7 @@ module.exports = function (RED) {
|
|
|
43
46
|
}
|
|
44
47
|
else if (mode === 'upload') {
|
|
45
48
|
// Uploaders send RTCM data to a mountpoint so that clients can consume it.
|
|
49
|
+
options.authmode = authmode;
|
|
46
50
|
client = NtripClient.createUploader(options);
|
|
47
51
|
}
|
|
48
52
|
else {
|
|
@@ -69,6 +73,15 @@ module.exports = function (RED) {
|
|
|
69
73
|
shape: 'ring',
|
|
70
74
|
text: 'NTRIP server connected.',
|
|
71
75
|
});
|
|
76
|
+
}
|
|
77
|
+
// check if ICY 406 Not Acceptable
|
|
78
|
+
else if (response.startsWith(NtripServerNotOkReply)) {
|
|
79
|
+
node.status({
|
|
80
|
+
fill: 'red',
|
|
81
|
+
shape: 'ring',
|
|
82
|
+
text: 'NTRIP server rejected connection.',
|
|
83
|
+
});
|
|
84
|
+
node.error('Server rejected connect: ' + response);
|
|
72
85
|
}
|
|
73
86
|
else if (response.startsWith(NtripServerMissingMountpoint)) {
|
|
74
87
|
node.status({
|
|
@@ -108,6 +121,13 @@ module.exports = function (RED) {
|
|
|
108
121
|
|
|
109
122
|
this.on('input', async function (msg) {
|
|
110
123
|
if (msg.payload) {
|
|
124
|
+
node.messagesReceived++;
|
|
125
|
+
node.status({
|
|
126
|
+
fill: 'green',
|
|
127
|
+
shape: 'ring',
|
|
128
|
+
text: 'Messages ' + node.messagesReceived,
|
|
129
|
+
});
|
|
130
|
+
|
|
111
131
|
try {
|
|
112
132
|
let data = msg.payload;
|
|
113
133
|
if (Array.isArray(data)) {
|
|
@@ -115,8 +135,11 @@ module.exports = function (RED) {
|
|
|
115
135
|
}
|
|
116
136
|
else {
|
|
117
137
|
client.write(data);
|
|
118
|
-
}
|
|
119
138
|
|
|
139
|
+
if(node.passthrough) {
|
|
140
|
+
node.send(msg);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
120
143
|
} catch (error) {
|
|
121
144
|
node.status({ fill: 'red', shape: 'ring', text: error });
|
|
122
145
|
node.error('Failed to write data: ' + error, error);
|