-
Notifications
You must be signed in to change notification settings - Fork 2
/
udp.js
99 lines (78 loc) · 3.15 KB
/
udp.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
const PORT = 49000;
const HOST = '127.0.0.1';
const FREQ = 2;
const dgram = require('dgram');
const client = dgram.createSocket('udp4');
const createMessage = (dref, idx, freq) => {
// A dataref request should be 413 bytes long
// {
// label: null terminated 4 chars (5 bytes), e.g. "RREF\0"
// frequency: int (4 bytes)
// index: int (4 bytes)
// name. char (400 bytes)
// }
const message = Buffer.alloc(413);
// Label that tells X Plane that we are asking for datarefs
message.write('RREF\0');
// Frequency that we want X Plane to send the data (timer per sedond)
message.writeInt8(freq, 5);
// Index: X Plane will respond with this index to let you know what message it is responding to
message.writeInt8(idx, 9);
// This is the dataref you are asking for
message.write(dref, 13);
return message;
};
const messages = [
// 'sim/name/of/dataref', index, frequency'
createMessage('sim/flightmodel/position/latitude', 1, FREQ),
createMessage('sim/flightmodel/position/longitude', 1, FREQ),
createMessage('sim/flightmodel/position/mag_psi', 1, FREQ),
// Add as many as you like (within X Plane's recommended limitation)
];
client.on('listening', () => {
const address = client.address();
console.log(`UDP client listening on ${address.address}:${address.port}`);
});
client.on('message', (message, remote) => {
// Message structure received from X Plane:
// {
// label: 4 bytes,
// 1 byte (for internal use by X Plane)
// index: 4 bytes
// value: float - 8 bytes x n
// }
// Read the first 4 bytes. This is the label that x-plane responds with to indicate
// what type of data you are receiving. In our case, this should be "RREF". If it is
// not, ignore the message.
// The next byte (offset 4) is used by x plane, and not of interest
// The index (at offset 5) is the index that you specified in the message. To specify
// which request X Plane is responding to
// The values starts at offset 9. 8 bytes per value. Values will appear in the same order
// as the requested values
const label = message.toString('utf8', 0, 4);
if (label !== 'RREF') {
console.log('Unknown package. Ignoring');
} else {
let offset = 9;
let messages = [];
// RREFs values are floats. They occupy 8 bytes. One message can contain several values,
// depending on how many you asked for. Read every value by iterating over message and
// increasing the offset by 8.
while (offset < message.length) {
const value = message.readFloatLE(offset);
messages.push(value);
console.log('Decoded message: ' + value);
offset += 8;
}
// Do something with the values (e.g. emit them over socket.io to a client, or whatever)
}
});
for (let i = 0; i < messages.length; i++) {
client.send(messages[i], 0, messages[i].length, PORT, HOST, (err, bytes) => {
if (err) {
console.log('Error', err)
} else {
console.log(`UDP message sent to ${HOST}:${PORT}`);
}
});
}