hap-nodejs 0.12.3-beta.2 → 0.12.3-beta.21

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.
Files changed (175) hide show
  1. package/README.md +1 -0
  2. package/dist/accessories/AirConditioner_accessory.js +24 -24
  3. package/dist/accessories/AirConditioner_accessory.js.map +1 -1
  4. package/dist/accessories/AppleTVRemote_accessory.js +23 -23
  5. package/dist/accessories/AppleTVRemote_accessory.js.map +1 -1
  6. package/dist/accessories/Camera_accessory.js +292 -373
  7. package/dist/accessories/Camera_accessory.js.map +1 -1
  8. package/dist/accessories/Fan_accessory.js +15 -21
  9. package/dist/accessories/Fan_accessory.js.map +1 -1
  10. package/dist/accessories/GarageDoorOpener_accessory.js +12 -12
  11. package/dist/accessories/GarageDoorOpener_accessory.js.map +1 -1
  12. package/dist/accessories/Light-AdaptiveLighting_accessory.js +31 -21
  13. package/dist/accessories/Light-AdaptiveLighting_accessory.js.map +1 -1
  14. package/dist/accessories/Light_accessory.js +45 -48
  15. package/dist/accessories/Light_accessory.js.map +1 -1
  16. package/dist/accessories/Lock_accessory.js +11 -11
  17. package/dist/accessories/Lock_accessory.js.map +1 -1
  18. package/dist/accessories/MotionSensor_accessory.js +8 -8
  19. package/dist/accessories/MotionSensor_accessory.js.map +1 -1
  20. package/dist/accessories/Outlet_accessory.js +10 -10
  21. package/dist/accessories/Outlet_accessory.js.map +1 -1
  22. package/dist/accessories/SmartSpeaker_accessory.js +11 -11
  23. package/dist/accessories/SmartSpeaker_accessory.js.map +1 -1
  24. package/dist/accessories/Sprinkler_accessory.js +19 -19
  25. package/dist/accessories/Sprinkler_accessory.js.map +1 -1
  26. package/dist/accessories/TV_accessory.js +17 -17
  27. package/dist/accessories/TV_accessory.js.map +1 -1
  28. package/dist/accessories/TemperatureSensor_accessory.js +6 -6
  29. package/dist/accessories/TemperatureSensor_accessory.js.map +1 -1
  30. package/dist/accessories/Wi-FiRouter_accessory.js +3 -3
  31. package/dist/accessories/Wi-FiRouter_accessory.js.map +1 -1
  32. package/dist/accessories/Wi-FiSatellite_accessory.js +4 -4
  33. package/dist/accessories/Wi-FiSatellite_accessory.js.map +1 -1
  34. package/dist/accessories/gstreamer-audioProducer.js +36 -47
  35. package/dist/accessories/gstreamer-audioProducer.js.map +1 -1
  36. package/dist/accessories/types.js +2 -2
  37. package/dist/accessories/types.js.map +1 -1
  38. package/dist/index.d.ts +0 -14
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +5 -28
  41. package/dist/index.js.map +1 -1
  42. package/dist/lib/Accessory.d.ts +1 -58
  43. package/dist/lib/Accessory.d.ts.map +1 -1
  44. package/dist/lib/Accessory.js +747 -1149
  45. package/dist/lib/Accessory.js.map +1 -1
  46. package/dist/lib/Advertiser.d.ts +1 -2
  47. package/dist/lib/Advertiser.d.ts.map +1 -1
  48. package/dist/lib/Advertiser.js +392 -524
  49. package/dist/lib/Advertiser.js.map +1 -1
  50. package/dist/lib/Bridge.js +6 -10
  51. package/dist/lib/Bridge.js.map +1 -1
  52. package/dist/lib/Characteristic.d.ts +2 -133
  53. package/dist/lib/Characteristic.d.ts.map +1 -1
  54. package/dist/lib/Characteristic.js +1467 -669
  55. package/dist/lib/Characteristic.js.map +1 -1
  56. package/dist/lib/HAPServer.d.ts +0 -10
  57. package/dist/lib/HAPServer.d.ts.map +1 -1
  58. package/dist/lib/HAPServer.js +216 -280
  59. package/dist/lib/HAPServer.js.map +1 -1
  60. package/dist/lib/Service.d.ts +1 -51
  61. package/dist/lib/Service.d.ts.map +1 -1
  62. package/dist/lib/Service.js +474 -322
  63. package/dist/lib/Service.js.map +1 -1
  64. package/dist/lib/camera/RTPProxy.js +112 -104
  65. package/dist/lib/camera/RTPProxy.js.map +1 -1
  66. package/dist/lib/camera/RTPStreamManagement.d.ts +0 -65
  67. package/dist/lib/camera/RTPStreamManagement.d.ts.map +1 -1
  68. package/dist/lib/camera/RTPStreamManagement.js +255 -278
  69. package/dist/lib/camera/RTPStreamManagement.js.map +1 -1
  70. package/dist/lib/camera/RecordingManagement.js +318 -381
  71. package/dist/lib/camera/RecordingManagement.js.map +1 -1
  72. package/dist/lib/camera/index.d.ts +0 -1
  73. package/dist/lib/camera/index.d.ts.map +1 -1
  74. package/dist/lib/camera/index.js +1 -2
  75. package/dist/lib/camera/index.js.map +1 -1
  76. package/dist/lib/controller/AdaptiveLightingController.d.ts +19 -3
  77. package/dist/lib/controller/AdaptiveLightingController.d.ts.map +1 -1
  78. package/dist/lib/controller/AdaptiveLightingController.js +217 -218
  79. package/dist/lib/controller/AdaptiveLightingController.js.map +1 -1
  80. package/dist/lib/controller/CameraController.d.ts +0 -4
  81. package/dist/lib/controller/CameraController.d.ts.map +1 -1
  82. package/dist/lib/controller/CameraController.js +189 -256
  83. package/dist/lib/controller/CameraController.js.map +1 -1
  84. package/dist/lib/controller/DoorbellController.js +38 -39
  85. package/dist/lib/controller/DoorbellController.js.map +1 -1
  86. package/dist/lib/controller/RemoteController.d.ts +0 -14
  87. package/dist/lib/controller/RemoteController.d.ts.map +1 -1
  88. package/dist/lib/controller/RemoteController.js +340 -415
  89. package/dist/lib/controller/RemoteController.js.map +1 -1
  90. package/dist/lib/controller/index.js +1 -1
  91. package/dist/lib/datastream/DataStreamManagement.js +56 -57
  92. package/dist/lib/datastream/DataStreamManagement.js.map +1 -1
  93. package/dist/lib/datastream/DataStreamParser.js +259 -304
  94. package/dist/lib/datastream/DataStreamParser.js.map +1 -1
  95. package/dist/lib/datastream/DataStreamServer.d.ts +0 -5
  96. package/dist/lib/datastream/DataStreamServer.d.ts.map +1 -1
  97. package/dist/lib/datastream/DataStreamServer.js +252 -269
  98. package/dist/lib/datastream/DataStreamServer.js.map +1 -1
  99. package/dist/lib/datastream/index.js +1 -1
  100. package/dist/lib/definitions/CharacteristicDefinitions.d.ts +1 -106
  101. package/dist/lib/definitions/CharacteristicDefinitions.d.ts.map +1 -1
  102. package/dist/lib/definitions/CharacteristicDefinitions.js +2000 -2995
  103. package/dist/lib/definitions/CharacteristicDefinitions.js.map +1 -1
  104. package/dist/lib/definitions/ServiceDefinitions.d.ts +0 -32
  105. package/dist/lib/definitions/ServiceDefinitions.d.ts.map +1 -1
  106. package/dist/lib/definitions/ServiceDefinitions.js +820 -1147
  107. package/dist/lib/definitions/ServiceDefinitions.js.map +1 -1
  108. package/dist/lib/definitions/generate-definitions.js +383 -679
  109. package/dist/lib/definitions/generate-definitions.js.map +1 -1
  110. package/dist/lib/definitions/generator-configuration.js +29 -29
  111. package/dist/lib/definitions/generator-configuration.js.map +1 -1
  112. package/dist/lib/definitions/index.js +1 -1
  113. package/dist/lib/model/AccessoryInfo.js +101 -136
  114. package/dist/lib/model/AccessoryInfo.js.map +1 -1
  115. package/dist/lib/model/ControllerStorage.js +86 -89
  116. package/dist/lib/model/ControllerStorage.js.map +1 -1
  117. package/dist/lib/model/HAPStorage.js +15 -16
  118. package/dist/lib/model/HAPStorage.js.map +1 -1
  119. package/dist/lib/model/IdentifierCache.js +49 -49
  120. package/dist/lib/model/IdentifierCache.js.map +1 -1
  121. package/dist/lib/tv/AccessControlManagement.js +40 -44
  122. package/dist/lib/tv/AccessControlManagement.js.map +1 -1
  123. package/dist/lib/util/checkName.d.ts +2 -1
  124. package/dist/lib/util/checkName.d.ts.map +1 -1
  125. package/dist/lib/util/checkName.js +7 -11
  126. package/dist/lib/util/checkName.js.map +1 -1
  127. package/dist/lib/util/clone.js +5 -27
  128. package/dist/lib/util/clone.js.map +1 -1
  129. package/dist/lib/util/color-utils.js +8 -12
  130. package/dist/lib/util/color-utils.js.map +1 -1
  131. package/dist/lib/util/eventedhttp.d.ts.map +1 -1
  132. package/dist/lib/util/eventedhttp.js +301 -409
  133. package/dist/lib/util/eventedhttp.js.map +1 -1
  134. package/dist/lib/util/hapCrypto.js +31 -32
  135. package/dist/lib/util/hapCrypto.js.map +1 -1
  136. package/dist/lib/util/hapStatusError.js +9 -12
  137. package/dist/lib/util/hapStatusError.js.map +1 -1
  138. package/dist/lib/util/net-utils.js +32 -53
  139. package/dist/lib/util/net-utils.js.map +1 -1
  140. package/dist/lib/util/once.js +3 -8
  141. package/dist/lib/util/once.js.map +1 -1
  142. package/dist/lib/util/promise-utils.js +8 -13
  143. package/dist/lib/util/promise-utils.js.map +1 -1
  144. package/dist/lib/util/request-util.js +2 -3
  145. package/dist/lib/util/request-util.js.map +1 -1
  146. package/dist/lib/util/time.js +5 -5
  147. package/dist/lib/util/time.js.map +1 -1
  148. package/dist/lib/util/tlv.d.ts +0 -27
  149. package/dist/lib/util/tlv.d.ts.map +1 -1
  150. package/dist/lib/util/tlv.js +71 -113
  151. package/dist/lib/util/tlv.js.map +1 -1
  152. package/dist/lib/util/uuid.d.ts +0 -9
  153. package/dist/lib/util/uuid.d.ts.map +1 -1
  154. package/dist/lib/util/uuid.js +15 -33
  155. package/dist/lib/util/uuid.js.map +1 -1
  156. package/dist/types.d.ts +0 -35
  157. package/dist/types.d.ts.map +1 -1
  158. package/dist/types.js.map +1 -1
  159. package/package.json +10 -10
  160. package/dist/BridgedCore.d.ts +0 -2
  161. package/dist/BridgedCore.d.ts.map +0 -1
  162. package/dist/BridgedCore.js +0 -43
  163. package/dist/BridgedCore.js.map +0 -1
  164. package/dist/Core.d.ts +0 -2
  165. package/dist/Core.d.ts.map +0 -1
  166. package/dist/Core.js +0 -52
  167. package/dist/Core.js.map +0 -1
  168. package/dist/lib/AccessoryLoader.d.ts +0 -28
  169. package/dist/lib/AccessoryLoader.d.ts.map +0 -1
  170. package/dist/lib/AccessoryLoader.js +0 -166
  171. package/dist/lib/AccessoryLoader.js.map +0 -1
  172. package/dist/lib/camera/Camera.d.ts +0 -43
  173. package/dist/lib/camera/Camera.d.ts.map +0 -1
  174. package/dist/lib/camera/Camera.js +0 -36
  175. package/dist/lib/camera/Camera.js.map +0 -1
