-
Notifications
You must be signed in to change notification settings - Fork 1
/
discoverSonyDevice.ts
65 lines (63 loc) · 1.71 KB
/
discoverSonyDevice.ts
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
import dgram from "dgram";
const SONY_API = "schemas-sony-com:service:ScalarWebAPI:1",
SSDP_ADDRESS = "239.255.255.250",
SSDP_PORT = 1900;
/**
* Discover Sony devices supporting SSDP.
*
* @returns UPnP Device Description location (url; e.g., http://192.168.122.1:64321/dd.xml)
* @see {@link https://developer.sony.com/develop/audio-control-api/hardware-overview/discovery-process}
*/
export async function discoverSonyDevice(timeout?: number): Promise<string> {
if (!timeout || timeout < 0) {
timeout = 2000;
}
return new Promise<string>(function (resolve, reject) {
try {
const mSearchMessage = Buffer.from(
"M-SEARCH * HTTP/1.1\r\n" +
`HOST:${SSDP_ADDRESS}:${SSDP_PORT}\r\n` +
'MAN:"ssdp:discover"\r\n' +
"MX:1\r\n" +
`ST:urn:${SONY_API}\r\n` +
"\r\n"
);
const client = dgram.createSocket("udp4");
let resolved = false;
client.on("message", (message) => {
if (resolved) {
return;
}
const location = /LOCATION: (.*)/.exec(message.toString())[1];
client.close();
resolved = true;
resolve(location);
});
client.on("error", (err) => {
if (resolved) {
return;
}
client.close();
resolved = true;
reject(err);
});
client.send(
mSearchMessage,
0,
mSearchMessage.length,
SSDP_PORT,
SSDP_ADDRESS
);
setTimeout(() => {
if (resolved) {
return;
}
client.removeAllListeners();
resolved = true;
reject(new Error("Service discovery timeout"));
}, timeout);
} catch (error) {
reject(error);
}
});
}