aes70 1.3.3 → 1.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/Changelog +46 -0
  2. package/dist/AES70.es5.js +1 -1
  3. package/package.json +9 -3
  4. package/src/OCP1/encode_message.js +3 -6
  5. package/src/OCP1/message_generator.js +21 -21
  6. package/src/OCP1.js +162 -0
  7. package/src/controller/ControlClasses/OcaFilterFIR.d.ts +5 -0
  8. package/src/controller/ControlClasses/OcaFilterFIR.js +9 -1
  9. package/src/controller/ControlClasses/OcaLibrary.d.ts +3 -1
  10. package/src/controller/ControlClasses/OcaLibrary.js +3 -1
  11. package/src/controller/ControlClasses/OcaPowerManager.d.ts +5 -0
  12. package/src/controller/ControlClasses/OcaPowerManager.js +9 -1
  13. package/src/controller/ControlClasses/OcaPowerSupply.d.ts +10 -0
  14. package/src/controller/ControlClasses/OcaPowerSupply.js +20 -2
  15. package/src/controller/ControlClasses/OcaSensor.d.ts +5 -0
  16. package/src/controller/ControlClasses/OcaSensor.js +9 -1
  17. package/src/controller/ControlClasses.d.ts +0 -1
  18. package/src/controller/arguments.d.ts +1 -2
  19. package/src/controller/client_connection.d.ts +1 -1
  20. package/src/controller/client_connection.js +56 -32
  21. package/src/controller/event.js +4 -1
  22. package/src/controller/make_control_class.js +24 -4
  23. package/src/controller/remote_device.d.ts +1 -1
  24. package/src/controller/remote_device.js +48 -24
  25. package/src/controller/udp_connection.js +22 -20
  26. package/src/controller/websocket_connection.js +3 -1
  27. package/src/controller/websocket_connection_node.js +3 -1
  28. package/tests/device/locking.js +2 -1
  29. package/tests/device/method_callback.js +24 -0
  30. package/tests/device/test.js +11 -4
  31. package/tests/device.js +15 -2
  32. package/bin/connectMany.js +0 -64
  33. package/src/OCP1/.keepalive.js.swo +0 -0
  34. package/src/OCP1/OcaClassID.js +0 -16
@@ -58,15 +58,35 @@ function implement_method(cls, method) {
58
58
 
59
59
  const [name, level, index, argumentTypes, returnTypes] = method;
60
60
 
61
- cls.prototype[name] = function () {
61
+ cls.prototype[name] = function (...args) {
62
+ const argumentCount = argumentTypes.length;
63
+ let callback = null;
64
+
65
+ // If there are too few arguments, this might mean
66
+ //
67
+ // - that some of them use the default encoding (e.g. 0)
68
+ // - that the method signature has change in the AES70 version
69
+ // used
70
+ //
71
+ // this is why we do not error here, yet.
72
+ if (argumentCount < args.length) {
73
+ if (
74
+ argumentCount + 1 === args.length &&
75
+ typeof args[argumentCount] === 'function'
76
+ ) {
77
+ callback = args[argumentCount];
78
+ args.length = argumentCount;
79
+ }
80
+ }
81
+
62
82
  const cmd = new CommandRrq(
63
83
  this.ono,
64
84
  level,
65
85
  index,
66
- argumentTypes.length,
67
- new EncodedArguments(argumentTypes, Array.from(arguments))
86
+ argumentCount,
87
+ new EncodedArguments(argumentTypes, args)
68
88
  );
69
- return this.device.send_command(cmd, returnTypes);
89
+ return this.device.send_command(cmd, returnTypes, callback);
70
90
  };
71
91
  }
72
92
 
@@ -47,7 +47,7 @@ export declare class RemoteDevice {
47
47
  * The Subscription manager object.
48
48
  */
49
49
  SubscriptionManager: OcaSubscriptionManager;
50
-
50
+
51
51
  /**
52
52
  * The Power manager object.
53
53
  */
@@ -105,6 +105,14 @@ function tree_to_rolemap(tree, s) {
105
105
  });
106
106
  }
