1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
#!/usr/bin/ucode
import { readfile, writefile, mkdir, rename, unlink, chmod } from 'fs';
import * as uci from 'uci';
import * as ubus from 'ubus';
import { onvif_build } from './onvif-model.uc';
import { devices_resolve, camera_pipeline } from './config.uc';
const DIRECTORY = '/var/run/onvif-simple-server';
const CONFIG = DIRECTORY + '/config.json';
let cursor = uci.cursor();
let server = cursor.get_all('onvif-simple-server', 'main');
if (!server || server.enabled == '0' || (server.config_file && server.config_file != CONFIG))
exit(0);
if (ARGV[0] == 'stop') {
unlink(CONFIG);
exit(0);
}
try {
let inventory = readfile('/var/run/gst-rtsp/devices.json');
if (!inventory)
die('Video inventory is unavailable\n');
let state = json(inventory);
if (state.boot_id != trim(readfile('/proc/sys/kernel/random/boot_id')))
die('Video inventory belongs to another boot\n');
let listen = cursor.get('uhttpd', 'onvif', 'listen_http');
if (type(listen) == 'array')
listen = listen[0];
let port = int(split(listen ?? '', ':')[-1]);
if (port < 1 || port > 65535)
die('ONVIF HTTP listener is not configured\n');
let settings = cursor.get_all('gst-rtsp');
state.runtime = {};
for (let camera in values(settings)) {
if (camera['.type'] != 'camera')
continue;
let text = readfile('/var/run/gst-rtsp/' + camera['.name'] + '.json');
if (!text)
continue;
let actual = json(text);
if (actual.boot_id == state.boot_id &&
actual.pipeline == camera_pipeline(cursor, camera['.name'], state))
state.runtime = { ...state.runtime, ...actual.streams };
}
for (let stream in values(settings))
if (stream['.type'] == 'stream' && stream.enabled == '1')
devices_resolve(cursor, stream);
let board = ubus.call({ object: 'system', method: 'board', data: {} });
if (!board)
die('Cannot read system board identity\n');
for (let path in ['/sys/firmware/devicetree/base/serial-number',
'/sys/devices/virtual/dmi/id/product_serial']) {
if (board.serial)
break;
let serial = trim(readfile(path) ?? '', '\x00\t\r\n ');
if (serial)
board.serial = serial;
}
let config = onvif_build(settings, state, { ...server, port }, board);
if (!config) {
unlink(CONFIG);
exit(0);
}
mkdir(DIRECTORY, 0750);
let text = sprintf('%J', config);
if (writefile(CONFIG + '.new', text) != length(text) ||
!chmod(CONFIG + '.new', 0600) || !rename(CONFIG + '.new', CONFIG))
die('Cannot publish ONVIF configuration\n');
} catch (e) {
unlink(CONFIG);
warn('gst-rtsp ONVIF: ', e, '\n');
exit(1);
}
|