-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathdiscovery.js
113 lines (89 loc) · 2.96 KB
/
discovery.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
'use strict';
const EventEmitter = require('events');
const dgram = require('dgram');
const os = require('os');
const net = require('net');
class Discovery extends EventEmitter {
constructor(hubManager, homey) {
super();
this.homey = homey;
this._hubManager = hubManager;
this.LISTENER_PORT = 5446;
this.MULTICAST_ADDR = '255.255.255.255';
this.MULTICAST_PORT = 5224;
this.PING_INTERVAL = 2000;
this.Listener = this._getListener();
this._getBroadcastSocket();
}
_getBroadcastSocket() {
const socket = dgram.createSocket('udp4');
socket.on('error', (err) => {
console.log(`discovery.js: Socket error ${err}`);
socket.close();
});
socket.on('listening', () => {
socket.setBroadcast(true);
this.homey.setInterval(() => {
const data = '_logitech-reverse-bonjour._tcp.local.\r\n' +
this.LISTENER_PORT + '\r\n' +
this._getLocalIp() + '\r\n' +
'string';
const search = Buffer.from(data, 'ascii')
try {
socket.send(search, 0, search.length, this.MULTICAST_PORT, this.MULTICAST_ADDR);
} catch (ex) {
console.log(ex);
}
}, this.PING_INTERVAL);
});
socket.bind();
}
_getListener() {
const server = net.createServer(client => {
let buffer = '';
client.on('error', err => {
console.log(`discovery.js error: ${err}`);
});
client.on('data', (data) => {
buffer += data.toString();
});
client.on('end', () => {
const hubInfo = this._deserializeHubInfo(buffer);
if (hubInfo.ip !== undefined) {
this._hubManager.addHub(hubInfo);
this.emit('hubconnected', hubInfo);
}
});
client.pipe(client);
});
server.on('error', (err) => {
console.log(err);
throw err;
});
server.listen(this.LISTENER_PORT, () => {
console.log('server bound');
});
return server;
}
_deserializeHubInfo(response) {
const pairs = {}
response.split(';')
.forEach(function(rawPair) {
const splitted = rawPair.split(':')
pairs[splitted[0]] = splitted[1]
})
return pairs
}
_getLocalIp() {
const ifaces = os.networkInterfaces();
let address = '0.0.0.0';
Object.keys(ifaces).forEach(function(ifname) {
ifaces[ifname].forEach(function(iface) {
if (iface.family === 'IPv4' && iface.internal === false)
address = iface.address;
});
});
return address;
}
}
module.exports = Discovery;