hap-nodejs 1.0.0-beta.7 → 1.0.0
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/README.md +7 -3
- package/dist/accessories/AirConditioner_accessory.js +24 -24
- package/dist/accessories/AirConditioner_accessory.js.map +1 -1
- package/dist/accessories/AppleTVRemote_accessory.js +23 -23
- package/dist/accessories/AppleTVRemote_accessory.js.map +1 -1
- package/dist/accessories/Camera_accessory.js +295 -380
- package/dist/accessories/Camera_accessory.js.map +1 -1
- package/dist/accessories/Fan_accessory.js +15 -21
- package/dist/accessories/Fan_accessory.js.map +1 -1
- package/dist/accessories/GarageDoorOpener_accessory.js +12 -12
- package/dist/accessories/GarageDoorOpener_accessory.js.map +1 -1
- package/dist/accessories/Light-AdaptiveLighting_accessory.js +31 -21
- package/dist/accessories/Light-AdaptiveLighting_accessory.js.map +1 -1
- package/dist/accessories/Light_accessory.js +45 -48
- package/dist/accessories/Light_accessory.js.map +1 -1
- package/dist/accessories/Lock_accessory.js +11 -11
- package/dist/accessories/Lock_accessory.js.map +1 -1
- package/dist/accessories/MotionSensor_accessory.js +8 -8
- package/dist/accessories/MotionSensor_accessory.js.map +1 -1
- package/dist/accessories/Outlet_accessory.js +10 -10
- package/dist/accessories/Outlet_accessory.js.map +1 -1
- package/dist/accessories/SmartSpeaker_accessory.js +11 -11
- package/dist/accessories/SmartSpeaker_accessory.js.map +1 -1
- package/dist/accessories/Sprinkler_accessory.js +19 -19
- package/dist/accessories/Sprinkler_accessory.js.map +1 -1
- package/dist/accessories/TV_accessory.js +17 -17
- package/dist/accessories/TV_accessory.js.map +1 -1
- package/dist/accessories/TemperatureSensor_accessory.js +6 -6
- package/dist/accessories/TemperatureSensor_accessory.js.map +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.js +3 -3
- package/dist/accessories/Wi-FiRouter_accessory.js.map +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.js +4 -4
- package/dist/accessories/Wi-FiSatellite_accessory.js.map +1 -1
- package/dist/accessories/gstreamer-audioProducer.js +45 -55
- package/dist/accessories/gstreamer-audioProducer.js.map +1 -1
- package/dist/accessories/types.js +2 -2
- package/dist/accessories/types.js.map +1 -1
- package/dist/index.d.ts +0 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -31
- package/dist/index.js.map +1 -1
- package/dist/internal-types.d.ts +4 -4
- package/dist/internal-types.d.ts.map +1 -1
- package/dist/internal-types.js +10 -6
- package/dist/internal-types.js.map +1 -1
- package/dist/lib/Accessory.d.ts +19 -74
- package/dist/lib/Accessory.d.ts.map +1 -1
- package/dist/lib/Accessory.js +775 -1155
- package/dist/lib/Accessory.js.map +1 -1
- package/dist/lib/Advertiser.d.ts +5 -6
- package/dist/lib/Advertiser.d.ts.map +1 -1
- package/dist/lib/Advertiser.js +402 -521
- package/dist/lib/Advertiser.js.map +1 -1
- package/dist/lib/Bridge.js +6 -10
- package/dist/lib/Bridge.js.map +1 -1
- package/dist/lib/Characteristic.d.ts +31 -93
- package/dist/lib/Characteristic.d.ts.map +1 -1
- package/dist/lib/Characteristic.js +1474 -668
- package/dist/lib/Characteristic.js.map +1 -1
- package/dist/lib/HAPServer.d.ts +10 -22
- package/dist/lib/HAPServer.d.ts.map +1 -1
- package/dist/lib/HAPServer.js +224 -286
- package/dist/lib/HAPServer.js.map +1 -1
- package/dist/lib/Service.d.ts +9 -27
- package/dist/lib/Service.d.ts.map +1 -1
- package/dist/lib/Service.js +476 -314
- package/dist/lib/Service.js.map +1 -1
- package/dist/lib/camera/RTPProxy.d.ts +0 -2
- package/dist/lib/camera/RTPProxy.d.ts.map +1 -1
- package/dist/lib/camera/RTPProxy.js +112 -104
- package/dist/lib/camera/RTPProxy.js.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.d.ts +2 -67
- package/dist/lib/camera/RTPStreamManagement.d.ts.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.js +272 -292
- package/dist/lib/camera/RTPStreamManagement.js.map +1 -1
- package/dist/lib/camera/RecordingManagement.d.ts +0 -1
- package/dist/lib/camera/RecordingManagement.d.ts.map +1 -1
- package/dist/lib/camera/RecordingManagement.js +325 -392
- package/dist/lib/camera/RecordingManagement.js.map +1 -1
- package/dist/lib/camera/index.d.ts +0 -1
- package/dist/lib/camera/index.d.ts.map +1 -1
- package/dist/lib/camera/index.js +1 -2
- package/dist/lib/camera/index.js.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.d.ts +19 -4
- package/dist/lib/controller/AdaptiveLightingController.d.ts.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.js +220 -221
- package/dist/lib/controller/AdaptiveLightingController.js.map +1 -1
- package/dist/lib/controller/CameraController.d.ts +0 -6
- package/dist/lib/controller/CameraController.d.ts.map +1 -1
- package/dist/lib/controller/CameraController.js +192 -258
- package/dist/lib/controller/CameraController.js.map +1 -1
- package/dist/lib/controller/Controller.d.ts +1 -1
- package/dist/lib/controller/Controller.d.ts.map +1 -1
- package/dist/lib/controller/Controller.js +3 -3
- package/dist/lib/controller/Controller.js.map +1 -1
- package/dist/lib/controller/DoorbellController.js +38 -39
- package/dist/lib/controller/DoorbellController.js.map +1 -1
- package/dist/lib/controller/RemoteController.d.ts +4 -20
- package/dist/lib/controller/RemoteController.d.ts.map +1 -1
- package/dist/lib/controller/RemoteController.js +351 -424
- package/dist/lib/controller/RemoteController.js.map +1 -1
- package/dist/lib/controller/index.js +1 -1
- package/dist/lib/datastream/DataStreamManagement.js +57 -58
- 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 +261 -306
- package/dist/lib/datastream/DataStreamParser.js.map +1 -1
- package/dist/lib/datastream/DataStreamServer.d.ts +0 -8
- package/dist/lib/datastream/DataStreamServer.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamServer.js +262 -275
- package/dist/lib/datastream/DataStreamServer.js.map +1 -1
- package/dist/lib/datastream/index.js +1 -1
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts +50 -40
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/CharacteristicDefinitions.js +2059 -2754
- package/dist/lib/definitions/CharacteristicDefinitions.js.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.d.ts +14 -8
- package/dist/lib/definitions/ServiceDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.js +834 -1053
- package/dist/lib/definitions/ServiceDefinitions.js.map +1 -1
- package/dist/lib/definitions/generate-definitions.js +383 -679
- package/dist/lib/definitions/generate-definitions.js.map +1 -1
- package/dist/lib/definitions/generator-configuration.d.ts.map +1 -1
- package/dist/lib/definitions/generator-configuration.js +163 -35
- package/dist/lib/definitions/generator-configuration.js.map +1 -1
- package/dist/lib/definitions/index.js +1 -1
- package/dist/lib/model/AccessoryInfo.d.ts +0 -1
- package/dist/lib/model/AccessoryInfo.d.ts.map +1 -1
- package/dist/lib/model/AccessoryInfo.js +102 -137
- package/dist/lib/model/AccessoryInfo.js.map +1 -1
- package/dist/lib/model/ControllerStorage.js +86 -89
- package/dist/lib/model/ControllerStorage.js.map +1 -1
- package/dist/lib/model/HAPStorage.js +15 -16
- package/dist/lib/model/HAPStorage.js.map +1 -1
- package/dist/lib/model/IdentifierCache.js +49 -49
- package/dist/lib/model/IdentifierCache.js.map +1 -1
- package/dist/lib/tv/AccessControlManagement.d.ts +0 -1
- package/dist/lib/tv/AccessControlManagement.d.ts.map +1 -1
- package/dist/lib/tv/AccessControlManagement.js +43 -46
- package/dist/lib/tv/AccessControlManagement.js.map +1 -1
- package/dist/lib/util/checkName.d.ts +8 -0
- package/dist/lib/util/checkName.d.ts.map +1 -0
- package/dist/lib/util/checkName.js +17 -0
- package/dist/lib/util/checkName.js.map +1 -0
- package/dist/lib/util/clone.js +6 -29
- package/dist/lib/util/clone.js.map +1 -1
- package/dist/lib/util/color-utils.js +8 -12
- package/dist/lib/util/color-utils.js.map +1 -1
- package/dist/lib/util/eventedhttp.d.ts +5 -9
- package/dist/lib/util/eventedhttp.d.ts.map +1 -1
- package/dist/lib/util/eventedhttp.js +306 -405
- package/dist/lib/util/eventedhttp.js.map +1 -1
- package/dist/lib/util/hapCrypto.d.ts +0 -1
- package/dist/lib/util/hapCrypto.d.ts.map +1 -1
- package/dist/lib/util/hapCrypto.js +39 -41
- package/dist/lib/util/hapCrypto.js.map +1 -1
- package/dist/lib/util/hapStatusError.js +9 -12
- package/dist/lib/util/hapStatusError.js.map +1 -1
- package/dist/lib/util/net-utils.d.ts.map +1 -1
- package/dist/lib/util/net-utils.js +34 -54
- package/dist/lib/util/net-utils.js.map +1 -1
- package/dist/lib/util/once.js +4 -10
- package/dist/lib/util/once.js.map +1 -1
- package/dist/lib/util/promise-utils.d.ts +0 -1
- package/dist/lib/util/promise-utils.d.ts.map +1 -1
- package/dist/lib/util/promise-utils.js +10 -16
- package/dist/lib/util/promise-utils.js.map +1 -1
- package/dist/lib/util/request-util.js +8 -10
- 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 +7 -8
- package/dist/lib/util/time.js.map +1 -1
- package/dist/lib/util/tlv.d.ts +0 -28
- package/dist/lib/util/tlv.d.ts.map +1 -1
- package/dist/lib/util/tlv.js +83 -126
- package/dist/lib/util/tlv.js.map +1 -1
- package/dist/lib/util/uuid.d.ts +0 -10
- package/dist/lib/util/uuid.d.ts.map +1 -1
- package/dist/lib/util/uuid.js +22 -40
- package/dist/lib/util/uuid.js.map +1 -1
- package/dist/types.d.ts +0 -35
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +29 -28
- package/dist/BridgedCore.d.ts +0 -2
- package/dist/BridgedCore.d.ts.map +0 -1
- package/dist/BridgedCore.js +0 -43
- package/dist/BridgedCore.js.map +0 -1
- package/dist/Core.d.ts +0 -2
- package/dist/Core.d.ts.map +0 -1
- package/dist/Core.js +0 -52
- package/dist/Core.js.map +0 -1
- package/dist/lib/AccessoryLoader.d.ts +0 -28
- package/dist/lib/AccessoryLoader.d.ts.map +0 -1
- package/dist/lib/AccessoryLoader.js +0 -167
- package/dist/lib/AccessoryLoader.js.map +0 -1
- package/dist/lib/camera/Camera.d.ts +0 -44
- package/dist/lib/camera/Camera.d.ts.map +0 -1
- package/dist/lib/camera/Camera.js +0 -36
- package/dist/lib/camera/Camera.js.map +0 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SiriAudioSession = exports.SiriAudioSessionEvents = exports.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
exports.SiriAudioSession = exports.SiriAudioSessionEvents = exports.RemoteController = exports.RemoteControllerEvents = exports.TargetUpdates = exports.AudioCodecTypes = exports.ButtonState = exports.TargetCategory = exports.ButtonType = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
const debug_1 = tslib_1.__importDefault(require("debug"));
|
|
7
|
+
const events_1 = require("events");
|
|
8
|
+
const Characteristic_1 = require("../Characteristic");
|
|
9
|
+
const datastream_1 = require("../datastream");
|
|
10
|
+
const Service_1 = require("../Service");
|
|
11
|
+
const tlv = tslib_1.__importStar(require("../util/tlv"));
|
|
12
|
+
const debug = (0, debug_1.default)("HAP-NodeJS:Remote:Controller");
|
|
13
13
|
var TargetControlCommands;
|
|
14
14
|
(function (TargetControlCommands) {
|
|
15
15
|
TargetControlCommands[TargetControlCommands["MAXIMUM_TARGETS"] = 1] = "MAXIMUM_TARGETS";
|
|
@@ -42,7 +42,7 @@ var ButtonType;
|
|
|
42
42
|
ButtonType[ButtonType["SIRI"] = 11] = "SIRI";
|
|
43
43
|
ButtonType[ButtonType["POWER"] = 12] = "POWER";
|
|
44
44
|
ButtonType[ButtonType["GENERIC"] = 13] = "GENERIC";
|
|
45
|
-
})(ButtonType
|
|
45
|
+
})(ButtonType || (exports.ButtonType = ButtonType = {}));
|
|
46
46
|
var TargetControlList;
|
|
47
47
|
(function (TargetControlList) {
|
|
48
48
|
TargetControlList[TargetControlList["OPERATION"] = 1] = "OPERATION";
|
|
@@ -73,7 +73,7 @@ var TargetCategory;
|
|
|
73
73
|
// noinspection JSUnusedGlobalSymbols
|
|
74
74
|
TargetCategory[TargetCategory["UNDEFINED"] = 0] = "UNDEFINED";
|
|
75
75
|
TargetCategory[TargetCategory["APPLE_TV"] = 24] = "APPLE_TV";
|
|
76
|
-
})(TargetCategory
|
|
76
|
+
})(TargetCategory || (exports.TargetCategory = TargetCategory = {}));
|
|
77
77
|
var ButtonConfigurationTypes;
|
|
78
78
|
(function (ButtonConfigurationTypes) {
|
|
79
79
|
ButtonConfigurationTypes[ButtonConfigurationTypes["BUTTON_ID"] = 1] = "BUTTON_ID";
|
|
@@ -94,7 +94,7 @@ var ButtonState;
|
|
|
94
94
|
(function (ButtonState) {
|
|
95
95
|
ButtonState[ButtonState["UP"] = 0] = "UP";
|
|
96
96
|
ButtonState[ButtonState["DOWN"] = 1] = "DOWN";
|
|
97
|
-
})(ButtonState
|
|
97
|
+
})(ButtonState || (exports.ButtonState = ButtonState = {}));
|
|
98
98
|
var SelectedAudioInputStreamConfigurationTypes;
|
|
99
99
|
(function (SelectedAudioInputStreamConfigurationTypes) {
|
|
100
100
|
SelectedAudioInputStreamConfigurationTypes[SelectedAudioInputStreamConfigurationTypes["SELECTED_AUDIO_INPUT_STREAM_CONFIGURATION"] = 1] = "SELECTED_AUDIO_INPUT_STREAM_CONFIGURATION";
|
|
@@ -124,7 +124,7 @@ var AudioCodecTypes;
|
|
|
124
124
|
AudioCodecTypes[AudioCodecTypes["MSBC"] = 4] = "MSBC";
|
|
125
125
|
AudioCodecTypes[AudioCodecTypes["AMR"] = 5] = "AMR";
|
|
126
126
|
AudioCodecTypes[AudioCodecTypes["AMR_WB"] = 6] = "AMR_WB";
|
|
127
|
-
})(AudioCodecTypes
|
|
127
|
+
})(AudioCodecTypes || (exports.AudioCodecTypes = AudioCodecTypes = {}));
|
|
128
128
|
var AudioCodecParametersTypes;
|
|
129
129
|
(function (AudioCodecParametersTypes) {
|
|
130
130
|
AudioCodecParametersTypes[AudioCodecParametersTypes["CHANNEL"] = 1] = "CHANNEL";
|
|
@@ -148,7 +148,7 @@ var TargetUpdates;
|
|
|
148
148
|
TargetUpdates[TargetUpdates["CATEGORY"] = 1] = "CATEGORY";
|
|
149
149
|
TargetUpdates[TargetUpdates["UPDATED_BUTTONS"] = 2] = "UPDATED_BUTTONS";
|
|
150
150
|
TargetUpdates[TargetUpdates["REMOVED_BUTTONS"] = 3] = "REMOVED_BUTTONS";
|
|
151
|
-
})(TargetUpdates
|
|
151
|
+
})(TargetUpdates || (exports.TargetUpdates = TargetUpdates = {}));
|
|
152
152
|
/**
|
|
153
153
|
* @group Apple TV Remote
|
|
154
154
|
*/
|
|
@@ -186,14 +186,46 @@ var RemoteControllerEvents;
|
|
|
186
186
|
* when the accessory gets unpaired.
|
|
187
187
|
*/
|
|
188
188
|
RemoteControllerEvents["TARGETS_RESET"] = "targets-reset";
|
|
189
|
-
})(RemoteControllerEvents
|
|
189
|
+
})(RemoteControllerEvents || (exports.RemoteControllerEvents = RemoteControllerEvents = {}));
|
|
190
190
|
/**
|
|
191
191
|
* Handles everything needed to implement a fully working HomeKit remote controller.
|
|
192
192
|
*
|
|
193
193
|
* @group Apple TV Remote
|
|
194
194
|
*/
|
|
195
|
-
|
|
196
|
-
|
|
195
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
196
|
+
class RemoteController extends events_1.EventEmitter {
|
|
197
|
+
stateChangeDelegate;
|
|
198
|
+
audioSupported;
|
|
199
|
+
audioProducerConstructor;
|
|
200
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
201
|
+
audioProducerOptions;
|
|
202
|
+
targetControlManagementService;
|
|
203
|
+
targetControlService;
|
|
204
|
+
siriService;
|
|
205
|
+
audioStreamManagementService;
|
|
206
|
+
dataStreamManagement;
|
|
207
|
+
buttons = {}; // internal mapping of buttonId to buttonType for supported buttons
|
|
208
|
+
supportedConfiguration;
|
|
209
|
+
targetConfigurations = new Map();
|
|
210
|
+
targetConfigurationsString = "";
|
|
211
|
+
lastButtonEvent = "";
|
|
212
|
+
activeIdentifier = 0; // id of 0 means no device selected
|
|
213
|
+
activeConnection; // session which marked this remote as active and listens for events and siri
|
|
214
|
+
activeConnectionDisconnectListener;
|
|
215
|
+
supportedAudioConfiguration;
|
|
216
|
+
selectedAudioConfiguration;
|
|
217
|
+
selectedAudioConfigurationString;
|
|
218
|
+
dataStreamConnections = new Map(); // maps targetIdentifiers to active data stream connections
|
|
219
|
+
activeAudioSession;
|
|
220
|
+
nextAudioSession;
|
|
221
|
+
/**
|
|
222
|
+
* @private
|
|
223
|
+
*/
|
|
224
|
+
eventHandler;
|
|
225
|
+
/**
|
|
226
|
+
* @private
|
|
227
|
+
*/
|
|
228
|
+
requestHandler;
|
|
197
229
|
/**
|
|
198
230
|
* Creates a new RemoteController.
|
|
199
231
|
* If siri voice input is supported the constructor to an SiriAudioStreamProducer needs to be supplied.
|
|
@@ -206,22 +238,16 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
206
238
|
* constructor. This should be used to supply configurations to the stream producer.
|
|
207
239
|
*/
|
|
208
240
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
_this.audioProducerOptions = producerOptions;
|
|
220
|
-
var configuration = _this.constructSupportedConfiguration();
|
|
221
|
-
_this.supportedConfiguration = _this.buildTargetControlSupportedConfigurationTLV(configuration);
|
|
222
|
-
var audioConfiguration = _this.constructSupportedAudioConfiguration();
|
|
223
|
-
_this.supportedAudioConfiguration = RemoteController.buildSupportedAudioConfigurationTLV(audioConfiguration);
|
|
224
|
-
_this.selectedAudioConfiguration = {
|
|
241
|
+
constructor(audioProducerConstructor, producerOptions) {
|
|
242
|
+
super();
|
|
243
|
+
this.audioSupported = audioProducerConstructor !== undefined;
|
|
244
|
+
this.audioProducerConstructor = audioProducerConstructor;
|
|
245
|
+
this.audioProducerOptions = producerOptions;
|
|
246
|
+
const configuration = this.constructSupportedConfiguration();
|
|
247
|
+
this.supportedConfiguration = this.buildTargetControlSupportedConfigurationTLV(configuration);
|
|
248
|
+
const audioConfiguration = this.constructSupportedAudioConfiguration();
|
|
249
|
+
this.supportedAudioConfiguration = RemoteController.buildSupportedAudioConfigurationTLV(audioConfiguration);
|
|
250
|
+
this.selectedAudioConfiguration = {
|
|
225
251
|
codecType: 3 /* AudioCodecTypes.OPUS */,
|
|
226
252
|
parameters: {
|
|
227
253
|
channels: 1,
|
|
@@ -230,24 +256,22 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
230
256
|
rtpTime: 20,
|
|
231
257
|
},
|
|
232
258
|
};
|
|
233
|
-
|
|
234
|
-
audioCodecConfiguration:
|
|
259
|
+
this.selectedAudioConfigurationString = RemoteController.buildSelectedAudioConfigurationTLV({
|
|
260
|
+
audioCodecConfiguration: this.selectedAudioConfiguration,
|
|
235
261
|
});
|
|
236
|
-
return _this;
|
|
237
262
|
}
|
|
238
263
|
/**
|
|
239
264
|
* @private
|
|
240
265
|
*/
|
|
241
|
-
|
|
266
|
+
controllerId() {
|
|
242
267
|
return "remote" /* DefaultControllerType.REMOTE */;
|
|
243
|
-
}
|
|
268
|
+
}
|
|
244
269
|
/**
|
|
245
270
|
* Set a new target as active target. A value of 0 indicates that no target is selected currently.
|
|
246
271
|
*
|
|
247
272
|
* @param activeIdentifier - target identifier
|
|
248
273
|
*/
|
|
249
|
-
|
|
250
|
-
var _this = this;
|
|
274
|
+
setActiveIdentifier(activeIdentifier) {
|
|
251
275
|
if (activeIdentifier === this.activeIdentifier) {
|
|
252
276
|
return;
|
|
253
277
|
}
|
|
@@ -260,96 +284,73 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
260
284
|
if (this.activeAudioSession) {
|
|
261
285
|
this.handleSiriAudioStop();
|
|
262
286
|
}
|
|
263
|
-
setTimeout(
|
|
287
|
+
setTimeout(() => this.emit("active-identifier-change" /* RemoteControllerEvents.ACTIVE_IDENTIFIER_CHANGE */, activeIdentifier), 0);
|
|
264
288
|
this.setInactive();
|
|
265
|
-
}
|
|
289
|
+
}
|
|
266
290
|
/**
|
|
267
291
|
* @returns if the current target is active, meaning the active device is listening for button events or audio sessions
|
|
268
292
|
*/
|
|
269
|
-
|
|
293
|
+
isActive() {
|
|
270
294
|
return !!this.activeConnection;
|
|
271
|
-
}
|
|
295
|
+
}
|
|
272
296
|
/**
|
|
273
297
|
* Checks if the supplied targetIdentifier is configured.
|
|
274
298
|
*
|
|
275
299
|
* @param targetIdentifier - The target identifier.
|
|
276
300
|
*/
|
|
277
|
-
|
|
301
|
+
isConfigured(targetIdentifier) {
|
|
278
302
|
return this.targetConfigurations.has(targetIdentifier);
|
|
279
|
-
}
|
|
303
|
+
}
|
|
280
304
|
/**
|
|
281
305
|
* Returns the targetIdentifier for a give device name
|
|
282
306
|
*
|
|
283
307
|
* @param name - The name of the device.
|
|
284
308
|
* @returns The targetIdentifier of the device or undefined if not existent.
|
|
285
309
|
*/
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
var _d = tslib_1.__read(_c.value, 2), activeIdentifier = _d[0], configuration = _d[1];
|
|
291
|
-
if (configuration.targetName === name) {
|
|
292
|
-
return parseInt(activeIdentifier, 10);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
297
|
-
finally {
|
|
298
|
-
try {
|
|
299
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
310
|
+
getTargetIdentifierByName(name) {
|
|
311
|
+
for (const [activeIdentifier, configuration] of Object.entries(this.targetConfigurations)) {
|
|
312
|
+
if (configuration.targetName === name) {
|
|
313
|
+
return parseInt(activeIdentifier, 10);
|
|
300
314
|
}
|
|
301
|
-
finally { if (e_1) throw e_1.error; }
|
|
302
315
|
}
|
|
303
316
|
return undefined;
|
|
304
|
-
}
|
|
317
|
+
}
|
|
305
318
|
/**
|
|
306
319
|
* Sends a button event to press the supplied button.
|
|
307
320
|
*
|
|
308
321
|
* @param button - button to be pressed
|
|
309
322
|
*/
|
|
310
|
-
|
|
323
|
+
pushButton(button) {
|
|
311
324
|
this.sendButtonEvent(button, 1 /* ButtonState.DOWN */);
|
|
312
|
-
}
|
|
325
|
+
}
|
|
313
326
|
/**
|
|
314
327
|
* Sends a button event that the supplied button was released.
|
|
315
328
|
*
|
|
316
329
|
* @param button - button which was released
|
|
317
330
|
*/
|
|
318
|
-
|
|
331
|
+
releaseButton(button) {
|
|
319
332
|
this.sendButtonEvent(button, 0 /* ButtonState.UP */);
|
|
320
|
-
}
|
|
333
|
+
}
|
|
321
334
|
/**
|
|
322
335
|
* Presses a supplied button for a given time.
|
|
323
336
|
*
|
|
324
337
|
* @param button - button to be pressed and released
|
|
325
338
|
* @param time - time in milliseconds (defaults to 200ms)
|
|
326
339
|
*/
|
|
327
|
-
|
|
328
|
-
var _this = this;
|
|
329
|
-
if (time === void 0) { time = 200; }
|
|
340
|
+
pushAndReleaseButton(button, time = 200) {
|
|
330
341
|
this.pushButton(button);
|
|
331
|
-
setTimeout(
|
|
332
|
-
}
|
|
333
|
-
/**
|
|
334
|
-
* This method adds and configures the remote services for a give accessory.
|
|
335
|
-
*
|
|
336
|
-
* @param accessory - the give accessory this remote should be added to
|
|
337
|
-
* @deprecated - use {@link Accessory.configureController} instead
|
|
338
|
-
*/
|
|
339
|
-
RemoteController.prototype.addServicesToAccessory = function (accessory) {
|
|
340
|
-
accessory.configureController(this);
|
|
341
|
-
};
|
|
342
|
+
setTimeout(() => this.releaseButton(button), time);
|
|
343
|
+
}
|
|
342
344
|
// ---------------------------------- CONFIGURATION ----------------------------------
|
|
343
345
|
// override methods if you would like to change anything (but should not be necessary most likely)
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
ticksPerSecond: 1000,
|
|
346
|
+
constructSupportedConfiguration() {
|
|
347
|
+
const configuration = {
|
|
348
|
+
maximumTargets: 10, // some random number. (ten should be okay?)
|
|
349
|
+
ticksPerSecond: 1000, // we rely on unix timestamps
|
|
349
350
|
supportedButtonConfiguration: [],
|
|
350
351
|
hardwareImplemented: this.audioSupported, // siri is only allowed for hardware implemented remotes
|
|
351
352
|
};
|
|
352
|
-
|
|
353
|
+
const supportedButtons = [
|
|
353
354
|
1 /* ButtonType.MENU */, 2 /* ButtonType.PLAY_PAUSE */, 3 /* ButtonType.TV_HOME */, 4 /* ButtonType.SELECT */,
|
|
354
355
|
5 /* ButtonType.ARROW_UP */, 6 /* ButtonType.ARROW_RIGHT */, 7 /* ButtonType.ARROW_DOWN */, 8 /* ButtonType.ARROW_LEFT */,
|
|
355
356
|
9 /* ButtonType.VOLUME_UP */, 10 /* ButtonType.VOLUME_DOWN */, 12 /* ButtonType.POWER */, 13 /* ButtonType.GENERIC */,
|
|
@@ -357,17 +358,17 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
357
358
|
if (this.audioSupported) { // add siri button if this remote supports it
|
|
358
359
|
supportedButtons.push(11 /* ButtonType.SIRI */);
|
|
359
360
|
}
|
|
360
|
-
supportedButtons.forEach(
|
|
361
|
-
|
|
361
|
+
supportedButtons.forEach(button => {
|
|
362
|
+
const buttonConfiguration = {
|
|
362
363
|
buttonID: 100 + button,
|
|
363
364
|
buttonType: button,
|
|
364
365
|
};
|
|
365
366
|
configuration.supportedButtonConfiguration.push(buttonConfiguration);
|
|
366
|
-
|
|
367
|
+
this.buttons[button] = buttonConfiguration.buttonID; // also saving mapping of type to id locally
|
|
367
368
|
});
|
|
368
369
|
return configuration;
|
|
369
|
-
}
|
|
370
|
-
|
|
370
|
+
}
|
|
371
|
+
constructSupportedAudioConfiguration() {
|
|
371
372
|
// the following parameters are expected from HomeKit for a remote
|
|
372
373
|
return {
|
|
373
374
|
audioCodecConfiguration: {
|
|
@@ -379,19 +380,19 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
379
380
|
},
|
|
380
381
|
},
|
|
381
382
|
};
|
|
382
|
-
}
|
|
383
|
+
}
|
|
383
384
|
// --------------------------------- TARGET CONTROL ----------------------------------
|
|
384
385
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
386
|
+
handleTargetControlWrite(value, callback) {
|
|
387
|
+
const data = Buffer.from(value, "base64");
|
|
388
|
+
const objects = tlv.decode(data);
|
|
389
|
+
const operation = objects[1 /* TargetControlList.OPERATION */][0];
|
|
390
|
+
let targetConfiguration = undefined;
|
|
390
391
|
if (objects[2 /* TargetControlList.TARGET_CONFIGURATION */]) { // if target configuration was sent, parse it
|
|
391
392
|
targetConfiguration = this.parseTargetConfigurationTLV(objects[2 /* TargetControlList.TARGET_CONFIGURATION */]);
|
|
392
393
|
}
|
|
393
394
|
debug("Received TargetControl write operation %s", Operation[operation]);
|
|
394
|
-
|
|
395
|
+
let handler;
|
|
395
396
|
switch (operation) {
|
|
396
397
|
case Operation.ADD:
|
|
397
398
|
handler = this.handleAddTarget.bind(this);
|
|
@@ -412,7 +413,7 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
412
413
|
callback(-70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */, undefined);
|
|
413
414
|
return;
|
|
414
415
|
}
|
|
415
|
-
|
|
416
|
+
const status = handler(targetConfiguration);
|
|
416
417
|
if (status === 0 /* HAPStatus.SUCCESS */) {
|
|
417
418
|
callback(undefined, this.targetConfigurationsString); // passing value for write response
|
|
418
419
|
if (operation === Operation.ADD && this.activeIdentifier === 0) {
|
|
@@ -422,26 +423,23 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
422
423
|
else {
|
|
423
424
|
callback(new Error(status + ""));
|
|
424
425
|
}
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
var _this = this;
|
|
426
|
+
}
|
|
427
|
+
handleAddTarget(targetConfiguration) {
|
|
428
428
|
if (!targetConfiguration) {
|
|
429
429
|
return -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */;
|
|
430
430
|
}
|
|
431
431
|
this.targetConfigurations.set(targetConfiguration.targetIdentifier, targetConfiguration);
|
|
432
432
|
debug("Configured new target '" + targetConfiguration.targetName + "' with targetIdentifier '" + targetConfiguration.targetIdentifier + "'");
|
|
433
|
-
setTimeout(
|
|
433
|
+
setTimeout(() => this.emit("target-add" /* RemoteControllerEvents.TARGET_ADDED */, targetConfiguration), 0);
|
|
434
434
|
this.updatedTargetConfiguration(); // set response
|
|
435
435
|
return 0 /* HAPStatus.SUCCESS */;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
var e_2, _a;
|
|
439
|
-
var _this = this;
|
|
436
|
+
}
|
|
437
|
+
handleUpdateTarget(targetConfiguration) {
|
|
440
438
|
if (!targetConfiguration) {
|
|
441
439
|
return -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */;
|
|
442
440
|
}
|
|
443
|
-
|
|
444
|
-
|
|
441
|
+
const updates = [];
|
|
442
|
+
const configuredTarget = this.targetConfigurations.get(targetConfiguration.targetIdentifier);
|
|
445
443
|
if (!configuredTarget) {
|
|
446
444
|
return -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */;
|
|
447
445
|
}
|
|
@@ -457,76 +455,64 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
457
455
|
}
|
|
458
456
|
if (targetConfiguration.buttonConfiguration) {
|
|
459
457
|
debug("%d button configurations were updated for target '%s' (%d)", Object.keys(targetConfiguration.buttonConfiguration).length, configuredTarget.targetName, configuredTarget.targetIdentifier);
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
savedConfiguration.buttonType = configuration.buttonType;
|
|
465
|
-
savedConfiguration.buttonName = configuration.buttonName;
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
469
|
-
finally {
|
|
470
|
-
try {
|
|
471
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
472
|
-
}
|
|
473
|
-
finally { if (e_2) throw e_2.error; }
|
|
458
|
+
for (const configuration of Object.values(targetConfiguration.buttonConfiguration)) {
|
|
459
|
+
const savedConfiguration = configuredTarget.buttonConfiguration[configuration.buttonID];
|
|
460
|
+
savedConfiguration.buttonType = configuration.buttonType;
|
|
461
|
+
savedConfiguration.buttonName = configuration.buttonName;
|
|
474
462
|
}
|
|
475
463
|
updates.push(2 /* TargetUpdates.UPDATED_BUTTONS */);
|
|
476
464
|
}
|
|
477
|
-
setTimeout(
|
|
465
|
+
setTimeout(() => this.emit("target-update" /* RemoteControllerEvents.TARGET_UPDATED */, targetConfiguration, updates), 0);
|
|
478
466
|
this.updatedTargetConfiguration(); // set response
|
|
479
467
|
return 0 /* HAPStatus.SUCCESS */;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
var _this = this;
|
|
468
|
+
}
|
|
469
|
+
handleRemoveTarget(targetConfiguration) {
|
|
483
470
|
if (!targetConfiguration) {
|
|
484
471
|
return -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */;
|
|
485
472
|
}
|
|
486
|
-
|
|
473
|
+
const configuredTarget = this.targetConfigurations.get(targetConfiguration.targetIdentifier);
|
|
487
474
|
if (!configuredTarget) {
|
|
488
475
|
return -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */;
|
|
489
476
|
}
|
|
490
477
|
if (targetConfiguration.buttonConfiguration) {
|
|
491
|
-
for (
|
|
478
|
+
for (const key in targetConfiguration.buttonConfiguration) {
|
|
492
479
|
if (Object.prototype.hasOwnProperty.call(targetConfiguration.buttonConfiguration, key)) {
|
|
493
480
|
delete configuredTarget.buttonConfiguration[key];
|
|
494
481
|
}
|
|
495
482
|
}
|
|
496
483
|
debug("Removed %d button configurations of target '%s' (%d)", Object.keys(targetConfiguration.buttonConfiguration).length, configuredTarget.targetName, configuredTarget.targetIdentifier);
|
|
497
|
-
setTimeout(
|
|
484
|
+
setTimeout(() => this.emit("target-update" /* RemoteControllerEvents.TARGET_UPDATED */, configuredTarget, [3 /* TargetUpdates.REMOVED_BUTTONS */]), 0);
|
|
498
485
|
}
|
|
499
486
|
else {
|
|
500
487
|
this.targetConfigurations.delete(targetConfiguration.targetIdentifier);
|
|
501
488
|
debug("Target '%s' (%d) was removed", configuredTarget.targetName, configuredTarget.targetIdentifier);
|
|
502
|
-
setTimeout(
|
|
503
|
-
|
|
489
|
+
setTimeout(() => this.emit("target-remove" /* RemoteControllerEvents.TARGET_REMOVED */, targetConfiguration.targetIdentifier), 0);
|
|
490
|
+
const keys = Object.keys(this.targetConfigurations);
|
|
504
491
|
this.setActiveIdentifier(keys.length === 0 ? 0 : parseInt(keys[0], 10)); // switch to next available remote
|
|
505
492
|
}
|
|
506
493
|
this.updatedTargetConfiguration(); // set response
|
|
507
494
|
return 0 /* HAPStatus.SUCCESS */;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
var _this = this;
|
|
495
|
+
}
|
|
496
|
+
handleResetTargets(targetConfiguration) {
|
|
511
497
|
if (targetConfiguration) {
|
|
512
498
|
return -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */;
|
|
513
499
|
}
|
|
514
500
|
debug("Resetting all target configurations");
|
|
515
501
|
this.targetConfigurations = new Map();
|
|
516
502
|
this.updatedTargetConfiguration(); // set response
|
|
517
|
-
setTimeout(
|
|
503
|
+
setTimeout(() => this.emit("targets-reset" /* RemoteControllerEvents.TARGETS_RESET */), 0);
|
|
518
504
|
this.setActiveIdentifier(0); // resetting active identifier (also sets active to false)
|
|
519
505
|
return 0 /* HAPStatus.SUCCESS */;
|
|
520
|
-
}
|
|
521
|
-
|
|
506
|
+
}
|
|
507
|
+
handleListTargets(targetConfiguration) {
|
|
522
508
|
if (targetConfiguration) {
|
|
523
509
|
return -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */;
|
|
524
510
|
}
|
|
525
511
|
// this.targetConfigurationsString is updated after each change, so we basically don't need to do anything here
|
|
526
512
|
debug("Returning " + Object.keys(this.targetConfigurations).length + " target configurations");
|
|
527
513
|
return 0 /* HAPStatus.SUCCESS */;
|
|
528
|
-
}
|
|
529
|
-
|
|
514
|
+
}
|
|
515
|
+
handleActiveWrite(value, callback, connection) {
|
|
530
516
|
if (this.activeIdentifier === 0) {
|
|
531
517
|
debug("Tried to change active state. There is no active target set though");
|
|
532
518
|
callback(-70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */);
|
|
@@ -542,7 +528,7 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
542
528
|
this.activeConnectionDisconnectListener = this.handleActiveSessionDisconnected.bind(this, this.activeConnection);
|
|
543
529
|
this.activeConnection.on("closed" /* HAPConnectionEvent.CLOSED */, this.activeConnectionDisconnectListener);
|
|
544
530
|
}
|
|
545
|
-
|
|
531
|
+
const activeTarget = this.targetConfigurations.get(this.activeIdentifier);
|
|
546
532
|
if (!activeTarget) {
|
|
547
533
|
callback(-70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */);
|
|
548
534
|
return;
|
|
@@ -550,9 +536,8 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
550
536
|
debug("Remote with activeTarget '%s' (%d) was set to %s", activeTarget.targetName, this.activeIdentifier, value ? "ACTIVE" : "INACTIVE");
|
|
551
537
|
callback();
|
|
552
538
|
this.emit("active-change" /* RemoteControllerEvents.ACTIVE_CHANGE */, value);
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
var _this = this;
|
|
539
|
+
}
|
|
540
|
+
setInactive() {
|
|
556
541
|
if (this.activeConnection === undefined) {
|
|
557
542
|
return;
|
|
558
543
|
}
|
|
@@ -561,17 +546,17 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
561
546
|
this.activeConnectionDisconnectListener = undefined;
|
|
562
547
|
this.targetControlService.getCharacteristic(Characteristic_1.Characteristic.Active).updateValue(false);
|
|
563
548
|
debug("Remote was set to INACTIVE");
|
|
564
|
-
setTimeout(
|
|
565
|
-
}
|
|
566
|
-
|
|
549
|
+
setTimeout(() => this.emit("active-change" /* RemoteControllerEvents.ACTIVE_CHANGE */, false), 0);
|
|
550
|
+
}
|
|
551
|
+
handleActiveSessionDisconnected(connection) {
|
|
567
552
|
if (connection !== this.activeConnection) {
|
|
568
553
|
return;
|
|
569
554
|
}
|
|
570
555
|
debug("Active hap session disconnected!");
|
|
571
556
|
this.setInactive();
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
|
|
557
|
+
}
|
|
558
|
+
sendButtonEvent(button, buttonState) {
|
|
559
|
+
const buttonID = this.buttons[button];
|
|
575
560
|
if (buttonID === undefined || buttonID === 0) {
|
|
576
561
|
throw new Error("Tried sending button event for unsupported button (" + button + ")");
|
|
577
562
|
}
|
|
@@ -590,33 +575,33 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
590
575
|
}
|
|
591
576
|
return;
|
|
592
577
|
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
578
|
+
const buttonIdTlv = tlv.encode(1 /* ButtonEvent.BUTTON_ID */, buttonID);
|
|
579
|
+
const buttonStateTlv = tlv.encode(2 /* ButtonEvent.BUTTON_STATE */, buttonState);
|
|
580
|
+
const timestampTlv = tlv.encode(3 /* ButtonEvent.TIMESTAMP */, tlv.writeVariableUIntLE(new Date().getTime()));
|
|
581
|
+
const activeIdentifierTlv = tlv.encode(4 /* ButtonEvent.ACTIVE_IDENTIFIER */, tlv.writeUInt32(this.activeIdentifier));
|
|
597
582
|
this.lastButtonEvent = Buffer.concat([
|
|
598
583
|
buttonIdTlv, buttonStateTlv, timestampTlv, activeIdentifierTlv,
|
|
599
584
|
]).toString("base64");
|
|
600
585
|
this.targetControlService.getCharacteristic(Characteristic_1.Characteristic.ButtonEvent).sendEventNotification(this.lastButtonEvent);
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
586
|
+
}
|
|
587
|
+
parseTargetConfigurationTLV(data) {
|
|
588
|
+
const configTLV = tlv.decode(data);
|
|
589
|
+
const identifier = tlv.readUInt32(configTLV[1 /* TargetConfigurationTypes.TARGET_IDENTIFIER */]);
|
|
590
|
+
let name = undefined;
|
|
606
591
|
if (configTLV[2 /* TargetConfigurationTypes.TARGET_NAME */]) {
|
|
607
592
|
name = configTLV[2 /* TargetConfigurationTypes.TARGET_NAME */].toString();
|
|
608
593
|
}
|
|
609
|
-
|
|
594
|
+
let category = undefined;
|
|
610
595
|
if (configTLV[3 /* TargetConfigurationTypes.TARGET_CATEGORY */]) {
|
|
611
596
|
category = tlv.readUInt16(configTLV[3 /* TargetConfigurationTypes.TARGET_CATEGORY */]);
|
|
612
597
|
}
|
|
613
|
-
|
|
598
|
+
const buttonConfiguration = {};
|
|
614
599
|
if (configTLV[4 /* TargetConfigurationTypes.BUTTON_CONFIGURATION */]) {
|
|
615
|
-
|
|
616
|
-
buttonConfigurationTLV.forEach(
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
600
|
+
const buttonConfigurationTLV = tlv.decodeList(configTLV[4 /* TargetConfigurationTypes.BUTTON_CONFIGURATION */], 1 /* ButtonConfigurationTypes.BUTTON_ID */);
|
|
601
|
+
buttonConfigurationTLV.forEach(entry => {
|
|
602
|
+
const buttonId = entry[1 /* ButtonConfigurationTypes.BUTTON_ID */][0];
|
|
603
|
+
const buttonType = tlv.readUInt16(entry[2 /* ButtonConfigurationTypes.BUTTON_TYPE */]);
|
|
604
|
+
let buttonName;
|
|
620
605
|
if (entry[3 /* ButtonConfigurationTypes.BUTTON_NAME */]) {
|
|
621
606
|
buttonName = entry[3 /* ButtonConfigurationTypes.BUTTON_NAME */].toString();
|
|
622
607
|
}
|
|
@@ -637,74 +622,52 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
637
622
|
targetCategory: category,
|
|
638
623
|
buttonConfiguration: buttonConfiguration,
|
|
639
624
|
};
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
var tlvBuffer = tlv.encode(1 /* ButtonConfigurationTypes.BUTTON_ID */, value.buttonID, 2 /* ButtonConfigurationTypes.BUTTON_TYPE */, tlv.writeUInt16(value.buttonType));
|
|
656
|
-
if (value.buttonName) {
|
|
657
|
-
tlvBuffer = Buffer.concat([
|
|
658
|
-
tlvBuffer,
|
|
659
|
-
tlv.encode(3 /* ButtonConfigurationTypes.BUTTON_NAME */, value.buttonName),
|
|
660
|
-
]);
|
|
661
|
-
}
|
|
662
|
-
buttonConfigurationBuffers.push(tlvBuffer);
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
666
|
-
finally {
|
|
667
|
-
try {
|
|
668
|
-
if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
|
|
669
|
-
}
|
|
670
|
-
finally { if (e_4) throw e_4.error; }
|
|
625
|
+
}
|
|
626
|
+
updatedTargetConfiguration() {
|
|
627
|
+
const bufferList = [];
|
|
628
|
+
for (const configuration of Object.values(this.targetConfigurations)) {
|
|
629
|
+
const targetIdentifier = tlv.encode(1 /* TargetConfigurationTypes.TARGET_IDENTIFIER */, tlv.writeUInt32(configuration.targetIdentifier));
|
|
630
|
+
const targetName = tlv.encode(2 /* TargetConfigurationTypes.TARGET_NAME */, configuration.targetName);
|
|
631
|
+
const targetCategory = tlv.encode(3 /* TargetConfigurationTypes.TARGET_CATEGORY */, tlv.writeUInt16(configuration.targetCategory));
|
|
632
|
+
const buttonConfigurationBuffers = [];
|
|
633
|
+
for (const value of configuration.buttonConfiguration.values()) {
|
|
634
|
+
let tlvBuffer = tlv.encode(1 /* ButtonConfigurationTypes.BUTTON_ID */, value.buttonID, 2 /* ButtonConfigurationTypes.BUTTON_TYPE */, tlv.writeUInt16(value.buttonType));
|
|
635
|
+
if (value.buttonName) {
|
|
636
|
+
tlvBuffer = Buffer.concat([
|
|
637
|
+
tlvBuffer,
|
|
638
|
+
tlv.encode(3 /* ButtonConfigurationTypes.BUTTON_NAME */, value.buttonName),
|
|
639
|
+
]);
|
|
671
640
|
}
|
|
672
|
-
|
|
673
|
-
var targetConfiguration = Buffer.concat([targetIdentifier, targetName, targetCategory, buttonConfiguration]);
|
|
674
|
-
bufferList.push(tlv.encode(2 /* TargetControlList.TARGET_CONFIGURATION */, targetConfiguration));
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
678
|
-
finally {
|
|
679
|
-
try {
|
|
680
|
-
if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
|
|
641
|
+
buttonConfigurationBuffers.push(tlvBuffer);
|
|
681
642
|
}
|
|
682
|
-
|
|
643
|
+
const buttonConfiguration = tlv.encode(4 /* TargetConfigurationTypes.BUTTON_CONFIGURATION */, Buffer.concat(buttonConfigurationBuffers));
|
|
644
|
+
const targetConfiguration = Buffer.concat([targetIdentifier, targetName, targetCategory, buttonConfiguration]);
|
|
645
|
+
bufferList.push(tlv.encode(2 /* TargetControlList.TARGET_CONFIGURATION */, targetConfiguration));
|
|
683
646
|
}
|
|
684
647
|
this.targetConfigurationsString = Buffer.concat(bufferList).toString("base64");
|
|
685
|
-
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
configuration.supportedButtonConfiguration.forEach(
|
|
692
|
-
|
|
648
|
+
this.stateChangeDelegate?.();
|
|
649
|
+
}
|
|
650
|
+
buildTargetControlSupportedConfigurationTLV(configuration) {
|
|
651
|
+
const maximumTargets = tlv.encode(1 /* TargetControlCommands.MAXIMUM_TARGETS */, configuration.maximumTargets);
|
|
652
|
+
const ticksPerSecond = tlv.encode(2 /* TargetControlCommands.TICKS_PER_SECOND */, tlv.writeVariableUIntLE(configuration.ticksPerSecond));
|
|
653
|
+
const supportedButtonConfigurationBuffers = [];
|
|
654
|
+
configuration.supportedButtonConfiguration.forEach(value => {
|
|
655
|
+
const tlvBuffer = tlv.encode(1 /* SupportedButtonConfigurationTypes.BUTTON_ID */, value.buttonID, 2 /* SupportedButtonConfigurationTypes.BUTTON_TYPE */, tlv.writeUInt16(value.buttonType));
|
|
693
656
|
supportedButtonConfigurationBuffers.push(tlvBuffer);
|
|
694
657
|
});
|
|
695
|
-
|
|
696
|
-
|
|
658
|
+
const supportedButtonConfiguration = tlv.encode(3 /* TargetControlCommands.SUPPORTED_BUTTON_CONFIGURATION */, Buffer.concat(supportedButtonConfigurationBuffers));
|
|
659
|
+
const type = tlv.encode(4 /* TargetControlCommands.TYPE */, configuration.hardwareImplemented ? 1 : 0);
|
|
697
660
|
return Buffer.concat([maximumTargets, ticksPerSecond, supportedButtonConfiguration, type]).toString("base64");
|
|
698
|
-
}
|
|
661
|
+
}
|
|
699
662
|
// --------------------------------- SIRI/DATA STREAM --------------------------------
|
|
700
663
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
701
|
-
|
|
702
|
-
|
|
664
|
+
handleTargetControlWhoAmI(connection, message) {
|
|
665
|
+
const targetIdentifier = message.identifier;
|
|
703
666
|
this.dataStreamConnections.set(targetIdentifier, connection);
|
|
704
667
|
debug("Discovered HDS connection for targetIdentifier %s", targetIdentifier);
|
|
705
668
|
connection.addProtocolHandler("dataSend" /* Protocols.DATA_SEND */, this);
|
|
706
|
-
}
|
|
707
|
-
|
|
669
|
+
}
|
|
670
|
+
handleSiriAudioStart() {
|
|
708
671
|
if (!this.audioSupported) {
|
|
709
672
|
throw new Error("Cannot start siri stream on remote where siri is not supported");
|
|
710
673
|
}
|
|
@@ -718,13 +681,13 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
718
681
|
debug("Tried opening Siri audio stream, however there is already one in progress");
|
|
719
682
|
return;
|
|
720
683
|
}
|
|
721
|
-
|
|
684
|
+
const connection = this.dataStreamConnections.get(this.activeIdentifier); // get connection for current target
|
|
722
685
|
if (connection === undefined) { // target seems not connected, ignore it
|
|
723
686
|
debug("Tried opening Siri audio stream however target is not connected via HDS");
|
|
724
687
|
return;
|
|
725
688
|
}
|
|
726
689
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
727
|
-
|
|
690
|
+
const audioSession = new SiriAudioSession(connection, this.selectedAudioConfiguration, this.audioProducerConstructor, this.audioProducerOptions);
|
|
728
691
|
if (!this.activeAudioSession) {
|
|
729
692
|
this.activeAudioSession = audioSession;
|
|
730
693
|
}
|
|
@@ -735,8 +698,8 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
735
698
|
}
|
|
736
699
|
audioSession.on("close" /* SiriAudioSessionEvents.CLOSE */, this.handleSiriAudioSessionClosed.bind(this, audioSession));
|
|
737
700
|
audioSession.start();
|
|
738
|
-
}
|
|
739
|
-
|
|
701
|
+
}
|
|
702
|
+
handleSiriAudioStop() {
|
|
740
703
|
if (this.activeAudioSession) {
|
|
741
704
|
if (!this.activeAudioSession.isClosing()) {
|
|
742
705
|
this.activeAudioSession.stop();
|
|
@@ -748,11 +711,11 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
748
711
|
}
|
|
749
712
|
}
|
|
750
713
|
debug("handleSiriAudioStop called although no audio session was started");
|
|
751
|
-
}
|
|
714
|
+
}
|
|
752
715
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
716
|
+
handleDataSendAckEvent(message) {
|
|
717
|
+
const streamId = message.streamId;
|
|
718
|
+
const endOfStream = message.endOfStream;
|
|
756
719
|
if (this.activeAudioSession && this.activeAudioSession.streamId === streamId) {
|
|
757
720
|
this.activeAudioSession.handleDataSendAckEvent(endOfStream);
|
|
758
721
|
}
|
|
@@ -762,11 +725,11 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
762
725
|
else {
|
|
763
726
|
debug("Received dataSend acknowledgment event for unknown streamId '%s'", streamId);
|
|
764
727
|
}
|
|
765
|
-
}
|
|
728
|
+
}
|
|
766
729
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
730
|
+
handleDataSendCloseEvent(message) {
|
|
731
|
+
const streamId = message.streamId;
|
|
732
|
+
const reason = message.reason;
|
|
770
733
|
if (this.activeAudioSession && this.activeAudioSession.streamId === streamId) {
|
|
771
734
|
this.activeAudioSession.handleDataSendCloseEvent(reason);
|
|
772
735
|
}
|
|
@@ -776,8 +739,8 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
776
739
|
else {
|
|
777
740
|
debug("Received dataSend close event for unknown streamId '%s'", streamId);
|
|
778
741
|
}
|
|
779
|
-
}
|
|
780
|
-
|
|
742
|
+
}
|
|
743
|
+
handleSiriAudioSessionClosed(session) {
|
|
781
744
|
if (session === this.activeAudioSession) {
|
|
782
745
|
this.activeAudioSession = this.nextAudioSession;
|
|
783
746
|
this.nextAudioSession = undefined;
|
|
@@ -785,38 +748,27 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
785
748
|
else if (session === this.nextAudioSession) {
|
|
786
749
|
this.nextAudioSession = undefined;
|
|
787
750
|
}
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
debug("HDS connection disconnected for targetIdentifier %s", targetIdentifier);
|
|
796
|
-
this.dataStreamConnections.delete(targetIdentifier);
|
|
797
|
-
break;
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
802
|
-
finally {
|
|
803
|
-
try {
|
|
804
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
751
|
+
}
|
|
752
|
+
handleDataStreamConnectionClosed(connection) {
|
|
753
|
+
for (const [targetIdentifier, connection0] of this.dataStreamConnections) {
|
|
754
|
+
if (connection === connection0) {
|
|
755
|
+
debug("HDS connection disconnected for targetIdentifier %s", targetIdentifier);
|
|
756
|
+
this.dataStreamConnections.delete(targetIdentifier);
|
|
757
|
+
break;
|
|
805
758
|
}
|
|
806
|
-
finally { if (e_5) throw e_5.error; }
|
|
807
759
|
}
|
|
808
|
-
}
|
|
760
|
+
}
|
|
809
761
|
// ------------------------------- AUDIO CONFIGURATION -------------------------------
|
|
810
762
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
763
|
+
handleSelectedAudioConfigurationWrite(value, callback) {
|
|
764
|
+
const data = Buffer.from(value, "base64");
|
|
765
|
+
const objects = tlv.decode(data);
|
|
766
|
+
const selectedAudioStreamConfiguration = tlv.decode(objects[1 /* SelectedAudioInputStreamConfigurationTypes.SELECTED_AUDIO_INPUT_STREAM_CONFIGURATION */]);
|
|
767
|
+
const codec = selectedAudioStreamConfiguration[1 /* AudioCodecConfigurationTypes.CODEC_TYPE */][0];
|
|
768
|
+
const parameters = tlv.decode(selectedAudioStreamConfiguration[2 /* AudioCodecConfigurationTypes.CODEC_PARAMETERS */]);
|
|
769
|
+
const channels = parameters[1 /* AudioCodecParametersTypes.CHANNEL */][0];
|
|
770
|
+
const bitrate = parameters[2 /* AudioCodecParametersTypes.BIT_RATE */][0];
|
|
771
|
+
const samplerate = parameters[3 /* AudioCodecParametersTypes.SAMPLE_RATE */][0];
|
|
820
772
|
this.selectedAudioConfiguration = {
|
|
821
773
|
codecType: codec,
|
|
822
774
|
parameters: {
|
|
@@ -830,20 +782,20 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
830
782
|
audioCodecConfiguration: this.selectedAudioConfiguration,
|
|
831
783
|
});
|
|
832
784
|
callback();
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
785
|
+
}
|
|
786
|
+
static buildSupportedAudioConfigurationTLV(configuration) {
|
|
787
|
+
const codecConfigurationTLV = RemoteController.buildCodecConfigurationTLV(configuration.audioCodecConfiguration);
|
|
788
|
+
const supportedAudioStreamConfiguration = tlv.encode(1 /* SupportedAudioStreamConfigurationTypes.AUDIO_CODEC_CONFIGURATION */, codecConfigurationTLV);
|
|
837
789
|
return supportedAudioStreamConfiguration.toString("base64");
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
790
|
+
}
|
|
791
|
+
static buildSelectedAudioConfigurationTLV(configuration) {
|
|
792
|
+
const codecConfigurationTLV = RemoteController.buildCodecConfigurationTLV(configuration.audioCodecConfiguration);
|
|
793
|
+
const supportedAudioStreamConfiguration = tlv.encode(1 /* SelectedAudioInputStreamConfigurationTypes.SELECTED_AUDIO_INPUT_STREAM_CONFIGURATION */, codecConfigurationTLV);
|
|
842
794
|
return supportedAudioStreamConfiguration.toString("base64");
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
795
|
+
}
|
|
796
|
+
static buildCodecConfigurationTLV(codecConfiguration) {
|
|
797
|
+
const parameters = codecConfiguration.parameters;
|
|
798
|
+
let parametersTLV = tlv.encode(1 /* AudioCodecParametersTypes.CHANNEL */, parameters.channels, 2 /* AudioCodecParametersTypes.BIT_RATE */, parameters.bitrate, 3 /* AudioCodecParametersTypes.SAMPLE_RATE */, parameters.samplerate);
|
|
847
799
|
if (parameters.rtpTime) {
|
|
848
800
|
parametersTLV = Buffer.concat([
|
|
849
801
|
parametersTLV,
|
|
@@ -851,13 +803,12 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
851
803
|
]);
|
|
852
804
|
}
|
|
853
805
|
return tlv.encode(1 /* AudioCodecConfigurationTypes.CODEC_TYPE */, codecConfiguration.codecType, 2 /* AudioCodecConfigurationTypes.CODEC_PARAMETERS */, parametersTLV);
|
|
854
|
-
}
|
|
806
|
+
}
|
|
855
807
|
// -----------------------------------------------------------------------------------
|
|
856
808
|
/**
|
|
857
809
|
* @private
|
|
858
810
|
*/
|
|
859
|
-
|
|
860
|
-
var _a;
|
|
811
|
+
constructServices() {
|
|
861
812
|
this.targetControlManagementService = new Service_1.Service.TargetControlManagement("", "");
|
|
862
813
|
this.targetControlManagementService.setCharacteristic(Characteristic_1.Characteristic.TargetControlSupportedConfiguration, this.supportedConfiguration);
|
|
863
814
|
this.targetControlManagementService.setCharacteristic(Characteristic_1.Characteristic.TargetControlList, this.targetConfigurationsString);
|
|
@@ -883,195 +834,180 @@ var RemoteController = /** @class */ (function (_super) {
|
|
|
883
834
|
targetControl: this.targetControlService,
|
|
884
835
|
siri: this.siriService,
|
|
885
836
|
audioStreamManagement: this.audioStreamManagementService,
|
|
886
|
-
dataStreamTransportManagement:
|
|
837
|
+
dataStreamTransportManagement: this.dataStreamManagement?.getService(),
|
|
887
838
|
};
|
|
888
|
-
}
|
|
839
|
+
}
|
|
889
840
|
/**
|
|
890
841
|
* @private
|
|
891
842
|
*/
|
|
892
|
-
|
|
843
|
+
initWithServices(serviceMap) {
|
|
893
844
|
this.targetControlManagementService = serviceMap.targetControlManagement;
|
|
894
845
|
this.targetControlService = serviceMap.targetControl;
|
|
895
846
|
this.siriService = serviceMap.siri;
|
|
896
847
|
this.audioStreamManagementService = serviceMap.audioStreamManagement;
|
|
897
848
|
this.dataStreamManagement = new datastream_1.DataStreamManagement(serviceMap.dataStreamTransportManagement);
|
|
898
|
-
}
|
|
849
|
+
}
|
|
899
850
|
/**
|
|
900
851
|
* @private
|
|
901
852
|
*/
|
|
902
|
-
|
|
903
|
-
var _a;
|
|
904
|
-
var _this = this;
|
|
853
|
+
configureServices() {
|
|
905
854
|
if (!this.targetControlManagementService || !this.targetControlService) {
|
|
906
855
|
throw new Error("Unexpected state: Services not configured!"); // playing it save
|
|
907
856
|
}
|
|
908
857
|
this.targetControlManagementService.getCharacteristic(Characteristic_1.Characteristic.TargetControlList)
|
|
909
|
-
.on("get" /* CharacteristicEventTypes.GET */,
|
|
910
|
-
callback(null,
|
|
858
|
+
.on("get" /* CharacteristicEventTypes.GET */, callback => {
|
|
859
|
+
callback(null, this.targetConfigurationsString);
|
|
911
860
|
})
|
|
912
861
|
.on("set" /* CharacteristicEventTypes.SET */, this.handleTargetControlWrite.bind(this));
|
|
913
862
|
this.targetControlService.getCharacteristic(Characteristic_1.Characteristic.ActiveIdentifier)
|
|
914
|
-
.on("get" /* CharacteristicEventTypes.GET */,
|
|
915
|
-
callback(undefined,
|
|
863
|
+
.on("get" /* CharacteristicEventTypes.GET */, callback => {
|
|
864
|
+
callback(undefined, this.activeIdentifier);
|
|
916
865
|
});
|
|
917
866
|
this.targetControlService.getCharacteristic(Characteristic_1.Characteristic.Active)
|
|
918
|
-
.on("get" /* CharacteristicEventTypes.GET */,
|
|
919
|
-
callback(undefined,
|
|
867
|
+
.on("get" /* CharacteristicEventTypes.GET */, callback => {
|
|
868
|
+
callback(undefined, this.isActive());
|
|
920
869
|
})
|
|
921
|
-
.on("set" /* CharacteristicEventTypes.SET */,
|
|
870
|
+
.on("set" /* CharacteristicEventTypes.SET */, (value, callback, context, connection) => {
|
|
922
871
|
if (!connection) {
|
|
923
872
|
debug("Set event handler for Remote.Active cannot be called from plugin. Connection undefined!");
|
|
924
873
|
callback(-70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */);
|
|
925
874
|
return;
|
|
926
875
|
}
|
|
927
|
-
|
|
876
|
+
this.handleActiveWrite(value, callback, connection);
|
|
928
877
|
});
|
|
929
878
|
this.targetControlService.getCharacteristic(Characteristic_1.Characteristic.ButtonEvent)
|
|
930
|
-
.on("get" /* CharacteristicEventTypes.GET */,
|
|
931
|
-
callback(undefined,
|
|
879
|
+
.on("get" /* CharacteristicEventTypes.GET */, (callback) => {
|
|
880
|
+
callback(undefined, this.lastButtonEvent);
|
|
932
881
|
});
|
|
933
882
|
if (this.audioSupported) {
|
|
934
883
|
this.audioStreamManagementService.getCharacteristic(Characteristic_1.Characteristic.SelectedAudioStreamConfiguration)
|
|
935
|
-
.on("get" /* CharacteristicEventTypes.GET */,
|
|
936
|
-
callback(null,
|
|
884
|
+
.on("get" /* CharacteristicEventTypes.GET */, callback => {
|
|
885
|
+
callback(null, this.selectedAudioConfigurationString);
|
|
937
886
|
})
|
|
938
887
|
.on("set" /* CharacteristicEventTypes.SET */, this.handleSelectedAudioConfigurationWrite.bind(this))
|
|
939
888
|
.updateValue(this.selectedAudioConfigurationString);
|
|
940
889
|
this.dataStreamManagement
|
|
941
890
|
.onEventMessage("targetControl" /* Protocols.TARGET_CONTROL */, "whoami" /* Topics.WHOAMI */, this.handleTargetControlWhoAmI.bind(this))
|
|
942
891
|
.onServerEvent("connection-closed" /* DataStreamServerEvent.CONNECTION_CLOSED */, this.handleDataStreamConnectionClosed.bind(this));
|
|
943
|
-
this.eventHandler =
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
892
|
+
this.eventHandler = {
|
|
893
|
+
["ack" /* Topics.ACK */]: this.handleDataSendAckEvent.bind(this),
|
|
894
|
+
["close" /* Topics.CLOSE */]: this.handleDataSendCloseEvent.bind(this),
|
|
895
|
+
};
|
|
947
896
|
}
|
|
948
|
-
}
|
|
897
|
+
}
|
|
949
898
|
/**
|
|
950
899
|
* @private
|
|
951
900
|
*/
|
|
952
|
-
|
|
953
|
-
var _a;
|
|
901
|
+
handleControllerRemoved() {
|
|
954
902
|
this.targetControlManagementService = undefined;
|
|
955
903
|
this.targetControlService = undefined;
|
|
956
904
|
this.siriService = undefined;
|
|
957
905
|
this.audioStreamManagementService = undefined;
|
|
958
906
|
this.eventHandler = undefined;
|
|
959
907
|
this.requestHandler = undefined;
|
|
960
|
-
|
|
908
|
+
this.dataStreamManagement?.destroy();
|
|
961
909
|
this.dataStreamManagement = undefined;
|
|
962
910
|
// the call to dataStreamManagement.destroy will close any open data stream connection
|
|
963
911
|
// which will result in a call to this.handleDataStreamConnectionClosed, cleaning up this.dataStreamConnections.
|
|
964
912
|
// It will also result in a call to SiriAudioSession.handleDataStreamConnectionClosed (if there are any open session)
|
|
965
913
|
// which again results in a call to this.handleSiriAudioSessionClosed,cleaning up this.activeAudioSession and this.nextAudioSession.
|
|
966
|
-
}
|
|
914
|
+
}
|
|
967
915
|
/**
|
|
968
916
|
* @private
|
|
969
917
|
*/
|
|
970
|
-
|
|
918
|
+
handleFactoryReset() {
|
|
971
919
|
debug("Running factory reset. Resetting targets...");
|
|
972
920
|
this.handleResetTargets(undefined);
|
|
973
921
|
this.lastButtonEvent = "";
|
|
974
|
-
}
|
|
922
|
+
}
|
|
975
923
|
/**
|
|
976
924
|
* @private
|
|
977
925
|
*/
|
|
978
|
-
|
|
926
|
+
serialize() {
|
|
979
927
|
if (!this.activeIdentifier && Object.keys(this.targetConfigurations).length === 0) {
|
|
980
928
|
return undefined;
|
|
981
929
|
}
|
|
982
930
|
return {
|
|
983
931
|
activeIdentifier: this.activeIdentifier,
|
|
984
|
-
targetConfigurations:
|
|
985
|
-
var _b = tslib_1.__read(_a, 2), key = _b[0], value = _b[1];
|
|
932
|
+
targetConfigurations: [...this.targetConfigurations].reduce((obj, [key, value]) => {
|
|
986
933
|
obj[key] = value;
|
|
987
934
|
return obj;
|
|
988
935
|
}, {}),
|
|
989
936
|
};
|
|
990
|
-
}
|
|
937
|
+
}
|
|
991
938
|
/**
|
|
992
939
|
* @private
|
|
993
940
|
*/
|
|
994
|
-
|
|
941
|
+
deserialize(serialized) {
|
|
995
942
|
this.activeIdentifier = serialized.activeIdentifier;
|
|
996
|
-
this.targetConfigurations = Object.entries(serialized.targetConfigurations).reduce(
|
|
997
|
-
|
|
998
|
-
var identifier = parseInt(key, 10);
|
|
943
|
+
this.targetConfigurations = Object.entries(serialized.targetConfigurations).reduce((map, [key, value]) => {
|
|
944
|
+
const identifier = parseInt(key, 10);
|
|
999
945
|
map.set(identifier, value);
|
|
1000
946
|
return map;
|
|
1001
947
|
}, new Map());
|
|
1002
948
|
this.updatedTargetConfiguration();
|
|
1003
|
-
}
|
|
949
|
+
}
|
|
1004
950
|
/**
|
|
1005
951
|
* @private
|
|
1006
952
|
*/
|
|
1007
|
-
|
|
953
|
+
setupStateChangeDelegate(delegate) {
|
|
1008
954
|
this.stateChangeDelegate = delegate;
|
|
1009
|
-
};
|
|
1010
|
-
return RemoteController;
|
|
1011
|
-
}(events_1.EventEmitter));
|
|
1012
|
-
exports.RemoteController = RemoteController;
|
|
1013
|
-
// noinspection JSUnusedGlobalSymbols
|
|
1014
|
-
/**
|
|
1015
|
-
* @deprecated - only there for backwards compatibility, please use {@link RemoteController} directly
|
|
1016
|
-
* @group Apple TV Remote
|
|
1017
|
-
*/
|
|
1018
|
-
var HomeKitRemoteController = /** @class */ (function (_super) {
|
|
1019
|
-
tslib_1.__extends(HomeKitRemoteController, _super);
|
|
1020
|
-
function HomeKitRemoteController() {
|
|
1021
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
1022
955
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
exports.HomeKitRemoteController = HomeKitRemoteController;
|
|
956
|
+
}
|
|
957
|
+
exports.RemoteController = RemoteController;
|
|
1026
958
|
/**
|
|
1027
959
|
* @group Apple TV Remote
|
|
1028
960
|
*/
|
|
1029
961
|
var SiriAudioSessionEvents;
|
|
1030
962
|
(function (SiriAudioSessionEvents) {
|
|
1031
963
|
SiriAudioSessionEvents["CLOSE"] = "close";
|
|
1032
|
-
})(SiriAudioSessionEvents
|
|
964
|
+
})(SiriAudioSessionEvents || (exports.SiriAudioSessionEvents = SiriAudioSessionEvents = {}));
|
|
1033
965
|
/**
|
|
1034
966
|
* Represents an ongoing audio transmission
|
|
1035
967
|
* @group Apple TV Remote
|
|
1036
968
|
*/
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
969
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
970
|
+
class SiriAudioSession extends events_1.EventEmitter {
|
|
971
|
+
connection;
|
|
972
|
+
selectedAudioConfiguration;
|
|
973
|
+
producer;
|
|
974
|
+
producerRunning = false; // indicates if the producer is running
|
|
975
|
+
producerTimer; // producer has a 3s timeout to produce the first frame, otherwise transmission will be cancelled
|
|
976
|
+
/**
|
|
977
|
+
* @private file private API
|
|
978
|
+
*/
|
|
979
|
+
state = 0 /* SiriAudioSessionState.STARTING */;
|
|
980
|
+
streamId; // present when state >= SENDING
|
|
981
|
+
endOfStream = false;
|
|
982
|
+
audioFrameQueue = [];
|
|
983
|
+
maxQueueSize = 1024;
|
|
984
|
+
sequenceNumber = 0;
|
|
985
|
+
closeListener;
|
|
986
|
+
constructor(connection, selectedAudioConfiguration, producerConstructor,
|
|
1040
987
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types,@typescript-eslint/no-explicit-any
|
|
1041
988
|
producerOptions) {
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
_this.state = 0 /* SiriAudioSessionState.STARTING */;
|
|
1048
|
-
_this.endOfStream = false;
|
|
1049
|
-
_this.audioFrameQueue = [];
|
|
1050
|
-
_this.maxQueueSize = 1024;
|
|
1051
|
-
_this.sequenceNumber = 0;
|
|
1052
|
-
_this.connection = connection;
|
|
1053
|
-
_this.selectedAudioConfiguration = selectedAudioConfiguration;
|
|
1054
|
-
_this.producer = new producerConstructor(_this.handleSiriAudioFrame.bind(_this), _this.handleProducerError.bind(_this), producerOptions);
|
|
1055
|
-
_this.connection.on("closed" /* DataStreamConnectionEvent.CLOSED */, _this.closeListener = _this.handleDataStreamConnectionClosed.bind(_this));
|
|
1056
|
-
return _this;
|
|
989
|
+
super();
|
|
990
|
+
this.connection = connection;
|
|
991
|
+
this.selectedAudioConfiguration = selectedAudioConfiguration;
|
|
992
|
+
this.producer = new producerConstructor(this.handleSiriAudioFrame.bind(this), this.handleProducerError.bind(this), producerOptions);
|
|
993
|
+
this.connection.on("closed" /* DataStreamConnectionEvent.CLOSED */, this.closeListener = this.handleDataStreamConnectionClosed.bind(this));
|
|
1057
994
|
}
|
|
1058
995
|
/**
|
|
1059
996
|
* Called when siri button is pressed
|
|
1060
997
|
*/
|
|
1061
|
-
|
|
1062
|
-
var _this = this;
|
|
998
|
+
start() {
|
|
1063
999
|
debug("Sending request to start siri audio stream");
|
|
1064
1000
|
// opening dataSend
|
|
1065
1001
|
this.connection.sendRequest("dataSend" /* Protocols.DATA_SEND */, "open" /* Topics.OPEN */, {
|
|
1066
1002
|
target: "controller",
|
|
1067
1003
|
type: "audio.siri",
|
|
1068
|
-
},
|
|
1069
|
-
if (
|
|
1004
|
+
}, (error, status, message) => {
|
|
1005
|
+
if (this.state === 3 /* SiriAudioSessionState.CLOSED */) {
|
|
1070
1006
|
debug("Ignoring dataSend open response as the session is already closed");
|
|
1071
1007
|
return;
|
|
1072
1008
|
}
|
|
1073
|
-
assert_1.default.strictEqual(
|
|
1074
|
-
|
|
1009
|
+
assert_1.default.strictEqual(this.state, 0 /* SiriAudioSessionState.STARTING */);
|
|
1010
|
+
this.state = 1 /* SiriAudioSessionState.SENDING */;
|
|
1075
1011
|
if (error || status) {
|
|
1076
1012
|
if (error) { // errors get produced by hap-nodejs
|
|
1077
1013
|
debug("Error occurred trying to start siri audio stream: %s", error.message);
|
|
@@ -1079,30 +1015,30 @@ var SiriAudioSession = /** @class */ (function (_super) {
|
|
|
1079
1015
|
else if (status) { // status codes are those returned by the hds response
|
|
1080
1016
|
debug("Controller responded with non-zero status code: %s", datastream_1.HDSStatus[status]);
|
|
1081
1017
|
}
|
|
1082
|
-
|
|
1018
|
+
this.closed();
|
|
1083
1019
|
}
|
|
1084
1020
|
else {
|
|
1085
|
-
|
|
1086
|
-
if (!
|
|
1087
|
-
|
|
1021
|
+
this.streamId = message.streamId;
|
|
1022
|
+
if (!this.producerRunning) { // audio producer errored in the meantime
|
|
1023
|
+
this.sendDataSendCloseEvent(3 /* HDSProtocolSpecificErrorReason.CANCELLED */);
|
|
1088
1024
|
}
|
|
1089
1025
|
else {
|
|
1090
|
-
debug("Successfully setup siri audio stream with streamId %d",
|
|
1026
|
+
debug("Successfully setup siri audio stream with streamId %d", this.streamId);
|
|
1091
1027
|
}
|
|
1092
1028
|
}
|
|
1093
1029
|
});
|
|
1094
1030
|
this.startAudioProducer(); // start audio producer and queue frames in the meantime
|
|
1095
|
-
}
|
|
1031
|
+
}
|
|
1096
1032
|
/**
|
|
1097
1033
|
* @returns if the audio session is closing
|
|
1098
1034
|
*/
|
|
1099
|
-
|
|
1035
|
+
isClosing() {
|
|
1100
1036
|
return this.state >= 2 /* SiriAudioSessionState.CLOSING */;
|
|
1101
|
-
}
|
|
1037
|
+
}
|
|
1102
1038
|
/**
|
|
1103
1039
|
* Called when siri button is released (or active identifier is changed to another device)
|
|
1104
1040
|
*/
|
|
1105
|
-
|
|
1041
|
+
stop() {
|
|
1106
1042
|
(0, assert_1.default)(this.state <= 1 /* SiriAudioSessionState.SENDING */, "state was higher than SENDING");
|
|
1107
1043
|
debug("Stopping siri audio stream with streamId %d", this.streamId);
|
|
1108
1044
|
this.endOfStream = true; // mark as endOfStream
|
|
@@ -1114,28 +1050,26 @@ var SiriAudioSession = /** @class */ (function (_super) {
|
|
|
1114
1050
|
else { // if state is not SENDING (aka state is STARTING) the callback for DATA_SEND OPEN did not yet return (or never will)
|
|
1115
1051
|
this.closed();
|
|
1116
1052
|
}
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
var _this = this;
|
|
1053
|
+
}
|
|
1054
|
+
startAudioProducer() {
|
|
1120
1055
|
this.producer.startAudioProduction(this.selectedAudioConfiguration);
|
|
1121
1056
|
this.producerRunning = true;
|
|
1122
|
-
this.producerTimer = setTimeout(
|
|
1123
|
-
debug("Didn't receive any frames from audio producer for stream with streamId %s. Canceling the stream now.",
|
|
1124
|
-
|
|
1125
|
-
|
|
1057
|
+
this.producerTimer = setTimeout(() => {
|
|
1058
|
+
debug("Didn't receive any frames from audio producer for stream with streamId %s. Canceling the stream now.", this.streamId);
|
|
1059
|
+
this.producerTimer = undefined;
|
|
1060
|
+
this.handleProducerError(3 /* HDSProtocolSpecificErrorReason.CANCELLED */);
|
|
1126
1061
|
}, 3000);
|
|
1127
1062
|
this.producerTimer.unref();
|
|
1128
|
-
}
|
|
1129
|
-
|
|
1063
|
+
}
|
|
1064
|
+
stopAudioProducer() {
|
|
1130
1065
|
this.producer.stopAudioProduction();
|
|
1131
1066
|
this.producerRunning = false;
|
|
1132
1067
|
if (this.producerTimer) {
|
|
1133
1068
|
clearTimeout(this.producerTimer);
|
|
1134
1069
|
this.producerTimer = undefined;
|
|
1135
1070
|
}
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
|
-
var _this = this;
|
|
1071
|
+
}
|
|
1072
|
+
handleSiriAudioFrame(frame) {
|
|
1139
1073
|
if (this.state >= 2 /* SiriAudioSessionState.CLOSING */) {
|
|
1140
1074
|
return;
|
|
1141
1075
|
}
|
|
@@ -1149,44 +1083,38 @@ var SiriAudioSession = /** @class */ (function (_super) {
|
|
|
1149
1083
|
if (this.state !== 1 /* SiriAudioSessionState.SENDING */) { // dataSend isn't open yet
|
|
1150
1084
|
return;
|
|
1151
1085
|
}
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
queued.forEach(
|
|
1156
|
-
|
|
1086
|
+
let queued;
|
|
1087
|
+
while ((queued = this.popSome()) !== null) { // send packets
|
|
1088
|
+
const packets = [];
|
|
1089
|
+
queued.forEach(frame => {
|
|
1090
|
+
const packetData = {
|
|
1157
1091
|
data: frame.data,
|
|
1158
1092
|
metadata: {
|
|
1159
1093
|
rms: new datastream_1.Float32(frame.rms),
|
|
1160
|
-
sequenceNumber: new datastream_1.Int64(
|
|
1094
|
+
sequenceNumber: new datastream_1.Int64(this.sequenceNumber++),
|
|
1161
1095
|
},
|
|
1162
1096
|
};
|
|
1163
1097
|
packets.push(packetData);
|
|
1164
1098
|
});
|
|
1165
|
-
|
|
1099
|
+
const message = {
|
|
1166
1100
|
packets: packets,
|
|
1167
|
-
streamId: new datastream_1.Int64(
|
|
1168
|
-
endOfStream:
|
|
1101
|
+
streamId: new datastream_1.Int64(this.streamId),
|
|
1102
|
+
endOfStream: this.endOfStream,
|
|
1169
1103
|
};
|
|
1170
1104
|
try {
|
|
1171
|
-
|
|
1105
|
+
this.connection.sendEvent("dataSend" /* Protocols.DATA_SEND */, "data" /* Topics.DATA */, message);
|
|
1172
1106
|
}
|
|
1173
1107
|
catch (error) {
|
|
1174
1108
|
debug("Error occurred when trying to send audio frame of hds connection: %s", error.message);
|
|
1175
|
-
|
|
1176
|
-
|
|
1109
|
+
this.stopAudioProducer();
|
|
1110
|
+
this.closed();
|
|
1177
1111
|
}
|
|
1178
|
-
if (
|
|
1179
|
-
|
|
1112
|
+
if (this.endOfStream) {
|
|
1113
|
+
break; // popSome() returns empty list if endOfStream=true
|
|
1180
1114
|
}
|
|
1181
|
-
};
|
|
1182
|
-
var this_1 = this;
|
|
1183
|
-
while ((queued = this.popSome()) !== null) {
|
|
1184
|
-
var state_1 = _loop_1();
|
|
1185
|
-
if (state_1 === "break")
|
|
1186
|
-
break;
|
|
1187
1115
|
}
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1116
|
+
}
|
|
1117
|
+
handleProducerError(error) {
|
|
1190
1118
|
if (this.state >= 2 /* SiriAudioSessionState.CLOSING */) {
|
|
1191
1119
|
return;
|
|
1192
1120
|
}
|
|
@@ -1194,21 +1122,21 @@ var SiriAudioSession = /** @class */ (function (_super) {
|
|
|
1194
1122
|
if (this.state === 1 /* SiriAudioSessionState.SENDING */) { // if state is less than sending dataSend isn't open (yet)
|
|
1195
1123
|
this.sendDataSendCloseEvent(error); // cancel submission
|
|
1196
1124
|
}
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1125
|
+
}
|
|
1126
|
+
handleDataSendAckEvent(endOfStream) {
|
|
1199
1127
|
assert_1.default.strictEqual(endOfStream, true);
|
|
1200
1128
|
debug("Received acknowledgment for siri audio stream with streamId %s, closing it now", this.streamId);
|
|
1201
1129
|
this.sendDataSendCloseEvent(0 /* HDSProtocolSpecificErrorReason.NORMAL */);
|
|
1202
|
-
}
|
|
1203
|
-
|
|
1130
|
+
}
|
|
1131
|
+
handleDataSendCloseEvent(reason) {
|
|
1204
1132
|
// @ts-expect-error: forceConsistentCasingInFileNames compiler option
|
|
1205
1133
|
debug("Received close event from controller with reason %s for stream with streamId %s", datastream_1.HDSProtocolSpecificErrorReason[reason], this.streamId);
|
|
1206
1134
|
if (this.state <= 1 /* SiriAudioSessionState.SENDING */) {
|
|
1207
1135
|
this.stopAudioProducer();
|
|
1208
1136
|
}
|
|
1209
1137
|
this.closed();
|
|
1210
|
-
}
|
|
1211
|
-
|
|
1138
|
+
}
|
|
1139
|
+
sendDataSendCloseEvent(reason) {
|
|
1212
1140
|
(0, assert_1.default)(this.state >= 1 /* SiriAudioSessionState.SENDING */, "state was less than SENDING");
|
|
1213
1141
|
(0, assert_1.default)(this.state <= 2 /* SiriAudioSessionState.CLOSING */, "state was higher than CLOSING");
|
|
1214
1142
|
this.connection.sendEvent("dataSend" /* Protocols.DATA_SEND */, "close" /* Topics.CLOSE */, {
|
|
@@ -1216,36 +1144,35 @@ var SiriAudioSession = /** @class */ (function (_super) {
|
|
|
1216
1144
|
reason: new datastream_1.Int64(reason),
|
|
1217
1145
|
});
|
|
1218
1146
|
this.closed();
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1147
|
+
}
|
|
1148
|
+
handleDataStreamConnectionClosed() {
|
|
1221
1149
|
debug("Closing audio session with streamId %d", this.streamId);
|
|
1222
1150
|
if (this.state <= 1 /* SiriAudioSessionState.SENDING */) {
|
|
1223
1151
|
this.stopAudioProducer();
|
|
1224
1152
|
}
|
|
1225
1153
|
this.closed();
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1228
|
-
|
|
1154
|
+
}
|
|
1155
|
+
closed() {
|
|
1156
|
+
const lastState = this.state;
|
|
1229
1157
|
this.state = 3 /* SiriAudioSessionState.CLOSED */;
|
|
1230
1158
|
if (lastState !== 3 /* SiriAudioSessionState.CLOSED */) {
|
|
1231
1159
|
this.emit("close" /* SiriAudioSessionEvents.CLOSE */);
|
|
1232
1160
|
this.connection.removeListener("closed" /* DataStreamConnectionEvent.CLOSED */, this.closeListener);
|
|
1233
1161
|
}
|
|
1234
1162
|
this.removeAllListeners();
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1163
|
+
}
|
|
1164
|
+
popSome() {
|
|
1237
1165
|
if (this.audioFrameQueue.length < 5 && !this.endOfStream) {
|
|
1238
1166
|
return null;
|
|
1239
1167
|
}
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
for (
|
|
1243
|
-
|
|
1168
|
+
const size = Math.min(this.audioFrameQueue.length, 5); // 5 frames per hap packet seems fine
|
|
1169
|
+
const result = [];
|
|
1170
|
+
for (let i = 0; i < size; i++) {
|
|
1171
|
+
const element = this.audioFrameQueue.shift(); // removes first element
|
|
1244
1172
|
result.push(element);
|
|
1245
1173
|
}
|
|
1246
1174
|
return result;
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
}(events_1.EventEmitter));
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1250
1177
|
exports.SiriAudioSession = SiriAudioSession;
|
|
1251
1178
|
//# sourceMappingURL=RemoteController.js.map
|