107
107
 
108
+ const subscriberMethod = {
109
+ ONo: 1055,
110
+ MethodID: {
111
+ DefLevel: 1,
112
+ MethodIndex: 1,
113
+ },
114
+ };
115
+
108
116
  /**
109
117
  * Controller class for a remote OCA device.
110
118
  *
@@ -239,18 +247,31 @@ export class RemoteDevice extends Events {
239
247
  this.connection.close();
240
248
  }
241
249
 
242
- send_command(cmd, returnType) {
243
- return this.connection.send_command(cmd, returnType);
250
+ send_command(cmd, returnType, callback) {
251
+ return this.connection.send_command(cmd, returnType, callback);
244
252
  }
245
253
 
246
- add_subscription(event, callback) {
254
+ _doSubscribe(event) {
255
+ return this.SubscriptionManager.AddSubscription(
256
+ event,
257
+ subscriberMethod,
258
+ new Uint8Array(0),
259
+ OcaNotificationDeliveryMode.Reliable,
260
+ new Uint8Array(0)
261
+ );
262
+ }
263
+
264
+ async add_subscription(event, callback) {
247
265
  const key = eventToKey(event);
266
+ const subscriptions = this.subscriptions;
248
267
 
249
- const S = this.subscriptions.get(key);
268
+ {
269
+ const info = subscriptions.get(key);
250
270
 
251
- if (S) {
252
- S.callbacks.add(callback);
253
- return Promise.resolve(true);
271
+ if (info) {
272
+ info.callbacks.add(callback);
273
+ return true;
274
+ }
254
275
  }
255
276
 
256
277
  /* do the actual subscription */
@@ -258,7 +279,7 @@ export class RemoteDevice extends Events {
258
279
  const cb = (o) => {
259
280
  const S = this.subscriptions.get(key);
260
281
  if (!S) {
261
- warn('Subscription lost.\n');
282
+ warn('Subscription lost.');
262
283
  return;
263
284
  }
264
285
  const a = S.callbacks;
@@ -271,38 +292,41 @@ export class RemoteDevice extends Events {
271
292
  });
272
293
  };
273
294
 
274
- const method = this.connection.get_new_subscriber(cb);
295
+ this.connection._addSubscriber(event, cb);
275
296
 
276
- this.subscriptions.set(key, {
297
+ const info = {
277
298
  callbacks: new Set([callback]),
278
- method: method,
279
299
  callback: cb,
280
- });
300
+ };
281
301
 
282
- return this.SubscriptionManager.AddSubscription(
283
- event,
284
- method,
285
- new Uint8Array(0),
286
- OcaNotificationDeliveryMode.Reliable,
287
- new Uint8Array(0)
288
- );
302
+ subscriptions.set(key, info);
303
+
304
+ try {
305
+ await this._doSubscribe(event);
306
+ } catch (err) {
307
+ subscriptions.delete(key);
308
+ throw err;
309
+ }
289
310
  }
290
311
 
