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.
- package/Changelog +46 -0
- package/dist/AES70.es5.js +1 -1
- package/package.json +9 -3
- package/src/OCP1/encode_message.js +3 -6
- package/src/OCP1/message_generator.js +21 -21
- package/src/OCP1.js +162 -0
- package/src/controller/ControlClasses/OcaFilterFIR.d.ts +5 -0
- package/src/controller/ControlClasses/OcaFilterFIR.js +9 -1
- package/src/controller/ControlClasses/OcaLibrary.d.ts +3 -1
- package/src/controller/ControlClasses/OcaLibrary.js +3 -1
- package/src/controller/ControlClasses/OcaPowerManager.d.ts +5 -0
- package/src/controller/ControlClasses/OcaPowerManager.js +9 -1
- package/src/controller/ControlClasses/OcaPowerSupply.d.ts +10 -0
- package/src/controller/ControlClasses/OcaPowerSupply.js +20 -2
- package/src/controller/ControlClasses/OcaSensor.d.ts +5 -0
- package/src/controller/ControlClasses/OcaSensor.js +9 -1
- package/src/controller/ControlClasses.d.ts +0 -1
- package/src/controller/arguments.d.ts +1 -2
- package/src/controller/client_connection.d.ts +1 -1
- package/src/controller/client_connection.js +56 -32
- package/src/controller/event.js +4 -1
- package/src/controller/make_control_class.js +24 -4
- package/src/controller/remote_device.d.ts +1 -1
- package/src/controller/remote_device.js +48 -24
- package/src/controller/udp_connection.js +22 -20
- package/src/controller/websocket_connection.js +3 -1
- package/src/controller/websocket_connection_node.js +3 -1
- package/tests/device/locking.js +2 -1
- package/tests/device/method_callback.js +24 -0
- package/tests/device/test.js +11 -4
- package/tests/device.js +15 -2
- package/bin/connectMany.js +0 -64
- package/src/OCP1/.keepalive.js.swo +0 -0
- 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
|
-
|
|
67
|
-
new EncodedArguments(argumentTypes,
|
|
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
|
|
|
@@ -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
|
-
|
|
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
|
-
|
|
268
|
+
{
|
|
269
|
+
const info = subscriptions.get(key);
|
|
250
270
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
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
|
|
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
|
-
|
|
295
|
+
this.connection._addSubscriber(event, cb);
|
|
275
296
|
|
|
276
|
-
|
|
297
|
+
const info = {
|
|
277
298
|
callbacks: new Set([callback]),
|
|
278
|
-
method: method,
|
|
279
299
|
callback: cb,
|
|
280
|
-
}
|
|
300
|
+
};
|
|
281
301
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
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
|
|
315
|
+
const info = this.subscriptions.get(key);
|
|
295
316
|
|
|
296
|
-
if (!
|
|
317
|
+
if (!info) return Promise.reject('Callback not registered.');
|
|
297
318
|
|
|
298
|
-
const a =
|
|
319
|
+
const a = info.callbacks;
|
|
299
320
|
|
|
300
321
|
a.delete(callback);
|
|
301
322
|
|
|
302
323
|
if (!a.size) {
|
|
303
|
-
this.connection.
|
|
324
|
+
this.connection._removeSubscriber(event);
|
|
304
325
|
this.subscriptions.delete(key);
|
|
305
|
-
return this.SubscriptionManager.RemoveSubscription(
|
|
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([
|
|
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 =
|
|
105
|
-
|
|
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
|
-
|
|
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(
|
|
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 [
|
|
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(([
|
|
270
|
+
failed.forEach(([handle, pendingCommand]) => {
|
|
269
271
|
pendingCommands.delete(handle);
|
|
270
272
|
pendingCommand.reject(timeoutError);
|
|
271
273
|
});
|
|
272
274
|
}
|
|
273
275
|
|
|
274
|
-
retries.forEach(([
|
|
276
|
+
retries.forEach(([handle, pendingCommand]) => {
|
|
275
277
|
pendingCommands.delete(handle);
|
|
276
278
|
pendingCommands.set(handle, pendingCommand);
|
|
277
279
|
this.send(pendingCommand.command);
|
|
@@ -54,7 +54,9 @@ export class WebSocketConnection extends ClientConnection {
|
|
|
54
54
|
cleanup() {
|
|
55
55
|
super.cleanup();
|
|
56
56
|
if (this.ws) {
|
|
57
|
-
try {
|
|
57
|
+
try {
|
|
58
|
+
this.ws.close();
|
|
59
|
+
} catch (err) {}
|
|
58
60
|
this.ws.removeAllListeners();
|
|
59
61
|
this.ws = null;
|
|
60
62
|
}
|
package/tests/device/locking.js
CHANGED
|
@@ -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 ];
|
package/tests/device/test.js
CHANGED
|
@@ -44,15 +44,22 @@ export class Test {
|
|
|
44
44
|
{
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
close_device(device)
|
|
48
48
|
{
|
|
49
|
-
if (
|
|
49
|
+
if (device !== null)
|
|
50
50
|
{
|
|
51
|
-
|
|
52
|
-
|
|
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
|
{
|
package/bin/connectMany.js
DELETED
|
@@ -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
|
package/src/OCP1/OcaClassID.js
DELETED
|
@@ -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
|
-
);
|