hap-nodejs 1.1.1-beta.2 → 1.1.1-beta.4
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 +50 -53
- package/README.md +16 -19
- package/dist/accessories/AirConditioner_accessory.js +28 -30
- package/dist/accessories/AirConditioner_accessory.js.map +1 -1
- package/dist/accessories/AppleTVRemote_accessory.js +69 -81
- package/dist/accessories/AppleTVRemote_accessory.js.map +1 -1
- package/dist/accessories/Camera_accessory.js +141 -136
- package/dist/accessories/Camera_accessory.js.map +1 -1
- package/dist/accessories/Fan_accessory.js +18 -22
- package/dist/accessories/Fan_accessory.js.map +1 -1
- package/dist/accessories/GarageDoorOpener_accessory.js +33 -35
- package/dist/accessories/GarageDoorOpener_accessory.js.map +1 -1
- package/dist/accessories/Light-AdaptiveLighting_accessory.js +42 -44
- package/dist/accessories/Light-AdaptiveLighting_accessory.js.map +1 -1
- package/dist/accessories/Light_accessory.js +32 -34
- package/dist/accessories/Light_accessory.js.map +1 -1
- package/dist/accessories/Lock_accessory.js +25 -26
- package/dist/accessories/Lock_accessory.js.map +1 -1
- package/dist/accessories/MotionSensor_accessory.js +13 -16
- package/dist/accessories/MotionSensor_accessory.js.map +1 -1
- package/dist/accessories/Outlet_accessory.js +20 -22
- package/dist/accessories/Outlet_accessory.js.map +1 -1
- package/dist/accessories/SmartSpeaker_accessory.js +18 -20
- package/dist/accessories/SmartSpeaker_accessory.js.map +1 -1
- package/dist/accessories/Sprinkler_accessory.js +34 -37
- package/dist/accessories/Sprinkler_accessory.js.map +1 -1
- package/dist/accessories/TV_accessory.js +43 -45
- package/dist/accessories/TV_accessory.js.map +1 -1
- package/dist/accessories/TemperatureSensor_accessory.js +12 -15
- 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 +9 -12
- 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 +11 -14
- 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 +37 -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 +83 -87
- package/dist/accessories/types.js.map +1 -1
- package/dist/index.d.ts +26 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -34
- 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 +19 -21
- package/dist/internal-types.js.map +1 -1
- package/dist/lib/Accessory.d.ts +38 -37
- package/dist/lib/Accessory.d.ts.map +1 -1
- package/dist/lib/Accessory.js +286 -291
- 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 +128 -136
- 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 +2 -6
- package/dist/lib/Bridge.js.map +1 -1
- package/dist/lib/Characteristic.d.ts +40 -41
- package/dist/lib/Characteristic.d.ts.map +1 -1
- package/dist/lib/Characteristic.js +204 -208
- package/dist/lib/Characteristic.js.map +1 -1
- package/dist/lib/HAPServer.d.ts +31 -30
- package/dist/lib/HAPServer.d.ts.map +1 -1
- package/dist/lib/HAPServer.js +220 -229
- 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 +63 -67
- package/dist/lib/Service.js.map +1 -1
- package/dist/lib/camera/RTPProxy.d.ts +2 -1
- package/dist/lib/camera/RTPProxy.d.ts.map +1 -1
- package/dist/lib/camera/RTPProxy.js +28 -44
- package/dist/lib/camera/RTPProxy.js.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.d.ts +34 -33
- package/dist/lib/camera/RTPStreamManagement.d.ts.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.js +179 -151
- package/dist/lib/camera/RTPStreamManagement.js.map +1 -1
- package/dist/lib/camera/RecordingManagement.d.ts +19 -17
- package/dist/lib/camera/RecordingManagement.d.ts.map +1 -1
- package/dist/lib/camera/RecordingManagement.js +160 -151
- 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 +3 -6
- 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 +152 -144
- package/dist/lib/controller/AdaptiveLightingController.js.map +1 -1
- package/dist/lib/controller/CameraController.d.ts +22 -20
- package/dist/lib/controller/CameraController.d.ts.map +1 -1
- package/dist/lib/controller/CameraController.js +74 -78
- 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 +5 -8
- package/dist/lib/controller/Controller.js.map +1 -1
- package/dist/lib/controller/DoorbellController.d.ts +5 -4
- package/dist/lib/controller/DoorbellController.d.ts.map +1 -1
- package/dist/lib/controller/DoorbellController.js +9 -13
- package/dist/lib/controller/DoorbellController.js.map +1 -1
- package/dist/lib/controller/RemoteController.d.ts +39 -37
- package/dist/lib/controller/RemoteController.d.ts.map +1 -1
- package/dist/lib/controller/RemoteController.js +208 -197
- 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 +5 -8
- 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 +39 -39
- package/dist/lib/datastream/DataStreamManagement.js.map +1 -1
- package/dist/lib/datastream/DataStreamParser.d.ts +1 -0
- package/dist/lib/datastream/DataStreamParser.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamParser.js +57 -77
- package/dist/lib/datastream/DataStreamParser.js.map +1 -1
- package/dist/lib/datastream/DataStreamServer.d.ts +23 -22
- package/dist/lib/datastream/DataStreamServer.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamServer.js +154 -164
- 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 +3 -6
- package/dist/lib/datastream/index.js.map +1 -1
- package/dist/lib/dbus/align.d.ts +2 -0
- package/dist/lib/dbus/align.d.ts.map +1 -0
- package/dist/lib/dbus/align.js +12 -0
- package/dist/lib/dbus/align.js.map +1 -0
- package/dist/lib/dbus/bus.d.ts +38 -0
- package/dist/lib/dbus/bus.d.ts.map +1 -0
- package/dist/lib/dbus/bus.js +222 -0
- package/dist/lib/dbus/bus.js.map +1 -0
- package/dist/lib/dbus/constants.d.ts +43 -0
- package/dist/lib/dbus/constants.d.ts.map +1 -0
- package/dist/lib/dbus/constants.js +53 -0
- package/dist/lib/dbus/constants.js.map +1 -0
- package/dist/lib/dbus/dbus-buffer.d.ts +30 -0
- package/dist/lib/dbus/dbus-buffer.d.ts.map +1 -0
- package/dist/lib/dbus/dbus-buffer.js +175 -0
- package/dist/lib/dbus/dbus-buffer.js.map +1 -0
- package/dist/lib/dbus/handshake.d.ts +2 -0
- package/dist/lib/dbus/handshake.d.ts.map +1 -0
- package/dist/lib/dbus/handshake.js +130 -0
- package/dist/lib/dbus/handshake.js.map +1 -0
- package/dist/lib/dbus/index.d.ts +3 -0
- package/dist/lib/dbus/index.d.ts.map +1 -0
- package/dist/lib/dbus/index.js +123 -0
- package/dist/lib/dbus/index.js.map +1 -0
- package/dist/lib/dbus/introspect.d.ts +30 -0
- package/dist/lib/dbus/introspect.d.ts.map +1 -0
- package/dist/lib/dbus/introspect.js +208 -0
- package/dist/lib/dbus/introspect.js.map +1 -0
- package/dist/lib/dbus/marshall.d.ts +2 -0
- package/dist/lib/dbus/marshall.d.ts.map +1 -0
- package/dist/lib/dbus/marshall.js +97 -0
- package/dist/lib/dbus/marshall.js.map +1 -0
- package/dist/lib/dbus/marshallers.d.ts +10 -0
- package/dist/lib/dbus/marshallers.d.ts.map +1 -0
- package/dist/lib/dbus/marshallers.js +329 -0
- package/dist/lib/dbus/marshallers.js.map +1 -0
- package/dist/lib/dbus/message.d.ts +4 -0
- package/dist/lib/dbus/message.d.ts.map +1 -0
- package/dist/lib/dbus/message.js +116 -0
- package/dist/lib/dbus/message.js.map +1 -0
- package/dist/lib/dbus/put.d.ts +21 -0
- package/dist/lib/dbus/put.d.ts.map +1 -0
- package/dist/lib/dbus/put.js +120 -0
- package/dist/lib/dbus/put.js.map +1 -0
- package/dist/lib/dbus/readline.d.ts +2 -0
- package/dist/lib/dbus/readline.d.ts.map +1 -0
- package/dist/lib/dbus/readline.js +27 -0
- package/dist/lib/dbus/readline.js.map +1 -0
- package/dist/lib/dbus/signature.d.ts +2 -0
- package/dist/lib/dbus/signature.d.ts.map +1 -0
- package/dist/lib/dbus/signature.js +59 -0
- package/dist/lib/dbus/signature.js.map +1 -0
- package/dist/lib/dbus/stdifaces.d.ts +3 -0
- package/dist/lib/dbus/stdifaces.d.ts.map +1 -0
- package/dist/lib/dbus/stdifaces.js +206 -0
- package/dist/lib/dbus/stdifaces.js.map +1 -0
- 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 +958 -1204
- 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 +620 -695
- 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 +246 -253
- 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 +160 -165
- 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 +2 -5
- package/dist/lib/definitions/index.js.map +1 -1
- package/dist/lib/model/AccessoryInfo.d.ts +4 -3
- package/dist/lib/model/AccessoryInfo.d.ts.map +1 -1
- package/dist/lib/model/AccessoryInfo.js +50 -53
- 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 +17 -22
- 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 +4 -11
- 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 +19 -27
- 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 +27 -29
- 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 +6 -9
- 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 +1 -5
- 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 +4 -9
- package/dist/lib/util/color-utils.js.map +1 -1
- package/dist/lib/util/eventedhttp.d.ts +23 -22
- package/dist/lib/util/eventedhttp.d.ts.map +1 -1
- package/dist/lib/util/eventedhttp.js +109 -116
- package/dist/lib/util/eventedhttp.js.map +1 -1
- package/dist/lib/util/hapCrypto.d.ts +3 -2
- package/dist/lib/util/hapCrypto.d.ts.map +1 -1
- package/dist/lib/util/hapCrypto.js +31 -40
- 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 +4 -8
- 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 +17 -23
- 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 +2 -6
- 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 +3 -9
- package/dist/lib/util/promise-utils.js.map +1 -1
- package/dist/lib/util/request-util.d.ts +3 -2
- package/dist/lib/util/request-util.d.ts.map +1 -1
- package/dist/lib/util/request-util.js +11 -19
- package/dist/lib/util/request-util.js.map +1 -1
- package/dist/lib/util/time.d.ts +1 -0
- package/dist/lib/util/time.d.ts.map +1 -1
- package/dist/lib/util/time.js +6 -11
- package/dist/lib/util/time.js.map +1 -1
- package/dist/lib/util/tlv.d.ts +1 -0
- package/dist/lib/util/tlv.d.ts.map +1 -1
- package/dist/lib/util/tlv.js +28 -43
- package/dist/lib/util/tlv.js.map +1 -1
- package/dist/lib/util/uuid.d.ts +1 -0
- package/dist/lib/util/uuid.d.ts.map +1 -1
- package/dist/lib/util/uuid.js +26 -38
- 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 +3 -5
- package/dist/types.js.map +1 -1
- package/package.json +48 -45
- package/@types/simple-plist.d.ts +0 -4
- package/dist/lib/gen/HomeKit.d.ts +0 -7
- package/dist/lib/gen/HomeKit.d.ts.map +0 -1
- package/dist/lib/gen/HomeKit.js +0 -8
- package/dist/lib/gen/HomeKit.js.map +0 -1
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
const tlv = tslib_1.__importStar(require("../util/tlv"));
|
|
12
|
-
const debug = (0, debug_1.default)("HAP-NodeJS:Remote:Controller");
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { Buffer } from 'node:buffer';
|
|
3
|
+
import { EventEmitter } from 'node:events';
|
|
4
|
+
import createDebug from 'debug';
|
|
5
|
+
import { Characteristic } from '../Characteristic.js';
|
|
6
|
+
import { DataStreamManagement, Float32, HDSStatus, Int64, } from '../datastream/index.js';
|
|
7
|
+
import { Service } from '../Service.js';
|
|
8
|
+
import { decode, decodeList, encode, readUInt16, readUInt32, writeUInt16, writeUInt32, writeVariableUIntLE, } from '../util/tlv.js';
|
|
9
|
+
const debug = createDebug('HAP-NodeJS:Remote:Controller');
|
|
10
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
13
11
|
var TargetControlCommands;
|
|
14
12
|
(function (TargetControlCommands) {
|
|
15
13
|
TargetControlCommands[TargetControlCommands["MAXIMUM_TARGETS"] = 1] = "MAXIMUM_TARGETS";
|
|
@@ -17,6 +15,7 @@ var TargetControlCommands;
|
|
|
17
15
|
TargetControlCommands[TargetControlCommands["SUPPORTED_BUTTON_CONFIGURATION"] = 3] = "SUPPORTED_BUTTON_CONFIGURATION";
|
|
18
16
|
TargetControlCommands[TargetControlCommands["TYPE"] = 4] = "TYPE";
|
|
19
17
|
})(TargetControlCommands || (TargetControlCommands = {}));
|
|
18
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
20
19
|
var SupportedButtonConfigurationTypes;
|
|
21
20
|
(function (SupportedButtonConfigurationTypes) {
|
|
22
21
|
SupportedButtonConfigurationTypes[SupportedButtonConfigurationTypes["BUTTON_ID"] = 1] = "BUTTON_ID";
|
|
@@ -25,9 +24,9 @@ var SupportedButtonConfigurationTypes;
|
|
|
25
24
|
/**
|
|
26
25
|
* @group Apple TV Remote
|
|
27
26
|
*/
|
|
28
|
-
|
|
27
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
28
|
+
export var ButtonType;
|
|
29
29
|
(function (ButtonType) {
|
|
30
|
-
// noinspection JSUnusedGlobalSymbols
|
|
31
30
|
ButtonType[ButtonType["UNDEFINED"] = 0] = "UNDEFINED";
|
|
32
31
|
ButtonType[ButtonType["MENU"] = 1] = "MENU";
|
|
33
32
|
ButtonType[ButtonType["PLAY_PAUSE"] = 2] = "PLAY_PAUSE";
|
|
@@ -42,7 +41,8 @@ var ButtonType;
|
|
|
42
41
|
ButtonType[ButtonType["SIRI"] = 11] = "SIRI";
|
|
43
42
|
ButtonType[ButtonType["POWER"] = 12] = "POWER";
|
|
44
43
|
ButtonType[ButtonType["GENERIC"] = 13] = "GENERIC";
|
|
45
|
-
})(ButtonType || (
|
|
44
|
+
})(ButtonType || (ButtonType = {}));
|
|
45
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
46
46
|
var TargetControlList;
|
|
47
47
|
(function (TargetControlList) {
|
|
48
48
|
TargetControlList[TargetControlList["OPERATION"] = 1] = "OPERATION";
|
|
@@ -50,7 +50,6 @@ var TargetControlList;
|
|
|
50
50
|
})(TargetControlList || (TargetControlList = {}));
|
|
51
51
|
var Operation;
|
|
52
52
|
(function (Operation) {
|
|
53
|
-
// noinspection JSUnusedGlobalSymbols
|
|
54
53
|
Operation[Operation["UNDEFINED"] = 0] = "UNDEFINED";
|
|
55
54
|
Operation[Operation["LIST"] = 1] = "LIST";
|
|
56
55
|
Operation[Operation["ADD"] = 2] = "ADD";
|
|
@@ -58,6 +57,7 @@ var Operation;
|
|
|
58
57
|
Operation[Operation["RESET"] = 4] = "RESET";
|
|
59
58
|
Operation[Operation["UPDATE"] = 5] = "UPDATE";
|
|
60
59
|
})(Operation || (Operation = {}));
|
|
60
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
61
61
|
var TargetConfigurationTypes;
|
|
62
62
|
(function (TargetConfigurationTypes) {
|
|
63
63
|
TargetConfigurationTypes[TargetConfigurationTypes["TARGET_IDENTIFIER"] = 1] = "TARGET_IDENTIFIER";
|
|
@@ -68,18 +68,20 @@ var TargetConfigurationTypes;
|
|
|
68
68
|
/**
|
|
69
69
|
* @group Apple TV Remote
|
|
70
70
|
*/
|
|
71
|
-
|
|
71
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
72
|
+
export var TargetCategory;
|
|
72
73
|
(function (TargetCategory) {
|
|
73
|
-
// noinspection JSUnusedGlobalSymbols
|
|
74
74
|
TargetCategory[TargetCategory["UNDEFINED"] = 0] = "UNDEFINED";
|
|
75
75
|
TargetCategory[TargetCategory["APPLE_TV"] = 24] = "APPLE_TV";
|
|
76
|
-
})(TargetCategory || (
|
|
76
|
+
})(TargetCategory || (TargetCategory = {}));
|
|
77
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
77
78
|
var ButtonConfigurationTypes;
|
|
78
79
|
(function (ButtonConfigurationTypes) {
|
|
79
80
|
ButtonConfigurationTypes[ButtonConfigurationTypes["BUTTON_ID"] = 1] = "BUTTON_ID";
|
|
80
81
|
ButtonConfigurationTypes[ButtonConfigurationTypes["BUTTON_TYPE"] = 2] = "BUTTON_TYPE";
|
|
81
82
|
ButtonConfigurationTypes[ButtonConfigurationTypes["BUTTON_NAME"] = 3] = "BUTTON_NAME";
|
|
82
83
|
})(ButtonConfigurationTypes || (ButtonConfigurationTypes = {}));
|
|
84
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
83
85
|
var ButtonEvent;
|
|
84
86
|
(function (ButtonEvent) {
|
|
85
87
|
ButtonEvent[ButtonEvent["BUTTON_ID"] = 1] = "BUTTON_ID";
|
|
@@ -90,22 +92,25 @@ var ButtonEvent;
|
|
|
90
92
|
/**
|
|
91
93
|
* @group Apple TV Remote
|
|
92
94
|
*/
|
|
93
|
-
|
|
95
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
96
|
+
export var ButtonState;
|
|
94
97
|
(function (ButtonState) {
|
|
95
98
|
ButtonState[ButtonState["UP"] = 0] = "UP";
|
|
96
99
|
ButtonState[ButtonState["DOWN"] = 1] = "DOWN";
|
|
97
|
-
})(ButtonState || (
|
|
100
|
+
})(ButtonState || (ButtonState = {}));
|
|
101
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
98
102
|
var SelectedAudioInputStreamConfigurationTypes;
|
|
99
103
|
(function (SelectedAudioInputStreamConfigurationTypes) {
|
|
100
104
|
SelectedAudioInputStreamConfigurationTypes[SelectedAudioInputStreamConfigurationTypes["SELECTED_AUDIO_INPUT_STREAM_CONFIGURATION"] = 1] = "SELECTED_AUDIO_INPUT_STREAM_CONFIGURATION";
|
|
101
105
|
})(SelectedAudioInputStreamConfigurationTypes || (SelectedAudioInputStreamConfigurationTypes = {}));
|
|
102
106
|
// ----------
|
|
107
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
103
108
|
var SupportedAudioStreamConfigurationTypes;
|
|
104
109
|
(function (SupportedAudioStreamConfigurationTypes) {
|
|
105
|
-
// noinspection JSUnusedGlobalSymbols
|
|
106
110
|
SupportedAudioStreamConfigurationTypes[SupportedAudioStreamConfigurationTypes["AUDIO_CODEC_CONFIGURATION"] = 1] = "AUDIO_CODEC_CONFIGURATION";
|
|
107
111
|
SupportedAudioStreamConfigurationTypes[SupportedAudioStreamConfigurationTypes["COMFORT_NOISE_SUPPORT"] = 2] = "COMFORT_NOISE_SUPPORT";
|
|
108
112
|
})(SupportedAudioStreamConfigurationTypes || (SupportedAudioStreamConfigurationTypes = {}));
|
|
113
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
109
114
|
var AudioCodecConfigurationTypes;
|
|
110
115
|
(function (AudioCodecConfigurationTypes) {
|
|
111
116
|
AudioCodecConfigurationTypes[AudioCodecConfigurationTypes["CODEC_TYPE"] = 1] = "CODEC_TYPE";
|
|
@@ -114,9 +119,9 @@ var AudioCodecConfigurationTypes;
|
|
|
114
119
|
/**
|
|
115
120
|
* @group Camera
|
|
116
121
|
*/
|
|
117
|
-
|
|
122
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
123
|
+
export var AudioCodecTypes;
|
|
118
124
|
(function (AudioCodecTypes) {
|
|
119
|
-
// noinspection JSUnusedGlobalSymbols
|
|
120
125
|
AudioCodecTypes[AudioCodecTypes["PCMU"] = 0] = "PCMU";
|
|
121
126
|
AudioCodecTypes[AudioCodecTypes["PCMA"] = 1] = "PCMA";
|
|
122
127
|
AudioCodecTypes[AudioCodecTypes["AAC_ELD"] = 2] = "AAC_ELD";
|
|
@@ -124,14 +129,16 @@ var AudioCodecTypes;
|
|
|
124
129
|
AudioCodecTypes[AudioCodecTypes["MSBC"] = 4] = "MSBC";
|
|
125
130
|
AudioCodecTypes[AudioCodecTypes["AMR"] = 5] = "AMR";
|
|
126
131
|
AudioCodecTypes[AudioCodecTypes["AMR_WB"] = 6] = "AMR_WB";
|
|
127
|
-
})(AudioCodecTypes || (
|
|
132
|
+
})(AudioCodecTypes || (AudioCodecTypes = {}));
|
|
133
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
128
134
|
var AudioCodecParametersTypes;
|
|
129
135
|
(function (AudioCodecParametersTypes) {
|
|
130
136
|
AudioCodecParametersTypes[AudioCodecParametersTypes["CHANNEL"] = 1] = "CHANNEL";
|
|
131
137
|
AudioCodecParametersTypes[AudioCodecParametersTypes["BIT_RATE"] = 2] = "BIT_RATE";
|
|
132
138
|
AudioCodecParametersTypes[AudioCodecParametersTypes["SAMPLE_RATE"] = 3] = "SAMPLE_RATE";
|
|
133
|
-
AudioCodecParametersTypes[AudioCodecParametersTypes["PACKET_TIME"] = 4] = "PACKET_TIME";
|
|
139
|
+
AudioCodecParametersTypes[AudioCodecParametersTypes["PACKET_TIME"] = 4] = "PACKET_TIME";
|
|
134
140
|
})(AudioCodecParametersTypes || (AudioCodecParametersTypes = {}));
|
|
141
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
135
142
|
var SiriAudioSessionState;
|
|
136
143
|
(function (SiriAudioSessionState) {
|
|
137
144
|
SiriAudioSessionState[SiriAudioSessionState["STARTING"] = 0] = "STARTING";
|
|
@@ -142,17 +149,19 @@ var SiriAudioSessionState;
|
|
|
142
149
|
/**
|
|
143
150
|
* @group Apple TV Remote
|
|
144
151
|
*/
|
|
145
|
-
|
|
152
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
153
|
+
export var TargetUpdates;
|
|
146
154
|
(function (TargetUpdates) {
|
|
147
155
|
TargetUpdates[TargetUpdates["NAME"] = 0] = "NAME";
|
|
148
156
|
TargetUpdates[TargetUpdates["CATEGORY"] = 1] = "CATEGORY";
|
|
149
157
|
TargetUpdates[TargetUpdates["UPDATED_BUTTONS"] = 2] = "UPDATED_BUTTONS";
|
|
150
158
|
TargetUpdates[TargetUpdates["REMOVED_BUTTONS"] = 3] = "REMOVED_BUTTONS";
|
|
151
|
-
})(TargetUpdates || (
|
|
159
|
+
})(TargetUpdates || (TargetUpdates = {}));
|
|
152
160
|
/**
|
|
153
161
|
* @group Apple TV Remote
|
|
154
162
|
*/
|
|
155
|
-
|
|
163
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
164
|
+
export var RemoteControllerEvents;
|
|
156
165
|
(function (RemoteControllerEvents) {
|
|
157
166
|
/**
|
|
158
167
|
* This event is emitted when the active state of the remote has changed.
|
|
@@ -186,18 +195,17 @@ var RemoteControllerEvents;
|
|
|
186
195
|
* when the accessory gets unpaired.
|
|
187
196
|
*/
|
|
188
197
|
RemoteControllerEvents["TARGETS_RESET"] = "targets-reset";
|
|
189
|
-
})(RemoteControllerEvents || (
|
|
198
|
+
})(RemoteControllerEvents || (RemoteControllerEvents = {}));
|
|
190
199
|
/**
|
|
191
200
|
* Handles everything needed to implement a fully working HomeKit remote controller.
|
|
192
201
|
*
|
|
193
202
|
* @group Apple TV Remote
|
|
194
203
|
*/
|
|
195
|
-
// eslint-disable-next-line
|
|
196
|
-
class RemoteController extends
|
|
204
|
+
// eslint-disable-next-line ts/no-unsafe-declaration-merging
|
|
205
|
+
export class RemoteController extends EventEmitter {
|
|
197
206
|
stateChangeDelegate;
|
|
198
207
|
audioSupported;
|
|
199
208
|
audioProducerConstructor;
|
|
200
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
201
209
|
audioProducerOptions;
|
|
202
210
|
targetControlManagementService;
|
|
203
211
|
targetControlService;
|
|
@@ -207,8 +215,8 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
207
215
|
buttons = {}; // internal mapping of buttonId to buttonType for supported buttons
|
|
208
216
|
supportedConfiguration;
|
|
209
217
|
targetConfigurations = new Map();
|
|
210
|
-
targetConfigurationsString =
|
|
211
|
-
lastButtonEvent =
|
|
218
|
+
targetConfigurationsString = '';
|
|
219
|
+
lastButtonEvent = '';
|
|
212
220
|
activeIdentifier = 0; // id of 0 means no device selected
|
|
213
221
|
activeConnection; // session which marked this remote as active and listens for events and siri
|
|
214
222
|
activeConnectionDisconnectListener;
|
|
@@ -235,9 +243,8 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
235
243
|
*
|
|
236
244
|
* @param audioProducerConstructor - constructor for a SiriAudioStreamProducer
|
|
237
245
|
* @param producerOptions - if supplied this argument will be supplied as third argument of the SiriAudioStreamProducer
|
|
238
|
-
*
|
|
246
|
+
* constructor. This should be used to supply configurations to the stream producer.
|
|
239
247
|
*/
|
|
240
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types
|
|
241
248
|
constructor(audioProducerConstructor, producerOptions) {
|
|
242
249
|
super();
|
|
243
250
|
this.audioSupported = audioProducerConstructor !== undefined;
|
|
@@ -276,11 +283,11 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
276
283
|
return;
|
|
277
284
|
}
|
|
278
285
|
if (activeIdentifier !== 0 && !this.targetConfigurations.has(activeIdentifier)) {
|
|
279
|
-
throw Error(
|
|
286
|
+
throw new Error('Tried setting unconfigured targetIdentifier to active');
|
|
280
287
|
}
|
|
281
|
-
debug(
|
|
288
|
+
debug('%d is now the active target', activeIdentifier);
|
|
282
289
|
this.activeIdentifier = activeIdentifier;
|
|
283
|
-
this.targetControlService.getCharacteristic(
|
|
290
|
+
this.targetControlService.getCharacteristic(Characteristic.ActiveIdentifier).updateValue(activeIdentifier);
|
|
284
291
|
if (this.activeAudioSession) {
|
|
285
292
|
this.handleSiriAudioStop();
|
|
286
293
|
}
|
|
@@ -310,7 +317,7 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
310
317
|
getTargetIdentifierByName(name) {
|
|
311
318
|
for (const [activeIdentifier, configuration] of Object.entries(this.targetConfigurations)) {
|
|
312
319
|
if (configuration.targetName === name) {
|
|
313
|
-
return parseInt(activeIdentifier, 10);
|
|
320
|
+
return Number.parseInt(activeIdentifier, 10);
|
|
314
321
|
}
|
|
315
322
|
}
|
|
316
323
|
return undefined;
|
|
@@ -351,14 +358,23 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
351
358
|
hardwareImplemented: this.audioSupported, // siri is only allowed for hardware implemented remotes
|
|
352
359
|
};
|
|
353
360
|
const supportedButtons = [
|
|
354
|
-
1 /* ButtonType.MENU */,
|
|
355
|
-
|
|
356
|
-
|
|
361
|
+
1 /* ButtonType.MENU */,
|
|
362
|
+
2 /* ButtonType.PLAY_PAUSE */,
|
|
363
|
+
3 /* ButtonType.TV_HOME */,
|
|
364
|
+
4 /* ButtonType.SELECT */,
|
|
365
|
+
5 /* ButtonType.ARROW_UP */,
|
|
366
|
+
6 /* ButtonType.ARROW_RIGHT */,
|
|
367
|
+
7 /* ButtonType.ARROW_DOWN */,
|
|
368
|
+
8 /* ButtonType.ARROW_LEFT */,
|
|
369
|
+
9 /* ButtonType.VOLUME_UP */,
|
|
370
|
+
10 /* ButtonType.VOLUME_DOWN */,
|
|
371
|
+
12 /* ButtonType.POWER */,
|
|
372
|
+
13 /* ButtonType.GENERIC */,
|
|
357
373
|
];
|
|
358
374
|
if (this.audioSupported) { // add siri button if this remote supports it
|
|
359
375
|
supportedButtons.push(11 /* ButtonType.SIRI */);
|
|
360
376
|
}
|
|
361
|
-
supportedButtons.forEach(button => {
|
|
377
|
+
supportedButtons.forEach((button) => {
|
|
362
378
|
const buttonConfiguration = {
|
|
363
379
|
buttonID: 100 + button,
|
|
364
380
|
buttonType: button,
|
|
@@ -382,16 +398,15 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
382
398
|
};
|
|
383
399
|
}
|
|
384
400
|
// --------------------------------- TARGET CONTROL ----------------------------------
|
|
385
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
386
401
|
handleTargetControlWrite(value, callback) {
|
|
387
|
-
const data = Buffer.from(value,
|
|
388
|
-
const objects =
|
|
402
|
+
const data = Buffer.from(value, 'base64');
|
|
403
|
+
const objects = decode(data);
|
|
389
404
|
const operation = objects[1 /* TargetControlList.OPERATION */][0];
|
|
390
|
-
let targetConfiguration
|
|
405
|
+
let targetConfiguration;
|
|
391
406
|
if (objects[2 /* TargetControlList.TARGET_CONFIGURATION */]) { // if target configuration was sent, parse it
|
|
392
407
|
targetConfiguration = this.parseTargetConfigurationTLV(objects[2 /* TargetControlList.TARGET_CONFIGURATION */]);
|
|
393
408
|
}
|
|
394
|
-
debug(
|
|
409
|
+
debug('Received TargetControl write operation %s', Operation[operation]);
|
|
395
410
|
let handler;
|
|
396
411
|
switch (operation) {
|
|
397
412
|
case Operation.ADD:
|
|
@@ -421,7 +436,7 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
421
436
|
}
|
|
422
437
|
}
|
|
423
438
|
else {
|
|
424
|
-
callback(new Error(status
|
|
439
|
+
callback(new Error(`${status}`));
|
|
425
440
|
}
|
|
426
441
|
}
|
|
427
442
|
handleAddTarget(targetConfiguration) {
|
|
@@ -429,7 +444,7 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
429
444
|
return -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */;
|
|
430
445
|
}
|
|
431
446
|
this.targetConfigurations.set(targetConfiguration.targetIdentifier, targetConfiguration);
|
|
432
|
-
debug(
|
|
447
|
+
debug(`Configured new target '${targetConfiguration.targetName}' with targetIdentifier '${targetConfiguration.targetIdentifier}'`);
|
|
433
448
|
setTimeout(() => this.emit("target-add" /* RemoteControllerEvents.TARGET_ADDED */, targetConfiguration), 0);
|
|
434
449
|
this.updatedTargetConfiguration(); // set response
|
|
435
450
|
return 0 /* HAPStatus.SUCCESS */;
|
|
@@ -444,17 +459,17 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
444
459
|
return -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */;
|
|
445
460
|
}
|
|
446
461
|
if (targetConfiguration.targetName) {
|
|
447
|
-
debug(
|
|
462
|
+
debug('Target name was updated \'%s\' => \'%s\' (%d)', configuredTarget.targetName, targetConfiguration.targetName, configuredTarget.targetIdentifier);
|
|
448
463
|
configuredTarget.targetName = targetConfiguration.targetName;
|
|
449
464
|
updates.push(0 /* TargetUpdates.NAME */);
|
|
450
465
|
}
|
|
451
466
|
if (targetConfiguration.targetCategory) {
|
|
452
|
-
debug(
|
|
467
|
+
debug('Target category was updated \'%d\' => \'%d\' for target \'%s\' (%d)', configuredTarget.targetCategory, targetConfiguration.targetCategory, configuredTarget.targetName, configuredTarget.targetIdentifier);
|
|
453
468
|
configuredTarget.targetCategory = targetConfiguration.targetCategory;
|
|
454
469
|
updates.push(1 /* TargetUpdates.CATEGORY */);
|
|
455
470
|
}
|
|
456
471
|
if (targetConfiguration.buttonConfiguration) {
|
|
457
|
-
debug(
|
|
472
|
+
debug('%d button configurations were updated for target \'%s\' (%d)', Object.keys(targetConfiguration.buttonConfiguration).length, configuredTarget.targetName, configuredTarget.targetIdentifier);
|
|
458
473
|
for (const configuration of Object.values(targetConfiguration.buttonConfiguration)) {
|
|
459
474
|
const savedConfiguration = configuredTarget.buttonConfiguration[configuration.buttonID];
|
|
460
475
|
savedConfiguration.buttonType = configuration.buttonType;
|
|
@@ -480,15 +495,15 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
480
495
|
delete configuredTarget.buttonConfiguration[key];
|
|
481
496
|
}
|
|
482
497
|
}
|
|
483
|
-
debug(
|
|
498
|
+
debug('Removed %d button configurations of target \'%s\' (%d)', Object.keys(targetConfiguration.buttonConfiguration).length, configuredTarget.targetName, configuredTarget.targetIdentifier);
|
|
484
499
|
setTimeout(() => this.emit("target-update" /* RemoteControllerEvents.TARGET_UPDATED */, configuredTarget, [3 /* TargetUpdates.REMOVED_BUTTONS */]), 0);
|
|
485
500
|
}
|
|
486
501
|
else {
|
|
487
502
|
this.targetConfigurations.delete(targetConfiguration.targetIdentifier);
|
|
488
|
-
debug(
|
|
503
|
+
debug('Target \'%s\' (%d) was removed', configuredTarget.targetName, configuredTarget.targetIdentifier);
|
|
489
504
|
setTimeout(() => this.emit("target-remove" /* RemoteControllerEvents.TARGET_REMOVED */, targetConfiguration.targetIdentifier), 0);
|
|
490
505
|
const keys = Object.keys(this.targetConfigurations);
|
|
491
|
-
this.setActiveIdentifier(keys.length === 0 ? 0 : parseInt(keys[0], 10)); // switch to next available remote
|
|
506
|
+
this.setActiveIdentifier(keys.length === 0 ? 0 : Number.parseInt(keys[0], 10)); // switch to next available remote
|
|
492
507
|
}
|
|
493
508
|
this.updatedTargetConfiguration(); // set response
|
|
494
509
|
return 0 /* HAPStatus.SUCCESS */;
|
|
@@ -497,7 +512,7 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
497
512
|
if (targetConfiguration) {
|
|
498
513
|
return -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */;
|
|
499
514
|
}
|
|
500
|
-
debug(
|
|
515
|
+
debug('Resetting all target configurations');
|
|
501
516
|
this.targetConfigurations = new Map();
|
|
502
517
|
this.updatedTargetConfiguration(); // set response
|
|
503
518
|
setTimeout(() => this.emit("targets-reset" /* RemoteControllerEvents.TARGETS_RESET */), 0);
|
|
@@ -509,12 +524,12 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
509
524
|
return -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */;
|
|
510
525
|
}
|
|
511
526
|
// this.targetConfigurationsString is updated after each change, so we basically don't need to do anything here
|
|
512
|
-
debug(
|
|
527
|
+
debug(`Returning ${Object.keys(this.targetConfigurations).length} target configurations`);
|
|
513
528
|
return 0 /* HAPStatus.SUCCESS */;
|
|
514
529
|
}
|
|
515
530
|
handleActiveWrite(value, callback, connection) {
|
|
516
531
|
if (this.activeIdentifier === 0) {
|
|
517
|
-
debug(
|
|
532
|
+
debug('Tried to change active state. There is no active target set though');
|
|
518
533
|
callback(-70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */);
|
|
519
534
|
return;
|
|
520
535
|
}
|
|
@@ -533,7 +548,7 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
533
548
|
callback(-70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */);
|
|
534
549
|
return;
|
|
535
550
|
}
|
|
536
|
-
debug(
|
|
551
|
+
debug('Remote with activeTarget \'%s\' (%d) was set to %s', activeTarget.targetName, this.activeIdentifier, value ? 'ACTIVE' : 'INACTIVE');
|
|
537
552
|
callback();
|
|
538
553
|
this.emit("active-change" /* RemoteControllerEvents.ACTIVE_CHANGE */, value);
|
|
539
554
|
}
|
|
@@ -544,27 +559,27 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
544
559
|
this.activeConnection.removeListener("closed" /* HAPConnectionEvent.CLOSED */, this.activeConnectionDisconnectListener);
|
|
545
560
|
this.activeConnection = undefined;
|
|
546
561
|
this.activeConnectionDisconnectListener = undefined;
|
|
547
|
-
this.targetControlService.getCharacteristic(
|
|
548
|
-
debug(
|
|
562
|
+
this.targetControlService.getCharacteristic(Characteristic.Active).updateValue(false);
|
|
563
|
+
debug('Remote was set to INACTIVE');
|
|
549
564
|
setTimeout(() => this.emit("active-change" /* RemoteControllerEvents.ACTIVE_CHANGE */, false), 0);
|
|
550
565
|
}
|
|
551
566
|
handleActiveSessionDisconnected(connection) {
|
|
552
567
|
if (connection !== this.activeConnection) {
|
|
553
568
|
return;
|
|
554
569
|
}
|
|
555
|
-
debug(
|
|
570
|
+
debug('Active hap session disconnected!');
|
|
556
571
|
this.setInactive();
|
|
557
572
|
}
|
|
558
573
|
sendButtonEvent(button, buttonState) {
|
|
559
574
|
const buttonID = this.buttons[button];
|
|
560
575
|
if (buttonID === undefined || buttonID === 0) {
|
|
561
|
-
throw new Error(
|
|
576
|
+
throw new Error(`Tried sending button event for unsupported button (${button})`);
|
|
562
577
|
}
|
|
563
578
|
if (this.activeIdentifier === 0) { // cannot press button if no device is selected
|
|
564
|
-
throw new Error(
|
|
579
|
+
throw new Error('Tried sending button event although no target was selected');
|
|
565
580
|
}
|
|
566
581
|
if (!this.isActive()) { // cannot press button if device is not active (aka no Apple TV is listening)
|
|
567
|
-
throw new Error(
|
|
582
|
+
throw new Error('Tried sending button event although target was not marked as active');
|
|
568
583
|
}
|
|
569
584
|
if (button === 11 /* ButtonType.SIRI */ && this.audioSupported) {
|
|
570
585
|
if (buttonState === 1 /* ButtonState.DOWN */) { // start streaming session
|
|
@@ -575,32 +590,35 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
575
590
|
}
|
|
576
591
|
return;
|
|
577
592
|
}
|
|
578
|
-
const buttonIdTlv =
|
|
579
|
-
const buttonStateTlv =
|
|
580
|
-
const timestampTlv =
|
|
581
|
-
const activeIdentifierTlv =
|
|
593
|
+
const buttonIdTlv = encode(1 /* ButtonEvent.BUTTON_ID */, buttonID);
|
|
594
|
+
const buttonStateTlv = encode(2 /* ButtonEvent.BUTTON_STATE */, buttonState);
|
|
595
|
+
const timestampTlv = encode(3 /* ButtonEvent.TIMESTAMP */, writeVariableUIntLE(new Date().getTime()));
|
|
596
|
+
const activeIdentifierTlv = encode(4 /* ButtonEvent.ACTIVE_IDENTIFIER */, writeUInt32(this.activeIdentifier));
|
|
582
597
|
this.lastButtonEvent = Buffer.concat([
|
|
583
|
-
buttonIdTlv,
|
|
584
|
-
|
|
585
|
-
|
|
598
|
+
buttonIdTlv,
|
|
599
|
+
buttonStateTlv,
|
|
600
|
+
timestampTlv,
|
|
601
|
+
activeIdentifierTlv,
|
|
602
|
+
]).toString('base64');
|
|
603
|
+
this.targetControlService.getCharacteristic(Characteristic.ButtonEvent).sendEventNotification(this.lastButtonEvent);
|
|
586
604
|
}
|
|
587
605
|
parseTargetConfigurationTLV(data) {
|
|
588
|
-
const configTLV =
|
|
589
|
-
const identifier =
|
|
590
|
-
let name
|
|
606
|
+
const configTLV = decode(data);
|
|
607
|
+
const identifier = readUInt32(configTLV[1 /* TargetConfigurationTypes.TARGET_IDENTIFIER */]);
|
|
608
|
+
let name;
|
|
591
609
|
if (configTLV[2 /* TargetConfigurationTypes.TARGET_NAME */]) {
|
|
592
610
|
name = configTLV[2 /* TargetConfigurationTypes.TARGET_NAME */].toString();
|
|
593
611
|
}
|
|
594
|
-
let category
|
|
612
|
+
let category;
|
|
595
613
|
if (configTLV[3 /* TargetConfigurationTypes.TARGET_CATEGORY */]) {
|
|
596
|
-
category =
|
|
614
|
+
category = readUInt16(configTLV[3 /* TargetConfigurationTypes.TARGET_CATEGORY */]);
|
|
597
615
|
}
|
|
598
616
|
const buttonConfiguration = {};
|
|
599
617
|
if (configTLV[4 /* TargetConfigurationTypes.BUTTON_CONFIGURATION */]) {
|
|
600
|
-
const buttonConfigurationTLV =
|
|
601
|
-
buttonConfigurationTLV.forEach(entry => {
|
|
618
|
+
const buttonConfigurationTLV = decodeList(configTLV[4 /* TargetConfigurationTypes.BUTTON_CONFIGURATION */], 1 /* ButtonConfigurationTypes.BUTTON_ID */);
|
|
619
|
+
buttonConfigurationTLV.forEach((entry) => {
|
|
602
620
|
const buttonId = entry[1 /* ButtonConfigurationTypes.BUTTON_ID */][0];
|
|
603
|
-
const buttonType =
|
|
621
|
+
const buttonType = readUInt16(entry[2 /* ButtonConfigurationTypes.BUTTON_TYPE */]);
|
|
604
622
|
let buttonName;
|
|
605
623
|
if (entry[3 /* ButtonConfigurationTypes.BUTTON_NAME */]) {
|
|
606
624
|
buttonName = entry[3 /* ButtonConfigurationTypes.BUTTON_NAME */].toString();
|
|
@@ -611,8 +629,8 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
611
629
|
}
|
|
612
630
|
buttonConfiguration[buttonId] = {
|
|
613
631
|
buttonID: buttonId,
|
|
614
|
-
buttonType
|
|
615
|
-
buttonName
|
|
632
|
+
buttonType,
|
|
633
|
+
buttonName,
|
|
616
634
|
};
|
|
617
635
|
});
|
|
618
636
|
}
|
|
@@ -620,73 +638,72 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
620
638
|
targetIdentifier: identifier,
|
|
621
639
|
targetName: name,
|
|
622
640
|
targetCategory: category,
|
|
623
|
-
buttonConfiguration
|
|
641
|
+
buttonConfiguration,
|
|
624
642
|
};
|
|
625
643
|
}
|
|
626
644
|
updatedTargetConfiguration() {
|
|
627
645
|
const bufferList = [];
|
|
628
646
|
for (const configuration of Object.values(this.targetConfigurations)) {
|
|
629
|
-
const targetIdentifier =
|
|
630
|
-
const targetName =
|
|
631
|
-
const targetCategory =
|
|
647
|
+
const targetIdentifier = encode(1 /* TargetConfigurationTypes.TARGET_IDENTIFIER */, writeUInt32(configuration.targetIdentifier));
|
|
648
|
+
const targetName = encode(2 /* TargetConfigurationTypes.TARGET_NAME */, configuration.targetName);
|
|
649
|
+
const targetCategory = encode(3 /* TargetConfigurationTypes.TARGET_CATEGORY */, writeUInt16(configuration.targetCategory));
|
|
632
650
|
const buttonConfigurationBuffers = [];
|
|
633
651
|
for (const value of configuration.buttonConfiguration.values()) {
|
|
634
|
-
let tlvBuffer =
|
|
652
|
+
let tlvBuffer = encode(1 /* ButtonConfigurationTypes.BUTTON_ID */, value.buttonID, 2 /* ButtonConfigurationTypes.BUTTON_TYPE */, writeUInt16(value.buttonType));
|
|
635
653
|
if (value.buttonName) {
|
|
636
654
|
tlvBuffer = Buffer.concat([
|
|
637
655
|
tlvBuffer,
|
|
638
|
-
|
|
656
|
+
encode(3 /* ButtonConfigurationTypes.BUTTON_NAME */, value.buttonName),
|
|
639
657
|
]);
|
|
640
658
|
}
|
|
641
659
|
buttonConfigurationBuffers.push(tlvBuffer);
|
|
642
660
|
}
|
|
643
|
-
const buttonConfiguration =
|
|
661
|
+
const buttonConfiguration = encode(4 /* TargetConfigurationTypes.BUTTON_CONFIGURATION */, Buffer.concat(buttonConfigurationBuffers));
|
|
644
662
|
const targetConfiguration = Buffer.concat([targetIdentifier, targetName, targetCategory, buttonConfiguration]);
|
|
645
|
-
bufferList.push(
|
|
663
|
+
bufferList.push(encode(2 /* TargetControlList.TARGET_CONFIGURATION */, targetConfiguration));
|
|
646
664
|
}
|
|
647
|
-
this.targetConfigurationsString = Buffer.concat(bufferList).toString(
|
|
665
|
+
this.targetConfigurationsString = Buffer.concat(bufferList).toString('base64');
|
|
648
666
|
this.stateChangeDelegate?.();
|
|
649
667
|
}
|
|
650
668
|
buildTargetControlSupportedConfigurationTLV(configuration) {
|
|
651
|
-
const maximumTargets =
|
|
652
|
-
const ticksPerSecond =
|
|
669
|
+
const maximumTargets = encode(1 /* TargetControlCommands.MAXIMUM_TARGETS */, configuration.maximumTargets);
|
|
670
|
+
const ticksPerSecond = encode(2 /* TargetControlCommands.TICKS_PER_SECOND */, writeVariableUIntLE(configuration.ticksPerSecond));
|
|
653
671
|
const supportedButtonConfigurationBuffers = [];
|
|
654
|
-
configuration.supportedButtonConfiguration.forEach(value => {
|
|
655
|
-
const tlvBuffer =
|
|
672
|
+
configuration.supportedButtonConfiguration.forEach((value) => {
|
|
673
|
+
const tlvBuffer = encode(1 /* SupportedButtonConfigurationTypes.BUTTON_ID */, value.buttonID, 2 /* SupportedButtonConfigurationTypes.BUTTON_TYPE */, writeUInt16(value.buttonType));
|
|
656
674
|
supportedButtonConfigurationBuffers.push(tlvBuffer);
|
|
657
675
|
});
|
|
658
|
-
const supportedButtonConfiguration =
|
|
659
|
-
const type =
|
|
660
|
-
return Buffer.concat([maximumTargets, ticksPerSecond, supportedButtonConfiguration, type]).toString(
|
|
676
|
+
const supportedButtonConfiguration = encode(3 /* TargetControlCommands.SUPPORTED_BUTTON_CONFIGURATION */, Buffer.concat(supportedButtonConfigurationBuffers));
|
|
677
|
+
const type = encode(4 /* TargetControlCommands.TYPE */, configuration.hardwareImplemented ? 1 : 0);
|
|
678
|
+
return Buffer.concat([maximumTargets, ticksPerSecond, supportedButtonConfiguration, type]).toString('base64');
|
|
661
679
|
}
|
|
662
680
|
// --------------------------------- SIRI/DATA STREAM --------------------------------
|
|
663
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
664
681
|
handleTargetControlWhoAmI(connection, message) {
|
|
665
682
|
const targetIdentifier = message.identifier;
|
|
666
683
|
this.dataStreamConnections.set(targetIdentifier, connection);
|
|
667
|
-
debug(
|
|
684
|
+
debug('Discovered HDS connection for targetIdentifier %s', targetIdentifier);
|
|
668
685
|
connection.addProtocolHandler("dataSend" /* Protocols.DATA_SEND */, this);
|
|
669
686
|
}
|
|
670
687
|
handleSiriAudioStart() {
|
|
671
688
|
if (!this.audioSupported) {
|
|
672
|
-
throw new Error(
|
|
689
|
+
throw new Error('Cannot start siri stream on remote where siri is not supported');
|
|
673
690
|
}
|
|
674
691
|
if (!this.isActive()) {
|
|
675
|
-
debug(
|
|
692
|
+
debug('Tried opening Siri audio stream, however no controller is connected!');
|
|
676
693
|
return;
|
|
677
694
|
}
|
|
678
695
|
if (this.activeAudioSession && (!this.activeAudioSession.isClosing() || this.nextAudioSession)) {
|
|
679
696
|
// there is already a session running, which is not in closing state and/or there is even already a
|
|
680
697
|
// nextAudioSession running. ignoring start request
|
|
681
|
-
debug(
|
|
698
|
+
debug('Tried opening Siri audio stream, however there is already one in progress');
|
|
682
699
|
return;
|
|
683
700
|
}
|
|
684
701
|
const connection = this.dataStreamConnections.get(this.activeIdentifier); // get connection for current target
|
|
685
702
|
if (connection === undefined) { // target seems not connected, ignore it
|
|
686
|
-
debug(
|
|
703
|
+
debug('Tried opening Siri audio stream however target is not connected via HDS');
|
|
687
704
|
return;
|
|
688
705
|
}
|
|
689
|
-
// eslint-disable-next-line
|
|
706
|
+
// eslint-disable-next-line ts/no-use-before-define
|
|
690
707
|
const audioSession = new SiriAudioSession(connection, this.selectedAudioConfiguration, this.audioProducerConstructor, this.audioProducerOptions);
|
|
691
708
|
if (!this.activeAudioSession) {
|
|
692
709
|
this.activeAudioSession = audioSession;
|
|
@@ -696,6 +713,7 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
696
713
|
// so no collision with the input device can happen
|
|
697
714
|
this.nextAudioSession = audioSession;
|
|
698
715
|
}
|
|
716
|
+
// eslint-disable-next-line ts/no-use-before-define
|
|
699
717
|
audioSession.on("close" /* SiriAudioSessionEvents.CLOSE */, this.handleSiriAudioSessionClosed.bind(this, audioSession));
|
|
700
718
|
audioSession.start();
|
|
701
719
|
}
|
|
@@ -710,9 +728,8 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
710
728
|
return;
|
|
711
729
|
}
|
|
712
730
|
}
|
|
713
|
-
debug(
|
|
731
|
+
debug('handleSiriAudioStop called although no audio session was started');
|
|
714
732
|
}
|
|
715
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
716
733
|
handleDataSendAckEvent(message) {
|
|
717
734
|
const streamId = message.streamId;
|
|
718
735
|
const endOfStream = message.endOfStream;
|
|
@@ -723,10 +740,9 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
723
740
|
this.nextAudioSession.handleDataSendAckEvent(endOfStream);
|
|
724
741
|
}
|
|
725
742
|
else {
|
|
726
|
-
debug(
|
|
743
|
+
debug('Received dataSend acknowledgment event for unknown streamId \'%s\'', streamId);
|
|
727
744
|
}
|
|
728
745
|
}
|
|
729
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
730
746
|
handleDataSendCloseEvent(message) {
|
|
731
747
|
const streamId = message.streamId;
|
|
732
748
|
const reason = message.reason;
|
|
@@ -737,7 +753,7 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
737
753
|
this.nextAudioSession.handleDataSendCloseEvent(reason);
|
|
738
754
|
}
|
|
739
755
|
else {
|
|
740
|
-
debug(
|
|
756
|
+
debug('Received dataSend close event for unknown streamId \'%s\'', streamId);
|
|
741
757
|
}
|
|
742
758
|
}
|
|
743
759
|
handleSiriAudioSessionClosed(session) {
|
|
@@ -752,29 +768,28 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
752
768
|
handleDataStreamConnectionClosed(connection) {
|
|
753
769
|
for (const [targetIdentifier, connection0] of this.dataStreamConnections) {
|
|
754
770
|
if (connection === connection0) {
|
|
755
|
-
debug(
|
|
771
|
+
debug('HDS connection disconnected for targetIdentifier %s', targetIdentifier);
|
|
756
772
|
this.dataStreamConnections.delete(targetIdentifier);
|
|
757
773
|
break;
|
|
758
774
|
}
|
|
759
775
|
}
|
|
760
776
|
}
|
|
761
777
|
// ------------------------------- AUDIO CONFIGURATION -------------------------------
|
|
762
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
763
778
|
handleSelectedAudioConfigurationWrite(value, callback) {
|
|
764
|
-
const data = Buffer.from(value,
|
|
765
|
-
const objects =
|
|
766
|
-
const selectedAudioStreamConfiguration =
|
|
779
|
+
const data = Buffer.from(value, 'base64');
|
|
780
|
+
const objects = decode(data);
|
|
781
|
+
const selectedAudioStreamConfiguration = decode(objects[1 /* SelectedAudioInputStreamConfigurationTypes.SELECTED_AUDIO_INPUT_STREAM_CONFIGURATION */]);
|
|
767
782
|
const codec = selectedAudioStreamConfiguration[1 /* AudioCodecConfigurationTypes.CODEC_TYPE */][0];
|
|
768
|
-
const parameters =
|
|
783
|
+
const parameters = decode(selectedAudioStreamConfiguration[2 /* AudioCodecConfigurationTypes.CODEC_PARAMETERS */]);
|
|
769
784
|
const channels = parameters[1 /* AudioCodecParametersTypes.CHANNEL */][0];
|
|
770
785
|
const bitrate = parameters[2 /* AudioCodecParametersTypes.BIT_RATE */][0];
|
|
771
786
|
const samplerate = parameters[3 /* AudioCodecParametersTypes.SAMPLE_RATE */][0];
|
|
772
787
|
this.selectedAudioConfiguration = {
|
|
773
788
|
codecType: codec,
|
|
774
789
|
parameters: {
|
|
775
|
-
channels
|
|
776
|
-
bitrate
|
|
777
|
-
samplerate
|
|
790
|
+
channels,
|
|
791
|
+
bitrate,
|
|
792
|
+
samplerate,
|
|
778
793
|
rtpTime: 20,
|
|
779
794
|
},
|
|
780
795
|
};
|
|
@@ -785,47 +800,47 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
785
800
|
}
|
|
786
801
|
static buildSupportedAudioConfigurationTLV(configuration) {
|
|
787
802
|
const codecConfigurationTLV = RemoteController.buildCodecConfigurationTLV(configuration.audioCodecConfiguration);
|
|
788
|
-
const supportedAudioStreamConfiguration =
|
|
789
|
-
return supportedAudioStreamConfiguration.toString(
|
|
803
|
+
const supportedAudioStreamConfiguration = encode(1 /* SupportedAudioStreamConfigurationTypes.AUDIO_CODEC_CONFIGURATION */, codecConfigurationTLV);
|
|
804
|
+
return supportedAudioStreamConfiguration.toString('base64');
|
|
790
805
|
}
|
|
791
806
|
static buildSelectedAudioConfigurationTLV(configuration) {
|
|
792
807
|
const codecConfigurationTLV = RemoteController.buildCodecConfigurationTLV(configuration.audioCodecConfiguration);
|
|
793
|
-
const supportedAudioStreamConfiguration =
|
|
794
|
-
return supportedAudioStreamConfiguration.toString(
|
|
808
|
+
const supportedAudioStreamConfiguration = encode(1 /* SelectedAudioInputStreamConfigurationTypes.SELECTED_AUDIO_INPUT_STREAM_CONFIGURATION */, codecConfigurationTLV);
|
|
809
|
+
return supportedAudioStreamConfiguration.toString('base64');
|
|
795
810
|
}
|
|
796
811
|
static buildCodecConfigurationTLV(codecConfiguration) {
|
|
797
812
|
const parameters = codecConfiguration.parameters;
|
|
798
|
-
let parametersTLV =
|
|
813
|
+
let parametersTLV = encode(1 /* AudioCodecParametersTypes.CHANNEL */, parameters.channels, 2 /* AudioCodecParametersTypes.BIT_RATE */, parameters.bitrate, 3 /* AudioCodecParametersTypes.SAMPLE_RATE */, parameters.samplerate);
|
|
799
814
|
if (parameters.rtpTime) {
|
|
800
815
|
parametersTLV = Buffer.concat([
|
|
801
816
|
parametersTLV,
|
|
802
|
-
|
|
817
|
+
encode(4 /* AudioCodecParametersTypes.PACKET_TIME */, parameters.rtpTime),
|
|
803
818
|
]);
|
|
804
819
|
}
|
|
805
|
-
return
|
|
820
|
+
return encode(1 /* AudioCodecConfigurationTypes.CODEC_TYPE */, codecConfiguration.codecType, 2 /* AudioCodecConfigurationTypes.CODEC_PARAMETERS */, parametersTLV);
|
|
806
821
|
}
|
|
807
822
|
// -----------------------------------------------------------------------------------
|
|
808
823
|
/**
|
|
809
824
|
* @private
|
|
810
825
|
*/
|
|
811
826
|
constructServices() {
|
|
812
|
-
this.targetControlManagementService = new
|
|
813
|
-
this.targetControlManagementService.setCharacteristic(
|
|
814
|
-
this.targetControlManagementService.setCharacteristic(
|
|
827
|
+
this.targetControlManagementService = new Service.TargetControlManagement('', '');
|
|
828
|
+
this.targetControlManagementService.setCharacteristic(Characteristic.TargetControlSupportedConfiguration, this.supportedConfiguration);
|
|
829
|
+
this.targetControlManagementService.setCharacteristic(Characteristic.TargetControlList, this.targetConfigurationsString);
|
|
815
830
|
this.targetControlManagementService.setPrimaryService();
|
|
816
831
|
// you can also expose multiple TargetControl services to control multiple apple tvs simultaneously.
|
|
817
832
|
// should we extend this class to support multiple TargetControl services or should users just create a second accessory?
|
|
818
|
-
this.targetControlService = new
|
|
819
|
-
this.targetControlService.setCharacteristic(
|
|
820
|
-
this.targetControlService.setCharacteristic(
|
|
821
|
-
this.targetControlService.setCharacteristic(
|
|
833
|
+
this.targetControlService = new Service.TargetControl('', '');
|
|
834
|
+
this.targetControlService.setCharacteristic(Characteristic.ActiveIdentifier, 0);
|
|
835
|
+
this.targetControlService.setCharacteristic(Characteristic.Active, false);
|
|
836
|
+
this.targetControlService.setCharacteristic(Characteristic.ButtonEvent, this.lastButtonEvent);
|
|
822
837
|
if (this.audioSupported) {
|
|
823
|
-
this.siriService = new
|
|
824
|
-
this.siriService.setCharacteristic(
|
|
825
|
-
this.audioStreamManagementService = new
|
|
826
|
-
this.audioStreamManagementService.setCharacteristic(
|
|
827
|
-
this.audioStreamManagementService.setCharacteristic(
|
|
828
|
-
this.dataStreamManagement = new
|
|
838
|
+
this.siriService = new Service.Siri('', '');
|
|
839
|
+
this.siriService.setCharacteristic(Characteristic.SiriInputType, Characteristic.SiriInputType.PUSH_BUTTON_TRIGGERED_APPLE_TV);
|
|
840
|
+
this.audioStreamManagementService = new Service.AudioStreamManagement('', '');
|
|
841
|
+
this.audioStreamManagementService.setCharacteristic(Characteristic.SupportedAudioStreamConfiguration, this.supportedAudioConfiguration);
|
|
842
|
+
this.audioStreamManagementService.setCharacteristic(Characteristic.SelectedAudioStreamConfiguration, this.selectedAudioConfigurationString);
|
|
843
|
+
this.dataStreamManagement = new DataStreamManagement();
|
|
829
844
|
this.siriService.addLinkedService(this.dataStreamManagement.getService());
|
|
830
845
|
this.siriService.addLinkedService(this.audioStreamManagementService);
|
|
831
846
|
}
|
|
@@ -845,43 +860,43 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
845
860
|
this.targetControlService = serviceMap.targetControl;
|
|
846
861
|
this.siriService = serviceMap.siri;
|
|
847
862
|
this.audioStreamManagementService = serviceMap.audioStreamManagement;
|
|
848
|
-
this.dataStreamManagement = new
|
|
863
|
+
this.dataStreamManagement = new DataStreamManagement(serviceMap.dataStreamTransportManagement);
|
|
849
864
|
}
|
|
850
865
|
/**
|
|
851
866
|
* @private
|
|
852
867
|
*/
|
|
853
868
|
configureServices() {
|
|
854
869
|
if (!this.targetControlManagementService || !this.targetControlService) {
|
|
855
|
-
throw new Error(
|
|
870
|
+
throw new Error('Unexpected state: Services not configured!'); // playing it save
|
|
856
871
|
}
|
|
857
|
-
this.targetControlManagementService.getCharacteristic(
|
|
858
|
-
.on("get" /* CharacteristicEventTypes.GET */, callback => {
|
|
872
|
+
this.targetControlManagementService.getCharacteristic(Characteristic.TargetControlList)
|
|
873
|
+
.on("get" /* CharacteristicEventTypes.GET */, (callback) => {
|
|
859
874
|
callback(null, this.targetConfigurationsString);
|
|
860
875
|
})
|
|
861
876
|
.on("set" /* CharacteristicEventTypes.SET */, this.handleTargetControlWrite.bind(this));
|
|
862
|
-
this.targetControlService.getCharacteristic(
|
|
863
|
-
.on("get" /* CharacteristicEventTypes.GET */, callback => {
|
|
877
|
+
this.targetControlService.getCharacteristic(Characteristic.ActiveIdentifier)
|
|
878
|
+
.on("get" /* CharacteristicEventTypes.GET */, (callback) => {
|
|
864
879
|
callback(undefined, this.activeIdentifier);
|
|
865
880
|
});
|
|
866
|
-
this.targetControlService.getCharacteristic(
|
|
867
|
-
.on("get" /* CharacteristicEventTypes.GET */, callback => {
|
|
881
|
+
this.targetControlService.getCharacteristic(Characteristic.Active)
|
|
882
|
+
.on("get" /* CharacteristicEventTypes.GET */, (callback) => {
|
|
868
883
|
callback(undefined, this.isActive());
|
|
869
884
|
})
|
|
870
885
|
.on("set" /* CharacteristicEventTypes.SET */, (value, callback, context, connection) => {
|
|
871
886
|
if (!connection) {
|
|
872
|
-
debug(
|
|
887
|
+
debug('Set event handler for Remote.Active cannot be called from plugin. Connection undefined!');
|
|
873
888
|
callback(-70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */);
|
|
874
889
|
return;
|
|
875
890
|
}
|
|
876
891
|
this.handleActiveWrite(value, callback, connection);
|
|
877
892
|
});
|
|
878
|
-
this.targetControlService.getCharacteristic(
|
|
893
|
+
this.targetControlService.getCharacteristic(Characteristic.ButtonEvent)
|
|
879
894
|
.on("get" /* CharacteristicEventTypes.GET */, (callback) => {
|
|
880
895
|
callback(undefined, this.lastButtonEvent);
|
|
881
896
|
});
|
|
882
897
|
if (this.audioSupported) {
|
|
883
|
-
this.audioStreamManagementService.getCharacteristic(
|
|
884
|
-
.on("get" /* CharacteristicEventTypes.GET */, callback => {
|
|
898
|
+
this.audioStreamManagementService.getCharacteristic(Characteristic.SelectedAudioStreamConfiguration)
|
|
899
|
+
.on("get" /* CharacteristicEventTypes.GET */, (callback) => {
|
|
885
900
|
callback(null, this.selectedAudioConfigurationString);
|
|
886
901
|
})
|
|
887
902
|
.on("set" /* CharacteristicEventTypes.SET */, this.handleSelectedAudioConfigurationWrite.bind(this))
|
|
@@ -916,9 +931,9 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
916
931
|
* @private
|
|
917
932
|
*/
|
|
918
933
|
handleFactoryReset() {
|
|
919
|
-
debug(
|
|
934
|
+
debug('Running factory reset. Resetting targets...');
|
|
920
935
|
this.handleResetTargets(undefined);
|
|
921
|
-
this.lastButtonEvent =
|
|
936
|
+
this.lastButtonEvent = '';
|
|
922
937
|
}
|
|
923
938
|
/**
|
|
924
939
|
* @private
|
|
@@ -941,7 +956,7 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
941
956
|
deserialize(serialized) {
|
|
942
957
|
this.activeIdentifier = serialized.activeIdentifier;
|
|
943
958
|
this.targetConfigurations = Object.entries(serialized.targetConfigurations).reduce((map, [key, value]) => {
|
|
944
|
-
const identifier = parseInt(key, 10);
|
|
959
|
+
const identifier = Number.parseInt(key, 10);
|
|
945
960
|
map.set(identifier, value);
|
|
946
961
|
return map;
|
|
947
962
|
}, new Map());
|
|
@@ -954,27 +969,27 @@ class RemoteController extends events_1.EventEmitter {
|
|
|
954
969
|
this.stateChangeDelegate = delegate;
|
|
955
970
|
}
|
|
956
971
|
}
|
|
957
|
-
exports.RemoteController = RemoteController;
|
|
958
972
|
/**
|
|
959
973
|
* @group Apple TV Remote
|
|
960
974
|
*/
|
|
961
|
-
|
|
975
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
976
|
+
export var SiriAudioSessionEvents;
|
|
962
977
|
(function (SiriAudioSessionEvents) {
|
|
963
978
|
SiriAudioSessionEvents["CLOSE"] = "close";
|
|
964
|
-
})(SiriAudioSessionEvents || (
|
|
979
|
+
})(SiriAudioSessionEvents || (SiriAudioSessionEvents = {}));
|
|
965
980
|
/**
|
|
966
981
|
* Represents an ongoing audio transmission
|
|
967
982
|
* @group Apple TV Remote
|
|
968
983
|
*/
|
|
969
|
-
// eslint-disable-next-line
|
|
970
|
-
class SiriAudioSession extends
|
|
984
|
+
// eslint-disable-next-line ts/no-unsafe-declaration-merging
|
|
985
|
+
export class SiriAudioSession extends EventEmitter {
|
|
971
986
|
connection;
|
|
972
987
|
selectedAudioConfiguration;
|
|
973
988
|
producer;
|
|
974
989
|
producerRunning = false; // indicates if the producer is running
|
|
975
990
|
producerTimer; // producer has a 3s timeout to produce the first frame, otherwise transmission will be cancelled
|
|
976
991
|
/**
|
|
977
|
-
* @private
|
|
992
|
+
* @private
|
|
978
993
|
*/
|
|
979
994
|
state = 0 /* SiriAudioSessionState.STARTING */;
|
|
980
995
|
streamId; // present when state >= SENDING
|
|
@@ -983,12 +998,11 @@ class SiriAudioSession extends events_1.EventEmitter {
|
|
|
983
998
|
maxQueueSize = 1024;
|
|
984
999
|
sequenceNumber = 0;
|
|
985
1000
|
closeListener;
|
|
986
|
-
constructor(connection, selectedAudioConfiguration, producerConstructor,
|
|
987
|
-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types,@typescript-eslint/no-explicit-any
|
|
988
|
-
producerOptions) {
|
|
1001
|
+
constructor(connection, selectedAudioConfiguration, producerConstructor, producerOptions) {
|
|
989
1002
|
super();
|
|
990
1003
|
this.connection = connection;
|
|
991
1004
|
this.selectedAudioConfiguration = selectedAudioConfiguration;
|
|
1005
|
+
// eslint-disable-next-line new-cap
|
|
992
1006
|
this.producer = new producerConstructor(this.handleSiriAudioFrame.bind(this), this.handleProducerError.bind(this), producerOptions);
|
|
993
1007
|
this.connection.on("closed" /* DataStreamConnectionEvent.CLOSED */, this.closeListener = this.handleDataStreamConnectionClosed.bind(this));
|
|
994
1008
|
}
|
|
@@ -996,24 +1010,24 @@ class SiriAudioSession extends events_1.EventEmitter {
|
|
|
996
1010
|
* Called when siri button is pressed
|
|
997
1011
|
*/
|
|
998
1012
|
start() {
|
|
999
|
-
debug(
|
|
1013
|
+
debug('Sending request to start siri audio stream');
|
|
1000
1014
|
// opening dataSend
|
|
1001
1015
|
this.connection.sendRequest("dataSend" /* Protocols.DATA_SEND */, "open" /* Topics.OPEN */, {
|
|
1002
|
-
target:
|
|
1003
|
-
type:
|
|
1016
|
+
target: 'controller',
|
|
1017
|
+
type: 'audio.siri',
|
|
1004
1018
|
}, (error, status, message) => {
|
|
1005
1019
|
if (this.state === 3 /* SiriAudioSessionState.CLOSED */) {
|
|
1006
|
-
debug(
|
|
1020
|
+
debug('Ignoring dataSend open response as the session is already closed');
|
|
1007
1021
|
return;
|
|
1008
1022
|
}
|
|
1009
|
-
|
|
1023
|
+
assert.strictEqual(this.state, 0 /* SiriAudioSessionState.STARTING */);
|
|
1010
1024
|
this.state = 1 /* SiriAudioSessionState.SENDING */;
|
|
1011
1025
|
if (error || status) {
|
|
1012
1026
|
if (error) { // errors get produced by hap-nodejs
|
|
1013
|
-
debug(
|
|
1027
|
+
debug('Error occurred trying to start siri audio stream: %s', error.message);
|
|
1014
1028
|
}
|
|
1015
1029
|
else if (status) { // status codes are those returned by the hds response
|
|
1016
|
-
debug(
|
|
1030
|
+
debug('Controller responded with non-zero status code: %s', HDSStatus[status]);
|
|
1017
1031
|
}
|
|
1018
1032
|
this.closed();
|
|
1019
1033
|
}
|
|
@@ -1023,7 +1037,7 @@ class SiriAudioSession extends events_1.EventEmitter {
|
|
|
1023
1037
|
this.sendDataSendCloseEvent(3 /* HDSProtocolSpecificErrorReason.CANCELLED */);
|
|
1024
1038
|
}
|
|
1025
1039
|
else {
|
|
1026
|
-
debug(
|
|
1040
|
+
debug('Successfully setup siri audio stream with streamId %d', this.streamId);
|
|
1027
1041
|
}
|
|
1028
1042
|
}
|
|
1029
1043
|
});
|
|
@@ -1039,8 +1053,8 @@ class SiriAudioSession extends events_1.EventEmitter {
|
|
|
1039
1053
|
* Called when siri button is released (or active identifier is changed to another device)
|
|
1040
1054
|
*/
|
|
1041
1055
|
stop() {
|
|
1042
|
-
(
|
|
1043
|
-
debug(
|
|
1056
|
+
assert(this.state <= 1 /* SiriAudioSessionState.SENDING */, 'state was higher than SENDING');
|
|
1057
|
+
debug('Stopping siri audio stream with streamId %d', this.streamId);
|
|
1044
1058
|
this.endOfStream = true; // mark as endOfStream
|
|
1045
1059
|
this.stopAudioProducer();
|
|
1046
1060
|
if (this.state === 1 /* SiriAudioSessionState.SENDING */) {
|
|
@@ -1055,7 +1069,7 @@ class SiriAudioSession extends events_1.EventEmitter {
|
|
|
1055
1069
|
this.producer.startAudioProduction(this.selectedAudioConfiguration);
|
|
1056
1070
|
this.producerRunning = true;
|
|
1057
1071
|
this.producerTimer = setTimeout(() => {
|
|
1058
|
-
debug(
|
|
1072
|
+
debug('Didn\'t receive any frames from audio producer for stream with streamId %s. Canceling the stream now.', this.streamId);
|
|
1059
1073
|
this.producerTimer = undefined;
|
|
1060
1074
|
this.handleProducerError(3 /* HDSProtocolSpecificErrorReason.CANCELLED */);
|
|
1061
1075
|
}, 3000);
|
|
@@ -1083,35 +1097,33 @@ class SiriAudioSession extends events_1.EventEmitter {
|
|
|
1083
1097
|
if (this.state !== 1 /* SiriAudioSessionState.SENDING */) { // dataSend isn't open yet
|
|
1084
1098
|
return;
|
|
1085
1099
|
}
|
|
1086
|
-
let queued;
|
|
1087
|
-
while (
|
|
1100
|
+
let queued = this.popSome();
|
|
1101
|
+
while (queued !== null) { // send packets
|
|
1088
1102
|
const packets = [];
|
|
1089
|
-
queued.forEach(frame => {
|
|
1103
|
+
queued.forEach((frame) => {
|
|
1090
1104
|
const packetData = {
|
|
1091
1105
|
data: frame.data,
|
|
1092
1106
|
metadata: {
|
|
1093
|
-
rms: new
|
|
1094
|
-
sequenceNumber: new
|
|
1107
|
+
rms: new Float32(frame.rms),
|
|
1108
|
+
sequenceNumber: new Int64(this.sequenceNumber++),
|
|
1095
1109
|
},
|
|
1096
1110
|
};
|
|
1097
1111
|
packets.push(packetData);
|
|
1098
1112
|
});
|
|
1099
1113
|
const message = {
|
|
1100
|
-
packets
|
|
1101
|
-
streamId: new
|
|
1114
|
+
packets,
|
|
1115
|
+
streamId: new Int64(this.streamId),
|
|
1102
1116
|
endOfStream: this.endOfStream,
|
|
1103
1117
|
};
|
|
1104
1118
|
try {
|
|
1105
1119
|
this.connection.sendEvent("dataSend" /* Protocols.DATA_SEND */, "data" /* Topics.DATA */, message);
|
|
1106
1120
|
}
|
|
1107
1121
|
catch (error) {
|
|
1108
|
-
debug(
|
|
1122
|
+
debug('Error occurred when trying to send audio frame of hds connection: %s', error.message);
|
|
1109
1123
|
this.stopAudioProducer();
|
|
1110
1124
|
this.closed();
|
|
1111
1125
|
}
|
|
1112
|
-
|
|
1113
|
-
break; // popSome() returns empty list if endOfStream=true
|
|
1114
|
-
}
|
|
1126
|
+
queued = this.popSome();
|
|
1115
1127
|
}
|
|
1116
1128
|
}
|
|
1117
1129
|
handleProducerError(error) {
|
|
@@ -1124,29 +1136,29 @@ class SiriAudioSession extends events_1.EventEmitter {
|
|
|
1124
1136
|
}
|
|
1125
1137
|
}
|
|
1126
1138
|
handleDataSendAckEvent(endOfStream) {
|
|
1127
|
-
|
|
1128
|
-
debug(
|
|
1139
|
+
assert.strictEqual(endOfStream, true);
|
|
1140
|
+
debug('Received acknowledgment for siri audio stream with streamId %s, closing it now', this.streamId);
|
|
1129
1141
|
this.sendDataSendCloseEvent(0 /* HDSProtocolSpecificErrorReason.NORMAL */);
|
|
1130
1142
|
}
|
|
1131
1143
|
handleDataSendCloseEvent(reason) {
|
|
1132
1144
|
// @ts-expect-error: forceConsistentCasingInFileNames compiler option
|
|
1133
|
-
debug(
|
|
1145
|
+
debug('Received close event from controller with reason %s for stream with streamId %s', HDSProtocolSpecificErrorReason[reason], this.streamId);
|
|
1134
1146
|
if (this.state <= 1 /* SiriAudioSessionState.SENDING */) {
|
|
1135
1147
|
this.stopAudioProducer();
|
|
1136
1148
|
}
|
|
1137
1149
|
this.closed();
|
|
1138
1150
|
}
|
|
1139
1151
|
sendDataSendCloseEvent(reason) {
|
|
1140
|
-
(
|
|
1141
|
-
(
|
|
1152
|
+
assert(this.state >= 1 /* SiriAudioSessionState.SENDING */, 'state was less than SENDING');
|
|
1153
|
+
assert(this.state <= 2 /* SiriAudioSessionState.CLOSING */, 'state was higher than CLOSING');
|
|
1142
1154
|
this.connection.sendEvent("dataSend" /* Protocols.DATA_SEND */, "close" /* Topics.CLOSE */, {
|
|
1143
|
-
streamId: new
|
|
1144
|
-
reason: new
|
|
1155
|
+
streamId: new Int64(this.streamId),
|
|
1156
|
+
reason: new Int64(reason),
|
|
1145
1157
|
});
|
|
1146
1158
|
this.closed();
|
|
1147
1159
|
}
|
|
1148
1160
|
handleDataStreamConnectionClosed() {
|
|
1149
|
-
debug(
|
|
1161
|
+
debug('Closing audio session with streamId %d', this.streamId);
|
|
1150
1162
|
if (this.state <= 1 /* SiriAudioSessionState.SENDING */) {
|
|
1151
1163
|
this.stopAudioProducer();
|
|
1152
1164
|
}
|
|
@@ -1174,5 +1186,4 @@ class SiriAudioSession extends events_1.EventEmitter {
|
|
|
1174
1186
|
return result;
|
|
1175
1187
|
}
|
|
1176
1188
|
}
|
|
1177
|
-
exports.SiriAudioSession = SiriAudioSession;
|
|
1178
1189
|
//# sourceMappingURL=RemoteController.js.map
|