291
312
  remove_subscription(event, callback) {
292
313
  const key = eventToKey(event);
293
314
 
294
- const S = this.subscriptions.get(key);
315
+ const info = this.subscriptions.get(key);
295
316
 
296
- if (!S) return Promise.reject('Callback not registered.');
317
+ if (!info) return Promise.reject('Callback not registered.');
297
318
 
298
- const a = S.callbacks;
319
+ const a = info.callbacks;
299
320
 
300
321
  a.delete(callback);
301
322
 
302
323
  if (!a.size) {
303
- this.connection.remove_subscriber(S.method);
324
+ this.connection._removeSubscriber(event);
304
325
  this.subscriptions.delete(key);
305
- return this.SubscriptionManager.RemoveSubscription(event, S.method);
326
+ return this.SubscriptionManager.RemoveSubscription(
327
+ event,
328
+ subscriberMethod
329
+ );
306
330
  }
307
331
 
308
332
  return Promise.resolve(true);
@@ -25,8 +25,7 @@ async function waitForKeepalive(socket, options) {
25
25
 
26
26
  pos = decodeMessage(new DataView(data.buffer), 0, pdus);
27
27
 
28
- if (pdus.length !== 1)
29
- throw new Error('Expected keepalive response.');
28
+ if (pdus.length !== 1) throw new Error('Expected keepalive response.');
30
29
 
31
30
  socket.off('message', onMessage);
32
31
  socket.off('error', reject);
@@ -43,8 +42,7 @@ async function waitForKeepalive(socket, options) {
43
42
  for (let i = 0; i < 3; i++) {
44
43
  socket.send(msg);
45
44
 
46
- if (await Promise.race([ waiter, delay(t) ]))
47
- return;
45
+ if (await Promise.race([waiter, delay(t)])) return;
48
46
  }
49
47
 
50
48
  throw new Error('Failed to connect.');
@@ -101,8 +99,10 @@ export class UDPConnection extends ClientConnection {
101
99
  this._write_out_id = -1;
102
100
  this._write_out();
103
101
  };
104
- this._retry_id = (this.retry_interval > 0) ?
105
- setInterval(() => this._retryCommands(), this.retry_interval) : -1;
102
+ this._retry_id =
103
+ this.retry_interval > 0
104
+ ? setInterval(() => this._retryCommands(), this.retry_interval)
105
+ : -1;
106
106
  this.q = [];
107
107
  socket.on('message', (data, rinfo) => {
108
108
  try {
@@ -176,16 +176,13 @@ export class UDPConnection extends ClientConnection {
176
176
  write(buf) {
177
177
  this.q.push(buf);
178
178
 
179
- if (this.tx_idle_time() >= this.delay)
180
- this._write_out();
181
- else
182
- this._schedule_write_out();
179
+ if (this.tx_idle_time() >= this.delay) this._write_out();
180
+ else this._schedule_write_out();
183
181
  }
184
182
 
185
183
  flush() {
186
184
  super.flush();
187
- if (this.tx_idle_time() > this.delay)
188
- this._write_out();
185
+ if (this.tx_idle_time() > this.delay) this._write_out();
189
186
  }
190
187
 
191
188
  cleanup() {
@@ -208,6 +205,10 @@ export class UDPConnection extends ClientConnection {
208
205
  return performance.now();
209
206
  }
210
207
 
208
+ _estimate_next_tx_time() {
209
+ return this._now() + (this.delay + 2) * this.q.length;
210
+ }
211
+
211
212
  _write_out() {
212
213
  if (!this.socket) return;
213
214
  const q = this.q;
@@ -219,8 +220,7 @@ export class UDPConnection extends ClientConnection {
219
220
  this.socket.send(Buffer.from(buf));
220
221
  super.write(buf);
221
222
 
222
- if (q.length)
223
- this._schedule_write_out();
223
+ if (q.length) this._schedule_write_out();
224
224
  }
225
225
 
226
226
  _schedule_write_out() {
@@ -233,10 +233,12 @@ export class UDPConnection extends ClientConnection {
233
233
  }
234
234
 
235
235
  // Already scheduled.
236
- if (this._write_out_id !== -1)
237
- return;
236
+ if (this._write_out_id !== -1) return;
238
237
 
239
- this._write_out_id = setTimeout(this._write_out_callback, delay - tx_idle_time);
238
+ this._write_out_id = setTimeout(
239
+ this._write_out_callback,
240
+ delay - tx_idle_time
241
+ );
240
242
  }
241
243
 
242
244
  _retryCommands() {
@@ -251,7 +253,7 @@ export class UDPConnection extends ClientConnection {
251
253
  const failed = [];
252
254
 
253
255
  for (const entry of pendingCommands) {
254
- const [ handle, pendingCommand ] = entry;
256
+ const [, pendingCommand] = entry;
255
257
 
256
258
  // All later commands are newer than the cutoff.
257
259
  if (pendingCommand.lastSent > retryTime) break;
@@ -265,13 +267,13 @@ export class UDPConnection extends ClientConnection {
265
267
  if (failed.length) {
266
268
  const timeoutError = new Error('Timeout.');
267
269
 
268
- failed.forEach(([ handle, pendingCommand ]) => {
270
+ failed.forEach(([handle, pendingCommand]) => {
269
271
  pendingCommands.delete(handle);
270
272
  pendingCommand.reject(timeoutError);
271
273
  });
272
274
  }
273
275
 
274
- retries.forEach(([ handle, pendingCommand ]) => {
276
+ retries.forEach(([handle, pendingCommand]) => {
275
277
  pendingCommands.delete(handle);
276
278
  pendingCommands.set(handle, pendingCommand);
277
279
  this.send(pendingCommand.command);
@@ -52,7 +52,9 @@ export class WebSocketConnection extends ClientConnection {
52
52
  cleanup() {
53
53
  super.cleanup();
54
54
  if (this.ws) {
55
- try { this.ws.close(); } catch (err) {}
55
+ try {
56
+ this.ws.close();
57
+ } catch (err) {}
56
58
  this.ws = null;
57
59
  }
58
60
  }
@@ -54,7 +54,9 @@ export class WebSocketConnection extends ClientConnection {
54
54
  cleanup() {
55
55
  super.cleanup();
56
56
  if (this.ws) {
57
- try { this.ws.close(); } catch (err) {}
57
+ try {
58
+ this.ws.close();
59
+ } catch (err) {}
58
60
  this.ws.removeAllListeners();
59
61
  this.ws = null;
60
62
  }
@@ -44,7 +44,8 @@ class Locking extends ObjectTest
44
44
  cleanup()
45
45
  {
46
46
  super.cleanup();
47
- this.other_device.close();
47
+ this.close_device(this.other_device);
48
+ this.other_device = null;
48
49
  }
49
50
  }
50
51
 
@@ -0,0 +1,24 @@
1
+ import { Test } from './test.js';
2
+
3
+ class CheckCallbackMethod extends Test {
4
+ async run() {
5
+ const root = this.device.Root;
6
+
7
+ const result = await root.GetMembers();
8
+
9
+ const result2 = await new Promise((resolve, reject) => {
10
+ const tmp = root.GetMembers((ok, result) => {
11
+ (ok ? resolve : reject)(result);
12
+ });
13
+ if (tmp) {
14
+ console.error('got %o', tmp);
15
+ throw new Error('Unexpected return value.');
16
+ }
17
+ });
18
+
19
+ if (result.length !== result2.length)
20
+ throw new Error('Result mismatch.');
21
+ }
22
+ }
23
+
24
+ export default [ CheckCallbackMethod ];
@@ -44,15 +44,22 @@ export class Test {
44
44
  {
45
45
  }
46
46
 
47
- cleanup()
47
+ close_device(device)
48
48
  {
49
- if (this.device !== null)
49
+ if (device !== null)
50
50
  {
51
- this.device.close();
52
- this.device = null;
51
+ device.connection.emit('test_done');
52
+ device.close();
53
+ device = null;
53
54
  }
54
55
  }
55
56
 
57
+ cleanup()
58
+ {
59
+ this.close_device(this.device);
60
+ this.device = null;
61
+ }
62
+
56
63
  static focus()
57
64
  {
58
65
  return false;
package/tests/device.js CHANGED
@@ -13,6 +13,7 @@ import CheckTreeTests from './device/check_tree.js';
13
13
  import KeepaliveTests from './device/keepalive.js';
14
14
  import LockingTests from './device/locking.js';
15
15
  import PropertyChangesTests from './device/property_changes.js';
16
+ import MethodCallbackTests from './device/method_callback.js';
16
17
 
17
18
  if (argv.length < 3)
18
19
  {
@@ -169,7 +170,8 @@ function get_runner(get_device)
169
170
  CheckTreeTests,
170
171
  //KeepaliveTests,
171
172
  LockingTests,
172
- PropertyChangesTests
173
+ PropertyChangesTests,
174
+ MethodCallbackTests
173
175
  ].flat();
174
176
 
175
177
  // require('./device/property_changes'),
@@ -187,12 +189,23 @@ function timeout(n)
187
189
 
188
190
  async function run_tests(type, target)
189
191
  {
192
+ let onClose = null;
193
+
194
+ const close_p = new Promise((resolve, reject) => {
195
+ onClose = () => setTimeout(() => reject(new Error('Closed.')), 1000);
196
+ });
197
+
190
198
  const get_device = async () => {
191
199
  const connection = await type.connect(connect_options(target));
192
200
  const device = new RemoteDevice(connection);
193
201
 
194
202
  device.set_keepalive_interval(1);
195
203
 
204
+ connection.on('close', onClose);
205
+ connection.on('test_done', () => {
206
+ connection.removeEventListener('close', onClose);
207
+ });
208
+
196
209
  return device;
197
210
  };
198
211
 
@@ -203,7 +216,7 @@ async function run_tests(type, target)
203
216
  const timeout_p = timeout(60*1000);
204
217
  const test_p = test_runner.run();
205
218
 
206
- await Promise.race([ timeout_p.then(() => { timed_out = true; }), test_p ]);
219
+ await Promise.race([ timeout_p.then(() => { timed_out = true; }), test_p, close_p ]);
207
220
 
208
221
  if (timed_out)
209
222
  {
@@ -1,64 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { stdout, argv, exit } from 'process';
4
- import { RemoteDevice } from '../src/controller/remote_device.js';
5
- import { TCPConnection } from '../src/controller/tcp_connection.js';
6
- import { format } from 'util';
7
-
8
- if (argv.length < 4)
9
- {
10
- console.log('Usage: node print_tree.js <ip> <port>');
11
- exit(1);
12
- }
13
-
14
- function delay(n) {
15
- if (!n) return Promise.resolve();
16
- return new Promise((resolve) => setTimeout(resolve, n));
17
- }
18
-
19
- const host = argv[2];
20
- const port = parseInt(argv[3]);
21
- const N = 1000;
22
-
23
- const destinations = new Array(N).fill(0).map((_, index) => {
24
- return { host: host, port: port + index };
25
- });
26
-
27
- async function connectAndDiscover(destination) {
28
- const con = await TCPConnection.connect(destination);
29
-
30
- const device = new RemoteDevice(con);
31
-
32
- const objectTree = await device.get_device_tree();
33
-
34
- device.close();
35
-
36
- return objectTree;
37
- }
38
-
39
- async function run() {
40
- for (let i = 0; i < destinations.length;) {
41
- let tasks = [];
42
-
43
- while (tasks.length < 5) {
44
- tasks.push(connectAndDiscover(destinations[i++]));
45
- }
46
-
47
- await Promise.all(tasks);
48
-
49
- stdout.write(format('\r %d %% done.',
50
- Math.floor(100 * i / destinations.length)));
51
-
52
- await delay(50);
53
- }
54
- }
55
-
56
- run().then(
57
- () => {
58
- console.log('\nDone');
59
- },
60
- (err) => {
61
- console.error(err);
62
- exit(1);
63
- }
64
- );
Binary file
@@ -1,16 +0,0 @@
1
- /*
2
- * This file has been generated.
3
- */
4
- import { Struct } from './Struct.js';
5
- import { FieldType } from './FieldType.js';
6
- import { OcaUint16 } from './OcaUint16.js';
7
-
8
- import { OcaClassID as type } from '../types/OcaClassID.js';
9
-
10
- export const OcaClassID = Struct(
11
- {
12
- FieldCount: OcaUint16,
13
- Fields: FieldType,
14
- },
15
- type
16
- );