forked from langovoi/homebridge-upnp
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathUPnPPlatform.js
124 lines (95 loc) · 3.11 KB
/
UPnPPlatform.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
114
115
116
117
118
119
120
121
122
123
124
const Client = require('node-ssdp').Client;
const Server = require('node-ssdp').Server;
class UPnPPlatform {
constructor(log, config, api) {
this.log = log;
this._client = new Client({
...config.ssdpClient,
customLogger: this.log.debug.bind(this.log)
});
this._server = new Server({
...config.ssdpServer,
customLogger: this.log.debug.bind(this.log)
});
this._devices = [];
this._STToDevice = {
'urn:schemas-upnp-org:device:MediaRenderer:1': require('./MediaRenderer1')
};
if (api) {
this.api = api;
this.api.on('didFinishLaunching', () => {
this._start()
});
this.api.on('shutdown', () => {
this._shutdown();
})
}
}
configureAccessory(accessory) {
const Device = this._STToDevice[accessory.context.ST];
if (Device) {
const device = new Device(this, accessory.context.USN, accessory);
this.addDevice(device);
} else {
this.removeAccessory(accessory)
}
}
_start() {
this._client.on('response', (headers) => {
const Device = this._STToDevice[headers.ST];
if(!Device) {
return;
}
let device = this._devices.find(device => device.USN === headers.USN);
if(!device) {
device = new Device(this, headers.USN);
}
device.setLocation(headers.LOCATION);
});
this._server.on('advertise-alive', (headers) => {
const Device = this._STToDevice[headers.NT];
if (!Device) {
return;
}
let device = this._devices.find(device => device.USN === headers.USN);
if(!device) {
device = new Device(this, headers.USN);
}
if(device.hasLocation()) {
device.onAlive();
} else {
device.setLocation(headers.LOCATION);
}
});
this._server.on('advertise-bye', (headers) => {
const Device = this._STToDevice[headers.NT];
if (!Device) {
return;
}
const device = this._devices.find(device => device.USN === headers.USN);
if(device) {
device.onBye();
}
});
this._client.search('ssdp:all');
this._server.start();
}
addAccessory(accessory) {
this.api.registerPlatformAccessories(require('./package.json').name, 'UPnP', [accessory]);
}
removeAccessory(accessory) {
this.api.unregisterPlatformAccessories(require('./package.json').name, 'UPnP', [accessory]);
}
addDevice(device) {
this.log('Add device', device.accessory.displayName);
this._devices.push(device);
}
_shutdown() {
this._client.stop();
this._server.stop();
for(const device of this._devices) {
device.stop();
}
}
}
module.exports = UPnPPlatform;