@@ -1,16 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RecordingManagement = exports.PacketDataType = exports.AudioRecordingSamplerate = exports.AudioRecordingCodecType = exports.MediaContainerType = exports.EventTriggerOption = void 0;
4
- var tslib_1 = require("tslib");
5
- var crypto_1 = tslib_1.__importDefault(require("crypto"));
6
- var debug_1 = tslib_1.__importDefault(require("debug"));
7
- var events_1 = require("events");
8
- var Characteristic_1 = require("../Characteristic");
9
- var datastream_1 = require("../datastream");
10
- var Service_1 = require("../Service");
11
- var hapStatusError_1 = require("../util/hapStatusError");
12
- var tlv = tslib_1.__importStar(require("../util/tlv"));
13
- var debug = (0, debug_1.default)("HAP-NodeJS:Camera:RecordingManagement");
4
+ const tslib_1 = require("tslib");
5
+ const crypto_1 = tslib_1.__importDefault(require("crypto"));
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 hapStatusError_1 = require("../util/hapStatusError");
12
+ const tlv = tslib_1.__importStar(require("../util/tlv"));
13
+ const debug = (0, debug_1.default)("HAP-NodeJS:Camera:RecordingManagement");
14
14
  /**
15
15
  * Describes the Event trigger.
16
16
  *
@@ -136,63 +136,70 @@ var PacketDataType;
136
136
  /**
137
137
  * @group Camera
138
138
  */
