hap-nodejs 1.1.1-beta.5 → 1.1.1-beta.7
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/@types/bonjour-hap.d.ts +53 -50
- package/@types/simple-plist.d.ts +4 -0
- package/README.md +19 -16
- package/dist/accessories/AirConditioner_accessory.js +32 -30
- package/dist/accessories/AirConditioner_accessory.js.map +1 -1
- package/dist/accessories/AppleTVRemote_accessory.js +86 -74
- package/dist/accessories/AppleTVRemote_accessory.js.map +1 -1
- package/dist/accessories/Camera_accessory.js +138 -143
- package/dist/accessories/Camera_accessory.js.map +1 -1
- package/dist/accessories/Fan_accessory.js +24 -20
- package/dist/accessories/Fan_accessory.js.map +1 -1
- package/dist/accessories/GarageDoorOpener_accessory.js +37 -35
- package/dist/accessories/GarageDoorOpener_accessory.js.map +1 -1
- package/dist/accessories/Light-AdaptiveLighting_accessory.js +46 -44
- package/dist/accessories/Light-AdaptiveLighting_accessory.js.map +1 -1
- package/dist/accessories/Light_accessory.js +36 -34
- package/dist/accessories/Light_accessory.js.map +1 -1
- package/dist/accessories/Lock_accessory.js +28 -27
- package/dist/accessories/Lock_accessory.js.map +1 -1
- package/dist/accessories/MotionSensor_accessory.js +18 -15
- package/dist/accessories/MotionSensor_accessory.js.map +1 -1
- package/dist/accessories/Outlet_accessory.js +24 -22
- package/dist/accessories/Outlet_accessory.js.map +1 -1
- package/dist/accessories/SmartSpeaker_accessory.js +22 -20
- package/dist/accessories/SmartSpeaker_accessory.js.map +1 -1
- package/dist/accessories/Sprinkler_accessory.js +39 -36
- package/dist/accessories/Sprinkler_accessory.js.map +1 -1
- package/dist/accessories/TV_accessory.js +47 -45
- package/dist/accessories/TV_accessory.js.map +1 -1
- package/dist/accessories/TemperatureSensor_accessory.js +17 -14
- package/dist/accessories/TemperatureSensor_accessory.js.map +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.d.ts +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.d.ts.map +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.js +14 -11
- package/dist/accessories/Wi-FiRouter_accessory.js.map +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.d.ts +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.d.ts.map +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.js +16 -13
- package/dist/accessories/Wi-FiSatellite_accessory.js.map +1 -1
- package/dist/accessories/gstreamer-audioProducer.d.ts +3 -3
- package/dist/accessories/gstreamer-audioProducer.d.ts.map +1 -1
- package/dist/accessories/gstreamer-audioProducer.js +39 -38
- package/dist/accessories/gstreamer-audioProducer.js.map +1 -1
- package/dist/accessories/types.d.ts +63 -63
- package/dist/accessories/types.d.ts.map +1 -1
- package/dist/accessories/types.js +87 -83
- package/dist/accessories/types.js.map +1 -1
- package/dist/index.d.ts +28 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -40
- package/dist/index.js.map +1 -1
- package/dist/internal-types.d.ts +1 -1
- package/dist/internal-types.d.ts.map +1 -1
- package/dist/internal-types.js +21 -19
- package/dist/internal-types.js.map +1 -1
- package/dist/lib/Accessory.d.ts +37 -38
- package/dist/lib/Accessory.d.ts.map +1 -1
- package/dist/lib/Accessory.js +299 -289
- package/dist/lib/Accessory.js.map +1 -1
- package/dist/lib/Advertiser.d.ts +7 -7
- package/dist/lib/Advertiser.d.ts.map +1 -1
- package/dist/lib/Advertiser.js +136 -128
- package/dist/lib/Advertiser.js.map +1 -1
- package/dist/lib/Bridge.d.ts +1 -1
- package/dist/lib/Bridge.d.ts.map +1 -1
- package/dist/lib/Bridge.js +6 -2
- package/dist/lib/Bridge.js.map +1 -1
- package/dist/lib/Characteristic.d.ts +41 -40
- package/dist/lib/Characteristic.d.ts.map +1 -1
- package/dist/lib/Characteristic.js +210 -206
- package/dist/lib/Characteristic.js.map +1 -1
- package/dist/lib/HAPServer.d.ts +30 -35
- package/dist/lib/HAPServer.d.ts.map +1 -1
- package/dist/lib/HAPServer.js +229 -225
- package/dist/lib/HAPServer.js.map +1 -1
- package/dist/lib/Service.d.ts +22 -22
- package/dist/lib/Service.d.ts.map +1 -1
- package/dist/lib/Service.js +71 -67
- package/dist/lib/Service.js.map +1 -1
- package/dist/lib/camera/RTPProxy.d.ts +1 -2
- package/dist/lib/camera/RTPProxy.d.ts.map +1 -1
- package/dist/lib/camera/RTPProxy.js +44 -28
- package/dist/lib/camera/RTPProxy.js.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.d.ts +33 -34
- package/dist/lib/camera/RTPStreamManagement.d.ts.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.js +149 -181
- package/dist/lib/camera/RTPStreamManagement.js.map +1 -1
- package/dist/lib/camera/RecordingManagement.d.ts +17 -19
- package/dist/lib/camera/RecordingManagement.d.ts.map +1 -1
- package/dist/lib/camera/RecordingManagement.js +153 -162
- package/dist/lib/camera/RecordingManagement.js.map +1 -1
- package/dist/lib/camera/index.d.ts +3 -3
- package/dist/lib/camera/index.d.ts.map +1 -1
- package/dist/lib/camera/index.js +6 -3
- package/dist/lib/camera/index.js.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.d.ts +33 -33
- package/dist/lib/controller/AdaptiveLightingController.d.ts.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.js +146 -154
- package/dist/lib/controller/AdaptiveLightingController.js.map +1 -1
- package/dist/lib/controller/CameraController.d.ts +20 -22
- package/dist/lib/controller/CameraController.d.ts.map +1 -1
- package/dist/lib/controller/CameraController.js +78 -74
- package/dist/lib/controller/CameraController.js.map +1 -1
- package/dist/lib/controller/Controller.d.ts +4 -4
- package/dist/lib/controller/Controller.d.ts.map +1 -1
- package/dist/lib/controller/Controller.js +8 -5
- package/dist/lib/controller/Controller.js.map +1 -1
- package/dist/lib/controller/DoorbellController.d.ts +4 -5
- package/dist/lib/controller/DoorbellController.d.ts.map +1 -1
- package/dist/lib/controller/DoorbellController.js +13 -9
- package/dist/lib/controller/DoorbellController.js.map +1 -1
- package/dist/lib/controller/RemoteController.d.ts +37 -39
- package/dist/lib/controller/RemoteController.d.ts.map +1 -1
- package/dist/lib/controller/RemoteController.js +199 -210
- package/dist/lib/controller/RemoteController.js.map +1 -1
- package/dist/lib/controller/index.d.ts +5 -5
- package/dist/lib/controller/index.d.ts.map +1 -1
- package/dist/lib/controller/index.js +8 -5
- package/dist/lib/controller/index.js.map +1 -1
- package/dist/lib/datastream/DataStreamManagement.d.ts +2 -2
- package/dist/lib/datastream/DataStreamManagement.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamManagement.js +40 -40
- package/dist/lib/datastream/DataStreamManagement.js.map +1 -1
- package/dist/lib/datastream/DataStreamParser.d.ts +0 -1
- package/dist/lib/datastream/DataStreamParser.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamParser.js +77 -57
- package/dist/lib/datastream/DataStreamParser.js.map +1 -1
- package/dist/lib/datastream/DataStreamServer.d.ts +22 -27
- package/dist/lib/datastream/DataStreamServer.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamServer.js +164 -159
- package/dist/lib/datastream/DataStreamServer.js.map +1 -1
- package/dist/lib/datastream/index.d.ts +3 -3
- package/dist/lib/datastream/index.d.ts.map +1 -1
- package/dist/lib/datastream/index.js +6 -3
- package/dist/lib/datastream/index.js.map +1 -1
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts +1 -1
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/CharacteristicDefinitions.js +1203 -957
- package/dist/lib/definitions/CharacteristicDefinitions.js.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.d.ts +1 -1
- package/dist/lib/definitions/ServiceDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.js +695 -620
- package/dist/lib/definitions/ServiceDefinitions.js.map +1 -1
- package/dist/lib/definitions/generate-definitions.d.ts +3 -3
- package/dist/lib/definitions/generate-definitions.d.ts.map +1 -1
- package/dist/lib/definitions/generate-definitions.js +259 -247
- package/dist/lib/definitions/generate-definitions.js.map +1 -1
- package/dist/lib/definitions/generator-configuration.d.ts +1 -1
- package/dist/lib/definitions/generator-configuration.d.ts.map +1 -1
- package/dist/lib/definitions/generator-configuration.js +181 -176
- package/dist/lib/definitions/generator-configuration.js.map +1 -1
- package/dist/lib/definitions/index.d.ts +2 -2
- package/dist/lib/definitions/index.d.ts.map +1 -1
- package/dist/lib/definitions/index.js +5 -2
- package/dist/lib/definitions/index.js.map +1 -1
- package/dist/lib/gen/HomeKit.d.ts +7 -0
- package/dist/lib/gen/HomeKit.d.ts.map +1 -0
- package/dist/lib/gen/HomeKit.js +8 -0
- package/dist/lib/gen/HomeKit.js.map +1 -0
- package/dist/lib/model/AccessoryInfo.d.ts +3 -4
- package/dist/lib/model/AccessoryInfo.d.ts.map +1 -1
- package/dist/lib/model/AccessoryInfo.js +55 -52
- package/dist/lib/model/AccessoryInfo.js.map +1 -1
- package/dist/lib/model/ControllerStorage.d.ts +3 -3
- package/dist/lib/model/ControllerStorage.d.ts.map +1 -1
- package/dist/lib/model/ControllerStorage.js +23 -18
- package/dist/lib/model/ControllerStorage.js.map +1 -1
- package/dist/lib/model/HAPStorage.d.ts +2 -2
- package/dist/lib/model/HAPStorage.d.ts.map +1 -1
- package/dist/lib/model/HAPStorage.js +11 -4
- package/dist/lib/model/HAPStorage.js.map +1 -1
- package/dist/lib/model/IdentifierCache.d.ts +1 -1
- package/dist/lib/model/IdentifierCache.d.ts.map +1 -1
- package/dist/lib/model/IdentifierCache.js +27 -19
- package/dist/lib/model/IdentifierCache.js.map +1 -1
- package/dist/lib/tv/AccessControlManagement.d.ts +9 -9
- package/dist/lib/tv/AccessControlManagement.d.ts.map +1 -1
- package/dist/lib/tv/AccessControlManagement.js +29 -27
- package/dist/lib/tv/AccessControlManagement.js.map +1 -1
- package/dist/lib/util/checkName.d.ts +2 -2
- package/dist/lib/util/checkName.d.ts.map +1 -1
- package/dist/lib/util/checkName.js +9 -6
- package/dist/lib/util/checkName.js.map +1 -1
- package/dist/lib/util/clone.d.ts.map +1 -1
- package/dist/lib/util/clone.js +5 -1
- package/dist/lib/util/clone.js.map +1 -1
- package/dist/lib/util/color-utils.d.ts +1 -1
- package/dist/lib/util/color-utils.d.ts.map +1 -1
- package/dist/lib/util/color-utils.js +9 -4
- package/dist/lib/util/color-utils.js.map +1 -1
- package/dist/lib/util/eventedhttp.d.ts +22 -23
- package/dist/lib/util/eventedhttp.d.ts.map +1 -1
- package/dist/lib/util/eventedhttp.js +116 -109
- package/dist/lib/util/eventedhttp.js.map +1 -1
- package/dist/lib/util/hapCrypto.d.ts +2 -3
- package/dist/lib/util/hapCrypto.d.ts.map +1 -1
- package/dist/lib/util/hapCrypto.js +40 -31
- package/dist/lib/util/hapCrypto.js.map +1 -1
- package/dist/lib/util/hapStatusError.d.ts +1 -1
- package/dist/lib/util/hapStatusError.d.ts.map +1 -1
- package/dist/lib/util/hapStatusError.js +8 -4
- package/dist/lib/util/hapStatusError.js.map +1 -1
- package/dist/lib/util/net-utils.d.ts +1 -1
- package/dist/lib/util/net-utils.js +23 -17
- package/dist/lib/util/net-utils.js.map +1 -1
- package/dist/lib/util/once.d.ts.map +1 -1
- package/dist/lib/util/once.js +6 -2
- package/dist/lib/util/once.js.map +1 -1
- package/dist/lib/util/promise-utils.d.ts +1 -1
- package/dist/lib/util/promise-utils.d.ts.map +1 -1
- package/dist/lib/util/promise-utils.js +10 -3
- package/dist/lib/util/promise-utils.js.map +1 -1
- package/dist/lib/util/request-util.d.ts +2 -3
- package/dist/lib/util/request-util.d.ts.map +1 -1
- package/dist/lib/util/request-util.js +19 -11
- package/dist/lib/util/request-util.js.map +1 -1
- package/dist/lib/util/time.d.ts +0 -1
- package/dist/lib/util/time.d.ts.map +1 -1
- package/dist/lib/util/time.js +11 -6
- package/dist/lib/util/time.js.map +1 -1
- package/dist/lib/util/tlv.d.ts +0 -1
- package/dist/lib/util/tlv.d.ts.map +1 -1
- package/dist/lib/util/tlv.js +43 -28
- package/dist/lib/util/tlv.js.map +1 -1
- package/dist/lib/util/uuid.d.ts +0 -1
- package/dist/lib/util/uuid.d.ts.map +1 -1
- package/dist/lib/util/uuid.js +38 -26
- package/dist/lib/util/uuid.js.map +1 -1
- package/dist/types.d.ts +24 -24
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +5 -3
- package/dist/types.js.map +1 -1
- package/package.json +47 -52
- package/dist/lib/dbus/align.d.ts +0 -2
- package/dist/lib/dbus/align.d.ts.map +0 -1
- package/dist/lib/dbus/align.js +0 -12
- package/dist/lib/dbus/align.js.map +0 -1
- package/dist/lib/dbus/bus.d.ts +0 -38
- package/dist/lib/dbus/bus.d.ts.map +0 -1
- package/dist/lib/dbus/bus.js +0 -222
- package/dist/lib/dbus/bus.js.map +0 -1
- package/dist/lib/dbus/constants.d.ts +0 -43
- package/dist/lib/dbus/constants.d.ts.map +0 -1
- package/dist/lib/dbus/constants.js +0 -53
- package/dist/lib/dbus/constants.js.map +0 -1
- package/dist/lib/dbus/dbus-buffer.d.ts +0 -30
- package/dist/lib/dbus/dbus-buffer.d.ts.map +0 -1
- package/dist/lib/dbus/dbus-buffer.js +0 -175
- package/dist/lib/dbus/dbus-buffer.js.map +0 -1
- package/dist/lib/dbus/handshake.d.ts +0 -2
- package/dist/lib/dbus/handshake.d.ts.map +0 -1
- package/dist/lib/dbus/handshake.js +0 -130
- package/dist/lib/dbus/handshake.js.map +0 -1
- package/dist/lib/dbus/index.d.ts +0 -3
- package/dist/lib/dbus/index.d.ts.map +0 -1
- package/dist/lib/dbus/index.js +0 -123
- package/dist/lib/dbus/index.js.map +0 -1
- package/dist/lib/dbus/introspect.d.ts +0 -30
- package/dist/lib/dbus/introspect.d.ts.map +0 -1
- package/dist/lib/dbus/introspect.js +0 -208
- package/dist/lib/dbus/introspect.js.map +0 -1
- package/dist/lib/dbus/marshall.d.ts +0 -2
- package/dist/lib/dbus/marshall.d.ts.map +0 -1
- package/dist/lib/dbus/marshall.js +0 -97
- package/dist/lib/dbus/marshall.js.map +0 -1
- package/dist/lib/dbus/marshallers.d.ts +0 -10
- package/dist/lib/dbus/marshallers.d.ts.map +0 -1
- package/dist/lib/dbus/marshallers.js +0 -329
- package/dist/lib/dbus/marshallers.js.map +0 -1
- package/dist/lib/dbus/message.d.ts +0 -4
- package/dist/lib/dbus/message.d.ts.map +0 -1
- package/dist/lib/dbus/message.js +0 -116
- package/dist/lib/dbus/message.js.map +0 -1
- package/dist/lib/dbus/put.d.ts +0 -21
- package/dist/lib/dbus/put.d.ts.map +0 -1
- package/dist/lib/dbus/put.js +0 -120
- package/dist/lib/dbus/put.js.map +0 -1
- package/dist/lib/dbus/readline.d.ts +0 -2
- package/dist/lib/dbus/readline.d.ts.map +0 -1
- package/dist/lib/dbus/readline.js +0 -27
- package/dist/lib/dbus/readline.js.map +0 -1
- package/dist/lib/dbus/signature.d.ts +0 -2
- package/dist/lib/dbus/signature.d.ts.map +0 -1
- package/dist/lib/dbus/signature.js +0 -59
- package/dist/lib/dbus/signature.js.map +0 -1
- package/dist/lib/dbus/stdifaces.d.ts +0 -3
- package/dist/lib/dbus/stdifaces.d.ts.map +0 -1
- package/dist/lib/dbus/stdifaces.js +0 -206
- package/dist/lib/dbus/stdifaces.js.map +0 -1
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DataStreamConnection = exports.HDSConnectionError = exports.HDSConnectionErrorType = exports.DataStreamConnectionEvent = exports.DataStreamServer = exports.DataStreamServerEvent = exports.MessageType = exports.HDSProtocolError = exports.HDSProtocolSpecificErrorReason = exports.HDSStatus = exports.Topics = exports.Protocols = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
const crypto_1 = tslib_1.__importDefault(require("crypto"));
|
|
7
|
+
const debug_1 = tslib_1.__importDefault(require("debug"));
|
|
8
|
+
const events_1 = require("events");
|
|
9
|
+
const net_1 = tslib_1.__importDefault(require("net"));
|
|
10
|
+
const hapCrypto = tslib_1.__importStar(require("../util/hapCrypto"));
|
|
11
|
+
const DataStreamParser_1 = require("./DataStreamParser");
|
|
12
|
+
const debug = (0, debug_1.default)("HAP-NodeJS:DataStream:Server");
|
|
10
13
|
/**
|
|
11
14
|
* @group HomeKit Data Streams (HDS)
|
|
12
15
|
*/
|
|
13
|
-
|
|
14
|
-
export var Protocols;
|
|
16
|
+
var Protocols;
|
|
15
17
|
(function (Protocols) {
|
|
16
18
|
Protocols["CONTROL"] = "control";
|
|
17
19
|
Protocols["TARGET_CONTROL"] = "targetControl";
|
|
18
20
|
Protocols["DATA_SEND"] = "dataSend";
|
|
19
|
-
})(Protocols || (Protocols = {}));
|
|
21
|
+
})(Protocols || (exports.Protocols = Protocols = {}));
|
|
20
22
|
/**
|
|
21
23
|
* @group HomeKit Data Streams (HDS)
|
|
22
24
|
*/
|
|
23
|
-
|
|
24
|
-
export var Topics;
|
|
25
|
+
var Topics;
|
|
25
26
|
(function (Topics) {
|
|
26
27
|
// control
|
|
27
28
|
Topics["HELLO"] = "hello";
|
|
@@ -32,12 +33,13 @@ export var Topics;
|
|
|
32
33
|
Topics["DATA"] = "data";
|
|
33
34
|
Topics["ACK"] = "ack";
|
|
34
35
|
Topics["CLOSE"] = "close";
|
|
35
|
-
})(Topics || (Topics = {}));
|
|
36
|
+
})(Topics || (exports.Topics = Topics = {}));
|
|
36
37
|
/**
|
|
37
38
|
* @group HomeKit Data Streams (HDS)
|
|
38
39
|
*/
|
|
39
|
-
|
|
40
|
+
var HDSStatus;
|
|
40
41
|
(function (HDSStatus) {
|
|
42
|
+
// noinspection JSUnusedGlobalSymbols
|
|
41
43
|
HDSStatus[HDSStatus["SUCCESS"] = 0] = "SUCCESS";
|
|
42
44
|
HDSStatus[HDSStatus["OUT_OF_MEMORY"] = 1] = "OUT_OF_MEMORY";
|
|
43
45
|
HDSStatus[HDSStatus["TIMEOUT"] = 2] = "TIMEOUT";
|
|
@@ -45,13 +47,13 @@ export var HDSStatus;
|
|
|
45
47
|
HDSStatus[HDSStatus["PAYLOAD_ERROR"] = 4] = "PAYLOAD_ERROR";
|
|
46
48
|
HDSStatus[HDSStatus["MISSING_PROTOCOL"] = 5] = "MISSING_PROTOCOL";
|
|
47
49
|
HDSStatus[HDSStatus["PROTOCOL_SPECIFIC_ERROR"] = 6] = "PROTOCOL_SPECIFIC_ERROR";
|
|
48
|
-
})(HDSStatus || (HDSStatus = {}));
|
|
50
|
+
})(HDSStatus || (exports.HDSStatus = HDSStatus = {}));
|
|
49
51
|
/**
|
|
50
52
|
* @group HomeKit Data Streams (HDS)
|
|
51
53
|
*/
|
|
52
|
-
|
|
53
|
-
export var HDSProtocolSpecificErrorReason;
|
|
54
|
+
var HDSProtocolSpecificErrorReason;
|
|
54
55
|
(function (HDSProtocolSpecificErrorReason) {
|
|
56
|
+
// noinspection JSUnusedGlobalSymbols
|
|
55
57
|
HDSProtocolSpecificErrorReason[HDSProtocolSpecificErrorReason["NORMAL"] = 0] = "NORMAL";
|
|
56
58
|
HDSProtocolSpecificErrorReason[HDSProtocolSpecificErrorReason["NOT_ALLOWED"] = 1] = "NOT_ALLOWED";
|
|
57
59
|
HDSProtocolSpecificErrorReason[HDSProtocolSpecificErrorReason["BUSY"] = 2] = "BUSY";
|
|
@@ -62,31 +64,26 @@ export var HDSProtocolSpecificErrorReason;
|
|
|
62
64
|
HDSProtocolSpecificErrorReason[HDSProtocolSpecificErrorReason["BAD_DATA"] = 7] = "BAD_DATA";
|
|
63
65
|
HDSProtocolSpecificErrorReason[HDSProtocolSpecificErrorReason["PROTOCOL_ERROR"] = 8] = "PROTOCOL_ERROR";
|
|
64
66
|
HDSProtocolSpecificErrorReason[HDSProtocolSpecificErrorReason["INVALID_CONFIGURATION"] = 9] = "INVALID_CONFIGURATION";
|
|
65
|
-
})(HDSProtocolSpecificErrorReason || (HDSProtocolSpecificErrorReason = {}));
|
|
66
|
-
/**
|
|
67
|
-
* @hidden
|
|
68
|
-
*/
|
|
69
|
-
// @ts-expect-error - workaround for import issues in the compiled output, when accessing values using a variable key
|
|
70
|
-
export const HDSProtocolSpecificErrorReasonConst = HDSProtocolSpecificErrorReason;
|
|
67
|
+
})(HDSProtocolSpecificErrorReason || (exports.HDSProtocolSpecificErrorReason = HDSProtocolSpecificErrorReason = {}));
|
|
71
68
|
/**
|
|
72
69
|
* An error indicating a protocol level HDS error.
|
|
73
70
|
* E.g. it may be used to encode a {@link HDSStatus.PROTOCOL_SPECIFIC_ERROR} in the {@link Protocols.DATA_SEND} protocol.
|
|
74
71
|
* @group HomeKit Data Streams (HDS)
|
|
75
72
|
*/
|
|
76
|
-
|
|
73
|
+
class HDSProtocolError extends Error {
|
|
77
74
|
reason;
|
|
78
75
|
/**
|
|
79
76
|
* Initializes a new `HDSProtocolError`
|
|
80
77
|
* @param reason - The {@link HDSProtocolSpecificErrorReason}.
|
|
81
|
-
*
|
|
78
|
+
* Values MUST NOT be {@link HDSProtocolSpecificErrorReason.NORMAL}.
|
|
82
79
|
*/
|
|
83
80
|
constructor(reason) {
|
|
84
|
-
super(
|
|
85
|
-
|
|
81
|
+
super("HDSProtocolError: " + reason);
|
|
82
|
+
(0, assert_1.default)(reason !== 0 /* HDSProtocolSpecificErrorReason.NORMAL */, "Cannot initialize a HDSProtocolError with NORMAL!");
|
|
86
83
|
this.reason = reason;
|
|
87
84
|
}
|
|
88
85
|
}
|
|
89
|
-
|
|
86
|
+
exports.HDSProtocolError = HDSProtocolError;
|
|
90
87
|
var ServerState;
|
|
91
88
|
(function (ServerState) {
|
|
92
89
|
ServerState[ServerState["UNINITIALIZED"] = 0] = "UNINITIALIZED";
|
|
@@ -94,7 +91,6 @@ var ServerState;
|
|
|
94
91
|
ServerState[ServerState["LISTENING"] = 2] = "LISTENING";
|
|
95
92
|
ServerState[ServerState["CLOSING"] = 3] = "CLOSING";
|
|
96
93
|
})(ServerState || (ServerState = {}));
|
|
97
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
98
94
|
var ConnectionState;
|
|
99
95
|
(function (ConnectionState) {
|
|
100
96
|
ConnectionState[ConnectionState["UNIDENTIFIED"] = 0] = "UNIDENTIFIED";
|
|
@@ -106,18 +102,16 @@ var ConnectionState;
|
|
|
106
102
|
/**
|
|
107
103
|
* @group HomeKit Data Streams (HDS)
|
|
108
104
|
*/
|
|
109
|
-
|
|
110
|
-
export var MessageType;
|
|
105
|
+
var MessageType;
|
|
111
106
|
(function (MessageType) {
|
|
112
107
|
MessageType[MessageType["EVENT"] = 1] = "EVENT";
|
|
113
108
|
MessageType[MessageType["REQUEST"] = 2] = "REQUEST";
|
|
114
109
|
MessageType[MessageType["RESPONSE"] = 3] = "RESPONSE";
|
|
115
|
-
})(MessageType || (MessageType = {}));
|
|
110
|
+
})(MessageType || (exports.MessageType = MessageType = {}));
|
|
116
111
|
/**
|
|
117
112
|
* @group HomeKit Data Streams (HDS)
|
|
118
113
|
*/
|
|
119
|
-
|
|
120
|
-
export var DataStreamServerEvent;
|
|
114
|
+
var DataStreamServerEvent;
|
|
121
115
|
(function (DataStreamServerEvent) {
|
|
122
116
|
/**
|
|
123
117
|
* This event is emitted when a new client socket is received. At this point we have no idea to what
|
|
@@ -128,23 +122,23 @@ export var DataStreamServerEvent;
|
|
|
128
122
|
* This event is emitted when the socket of a connection gets closed.
|
|
129
123
|
*/
|
|
130
124
|
DataStreamServerEvent["CONNECTION_CLOSED"] = "connection-closed";
|
|
131
|
-
})(DataStreamServerEvent || (DataStreamServerEvent = {}));
|
|
125
|
+
})(DataStreamServerEvent || (exports.DataStreamServerEvent = DataStreamServerEvent = {}));
|
|
132
126
|
/**
|
|
133
127
|
* DataStreamServer which listens for incoming tcp connections and handles identification of new connections
|
|
134
128
|
* @group HomeKit Data Streams (HDS)
|
|
135
129
|
*/
|
|
136
|
-
// eslint-disable-next-line
|
|
137
|
-
|
|
138
|
-
static version =
|
|
130
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
131
|
+
class DataStreamServer extends events_1.EventEmitter {
|
|
132
|
+
static version = "1.0";
|
|
139
133
|
state = 0 /* ServerState.UNINITIALIZED */;
|
|
140
|
-
static accessoryToControllerInfo = Buffer.from(
|
|
141
|
-
static controllerToAccessoryInfo = Buffer.from(
|
|
134
|
+
static accessoryToControllerInfo = Buffer.from("HDS-Read-Encryption-Key");
|
|
135
|
+
static controllerToAccessoryInfo = Buffer.from("HDS-Write-Encryption-Key");
|
|
142
136
|
tcpServer;
|
|
143
137
|
tcpPort;
|
|
144
138
|
preparedSessions = [];
|
|
145
139
|
connections = [];
|
|
146
140
|
removeListenersOnceClosed = false;
|
|
147
|
-
internalEventEmitter = new
|
|
141
|
+
internalEventEmitter = new events_1.EventEmitter(); // used for message event and message request handlers
|
|
148
142
|
constructor() {
|
|
149
143
|
super();
|
|
150
144
|
}
|
|
@@ -158,7 +152,7 @@ export class DataStreamServer extends EventEmitter {
|
|
|
158
152
|
* @param handler - function to be called for every occurring event
|
|
159
153
|
*/
|
|
160
154
|
onEventMessage(protocol, event, handler) {
|
|
161
|
-
this.internalEventEmitter.on(
|
|
155
|
+
this.internalEventEmitter.on(protocol + "-e-" + event, handler);
|
|
162
156
|
return this;
|
|
163
157
|
}
|
|
164
158
|
/**
|
|
@@ -169,7 +163,7 @@ export class DataStreamServer extends EventEmitter {
|
|
|
169
163
|
* @param handler - registered event handler
|
|
170
164
|
*/
|
|
171
165
|
removeEventHandler(protocol, event, handler) {
|
|
172
|
-
this.internalEventEmitter.removeListener(
|
|
166
|
+
this.internalEventEmitter.removeListener(protocol + "-e-" + event, handler);
|
|
173
167
|
return this;
|
|
174
168
|
}
|
|
175
169
|
/**
|
|
@@ -182,7 +176,7 @@ export class DataStreamServer extends EventEmitter {
|
|
|
182
176
|
* @param handler - function to be called for every occurring request
|
|
183
177
|
*/
|
|
184
178
|
onRequestMessage(protocol, request, handler) {
|
|
185
|
-
this.internalEventEmitter.on(
|
|
179
|
+
this.internalEventEmitter.on(protocol + "-r-" + request, handler);
|
|
186
180
|
return this;
|
|
187
181
|
}
|
|
188
182
|
/**
|
|
@@ -193,20 +187,20 @@ export class DataStreamServer extends EventEmitter {
|
|
|
193
187
|
* @param handler - registered request handler
|
|
194
188
|
*/
|
|
195
189
|
removeRequestHandler(protocol, request, handler) {
|
|
196
|
-
this.internalEventEmitter.removeListener(
|
|
190
|
+
this.internalEventEmitter.removeListener(protocol + "-r-" + request, handler);
|
|
197
191
|
return this;
|
|
198
192
|
}
|
|
199
193
|
prepareSession(connection, controllerKeySalt, callback) {
|
|
200
|
-
debug(
|
|
201
|
-
const accessoryKeySalt = randomBytes(32);
|
|
194
|
+
debug("Preparing for incoming HDS connection from %s", connection.sessionID);
|
|
195
|
+
const accessoryKeySalt = crypto_1.default.randomBytes(32);
|
|
202
196
|
const salt = Buffer.concat([controllerKeySalt, accessoryKeySalt]);
|
|
203
|
-
const accessoryToControllerEncryptionKey = HKDF(
|
|
204
|
-
const controllerToAccessoryEncryptionKey = HKDF(
|
|
197
|
+
const accessoryToControllerEncryptionKey = hapCrypto.HKDF("sha512", salt, connection.encryption.sharedSecret, DataStreamServer.accessoryToControllerInfo, 32);
|
|
198
|
+
const controllerToAccessoryEncryptionKey = hapCrypto.HKDF("sha512", salt, connection.encryption.sharedSecret, DataStreamServer.controllerToAccessoryInfo, 32);
|
|
205
199
|
const preparedSession = {
|
|
206
|
-
connection,
|
|
207
|
-
accessoryToControllerEncryptionKey,
|
|
208
|
-
controllerToAccessoryEncryptionKey,
|
|
209
|
-
accessoryKeySalt,
|
|
200
|
+
connection: connection,
|
|
201
|
+
accessoryToControllerEncryptionKey: accessoryToControllerEncryptionKey,
|
|
202
|
+
controllerToAccessoryEncryptionKey: controllerToAccessoryEncryptionKey,
|
|
203
|
+
accessoryKeySalt: accessoryKeySalt,
|
|
210
204
|
connectTimeout: setTimeout(() => this.timeoutPreparedSession(preparedSession), 10000),
|
|
211
205
|
};
|
|
212
206
|
preparedSession.connectTimeout.unref();
|
|
@@ -221,7 +215,7 @@ export class DataStreamServer extends EventEmitter {
|
|
|
221
215
|
});
|
|
222
216
|
}
|
|
223
217
|
timeoutPreparedSession(preparedSession) {
|
|
224
|
-
debug(
|
|
218
|
+
debug("Prepared HDS session timed out out since no connection was opened for 10 seconds (%s)", preparedSession.connection.sessionID);
|
|
225
219
|
const index = this.preparedSessions.indexOf(preparedSession);
|
|
226
220
|
if (index >= 0) {
|
|
227
221
|
this.preparedSessions.splice(index, 1);
|
|
@@ -231,52 +225,51 @@ export class DataStreamServer extends EventEmitter {
|
|
|
231
225
|
checkTCPServerEstablished(preparedSession, callback) {
|
|
232
226
|
switch (this.state) {
|
|
233
227
|
case 0 /* ServerState.UNINITIALIZED */:
|
|
234
|
-
debug(
|
|
235
|
-
this.tcpServer = createServer();
|
|
236
|
-
this.tcpServer.once(
|
|
237
|
-
this.tcpServer.on(
|
|
238
|
-
this.tcpServer.on(
|
|
228
|
+
debug("Starting up TCP server.");
|
|
229
|
+
this.tcpServer = net_1.default.createServer();
|
|
230
|
+
this.tcpServer.once("listening", this.listening.bind(this, preparedSession, callback));
|
|
231
|
+
this.tcpServer.on("connection", this.onConnection.bind(this));
|
|
232
|
+
this.tcpServer.on("close", this.closed.bind(this));
|
|
239
233
|
this.tcpServer.listen();
|
|
240
234
|
this.state = 1 /* ServerState.BINDING */;
|
|
241
235
|
break;
|
|
242
236
|
case 1 /* ServerState.BINDING */:
|
|
243
|
-
debug(
|
|
244
|
-
this.tcpServer.once(
|
|
237
|
+
debug("TCP server already running. Waiting for it to bind.");
|
|
238
|
+
this.tcpServer.once("listening", this.listening.bind(this, preparedSession, callback));
|
|
245
239
|
break;
|
|
246
240
|
case 2 /* ServerState.LISTENING */:
|
|
247
|
-
debug(
|
|
241
|
+
debug("Instructing client to connect to already running TCP server");
|
|
248
242
|
preparedSession.port = this.tcpPort;
|
|
249
243
|
callback();
|
|
250
244
|
break;
|
|
251
245
|
case 3 /* ServerState.CLOSING */:
|
|
252
|
-
debug(
|
|
253
|
-
this.tcpServer.once(
|
|
246
|
+
debug("TCP socket is currently closing. Trying again when server is fully closed and opening a new one then.");
|
|
247
|
+
this.tcpServer.once("close", () => setTimeout(() => this.checkTCPServerEstablished(preparedSession, callback), 10));
|
|
254
248
|
break;
|
|
255
249
|
}
|
|
256
250
|
}
|
|
257
251
|
listening(preparedSession, callback) {
|
|
258
252
|
this.state = 2 /* ServerState.LISTENING */;
|
|
259
253
|
const address = this.tcpServer.address();
|
|
260
|
-
if (address && typeof address !==
|
|
254
|
+
if (address && typeof address !== "string") { // address is only typeof string when listening to a pipe or unix socket
|
|
261
255
|
this.tcpPort = address.port;
|
|
262
256
|
preparedSession.port = address.port;
|
|
263
|
-
debug(
|
|
257
|
+
debug("TCP server is now listening for new data stream connections on port %s", address.port);
|
|
264
258
|
callback();
|
|
265
259
|
}
|
|
266
260
|
}
|
|
267
261
|
onConnection(socket) {
|
|
268
|
-
debug(
|
|
269
|
-
|
|
270
|
-
|
|
262
|
+
debug("[%s] New DataStream connection was established", socket.remoteAddress);
|
|
263
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
264
|
+
const connection = new DataStreamConnection(socket);
|
|
271
265
|
connection.on("identification" /* DataStreamConnectionEvent.IDENTIFICATION */, this.handleSessionIdentification.bind(this, connection));
|
|
272
266
|
connection.on("handle-message-globally" /* DataStreamConnectionEvent.HANDLE_MESSAGE_GLOBALLY */, this.handleMessageGlobally.bind(this, connection));
|
|
273
267
|
connection.on("closed" /* DataStreamConnectionEvent.CLOSED */, this.connectionClosed.bind(this, connection));
|
|
274
|
-
/* eslint-enable ts/no-use-before-define */
|
|
275
268
|
this.connections.push(connection);
|
|
276
269
|
this.emit("connection-opened" /* DataStreamServerEvent.CONNECTION_OPENED */, connection);
|
|
277
270
|
}
|
|
278
271
|
handleSessionIdentification(connection, firstFrame, callback) {
|
|
279
|
-
let identifiedSession;
|
|
272
|
+
let identifiedSession = undefined;
|
|
280
273
|
for (let i = 0; i < this.preparedSessions.length; i++) {
|
|
281
274
|
const preparedSession = this.preparedSessions[i];
|
|
282
275
|
// if we successfully decrypt the first frame with this key we know to which session this connection belongs
|
|
@@ -287,7 +280,7 @@ export class DataStreamServer extends EventEmitter {
|
|
|
287
280
|
}
|
|
288
281
|
callback(identifiedSession);
|
|
289
282
|
if (identifiedSession) {
|
|
290
|
-
debug(
|
|
283
|
+
debug("[%s] Connection was successfully identified (linked with sessionId: %s)", connection.remoteAddress, identifiedSession.connection.sessionID);
|
|
291
284
|
const index = this.preparedSessions.indexOf(identifiedSession);
|
|
292
285
|
if (index >= 0) {
|
|
293
286
|
this.preparedSessions.splice(index, 1);
|
|
@@ -299,19 +292,19 @@ export class DataStreamServer extends EventEmitter {
|
|
|
299
292
|
// on the other hand the keepAlive should handle that also :thinking:
|
|
300
293
|
}
|
|
301
294
|
else { // we looped through all session and didn't find anything
|
|
302
|
-
debug(
|
|
295
|
+
debug("[%s] Could not identify connection. Terminating.", connection.remoteAddress);
|
|
303
296
|
connection.close(); // disconnecting since first message was not a valid hello
|
|
304
297
|
}
|
|
305
298
|
}
|
|
306
299
|
handleMessageGlobally(connection, message) {
|
|
307
|
-
|
|
308
|
-
let separator =
|
|
300
|
+
assert_1.default.notStrictEqual(message.type, 3 /* MessageType.RESPONSE */); // responses can't physically get here
|
|
301
|
+
let separator = "";
|
|
309
302
|
const args = [];
|
|
310
303
|
if (message.type === 1 /* MessageType.EVENT */) {
|
|
311
|
-
separator =
|
|
304
|
+
separator = "-e-";
|
|
312
305
|
}
|
|
313
306
|
else if (message.type === 2 /* MessageType.REQUEST */) {
|
|
314
|
-
separator =
|
|
307
|
+
separator = "-r-";
|
|
315
308
|
args.push(message.id);
|
|
316
309
|
}
|
|
317
310
|
args.push(message.message);
|
|
@@ -321,15 +314,15 @@ export class DataStreamServer extends EventEmitter {
|
|
|
321
314
|
}
|
|
322
315
|
catch (error) {
|
|
323
316
|
hadListeners = true;
|
|
324
|
-
debug(
|
|
317
|
+
debug("[%s] Error occurred while dispatching handler for HDS message: %o", connection.remoteAddress, message);
|
|
325
318
|
debug(error.stack);
|
|
326
319
|
}
|
|
327
320
|
if (!hadListeners) {
|
|
328
|
-
debug(
|
|
321
|
+
debug("[%s] WARNING no handler was found for message: %o", connection.remoteAddress, message);
|
|
329
322
|
}
|
|
330
323
|
}
|
|
331
324
|
connectionClosed(connection) {
|
|
332
|
-
debug(
|
|
325
|
+
debug("[%s] DataStream connection closed", connection.remoteAddress);
|
|
333
326
|
this.connections.splice(this.connections.indexOf(connection), 1);
|
|
334
327
|
this.emit("connection-closed" /* DataStreamServerEvent.CONNECTION_CLOSED */, connection);
|
|
335
328
|
this.checkCloseable();
|
|
@@ -339,7 +332,7 @@ export class DataStreamServer extends EventEmitter {
|
|
|
339
332
|
}
|
|
340
333
|
checkCloseable() {
|
|
341
334
|
if (this.connections.length === 0 && this.preparedSessions.length === 0 && this.state < 3 /* ServerState.CLOSING */) {
|
|
342
|
-
debug(
|
|
335
|
+
debug("Last connection disconnected. Closing the server now.");
|
|
343
336
|
this.state = 3 /* ServerState.CLOSING */;
|
|
344
337
|
this.tcpServer.close();
|
|
345
338
|
}
|
|
@@ -364,11 +357,11 @@ export class DataStreamServer extends EventEmitter {
|
|
|
364
357
|
this.state = 0 /* ServerState.UNINITIALIZED */;
|
|
365
358
|
}
|
|
366
359
|
}
|
|
360
|
+
exports.DataStreamServer = DataStreamServer;
|
|
367
361
|
/**
|
|
368
362
|
* @group HomeKit Data Streams (HDS)
|
|
369
363
|
*/
|
|
370
|
-
|
|
371
|
-
export var DataStreamConnectionEvent;
|
|
364
|
+
var DataStreamConnectionEvent;
|
|
372
365
|
(function (DataStreamConnectionEvent) {
|
|
373
366
|
/**
|
|
374
367
|
* This event is emitted when the first HDSFrame is received from a new connection.
|
|
@@ -385,35 +378,35 @@ export var DataStreamConnectionEvent;
|
|
|
385
378
|
* This event is emitted when the socket of the connection was closed.
|
|
386
379
|
*/
|
|
387
380
|
DataStreamConnectionEvent["CLOSED"] = "closed";
|
|
388
|
-
})(DataStreamConnectionEvent || (DataStreamConnectionEvent = {}));
|
|
381
|
+
})(DataStreamConnectionEvent || (exports.DataStreamConnectionEvent = DataStreamConnectionEvent = {}));
|
|
389
382
|
/**
|
|
390
383
|
* @group HomeKit Data Streams (HDS)
|
|
391
384
|
*/
|
|
392
|
-
|
|
393
|
-
export var HDSConnectionErrorType;
|
|
385
|
+
var HDSConnectionErrorType;
|
|
394
386
|
(function (HDSConnectionErrorType) {
|
|
395
387
|
HDSConnectionErrorType[HDSConnectionErrorType["ILLEGAL_STATE"] = 1] = "ILLEGAL_STATE";
|
|
396
388
|
HDSConnectionErrorType[HDSConnectionErrorType["CLOSED_SOCKET"] = 2] = "CLOSED_SOCKET";
|
|
397
389
|
HDSConnectionErrorType[HDSConnectionErrorType["MAX_PAYLOAD_LENGTH"] = 3] = "MAX_PAYLOAD_LENGTH";
|
|
398
|
-
})(HDSConnectionErrorType || (HDSConnectionErrorType = {}));
|
|
390
|
+
})(HDSConnectionErrorType || (exports.HDSConnectionErrorType = HDSConnectionErrorType = {}));
|
|
399
391
|
/**
|
|
400
392
|
* @group HomeKit Data Streams (HDS)
|
|
401
393
|
*/
|
|
402
|
-
|
|
394
|
+
class HDSConnectionError extends Error {
|
|
403
395
|
type;
|
|
404
396
|
constructor(message, type) {
|
|
405
397
|
super(message);
|
|
406
398
|
this.type = type;
|
|
407
399
|
}
|
|
408
400
|
}
|
|
401
|
+
exports.HDSConnectionError = HDSConnectionError;
|
|
409
402
|
/**
|
|
410
403
|
* DataStream connection which holds any necessary state information, encryption and decryption keys, manages
|
|
411
404
|
* protocol handlers and also handles sending and receiving of data stream frames.
|
|
412
405
|
*
|
|
413
406
|
* @group HomeKit Data Streams (HDS)
|
|
414
407
|
*/
|
|
415
|
-
// eslint-disable-next-line
|
|
416
|
-
|
|
408
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
409
|
+
class DataStreamConnection extends events_1.EventEmitter {
|
|
417
410
|
static MAX_PAYLOAD_LENGTH = 0b11111111111111111111;
|
|
418
411
|
socket;
|
|
419
412
|
connection; // reference to the hap connection. is present when state > UNIDENTIFIED
|
|
@@ -454,12 +447,12 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
454
447
|
},
|
|
455
448
|
});
|
|
456
449
|
this.helloTimer = setTimeout(() => {
|
|
457
|
-
debug(
|
|
450
|
+
debug("[%s] Hello message did not arrive in time. Killing the connection", this.remoteAddress);
|
|
458
451
|
this.close();
|
|
459
452
|
}, 10000);
|
|
460
|
-
this.socket.on(
|
|
461
|
-
this.socket.on(
|
|
462
|
-
this.socket.on(
|
|
453
|
+
this.socket.on("data", this.onSocketData.bind(this));
|
|
454
|
+
this.socket.on("error", this.onSocketError.bind(this));
|
|
455
|
+
this.socket.on("close", this.onSocketClose.bind(this));
|
|
463
456
|
// this is to mitigate the event emitter "memory leak warning".
|
|
464
457
|
// e.g. with HSV there might be multiple cameras subscribing to the CLOSE event. one subscription for
|
|
465
458
|
// every active recording stream on a camera. The default limit of 10 might be easily reached.
|
|
@@ -467,9 +460,10 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
467
460
|
// a warning is still be printed if running long enough.
|
|
468
461
|
this.setMaxListeners(100);
|
|
469
462
|
}
|
|
463
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
470
464
|
handleHello(id, message) {
|
|
471
465
|
// that hello is indeed the _first_ message received is verified in onSocketData(...)
|
|
472
|
-
debug(
|
|
466
|
+
debug("[%s] Received hello message from client: %o", this.remoteAddress, message);
|
|
473
467
|
clearTimeout(this.helloTimer);
|
|
474
468
|
this.helloTimer = undefined;
|
|
475
469
|
this.state = 2 /* ConnectionState.READY */;
|
|
@@ -508,7 +502,9 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
508
502
|
* @param event - name of the event (also referred to as topic. See {@link Topics} for some known ones)
|
|
509
503
|
* @param message - message dictionary which gets sent along the event
|
|
510
504
|
*/
|
|
505
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
511
506
|
sendEvent(protocol, event, message = {}) {
|
|
507
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
512
508
|
const header = {};
|
|
513
509
|
header.protocol = protocol;
|
|
514
510
|
header.event = event;
|
|
@@ -523,8 +519,9 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
523
519
|
* @param request - name of the request (also referred to as topic. See {@link Topics} for some known ones)
|
|
524
520
|
* @param message - message dictionary which gets sent along the request
|
|
525
521
|
* @param callback - handler which gets supplied with an error object if the response didn't
|
|
526
|
-
*
|
|
522
|
+
* arrive in time or the status and the message dictionary from the response
|
|
527
523
|
*/
|
|
524
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
528
525
|
sendRequest(protocol, request, message = {}, callback) {
|
|
529
526
|
let requestId;
|
|
530
527
|
do { // generate unused requestId
|
|
@@ -539,12 +536,13 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
539
536
|
delete this.responseHandlers[requestId];
|
|
540
537
|
delete this.responseTimers[requestId];
|
|
541
538
|
// handler should be able to clean up their stuff
|
|
542
|
-
handler(new Error(
|
|
539
|
+
handler(new Error("timeout"), undefined, {});
|
|
543
540
|
}, 10000); // 10s timer
|
|
541
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
544
542
|
const header = {};
|
|
545
543
|
header.protocol = protocol;
|
|
546
544
|
header.request = request;
|
|
547
|
-
header.id = new Int64(requestId);
|
|
545
|
+
header.id = new DataStreamParser_1.Int64(requestId);
|
|
548
546
|
this.sendHDSFrame(header, message);
|
|
549
547
|
}
|
|
550
548
|
/**
|
|
@@ -556,12 +554,15 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
556
554
|
* @param status - status indication if the request was successful. A status of zero indicates success.
|
|
557
555
|
* @param message - message dictionary which gets sent along the response
|
|
558
556
|
*/
|
|
559
|
-
sendResponse(protocol, response, id, status = HDSStatus.SUCCESS,
|
|
557
|
+
sendResponse(protocol, response, id, status = HDSStatus.SUCCESS,
|
|
558
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
559
|
+
message = {}) {
|
|
560
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
560
561
|
const header = {};
|
|
561
562
|
header.protocol = protocol;
|
|
562
563
|
header.response = response;
|
|
563
|
-
header.id = new Int64(id);
|
|
564
|
-
header.status = new Int64(status);
|
|
564
|
+
header.id = new DataStreamParser_1.Int64(id);
|
|
565
|
+
header.status = new DataStreamParser_1.Int64(status);
|
|
565
566
|
this.sendHDSFrame(header, message);
|
|
566
567
|
}
|
|
567
568
|
onSocketData(data) {
|
|
@@ -586,7 +587,7 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
586
587
|
// below listener is removed in .close()
|
|
587
588
|
this.connection.setMaxListeners(this.connection.getMaxListeners() + 1);
|
|
588
589
|
this.connection.on("closed" /* HAPConnectionEvent.CLOSED */, this.hapConnectionClosedListener); // register close listener
|
|
589
|
-
debug(
|
|
590
|
+
debug("[%s] Registering CLOSED handler to HAP connection. Connection currently has %d close handlers!", this.remoteAddress, this.connection.listeners("closed" /* HAPConnectionEvent.CLOSED */).length);
|
|
590
591
|
}
|
|
591
592
|
});
|
|
592
593
|
if (this.state === 0 /* ConnectionState.UNIDENTIFIED */) {
|
|
@@ -596,7 +597,7 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
596
597
|
}
|
|
597
598
|
for (; frameIndex < frames.length; frameIndex++) { // decrypt all remaining frames
|
|
598
599
|
if (!this.decryptHDSFrame(frames[frameIndex])) {
|
|
599
|
-
debug(
|
|
600
|
+
debug("[%s] HDS frame decryption or authentication failed. Connection will be terminated!", this.remoteAddress);
|
|
600
601
|
this.close();
|
|
601
602
|
return;
|
|
602
603
|
}
|
|
@@ -606,12 +607,12 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
606
607
|
const firstMessage = messages[0];
|
|
607
608
|
if (firstMessage.protocol !== "control" /* Protocols.CONTROL */ || firstMessage.type !== 2 /* MessageType.REQUEST */ || firstMessage.topic !== "hello" /* Topics.HELLO */) {
|
|
608
609
|
// first message is not the expected hello request
|
|
609
|
-
debug(
|
|
610
|
+
debug("[%s] First message received was not the expected hello message. Instead got: %o", this.remoteAddress, firstMessage);
|
|
610
611
|
this.close();
|
|
611
612
|
return;
|
|
612
613
|
}
|
|
613
614
|
}
|
|
614
|
-
messages.forEach(
|
|
615
|
+
messages.forEach(message => {
|
|
615
616
|
if (message.type === 3 /* MessageType.RESPONSE */) {
|
|
616
617
|
// protocol and topic are currently not tested here; just assumed they are correct;
|
|
617
618
|
// probably they are as the requestId is unique per connection no matter what protocol is used
|
|
@@ -623,14 +624,14 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
623
624
|
}
|
|
624
625
|
if (!responseHandler) {
|
|
625
626
|
// we got a response to a request we did not send; we ignore it for now, since nobody will be hurt
|
|
626
|
-
debug(
|
|
627
|
+
debug("WARNING we received a response to a request we have not sent: %o", message);
|
|
627
628
|
return;
|
|
628
629
|
}
|
|
629
630
|
try {
|
|
630
631
|
responseHandler(undefined, message.status, message.message);
|
|
631
632
|
}
|
|
632
633
|
catch (error) {
|
|
633
|
-
debug(
|
|
634
|
+
debug("[%s] Error occurred while dispatching response handler for HDS message: %o", this.remoteAddress, message);
|
|
634
635
|
debug(error.stack);
|
|
635
636
|
}
|
|
636
637
|
delete this.responseHandlers[message.id];
|
|
@@ -643,35 +644,35 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
643
644
|
return;
|
|
644
645
|
}
|
|
645
646
|
if (message.type === 1 /* MessageType.EVENT */) {
|
|
646
|
-
|
|
647
|
-
|
|
647
|
+
let eventHandler;
|
|
648
|
+
if (!handler.eventHandler || !(eventHandler = handler.eventHandler[message.topic])) {
|
|
649
|
+
debug("[%s] WARNING no event handler was found for message: %o", this.remoteAddress, message);
|
|
648
650
|
return;
|
|
649
651
|
}
|
|
650
|
-
const eventHandler = handler.eventHandler[message.topic];
|
|
651
652
|
try {
|
|
652
653
|
eventHandler(message.message);
|
|
653
654
|
}
|
|
654
655
|
catch (error) {
|
|
655
|
-
debug(
|
|
656
|
+
debug("[%s] Error occurred while dispatching event handler for HDS message: %o", this.remoteAddress, message);
|
|
656
657
|
debug(error.stack);
|
|
657
658
|
}
|
|
658
659
|
}
|
|
659
660
|
else if (message.type === 2 /* MessageType.REQUEST */) {
|
|
660
|
-
|
|
661
|
-
|
|
661
|
+
let requestHandler;
|
|
662
|
+
if (!handler.requestHandler || !(requestHandler = handler.requestHandler[message.topic])) {
|
|
663
|
+
debug("[%s] WARNING no request handler was found for message: %o", this.remoteAddress, message);
|
|
662
664
|
return;
|
|
663
665
|
}
|
|
664
|
-
const requestHandler = handler.requestHandler[message.topic];
|
|
665
666
|
try {
|
|
666
667
|
requestHandler(message.id, message.message);
|
|
667
668
|
}
|
|
668
669
|
catch (error) {
|
|
669
|
-
debug(
|
|
670
|
+
debug("[%s] Error occurred while dispatching request handler for HDS message: %o", this.remoteAddress, message);
|
|
670
671
|
debug(error.stack);
|
|
671
672
|
}
|
|
672
673
|
}
|
|
673
674
|
else {
|
|
674
|
-
debug(
|
|
675
|
+
debug("[%s] Encountered unknown message type with id %d", this.remoteAddress, message.type);
|
|
675
676
|
}
|
|
676
677
|
}
|
|
677
678
|
});
|
|
@@ -686,13 +687,13 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
686
687
|
for (let frameBegin = 0; frameBegin < totalBufferLength;) {
|
|
687
688
|
if (frameBegin + 4 > totalBufferLength) {
|
|
688
689
|
// we don't have enough data in the buffer for the next header
|
|
689
|
-
this.frameBuffer = data.
|
|
690
|
+
this.frameBuffer = data.slice(frameBegin);
|
|
690
691
|
break;
|
|
691
692
|
}
|
|
692
693
|
const payloadType = data.readUInt8(frameBegin); // type defining structure of payload; 8-bit; currently expected to be 1
|
|
693
694
|
const payloadLength = data.readUIntBE(frameBegin + 1, 3); // read 24-bit big-endian uint length field
|
|
694
695
|
if (payloadLength > DataStreamConnection.MAX_PAYLOAD_LENGTH) {
|
|
695
|
-
debug(
|
|
696
|
+
debug("[%s] Connection send payload with size bigger than the maximum allow for data stream", this.remoteAddress);
|
|
696
697
|
this.close();
|
|
697
698
|
return [];
|
|
698
699
|
}
|
|
@@ -700,38 +701,38 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
700
701
|
// check if the data from this frame is already there (payload + 16-byte authTag)
|
|
701
702
|
if (payloadLength + 16 > remainingBufferLength) {
|
|
702
703
|
// Frame is fragmented, so we wait until we receive more
|
|
703
|
-
this.frameBuffer = data.
|
|
704
|
+
this.frameBuffer = data.slice(frameBegin);
|
|
704
705
|
break;
|
|
705
706
|
}
|
|
706
707
|
const payloadBegin = frameBegin + 4;
|
|
707
708
|
const authTagBegin = payloadBegin + payloadLength;
|
|
708
|
-
const header = data.
|
|
709
|
-
const cipheredPayload = data.
|
|
709
|
+
const header = data.slice(frameBegin, payloadBegin); // header is also authenticated using authTag
|
|
710
|
+
const cipheredPayload = data.slice(payloadBegin, authTagBegin);
|
|
710
711
|
const plaintextPayload = Buffer.alloc(payloadLength);
|
|
711
|
-
const authTag = data.
|
|
712
|
+
const authTag = data.slice(authTagBegin, authTagBegin + 16);
|
|
712
713
|
frameBegin = authTagBegin + 16; // move to next frame
|
|
713
714
|
if (payloadType === 1) {
|
|
714
715
|
const hdsFrame = {
|
|
715
|
-
header,
|
|
716
|
-
cipheredPayload,
|
|
717
|
-
authTag,
|
|
716
|
+
header: header,
|
|
717
|
+
cipheredPayload: cipheredPayload,
|
|
718
|
+
authTag: authTag,
|
|
718
719
|
};
|
|
719
720
|
frames.push(hdsFrame);
|
|
720
721
|
}
|
|
721
722
|
else {
|
|
722
|
-
debug(
|
|
723
|
+
debug("[%s] Encountered unknown payload type %d for payload: %s", this.remoteAddress, plaintextPayload.toString("hex"));
|
|
723
724
|
}
|
|
724
725
|
}
|
|
725
726
|
return frames;
|
|
726
727
|
}
|
|
727
728
|
/**
|
|
728
|
-
* @private
|
|
729
|
+
* @private file-private API
|
|
729
730
|
*/
|
|
730
731
|
decryptHDSFrame(frame, keyOverwrite) {
|
|
731
|
-
writeUInt64LE(this.controllerToAccessoryNonce, this.controllerToAccessoryNonceBuffer, 0); // update nonce buffer
|
|
732
|
+
hapCrypto.writeUInt64LE(this.controllerToAccessoryNonce, this.controllerToAccessoryNonceBuffer, 0); // update nonce buffer
|
|
732
733
|
const key = keyOverwrite || this.controllerToAccessoryEncryptionKey;
|
|
733
734
|
try {
|
|
734
|
-
frame.plaintextPayload = chacha20_poly1305_decryptAndVerify(key, this.controllerToAccessoryNonceBuffer, frame.header, frame.cipheredPayload, frame.authTag);
|
|
735
|
+
frame.plaintextPayload = hapCrypto.chacha20_poly1305_decryptAndVerify(key, this.controllerToAccessoryNonceBuffer, frame.header, frame.cipheredPayload, frame.authTag);
|
|
735
736
|
this.controllerToAccessoryNonce++; // we had a successful encryption, increment the nonce
|
|
736
737
|
return true;
|
|
737
738
|
}
|
|
@@ -742,40 +743,42 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
742
743
|
}
|
|
743
744
|
decodePayloads(frames) {
|
|
744
745
|
const messages = [];
|
|
745
|
-
frames.forEach(
|
|
746
|
+
frames.forEach(frame => {
|
|
746
747
|
const payload = frame.plaintextPayload;
|
|
747
748
|
if (!payload) {
|
|
748
|
-
throw new HDSConnectionError(
|
|
749
|
+
throw new HDSConnectionError("Reached illegal state. Encountered HDSFrame with wasn't decrypted yet!", 1 /* HDSConnectionErrorType.ILLEGAL_STATE */);
|
|
749
750
|
}
|
|
750
751
|
const headerLength = payload.readUInt8(0);
|
|
751
752
|
const messageLength = payload.length - headerLength - 1;
|
|
752
753
|
const headerBegin = 1;
|
|
753
754
|
const messageBegin = headerBegin + headerLength;
|
|
754
|
-
const headerPayload = new DataStreamReader(payload.
|
|
755
|
-
const messagePayload = new DataStreamReader(payload.
|
|
755
|
+
const headerPayload = new DataStreamParser_1.DataStreamReader(payload.slice(headerBegin, headerBegin + headerLength));
|
|
756
|
+
const messagePayload = new DataStreamParser_1.DataStreamReader(payload.slice(messageBegin, messageBegin + messageLength));
|
|
757
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
756
758
|
let headerDictionary;
|
|
759
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
757
760
|
let messageDictionary;
|
|
758
761
|
try {
|
|
759
|
-
headerDictionary = DataStreamParser.decode(headerPayload);
|
|
762
|
+
headerDictionary = DataStreamParser_1.DataStreamParser.decode(headerPayload);
|
|
760
763
|
headerPayload.finished();
|
|
761
764
|
}
|
|
762
765
|
catch (error) {
|
|
763
|
-
debug(
|
|
766
|
+
debug("[%s] Failed to decode header payload: %s", this.remoteAddress, error.message);
|
|
764
767
|
return;
|
|
765
768
|
}
|
|
766
769
|
try {
|
|
767
|
-
messageDictionary = DataStreamParser.decode(messagePayload);
|
|
770
|
+
messageDictionary = DataStreamParser_1.DataStreamParser.decode(messagePayload);
|
|
768
771
|
messagePayload.finished();
|
|
769
772
|
}
|
|
770
773
|
catch (error) {
|
|
771
|
-
debug(
|
|
774
|
+
debug("[%s] Failed to decode message payload: %s (header: %o)", this.remoteAddress, error.message, headerDictionary);
|
|
772
775
|
return;
|
|
773
776
|
}
|
|
774
777
|
let type;
|
|
775
778
|
const protocol = headerDictionary.protocol;
|
|
776
779
|
let topic;
|
|
777
|
-
let id;
|
|
778
|
-
let status;
|
|
780
|
+
let id = undefined;
|
|
781
|
+
let status = undefined;
|
|
779
782
|
if (headerDictionary.event !== undefined) {
|
|
780
783
|
type = 1 /* MessageType.EVENT */;
|
|
781
784
|
topic = headerDictionary.event;
|
|
@@ -792,43 +795,44 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
792
795
|
status = headerDictionary.status;
|
|
793
796
|
}
|
|
794
797
|
else {
|
|
795
|
-
debug(
|
|
798
|
+
debug("[%s] Encountered unknown payload header format: %o (message: %o)", this.remoteAddress, headerDictionary, messageDictionary);
|
|
796
799
|
return;
|
|
797
800
|
}
|
|
798
801
|
const message = {
|
|
799
|
-
type,
|
|
800
|
-
protocol,
|
|
801
|
-
topic,
|
|
802
|
-
id,
|
|
803
|
-
status,
|
|
802
|
+
type: type,
|
|
803
|
+
protocol: protocol,
|
|
804
|
+
topic: topic,
|
|
805
|
+
id: id,
|
|
806
|
+
status: status,
|
|
804
807
|
message: messageDictionary,
|
|
805
808
|
};
|
|
806
809
|
messages.push(message);
|
|
807
810
|
});
|
|
808
811
|
return messages;
|
|
809
812
|
}
|
|
813
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
810
814
|
sendHDSFrame(header, message) {
|
|
811
815
|
if (this.state >= 3 /* ConnectionState.CLOSING */) {
|
|
812
|
-
throw new HDSConnectionError(
|
|
816
|
+
throw new HDSConnectionError("Cannot send message on closing/closed socket!", 2 /* HDSConnectionErrorType.CLOSED_SOCKET */);
|
|
813
817
|
}
|
|
814
|
-
const headerWriter = new DataStreamWriter();
|
|
815
|
-
const messageWriter = new DataStreamWriter();
|
|
816
|
-
DataStreamParser.encode(header, headerWriter);
|
|
817
|
-
DataStreamParser.encode(message, messageWriter);
|
|
818
|
+
const headerWriter = new DataStreamParser_1.DataStreamWriter();
|
|
819
|
+
const messageWriter = new DataStreamParser_1.DataStreamWriter();
|
|
820
|
+
DataStreamParser_1.DataStreamParser.encode(header, headerWriter);
|
|
821
|
+
DataStreamParser_1.DataStreamParser.encode(message, messageWriter);
|
|
818
822
|
const payloadHeaderBuffer = Buffer.alloc(1);
|
|
819
823
|
payloadHeaderBuffer.writeUInt8(headerWriter.length(), 0);
|
|
820
824
|
const payloadBuffer = Buffer.concat([payloadHeaderBuffer, headerWriter.getData(), messageWriter.getData()]);
|
|
821
825
|
if (payloadBuffer.length > DataStreamConnection.MAX_PAYLOAD_LENGTH) {
|
|
822
|
-
throw new HDSConnectionError(
|
|
826
|
+
throw new HDSConnectionError("Tried sending payload with length larger than the maximum allowed for data stream", 3 /* HDSConnectionErrorType.MAX_PAYLOAD_LENGTH */);
|
|
823
827
|
}
|
|
824
828
|
const frameTypeBuffer = Buffer.alloc(1);
|
|
825
829
|
frameTypeBuffer.writeUInt8(1, 0);
|
|
826
830
|
let frameLengthBuffer = Buffer.alloc(4);
|
|
827
831
|
frameLengthBuffer.writeUInt32BE(payloadBuffer.length, 0);
|
|
828
|
-
frameLengthBuffer = frameLengthBuffer.
|
|
832
|
+
frameLengthBuffer = frameLengthBuffer.slice(1, 4); // a bit hacky but the only real way to write 24-bit int in node
|
|
829
833
|
const frameHeader = Buffer.concat([frameTypeBuffer, frameLengthBuffer]);
|
|
830
|
-
writeUInt64LE(this.accessoryToControllerNonce++, this.accessoryToControllerNonceBuffer);
|
|
831
|
-
const encrypted = chacha20_poly1305_encryptAndSeal(this.accessoryToControllerEncryptionKey, this.accessoryToControllerNonceBuffer, frameHeader, payloadBuffer);
|
|
834
|
+
hapCrypto.writeUInt64LE(this.accessoryToControllerNonce++, this.accessoryToControllerNonceBuffer);
|
|
835
|
+
const encrypted = hapCrypto.chacha20_poly1305_encryptAndSeal(this.accessoryToControllerEncryptionKey, this.accessoryToControllerNonceBuffer, frameHeader, payloadBuffer);
|
|
832
836
|
this.socket.write(Buffer.concat([frameHeader, encrypted.ciphertext, encrypted.authTag]));
|
|
833
837
|
/* Useful for debugging outgoing packages and detecting encoding errors
|
|
834
838
|
console.log("SENT DATA: " + payloadBuffer.toString("hex"));
|
|
@@ -840,7 +844,7 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
840
844
|
};
|
|
841
845
|
const sentMessage = this.decodePayloads([frame])[0];
|
|
842
846
|
console.log("Sent message: " + JSON.stringify(sentMessage, null, 4));
|
|
843
|
-
|
|
847
|
+
//*/
|
|
844
848
|
}
|
|
845
849
|
close() {
|
|
846
850
|
if (this.state >= 3 /* ConnectionState.CLOSING */) {
|
|
@@ -854,11 +858,11 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
854
858
|
}
|
|
855
859
|
onHAPSessionClosed() {
|
|
856
860
|
// If the hap connection is closed it is probably also a good idea to close the data stream connection
|
|
857
|
-
debug(
|
|
861
|
+
debug("[%s] HAP connection disconnected. Also closing DataStream connection now.", this.remoteAddress);
|
|
858
862
|
this.close();
|
|
859
863
|
}
|
|
860
864
|
onSocketError(error) {
|
|
861
|
-
debug(
|
|
865
|
+
debug("[%s] Encountered socket error: %s", this.remoteAddress, error.message);
|
|
862
866
|
// onSocketClose will be called next
|
|
863
867
|
}
|
|
864
868
|
onSocketClose() {
|
|
@@ -870,4 +874,5 @@ export class DataStreamConnection extends EventEmitter {
|
|
|
870
874
|
this.removeAllListeners();
|
|
871
875
|
}
|
|
872
876
|
}
|
|
877
|
+
exports.DataStreamConnection = DataStreamConnection;
|
|
873
878
|
//# sourceMappingURL=DataStreamServer.js.map
|