139
- var RecordingManagement = /** @class */ (function () {
140
- function RecordingManagement(options, delegate, eventTriggerOptions, services) {
141
- var e_1, _a;
142
- /**
143
- * Array of sensor services (e.g. {@link Service.MotionSensor} or {@link Service.OccupancySensor}).
144
- * Any service in this array owns a {@link Characteristic.StatusActive} characteristic.
145
- * The value of the {@link Characteristic.HomeKitCameraActive} is mirrored towards the {@link Characteristic.StatusActive} characteristic.
146
- * The array is initialized my the caller shortly after calling the constructor.
147
- */
148
- this.sensorServices = [];
149
- /**
150
- * Defines if recording is enabled for this recording management.
151
- */
152
- this.recordingActive = false;
139
+ class RecordingManagement {
140
+ options;
141
+ delegate;
142
+ stateChangeDelegate;
143
+ supportedCameraRecordingConfiguration;
144
+ supportedVideoRecordingConfiguration;
145
+ supportedAudioRecordingConfiguration;
146
+ /**
147
+ * 32 bit mask of enabled {@link EventTriggerOption}s.
148
+ */
149
+ eventTriggerOptions;
150
+ recordingManagementService;
151
+ operatingModeService;
152
+ dataStreamManagement;
153
+ /**
154
+ * The currently active recording stream.
155
+ * Any camera only supports one stream at a time.
156
+ */
157
+ recordingStream;
158
+ selectedConfiguration;
159
+ /**
160
+ * Array of sensor services (e.g. {@link Service.MotionSensor} or {@link Service.OccupancySensor}).
161
+ * Any service in this array owns a {@link Characteristic.StatusActive} characteristic.
162
+ * The value of the {@link Characteristic.HomeKitCameraActive} is mirrored towards the {@link Characteristic.StatusActive} characteristic.
163
+ * The array is initialized my the caller shortly after calling the constructor.
164
+ */
165
+ sensorServices = [];
166
+ /**
167
+ * Defines if recording is enabled for this recording management.
168
+ */
169
+ recordingActive = false;
170
+ constructor(options, delegate, eventTriggerOptions, services) {
153
171
  this.options = options;
154
172
  this.delegate = delegate;
155
- var recordingServices = services || this.constructService();
173
+ const recordingServices = services || this.constructService();
156
174
  this.recordingManagementService = recordingServices.recordingManagement;
157
175
  this.operatingModeService = recordingServices.operatingMode;
158
176
  this.dataStreamManagement = recordingServices.dataStreamManagement;
159
177
  this.eventTriggerOptions = 0;
160
- try {
161
- for (var eventTriggerOptions_1 = tslib_1.__values(eventTriggerOptions), eventTriggerOptions_1_1 = eventTriggerOptions_1.next(); !eventTriggerOptions_1_1.done; eventTriggerOptions_1_1 = eventTriggerOptions_1.next()) {
162
- var option = eventTriggerOptions_1_1.value;
163
- this.eventTriggerOptions |= option; // OR
164
- }
165
- }
166
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
167
- finally {
168
- try {
169
- if (eventTriggerOptions_1_1 && !eventTriggerOptions_1_1.done && (_a = eventTriggerOptions_1.return)) _a.call(eventTriggerOptions_1);
170
- }
171
- finally { if (e_1) throw e_1.error; }
178
+ for (const option of eventTriggerOptions) {
179
+ this.eventTriggerOptions |= option; // OR
172
180
  }
173
181
  this.supportedCameraRecordingConfiguration = this._supportedCameraRecordingConfiguration(options);
174
182
  this.supportedVideoRecordingConfiguration = this._supportedVideoRecordingConfiguration(options.video);
175
183
  this.supportedAudioRecordingConfiguration = this._supportedAudioStreamConfiguration(options.audio);
176
184
  this.setupServiceHandlers();
177
185
  }
178
- RecordingManagement.prototype.constructService = function () {
179
- var recordingManagement = new Service_1.Service.CameraRecordingManagement("", "");
186
+ constructService() {
187
+ const recordingManagement = new Service_1.Service.CameraRecordingManagement("", "");
180
188
  recordingManagement.setCharacteristic(Characteristic_1.Characteristic.Active, false);
181
189
  recordingManagement.setCharacteristic(Characteristic_1.Characteristic.RecordingAudioActive, false);
182
- var operatingMode = new Service_1.Service.CameraOperatingMode("", "");
190
+ const operatingMode = new Service_1.Service.CameraOperatingMode("", "");
183
191
  operatingMode.setCharacteristic(Characteristic_1.Characteristic.EventSnapshotsActive, true);
184
192
  operatingMode.setCharacteristic(Characteristic_1.Characteristic.HomeKitCameraActive, true);
185
193
  operatingMode.setCharacteristic(Characteristic_1.Characteristic.PeriodicSnapshotsActive, true);
186
- var dataStreamManagement = new datastream_1.DataStreamManagement();
194
+ const dataStreamManagement = new datastream_1.DataStreamManagement();
187
195
  recordingManagement.addLinkedService(dataStreamManagement.getService());
188
196
  return {
189
197
  recordingManagement: recordingManagement,
190
198
  operatingMode: operatingMode,
191
199
  dataStreamManagement: dataStreamManagement,
192
200
  };
193
- };
194
- RecordingManagement.prototype.setupServiceHandlers = function () {
195
- var _this = this;
201
+ }
202
+ setupServiceHandlers() {
196
203
  // update the current configuration values to the current state.
197
204
  this.recordingManagementService.setCharacteristic(Characteristic_1.Characteristic.SupportedCameraRecordingConfiguration, this.supportedCameraRecordingConfiguration);
198
205
  this.recordingManagementService.setCharacteristic(Characteristic_1.Characteristic.SupportedVideoRecordingConfiguration, this.supportedVideoRecordingConfiguration);
@@ -202,57 +209,44 @@ var RecordingManagement = /** @class */ (function () {
202
209
  .onSet(this.handleSelectedCameraRecordingConfigurationWrite.bind(this))
203
210
  .setProps({ adminOnlyAccess: [1 /* Access.WRITE */] });
204
211
  this.recordingManagementService.getCharacteristic(Characteristic_1.Characteristic.Active)
205
- .onSet(function (value) {
206
- if (!!value === _this.recordingActive) {
212
+ .onSet(value => {
213
+ if (!!value === this.recordingActive) {
207
214
  return; // skip delegate call if state didn't change!
208
215
  }
209
- _this.recordingActive = !!value;
210
- _this.delegate.updateRecordingActive(_this.recordingActive);
216
+ this.recordingActive = !!value;
217
+ this.delegate.updateRecordingActive(this.recordingActive);
211
218
  })
212
- .on("change" /* CharacteristicEventTypes.CHANGE */, function () { var _a; return (_a = _this.stateChangeDelegate) === null || _a === void 0 ? void 0 : _a.call(_this); })
219
+ .on("change" /* CharacteristicEventTypes.CHANGE */, () => this.stateChangeDelegate?.())
213
220
  .setProps({ adminOnlyAccess: [1 /* Access.WRITE */] });
214
221
  this.recordingManagementService.getCharacteristic(Characteristic_1.Characteristic.RecordingAudioActive)
215
- .on("change" /* CharacteristicEventTypes.CHANGE */, function () { var _a; return (_a = _this.stateChangeDelegate) === null || _a === void 0 ? void 0 : _a.call(_this); });
222
+ .on("change" /* CharacteristicEventTypes.CHANGE */, () => this.stateChangeDelegate?.());
216
223
  this.operatingModeService.getCharacteristic(Characteristic_1.Characteristic.HomeKitCameraActive)
217
- .on("change" /* CharacteristicEventTypes.CHANGE */, function (change) {
218
- var e_2, _a;
219
- var _b;
220
- try {
221
- for (var _c = tslib_1.__values(_this.sensorServices), _d = _c.next(); !_d.done; _d = _c.next()) {
222
- var service = _d.value;
223
- service.setCharacteristic(Characteristic_1.Characteristic.StatusActive, !!change.newValue);
224
- }
224
+ .on("change" /* CharacteristicEventTypes.CHANGE */, change => {
225
+ for (const service of this.sensorServices) {
226
+ service.setCharacteristic(Characteristic_1.Characteristic.StatusActive, !!change.newValue);
225
227
  }
226
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
227
- finally {
228
- try {
229
- if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
230
- }
231
- finally { if (e_2) throw e_2.error; }
228
+ if (!change.newValue && this.recordingStream) {
229
+ this.recordingStream.close(1 /* HDSProtocolSpecificErrorReason.NOT_ALLOWED */);
232
230
  }
233
- if (!change.newValue && _this.recordingStream) {
234
- _this.recordingStream.close(1 /* HDSProtocolSpecificErrorReason.NOT_ALLOWED */);
235
- }
236
- (_b = _this.stateChangeDelegate) === null || _b === void 0 ? void 0 : _b.call(_this);
231
+ this.stateChangeDelegate?.();
237
232
  })
238
233
  .setProps({ adminOnlyAccess: [1 /* Access.WRITE */] });
239
234
  this.operatingModeService.getCharacteristic(Characteristic_1.Characteristic.EventSnapshotsActive)
240
- .on("change" /* CharacteristicEventTypes.CHANGE */, function () { var _a; return (_a = _this.stateChangeDelegate) === null || _a === void 0 ? void 0 : _a.call(_this); })
235
+ .on("change" /* CharacteristicEventTypes.CHANGE */, () => this.stateChangeDelegate?.())
241
236
  .setProps({ adminOnlyAccess: [1 /* Access.WRITE */] });
242
237
  this.operatingModeService.getCharacteristic(Characteristic_1.Characteristic.PeriodicSnapshotsActive)
243
- .on("change" /* CharacteristicEventTypes.CHANGE */, function () { var _a; return (_a = _this.stateChangeDelegate) === null || _a === void 0 ? void 0 : _a.call(_this); })
238
+ .on("change" /* CharacteristicEventTypes.CHANGE */, () => this.stateChangeDelegate?.())
244
239
  .setProps({ adminOnlyAccess: [1 /* Access.WRITE */] });
245
240
  this.dataStreamManagement
246
241
  .onRequestMessage("dataSend" /* Protocols.DATA_SEND */, "open" /* Topics.OPEN */, this.handleDataSendOpen.bind(this));
247
- };
242
+ }
248
243
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
249
- RecordingManagement.prototype.handleDataSendOpen = function (connection, id, message) {
250
- var _this = this;
244
+ handleDataSendOpen(connection, id, message) {
251
245
  // for message fields see https://github.com/Supereg/secure-video-specification#41-start
252
- var streamId = message.streamId;
253
- var type = message.type;
254
- var target = message.target;
255
- var reason = message.reason;
246
+ const streamId = message.streamId;
247
+ const type = message.type;
248
+ const target = message.target;
249
+ const reason = message.reason;
256
250
  if (target !== "controller" || type !== "ipcamera.recording") {
257
251
  debug("[HDS %s] Received data send with unexpected target: %s or type: %d. Rejecting...", connection.remoteAddress, target, type);
258
252
  connection.sendResponse("dataSend" /* Protocols.DATA_SEND */, "open" /* Topics.OPEN */, id, datastream_1.HDSStatus.PROTOCOL_SPECIFIC_ERROR, {
@@ -289,23 +283,22 @@ var RecordingManagement = /** @class */ (function () {
289
283
  debug("[HDS %s] HDS DATA_SEND Open with reason '%s'.", connection.remoteAddress, reason);
290
284
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
291
285
  this.recordingStream = new CameraRecordingStream(connection, this.delegate, id, streamId);
292
- this.recordingStream.on("closed" /* CameraRecordingStreamEvents.CLOSED */, function () {
286
+ this.recordingStream.on("closed" /* CameraRecordingStreamEvents.CLOSED */, () => {
293
287
  debug("[HDS %s] Removing active recoding session from recording management!", connection.remoteAddress);
294
- _this.recordingStream = undefined;
288
+ this.recordingStream = undefined;
295
289
  });
296
290
  this.recordingStream.startStreaming();
297
- };
298
- RecordingManagement.prototype.handleSelectedCameraRecordingConfigurationRead = function () {
291
+ }
292
+ handleSelectedCameraRecordingConfigurationRead() {
299
293
  if (!this.selectedConfiguration) {
300
294
  throw new hapStatusError_1.HapStatusError(-70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
301
295
  }
302
296
  return this.selectedConfiguration.base64;
303
- };
297
+ }
304
298
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
305
- RecordingManagement.prototype.handleSelectedCameraRecordingConfigurationWrite = function (value) {
306
- var _a, _b;
307
- var configuration = this.parseSelectedConfiguration(value);
308
- var changed = ((_a = this.selectedConfiguration) === null || _a === void 0 ? void 0 : _a.base64) !== value;
299
+ handleSelectedCameraRecordingConfigurationWrite(value) {
300
+ const configuration = this.parseSelectedConfiguration(value);
301
+ const changed = this.selectedConfiguration?.base64 !== value;
309
302
  this.selectedConfiguration = {
310
303
  parsed: configuration,
311
304
  base64: value,
@@ -313,38 +306,38 @@ var RecordingManagement = /** @class */ (function () {
313
306
  if (changed) {
314
307
  this.delegate.updateRecordingConfiguration(this.selectedConfiguration.parsed);
315
308
  // notify controller storage about updated values!
316
- (_b = this.stateChangeDelegate) === null || _b === void 0 ? void 0 : _b.call(this);
309
+ this.stateChangeDelegate?.();
317
310
  }
318
- };
319
- RecordingManagement.prototype.parseSelectedConfiguration = function (value) {
320
- var decoded = tlv.decode(Buffer.from(value, "base64"));
321
- var recording = tlv.decode(decoded[1 /* SelectedCameraRecordingConfigurationTypes.SELECTED_RECORDING_CONFIGURATION */]);
322
- var video = tlv.decode(decoded[2 /* SelectedCameraRecordingConfigurationTypes.SELECTED_VIDEO_CONFIGURATION */]);
323
- var audio = tlv.decode(decoded[3 /* SelectedCameraRecordingConfigurationTypes.SELECTED_AUDIO_CONFIGURATION */]);
324
- var prebufferLength = recording[1 /* SupportedCameraRecordingConfigurationTypes.PREBUFFER_LENGTH */].readInt32LE(0);
325
- var eventTriggerOptions = recording[2 /* SupportedCameraRecordingConfigurationTypes.EVENT_TRIGGER_OPTIONS */].readInt32LE(0);
326
- var mediaContainerConfiguration = tlv.decode(recording[3 /* SupportedCameraRecordingConfigurationTypes.MEDIA_CONTAINER_CONFIGURATIONS */]);
327
- var containerType = mediaContainerConfiguration[1 /* MediaContainerConfigurationTypes.MEDIA_CONTAINER_TYPE */][0];
328
- var mediaContainerParameters = tlv.decode(mediaContainerConfiguration[2 /* MediaContainerConfigurationTypes.MEDIA_CONTAINER_PARAMETERS */]);
329
- var fragmentLength = mediaContainerParameters[1 /* MediaContainerParameterTypes.FRAGMENT_LENGTH */].readInt32LE(0);
330
- var videoCodec = video[1 /* VideoCodecConfigurationTypes.CODEC_TYPE */][0];
331
- var videoParameters = tlv.decode(video[2 /* VideoCodecConfigurationTypes.CODEC_PARAMETERS */]);
332
- var videoAttributes = tlv.decode(video[3 /* VideoCodecConfigurationTypes.ATTRIBUTES */]);
333
- var profile = videoParameters[1 /* VideoCodecParametersTypes.PROFILE_ID */][0];
334
- var level = videoParameters[2 /* VideoCodecParametersTypes.LEVEL */][0];
335
- var videoBitrate = videoParameters[3 /* VideoCodecParametersTypes.BITRATE */].readInt32LE(0);
336
- var iFrameInterval = videoParameters[4 /* VideoCodecParametersTypes.IFRAME_INTERVAL */].readInt32LE(0);
337
- var width = videoAttributes[1 /* VideoAttributesTypes.IMAGE_WIDTH */].readInt16LE(0);
338
- var height = videoAttributes[2 /* VideoAttributesTypes.IMAGE_HEIGHT */].readInt16LE(0);
339
- var framerate = videoAttributes[3 /* VideoAttributesTypes.FRAME_RATE */][0];
340
- var audioCodec = audio[1 /* AudioCodecConfigurationTypes.CODEC_TYPE */][0];
341
- var audioParameters = tlv.decode(audio[2 /* AudioCodecConfigurationTypes.CODEC_PARAMETERS */]);
342
- var audioChannels = audioParameters[1 /* AudioCodecParametersTypes.CHANNEL */][0];
343
- var samplerate = audioParameters[3 /* AudioCodecParametersTypes.SAMPLE_RATE */][0];
344
- var audioBitrateMode = audioParameters[2 /* AudioCodecParametersTypes.BIT_RATE */][0];
345
- var audioBitrate = audioParameters[4 /* AudioCodecParametersTypes.MAX_AUDIO_BITRATE */].readUInt32LE(0);
346
- var typedEventTriggers = [];
347
- var bit_index = 0;
311
+ }
312
+ parseSelectedConfiguration(value) {
313
+ const decoded = tlv.decode(Buffer.from(value, "base64"));
314
+ const recording = tlv.decode(decoded[1 /* SelectedCameraRecordingConfigurationTypes.SELECTED_RECORDING_CONFIGURATION */]);
315
+ const video = tlv.decode(decoded[2 /* SelectedCameraRecordingConfigurationTypes.SELECTED_VIDEO_CONFIGURATION */]);
316
+ const audio = tlv.decode(decoded[3 /* SelectedCameraRecordingConfigurationTypes.SELECTED_AUDIO_CONFIGURATION */]);
317
+ const prebufferLength = recording[1 /* SupportedCameraRecordingConfigurationTypes.PREBUFFER_LENGTH */].readInt32LE(0);
318
+ let eventTriggerOptions = recording[2 /* SupportedCameraRecordingConfigurationTypes.EVENT_TRIGGER_OPTIONS */].readInt32LE(0);
319
+ const mediaContainerConfiguration = tlv.decode(recording[3 /* SupportedCameraRecordingConfigurationTypes.MEDIA_CONTAINER_CONFIGURATIONS */]);
320
+ const containerType = mediaContainerConfiguration[1 /* MediaContainerConfigurationTypes.MEDIA_CONTAINER_TYPE */][0];
321
+ const mediaContainerParameters = tlv.decode(mediaContainerConfiguration[2 /* MediaContainerConfigurationTypes.MEDIA_CONTAINER_PARAMETERS */]);
322
+ const fragmentLength = mediaContainerParameters[1 /* MediaContainerParameterTypes.FRAGMENT_LENGTH */].readInt32LE(0);
323
+ const videoCodec = video[1 /* VideoCodecConfigurationTypes.CODEC_TYPE */][0];
324
+ const videoParameters = tlv.decode(video[2 /* VideoCodecConfigurationTypes.CODEC_PARAMETERS */]);
325
+ const videoAttributes = tlv.decode(video[3 /* VideoCodecConfigurationTypes.ATTRIBUTES */]);
326
+ const profile = videoParameters[1 /* VideoCodecParametersTypes.PROFILE_ID */][0];
327
+ const level = videoParameters[2 /* VideoCodecParametersTypes.LEVEL */][0];
328
+ const videoBitrate = videoParameters[3 /* VideoCodecParametersTypes.BITRATE */].readInt32LE(0);
329
+ const iFrameInterval = videoParameters[4 /* VideoCodecParametersTypes.IFRAME_INTERVAL */].readInt32LE(0);
330
+ const width = videoAttributes[1 /* VideoAttributesTypes.IMAGE_WIDTH */].readInt16LE(0);
331
+ const height = videoAttributes[2 /* VideoAttributesTypes.IMAGE_HEIGHT */].readInt16LE(0);
332
+ const framerate = videoAttributes[3 /* VideoAttributesTypes.FRAME_RATE */][0];
333
+ const audioCodec = audio[1 /* AudioCodecConfigurationTypes.CODEC_TYPE */][0];
334
+ const audioParameters = tlv.decode(audio[2 /* AudioCodecConfigurationTypes.CODEC_PARAMETERS */]);
335
+ const audioChannels = audioParameters[1 /* AudioCodecParametersTypes.CHANNEL */][0];
336
+ const samplerate = audioParameters[3 /* AudioCodecParametersTypes.SAMPLE_RATE */][0];
337
+ const audioBitrateMode = audioParameters[2 /* AudioCodecParametersTypes.BIT_RATE */][0];
338
+ const audioBitrate = audioParameters[4 /* AudioCodecParametersTypes.MAX_AUDIO_BITRATE */].readUInt32LE(0);
339
+ const typedEventTriggers = [];
340
+ let bit_index = 0;
348
341
  while (eventTriggerOptions > 0) {
349
342
  if (eventTriggerOptions & 0x01) { // of the lowest bit is set add the next event trigger option
350
343
  typedEventTriggers.push(1 << bit_index);
@@ -357,7 +350,7 @@ var RecordingManagement = /** @class */ (function () {
357
350
  eventTriggerTypes: typedEventTriggers,
358
351
  mediaContainerConfiguration: {
359
352
  type: containerType,
360
- fragmentLength: fragmentLength,
353
+ fragmentLength,
361
354
  },
362
355
  videoCodec: {
363
356
  type: videoCodec,
@@ -370,104 +363,100 @@ var RecordingManagement = /** @class */ (function () {
370
363
  resolution: [width, height, framerate],
371
364
  },
372
365
  audioCodec: {
373
- audioChannels: audioChannels,
366
+ audioChannels,
374
367
  type: audioCodec,
375
- samplerate: samplerate,
368
+ samplerate,
376
369
  bitrateMode: audioBitrateMode,
377
370
  bitrate: audioBitrate,
378
371
  },
379
372
  };
380
- };
381
- RecordingManagement.prototype._supportedCameraRecordingConfiguration = function (options) {
382
- var mediaContainers = Array.isArray(options.mediaContainerConfiguration)
373
+ }
374
+ _supportedCameraRecordingConfiguration(options) {
375
+ const mediaContainers = Array.isArray(options.mediaContainerConfiguration)
383
376
  ? options.mediaContainerConfiguration
384
377
  : [options.mediaContainerConfiguration];
385
- var prebufferLength = Buffer.alloc(4);
386
- var eventTriggerOptions = Buffer.alloc(8);
378
+ const prebufferLength = Buffer.alloc(4);
379
+ const eventTriggerOptions = Buffer.alloc(8);
387
380
  prebufferLength.writeInt32LE(options.prebufferLength, 0);
388
381
  eventTriggerOptions.writeInt32LE(this.eventTriggerOptions, 0);
389
- return tlv.encode(1 /* SupportedCameraRecordingConfigurationTypes.PREBUFFER_LENGTH */, prebufferLength, 2 /* SupportedCameraRecordingConfigurationTypes.EVENT_TRIGGER_OPTIONS */, eventTriggerOptions, 3 /* SupportedCameraRecordingConfigurationTypes.MEDIA_CONTAINER_CONFIGURATIONS */, mediaContainers.map(function (config) {
390
- var fragmentLength = Buffer.alloc(4);
382
+ return tlv.encode(1 /* SupportedCameraRecordingConfigurationTypes.PREBUFFER_LENGTH */, prebufferLength, 2 /* SupportedCameraRecordingConfigurationTypes.EVENT_TRIGGER_OPTIONS */, eventTriggerOptions, 3 /* SupportedCameraRecordingConfigurationTypes.MEDIA_CONTAINER_CONFIGURATIONS */, mediaContainers.map(config => {
383
+ const fragmentLength = Buffer.alloc(4);
391
384
  fragmentLength.writeInt32LE(config.fragmentLength, 0);
392
385
  return tlv.encode(1 /* MediaContainerConfigurationTypes.MEDIA_CONTAINER_TYPE */, config.type, 2 /* MediaContainerConfigurationTypes.MEDIA_CONTAINER_PARAMETERS */, tlv.encode(1 /* MediaContainerParameterTypes.FRAGMENT_LENGTH */, fragmentLength));
393
386
  })).toString("base64");
394
- };
395
- RecordingManagement.prototype._supportedVideoRecordingConfiguration = function (videoOptions) {
387
+ }
388
+ _supportedVideoRecordingConfiguration(videoOptions) {
396
389
  if (!videoOptions.parameters) {
397
390
  throw new Error("Video parameters cannot be undefined");
398
391
  }
399
392
  if (!videoOptions.resolutions) {
400
393
  throw new Error("Video resolutions cannot be undefined");
401
394
  }
402
- var codecParameters = tlv.encode(1 /* VideoCodecParametersTypes.PROFILE_ID */, videoOptions.parameters.profiles, 2 /* VideoCodecParametersTypes.LEVEL */, videoOptions.parameters.levels);
403
- var videoStreamConfiguration = tlv.encode(1 /* VideoCodecConfigurationTypes.CODEC_TYPE */, videoOptions.type, 2 /* VideoCodecConfigurationTypes.CODEC_PARAMETERS */, codecParameters, 3 /* VideoCodecConfigurationTypes.ATTRIBUTES */, videoOptions.resolutions.map(function (resolution) {
395
+ const codecParameters = tlv.encode(1 /* VideoCodecParametersTypes.PROFILE_ID */, videoOptions.parameters.profiles, 2 /* VideoCodecParametersTypes.LEVEL */, videoOptions.parameters.levels);
396
+ const videoStreamConfiguration = tlv.encode(1 /* VideoCodecConfigurationTypes.CODEC_TYPE */, videoOptions.type, 2 /* VideoCodecConfigurationTypes.CODEC_PARAMETERS */, codecParameters, 3 /* VideoCodecConfigurationTypes.ATTRIBUTES */, videoOptions.resolutions.map(resolution => {
404
397
  if (resolution.length !== 3) {
405
398
  throw new Error("Unexpected video resolution");
406
399
  }
407
- var width = Buffer.alloc(2);
408
- var height = Buffer.alloc(2);
409
- var frameRate = Buffer.alloc(1);
400
+ const width = Buffer.alloc(2);
401
+ const height = Buffer.alloc(2);
402
+ const frameRate = Buffer.alloc(1);
410
403
  width.writeUInt16LE(resolution[0], 0);
411
404
  height.writeUInt16LE(resolution[1], 0);
412
405
  frameRate.writeUInt8(resolution[2], 0);
413
406
  return tlv.encode(1 /* VideoAttributesTypes.IMAGE_WIDTH */, width, 2 /* VideoAttributesTypes.IMAGE_HEIGHT */, height, 3 /* VideoAttributesTypes.FRAME_RATE */, frameRate);
414
407
  }));
415
408
  return tlv.encode(1 /* SupportedVideoRecordingConfigurationTypes.VIDEO_CODEC_CONFIGURATION */, videoStreamConfiguration).toString("base64");
416
- };
417
- RecordingManagement.prototype._supportedAudioStreamConfiguration = function (audioOptions) {
418
- var audioCodecs = Array.isArray(audioOptions.codecs)
409
+ }
410
+ _supportedAudioStreamConfiguration(audioOptions) {
411
+ const audioCodecs = Array.isArray(audioOptions.codecs)
419
412
  ? audioOptions.codecs
420
413
  : [audioOptions.codecs];
421
414
  if (audioCodecs.length === 0) {
422
415
  throw Error("CameraRecordingOptions.audio: At least one audio codec configuration must be specified!");
423
416
  }
424
- var codecConfigurations = audioCodecs.map(function (codec) {
425
- var providedSamplerates = Array.isArray(codec.samplerate)
417
+ const codecConfigurations = audioCodecs.map(codec => {
418
+ const providedSamplerates = Array.isArray(codec.samplerate)
426
419
  ? codec.samplerate
427
420
  : [codec.samplerate];
428
421
  if (providedSamplerates.length === 0) {
429
422
  throw new Error("CameraRecordingOptions.audio.codecs: Audio samplerate cannot be empty!");
430
423
  }
431
- var audioParameters = tlv.encode(1 /* AudioCodecParametersTypes.CHANNEL */, Math.max(1, codec.audioChannels || 1), 2 /* AudioCodecParametersTypes.BIT_RATE */, codec.bitrateMode || 0 /* AudioBitrate.VARIABLE */, 3 /* AudioCodecParametersTypes.SAMPLE_RATE */, providedSamplerates);
424
+ const audioParameters = tlv.encode(1 /* AudioCodecParametersTypes.CHANNEL */, Math.max(1, codec.audioChannels || 1), 2 /* AudioCodecParametersTypes.BIT_RATE */, codec.bitrateMode || 0 /* AudioBitrate.VARIABLE */, 3 /* AudioCodecParametersTypes.SAMPLE_RATE */, providedSamplerates);
432
425
  return tlv.encode(1 /* AudioCodecConfigurationTypes.CODEC_TYPE */, codec.type, 2 /* AudioCodecConfigurationTypes.CODEC_PARAMETERS */, audioParameters);
433
426
  });
434
427
  return tlv.encode(1 /* SupportedAudioRecordingConfigurationTypes.AUDIO_CODEC_CONFIGURATION */, codecConfigurations).toString("base64");
435
- };
436
- RecordingManagement.prototype.computeConfigurationHash = function (algorithm) {
437
- if (algorithm === void 0) { algorithm = "sha256"; }
438
- var configurationHash = crypto_1.default.createHash(algorithm);
428
+ }
429
+ computeConfigurationHash(algorithm = "sha256") {
430
+ const configurationHash = crypto_1.default.createHash(algorithm);
439
431
  configurationHash.update(this.supportedCameraRecordingConfiguration);
440
432
  configurationHash.update(this.supportedVideoRecordingConfiguration);
441
433
  configurationHash.update(this.supportedAudioRecordingConfiguration);
442
434
  return configurationHash.digest().toString("hex");
443
- };
435
+ }
444
436
  /**
445
437
  * @private
446
438
  */
447
- RecordingManagement.prototype.serialize = function () {
448
- var _a;
439
+ serialize() {
449
440
  return {
450
441
  configurationHash: {
451
442
  algorithm: "sha256",
452
443
  hash: this.computeConfigurationHash("sha256"),
453
444
  },
454
- selectedConfiguration: (_a = this.selectedConfiguration) === null || _a === void 0 ? void 0 : _a.base64,
445
+ selectedConfiguration: this.selectedConfiguration?.base64,
455
446
  recordingActive: this.recordingActive,
456
447
  recordingAudioActive: !!this.recordingManagementService.getCharacteristic(Characteristic_1.Characteristic.RecordingAudioActive).value,
457
448
  eventSnapshotsActive: !!this.operatingModeService.getCharacteristic(Characteristic_1.Characteristic.EventSnapshotsActive).value,
458
449
  homeKitCameraActive: !!this.operatingModeService.getCharacteristic(Characteristic_1.Characteristic.HomeKitCameraActive).value,
459
450
  periodicSnapshotsActive: !!this.operatingModeService.getCharacteristic(Characteristic_1.Characteristic.PeriodicSnapshotsActive).value,
460
451
  };
461
- };
452
+ }
462
453
  /**
463
454
  * @private
464
455
  */
465
- RecordingManagement.prototype.deserialize = function (serialized) {
466
- var e_3, _a;
467
- var _b;
468
- var changedState = false;
456
+ deserialize(serialized) {
457
+ let changedState = false;
469
458
  // we only restore the `selectedConfiguration` if our supported configuration hasn't changed.
470
- var currentConfigurationHash = this.computeConfigurationHash(serialized.configurationHash.algorithm);
459
+ const currentConfigurationHash = this.computeConfigurationHash(serialized.configurationHash.algorithm);
471
460
  if (serialized.selectedConfiguration) {
472
461
  if (currentConfigurationHash === serialized.configurationHash.hash) {
473
462
  this.selectedConfiguration = {
@@ -485,18 +474,8 @@ var RecordingManagement = /** @class */ (function () {
485
474
  this.operatingModeService.updateCharacteristic(Characteristic_1.Characteristic.EventSnapshotsActive, serialized.eventSnapshotsActive);
486
475
  this.operatingModeService.updateCharacteristic(Characteristic_1.Characteristic.PeriodicSnapshotsActive, serialized.periodicSnapshotsActive);
487
476
  this.operatingModeService.updateCharacteristic(Characteristic_1.Characteristic.HomeKitCameraActive, serialized.homeKitCameraActive);
488
- try {
489
- for (var _c = tslib_1.__values(this.sensorServices), _d = _c.next(); !_d.done; _d = _c.next()) {
490
- var service = _d.value;
491
- service.setCharacteristic(Characteristic_1.Characteristic.StatusActive, serialized.homeKitCameraActive);
492
- }
493
- }
494
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
495
- finally {
496
- try {
497
- if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
498
- }
499
- finally { if (e_3) throw e_3.error; }
477
+ for (const service of this.sensorServices) {
478
+ service.setCharacteristic(Characteristic_1.Characteristic.StatusActive, serialized.homeKitCameraActive);
500
479
  }
501
480
  try {
502
481
  if (this.selectedConfiguration) {
@@ -510,38 +489,27 @@ var RecordingManagement = /** @class */ (function () {
510
489
  console.error("Failed to properly initialize CameraRecordingDelegate from persistent storage: " + error.stack);
511
490
  }
512
491
  if (changedState) {
513
- (_b = this.stateChangeDelegate) === null || _b === void 0 ? void 0 : _b.call(this);
492
+ this.stateChangeDelegate?.();
514
493
  }
515
- };
494
+ }
516
495
  /**
517
496
  * @private
518
497
  */
519
- RecordingManagement.prototype.setupStateChangeDelegate = function (delegate) {
498
+ setupStateChangeDelegate(delegate) {
520
499
  this.stateChangeDelegate = delegate;
521
- };
522
- RecordingManagement.prototype.destroy = function () {
500
+ }
501
+ destroy() {
523
502
  this.dataStreamManagement.destroy();
524
- };
525
- RecordingManagement.prototype.handleFactoryReset = function () {
526
- var e_4, _a;
503
+ }
504
+ handleFactoryReset() {
527
505
  this.selectedConfiguration = undefined;
528
506
  this.recordingManagementService.updateCharacteristic(Characteristic_1.Characteristic.Active, false);
529
507
  this.recordingManagementService.updateCharacteristic(Characteristic_1.Characteristic.RecordingAudioActive, false);
530
508
  this.operatingModeService.updateCharacteristic(Characteristic_1.Characteristic.EventSnapshotsActive, true);
531
509
  this.operatingModeService.updateCharacteristic(Characteristic_1.Characteristic.PeriodicSnapshotsActive, true);
532
510
  this.operatingModeService.updateCharacteristic(Characteristic_1.Characteristic.HomeKitCameraActive, true);
533
- try {
534
- for (var _b = tslib_1.__values(this.sensorServices), _c = _b.next(); !_c.done; _c = _b.next()) {
535
- var service = _c.value;
536
- service.setCharacteristic(Characteristic_1.Characteristic.StatusActive, true);
537
- }
538
- }
539
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
540
- finally {
541
- try {
542
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
543
- }
544
- finally { if (e_4) throw e_4.error; }
511
+ for (const service of this.sensorServices) {
512
+ service.setCharacteristic(Characteristic_1.Characteristic.StatusActive, true);
545
513
  }
546
514
  try {
547
515
  // notifying the delegate about the updated state
@@ -551,9 +519,8 @@ var RecordingManagement = /** @class */ (function () {
551
519
  catch (error) {
552
520
  console.error("CameraRecordingDelegate failed to update state after handleFactoryReset: " + error.stack);
553
521
  }
554
- };
555
- return RecordingManagement;
556
- }());
522
+ }
523
+ }
557
524
  exports.RecordingManagement = RecordingManagement;
558
525
  /**
559
526
  * @group Camera
@@ -574,199 +541,172 @@ var CameraRecordingStreamEvents;
574
541
  * @group Camera
575
542
  */
576
543
  // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
577
- var CameraRecordingStream = /** @class */ (function (_super) {
578
- tslib_1.__extends(CameraRecordingStream, _super);
579
- function CameraRecordingStream(connection, delegate, requestId, streamId) {
580
- var _a;
581
- var _this = _super.call(this) || this;
582
- _this.closed = false;
583
- _this.eventHandler = (_a = {},
584
- _a["close" /* Topics.CLOSE */] = _this.handleDataSendClose.bind(_this),
585
- _a["ack" /* Topics.ACK */] = _this.handleDataSendAck.bind(_this),
586
- _a);
587
- _this.requestHandler = undefined;
588
- _this.connection = connection;
589
- _this.delegate = delegate;
590
- _this.hdsRequestId = requestId;
591
- _this.streamId = streamId;
592
- _this.connection.on("closed" /* DataStreamConnectionEvent.CLOSED */, _this.closeListener = _this.handleDataStreamConnectionClosed.bind(_this));
593
- _this.connection.addProtocolHandler("dataSend" /* Protocols.DATA_SEND */, _this);
594
- return _this;
544
+ class CameraRecordingStream extends events_1.EventEmitter {
545
+ connection;
546
+ delegate;
547
+ hdsRequestId;
548
+ streamId;
549
+ closed = false;
550
+ eventHandler = {
551
+ ["close" /* Topics.CLOSE */]: this.handleDataSendClose.bind(this),
552
+ ["ack" /* Topics.ACK */]: this.handleDataSendAck.bind(this),
553
+ };
554
+ requestHandler = undefined;
555
+ closeListener;
556
+ generator;
557
+ /**
558
+ * This timeout is used to detect non-returning generators.
559
+ * When we signal the delegate that it is being closed its generator must return withing 10s.
560
+ */
561
+ generatorTimeout;
562
+ /**
563
+ * This timer is used to check if the stream is properly closed when we expect it to do so.
564
+ * When we expect a close signal from the remote, we wait 12s for it. Otherwise, we abort and close it ourselves.
565
+ * This ensures memory is freed, and that we recover fast from erroneous states.
566
+ */
567
+ closingTimeout;
568
+ constructor(connection, delegate, requestId, streamId) {
569
+ super();
570
+ this.connection = connection;
571
+ this.delegate = delegate;
572
+ this.hdsRequestId = requestId;
573
+ this.streamId = streamId;
574
+ this.connection.on("closed" /* DataStreamConnectionEvent.CLOSED */, this.closeListener = this.handleDataStreamConnectionClosed.bind(this));
575
+ this.connection.addProtocolHandler("dataSend" /* Protocols.DATA_SEND */, this);
595
576
  }
596
- CameraRecordingStream.prototype.startStreaming = function () {
577
+ startStreaming() {
597
578
  // noinspection JSIgnoredPromiseFromCall
598
579
  this._startStreaming();
599
- };
600
- CameraRecordingStream.prototype._startStreaming = function () {
601
- return tslib_1.__awaiter(this, void 0, void 0, function () {
602
- var maxChunk, initialization, dataSequenceNumber, lastFragmentWasMarkedLast, _a, _b, _c, packet, fragment, offset, dataChunkSequenceNumber, data, event, e_5_1, error_1, closeReason;
603
- var _d, e_5, _e, _f;
604
- return tslib_1.__generator(this, function (_g) {
605
- switch (_g.label) {
606
- case 0:
607
- debug("[HDS %s] Sending DATA_SEND OPEN response for streamId %d", this.connection.remoteAddress, this.streamId);
608
- this.connection.sendResponse("dataSend" /* Protocols.DATA_SEND */, "open" /* Topics.OPEN */, this.hdsRequestId, datastream_1.HDSStatus.SUCCESS, {
609
- status: datastream_1.HDSStatus.SUCCESS,
610
- });
611
- maxChunk = 0x40000;
612
- initialization = true;
613
- dataSequenceNumber = 1;
614
- lastFragmentWasMarkedLast = false;
615
- _g.label = 1;
616
- case 1:
617
- _g.trys.push([1, 14, 15, 16]);
618
- this.generator = this.delegate.handleRecordingStreamRequest(this.streamId);
619
- _g.label = 2;
620
- case 2:
621
- _g.trys.push([2, 7, 8, 13]);
622
- _a = true, _b = tslib_1.__asyncValues(this.generator);
623
- _g.label = 3;
624
- case 3: return [4 /*yield*/, _b.next()];
625
- case 4:
626
- if (!(_c = _g.sent(), _d = _c.done, !_d)) return [3 /*break*/, 6];
627
- _f = _c.value;
628
- _a = false;
629
- packet = _f;
630
- if (this.closed) {
631
- console.error("[HDS ".concat(this.connection.remoteAddress, "] Delegate yielded fragment after stream ").concat(this.streamId, " was already closed!"));
632
- return [3 /*break*/, 6];
633
- }
634
- if (lastFragmentWasMarkedLast) {
635
- console.error("[HDS ".concat(this.connection.remoteAddress, "] Delegate yielded fragment for stream ").concat(this.streamId, " after already signaling end of stream!"));
636
- return [3 /*break*/, 6];
637
- }
638
- fragment = packet.data;
639
- offset = 0;
640
- dataChunkSequenceNumber = 1;
641
- while (offset < fragment.length) {
642
- data = fragment.slice(offset, offset + maxChunk);
643
- offset += data.length;
644
- event = {
645
- streamId: this.streamId,
646
- packets: [{
647
- data: data,
648
- metadata: {
649
- dataType: initialization ? "mediaInitialization" /* PacketDataType.MEDIA_INITIALIZATION */ : "mediaFragment" /* PacketDataType.MEDIA_FRAGMENT */,
650
- dataSequenceNumber: dataSequenceNumber,
651
- dataChunkSequenceNumber: dataChunkSequenceNumber,
652
- isLastDataChunk: offset >= fragment.length,
653
- dataTotalSize: dataChunkSequenceNumber === 1 ? fragment.length : undefined,
654
- },
655
- }],
656
- endOfStream: offset >= fragment.length ? Boolean(packet.isLast).valueOf() : undefined,
657
- };
658
- debug("[HDS %s] Sending DATA_SEND DATA for stream %d with metadata: %o and length %d; EoS: %s", this.connection.remoteAddress, this.streamId, event.packets[0].metadata, data.length, event.endOfStream);
659
- this.connection.sendEvent("dataSend" /* Protocols.DATA_SEND */, "data" /* Topics.DATA */, event);
660
- dataChunkSequenceNumber++;
661
- initialization = false;
662
- }
663
- lastFragmentWasMarkedLast = packet.isLast;
664
- if (packet.isLast) {
665
- return [3 /*break*/, 6];
666
- }
667
- dataSequenceNumber++;
668
- _g.label = 5;
669
- case 5:
670
- _a = true;
671
- return [3 /*break*/, 3];
672
- case 6: return [3 /*break*/, 13];
673
- case 7:
674
- e_5_1 = _g.sent();
675
- e_5 = { error: e_5_1 };
676
- return [3 /*break*/, 13];
677
- case 8:
678
- _g.trys.push([8, , 11, 12]);
679
- if (!(!_a && !_d && (_e = _b.return))) return [3 /*break*/, 10];
680
- return [4 /*yield*/, _e.call(_b)];
681
- case 9:
682
- _g.sent();
683
- _g.label = 10;
684
- case 10: return [3 /*break*/, 12];
685
- case 11:
686
- if (e_5) throw e_5.error;
687
- return [7 /*endfinally*/];
688
- case 12: return [7 /*endfinally*/];
689
- case 13:
690
- if (!lastFragmentWasMarkedLast && !this.closed) {
691
- // Delegate violates the contract. Exited normally on a non-closed stream without properly setting `isLast`.
692
- console.warn("[HDS ".concat(this.connection.remoteAddress, "] Delegate finished streaming for ").concat(this.streamId, " without setting RecordingPacket.isLast. ") +
693
- "Can't notify Controller about endOfStream!");
694
- }
695
- return [3 /*break*/, 16];
696
- case 14:
697
- error_1 = _g.sent();
698
- if (this.closed) {
699
- console.warn("[HDS ".concat(this.connection.remoteAddress, "] Encountered unexpected error on already closed recording stream ").concat(this.streamId, ": ").concat(error_1.stack));
700
- }
701
- else {
702
- closeReason = 5 /* HDSProtocolSpecificErrorReason.UNEXPECTED_FAILURE */;
703
- if (error_1 instanceof datastream_1.HDSProtocolError) {
704
- closeReason = error_1.reason;
705
- debug("[HDS %s] Delegate signaled to close the recording stream %d.", this.connection.remoteAddress, this.streamId);
706
- }
707
- else if (error_1 instanceof datastream_1.HDSConnectionError && error_1.type === 2 /* HDSConnectionErrorType.CLOSED_SOCKET */) {
708
- // we are probably on a shutdown or just late. Connection is dead. End the stream!
709
- debug("[HDS %s] Exited recording stream due to closed HDS socket: stream id %d.", this.connection.remoteAddress, this.streamId);
710
- return [2 /*return*/]; // execute finally and then exit (we want to skip the `sendEvent` below)
711
- }
712
- else {
713
- console.error("[HDS ".concat(this.connection.remoteAddress, "] Encountered unexpected error for recording stream ").concat(this.streamId, ": ").concat(error_1.stack));
714
- }
715
- // call close to go through standard close routine!
716
- this.close(closeReason);
717
- }
718
- return [2 /*return*/];
719
- case 15:
720
- this.generator = undefined;
721
- if (this.generatorTimeout) {
722
- clearTimeout(this.generatorTimeout);
723
- }
724
- if (!this.closed) {
725
- // e.g. when returning with `endOfStream` we rely on the HomeHub to send an ACK event to close the recording.
726
- // With this timer we ensure that the HomeHub has the chance to close the stream gracefully but at the same time
727
- // ensure that if something fails the recording stream is freed nonetheless.
728
- this.kickOffCloseTimeout();
729
- }
730
- return [7 /*endfinally*/];
731
- case 16:
732
- debug("[HDS %s] Finished DATA_SEND transmission for stream %d!", this.connection.remoteAddress, this.streamId);
733
- return [2 /*return*/];
734
- }
735
- });
580
+ }
581
+ async _startStreaming() {
582
+ debug("[HDS %s] Sending DATA_SEND OPEN response for streamId %d", this.connection.remoteAddress, this.streamId);
583
+ this.connection.sendResponse("dataSend" /* Protocols.DATA_SEND */, "open" /* Topics.OPEN */, this.hdsRequestId, datastream_1.HDSStatus.SUCCESS, {
584
+ status: datastream_1.HDSStatus.SUCCESS,
736
585
  });
737
- };
586
+ // 256 KiB (1KiB to 900 KiB)
587
+ const maxChunk = 0x40000;
588
+ // The first buffer which we receive from the generator is always the `mediaInitialization` packet (mp4 `moov` box).
589
+ let initialization = true;
590
+ let dataSequenceNumber = 1;
591
+ // tracks if the last received RecordingPacket was yielded with `isLast=true`.
592
+ let lastFragmentWasMarkedLast = false;
593
+ try {
594
+ this.generator = this.delegate.handleRecordingStreamRequest(this.streamId);
595
+ for await (const packet of this.generator) {
596
+ if (this.closed) {
597
+ console.error(`[HDS ${this.connection.remoteAddress}] Delegate yielded fragment after stream ${this.streamId} was already closed!`);
598
+ break;
599
+ }
600
+ if (lastFragmentWasMarkedLast) {
601
+ console.error(`[HDS ${this.connection.remoteAddress}] Delegate yielded fragment for stream ${this.streamId} after already signaling end of stream!`);
602
+ break;
603
+ }
604
+ const fragment = packet.data;
605
+ let offset = 0;
606
+ let dataChunkSequenceNumber = 1;
607
+ while (offset < fragment.length) {
608
+ if (this.closed) {
609
+ break;
610
+ }
611
+ const data = fragment.slice(offset, offset + maxChunk);
612
+ offset += data.length;
613
+ // see https://github.com/Supereg/secure-video-specification#42-binary-data
614
+ const event = {
615
+ streamId: this.streamId,
616
+ packets: [{
617
+ data: data,
618
+ metadata: {
619
+ dataType: initialization ? "mediaInitialization" /* PacketDataType.MEDIA_INITIALIZATION */ : "mediaFragment" /* PacketDataType.MEDIA_FRAGMENT */,
620
+ dataSequenceNumber: dataSequenceNumber,
621
+ dataChunkSequenceNumber: dataChunkSequenceNumber,
622
+ isLastDataChunk: offset >= fragment.length,
623
+ dataTotalSize: dataChunkSequenceNumber === 1 ? fragment.length : undefined,
624
+ },
625
+ }],
626
+ endOfStream: offset >= fragment.length ? Boolean(packet.isLast).valueOf() : undefined,
627
+ };
628
+ debug("[HDS %s] Sending DATA_SEND DATA for stream %d with metadata: %o and length %d; EoS: %s", this.connection.remoteAddress, this.streamId, event.packets[0].metadata, data.length, event.endOfStream);
629
+ this.connection.sendEvent("dataSend" /* Protocols.DATA_SEND */, "data" /* Topics.DATA */, event);
630
+ dataChunkSequenceNumber++;
631
+ initialization = false;
632
+ }
633
+ lastFragmentWasMarkedLast = packet.isLast;
634
+ if (packet.isLast) {
635
+ break;
636
+ }
637
+ dataSequenceNumber++;
638
+ }
639
+ if (!lastFragmentWasMarkedLast && !this.closed) {
640
+ // Delegate violates the contract. Exited normally on a non-closed stream without properly setting `isLast`.
641
+ console.warn(`[HDS ${this.connection.remoteAddress}] Delegate finished streaming for ${this.streamId} without setting RecordingPacket.isLast. ` +
642
+ "Can't notify Controller about endOfStream!");
643
+ }
644
+ }
645
+ catch (error) {
646
+ if (this.closed) {
647
+ console.warn(`[HDS ${this.connection.remoteAddress}] Encountered unexpected error on already closed recording stream ${this.streamId}: ${error.stack}`);
648
+ }
649
+ else {
650
+ let closeReason = 5 /* HDSProtocolSpecificErrorReason.UNEXPECTED_FAILURE */;
651
+ if (error instanceof datastream_1.HDSProtocolError) {
652
+ closeReason = error.reason;
653
+ debug("[HDS %s] Delegate signaled to close the recording stream %d.", this.connection.remoteAddress, this.streamId);
654
+ }
655
+ else if (error instanceof datastream_1.HDSConnectionError && error.type === 2 /* HDSConnectionErrorType.CLOSED_SOCKET */) {
656
+ // we are probably on a shutdown or just late. Connection is dead. End the stream!
657
+ debug("[HDS %s] Exited recording stream due to closed HDS socket: stream id %d.", this.connection.remoteAddress, this.streamId);
658
+ return; // execute finally and then exit (we want to skip the `sendEvent` below)
659
+ }
660
+ else {
661
+ console.error(`[HDS ${this.connection.remoteAddress}] Encountered unexpected error for recording stream ${this.streamId}: ${error.stack}`);
662
+ }
663
+ // call close to go through standard close routine!
664
+ this.close(closeReason);
665
+ }
666
+ return;
667
+ }
668
+ finally {
669
+ this.generator = undefined;
670
+ if (this.generatorTimeout) {
671
+ clearTimeout(this.generatorTimeout);
672
+ }
673
+ if (!this.closed) {
674
+ // e.g. when returning with `endOfStream` we rely on the HomeHub to send an ACK event to close the recording.
675
+ // With this timer we ensure that the HomeHub has the chance to close the stream gracefully but at the same time
676
+ // ensure that if something fails the recording stream is freed nonetheless.
677
+ this.kickOffCloseTimeout();
678
+ }
679
+ }
680
+ debug("[HDS %s] Finished DATA_SEND transmission for stream %d!", this.connection.remoteAddress, this.streamId);
681
+ }
738
682
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
739
- CameraRecordingStream.prototype.handleDataSendAck = function (message) {
740
- var _this = this;
741
- var streamId = message.streamId;
742
- var endOfStream = message.endOfStream;
683
+ handleDataSendAck(message) {
684
+ const streamId = message.streamId;
685
+ const endOfStream = message.endOfStream;
743
686
  // The HomeKit Controller will send a DATA_SEND ACK if we set the `endOfStream` flag in the last packet
744
687
  // of our DATA_SEND DATA packet.
745
688
  // To my testing the session is then considered complete and the HomeKit controller will close the HDS Connection after 5 seconds.
746
689
  debug("[HDS %s] Received DATA_SEND ACK packet for streamId %s. Acknowledged %s.", this.connection.remoteAddress, streamId, endOfStream);
747
- this.handleClosed(function () { var _a, _b; return (_b = (_a = _this.delegate).acknowledgeStream) === null || _b === void 0 ? void 0 : _b.call(_a, _this.streamId); });
748
- };
690
+ this.handleClosed(() => this.delegate.acknowledgeStream?.(this.streamId));
691
+ }
749
692
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
750
- CameraRecordingStream.prototype.handleDataSendClose = function (message) {
751
- var _this = this;
693
+ handleDataSendClose(message) {
752
694
  // see https://github.com/Supereg/secure-video-specification#43-close
753
- var streamId = message.streamId;
754
- var reason = message.reason;
695
+ const streamId = message.streamId;
696
+ const reason = message.reason;
755
697
  if (streamId !== this.streamId) {
756
698
  return;
757
699
  }
758
700
  debug("[HDS %s] Received DATA_SEND CLOSE for streamId %d with reason %s",
759
701
  // @ts-expect-error: forceConsistentCasingInFileNames compiler option
760
702
  this.connection.remoteAddress, streamId, datastream_1.HDSProtocolSpecificErrorReason[reason]);
761
- this.handleClosed(function () { return _this.delegate.closeRecordingStream(streamId, reason); });
762
- };
763
- CameraRecordingStream.prototype.handleDataStreamConnectionClosed = function () {
764
- var _this = this;
703
+ this.handleClosed(() => this.delegate.closeRecordingStream(streamId, reason));
704
+ }
705
+ handleDataStreamConnectionClosed() {
765
706
  debug("[HDS %s] The HDS connection of the stream %d closed.", this.connection.remoteAddress, this.streamId);
766
- this.handleClosed(function () { return _this.delegate.closeRecordingStream(_this.streamId, undefined); });
767
- };
768
- CameraRecordingStream.prototype.handleClosed = function (closure) {
769
- var _this = this;
707
+ this.handleClosed(() => this.delegate.closeRecordingStream(this.streamId, undefined));
708
+ }
709
+ handleClosed(closure) {
770
710
  this.closed = true;
771
711
  if (this.closingTimeout) {
772
712
  clearTimeout(this.closingTimeout);
@@ -777,25 +717,24 @@ var CameraRecordingStream = /** @class */ (function (_super) {
777
717
  if (this.generator) {
778
718
  // when this variable is defined, the generator hasn't returned yet.
779
719
  // we start a timeout to uncover potential programming mistakes where we await forever and can't free resources.
780
- this.generatorTimeout = setTimeout(function () {
720
+ this.generatorTimeout = setTimeout(() => {
781
721
  console.error("[HDS %s] Recording download stream %d is still awaiting generator although stream was closed 10s ago! " +
782
- "This is a programming mistake by the camera implementation which prevents freeing up resources.", _this.connection.remoteAddress, _this.streamId);
722
+ "This is a programming mistake by the camera implementation which prevents freeing up resources.", this.connection.remoteAddress, this.streamId);
783
723
  }, 10000);
784
724
  }
785
725
  try {
786
726
  closure();
787
727
  }
788
728
  catch (error) {
789
- console.error("[HDS ".concat(this.connection.remoteAddress, "] CameraRecordingDelegated failed to handle closing the stream ").concat(this.streamId, ": ").concat(error.stack));
729
+ console.error(`[HDS ${this.connection.remoteAddress}] CameraRecordingDelegated failed to handle closing the stream ${this.streamId}: ${error.stack}`);
790
730
  }
791
731
  this.emit("closed" /* CameraRecordingStreamEvents.CLOSED */);
792
- };
732
+ }
793
733
  /**
794
734
  * This method can be used to close a recording session from the outside.
795
735
  * @param reason - The reason to close the stream with.
796
736
  */
797
- CameraRecordingStream.prototype.close = function (reason) {
798
- var _this = this;
737
+ close(reason) {
799
738
  if (this.closed) {
800
739
  return;
801
740
  }
@@ -809,21 +748,19 @@ var CameraRecordingStream = /** @class */ (function (_super) {
809
748
  reason: reason,
810
749
  });
811
750
  }
812
- this.handleClosed(function () { return _this.delegate.closeRecordingStream(_this.streamId, reason); });
813
- };
814
- CameraRecordingStream.prototype.kickOffCloseTimeout = function () {
815
- var _this = this;
751
+ this.handleClosed(() => this.delegate.closeRecordingStream(this.streamId, reason));
752
+ }
753
+ kickOffCloseTimeout() {
816
754
  if (this.closingTimeout) {
817
755
  clearTimeout(this.closingTimeout);
818
756
  }
819
- this.closingTimeout = setTimeout(function () {
820
- if (_this.closed) {
757
+ this.closingTimeout = setTimeout(() => {
758
+ if (this.closed) {
821
759
  return;
822
760
  }
823
- debug("[HDS %s] Recording stream %d took longer than expected to fully close. Force closing now!", _this.connection.remoteAddress, _this.streamId);
824
- _this.close(3 /* HDSProtocolSpecificErrorReason.CANCELLED */);
761
+ debug("[HDS %s] Recording stream %d took longer than expected to fully close. Force closing now!", this.connection.remoteAddress, this.streamId);
762
+ this.close(3 /* HDSProtocolSpecificErrorReason.CANCELLED */);
825
763
  }, 12000);
826
- };
827
- return CameraRecordingStream;
828
- }(events_1.EventEmitter));
764
+ }
765
+ }
829
766
  //# sourceMappingURL=RecordingManagement.js.map