Compare commits

...

1008 Commits

Author SHA1 Message Date
Meng
f4828d4c1a dbg vlan config 2025-07-20 22:44:45 +02:00
Meng
f480b001c7 dbg apply 2025-07-17 10:10:11 +02:00
Meng
df45b0a720 adaption for bbfdm commit/revert 2025-07-16 09:19:17 +02:00
Meng
24646d3367 refactor and fix 2025-07-15 13:27:42 +02:00
Meng
53e743d0b2 bri dbg 2025-07-14 18:11:43 +02:00
Meng
952bcc924a add tr181-full-objects.json 2025-07-13 10:54:54 +02:00
Meng
c541463faf fix minor agent memory issue 2025-07-13 10:10:15 +02:00
Meng
506da7e733 fix memory issues 2025-07-13 00:51:29 +02:00
Meng
6662cee5c9 dbg 2025-07-13 00:33:46 +02:00
Meng
5f8c187880 dm-framework base 2025-07-10 16:46:46 +02:00
Amin Ben Romdhane
b8f99bbe64 ethmngr: 3.0.8 2025-07-01 17:50:59 +02:00
Jakob Olsson
42df10c708 map-agent: 6.3.6.7 2025-07-01 14:28:09 +02:00
Amin Ben Romdhane
7369ee4c20 wifidmd: 1.1.32 2025-07-01 12:48:47 +02:00
Amin Ben Romdhane
dc3aa2ec9d hostmngr: 1.3.1 2025-07-01 12:47:39 +02:00
Amin Ben Romdhane
312d28bec4 bbfdm: refresh DHCP entries when a new extender/repeater is connected 2025-07-01 12:33:12 +02:00
Anjan Chanda
45a754f567 ieee1905: 8.7.32 2025-07-01 09:44:59 +02:00
Amin Ben Romdhane
491f2ca07d netmngr: 1.1.8 2025-06-30 18:21:33 +02:00
Amin Ben Romdhane
2d5f9229f2 bbfdm: 1.16.6 2025-06-30 17:16:29 +02:00
Anjan Chanda
16536b9bc3 ieee1905: 8.7.31 2025-06-30 15:42:27 +02:00
Jakob Olsson
f552b68f10 map-agent: 6.3.6.6 2025-06-30 13:59:22 +02:00
Jakob Olsson
7c444911f7 map-agent: 6.3.6.5 2025-06-30 11:31:43 +02:00
Vivek Kumar Dutta
7a12fb28b1 wifidmd: reset WiFi with WiFi.Reset() cmd 2025-06-30 12:49:43 +05:30
Vivek Kumar Dutta
a430d76517 tr143: an7581 fastpath improvements 2025-06-29 10:46:16 +05:30
Janusz Dziedzic
b48c7e14dc map-agent: use correct networkid for dynamic backhaul 2025-06-27 14:27:36 +00:00
Gustaf Franzen
269d72c30a nng: 1.11
NNG - nanomsg-next-gen
2025-06-27 12:03:58 +00:00
Anjan Chanda
f19082aa1e ieee1905: 8.7.27 2025-06-27 13:45:19 +02:00
Janusz Dziedzic
43f0296ea2 libwifi: 7.13.4 2025-06-27 11:02:38 +00:00
Amin Ben Romdhane
6418f9fa8f bbfdm: 1.16.5 2025-06-26 17:01:41 +02:00
arbala
58ecaf9c15 map-agent: 6.3.6.4 2025-06-26 13:20:37 +02:00
Markus Gothe
0f8887f676 dslmngr: Add initial Airoha support. 2025-06-26 13:04:41 +02:00
Vivek Kumar Dutta
a1193cc6b8 wifidmd: 1.1.30 2025-06-26 14:44:02 +05:30
Vivek Kumar Dutta
392a41b38a ieee1905: tr181 vendor extn for localonly mode 2025-06-26 14:40:55 +05:30
Mohd Husaam Mehdi
c3128d3a14 self-diagnostics: collect contents of firewall log file 2025-06-26 13:25:22 +05:30
Anjan Chanda
4d88e123a9 ieee1905: 8.7.25 2025-06-26 09:27:43 +02:00
Vivek Kumar Dutta
fb050cae2e wifidmd: Set network_type with SetSSID 2025-06-25 18:03:30 +05:30
Jakob Olsson
90af4f350b map-agent: 6.3.6.3 2025-06-25 11:58:42 +02:00
Amin Ben Romdhane
605f0faacc parental-control: Use the correct instance name in reload service 2025-06-25 10:04:32 +02:00
arbala
065772401b ieee1905: 8.7.11 2025-06-25 09:47:06 +02:00
Vivek Kumar Dutta
886000a830 dnsmngr: Fix probable crash 2025-06-25 09:47:20 +05:30
Reidar Cederqvist
0b5a84e33a sulu: bump sulu-core to latest devel 2025-06-25 00:26:30 +02:00
Vivek Kumar Dutta
a2763cd075 bbfdm: Update reference db before set 2025-06-24 18:59:40 +05:30
Erik Karlsson
4a8b27ed95 map-agent: 6.3.6.2 2025-06-24 14:50:48 +02:00
Erik Karlsson
6eef7e4b21 ieee1905: do not use hw.board.basemac 2025-06-24 14:50:34 +02:00
Vivek Kumar Dutta
a0bde81de4 obuspa: Fix parameters in TransferCompelete event 2025-06-24 18:15:22 +05:30
Vivek Kumar Dutta
5e04f9312b sysmngr: Fix TransferComplete parameters 2025-06-24 18:13:42 +05:30
Vivek Kumar Dutta
a1e7f80ae0 logmngr: 1.0.17 2025-06-24 18:13:35 +05:30
Xiaofeng Meng
ed5169b94c sshmngr: Fix session detection for OpenSSH backend
The `sshmngr` service failed to list active sessions with the `sshd`
(OpenSSH) backend because the session detection logic could not handle
the process structure of modern OpenSSH, which uses an intermediate
process for new connections.

This commit resolves the issue by:
- Improving process lookup to check for grandparent PIDs, correctly
  identifying the session process.
- Querying the correct intermediate process for network connection details.
  parse netstat output.

The new logic is encapsulated in a `get_network_info` function within the
`openssh` backend script to maintain compatibility with the `dropbear`
backend, which uses a simpler implementation of the same function.
2025-06-24 18:04:44 +05:30
Jakob Olsson
c64701e6b2 map-agent: 6.3.6.1 2025-06-24 13:36:14 +02:00
Anjan Chanda
db6672c9ee wifimngr: 17.7.5 2025-06-24 10:28:45 +02:00
Vivek Kumar Dutta
05c4d0d3d1 obuspa: Fix log level for some recurring logs 2025-06-24 12:59:33 +05:30
Reidar Cederqvist
6535fe465c sulu: bump sulu-theme-genexis version to fix dark-mode logo 2025-06-23 10:52:55 +02:00
Markus Gothe
2703db3f2e mcastmngr: Add L2 snooping UCI generation.
If the WAN device is a bridge then generate
a default configuration using snooping instead
of proxying.
2025-06-23 09:29:47 +02:00
Suvendhu Hansa
bb603cb492 obuspa: mqtt fallback IP family in dual-stack mode 2025-06-21 19:17:25 +05:30
Reidar Cederqvist
f8d7788d6f sulu: update sulu to version 5.0 based on React 2025-06-20 20:53:42 +02:00
Vivek Kumar Dutta
97df4367eb bbfdm: 1.16.3 2025-06-20 18:44:02 +05:30
Vivek Kumar Dutta
21fbf0253c sysmngr: 1.0.27 2025-06-20 18:10:19 +05:30
Vivek Kumar Dutta
ced2b4187f netmode: 1.1.5 2025-06-20 12:43:21 +05:30
Suvendhu Hansa
bfdd27f72a obuspa: Option to configure DualStack preference 2025-06-20 09:08:20 +05:30
George Yang
6f1953e4a4 dectmngr-3.7.10 and libvoice-airoha-1.1.7
- Play dial tone for DECT handset
2025-06-19 15:00:38 +00:00
Roman Azarenko
fd816f8ee1 iopsys-analytics: read ubus event data from pipe 2025-06-19 16:51:27 +02:00
Jakob Olsson
cbdc083db5 ieee1905: 8.7.9 2025-06-19 15:20:38 +02:00
Jakob Olsson
eb1897a730 hostmngr: 1.3.0 2025-06-19 14:34:03 +02:00
Roman Azarenko
546450566e iopsys-analytics: get hostname from UCI, whitespace/typo cleanup 2025-06-18 22:16:31 +02:00
Vivek Kumar Dutta
5fb51c6fd9 wifidmd: Added EncryptionMode parameter 2025-06-18 20:52:26 +05:30
Sukru Senli
5d84d0ae29 wifi-services, map-plugins: add PKG_LICENSE_FILES 2025-06-18 17:07:33 +02:00
Anjan Chanda
340709b527 map-plugins: 0.0.4 2025-06-18 16:38:07 +02:00
George Yang
38bef28d00 dectmngr-3.7.9 and libvoice-airoha-1.1.6
- dectmngr: DTMF tone always be played in any DTMF mode
  whenever key is pressed.

- libvoice-airoha: Removed adamStrmSendDtmfr() calls.
  It is not actually needed for rfc4733 mode to generate
  RTP event for received DTMF tones.
2025-06-18 15:55:41 +02:00
Janusz Dziedzic
ba53aeda7d libwifi: 7.13.3 2025-06-18 13:48:13 +00:00
Mohd Husaam Mehdi
bd63c5a090 parental-control: fix path used to check if urlfiltering is enabled 2025-06-18 18:19:27 +05:30
George Yang
89c1fbb38a libvoice-airoha-1.1.5 2025-06-18 10:31:08 +02:00
Vivek Kumar Dutta
d6ff1d851b parental-control: 1.2.1 2025-06-18 11:02:16 +05:30
Vivek Kumar Dutta
107b1576e8 ipt-trigger: 1.0.3 2025-06-18 11:00:27 +05:30
Vivek Kumar Dutta
47694dc23e hostmngr: 1.2.21 2025-06-18 11:00:27 +05:30
Vivek Kumar Dutta
002836769c bridgemngr: 1.0.17 2025-06-18 11:00:23 +05:30
Amin Ben Romdhane
cafb9f09ba wifidmd: 1.1.27 2025-06-17 16:26:14 +02:00
Sukru Senli
a440adbef9 jsonval: 1.0.0
A small CLI tool to validate JSON files against a schema using json-schema-validator and nlohmann/json
2025-06-17 15:38:32 +02:00
Sukru Senli
2ba04321b3 json-schema-validator: 2.3.0 2025-06-17 17:13:00 +05:30
Sukru Senli
9126f2ef7d nlohmann-json: 3.11.2 2025-06-17 17:13:00 +05:30
Amin Ben Romdhane
ed01ddf670 bbfdm: 1.16.2 2025-06-16 16:05:39 +02:00
Janusz Dziedzic
7e360f7b30 map-agent: 6.3.6.0 2025-06-16 13:54:31 +00:00
Vivek Kumar Dutta
e15dcd3b25 wifidmd: Fetch radio status from wifi.radio ubus object 2025-06-16 09:55:27 +05:30
Suvendhu Hansa
9ee00a3c82 map-controller: added wpa,wpa2,wpa-mixed in uci validation 2025-06-13 20:26:17 +05:30
Janusz Dziedzic
ba94d88f0d libwifi: 7.13.2 2025-06-13 14:32:36 +00:00
George Yang
041e51edf3 libvoice-airoha: 1.1.4 and dectmngr: 3.7.8 2025-06-13 12:15:53 +02:00
Amin Ben Romdhane
6ca5af0790 bbfdm: 1.16.1 2025-06-13 11:11:55 +02:00
Anjan Chanda
6d32d6e8b3 map-plugins: 0.0.3 2025-06-13 11:05:32 +02:00
Anjan Chanda
2b4f9029f8 map-controller: 6.4.0.11 2025-06-13 11:04:27 +02:00
Vivek Kumar Dutta
8c3bf8763e obuspa: option to configure poll period 2025-06-13 10:40:40 +05:30
Mohd Husaam Mehdi
1c6243113c mcastmngr: update firewall script to get zone name dynamically 2025-06-12 19:50:36 +05:30
Mohd Husaam Mehdi
eedf8d2761 firewallmngr: update firewall script to get zone name dynamically 2025-06-12 19:43:14 +05:30
Amin Ben Romdhane
bf8b4de5da wifidmd: add a script to handle wifi configs relaod 2025-06-12 15:14:07 +05:30
Vivek Kumar Dutta
fd208e0e5f bbfdm: external reload handlers for wifi 2025-06-12 15:14:07 +05:30
Husaam Mehdi
5b090176a1 logmngr: Fix shadow variable names in lib 2025-06-12 14:34:46 +05:30
Jakob Olsson
93b1952f50 decollector: 6.2.1.7 2025-06-12 09:26:36 +02:00
Jakob Olsson
ddcfeeb339 map-controller: 6.4.0.6 2025-06-11 16:26:13 +02:00
Anjan Chanda
8cea3573f7 map-plugins: 0.0.2 2025-06-11 15:39:15 +02:00
Anjan Chanda
8ac0f69992 map-controller: 6.4.0.5 2025-06-11 15:38:10 +02:00
Janusz Dziedzic
65dea29e5f mapcontroller: 6.4.0.3 2025-06-11 12:28:27 +00:00
Janusz Dziedzic
2cecb4f75a libwifi: 7.13.1 2025-06-11 10:11:16 +00:00
Suvendhu Hansa
a47d302ec7 icwmp,twamp,userinterface: Fix duplicate zone names 2025-06-11 14:34:41 +05:30
Roman Azarenko
a9b3a392dd iopsys-analytics: fix typo in Makefile conditional
syslong-ng -> syslog-ng
2025-06-11 10:04:05 +02:00
Amin Ben Romdhane
397611aff5 wifidmd: 1.1.24 2025-06-10 17:39:43 +02:00
arbala
21c9fafc4d map-agent: 6.3.5.9 2025-06-10 17:21:49 +02:00
Anjan Chanda
41efd7d712 map-plugins: 0.0.1 2025-06-10 17:05:46 +02:00
Anjan Chanda
f1e37ac0d8 map-controller: 6.4.0.2 2025-06-10 17:04:22 +02:00
Vivek Kumar Dutta
ab6d3935d1 swmodd: 2.5.27 2025-06-10 11:02:12 +05:30
Roman Azarenko
db529f651e iopsys-analytics: add support for fluentbit 2025-06-09 16:47:18 +02:00
Mohd Husaam Mehdi
975bf57de0 analytics: add support for fluent-bit backend 2025-06-09 13:21:21 +00:00
Vivek Kumar Dutta
6fb3a1b91d wifidmd: Vendor extn to modify ssid in SetSSID 2025-06-09 17:02:59 +05:30
Suvendhu Hansa
57ae4eb344 icwmp,twamp: Fix zone name in firewall rules 2025-06-09 16:53:48 +05:30
Anjan Chanda
dc79aa56f9 map-controller: 6.4.0.1 2025-06-09 10:24:31 +02:00
Vivek Kumar Dutta
8334b65ad4 icwmp: Fix fault string initialization 2025-06-06 17:18:53 +05:30
Strhuan Blomquist
e9caa2e7cd cleanup of colleccd 2025-06-05 13:58:47 +00:00
Janusz Dziedzic
49a31dbd49 libwifi: 7.13.0 2025-06-05 08:10:38 +00:00
Vivek Kumar Dutta
31f223f7a0 icwmp: 9.9.8 2025-06-04 18:03:28 +05:30
Vivek Kumar Dutta
8e33d24256 sysmngr: 1.0.26 2025-06-04 17:59:04 +05:30
Mohd Husaam Mehdi
e6df8f9ad0 logmngr: add support for conf_dir in generated logrotate config 2025-06-04 15:02:45 +05:30
Reidar Cederqvist
2c3e9ce606 sulu: fix led brightness access 2025-06-04 10:58:45 +02:00
arbala
616e15b9c4 decollector: 6.2.1.6 2025-06-03 15:37:23 +02:00
Husaam Mehdi
93d2d09dcc parental-control: Option to enable/disable urlfilter 2025-06-03 15:56:45 +05:30
Janusz Dziedzic
ece7e8f22c wifimngr: 17.7.4 2025-06-03 08:17:45 +02:00
Vivek Kumar Dutta
879b473d20 bbfdm: Added netmode in critical service list 2025-06-02 19:07:40 +05:30
Vivek Kumar Dutta
ac9da0ec6f wifidmd: Cleanup updated for Radius parameters 2025-06-02 19:05:56 +05:30
Suvendhu Hansa
7c5046d9d8 bbfdm: added mapcontroller in critical service 2025-05-30 20:37:11 +05:30
Vivek Kumar Dutta
69ccc34b2c sysmngr: align with fwbank 2025-05-30 19:35:24 +05:30
Vivek Kumar Dutta
87a6852c1a sysmngr: fwbank: return failure result if input validation fails 2025-05-30 13:26:17 +05:30
Vivek Kumar Dutta
b0d1ada967 ddnsmngr: 1.0.12 2025-05-30 09:30:05 +05:30
Husaam Mehdi
09cccc39cc fluent-bit: Align syslog output with syslog-ng
- added support to prepend message length in syslog output
2025-05-30 09:27:19 +05:30
Jakob Olsson
7227cbd8da map-agent: 6.3.5.8 2025-05-28 13:00:50 +02:00
Vivek Kumar Dutta
c57b0322b0 netmode: 1.1.4 2025-05-28 12:36:43 +05:30
Sukru Senli
db626422dc netmode: Added mode specific scripts 2025-05-28 12:17:31 +05:30
Anjan Chanda
26ffa55453 wifimngr: 17.7.3 2025-05-27 20:23:43 +02:00
arbala
adc2b26a78 map-controller: 6.3.0.19 2025-05-27 17:34:01 +02:00
Amin Ben Romdhane
51e3ad0404 bbfdm: 1.15.30 2025-05-27 16:41:19 +02:00
Amin Ben Romdhane
d9448a0de4 icwmp: 9.9.7 2025-05-27 16:40:27 +02:00
Amin Ben Romdhane
84eff7c8e0 wifidmd: 1.1.21 2025-05-27 16:37:16 +02:00
Amin Ben Romdhane
53d940586e bridgemngr: 1.0.16 2025-05-27 16:33:00 +02:00
Amin Ben Romdhane
712435786a netmngr: 1.1.7 2025-05-27 16:31:58 +02:00
Jakob Olsson
e57bbc0306 map-agent: 6.3.5.7 2025-05-27 13:04:38 +02:00
Vivek Kumar Dutta
cc4aa5a415 wifidmd: Added InitiateWPSPBC() in DataElements 2025-05-27 09:12:37 +05:30
Amin Ben Romdhane
7e502d79c8 bridgemngr: 1.0.15 2025-05-26 17:18:03 +02:00
Amin Ben Romdhane
cbbc3b3725 wifi-services: Add Rating Data Model Extension 2025-05-26 13:13:15 +00:00
Mohd Husaam Mehdi
dcfe80ad8e fluent-bit: enable tail plugin to help read files 2025-05-26 18:42:27 +05:30
Mohd Husaam Mehdi
c8bbe8725a logmngr: enable hot reload for fluent-bit 2025-05-26 17:47:18 +05:30
Anjan Chanda
71828eb20b decollector: 6.2.1.5 2025-05-26 14:14:55 +02:00
Anjan Chanda
90fd7f326d decollector: 6.2.1.4 2025-05-26 12:01:47 +02:00
Anjan Chanda
1263451924 wifimngr: 17.7.2 2025-05-26 11:48:18 +02:00
Anjan Chanda
c74662e1dd wifi-services: 0.0.5 2025-05-26 11:47:09 +02:00
Janusz Dziedzic
34482e3c86 map-agent: 6.3.5.6 2025-05-26 07:45:43 +00:00
Filip Matusiak
96be0f9fab map-agent: 6.3.5.5
log: introduce feature level logging
2025-05-26 08:54:23 +02:00
Mohd Husaam Mehdi
971d1ca37e logmngr: add support for including config files in fluent-bit
* config files can be placed at /etc/fluent-bit/conf.d/ and
  they will be included
2025-05-26 11:46:38 +05:30
Vivek Kumar Dutta
99821b5010 obuspa: uci option to configure mqtt RequestResponseInfo 2025-05-25 21:45:02 +05:30
Erik Karlsson
c68b1c01eb libwifi: 7.12.10 2025-05-23 15:45:55 +02:00
George Yang
a053e7752f dectmngr: Support DCX81 firmware upgrade via init script 2025-05-23 14:58:44 +02:00
Amin Ben Romdhane
558bd40b9f wifidmd: Fix compilation error when WIFIDMD_DISABLE_LEGACY_WIFI is selected 2025-05-23 09:21:47 +02:00
Amin Ben Romdhane
432969f0bf wifidmd: 1.1.18 2025-05-22 18:02:19 +02:00
Sukru Senli
a7dfecba54 wifi-services: add LICENSE file 2025-05-22 16:41:57 +02:00
Jakob Olsson
0ba1417643 decollector: 6.2.1.3 2025-05-22 14:05:10 +02:00
Jakob Olsson
29d6ad2fbd map-controller: 6.3.0.18 2025-05-22 14:04:37 +02:00
Jakob Olsson
f7ef772ebf map-agent: 6.3.5.4 2025-05-22 14:04:02 +02:00
Amin Ben Romdhane
d0c9d595c8 wifidmd: 1.1.17 2025-05-22 11:14:15 +02:00
Amin Ben Romdhane
912d98f496 bbfdm: 1.15.29 2025-05-22 11:12:41 +02:00
George Yang
8fb1b55e57 libvoice-airoha: update uci-defaults to apply DECT RFPI from prodution data
Set the hw.board.dect_rfpi with value of USP 'DectRfpi'.
2025-05-22 10:37:45 +02:00
Vivek Kumar Dutta
c5e79244c7 wifidmd: 1.1.16 2025-05-22 14:04:21 +05:30
Amin Ben Romdhane
499f77d498 bbfdm: 1.15.28 2025-05-21 17:51:12 +02:00
Amin Ben Romdhane
480c954677 wifidmd: 1.1.15 2025-05-21 17:32:34 +02:00
Jakob Olsson
9a5564bca4 map-agent: hotplug: map-dynamic-backhaul: remove tracking of port connections prior to dynbh start 2025-05-21 15:50:17 +02:00
Jakob Olsson
67ee062946 map-agent: 6.3.5.3 2025-05-21 15:49:05 +02:00
Vivek Kumar Dutta
7ecdc3ccb4 timemngr: 1.1.9 2025-05-21 17:50:43 +05:30
Vivek Kumar Dutta
36490a7cda netmode: Add support for SupportedArguments 2025-05-21 16:22:27 +05:30
Anjan Chanda
1d31c5f795 wifimngr: 17.7.1 - update init.d script 2025-05-21 10:25:03 +02:00
Anjan Chanda
9a934269ae wifi-services: add libwifi dependency 2025-05-21 10:25:03 +02:00
Janusz Dziedzic
82e8c63c88 libwifi: 7.12.9 2025-05-20 16:15:23 +00:00
Erik Karlsson
4fe71d66d3 fluent-bit: use PKG_SOURCE_URL_FILE
This avoids having a very generic file name in the dl directory.
2025-05-20 15:21:00 +02:00
Jakob Olsson
74eac091ff decollector: 6.2.1.2 2025-05-20 15:15:37 +02:00
Janusz Dziedzic
94cf651a6c map-agent: 6.3.5.2 2025-05-20 12:56:20 +00:00
Janusz Dziedzic
08f909388c libwifi: 7.12.8 2025-05-20 12:51:47 +00:00
Amin Ben Romdhane
148d25caf0 bbfdm: 1.15.27 2025-05-20 14:45:36 +02:00
Amin Ben Romdhane
8d8cc94cdf wifidmd: 1.1.14 2025-05-20 14:41:39 +02:00
Anjan Chanda
0d6c7b2f70 wifimngr: 17.7.1 2025-05-20 14:24:52 +02:00
Anjan Chanda
0623e7017f libeasy: 7.4.6 2025-05-20 11:51:43 +02:00
Vivek Kumar Dutta
013f820b12 periodicstats: align with bbfdm 2025-05-20 15:18:17 +05:30
Vivek Kumar Dutta
9fd4584cdb bbfdm: Prevent repeated async calls to unstable micro-services 2025-05-20 15:18:17 +05:30
Anjan Chanda
3b3035441e wifimngr: 17.7.0 2025-05-20 11:45:46 +02:00
Anjan Chanda
38f36f3bdf libwifi: 7.12.7 2025-05-20 11:40:21 +02:00
Anjan Chanda
b27646211b wifi-services: 0.0.2 2025-05-20 11:36:17 +02:00
Vivek Kumar Dutta
70b5c78d22 icwmp: 9.9.6 2025-05-20 13:41:27 +05:30
Husaam Mehdi
2356ed6075 fluent-bit: bump version to 4.0.2 2025-05-20 13:34:35 +05:30
Suvendhu Hansa
39d484817e icwmp: Option to select SMM feature 2025-05-20 10:09:05 +05:30
Janusz Dziedzic
a73c089c2a libwifi: 7.12.6 2025-05-19 13:50:00 +00:00
Vivek Kumar Dutta
22d9f90528 netmode: fix extender configuration 2025-05-19 17:43:17 +05:30
Janusz Dziedzic
ac93499202 wifimngr: 17.6.6 2025-05-19 08:18:04 +00:00
Janusz Dziedzic
4dfc3455fb libwifi: 7.12.5 2025-05-19 08:18:04 +00:00
Anjan Chanda
5bc00d53fd decollector: 6.2.1.1 2025-05-19 09:22:49 +02:00
Suvendhu Hansa
6ec25f158c wifidmd: added vendor extension 2025-05-17 19:27:38 +00:00
Amin Ben Romdhane
9817ca11b5 wifidmd: 1.1.13 2025-05-16 15:38:11 +02:00
Vivek Kumar Dutta
ca49dfac97 netmode: support to define supported modes 2025-05-16 18:23:43 +05:30
Jakob Olsson
44238e2033 map-agent: 6.3.5.1 2025-05-16 09:04:55 +02:00
Jakob Olsson
e1d4bddbcf map-controller: 6.3.0.17 2025-05-16 09:03:18 +02:00
Anjan Chanda
c6a739ddc0 decollector: 6.2.1.0 2025-05-15 16:06:03 +02:00
Jakob Olsson
38f657fa84 map-controller: 6.3.0.16 2025-05-15 14:45:41 +02:00
Reidar Cederqvist
f5488143cd Sulu: improve mapping for device picture 2025-05-15 09:51:43 +02:00
Amin Ben Romdhane
cebbf0f860 wifidmd: 1.1.12 2025-05-14 22:47:25 +02:00
Amin Ben Romdhane
dcac2bd261 bbfdm: 1.15.25 2025-05-14 21:49:06 +02:00
Janusz Dziedzic
82c6cca440 libwifi: 7.12.4 2025-05-14 18:02:37 +00:00
Vivek Kumar Dutta
2a952644c5 parental-control: 1.1.6 2025-05-14 22:12:30 +05:30
Janusz Dziedzic
fac25dc016 libwifi: 7.12.3 2025-05-14 16:29:09 +00:00
arbala
623e1dc34e map-controller: 6.3.0.15 2025-05-14 15:59:39 +02:00
Erik Karlsson
ed30787ca4 map-controller: fix potential shell injection in 99-mapcntlr
Expand variables which may contain "user input" in the second pass
(production data is not likely to contain anything unsafe but it is
better to be on the safe side). In addition use "$@" instead of
hardcoded parameters and handle json_select failure. Use OpenWrt
get_mac_label instead of legacy methods to obtain MAC address.
2025-05-14 14:07:31 +02:00
Amin Ben Romdhane
d68e0847c4 dnsmngr: 1.0.17 2025-05-14 12:05:14 +02:00
Amin Ben Romdhane
08cb598de4 parental-control: 1.1.5 2025-05-14 12:03:53 +02:00
Amin Ben Romdhane
2763ba7656 periodicstats: 1.5.17 2025-05-14 11:57:51 +02:00
Amin Ben Romdhane
2591116be3 usermngr: 1.3.10 2025-05-14 11:56:23 +02:00
Amin Ben Romdhane
06876807c1 timemngr: 1.1.8 2025-05-14 11:55:20 +02:00
Amin Ben Romdhane
65344ebdc5 bulkdata: 2.1.20 2025-05-14 11:54:22 +02:00
Amin Ben Romdhane
7dc743630c tr143: 1.1.1 2025-05-14 11:53:09 +02:00
Amin Ben Romdhane
a8d7adbd1f wifidmd: 1.1.11 2025-05-14 11:52:19 +02:00
Amin Ben Romdhane
ba215d1d6f bbfdm: 1.15.24 2025-05-14 11:51:18 +02:00
Jakob Olsson
fdfa1526b8 map-controller: 6.3.0.14 2025-05-13 17:33:03 +02:00
Jakob Olsson
a93bde6fb5 map-agent: 6.3.5.0 2025-05-13 17:31:54 +02:00
Janusz Dziedzic
4135fbe369 wifimngr: 17.6.5 2025-05-12 09:36:56 +00:00
Erik Karlsson
e4e63ba991 wifimngr: remove LED handling 2025-05-09 11:48:40 +02:00
Janusz Dziedzic
832947703c wifimngr: 17.6.4 2025-05-09 07:59:21 +00:00
George Yang
14e5601aed dectmngr: remove the default PIN from dect config 2025-05-08 16:37:33 +02:00
George Yang
d3b2d4d9bf Revert "dectmngr: add rules in ruleng to handle DECT LED"
This reverts commit 5f36441b11.

As the solution caused conflict to WPS led.
2025-05-08 16:35:14 +02:00
George Yang
8741d7d82e dectmngr-3.7.7 2025-05-08 14:42:43 +02:00
Jakob Olsson
910538aad7 map-agent: 6.3.4.14 2025-05-08 14:24:51 +02:00
George Yang
5f36441b11 dectmngr: add rules in ruleng to handle DECT LED
Also remove the default DECT PIN '1234'.
2025-05-08 11:59:08 +00:00
Anjan Chanda
075728ce3e wifimngr: 17.6.3 2025-05-08 11:31:58 +02:00
Anjan Chanda
21687b6dc9 wifi-services: 0.0.1 2025-05-08 11:08:11 +02:00
Vivek Kumar Dutta
b5c2667d68 obuspa: Fix faults for operate commands 2025-05-07 21:47:51 +05:30
Amin Ben Romdhane
589c856cb7 ieee1905: 8.7.8 2025-05-07 15:04:12 +02:00
Amin Ben Romdhane
e819a32cd7 wifidmd: 1.1.10 2025-05-07 14:08:32 +02:00
George Yang
bc8c70f7d0 dectmngr-3.7.6 2025-05-06 18:04:22 +02:00
Elena Vengerova
fb17c3f51b libwifi, wifimngr: add eml_mode 2025-05-06 16:23:51 +04:00
Reidar Cederqvist
0dfd361033 sulu: fix WAN linktype 2025-05-06 13:09:42 +02:00
George Yang
6d31feaa00 dectmngr-3.7.5: DECT support for E755 2025-05-06 10:48:30 +02:00
Vivek Kumar Dutta
9df2d4b15e obuspa: Use legecy expanded paths for subscriptions 2025-05-05 18:51:47 +05:30
Suvendhu Hansa
b91ae7f7f0 tr143: use fastpath for download diagnostics in an7581 2025-05-02 19:03:01 +05:30
Vivek Kumar Dutta
6df1768244 netmode: datamodel vendor extension 2025-05-02 18:00:07 +05:30
Vivek Kumar Dutta
0a7245d2f9 obuspa: Optimize set requests to reduce reloads 2025-05-02 15:29:38 +05:30
Vivek Kumar Dutta
6166ba0041 obuspa: 10.0.0.5 2025-05-02 13:48:40 +05:30
George Yang
02577401c7 Config dect: Fix a typo 2025-05-02 10:14:58 +02:00
Vivek Kumar Dutta
eccfd8970a wifidmd: In SetSSID wait for changes to apply 2025-05-01 19:42:17 +05:30
Vivek Kumar Dutta
7097827eb8 obuspa: 10.0.0.4 2025-05-01 19:36:50 +05:30
Vivek Kumar Dutta
29e9ba389a obuspa: Updated SecuredRole only for bbfdm 2025-05-01 19:18:43 +05:30
George Yang
4c6f70342a dectmngr: Enable DECT base in default config
And also set the default PIN to '1234'.
2025-05-01 12:12:32 +02:00
Vivek Kumar Dutta
4708da4734 icwmp: 9.9.4 2025-05-01 10:21:15 +05:30
George Yang
55aba515ff libvoice-airoha: 1.1.3
DECT support on E755
2025-04-30 17:42:57 +02:00
George Yang
b1c9ce0d25 dectmngr-init: add few arguments for dectmngr
Add few arguments for dectmngr, which is based on the UCI config for
asterisk and dect:

    -sync $pcm_fsync (UCI dect.global.pcm_fsync)

    -slotsShift $pcm_slot_start (UCI dect.global.pcm_slot_star)

    -extensionShift N (starting index of UCI asterisk.extensionN for DECT)
2025-04-30 16:52:10 +02:00
Vivek Kumar Dutta
d3ae8b5020 obuspa: fix syslog format 2025-04-30 19:52:40 +05:30
Vivek Kumar Dutta
ca962744b8 obuspa: Integrated v10.0.0 2025-04-30 19:52:40 +05:30
George Yang
31c7500042 libvoice-airoha/uci-defaults: add DECT default settings for E755
Following default settings added to dect config:
  - dect.global.pcm_fsync='SHORT_LF'
  - dect.global.pcm_slot_start='8'
  - dect.global.dect_channel_start='3'
2025-04-30 16:16:16 +02:00
Jakob Olsson
e71ee20840 map-agent: 6.3.4.13 2025-04-30 12:27:20 +02:00
Mohd Mehdi
38763bfc0d logmngr: set fluent-bit coro_stack_size option to prevent segfault 2025-04-29 21:37:47 +05:30
Vivek Kumar Dutta
a43e3530c9 obuspa: align role definitions 2025-04-29 21:12:38 +05:30
Vivek Kumar Dutta
86ede4ab6b usermngr: Added admin,user users in default config 2025-04-29 20:09:52 +05:30
Jakob Olsson
d234e7adcc map-agent: 6.3.4.12 2025-04-29 15:34:41 +02:00
Erik Karlsson
e7e5ede6b9 ieee1905: populate device information based on OpenWrt properties
This follows how Device.DeviceInfo. is populated.
2025-04-29 15:15:33 +02:00
Janusz Dziedzic
476aee97a6 wifimngr: 17.6.1 2025-04-29 13:02:49 +00:00
Janusz Dziedzic
784c6553d8 libwifi: 7.12.1 2025-04-29 13:02:49 +00:00
Vivek Kumar Dutta
e2883f0f45 obuspa: use syslog for logging 2025-04-29 14:41:43 +05:30
Janusz Dziedzic
30d01926a8 map-agent: 6.3.4.11 2025-04-28 14:21:26 +00:00
Vivek Kumar Dutta
f6510849d6 usermngr: Remove deprecated RemoteAccessCapable 2025-04-28 19:22:33 +05:30
Vivek Kumar Dutta
d49e72be07 obuspa: mark roles as static 2025-04-28 19:08:13 +05:30
Janusz Dziedzic
35e9ed9b1b libwifi: 7.12.0 2025-04-28 13:00:03 +00:00
Sukru Senli
e66516242a lt-nand: remove unused package 2025-04-28 13:15:24 +02:00
Jakob Olsson
4affd50d2c map-agent: 6.3.4.10 2025-04-28 11:13:36 +02:00
Vivek Kumar Dutta
06dec89452 wifidmd: Fix mapping for Associated and Disassociated events 2025-04-28 13:42:12 +05:30
Vivek Kumar Dutta
130dbeacd5 bbfdm: Fix datamodel references generation 2025-04-25 19:54:19 +05:30
Vivek Kumar Dutta
d576d81b1f usermngr: Fix static user implementation 2025-04-25 19:52:28 +05:30
Reidar Cederqvist
ee6edfa5a9 sulu: remove SoftwareModules and topology widgets 2025-04-25 15:39:37 +02:00
Janusz Dziedzic
2f8c5e3f53 libwifi: 7.11.9 2025-04-25 08:10:37 +00:00
Erik Karlsson
5c0010edf8 ieee1905: 8.7.6 2025-04-24 13:17:37 +02:00
Jakob Olsson
001eb7e0a3 map-agent: 6.3.4.9 2025-04-24 11:53:59 +02:00
Janusz Dziedzic
a2209f555b map-agent: 6.3.4.8 2025-04-24 07:35:34 +00:00
Janusz Dziedzic
8c09e8658e wifimngr: 17.6.0 2025-04-24 06:50:21 +00:00
Reidar Cederqvist
1d85f324a4 sulu: update to latest sulu-core 2025-04-23 21:25:59 +02:00
Jakob Olsson
65926415ad map-agent: 6.3.4.7 2025-04-23 15:44:50 +02:00
Amin Ben Romdhane
50e865df53 wifidmd: 1.1.7 2025-04-23 15:00:52 +02:00
Amin Ben Romdhane
cf352e9990 bbfdm: 1.15.22 2025-04-23 14:59:09 +02:00
Jakob Olsson
ecec95ca57 map-agent: 6.3.4.6 2025-04-23 13:24:00 +02:00
Vivek Kumar Dutta
9a051abbf1 bbfdm: 1.15.21 2025-04-23 09:44:59 +05:30
Vivek Kumar Dutta
d3b5d8d598 bbfdm: bump RootDataModelVersion to 2.19 2025-04-22 19:10:14 +05:30
Vivek Kumar Dutta
3c4bbfb6d6 port-trigger: functionality merged in firewallmngr 2025-04-22 16:45:07 +05:30
Vivek Kumar Dutta
0122493c01 sysmngr: add support for KeepConfig in Activate 2025-04-22 16:36:29 +05:30
Anjan Chanda
6098c3ab56 decollector: 6.2.0.4 2025-04-22 09:53:12 +02:00
Anjan Chanda
252c98c4ef map-controller: 6.3.0.13 2025-04-22 09:25:38 +02:00
Vivek Kumar Dutta
5ea17980c8 wifidmd: Added BTMAbridged in ClientSteer command 2025-04-21 15:06:23 +05:30
Vivek Kumar Dutta
3ba06fa10f wifidmd: 1.1.5 2025-04-17 17:27:51 +05:30
Jakob Olsson
013086f558 decollector: 6.2.0.3 2025-04-17 13:00:26 +02:00
Jakob Olsson
3a8f8d604f map-agent: 6.3.4.5 2025-04-17 12:26:18 +02:00
Janusz Dziedzic
8612f5d4f6 map-agent: 6.3.4.4 2025-04-16 19:08:34 +00:00
Janusz Dziedzic
6aef37d406 libwifi: 7.11.8 2025-04-16 16:39:55 +00:00
Amin Ben Romdhane
753dc05320 wifidmd: 1.1.4 2025-04-16 15:27:17 +02:00
Amin Ben Romdhane
74878254b7 hostmngr: 1.2.20 2025-04-16 15:26:08 +02:00
Janusz Dziedzic
4f2697217a libwifi: 7.11.7 2025-04-16 10:28:11 +00:00
Amin Ben Romdhane
e36a9bc381 wifidmd: 1.1.3 2025-04-15 17:23:23 +02:00
Amin Ben Romdhane
a52d654c4f bbfdm: 1.15.19 2025-04-15 17:22:28 +02:00
Vivek Kumar Dutta
6cf5641ea7 cwmp: Use cpe specific acs password 2025-04-15 18:10:35 +05:30
Janusz Dziedzic
bce378a665 libwifi: 7.11.6 2025-04-15 12:32:27 +00:00
Jakob Olsson
9952f6e580 map-controller: 6.3.0.12 2025-04-15 14:06:28 +02:00
Vivek Kumar Dutta
7d0b38b9a7 wifidmd: replace BTMRequest() with ClientSteer() 2025-04-15 17:33:38 +05:30
Janusz Dziedzic
3a503ea955 libwifi: 7.11.5 2025-04-15 11:28:14 +00:00
Vivek Kumar Dutta
13cac21c60 bbfdm: removed stunc and xmpp from cwmp critical services list 2025-04-15 16:47:02 +05:30
Amin Ben Romdhane
f251701534 qosmngr: Updated log level 2025-04-15 11:16:46 +00:00
Vivek Kumar Dutta
5b882870c9 icwmp: register xmpp as cwmp only 2025-04-15 11:09:53 +00:00
Vivek Kumar Dutta
25f3acf2fd wifidmd: Fix AssociatedDevice for MLD supported DUTs 2025-04-15 11:09:53 +00:00
Suvendhu Hansa
c1fe6b05a6 xmpp: optimize xmpp uci map 2025-04-15 11:09:53 +00:00
Jakob Olsson
4ee9169771 hostmngr: 1.2.19 2025-04-15 13:03:11 +02:00
Amin Ben Romdhane
7172201515 bbfdm: install ruleng scripts 2025-04-15 11:32:55 +02:00
Erik Karlsson
c366451def logmngr: fix creation of logrotate configuration 2025-04-15 09:28:39 +02:00
Erik Karlsson
5874a005c6 logmngr: install logread to /sbin
It was being installed to /usr/sbin as workaround for conflict with
logd package. The correct solution is to not select logd package.
2025-04-15 09:22:16 +02:00
Vivek Dutta
ffab63b86f bbfdm: ruleng script to refresh reference_db 2025-04-15 06:41:24 +00:00
Janusz Dziedzic
929dd55d21 libwifi: 7.11.4 2025-04-14 17:23:56 +00:00
Reidar Cederqvist
3636e217a6 sulu-builder: add qrencode dependency for generating wifi qr code 2025-04-14 15:39:50 +02:00
Vivek Kumar Dutta
b99d4413dc obuspa: remove usages of stdout/stderr from init 2025-04-14 14:21:42 +05:30
Andreas Gnau
f2f6f6b787 map-controller: Allow setting Wi-Fi SSID from board.json
OpenWrt enables setting default Wi-Fi settings in board.json using
board.d scripts. Read from board.json for each band or all bands,
otherwise fall back to the old method of generating the SSID and key.

The following can be specified:

* WiFI SSID
* encryption mode
* key
* number of MAC addresses (not implemented in this commit)

Signed-off-by: Andreas Gnau <andreas.gnau@iopsys.eu>
2025-04-14 06:59:21 +00:00
Suvendhu Hansa
f2ea1049e0 firewallmngr: fix duplicate rule entries 2025-04-12 08:24:33 +00:00
Mohd Mehdi
ba837ff98a qosmngr: unified service and datamodel daemon 2025-04-11 14:47:43 +00:00
Amin Ben Romdhane
324244d26b wifidmd: Refactor 'wifidmd' into a unified daemon 2025-04-11 14:35:11 +00:00
Amin Ben Romdhane
0cded2b974 bbfdm: 1.15.16 2025-04-11 16:34:26 +02:00
Amin Ben Romdhane
27f0f7454f decollector: 6.2.0.2 2025-04-11 16:10:32 +02:00
Marina Maslova
3ff559907b libwifi: 7.11.3 2025-04-11 18:01:50 +04:00
Marina Maslova
d73f8975cf hostmngr: 1.2.18 2025-04-11 17:58:43 +04:00
Jakob Olsson
3ddf258a74 map-agent: 6.3.4.3 2025-04-11 11:50:44 +02:00
Jakob Olsson
cd2c817223 map-controller: 6.3.0.11: add option to provision bridge 2025-04-11 11:43:53 +02:00
Jakob Olsson
370c5938aa map-agent: 6.3.4.2 2025-04-11 09:12:28 +02:00
Filip Matusiak
ddd88a894c map-agent: 6.3.4.1 2025-04-10 14:27:13 +02:00
Vivek Kumar Dutta
459f2571ec wifidmd: 1.0.35 2025-04-10 16:25:53 +05:30
Vivek Kumar Dutta
c555b48d16 tr143: support https url in download diagnostics 2025-04-10 15:38:25 +05:30
Vivek Kumar Dutta
6a0f353c93 hostmngr: removed remote ref in AssociatedDevice 2025-04-10 12:58:37 +05:30
Amin Ben Romdhane
21e742d9f7 sysmngr: Show Processes by 'PID', 'Memory' or 'CPU_Time' 2025-04-10 03:59:07 +00:00
Janusz Dziedzic
f4654e78c5 libwifi: 7.11.2 2025-04-09 13:55:49 +00:00
Reidar Cederqvist
72c3e3c8ce sulu: add device picture on the dashboard 2025-04-09 15:46:42 +02:00
Janusz Dziedzic
1adf7b669f libwifi: 7.11.1 2025-04-09 07:00:29 +00:00
Amin Ben Romdhane
39ec8635c3 ieee1905: 8.7.5 2025-04-08 15:02:03 +02:00
Amin Ben Romdhane
5a3fbb7902 wifidmd: 1.0.34 2025-04-08 14:21:02 +02:00
Amin Ben Romdhane
5ecc3945f9 netmngr: 1.1.6 2025-04-08 14:20:52 +02:00
Amin Ben Romdhane
8a52715ad1 dhcpmngr: 1.0.6 2025-04-08 14:20:36 +02:00
Amin Ben Romdhane
8333a499d0 bbfdm: 1.15.15 2025-04-08 09:30:20 +02:00
Vivek Kumar Dutta
941a46dae6 icwmp: Fix firewall rule on reload 2025-04-07 19:17:49 +05:30
Amin Ben Romdhane
86d7bf8c67 sysmngr: show only top N process 2025-04-05 15:40:21 +05:30
Reidar Cederqvist
4ef5d86feb Sulu version 4.1.0 - dark mode 2025-04-04 16:52:14 +02:00
Vivek Kumar Dutta
c97637fd5f wifidmd: Fix SSID management for wifi7 duts 2025-04-04 18:58:18 +05:30
Suvendhu Hansa
033613f999 icwmp: Support to whitelist Connection Request IPs 2025-04-04 12:30:55 +00:00
Reidar Cederqvist
b18f6dc39c update sulu to latest devel 2025-04-03 10:40:48 +02:00
Janusz Dziedzic
5f5b171d5a map-agent: 6.3.4.0 2025-04-03 07:18:22 +00:00
Janusz Dziedzic
469e9d1196 libwifi: 7.11.0 2025-04-02 09:28:52 +00:00
Sukru Senli
53b824d2e0 ethmngr: filter out wireless interfaces from ethernet hotplug event generation 2025-03-31 09:56:38 +00:00
Reidar Cederqvist
4df9b5ab94 update sulu-core to latest devel and align sulu-builder and sulu-core versions 2025-03-31 10:57:53 +02:00
Sukru Senli
130cf8fd53 ethmngr: add ruleng ethport recipe 2025-03-30 14:47:05 +02:00
Markus Gothe
bfd327ca02 Revert "ethmngr: add ruleng ethport recipe and generate deprecated ubus event"
This reverts commit 1d24d5c4f7.
2025-03-30 14:47:00 +02:00
Rahul Thakur
bcea816742 ethmngr: add ruleng recipe for ethport hotplug event
hotplug event generated now from ruleng recipe based on the
network.device event
2025-03-30 14:46:54 +02:00
Markus Gothe
ee6a27dc76 Revert "ethmngr: removed deprecated ethport hotplug handler"
This reverts commit dcfa48d1f7.
2025-03-30 14:46:46 +02:00
Markus Gothe
78eb76e913 Revert "ethmngr: generate ethport event using ruleng"
This reverts commit 56d352fc83.
2025-03-30 14:46:28 +02:00
Erik Karlsson
21c3354b31 sysmngr: remove deprecated hw.board.hasWifi use 2025-03-28 11:36:46 +01:00
Vivek Kumar Dutta
dcfa48d1f7 ethmngr: removed deprecated ethport hotplug handler 2025-03-28 09:39:34 +05:30
Vivek Kumar Dutta
56d352fc83 ethmngr: generate ethport event using ruleng 2025-03-27 17:48:22 +05:30
Vivek Kumar Dutta
56093ef532 icwmp: Fix duplicate events in Inform 2025-03-27 11:26:29 +05:30
Jakob Olsson
60f1d0edbf map-agent: 6.3.3.9 2025-03-25 14:18:40 +01:00
Jakob Olsson
c2021e765a map-controller: 6.3.0.10 2025-03-25 13:44:26 +01:00
Anjan Chanda
83c31acbc7 map-controller: 6.3.0.9 2025-03-25 10:57:45 +01:00
Vivek Kumar Dutta
9380411fa6 qosmngr: Fix regression in generating default classify rules 2025-03-24 13:39:08 +00:00
Vivek Kumar Dutta
2a47619b32 logmngr: multiple fixes
- Fix regression in generating log-rotate policy
- Fix logread output in case of file rotation
2025-03-24 18:37:58 +05:30
Vivek Kumar Dutta
f2c665a0cf logmngr: Fix remote logging 2025-03-24 16:45:38 +05:30
Erik Karlsson
1dca89c130 logmngr: use busybox klogd alongside fluent-bit 2025-03-21 22:24:29 +01:00
Erik Karlsson
63d3ca365b logmngr: remove fluent-bit kmsg support
Also remove apply_config_file which is dead code.
2025-03-21 17:48:39 +01:00
Erik Karlsson
fa4f08aa29 Revert "fluent-bit: enable kmsg plugin"
This reverts commit 01d320300e.
2025-03-21 17:48:39 +01:00
Jakob Olsson
858dd78ff7 map-controller: 6.3.0.4 2025-03-21 16:58:47 +01:00
Reidar Cederqvist
eb0e19355d sulu: performance optimizations 2025-03-21 15:38:20 +01:00
Suvendhu Hansa
4015982a87 gateway-info: Added enable option 2025-03-20 13:20:58 +00:00
Jakob Olsson
0b6e35e36b map-controller: 6.3.0.3 2025-03-20 13:57:07 +01:00
Vivek Kumar Dutta
cca03dc995 bbfdm: optimize get calls 2025-03-20 18:19:19 +05:30
Vivek Kumar Dutta
3d69811bf4 bbfdm: Fix instances in Security object 2025-03-20 18:15:56 +05:30
Vivek Kumar Dutta
5a7e44cd04 logmngr: include kernel logs 2025-03-20 18:11:36 +05:30
Anjan Chanda
b883f2b310 mapcontroller: uci-defaults: adapt 'sta_steering' config 2025-03-20 12:25:15 +01:00
Vivek Kumar Dutta
97a845fda2 self-diagnostics: compile logs in case of failure 2025-03-20 14:48:54 +05:30
Vivek Kumar Dutta
21cdf07e54 sysmngr: removed refresh handler for ProcessStatus 2025-03-20 10:13:53 +05:30
Vivek Kumar Dutta
13094c3a1b obuspa: Fix duplicate SecuredRole entry 2025-03-20 10:11:39 +05:30
Vivek Kumar Dutta
d3cb6a70da icwmp: added migration script for gateway-info options 2025-03-20 10:10:54 +05:30
Vivek Kumar Dutta
19570e553d icwmp: disable cpe GetRPCMethods 2025-03-19 22:05:30 +05:30
Vivek Kumar Dutta
50e2add3ab swmodd: updated root path to /apps 2025-03-19 16:20:51 +00:00
Vivek Kumar Dutta
e33340ea8d sysmngr: prepone init 2025-03-19 21:46:29 +05:30
Vivek Kumar Dutta
6b882610c2 ieee1905: updated default dm fallback values 2025-03-19 18:53:00 +05:30
Gouri Natarajan
383dedb443 self-diagnostics: add backhaul info 2025-03-19 12:28:08 +00:00
Vivek Kumar Dutta
a8a2066675 usermngr: 1.3.6 2025-03-19 17:18:14 +05:30
Erik Karlsson
73dfc49647 qosmngr: avoid potential race condition
Wait for background task to finish before reloading in the foreground.
2025-03-19 09:51:29 +01:00
Vivek Kumar Dutta
083cbd7b56 ddnsmngr: Fix duplicate update 2025-03-19 09:26:12 +05:30
Amin Ben Romdhane
e87bcbb819 map-agent: hotplug: map-dynamic-backhaul: Refactor port filtering and bridge detection logic 2025-03-18 14:45:14 +00:00
Reidar Cederqvist
f8561996ab sulu: update usp-js to version 0.4.11 2025-03-18 15:26:07 +01:00
Vivek Kumar Dutta
01d320300e fluent-bit: enable kmsg plugin 2025-03-18 19:34:59 +05:30
Amin Ben Romdhane
3faecd3979 bbfdm: 1.15.12 2025-03-18 13:03:08 +01:00
Amin Ben Romdhane
984962e34e bulkdata: Update JSON service 2025-03-18 12:48:25 +01:00
Filip Matusiak
6140bfa09c map-agent: 6.3.3.8 - add AGENT_UNASSOC_STA_CONT_MONITOR 2025-03-18 10:59:34 +00:00
Mohd Mehdi
2cbb433cbd qosmngr: use procd task for qos initialization 2025-03-18 07:53:44 +00:00
Janusz Dziedzic
c676cde1fb libwifi: 7.10.9 2025-03-17 18:17:22 +00:00
Markus Gothe
363c2ff155 ponmngr: Add support for PLOAM password. 2025-03-17 15:30:07 +01:00
Reidar Cederqvist
2a2650b43e sulu: use latest version of usp-js 2025-03-17 11:03:53 +01:00
Vivek Kumar Dutta
a5c13c4ae7 bbfdm: updated log level 2025-03-17 12:16:59 +05:30
Janusz Dziedzic
bf40d37745 libwifi: 7.10.8 2025-03-14 13:18:21 +00:00
George Yang
8889d06568 dectmngr: Do not install DCX81 firmware for Airoha platform
- Update the makefile
- Remove the .bin file for Airoha
2025-03-13 15:33:35 +00:00
Marina Maslova
e7d2f54bda libwifi: 7.10.7 2025-03-13 18:39:39 +04:00
Vivek Kumar Dutta
1e31d2accd bbfdm: 1.15.10 2025-03-13 19:10:09 +05:30
Sukru Senli
1e08854dce sulu-builder: update user 'user' ACL 2025-03-13 12:49:01 +00:00
Amin Ben Romdhane
cb27d96fe6 bbfdm: Increase ubus timeout 2025-03-13 13:36:34 +01:00
Vivek Kumar Dutta
943667adc6 bbfdm: 1.15.8
- Added a config option to force recompile of datamodel microservices
- Use service_name from service json for registration
2025-03-13 16:10:08 +05:30
Vivek Kumar Dutta
89b2c6ab19 udpecho: assign priority to dm plugin 2025-03-13 12:21:24 +05:30
Vivek Kumar Dutta
760cd38113 twamp: assign priority to dm plugin 2025-03-13 12:20:44 +05:30
Vivek Kumar Dutta
1abc312d2c tr471: assign priority to dm plugin 2025-03-13 12:20:14 +05:30
Vivek Kumar Dutta
09abf6d6b1 tr143: assign priority to dm plugin 2025-03-13 12:19:30 +05:30
Vivek Kumar Dutta
fa203d73e0 stunc: assign priority to dm plugin 2025-03-13 12:17:30 +05:30
Vivek Kumar Dutta
880741d8c3 self-diagnostics: assign priority to dm plugin 2025-03-13 12:16:55 +05:30
Vivek Kumar Dutta
42bd6390b5 qosmngr: assign priority to dm plugin 2025-03-13 12:16:02 +05:30
Vivek Kumar Dutta
c9856f2a5b port-trigger: assign priority to dm plugin 2025-03-13 12:15:14 +05:30
Vivek Kumar Dutta
c086f72400 packet-capture-diagnostics: assign priority to dm plugin 2025-03-13 12:11:57 +05:30
Vivek Kumar Dutta
a50c380722 logmngr: assign priority to dm plugin 2025-03-13 12:11:12 +05:30
Vivek Kumar Dutta
2755d6be1c icwmp: assign priority to dm plugin 2025-03-13 12:07:24 +05:30
Vivek Kumar Dutta
359db9ddc3 hostmngr: assign priority to dm plugin 2025-03-13 12:06:49 +05:30
Vivek Kumar Dutta
e4f3daf1ed dnsmngr: assign priority to dm plugin 2025-03-13 12:05:59 +05:30
Vivek Kumar Dutta
557ea195ba bridgemngr: assign priority to plugins 2025-03-13 12:05:14 +05:30
Vivek Kumar Dutta
1c14d9f652 bbfdm: option to assign priority between plugins 2025-03-13 12:03:06 +05:30
Mohd Husaam Mehdi
b8ebda638c parentalcontrol: do not add rule for web traffic directed to self
* this is not necessary for the functioning of urlfilter, only DNS
  traffic directed towards the device should be intercepted
* secondly, this is causing problems sometimes where DNS and HTTP
  traffic cannot flow if a large file (9MB tested) is downloaded
  from the device (for example, a urlbundle file), the reason for
  this is not known yet, but the fix is to not intercept web
  traffic directed to the DUT
2025-03-13 11:27:16 +05:30
Mohd Husaam Mehdi
db089a3920 parentalcontrol: only check urlbundle enable to download bundle 2025-03-12 23:53:38 +05:30
Jakob Olsson
4110c22f64 map-agent: 6.3.3.7 2025-03-12 16:51:10 +01:00
Vivek Kumar Dutta
5b07fcce33 swmodd: 2.5.25 2025-03-12 16:55:34 +05:30
Vivek Kumar Dutta
2219f2efba sulu: Enable SecureRole for admin ACL 2025-03-12 11:33:27 +05:30
Meng
ba3b00c784 obuspa: Support ControllerTrust.SecuredRoles
Patch for the obuspa:
- Add DM_SECURE flag in usp_api.h.
- Register Device.LocalAgent.ControllerTrust.SecuredRoles with Validate_SecuredRoles().
- Implement DEVICE_CTRUST_IsControllerSecured() to check controller trust.
- Update DATA_MODEL_GetParameterValue() and group_get_vector functions to return
  an empty string for secure parameters when the controller is not secured.

Updated usp_utils.sh to to add SecuredRole from role ACL files
2025-03-12 11:33:27 +05:30
Vivek Kumar Dutta
9598258993 usermngr: Remove ash from SupportedShell 2025-03-12 11:24:18 +05:30
Amin Ben Romdhane
32ab2eb2cc self-diagnostics: 1.0.14 2025-03-12 04:56:22 +00:00
Vivek Kumar Dutta
63c27601e5 gateway-info: documentation and CI pipeline 2025-03-12 09:11:12 +05:30
Suvendhu Hansa
f2d4b6ff7d obuspa: Support to DHCP on-boarding via Option 125 2025-03-12 03:35:28 +00:00
Marina Maslova
e945226956 libwifi: 7.10.6 2025-03-11 20:22:24 +04:00
Jakob Olsson
9a7ff0bbf2 map-agent: 6.3.3.6 2025-03-11 15:27:25 +01:00
Janusz Dziedzic
97830621a6 wifimngr: 17.5.9 2025-03-11 13:51:51 +00:00
Janusz Dziedzic
1c77fb2e76 libwifi: 7.10.5 2025-03-11 12:47:05 +00:00
Jakob Olsson
67c4a3c317 map-agent: 6.3.3.5 2025-03-11 10:37:38 +01:00
Vivek Dutta
7f17359913 libvoice-airoha: Updated uci-default script
Uci default script should not commit the uci, as its committed by its
handler/runner latter on, this is required to avoid race conditions.
2025-03-11 08:59:28 +00:00
Vivek Kumar Dutta
b6212b90d8 owsd: Updated uci-default script 2025-03-11 08:00:40 +00:00
Suvendhu Hansa
74cbe1062a gateway-info: Added support for USP events 2025-03-11 07:42:11 +00:00
Vivek Kumar Dutta
2be4eeebb7 linux-pam: 1.7.0 2025-03-11 11:23:45 +05:30
Vivek Kumar Dutta
a49407ad79 passwdqc: 2.0.3 2025-03-11 11:23:02 +05:30
Reidar Cederqvist
24737321b0 sulu: update sulu to latest version 2025-03-10 16:09:07 +01:00
Janusz Dziedzic
3a72a7ee61 libwifi: 7.10.4 2025-03-10 15:04:34 +00:00
Vivek Kumar Dutta
d9b6136916 swmodd: 2.5.24 2025-03-10 17:58:48 +05:30
Vivek Dutta
537e1758c3 ieee1905: remove uci commit from uci-default 2025-03-10 08:28:51 +00:00
Vivek Kumar Dutta
c6bbe14c6f icwmp: Fix operate syntax for diagnostics 2025-03-10 08:39:18 +05:30
Vivek Kumar Dutta
8af265a689 bridgemngr: Fix wifi ubus usages 2025-03-10 08:32:34 +05:30
Vivek Kumar Dutta
193a6cf502 icwmp: support for mutual authentication 2025-03-09 15:02:54 +05:30
Markus Gothe
d6c148f7e3 dectmngr: Support DECT FW per target
Add support for installing default DECT FW per target. This solves the need
to be able to have different default FW for different hardware architectures.

For Airoha we will update the DECT FW to DSPG 4.13 build 21 RC1.
2025-03-07 15:28:41 +00:00
Amin Ben Romdhane
afdc0006b5 icwmp: 9.8.36 2025-03-07 14:53:33 +01:00
Suvendhu Hansa
2cb0f6e159 obuspa,gateway-info: Support GatewayInfo USP params 2025-03-07 13:42:51 +00:00
Suvendhu Hansa
db72ee376e obuspa: Fix raise condition in dhcp Controller setup 2025-03-07 11:36:43 +00:00
Jakob Olsson
2bbeb83eb2 map-agent: 6.3.3.4 2025-03-07 10:27:18 +01:00
Jakob Olsson
f718adf692 map-controller: 6.3.0.2 2025-03-07 10:27:18 +01:00
Vivek Kumar Dutta
2aaf56ac6d swmodd: added datamodel dependency on swmod ubus 2025-03-06 19:17:03 +05:30
Suvendhu Hansa
426cc077e0 obuspa: controller provisioning via dhcp 2025-03-06 13:42:18 +00:00
Janusz Dziedzic
879e549581 libwifi: 7.10.3 2025-03-06 13:38:52 +00:00
Amin Ben Romdhane
78f6198d0a sysmngr: reduce log verbosity
- Change log level from 4 to 3 to show only error logs
2025-03-06 11:44:29 +01:00
Janusz Dziedzic
6ddaa150b4 wifimngr: 17.5.8 2025-03-06 10:33:22 +00:00
Janusz Dziedzic
9188a99c99 libwifi: 7.10.2 2025-03-06 10:33:22 +00:00
Amin Ben Romdhane
352a56448e userinterface: Fix misplaced closing quote 2025-03-06 10:15:36 +01:00
Jakob Olsson
5c7fea694f map-controller: 6.3.0.1 2025-03-05 16:37:16 +01:00
Vivek Kumar Dutta
5474007dcf swmodd: 2.5.22 2025-03-05 19:23:26 +05:30
Vivek Kumar Dutta
320d155a96 sysmngr: extend keep_config from Download to Activate 2025-03-05 19:13:19 +05:30
Meng
73f91e09db obuspa: add patches/0006-contains-expression.patch 2025-03-05 13:09:57 +00:00
Amin Ben Romdhane
36d2b24bae icwmp: Fix 'M Reboot' event is not sent on firmware upgrade 2025-03-05 11:45:57 +00:00
Janusz Dziedzic
f9010d9ef1 libwifi: 7.10.1 2025-03-05 11:08:01 +00:00
Vivek Kumar Dutta
aeda3280b3 bbfdm: avoid uci commit in uci-defaults 2025-03-05 09:10:42 +00:00
Jakob Olsson
5e3b30daa8 map-agent: 6.3.3.3 2025-03-05 10:05:09 +01:00
Mohd Mehdi
ee2165b184 qosmngr: update rate processing for queue 2025-03-05 06:02:13 +00:00
Vivek Kumar Dutta
1b7fa8ba15 qosmngr: updated uci-default scripts 2025-03-05 10:28:33 +05:30
Vivek Kumar Dutta
052dc52801 parental-control: updated uci-default script 2025-03-05 10:25:42 +05:30
Vivek Kumar Dutta
4373ec21aa obuspc: avoid uci commit in uci-defaults 2025-03-05 10:24:13 +05:30
Vivek Kumar Dutta
892e0f3599 obuspa: avoid uci commit in uci-defaults 2025-03-05 10:22:23 +05:30
Vivek Kumar Dutta
d9a742b734 mcastmngr: avoid uci commit in uci-defaults 2025-03-05 10:20:06 +05:30
Vivek Kumar Dutta
9e1a8de1bd logmngr: avoid uci commit in uci-defaults 2025-03-05 10:18:22 +05:30
Vivek Kumar Dutta
73c8e7eb75 gateway-info: avoid uci commit in uci-defaults 2025-03-05 10:13:15 +05:30
Vivek Kumar Dutta
41ba4fcedc dhcpmngr: avoid uci commit in uci-defaults 2025-03-05 10:10:41 +05:30
Erik Karlsson
b673daf265 swmodd: avoid uci-defaults script failure
Keep uci-defaults script from failing if there are no containers.
2025-03-04 16:09:40 +01:00
Vivek Kumar Dutta
06b9f7eb00 parental-control: 1.1.4 2025-03-04 19:10:00 +05:30
Vivek Kumar Dutta
092026794e netmngr: 1.1.5 2025-03-04 19:07:44 +05:30
Vivek Kumar Dutta
0bc9dd365f bridgemngr: 1.0.12 2025-03-04 19:05:57 +05:30
Vivek Kumar Dutta
f4eb3ec090 icwmp: 9.8.34 2025-03-04 19:04:57 +05:30
Vivek Kumar Dutta
7596b3b4f4 bbfdm: Fix Max instance log and uci list buffer size 2025-03-04 19:01:01 +05:30
Erik Karlsson
d546e1699f sshmngr: enable SFTP by default
Note that the openssh-sftp-server package works together with both
OpenSSH and dropbear
2025-03-04 12:39:23 +00:00
Amin Ben Romdhane
fe4a859af6 bbfdm: 1.15.5 2025-03-04 10:36:37 +01:00
Anjan Chanda
7ecce240d0 map-controller: 6.3.0.0 2025-03-03 17:51:48 +01:00
Jakob Olsson
a8dd08cf33 map-agent: 6.3.3.2 2025-03-03 15:01:05 +01:00
George Yang
9a38439d11 libvoice-airoha: 1.1.2 2025-03-03 14:35:27 +01:00
Jakob Olsson
06c977c39d remove package map-topology 2025-03-03 09:58:29 +01:00
Janusz Dziedzic
1e352925ef wifimngr: 17.5.7 2025-02-28 15:43:24 +00:00
Janusz Dziedzic
9b6a9158af Revert "libwifi: 7.10.1"
This reverts commit fd49d9a203.
2025-02-28 15:41:50 +00:00
Janusz Dziedzic
fd49d9a203 libwifi: 7.10.1 2025-02-28 15:13:01 +00:00
Janusz Dziedzic
093d1b95da libwifi: 7.10.0 2025-02-28 13:51:56 +00:00
Janusz Dziedzic
52ef85a910 libwifi: 8.0.0 2025-02-28 13:31:46 +00:00
Elena Vengerova
ca8f2f91ab libwifi: 7.9.9 2025-02-28 15:49:36 +04:00
Janusz Dziedzic
3553cca81c wifimngr: 17.5.6 2025-02-28 11:44:53 +00:00
Janusz Dziedzic
bdeea206e3 libwifi: 7.9.8 2025-02-28 11:43:21 +00:00
Marina Maslova
34cb916d59 libwifi: 7.9.7 2025-02-28 15:10:37 +04:00
Marina Maslova
5f253a5d5c libwifi: fix en7523 names updated on migration to 7.4 2025-02-28 10:52:37 +00:00
Balalakshmi Arunachalam Rajendran
948f727a0b map-agent: map-topology-discovery: fix the redirection of buildcmdu
Not redirecting caused stdout issues over the serial console.
2025-02-28 09:52:29 +00:00
Vivek Kumar Dutta
7b4be698fc obuspa: Fix overriding of permissions on reboot 2025-02-28 15:14:03 +05:30
Vivek Kumar Dutta
3f079d7543 sulu: Added Firewall in admin ACL 2025-02-28 15:13:15 +05:30
Balalakshmi Arunachalam Rajendran
52d5bf6db6 map-agent: map-topology-discovery: remove redirection of buildcmdu result 2025-02-27 12:45:12 +00:00
Suvendhu Hansa
d80d41a6f6 timemngr: use NTP servers from dhcp option 42 2025-02-27 17:03:21 +05:30
George Yang
4b8d721af8 libvoice-airoha: Fix compiling error for airoha32 because of codec difference 2025-02-27 11:22:01 +01:00
Jakob Olsson
a2b051c773 map-controller: 6.2.3.1 2025-02-27 10:46:41 +01:00
Vivek Kumar Dutta
2aa49112f3 obuspa: Fix full_access assignment 2025-02-27 13:59:04 +05:30
Vivek Kumar Dutta
60b21cb3ce Revert "libvoice-airoha: Update codec list from 2024Q4_Airoha_LTS_SDK"
This reverts commit 55e9299da5.
2025-02-27 12:26:57 +05:30
George Yang
55e9299da5 libvoice-airoha: Update codec list from 2024Q4_Airoha_LTS_SDK 2025-02-26 17:54:36 +01:00
Amin Ben Romdhane
6df78961ab bbfdm: 1.15.4 2025-02-26 17:00:48 +01:00
Janusz Dziedzic
6a65a15b0d wifimngr: 17.5.5 2025-02-26 12:24:51 +00:00
Janusz Dziedzic
2a1f9a00d4 libwifi: 7.9.6 2025-02-26 12:24:51 +00:00
Vivek Kumar Dutta
211de47076 sulu: Align role json files 2025-02-26 12:02:07 +00:00
Vivek Kumar Dutta
af3cf465bc usermngr: Added full_access and Untrusted role 2025-02-26 12:02:07 +00:00
Vivek Kumar Dutta
c1a8c1aa86 obuspa: Updated max CT role
- Updated role json to include role name and instance number
- Removed full_access.json
- Reuse full_access Role from core code
2025-02-26 12:02:07 +00:00
George Yang
08fb82fae4 libvoice-airoha: Fix error caller name in CLIP, REF #16094 2025-02-26 11:11:51 +01:00
Suvendhu Hansa
0c4485ea15 bbfdm: moved GatewayInfo DM to gateway-info 2025-02-26 09:32:03 +05:30
Suvendhu Hansa
064b655fa9 icwmp: move GatewayInfo config to gateway-info package 2025-02-26 09:27:49 +05:30
Suvendhu Hansa
d71d4914d5 gateway-info: 1.0.0
- Updated netmode config to mark wan interface in gwinfo
2025-02-26 09:20:08 +05:30
Jakob Olsson
2a7f21a8f8 map-agent: 6.3.3.1 2025-02-25 17:00:13 +01:00
Erik Karlsson
d720da1852 firewallmngr: add missing "iptables -w" 2025-02-25 14:31:11 +01:00
Erik Karlsson
e9f40eba08 bbfdm: fix shell injection in /etc/firewall.portmap
Rework the script to use iptables-restore instead of eval

(cherry picked from commit cf8350b6b365429aa68f0f957f79eb31bb43e2db)
(cherry picked from commit df87055d04)
2025-02-25 14:13:01 +01:00
Erik Karlsson
3d68c3b9f7 bbfdm: fix shell injection in /etc/firewall.service
Avoid use of eval

(cherry picked from commit 53167364863ef4afc249045fe5dcb510e3ec164d)
(cherry picked from commit 32848d7f69)
2025-02-25 14:12:52 +01:00
Markus Gothe
f5ad0195bc Update iptables rules to use proper locking. 2025-02-25 13:57:50 +01:00
Jakob Olsson
85818a7778 map-agent: 6.3.3.0 2025-02-25 13:14:56 +01:00
Dariusz Iwanoczko
b6e5749b7f fwbank: add copy_config method to fwbank API
Implemented copy_config handler to create and copy a system upgrade backup
2025-02-25 08:53:03 +00:00
Janusz Dziedzic
2a1323bfd0 libwifi: 7.9.5 2025-02-24 16:10:55 +00:00
Vivek Kumar Dutta
0c56d3ab39 bbfdm: minor output fixes 2025-02-24 19:57:34 +05:30
Vivek Kumar Dutta
c59c53aa47 usp-js: Updated allow_partial default to true 2025-02-24 18:43:34 +05:30
Vivek Kumar Dutta
90c3949696 bbfdm: Add multi-ap services in usp critical list 2025-02-24 12:19:41 +05:30
Markus Gothe
14ca35a64b Revert "qosmngr: fix ebtables-extensions dependencies"
This reverts commit c55ab35b14.
2025-02-24 03:18:38 +00:00
Vivek Kumar Dutta
cf148f6c06 ebtables-extensions: 2.0.5 2025-02-24 08:29:28 +05:30
Erik Karlsson
c3e0426c36 gryphon-led-module: remove obsolete commented out test code 2025-02-21 17:04:22 +01:00
Erik Karlsson
c7f3e52f92 gryphon-led-module: clean up package Makefile
Use a more modern approach for building kernel modules
out-of-tree. Remove a lot of unused stuff.
2025-02-21 17:04:22 +01:00
Erik Karlsson
1605577538 gryphon-led-module: fix error handling
The dev_get_drvdata/platform_get_drvdata functions do not return an
error pointer. Use devm_gpiod_get_index to manage GPIO resources. Do
not support obsolete Linux versions. Check the return value of
gpiod_direction_output
2025-02-21 17:04:22 +01:00
Reidar Cederqvist
69ba712cb3 Sulu: update to latest devel 2025-02-21 14:51:31 +00:00
Amin Ben Romdhane
634d40fa01 logmngr: 1.0.9 2025-02-21 15:45:37 +01:00
Amin Ben Romdhane
088ed56c50 icwmp: 9.8.32 2025-02-21 15:44:08 +01:00
Amin Ben Romdhane
d49c758d04 ieee1905: 8.7.3 2025-02-21 15:43:14 +01:00
Amin Ben Romdhane
187492a827 packet-capture-diagnostics: 1.0.3 2025-02-21 15:39:24 +01:00
Amin Ben Romdhane
0a375e6ac4 self-diagnostics: 1.0.13 2025-02-21 15:38:43 +01:00
Amin Ben Romdhane
226c5b4685 obuspa: 9.0.4.8 2025-02-21 15:37:40 +01:00
Amin Ben Romdhane
e72352d7e1 netmngr: 1.1.4 2025-02-21 15:36:08 +01:00
Amin Ben Romdhane
322d80f151 sysmngr: 1.0.17 2025-02-21 15:34:25 +01:00
Amin Ben Romdhane
8e4d3920d9 wifidmd: 1.0.32 2025-02-21 15:32:47 +01:00
Amin Ben Romdhane
241afdc4fd hostmngr: 1.2.15 2025-02-21 15:31:05 +01:00
Amin Ben Romdhane
4ee68f7a84 bbfdm: introduce data model core micro-service and update bbfdmd to use async call to optimize RPCs handling 2025-02-21 15:29:45 +01:00
Janusz Dziedzic
11b13af489 libwifi: 7.9.4 2025-02-21 10:15:00 +00:00
Vivek Kumar Dutta
5abf23d711 Revert "icwmp: fix gateway info race condition"
This reverts commit c118da628d.
2025-02-21 15:08:22 +05:30
Mohd Mehdi
38c7075422 qosmngr: remove unused variable and fix error logs in uci-default 2025-02-21 06:28:14 +00:00
Suvendhu Hansa
dead11036c wifidmd: Remove iwinfo dependency 2025-02-21 10:44:27 +05:30
Markus Gothe
e708d6caec ipt-trigger: Resolve dependecies for Mediatek platform. 2025-02-20 15:14:32 +01:00
Markus Gothe
3a7c4119ff ipt-trigger: Clean up dependencies. 2025-02-20 13:59:21 +01:00
Markus Gothe
b1fc7a09be Update ipt-trigger dependencies. 2025-02-20 11:35:19 +00:00
Janusz Dziedzic
7c0a37c8a8 libwifi: 7.9.3 2025-02-20 09:31:53 +00:00
Mohd Mehdi
bfdd241330 parental-control: add support for Status and Enable 2025-02-20 05:43:09 +00:00
Markus Gothe
cdc8972031 ebtables-extensions: Fix usage of KERNEL_MAKE_FLAGS
KERNEL_MAKE_FLAGS passes arguments to 'make'
and not to the compiler which is probably
what was intended.
2025-02-19 16:25:39 +01:00
Markus Gothe
f668c5cc33 ipt-trigger: Fix usage of KERNEL_MAKE_FLAGS
KERNEL_MAKE_FLAGS passes arguments to 'make'
and not to the compiler which is probably
what was intended.

This solves a compilation issue on the
Broadcom platform.
2025-02-19 16:07:59 +01:00
Erik Karlsson
ed0373f188 libvoice-airoha: 1.1.1 2025-02-19 15:32:51 +01:00
Janusz Dziedzic
74f37ee761 wifimngr: 17.5.4 2025-02-19 13:52:47 +00:00
Janusz Dziedzic
3970668d0e libwifi: 7.9.2 2025-02-19 13:51:05 +00:00
Jakob Olsson
fe833164de map-agent: 6.3.2.4 2025-02-19 13:08:46 +01:00
Erik Karlsson
eca57960a0 libvoice-airoha: set the default transmit and receive gain in the UCI config 2025-02-19 11:01:25 +00:00
Mohd Husaam Mehdi
41c8325aae parental-control: Support BlockHistory 2025-02-19 08:21:58 +00:00
Suvendhu Hansa
c118da628d icwmp: fix gateway info race condition 2025-02-19 06:47:15 +00:00
Suvendhu Hansa
0714c79917 obuspa: Add csv report support in Bulkdata mqtt 2025-02-18 14:01:16 +00:00
Vivek Kumar Dutta
d01f484999 swmodd: 2.5.21 2025-02-17 18:52:13 +05:30
Jakob Olsson
d161ccf816 map-controller: 6.2.3.0 2025-02-17 11:01:21 +01:00
Jakob Olsson
e18da4e996 map-controller: add config option to provision disabled APs 2025-02-17 09:59:25 +00:00
Jakob Olsson
4aca931a23 map-agent: 6.3.2.3 2025-02-14 17:29:54 +01:00
Elena Vengerova
81b0f6e7fe libwifi: 7.9.1 2025-02-14 15:36:50 +04:00
Vivek Kumar Dutta
93873874bb sulu: Fix mqtt acl generation 2025-02-14 12:44:18 +05:30
Vivek Kumar Dutta
88ca4b3011 icwmp: config options to skip datatype check and insecure connect 2025-02-14 12:39:48 +05:30
Amin Ben Romdhane
a3bd6392a1 bbfdm: 1.14.5 2025-02-13 14:47:43 +01:00
Janusz Dziedzic
ed01591374 map-agent: 6.3.2.2 2025-02-13 13:08:17 +00:00
arbala
c48d4923d6 map-controller: 6.2.2.3 2025-02-12 16:45:58 +01:00
Erik Karlsson
3dbc47b54f gryphon-led-module: turn LED off on system shutdown and module unload 2025-02-12 13:55:21 +01:00
Anjan Chanda
d6ef40fd0f decollector: 6.2.0.1 2025-02-12 12:20:24 +01:00
arbala
b94dbcdbdf map-agent: 6.3.2.1 2025-02-11 17:00:01 +01:00
Vivek Kumar Dutta
d0be4f8056 mcastmngr: Fix instance add/del operations 2025-02-11 19:30:46 +05:30
Suvendhu Hansa
5e392d0832 wifidmd: Fix SSID instance deletion 2025-02-11 13:56:02 +00:00
Vivek Kumar Dutta
acc92dfb1f obuspa: Config option to override CT roles with fw default roles 2025-02-11 19:24:02 +05:30
Erik Karlsson
5e13161b70 Fix out-of-tree Broadcom kernel module build
The inclusion of bcm-kernel-toolchain.mk cannot be conditional since
CONFIG_TARGET_brcmbca is not defined when package metadata is being
generated. Instead make it optional in case broadcom feed is absent.
2025-02-11 10:26:44 +01:00
Amin Ben Romdhane
20034609e0 wifidmd: 1.0.29 2025-02-10 20:16:33 +01:00
Anjan Chanda
58ddcd7499 decollector: 6.2.0.0 2025-02-10 17:18:13 +01:00
Suvendhu Hansa
81755b83ad dnsmngr: optimize dns-sd advertise object 2025-02-10 12:24:20 +00:00
Vivek Kumar Dutta
b96e7077fc icwmp: 9.8.30 2025-02-10 17:33:51 +05:30
Jakob Olsson
1b0a792b56 map-controller: 6.2.2.2 2025-02-10 12:29:58 +01:00
Vivek Kumar Dutta
4e093e59f3 obuspa: Fix random delay in get calls 2025-02-09 11:42:45 +05:30
Vivek Kumar Dutta
9400526e47 wifidmd: Use dump2 output for Network.SSID. table 2025-02-08 16:17:29 +05:30
Mohd Mehdi
a2733b66b7 parental-control: 1.1.0 2025-02-08 06:15:20 +00:00
Markus Gothe
40251b2371 ponmngr: Refactorize PtP-mode detection. 2025-02-07 16:39:00 +01:00
Markus Gothe
980779a583 Don't start ponmngr microservice in PtP-mode. 2025-02-07 15:55:58 +01:00
Jakob Olsson
ad31d21380 map-agent: 6.3.2.0 2025-02-07 12:18:24 +01:00
Anjan Chanda
525b56ebc5 ieee1905: 8.7.2 2025-02-07 09:59:20 +01:00
Janusz Dziedzic
abc15029e6 wifimngr: 17.5.3 2025-02-05 19:17:54 +00:00
Janusz Dziedzic
d992340d98 libwifi: 7.9.0 2025-02-05 17:20:39 +00:00
Jakob Olsson
e5fa525364 map-controller: 6.2.2.1 2025-02-05 16:59:37 +01:00
Marina Maslova
39622c277c map-agent: 6.3.1.2 2025-02-05 18:59:53 +04:00
Vivek Kumar Dutta
98a6c9bd62 icwmp: faultstring improvements 2025-02-05 19:29:55 +05:30
Vivek Kumar Dutta
409cecd943 sulu: Fix admin acl for ParentalControl 2025-02-05 17:37:07 +05:30
Vivek Kumar Dutta
54c92d5b42 bbfdm: 1.14.4
- Fix kill sequence of bbfdm services
- Removed support of BBF_CONFIGMNGR_SCRIPT_BACKEND
- Removed support of BBF_MAX_OBJECT_INSTANCES
- Enabled debug release
2025-02-05 17:26:58 +05:30
Jakob Olsson
2ef97edd43 map-agent: 6.3.1.1 2025-02-05 11:45:40 +01:00
Vivek Kumar Dutta
e19c743888 wifidmd: Fix 80+80MHz in OperatingChannelBandwidth 2025-02-05 14:51:59 +05:30
Roman Azarenko
81b5ade110 self-diagnostics: 1.0.12
- Fix saving model and serial number for report filename

Fixes: b0049df366 ("self-diagnostics: 1.0.10")
2025-02-05 03:24:58 +00:00
Jakob Olsson
c0cfca286e map-controller: 6.2.2.0 2025-02-04 16:51:15 +01:00
Jakob Olsson
584b0b9721 map-agent: 6.3.1.0 2025-02-04 16:48:04 +01:00
Jakob Olsson
d5634eb756 ieee1905: 8.7.0 2025-02-04 16:48:04 +01:00
Vivek Kumar Dutta
38304c4d90 parental-control: Fix segfault with logs 2025-02-04 12:52:11 +05:30
Janusz Dziedzic
b92064f72b ieee1905: add arping dependency 2025-02-03 09:22:30 +00:00
Vivek Kumar Dutta
38814a8f89 sulu: Optimize sulu setup 2025-02-03 10:03:17 +05:30
Vivek Kumar Dutta
9d5ff37aca wifidmd: Optimize SetSSID operate cmd 2025-02-02 14:38:17 +05:30
Vivek Kumar Dutta
68dec1aa1b obuspa: Fix max controller definition 2025-02-02 11:02:13 +05:30
Markus Gothe
f3bbafc15c libethernet: 7.2.117 2025-02-01 14:06:32 +01:00
Janusz Dziedzic
1789bd5afd wifimngr: 17.5.2 2025-01-31 16:27:29 +00:00
arbala
8e5bbbd37f remove use of cat for map-backhaul file 2025-01-31 15:20:38 +00:00
Amin Ben Romdhane
95bd27f079 bbfdm: 1.14.3 2025-01-31 15:09:37 +01:00
Vivek Kumar Dutta
7a9cd965a0 usermngr: 1.3.3 2025-01-31 16:20:30 +05:30
Vivek Kumar Dutta
67673fa604 tr104: package specific vendor extension 2025-01-31 15:42:54 +05:30
Vivek Kumar Dutta
9f54857be0 timemngr: package specific vendor extension 2025-01-31 14:25:27 +05:30
Vivek Kumar Dutta
a733e610b4 qosmngr: package specific vendor extension 2025-01-31 14:04:28 +05:30
Vivek Kumar Dutta
f48ada800e obuspa: package specific vendor extension 2025-01-31 13:11:20 +05:30
Vivek Kumar Dutta
868785688e netmngr: package specific vendor extension 2025-01-31 13:00:22 +05:30
Vivek Kumar Dutta
e9ccbaa772 ethmngr: package specific vendor extension 2025-01-31 12:47:24 +05:30
Janusz Dziedzic
0b6b0e6ca2 wifimngr: 17.5.1 2025-01-30 14:47:15 +00:00
Janusz Dziedzic
47e0ecff71 libwifi: 7.8.9 2025-01-30 14:45:44 +00:00
Reidar Cederqvist
3123202381 SULU: update to version 4.0.4 ready for beta1 2025-01-30 15:27:25 +01:00
Jakob Olsson
9a1861aeb2 map-controller: 6.2.1.0 2025-01-30 15:19:28 +01:00
Jakob Olsson
bba41922cc ieee1905: 8.6.5 2025-01-30 15:18:33 +01:00
Vivek Kumar Dutta
373611b687 mcastmngr: package specific vendor extn 2025-01-30 11:24:45 +00:00
Vivek Kumar Dutta
9576104e83 bridgemngr: package specific vendor extn 2025-01-30 11:24:45 +00:00
Vivek Kumar Dutta
57f14e5e58 parental-control: Support to define vendor extension 2025-01-30 11:24:45 +00:00
Vivek Kumar Dutta
d51a6fe3c6 bbfdm: Support to handler vendor extensions 2025-01-30 11:24:45 +00:00
Jakob Olsson
05b0f91ae0 ieee1905: 8.6.4 2025-01-30 10:37:09 +01:00
Jakob Olsson
aea7fe15e6 map-controller: 6.2.0.0 2025-01-30 10:36:26 +01:00
Jakob Olsson
c6c5e53dc8 map-agent: 6.3.0.0 2025-01-30 10:35:03 +01:00
Vivek Kumar Dutta
03d6f8ab44 icwmp: 9.8.28 2025-01-30 09:59:29 +05:30
Suvendhu Hansa
06ad490dd8 qosmngr: fix unnamed uci section usages 2025-01-30 09:35:33 +05:30
Vivek Kumar Dutta
439e1ac346 wifidmd: Align with mld ubus object names 2025-01-29 19:03:02 +05:30
Vivek Kumar Dutta
d62639e761 wifidmd: Updated dependency list 2025-01-29 13:16:14 +05:30
Janusz Dziedzic
a1569f010d map-agent: airoha simplify mld_prefix 2025-01-28 16:14:31 +00:00
Janusz Dziedzic
a513907df7 libwifi: 7.8.8 2025-01-28 16:14:07 +00:00
Suvendhu Hansa
2e9942589a qosmngr: support percentage ShapingRate 2025-01-28 13:56:17 +00:00
Reidar Cederqvist
6d6962e02e sulu: align with vendor extension update 2025-01-28 11:49:07 +00:00
Janusz Dziedzic
4ded4e8708 map-agent: 6.2.3.13 2025-01-28 11:02:08 +00:00
Janusz Dziedzic
d48a389d86 wifimngr: 17.5.0 2025-01-28 11:02:08 +00:00
Vivek Kumar Dutta
adcd7faafc bbfdm: Rename default Vendor extension prefix to X_IOWRT_EU 2025-01-28 16:11:38 +05:30
Amin Ben Romdhane
2acea2c6dd bbfdm: Introduce a new libbbfdm-api library version 2 2025-01-28 09:16:30 +00:00
Janusz Dziedzic
b8fc40e336 libwifi: 7.8.7 2025-01-28 07:31:26 +00:00
Markus Gothe
86d9d8721b libethernet: econet: Fix ifstats for broadcast and multicast. 2025-01-27 15:05:06 +01:00
Janusz Dziedzic
f031977f41 map-agent: add openssl-util/ebtables deps 2025-01-27 11:40:07 +00:00
Jakob Olsson
87a782f70e map-controller: 6.1.2.21 2025-01-27 10:54:05 +01:00
Vivek Kumar Dutta
f293c57de0 obuspa: Fix unique key search 2025-01-24 19:23:12 +05:30
Markus Gothe
9f354e1294 ebtables-extensions: Fix building of kernel modules.
Needs headers to be copied so we can build all files.
2025-01-24 14:38:19 +01:00
Elena Vengerova
44527f36a8 wifimngr: 17.4.9 2025-01-24 17:15:49 +04:00
Elena Vengerova
0d3f63ccda libwifi: 7.8.6 2025-01-24 16:44:06 +04:00
Marina Maslova
8839edb8f3 mapagent: set mld_prefix to 'mld_bss' for airoha 2025-01-24 16:34:04 +04:00
Marina Maslova
f8a3b236aa map-agent: 6.2.3.12 2025-01-24 16:30:02 +04:00
Erik Karlsson
c55ab35b14 qosmngr: fix ebtables-extensions dependencies
They should not be included on Broadcom. It leads to build failures.
2025-01-24 12:13:39 +00:00
Markus Gothe
b5397361d0 libethernet: econet: Add PON support. 2025-01-24 13:09:20 +01:00
Marina Maslova
15f4bc772c wifimngr: 17.4.8 2025-01-24 15:19:21 +04:00
Filip Matusiak
b97c158e53 ieee1905: 8.6.3
CI: fix run_compile_test dependency issue
map: align return value of tlv_validate_multi() with tlv_validate()
2025-01-24 11:00:30 +01:00
Vivek Kumar Dutta
b727004b4a ebtables-extensions: 2.0.4 2025-01-24 09:09:46 +05:30
Markus Gothe
a81e572f00 ebtables-extensions: Update naming convention.
Use a similiar naming convention as iptables
kernel modules.
2025-01-24 04:30:47 +01:00
Markus Gothe
e1c819724f libethernet: Fix detection of 'ae_wan' WAN-interface. 2025-01-23 14:14:46 +01:00
Vivek Kumar Dutta
e75042bfe5 libqos: Prevent going out of an array 2025-01-23 16:14:23 +05:30
Markus Gothe
da50843b37 mcastmngr: Fix snooping stats. 2025-01-23 09:28:31 +00:00
Suvendhu Hansa
ad43f26119 ethmngr: Config option to expose legacy ethernet object 2025-01-23 14:50:26 +05:30
Vivek Kumar Dutta
b1110c426b periodicstats: 1.5.16 2025-01-23 13:29:12 +05:30
Vivek Kumar Dutta
27e2c1ef7e ieee1905: Select datamodel plugin as default 2025-01-23 10:46:44 +05:30
Janusz Dziedzic
e7a8dd7683 map-agent: allow enable/disable MLO for airoha 2025-01-22 15:45:39 +00:00
Vivek Kumar Dutta
932b345e2b bulkdata: use bbfdm logging 2025-01-22 19:46:04 +05:30
Erik Karlsson
1567b1facb logmngr: make logging more responsive
Flush every second.
2025-01-22 11:45:13 +00:00
Vivek Kumar Dutta
0dfbdd2d02 parental-control: Added loglevel 2025-01-22 17:14:33 +05:30
Reidar Cederqvist
8ba85e2e40 sulu: 4.0.2
- remove unused config options
- add new option to make sulu default WEB UI
2025-01-22 08:07:00 +00:00
Janusz Dziedzic
4e976e89b7 libwifi: 7.8.5 2025-01-22 07:53:47 +00:00
Vivek Kumar Dutta
4203eefe9f ethmngr: Updated log level 2025-01-22 13:02:09 +05:30
Vivek Kumar Dutta
3940dbbd43 ethmngr: support add/del RMONStats objects 2025-01-22 12:52:50 +05:30
Markus Gothe
f84c374a16 mcastmngr: Make sure we don't crash during boot up.
Avoid polluting the syslog with messages regarding
mcastmngr crashing:

procd: Instance mcast::instance1 s in a crash loop 6 crashes, 0 seconds since last crash
2025-01-22 03:04:08 +00:00
Janusz Dziedzic
a116104811 libwifi: 7.8.4 2025-01-21 20:46:03 +00:00
Janusz Dziedzic
8454c2a092 map-agent: 6.2.3.11 2025-01-21 20:05:30 +00:00
Amin Ben Romdhane
e7e6a40d26 wifidmd: 1.0.23 2025-01-21 20:55:31 +01:00
Amin Ben Romdhane
34e6281473 bbfdm: 1.13.6 2025-01-21 20:54:23 +01:00
Markus Gothe
e3c9182bbc bridgemngr: Create centralized ebtables setup.
Create a centralized setup for ebtables.
This is necessary to garantuee the order
of how chains are created.

Right now it provides a 1:1 drop-in
replacement of how things currently work
and no changes are needed in the short term.
2025-01-21 11:38:36 +01:00
Markus Gothe
5cac9516c0 Revert "l2filter: Create centralized ebtables setup."
This reverts commit d67a40b6a0.
2025-01-21 11:15:47 +01:00
Markus Gothe
d67a40b6a0 l2filter: Create centralized ebtables setup.
Create a centralized setup for ebtables.
This is necessary to garantuee the order
of how chains are created.

Right now it provides a 1:1 drop-in
replacement of how things currently work
and no changes are needed in the short term.
2025-01-20 13:54:27 +01:00
Vivek Kumar Dutta
4c0582b1a0 netmngr: Fix IPv6rd object registration 2025-01-20 14:26:19 +05:30
Amin Ben Romdhane
9e7ef97e14 wifidmd: Config option to select DataElements and/or legacy WiFi 2025-01-20 10:09:14 +05:30
Vivek Kumar Dutta
114cbf2cf4 hostmngr: ActiveIPConnections Vendor extension 2025-01-19 21:25:43 +05:30
Vivek Kumar Dutta
c38e706e01 bbfdm: 1.13.5 2025-01-19 21:14:06 +05:30
Vivek Kumar Dutta
ef3ef93a5c netmngr: 1.1.1 2025-01-19 19:42:36 +05:30
Vivek Kumar Dutta
1bb792a893 timemngr: 1.1.5 2025-01-19 19:30:22 +05:30
Vivek Kumar Dutta
8c1e4ef6aa parental-control: 1.0.2 2025-01-17 22:11:22 +05:30
Vivek Kumar Dutta
5cf3c68b96 ethmngr: 3.0.1 2025-01-17 21:46:02 +05:30
Suvendhu Hansa
75a5058d15 sysmngr: Vendor extensions for FileDescriptors and ActiveConnections 2025-01-17 12:25:02 +00:00
Amin Ben Romdhane
930565f528 netmngr: Define a config flag for each Object exposed by libnetmngr 2025-01-17 11:53:59 +01:00
Erik Karlsson
3d3397703f map-agent: hotplug: topology-discovery: fix typo from previous change 2025-01-17 10:52:06 +01:00
Amin Ben Romdhane
fc2b5a2380 bbfdm: Delete OUT_NAME option as it is no longer in use 2025-01-17 10:44:33 +01:00
Janusz Dziedzic
0aa0cb6424 ieee1905: allow to build without TR181 2025-01-17 08:20:11 +00:00
Elena Vengerova
61b74b5bd3 libwifi: 7.8.3 2025-01-16 20:51:52 +04:00
Andreas Gnau
1d8add390d blkpg-part: Add package
Signed-off-by: Andreas Gnau <andreas.gnau@iopsys.eu>
2025-01-16 13:15:00 +01:00
Reidar Cederqvist
797e8cae82 update sulu to latest devel version 2025-01-15 19:05:51 +01:00
Jakob Olsson
083960ee2e map-agent: hotplug: topology-discovery: redirect ubus invokes to dev/null 2025-01-15 12:57:11 +01:00
Vivek Kumar Dutta
3f59dd1c89 libethernet: select required enct_api dependency 2025-01-15 17:22:18 +05:30
Jakob Olsson
823b5936f8 map-controller: 6.1.2.20 2025-01-15 11:23:02 +01:00
Jakob Olsson
368fe2aafa map-controller: 6.1.2.19 2025-01-15 10:19:20 +01:00
Vivek Kumar Dutta
8f1b18e4d4 libethernet: updated airoha depedency 2025-01-14 16:56:57 +00:00
Suvendhu Hansa
f3b6dbfceb ethmngr: unified service datamodel daemon 2025-01-14 16:55:40 +00:00
Jakob Olsson
b5ac400fd6 map-controller: 6.1.2.18 2025-01-14 15:18:42 +01:00
Suvendhu Hansa
ae1189c0d2 logmngr: Fix missing startup logs 2025-01-14 15:43:22 +05:30
Reidar Cederqvist
4e57074351 sulu: update sulu to latest devel
in this commit allplugins are merged into core, and
a new plugin is added for Genexis theme
2025-01-13 15:01:16 +01:00
Janusz Dziedzic
bbd0f972c6 libwifi: 7.8.2 2025-01-13 12:54:59 +00:00
arbala
50ceda4cd4 map-controller: 6.1.2.17 2025-01-10 16:29:06 +01:00
Suvendhu Hansa
0f5f018e99 sysmngr: Added TemperatureStatus DM 2025-01-09 06:28:13 +05:30
Vivek Kumar Dutta
eff826ac39 wifidmd: Remove wifi object from non-wireless devices 2025-01-09 06:17:48 +05:30
Vivek Kumar Dutta
62aed7d759 bbfdm: Updated conflicting API with libeasy 2025-01-09 06:15:47 +05:30
Piotr Kubik
4d72fddff8 iop: feeds_update: Remove script
Script is now stored in top repo.
2025-01-08 12:29:42 +01:00
Janusz Dziedzic
eb18ec1e2b map-controller: 6.1.2.16 2025-01-08 09:31:03 +00:00
Vivek Kumar Dutta
82a5082538 obuspa: Integrate v9.0.4 2025-01-08 09:10:50 +00:00
Andreas Gnau
4ec80e072d questd: Remove
Questd is no longer maintained. Alternative APIs are available to
achieve the same functionality.

Signed-off-by: Andreas Gnau <andreas.gnau@iopsys.eu>
2025-01-07 15:16:20 +00:00
Andreas Gnau
c4f4edd39d iop: Remove KConfig symbols
* CONFIG_TARGET_VERSION has not been used for years, remove it.
* CONFIG_TARGET_CUSTOMER is only used by one feed and is defined there as
  well, so the definition here is not needed, remove it.

Signed-off-by: Andreas Gnau <andreas.gnau@iopsys.eu>
2025-01-07 16:07:48 +01:00
Janusz Dziedzic
b02342e752 libwifi: 7.8.1 2025-01-07 10:15:10 +00:00
Janusz Dziedzic
562733b291 map-controller: 6.1.2.15 2025-01-03 14:39:14 +00:00
Janusz Dziedzic
9f6d7d44ed map-agent: 6.2.3.10 2025-01-03 14:39:14 +00:00
Janusz Dziedzic
84faa7f55b libwifi: 7.8.0 2025-01-03 11:58:42 +00:00
Vivek Kumar Dutta
b939c6988e sysmngr: 1.0.13 2025-01-02 19:07:36 +05:30
Suvendhu Hansa
9a28469028 hostmngr: Added vendor extensions 2025-01-02 17:30:47 +05:30
Vivek Kumar Dutta
64123c0f62 ethmngr: Support for Interface Stats Reset 2025-01-02 15:11:47 +05:30
Vivek Kumar Dutta
923a3e2f08 firewallmngr: use name option as instance marker 2025-01-02 14:00:11 +05:30
Suvendhu Hansa
c92e073ec5 periodicstats: unified daemon + datamodel 2025-01-02 06:33:46 +00:00
Suvendhu Hansa
6cdabddc23 bulkdata: Fix random crashes 2024-12-27 09:53:53 +00:00
Markus Gothe
a0eab2f7b9 qosmngr: Improve TSID to be unique. 2024-12-27 09:28:33 +01:00
Vivek Kumar Dutta
cb4b5c0c7c sysmngr: Updated fwbank validator to accept partial data 2024-12-26 19:43:47 +05:30
Rahul Thakur
bc4bb6b9ea mcastmngr: fix mld filtering 2024-12-24 16:20:56 +05:30
Vivek Kumar Dutta
c41ed55d5f wifidmd: Fix typo in MeasurementReport parameter 2024-12-23 10:59:29 +05:30
Jakob Olsson
4860a1a5a8 map-controler: 6.1.2.14 2024-12-19 16:51:08 +01:00
Vivek Kumar Dutta
973a0c689a sysmngr: added validator for reset_reason file 2024-12-19 19:16:58 +05:30
Jakob Olsson
89d03dc3b9 decollector: 6.1.0.7 2024-12-17 10:28:24 +01:00
Jakob Olsson
510dedb352 map-agent: 6.2.3.9 2024-12-17 10:27:13 +01:00
Jakob Olsson
caf9074ab8 map-agent: 6.2.3.8 2024-12-16 17:08:04 +01:00
Jakob Olsson
0676d5b990 map-controller: 6.1.2.13 2024-12-16 16:16:29 +01:00
Jakob Olsson
fb0413467b map-controller: 6.1.2.12 2024-12-16 14:22:10 +01:00
Markus Gothe
148aa95651 qosmngr: Fix Airoha issue with token rate. 2024-12-12 20:49:20 +01:00
Markus Gothe
daf54622d8 Update WAN ingress ratelimit with generic method.
Instead of using the MAC to do ratelimting we use
the Frame Engine, this has the the benefit of being
a more universal solution and will work with PON
without the need of implement APIs for using the
MAC to do ingress ratelimiting.

This also works fine when the integrated switch
is used as the wan.
2024-12-12 17:12:40 +00:00
Vivek Kumar Dutta
22aa3ff065 obuspa: updated test controller dependency 2024-12-12 11:39:08 +00:00
Vivek Kumar Dutta
eb06147743 mosquitto-auth-shadow: updated dependency on mosquitto-ssl to avoid ambiguity 2024-12-12 11:15:53 +00:00
Jakob Olsson
aaa8171f06 map-agent: 6.2.3.7 2024-12-12 11:57:11 +01:00
Jakob Olsson
8037020206 map-controller: 6.1.2.11 2024-12-12 10:41:13 +01:00
Jakob Olsson
3ab1e18f7d map-agent: 6.2.3.6 2024-12-11 16:42:01 +01:00
Jakob Olsson
d28738ecbf map-agent: 6.2.3.5 2024-12-11 15:57:23 +01:00
Jakob Olsson
247eea7a77 map-agent: 6.2.3.4 2024-12-11 13:19:11 +01:00
Vivek Kumar Dutta
404bb37ced obuspa: Fix unique key registrations 2024-12-11 15:03:05 +05:30
Vivek Kumar Dutta
722ddf9f88 bbfdm: Update Security object proto to cwmp 2024-12-11 14:59:31 +05:30
Vivek Kumar Dutta
c0b146a3fe logmngr: Updated unique datamodel parameters 2024-12-11 12:33:11 +05:30
Vivek Kumar Dutta
7acc13dd85 wifidmd: Updated unique key parameters 2024-12-11 11:53:06 +05:30
Vivek Kumar Dutta
14449614a2 firewallmngr: Updated unique datamodel parameters 2024-12-11 11:45:56 +05:30
Vivek Kumar Dutta
1e218554de sysmngr: Mark unique datamodel parameters 2024-12-11 11:43:19 +05:30
Vivek Kumar Dutta
05017194b5 dnsmngr: Updated unique key parameters 2024-12-11 11:38:29 +05:30
Vivek Kumar Dutta
6f709c0623 bridgemngr: Updated unique key parameters 2024-12-11 11:35:33 +05:30
Vivek Kumar Dutta
dd4907e86d tr104: Updated default values for CallStatus parameters 2024-12-11 09:58:14 +05:30
Jakob Olsson
b1eb97b7d7 map-controller: 6.1.2.10 2024-12-10 16:36:49 +01:00
Jakob Olsson
d9b86df719 map-agent: 6.2.3.3 2024-12-10 16:23:18 +01:00
Vivek Kumar Dutta
e656deb8f5 obuspa: enable cwmp specific datamodel 2024-12-10 19:49:51 +05:30
Vivek Kumar Dutta
e8f1b2167a icwmp: register xmpp for both proto 2024-12-10 19:38:21 +05:30
Amin Ben Romdhane
cfceae73ff sysmngr: 1.0.9 2024-12-10 13:24:49 +01:00
Rahul Thakur
6c7aa21626 logmngr: fix syslog-ng conf generation 2024-12-10 10:16:26 +00:00
Mohd Husaam Mehdi
52f554b84d qosmgr: add support for wan ingress and egress rate control 2024-12-10 09:51:47 +00:00
Vivek Kumar Dutta
70c823e303 obuspa: Optmize datamodel caching 2024-12-10 12:07:28 +05:30
Filip Matusiak
1f94ad341b map-agent: 6.2.3.2 2024-12-09 17:12:26 +01:00
Vivek Kumar Dutta
e02ad277f7 bbfdm: Fix empty output from microservices without proto 2024-12-09 17:05:51 +05:30
Janusz Dziedzic
a8a5f99769 wifimngr: 17.4.7 2024-12-06 15:18:12 +01:00
Mohd Husaam Mehdi
d161ef2238 qosmngr: updates related to rate control
* separate scheduling logic from rate control logic
* add support for burst_size
2024-12-06 13:46:35 +00:00
Jakob Olsson
64d1873eba map-agent: 6.2.3.1 2024-12-06 14:14:46 +01:00
Vivek Kumar Dutta
29a123446a wifidmd: update MLDUnit changes in mapcontroller/agent 2024-12-06 12:34:30 +00:00
Vivek Kumar Dutta
e7374d6bce icwmp: Register XMPP as cwmp and CWMPManagementServer as usp 2024-12-06 12:34:30 +00:00
Vivek Kumar Dutta
7dd517dba7 obuspa: register core datamodel with cwmp proto 2024-12-06 12:34:30 +00:00
Vivek Kumar Dutta
c7a6bdb4a0 bulkdata: register datamodel as cwmp only 2024-12-06 12:34:30 +00:00
Vivek Kumar Dutta
5e009f97e9 bbfdm: Support proto based filter for micro-services 2024-12-06 12:34:30 +00:00
Amin Ben Romdhane
d2a43566bc sysmngr: 1.0.8 2024-12-06 12:04:50 +01:00
Jakob Olsson
ab2b11e343 map-agent: 6.2.3.0 2024-12-06 10:48:41 +01:00
Amin Ben Romdhane
67db9fcc48 sysmngr: Added support for fwbank ubus object 2024-12-05 15:56:40 +01:00
Vivek Kumar Dutta
db855e4c38 wifidmd: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
b3b7d666b1 usermngr: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
dda4099874 userinterface: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
6c4f2842b8 usbmngr: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
fcad858660 tr104: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
8bd1e237ef timemngr: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
1e4af81108 sysmngr: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
6dbd4fbade swmodd: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
cd6a127fb9 sshmngr: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
cb3653ebe9 port-trigger: Install datamodel as firewallmngr plugin 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
765201ded3 ssdpd: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
54f75846ca qosmngr: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
090795699d ponmngr: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
551033461a periodicstats: Align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
2c3a493457 parental-control: Align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
e0bf63926a obuspa: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
c6e8454989 netmngr: Align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
16f1276346 mcastmngr: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
5d223f5909 ieee1905: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
83541d7e03 icwmp: Align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
76042997ca hostmngr: Align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
e47abdff8f firewallmngr: Align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
3eaa20c12e ethmngr: Align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
7ffb8b398f dslmngr: Align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
5b449b886c dnsmngr: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
13b00ca74d dhcpmngr: Align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
8b9e1a0f94 ddnsmngr: align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
9e3ee55e12 bulkdata: Align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
6a9eee1af5 bridgemngr: Align with bbfdm 2024-12-05 12:58:35 +00:00
Vivek Kumar Dutta
d9d2fc882f bbfdm: Register micro-services before exposing over ubus 2024-12-05 12:58:35 +00:00
Janusz Dziedzic
7df39bd465 map-agent: wait ap-autoconfig when MLO
Don't generate APs early - just wait
ap-autoconfig.
2024-12-05 12:31:12 +00:00
Janusz Dziedzic
317c1bdff0 libwifi: 7.7.9 2024-12-05 09:47:15 +00:00
Janusz Dziedzic
ac5602443f wifimngr: 17.4.6 2024-12-05 09:33:45 +00:00
Jakob Olsson
9816a42f00 map-agent: 6.2.2.3 2024-12-04 12:27:55 +01:00
Mohd Husaam Mehdi
12f70a7d91 qosmngr: add ingress and egress rate control support for airoha 2024-12-04 13:10:30 +05:30
Vivek Kumar Dutta
f3959d1ffd bulkdata: Fix segfault when server not responding 2024-12-04 12:59:33 +05:30
Suvendhu Hansa
b8c4404ba6 parental-control: 1.0.0 2024-12-03 21:47:33 +05:30
Vivek Kumar Dutta
b699f89d41 wifidmd: Show non-mlo STA in AccessPoint.AssociatedDevice 2024-12-03 18:19:53 +05:30
Jakob Olsson
6b26936300 map-agent: 6.2.2.2 2024-12-03 11:57:55 +01:00
Vivek Kumar Dutta
386412064c obuspa: config option for cwmp specific datamodels 2024-12-03 09:59:48 +05:30
Rahul Thakur
84ac60736f update makefile hostmngr
* 431b122 Implement ScheduleRef
2024-12-02 07:06:30 +00:00
Rahul Thakur
2d037f5e73 hostmngr: read access control schedule from schedules
* The Schedule object is deprecated in 2.18 and ScheduleRef is introduced,
update script to generate rules accordingly.
* Some shell script improvements.
2024-12-02 07:06:30 +00:00
Vivek Kumar Dutta
3cebe495c5 obuspa: Fix notification logging 2024-11-29 18:47:48 +05:30
Jakob Olsson
1e2dd935f5 decollector: 6.1.0.6 2024-11-29 12:01:26 +01:00
Vivek Kumar Dutta
425bf39763 netmngr: Optimize IP Interface Status parameter 2024-11-29 11:12:08 +05:30
Jakob Olsson
367a9b7ef3 map-agent: 6.2.2.1 2024-11-28 12:30:45 +01:00
Jakob Olsson
125b7d6f57 Revert "ieee1905: fix libwifi config option dependency"
This reverts commit 7d08926622.
2024-11-27 15:09:30 +01:00
Jakob Olsson
7d08926622 ieee1905: fix libwifi config option dependency 2024-11-27 14:43:22 +01:00
Vivek Kumar Dutta
396e0c6ca8 bbfdm: 1.12.26 2024-11-27 19:03:43 +05:30
Vivek Kumar Dutta
ab794f7469 wifidmd: Additional key validation for sae-mixed encryption 2024-11-27 18:39:41 +05:30
Vivek Kumar Dutta
e0cda7f5d0 swmodd: Fix datatype for Reset operate cmd 2024-11-27 18:08:34 +05:30
Vivek Kumar Dutta
ce6a87ffe7 usermngr: Fix typo in CheckCredentialsDiagnostics operate cmd 2024-11-27 18:01:40 +05:30
Vivek Kumar Dutta
9a83b05eac hostmngr: Fix datatype for WANStats parameters 2024-11-27 15:19:45 +05:30
Vivek Kumar Dutta
bfb9c65610 wifidmd: Fix datatype for TimeStamp parameters 2024-11-27 15:19:45 +05:30
Vivek Kumar Dutta
acea025b63 netmngr: Update datatype for Stats parameters 2024-11-27 15:19:45 +05:30
Rahul Thakur
01b5c29100 mcastmngr: fix err msg on mcast restart 2024-11-27 05:59:07 +00:00
Vivek Kumar Dutta
8c6c12fe53 qosmngr: Align datatype of dm parameters 2024-11-27 10:11:22 +05:30
Vivek Kumar Dutta
f9b36e5b0b obuspa: Update datatype registration 2024-11-26 21:51:11 +05:30
Jakob Olsson
a95afbb928 Map-agent: 6.2.2.0 2024-11-26 14:54:42 +01:00
Jakob Olsson
f4cf83b813 map-controller: 6.1.2.9 2024-11-26 14:51:17 +01:00
Janusz Dziedzic
94f7110729 map-agent: 6.2.1.14 2024-11-26 11:48:18 +00:00
Yalu Zhang
72de1d65c0 Update packages dectmngr and voicemngr
Fix issues related to setting pcm_id value and call state.
2024-11-26 11:12:37 +01:00
Amin Ben Romdhane
6a45c379c2 sysmngr: Added support for DeviceInfo.ProcessStatus.CPU. Object 2024-11-25 10:04:26 +01:00
Suvendhu Hansa
a2522dfff0 urlfilter: Use DotSO dm plugin in place of json 2024-11-25 13:36:55 +05:30
Jakob Olsson
4312fa6a16 decollector: 6.1.0.5 2024-11-22 12:13:19 +01:00
Vivek Kumar Dutta
62dd45321e bbfdm: 1.12.25 2024-11-22 13:34:56 +05:30
Jakob Olsson
258744a16e map-agent: 6.2.1.13 2024-11-21 16:23:04 +01:00
Vivek Kumar Dutta
b574d39642 urlfilter: Fix datamodel plugin installation 2024-11-21 19:52:54 +05:30
Vivek Kumar Dutta
deaa91514b bbfdm: 1.12.24 2024-11-21 16:56:26 +05:30
Mohd Husaam Mehdi
801dee5cfa ebtables-extension: fix ebtables compilation issue 2024-11-21 16:24:04 +05:30
Vivek Kumar Dutta
bf26939fb4 bbfdm: Fix tools validation plugin 2024-11-21 13:22:03 +05:30
Jakob Olsson
1c7945e834 decollector: 6.1.0.4 2024-11-20 17:11:13 +01:00
Jakob Olsson
d52f95fc35 map-agent: 6.2.1.12 2024-11-20 17:07:22 +01:00
Janusz Dziedzic
9325f1a724 wifimngr: 17.4.5 2024-11-20 14:52:33 +00:00
Vivek Kumar Dutta
dfcc8ff111 icwmp: 9.8.24
- Fix race condition in notification update
- Fix enable/disable of cwmp from usp
- Selected sysmngr for Device Info
2024-11-20 19:16:00 +05:30
Vivek Kumar Dutta
8366ad85e7 swmodd: Add support for EnvVariable in InstallDU command 2024-11-20 19:13:34 +05:30
Rahul Thakur
c56cb30b3b ebtables-extensions: merge gnx ebt extensions 2024-11-20 09:43:47 +00:00
Mohd Husaam Mehdi
c088fd5959 urlfilter: add default bundles and support to read them 2024-11-20 13:34:54 +05:30
Suvendhu Hansa
40bd23290f usermngr: daemonization 2024-11-19 13:14:38 +00:00
Vivek Kumar Dutta
8c7f2bc2bd obuspa: Use critical services def for reload handling 2024-11-19 18:41:33 +05:30
arbala
94181840b0 map-controller: 6.1.2.8 2024-11-19 11:40:03 +01:00
Mohd Husaam Mehdi
803afb7753 urlfilter: misc changes related to naming and schedule enable 2024-11-19 10:00:15 +00:00
Mohd Husaam Mehdi
6f253a35de cmph: add c minimal perfect hashing library package(for urlfilter) 2024-11-19 09:58:28 +00:00
Mohd Husaam Mehdi
c56853b477 dhcpmngr: depend on odhcpd full only when unbound replaces dnsmasq 2024-11-19 09:57:26 +00:00
Vivek Kumar Dutta
6640412546 icwmp: move critical service definition to bbfdm 2024-11-19 11:42:21 +05:30
Vivek Kumar Dutta
8b58c13823 bbfdm: Add support for proto based critical services 2024-11-19 11:06:30 +05:30
Amin Ben Romdhane
c36493a852 sysmngr: 1.0.4 2024-11-18 11:10:14 +01:00
Yalu Zhang
f2cd1c5573 dectmngr-3.7.2: Fix a bug in setting extension id for an outgoing call
voicemngr-1.2.2: Removed the timeout ubus requests to asterisk or dectmngr
to prevent locks.
Also Show information of existing calls in "ubus call dect status" for debug.
2024-11-15 17:32:27 +01:00
Amin Ben Romdhane
d4a631f0cb sysmngr: Added support for DeviceInfo.MemoryStatus.MemoryMonitor. Object 2024-11-15 16:04:38 +01:00
Janusz Dziedzic
c0208dab2e libwifi: 7.7.8 2024-11-13 10:27:05 +00:00
Mohd Husaam Mehdi
8dca6b8e44 bridgemngr: fix vendor extension macro usage 2024-11-12 16:16:59 +05:30
Mohd Husaam Mehdi
4b1a7859aa bridgemngr: add VLANFiltering bbfdm vendor extension as json 2024-11-12 15:50:20 +05:30
Vivek Kumar Dutta
6f28d90916 wifidmd: Align BackhaulMediaType value for self node 2024-11-12 15:31:41 +05:30
Jakob Olsson
285e24455d hostmngr: 1.2.9 2024-11-11 09:38:27 +01:00
Amin Ben Romdhane
d0c26b4bb7 sysmngr: Update the handling of process Instances 2024-11-08 15:19:28 +01:00
Amin Ben Romdhane
a71d90d2c7 wifidmd: 1.0.12 2024-11-08 15:12:55 +01:00
Vivek Kumar Dutta
78e1468f51 obuspa: Fix instance update in cached dm 2024-11-07 17:42:59 +05:30
Vivek Kumar Dutta
9a1e1dbd1a icmwp: optimize notification handling 2024-11-07 17:00:36 +05:30
Vivek Kumar Dutta
3ef21188b1 sysmngr: 1.0.1 2024-11-07 15:09:06 +05:30
Vivek Kumar Dutta
65daa6c56a bulkdata: Fix segfault with sub-task 2024-11-07 10:04:42 +05:30
Janusz Dziedzic
eb63f5d74f libwifi: 7.7.7 2024-11-06 17:56:00 +00:00
Amin Ben Romdhane
7da09349ec icwmp: Align with sysmngr 2024-11-06 15:18:41 +01:00
Amin Ben Romdhane
b2a28a12f6 bbfdm: Align with sysmngr 2024-11-06 15:11:23 +01:00
Amin Ben Romdhane
0fe5d2a232 logmngr: Align with sysmngr 2024-11-06 15:10:15 +01:00
Amin Ben Romdhane
b50f9946bb sysmngr: new package to manage DeviceInfo Object 2024-11-06 15:08:28 +01:00
Filip Matusiak
bf28778432 map-controller: 6.1.2.7 2024-11-06 10:19:07 +01:00
Amin Ben Romdhane
d6dad64328 bbfdm: 1.12.20 2024-11-06 10:01:33 +01:00
Filip Matusiak
46003fddd5 map-controller: 6.1.2.6 2024-11-05 16:49:13 +01:00
Vivek Kumar Dutta
2e7fc5fa14 bbfdm: prepone microservice startup
- Prepone dm microservice startup to avoid usp schema registration race
  condition
2024-11-05 18:51:18 +05:30
Jakob Olsson
7fb9b397ef decollector: 6.1.0.3 2024-11-05 13:39:46 +01:00
Vivek Kumar Dutta
cbe66d6c96 wifidmd: Update deprecated MultiAPDevice parameters 2024-11-05 18:06:59 +05:30
Amin Ben Romdhane
57d477c1da bbfdm: 1.12.18 2024-11-04 15:20:24 +01:00
Vivek Kumar Dutta
8e774faa3e self-diagnostics: 1.0.11 2024-11-04 12:29:14 +00:00
Vivek Kumar Dutta
6129323ca3 icwmp: Fix rpc event list after reboot 2024-11-04 17:40:48 +05:30
Vivek Kumar Dutta
6d6ecdfe92 obuspa: Fix probable segfault 2024-11-04 10:27:20 +05:30
Jakob Olsson
b66ae8d605 map-agent: 6.2.1.11 2024-10-31 14:15:27 +01:00
Jakob Olsson
ed97af82b5 map-controller: 6.1.2.5 2024-10-31 14:14:49 +01:00
Marina Maslova
464f037768 map-agent: add fixed interface names for proprietary mediatek driver 2024-10-30 15:18:53 +00:00
Janusz Dziedzic
024442da10 libwifi: skip probe-req events by default 2024-10-30 14:57:29 +00:00
Vivek Kumar Dutta
b0049df366 self-diagnostics: 1.0.10
- Print report_dir along with report_file
- Stop verbose logging of exec_cmds to prevent syslog overflow
- Increased timeouts of wifi diagnotics scripts
- Added report_dir in error output, if failed to generate tar
2024-10-30 13:35:21 +00:00
Jakob Olsson
7115c1734e map-agent: 6.2.1.10 2024-10-30 13:08:44 +01:00
Anjan Chanda
9b93ffef76 ieee1905: 8.6.1 2024-10-30 09:26:29 +01:00
Janusz Dziedzic
225b89ab4f wifimngr: 17.4.4 2024-10-30 07:51:07 +00:00
Janusz Dziedzic
d4464bf430 libwifi: 7.7.6 2024-10-30 07:47:47 +00:00
Marina Maslova
50731e00ef libwifi: use mtk module for proprietary mediatek driver on an7581 2024-10-30 07:47:25 +00:00
Amin Ben Romdhane
f9d3d22c14 bbfdm: 1.12.17
- Improve bbf.config handler for external config change
- Removed deprecated DeviceInfo.Processor. object
2024-10-29 12:33:52 +00:00
Anjan Chanda
607f3c5334 ieee1905: 8.6.0 2024-10-29 09:48:36 +01:00
Janusz Dziedzic
925c58aeaa libwifi: 7.7.5 2024-10-29 07:57:52 +00:00
Suvendhu Hansa
447acf3b27 bulkdata: unified DM with bulkdata daemon 2024-10-29 04:58:01 +00:00
Rahul Thakur
5bff6c3854 mcastmngr: remove unnecessary log 2024-10-29 10:25:53 +05:30
Andreas Gnau
70f4086ecc iop: Remove license_report
A CycloneDX SBOM is generated by the OpenWrt build system. It the same
license information as the license report. Remove the license report
script.

Signed-off-by: Andreas Gnau <andreas.gnau@iopsys.eu>
2024-10-28 13:57:29 +00:00
Vivek Kumar Dutta
b3bafdbba9 bbfdm: 1.12.16
- Add support for DeviceInfo.MaxNumberOfActivateTimeWindows
- Add support for DeviceInfo.HostName
- Generate error if plugin failed to installed
2024-10-28 08:54:36 +05:30
Yalu Zhang
5788d7d284 dectmngr-3.7.1: Add a new RPC to release call(s) on an extension
voicemngr-1.2.1: Change the RPC to dectmngr for releasing call(s) on a DECT extension
2024-10-25 17:23:52 +02:00
Jakob Olsson
a0c226d6ea map-controller: 6.1.2.4 2024-10-25 13:54:44 +02:00
Jakob Olsson
921657f464 map-controller: 6.1.2.3 2024-10-25 11:52:02 +02:00
Anjan Chanda
217ee3fa77 wifimngr: 17.4.3 2024-10-24 16:42:19 +02:00
Anjan Chanda
0aef613006 libwifi: 7.7.4 2024-10-24 16:41:29 +02:00
Markus Gothe
63e2bb8f6d ieee1905: 8.5.9 2024-10-24 16:13:29 +02:00
Markus Gothe
ea0059a932 hostmngr: 1.2.8 2024-10-24 15:50:32 +02:00
Jakob Olsson
a95a6d804a map-controller: 6.1.2.2 2024-10-24 14:23:21 +02:00
Jakob Olsson
3fbdd08037 map-agent: 6.2.1.9 2024-10-24 12:49:42 +02:00
Vivek Kumar Dutta
e04040c4ea bbfdm: 1.12.15 2024-10-24 14:50:11 +05:30
Jakob Olsson
20a85cce5f map-agent: 6.2.1.8 2024-10-24 09:44:04 +02:00
Vivek Kumar Dutta
2be7a59ff0 obuspa: Switch to WakeUp event for re-connections 2024-10-24 13:06:28 +05:30
Yalu Zhang
3102c0f981 dectmngr: add voicemngr in the dependency of Makefile 2024-10-24 09:25:44 +02:00
Vivek Kumar Dutta
8693a8f2c9 icwmp: Align with DeviceInfo.Reboots. 2024-10-24 12:22:09 +05:30
Amin Ben Romdhane
9bc4656525 bbfdm: Added support for Device.DeviceInfo.Reboots. object 2024-10-24 12:03:47 +05:30
Suvendhu Hansa
544000177c icwmp: Option to backup RPC in persistent storage 2024-10-24 11:31:46 +05:30
Strhuan Blomquist
2b1dbf7e36 iopsys-analytics: core watcher to fix modelname 2024-10-23 14:20:11 +00:00
Mohd Husaam Mehdi
641ec8a9eb urlfilter: fix crash on cleanup of dns answer struct 2024-10-23 10:16:39 +00:00
Janusz Dziedzic
c18929dbae libwifi: 7.7.3 2024-10-23 07:34:05 +00:00
Yalu Zhang
a592f34216 dectmngr-3.7.0: Add a new RPC to stop ringing on all incoming calls on an extension
voicemngr-1.2.0: Change the RPC to dectmngr for stopping ringing on an extension
2024-10-22 14:35:36 +02:00
Markus Gothe
4e2adf77cb mcastmngr: Implement L2 stats over UBUS.
Implement support for L2 mcast stats over UBUS.
2024-10-22 05:06:52 +00:00
Vivek Kumar Dutta
9fba09f00a bbfdm: Optimize event handling 2024-10-22 10:09:02 +05:30
Markus Gothe
12d377b3bd mcastmngr: 1.2.7 2024-10-21 17:07:34 +02:00
Rahul Thakur
cd1f81c8d9 update package logmngr
* fix uci defaults
* 37f9eef make protocol writable
2024-10-21 09:58:06 +00:00
Amin Ben Romdhane
f6774fd554 ieee1905: 8.5.8 2024-10-21 10:45:32 +02:00
Amin Ben Romdhane
ea248061f3 mcastmngr: 1.2.6 2024-10-21 10:44:12 +02:00
Amin Ben Romdhane
1e2894dd46 netmngr: 1.0.5 2024-10-21 10:43:05 +02:00
Vivek Kumar Dutta
92b607bd0e obuspa: reduce IPC cost for get calls 2024-10-18 18:34:08 +05:30
Mohd Husaam Mehdi
b766ea958a urlfilter: show Deny in bbfdm when no access policy set for filter 2024-10-18 06:45:37 +00:00
Markus Gothe
a7074db9f8 mcastmngr: Support hybrid proxying/snooping.
Support running mcproxy and snooping simultanous.
2024-10-17 16:19:04 +02:00
Janusz Dziedzic
5c819b2018 libwifi: 7.7.2 2024-10-17 12:57:25 +00:00
Janusz Dziedzic
c526df5143 libwifi: 7.7.1 2024-10-17 09:27:57 +00:00
Rahul Thakur
31ed2ae746 update package logmngr
*5e7c684 Fix data model params
* d23dcdf logmngr: add README
2024-10-17 14:31:30 +05:30
Rahul Thakur
702065eb3d update package dnsmngr
* fb49088 fix DNS.SD.Advertise.{i}.TransportProtocol
* b7115a9 Device.DNS.SD.Advertise.{i}.Interface doesn't show a correct reference value
* 94964b4 Device.DNS.SD.Advertise.{i}.InstanceName value is always shown as empty value
* bf29f7b Device.DNS.SD.Advertise.{i}.Alias default value is empty and remains empty even after setting it
2024-10-17 14:29:11 +05:30
Janusz Dziedzic
c418266af6 wifimngr: 17.4.2 2024-10-16 09:24:22 +00:00
Janusz Dziedzic
9c8d80d763 libwifi: 7.7.0 2024-10-16 08:03:15 +00:00
Vivek Kumar Dutta
007a8cb8bf icwmp: Use async task for diagnostics 2024-10-16 12:23:39 +05:30
Vivek Kumar Dutta
2fc7d55d6c bbfdm: 1.12.12 2024-10-16 12:22:26 +05:30
Vivek Kumar Dutta
b3bdcea137 obuspa: Fix miss-configs caused by uci update 2024-10-15 17:40:58 +05:30
Vivek Kumar Dutta
4673347125 obuspa: workaround to skip false warning on Download operation 2024-10-15 16:05:10 +05:30
Vivek Kumar Dutta
f827f9f408 bbfdm: 1.12.11 2024-10-15 14:30:44 +05:30
Vivek Kumar Dutta
6a8aed5d3f bbfdm: Schedule reboots on firmware AutoActivate 2024-10-15 14:11:05 +05:30
Janusz Dziedzic
5e54477cd1 libwifi: 7.6.9 2024-10-15 05:40:20 +00:00
Amin Ben Romdhane
ba9fcda886 obuspa: delete dmcaching exclude objects 2024-10-14 18:20:10 +02:00
Amin Ben Romdhane
c848d93316 hostmngr: 1.2.7 2024-10-14 18:17:13 +02:00
Amin Ben Romdhane
d00c8f1ea0 bbfdm: 1.12.9 2024-10-14 18:16:20 +02:00
Mohd Mehdi
9788a135aa urlfilter: ParentalControl datamodel 2024-10-14 10:10:12 +00:00
Jakob Olsson
899e6b1417 map-agent: 6.2.1.7 2024-10-11 09:04:35 +02:00
Mohd Husaam Mehdi
6f7f14b241 urlfilter: transform into ParentalControl bbf extension
* config file has been renamed from urlfilter to parentalcontrol
* along with urlfiltering, shell scripts handle internet_access
  and bedtime blocking support, which have been added as
  separate sections for better mapping to the bbf data model
  extension
* uci-default script has been added to handle migration from
  previous to new format
2024-10-11 12:18:26 +05:30
Vivek Kumar Dutta
cc0d1b5910 firewallmngr: 1.0.6 2024-10-10 17:10:29 +05:30
Vivek Kumar Dutta
0b6cd8154b ddnsmngr: 1.0.9 2024-10-10 16:47:42 +05:30
Vivek Kumar Dutta
c4cae5d6b4 bridgemngr: 1.0.6 2024-10-10 16:45:16 +05:30
Vivek Kumar Dutta
f58959842b dhcpmngr: 1.0.4 2024-10-10 16:44:50 +05:30
Vivek Kumar Dutta
b813c155bc sshmngr: 1.0.5 2024-10-10 16:42:50 +05:30
Vivek Kumar Dutta
98e53ae941 logmngr: 1.0.3 2024-10-10 16:02:51 +05:30
Vivek Kumar Dutta
4d993266b3 bbfdm: move VendorLogFile to logmngr 2024-10-10 14:30:41 +05:30
Suvendhu Hansa
8da27926a1 icwmp: 9.8.16
- External script to handle '2 Vendor Log File'
- Align with VendorLogFile
2024-10-10 12:49:49 +05:30
Suvendhu Hansa
7fae7acc91 logmngr: 1.0.2
- Added prefix with rotated log filename to distinguish
  with actual log files
- Fix compression value
- Moved VendorLogFiles datamodel from bbfdm to logmngr
2024-10-10 04:10:22 +00:00
Suvendhu Hansa
47708d34df self-diagnostics: Align with VendorLogFiles update 2024-10-10 09:20:43 +05:30
Markus Gothe
ab322f1194 timemngr: commit time UCI config. 2024-10-09 16:08:32 +02:00
Amin Ben Romdhane
aab45b16b0 Added libbbfdm-ubus and dm-service as dependencies for all microservices 2024-10-09 09:54:16 +02:00
Jakob Olsson
586920d8a8 map-agent: 6.2.1.6 2024-10-08 12:58:33 +02:00
Rahul Thakur
ac8a1c69ae update package dnsmngr
* 055de29 add support for dns.sd.advertise
2024-10-08 14:01:57 +05:30
Vivek Kumar Dutta
604cd52a79 bbfdm: Support to set list of references with json plugins 2024-10-08 12:52:38 +05:30
Jakob Olsson
37109a8531 decollector: 6.1.0.2 2024-10-04 14:11:21 +02:00
Jakob Olsson
136db7b085 map-agent: 6.2.1.5 2024-10-04 12:32:33 +02:00
Jakob Olsson
c177d59b7b map-agent: 6.2.1.4 2024-10-03 14:03:58 +02:00
Vivek Kumar Dutta
fa9611f4f5 usbmngr: 1.0.5 2024-10-03 16:38:54 +05:30
Jakob Olsson
859e2958c0 map-agent: 6.2.1.3 2024-10-03 12:10:25 +02:00
Vivek Kumar Dutta
0dda22833d obuspa: skip db override 2024-10-02 20:43:48 +05:30
Yalu Zhang
ccb40910e2 libvoice-broadcom-1.0.15: Change the mechanism of DECT simulation by not calling Broadcom APIs 2024-10-02 16:51:21 +02:00
Janusz Dziedzic
eddaa9233c libwifi: 7.6.8 2024-10-02 13:00:08 +00:00
Piotr Kubik
a09f5a3ba6 iop: update_feed_branches: Remove script
It was used to update branches of feeds according to the commit hashes
in feeds.conf. Mostly used when doing release branches for the
first time. We do it manually now, so it is not needed anymore.
2024-10-02 13:44:30 +02:00
Jakob Olsson
ed78a58455 map-agent: 6.2.1.2 2024-10-02 11:01:20 +02:00
Amin Ben Romdhane
b130d50bb3 tr104: 1.0.34 2024-10-02 10:08:31 +02:00
Vivek Kumar Dutta
7ab286753d obuspa: 9.0.0.6
- Added back firewall hook to force re-connect mqtt client on firewall reload
- Added wait for apply handler
2024-10-01 16:29:14 +05:30
Vivek Kumar Dutta
bc6aadb0ed tr104: added missing required NumberOfEntires parameters 2024-10-01 16:21:45 +05:30
Vivek Kumar Dutta
fd9c8b0922 icwmp: Fix GPN fault with multi-instances 2024-10-01 16:17:15 +05:30
Vivek Kumar Dutta
2c9b9cadfe icwmp: 9.8.14 2024-09-30 19:18:41 +05:30
Vivek Kumar Dutta
fb1ac0994d obuspa: multiple fixes
- remove workaround to ForceReconnect over MQTT with firewall hook
- removed schema reloader from obuspa
2024-09-30 18:56:07 +05:30
Janusz Dziedzic
5ba8e293eb libwifi: 7.6.7 2024-09-30 07:45:45 +00:00
Janusz Dziedzic
801ed0eb9f libwifi: 7.6.6 2024-09-27 16:34:33 +00:00
Rahul Thakur
54503f98d4 urlfilter: fix connection flush on firewall reload 2024-09-27 11:54:45 +00:00
Janusz Dziedzic
903ff637e7 libwifi: 7.6.5 2024-09-27 08:41:26 +00:00
Vivek Kumar Dutta
82ef5f6b6e wifidmd: Align with dump2 output 2024-09-26 16:10:24 +05:30
Anjan Chanda
398f09a1ce decollector: 6.1.0.1 2024-09-26 11:42:45 +02:00
Jakob Olsson
f29de07d0d map-agent: 6.2.1.1 2024-09-26 10:50:54 +02:00
Janusz Dziedzic
8524f719c1 wifimngr: 17.4.1 2024-09-26 05:57:13 +00:00
Janusz Dziedzic
0a73e686f5 libwifi: 7.6.4 2024-09-26 05:56:06 +00:00
Vivek Kumar Dutta
615b3d0507 obuspa: Fix transaction commit/abort calls 2024-09-25 20:06:17 +05:30
Vivek Kumar Dutta
4df8574fb6 stunc: 1.4.5 2024-09-25 10:34:08 +00:00
Vivek Kumar Dutta
e39d51a37b obuspa: Fix disconnection after set 2024-09-25 10:34:08 +00:00
Vivek Kumar Dutta
598b5c8e4a timemngr: Updated loglevel 2024-09-25 10:34:08 +00:00
445 changed files with 355524 additions and 5600 deletions

View File

@@ -1,17 +1,10 @@
if PACKAGE_bbfdmd
config BBF_VENDOR_EXTENSION
bool "Enable Vendor Extension"
default y
config BBF_VENDOR_PREFIX
string "Vendor Prefix"
default "X_IOPSYS_EU_"
default "X_IOWRT_EU_"
config BBF_OBFUSCATION_KEY
string "Obfuscation key"
default "371d530c95a17d1ca223a29b7a6cdc97e1135c1e0959b51106cca91a0b148b5e42742d372a359760742803f2a44bd88fca67ccdcfaeed26d02ce3b6049cb1e04"
config BBF_MAX_OBJECT_INSTANCES
int "Maximum number of instances per object"
default 255
endif

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bbfdm
PKG_VERSION:=1.12.6
PKG_VERSION:=1.16.6
USE_LOCAL:=0
ifneq ($(USE_LOCAL),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/bbfdm.git
PKG_SOURCE_VERSION:=0a33d96b693ac5cc34ba57f6fd53417d6eaeac61
PKG_SOURCE_VERSION:=1615b42e405faceceac825f9c0387a58b90785ae
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -19,6 +19,8 @@ endif
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
RSTRIP:=true
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
include bbfdm.mk
@@ -68,8 +70,13 @@ define Package/bbfdmd/config
source "$(SOURCE)/Config_bbfdmd.in"
endef
define Package/bbf_configmngr/config
source "$(SOURCE)/bbf_configmngr.in"
# Below config is a hack to force-recompile dependent micro-services
define Package/libbbfdm-api/config
if PACKAGE_bbfdmd
config BBF_LIBBBFDM_VERSION
string "Internal config variable to force recompile"
default "v${PKG_VERSION}"
endif
endef
define Package/libbbfdm-api/description
@@ -100,12 +107,14 @@ endif
CMAKE_OPTIONS += \
-DBBF_VENDOR_PREFIX:String="$(CONFIG_BBF_VENDOR_PREFIX)" \
-DBBF_MAX_OBJECT_INSTANCES:Integer=$(CONFIG_BBF_MAX_OBJECT_INSTANCES) \
-DBBFDMD_MAX_MSG_LEN:Integer=10485760
-DBBFDMD_MAX_MSG_LEN:Integer=10485760 \
-DCMAKE_BUILD_TYPE:String="Debug" \
define Package/libbbfdm-api/install
$(INSTALL_DIR) $(1)/lib
$(CP) $(PKG_BUILD_DIR)/libbbfdm-api/libbbfdm-api.so $(1)/lib/
$(CP) $(PKG_BUILD_DIR)/libbbfdm-api/legacy/libbbfdm-api.so $(1)/lib/
$(CP) $(PKG_BUILD_DIR)/libbbfdm-api/version-2/libbbfdm-api-v2.so $(1)/lib/
$(INSTALL_DIR) $(1)/usr/libexec/rpcd
$(CP) $(PKG_BUILD_DIR)/utilities/files/usr/libexec/rpcd/bbf.secure $(1)/usr/libexec/rpcd/bbf.secure
@@ -133,6 +142,7 @@ define Package/bbfdmd/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bbfdmd/ubus/bbfdmd $(1)/usr/sbin/
$(STRIP) $(1)/usr/sbin/bbfdmd
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/etc/init.d/bbfdmd $(1)/etc/init.d/bbfdmd
@@ -145,14 +155,10 @@ define Package/bbfdmd/install
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/etc/uci-defaults/91-fix-bbfdmd-enabled-option $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/ruleng.bbfdm $(1)/etc/uci-defaults
ifeq ($(CONFIG_BBF_VENDOR_EXTENSION),y)
$(BBFDM_INSTALL_CORE_PLUGIN) $(PKG_BUILD_DIR)/libbbfdm/vendor/vendor.json $(1)
endif
$(INSTALL_DIR) $(1)/usr/share/bbfdm/scripts
$(CP) $(PKG_BUILD_DIR)/utilities/files/usr/share/bbfdm/scripts/bbf_activate_handler.sh $(1)/usr/share/bbfdm/scripts/
$(CP) $(PKG_BUILD_DIR)/utilities/files/usr/share/bbfdm/scripts/bbf_check_idle.sh $(1)/usr/share/bbfdm/scripts/
$(INSTALL_DIR) $(1)/etc/ruleng
$(INSTALL_BIN) ./files/etc/ruleng/bbfdm.json $(1)/etc/ruleng
endef
define Package/dm-service/install
@@ -161,19 +167,23 @@ define Package/dm-service/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/dm-service/dm-service $(1)/usr/sbin/
$(BBFDM_REGISTER_SERVICES) -v ${CONFIG_BBF_VENDOR_PREFIX} ./bbfdm_service.json $(1) core
$(BBFDM_INSTALL_MS_DM) $(PKG_BUILD_DIR)/libbbfdm/libcore.so $(1) core
endef
define Package/bbf_configmngr/install
$(INSTALL_DIR) $(1)/etc/init.d
ifeq ($(CONFIG_BBF_CONFIGMNGR_C_BACKEND),y)
$(INSTALL_DIR) $(1)/etc/bbfdm/
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/usr/share/bbfdm/scripts
$(INSTALL_BIN) $(PKG_BUILD_DIR)/utilities/bbf_configd $(1)/usr/sbin/
$(STRIP) $(1)/usr/sbin/bbf_configd
$(INSTALL_BIN) ./files/etc/init.d/bbf_configd $(1)/etc/init.d/bbf_configd
endif
ifeq ($(CONFIG_BBF_CONFIGMNGR_SCRIPT_BACKEND),y)
$(INSTALL_DIR) $(1)/usr/libexec/rpcd
$(CP) $(PKG_BUILD_DIR)/utilities/files/usr/libexec/rpcd/bbf.config $(1)/usr/libexec/rpcd/bbf.config
endif
$(INSTALL_BIN) $(PKG_BUILD_DIR)/utilities/files/usr/share/bbfdm/scripts/bbf_config_notify.sh $(1)/usr/share/bbfdm/scripts/
$(INSTALL_DATA) ./files/etc/bbfdm/critical_services.json $(1)/etc/bbfdm/
endef
define Package/bbfdmd/prerm
@@ -186,11 +196,17 @@ define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/usr/include
$(INSTALL_DIR) $(1)/usr/include/libbbfdm-api
$(INSTALL_DIR) $(1)/usr/include/libbbfdm-api/legacy
$(INSTALL_DIR) $(1)/usr/include/libbbfdm-api/version-2
$(INSTALL_DIR) $(1)/usr/include/libbbfdm-ubus
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/*.h $(1)/usr/include/libbbfdm-api/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/legacy/*.h $(1)/usr/include/libbbfdm-api/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/legacy/*.h $(1)/usr/include/libbbfdm-api/legacy/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/version-2/*.h $(1)/usr/include/libbbfdm-api/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/version-2/*.h $(1)/usr/include/libbbfdm-api/version-2/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-ubus/bbfdm-ubus.h $(1)/usr/include/libbbfdm-ubus/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/include/*.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/libbbfdm-api/libbbfdm-api.so $(1)/usr/lib
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/legacy/include/*.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/libbbfdm-api/legacy/libbbfdm-api.so $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/libbbfdm-api/version-2/libbbfdm-api-v2.so $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/libbbfdm-ubus/libbbfdm-ubus.so $(1)/usr/lib
endef

View File

@@ -1,19 +0,0 @@
if PACKAGE_bbf_configmngr
choice
prompt "Select backend daemon for bbf.config"
default BBF_CONFIGMNGR_C_BACKEND
help
Select which backend daemon should be used for ubus bbf.config
config BBF_CONFIGMNGR_SCRIPT_BACKEND
bool "Use shell script backend"
help
Enable this option to use shell script as the backend for bbf.config. This can be useful for quick and easy scripting of configuration tasks.
config BBF_CONFIGMNGR_C_BACKEND
bool "Use C code backend"
help
Enable this option to use a C code implementation as the backend for bbf.config. This option is generally preferred for performance-critical tasks and scenarios requiring more robust and efficient handling.
endchoice
endif

View File

@@ -6,6 +6,7 @@ BBFDM_BASE_DM_PATH=/usr/share/bbfdm
BBFDM_INPUT_PATH=/etc/bbfdm/micro_services
BBFDM_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
PKG_CONFIG_DEPENDS += CONFIG_BBF_LIBBBFDM_VERSION
#BBFDM_VERSION:=$(shell grep -oP '(?<=^PKG_VERSION:=).*' ${BBFDM_DIR}/Makefile)
#BBFDM_TOOLS:=$(BUILD_DIR)/bbfdm-$(BBFDM_VERSION)/tools
@@ -47,7 +48,6 @@ BBFDM_INSTALL_CORE_PLUGIN:=$(BBFDM_DIR)/tools/bbfdm.sh -p
# Note:
# - There could be only one main plugin file, so its bind to PKG_NAME
# - Micro-service input.json will be auto generated with this call
# - Use -u (optional argument) to overwrite ubus object name
#
# Example:
# BBFDM_INSTALL_MS_DM $(PKG_BUILD_DIR)/libcwmp.so $(1) $(PKG_NAME)
@@ -88,27 +88,5 @@ BBFDM_INSTALL_MS_PLUGIN:=$(BBFDM_DIR)/tools/bbfdm.sh -m -p
#
BBFDM_INSTALL_SCRIPT:=$(BBFDM_DIR)/tools/bbfdm.sh -s
# Deprecated functions errors
define BbfdmInstallPluginInMicroservice
$(warning # BbfdmInstallPluginInMicroservice function is deprecated, use BBFDM_INSTALL_MS_PLUGIN macro #)
$(INSTALL_DIR) $(1)
$(INSTALL_DATA) $(2) $(1)/
endef
define BbfdmInstallMicroServiceInputFile
$(warning # function BbfdmInstallMicroServiceInputFile deprecated, input file auto generated with BBFDM_INSTALL_MS_DM #)
$(INSTALL_DIR) $(1)/etc/bbfdm/micro_services
$(INSTALL_DATA) $(2) $(1)/etc/bbfdm/micro_services/$(PKG_NAME).json
endef
define BbfdmInstallPlugin
$(warning # function BbfdmInstallPlugin deprecated, use BBFDM_INSTALL_CORE_PLUGIN macro #)
$(INSTALL_DIR) $(1)/etc/bbfdm/plugins
$(INSTALL_DATA) $(2) $(1)/etc/bbfdm/plugins/
endef
define BbfdmInstallPluginWithPriority
$(warning # fucntion BbfdmInstallPluginWithPriority deprecated, use BBFDM_INSTALL_CORE_PLUGIN #)
$(INSTALL_DIR) $(1)/etc/bbfdm/plugins
$(INSTALL_DATA) $(3) $(1)/etc/bbfdm/plugins/$(2)_$(shell basename ${3})
endef
BBFDM_REGISTER_SERVICES:=$(BBFDM_DIR)/tools/bbfdm.sh -t

54
bbfdm/bbfdm_service.json Normal file
View File

@@ -0,0 +1,54 @@
{
"daemon": {
"enable": "1",
"service_name": "core",
"unified_daemon": false,
"services": [
{
"parent_dm": "Device.",
"object": "LANConfigSecurity"
},
{
"parent_dm": "Device.",
"object": "Schedules"
},
{
"parent_dm": "Device.",
"object": "Security",
"proto": "cwmp"
},
{
"parent_dm": "Device.",
"object": "PacketCaptureDiagnostics"
},
{
"parent_dm": "Device.",
"object": "SelfTestDiagnostics"
},
{
"parent_dm": "Device.",
"object": "Syslog"
},
{
"parent_dm": "Device.",
"object": "{BBF_VENDOR_PREFIX}OpenVPN",
"proto": "usp"
},
{
"parent_dm": "Device.",
"object": "RootDataModelVersion"
},
{
"parent_dm": "Device.",
"object": "Reboot()"
},
{
"parent_dm": "Device.",
"object": "FactoryReset()"
}
],
"config": {
"loglevel": "3"
}
}
}

View File

@@ -0,0 +1,23 @@
{
"usp": [
"firewall",
"network",
"dhcp",
"time",
"wireless",
"ieee1905",
"mapcontroller",
"mosquitto",
"nginx",
"netmode"
],
"cwmp": [
"firewall",
"network",
"dhcp",
"mapcontroller",
"wireless",
"time",
"netmode"
]
}

View File

@@ -6,3 +6,7 @@ config bbfdmd 'bbfdmd'
config micro_services 'micro_services'
option enable '1'
option enable_core '0'
config reload_handler 'reload_handler'
option log_level '1'

View File

@@ -1,11 +1,15 @@
#!/bin/sh /etc/rc.common
START=80
STOP=10
STOP=07
USE_PROCD=1
PROG=/usr/sbin/bbf_configd
log() {
echo "${@}"|logger -t bbf.config -p info
}
create_needed_directories()
{
mkdir -p /tmp/bbfdm/.cwmp
@@ -15,11 +19,23 @@ create_needed_directories()
start_service()
{
local log_level
create_needed_directories
config_load bbfdm
config_get log_level "reload_handler" log_level 2
procd_open_instance "bbf_configd"
procd_set_param command ${PROG}
#procd_append_param command -d
procd_append_param command -l "${log_level}"
procd_set_param respawn
procd_close_instance "bbf_configd"
}
service_triggers() {
for config_file in /etc/config/*; do
config_name=$(basename "$config_file")
procd_add_config_trigger "config.change" "$config_name" /usr/share/bbfdm/scripts/bbf_config_notify.sh
done
}

View File

@@ -1,12 +1,13 @@
#!/bin/sh /etc/rc.common
START=85
STOP=8
START=97
STOP=05
USE_PROCD=1
PROG=/usr/sbin/dm-service
DM_AGENT_PROG=/usr/sbin/dm-agent
BBFDM_MICROSERVICE_DIR="/etc/bbfdm/micro_services"
BBFDM_MICROSERVICE_DIR="/etc/bbfdm/services"
. /usr/share/libubox/jshn.sh
@@ -24,7 +25,8 @@ validate_bbfdm_micro_service_section()
_add_microservice()
{
local name path loglevel
local enable enable_core
local enable enable_core unified_daemon dm_framework
local daemon_prog
# Check enable from micro-service
path="${1}"
@@ -41,15 +43,31 @@ _add_microservice()
log "datamodel micro-service ${name} not enabled"
return 0
fi
json_get_var unified_daemon unified_daemon 0
if [ "${unified_daemon}" -eq "1" ]; then
return 0
fi
json_get_var dm_framework dm-framework 0
if [ "${dm_framework}" -eq "1" ] || [ "${dm_framework}" = "true" ]; then
daemon_prog="${DM_AGENT_PROG}"
else
daemon_prog="${PROG}"
fi
json_select config
json_get_var loglevel loglevel 3
json_get_var loglevel loglevel 4
procd_open_instance "${name}"
procd_set_param command ${PROG}
procd_append_param command -m "${name}"
procd_append_param command -l "${loglevel}"
procd_set_param command ${daemon_prog}
# Only add parameters for dm-service, not for dm-agent
if [ "${daemon_prog}" = "${PROG}" ]; then
procd_append_param command -m "${name}"
procd_append_param command -l "${loglevel}"
fi
if [ "${enable_core}" -eq "1" ]; then
procd_set_param limits core="unlimited"

View File

@@ -1,7 +1,7 @@
#!/bin/sh /etc/rc.common
START=90
STOP=10
START=97
STOP=06
USE_PROCD=1
PROG=/usr/sbin/bbfdmd
@@ -17,7 +17,7 @@ validate_bbfdm_bbfdmd_section()
uci_validate_section bbfdm bbfdmd "bbfdmd" \
'enable:bool:true' \
'debug:bool:false' \
'loglevel:uinteger:3'
'loglevel:uinteger:4'
}
configure_bbfdmd()

View File

@@ -0,0 +1,66 @@
{
"hosts_refresh": {
"if" : [
{
"event": "host"
}
],
"then" : [
{
"object": "bbfdm.hostmngr",
"method":"refresh_references_db",
"args" : {},
"timeout": 1
}
]
},
"dhcp_refresh": {
"if_operator": "OR",
"if" : [
{
"event": "host"
},
{
"event": "wifi.dataelements.Associated"
}
],
"then" : [
{
"object": "bbfdm.dhcpmngr",
"method":"refresh_references_db",
"args" : {},
"timeout": 1
}
]
},
"ieee1905_refresh_add": {
"if" : [
{
"event": "ieee1905.neighbor.add"
}
],
"then" : [
{
"object": "bbfdm.ieee1905",
"method":"refresh_references_db",
"args" : {},
"timeout": 1
}
]
},
"ieee1905_refresh_del": {
"if" : [
{
"event": "ieee1905.neighbor.del"
}
],
"then" : [
{
"object": "bbfdm.ieee1905",
"method":"refresh_references_db",
"args" : {},
"timeout": 1
}
]
}
}

View File

@@ -51,10 +51,6 @@ parse_bbfdm_sysctl_conf_file() {
# Replace the original file with the modified content
mv "$tmpfile" "${bbfdm_sysctl_conf}"
# Apply the changes
uci commit network
sysctl -e -p "${bbfdm_sysctl_conf}" >&-
}
parse_bbfdm_sysctl_conf_file

View File

@@ -0,0 +1,2 @@
uci -q set ruleng.bbfdm=rule
uci -q set ruleng.bbfdm.recipe='/etc/ruleng/bbfdm.json'

View File

@@ -2,18 +2,19 @@
BBFDM_BASE_DM_PATH="usr/share/bbfdm"
BBFDM_INPUT_PATH="etc/bbfdm/micro_services"
INPUT_TEMPLATE='{"daemon":{"enable":"1","service_name":"template","config":{"loglevel":"3"}}}'
OUT_NAME=""
INPUT_FILE="0"
MICRO_SERVICE=0
SCRIPT=0
DIAG=0
PLUGIN=0
DEST=""
VENDOR_EXTN=""
TOOLS="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
SRC=""
EXTRA_DATA=""
while getopts ":mpsdu:" opt; do
while getopts ":mpsdtv:" opt; do
case ${opt} in
m)
MICRO_SERVICE=1
@@ -27,8 +28,11 @@ while getopts ":mpsdu:" opt; do
d)
DIAG=1
;;
u)
OUT_NAME="${OPTARG}"
t)
INPUT_FILE=1
;;
v)
VENDOR_EXTN=${OPTARG}
;;
?)
echo "Invalid option: ${OPTARG}"
@@ -43,6 +47,9 @@ shift
DEST="${1}"
shift
DATA="${1}"
shift
EXTRA_DATA="${1}"
install_bin() {
if ! install -m0755 ${1} ${2}; then
@@ -79,11 +86,20 @@ bbfdm_install_dm()
exit 1
fi
if [ ! -f "${src}" ]; then
echo "File $src does not exists..."
exit 1
fi
if [ "${src##*.}" = "json" ]; then
echo "Compacting BBFDM JSON file"
minfile=$(mktemp)
jq -c 'del(..|.description?)' ${src} > ${minfile}
if [ -n "${VENDOR_EXTN}" ]; then
sed -i "s/{BBF_VENDOR_PREFIX}/${VENDOR_EXTN}/g" ${minfile}
fi
src=${minfile}
if dpkg -s python3-jsonschema >/dev/null 2>&1; then
echo "Verifying bbfdm Datamodel JSON file"
@@ -103,23 +119,6 @@ bbfdm_install_dm()
fi
}
bbfdm_generate_input()
{
local dest ser
dest_dir=${1}
ser=${2}
dest=${dest_dir}/${ser}.json
if [ -n "${OUT_NAME}" ]; then
echo ${INPUT_TEMPLATE} | jq --arg service "${ser}" --arg OUT "${OUT_NAME}" '.daemon |= (.service_name = $service |.output.name = $OUT)' > ${dest}
else
echo ${INPUT_TEMPLATE} | jq --arg service "${ser}" '.daemon.service_name = $service' > ${dest}
fi
chmod 466 ${dest}
}
if [ -z "$SRC" ] || [ -z "${DEST}" ] ; then
echo "# BBFDM Null value in src[${SRC}], dest[${DEST}]"
exit 1
@@ -136,6 +135,40 @@ if [ "${SCRIPT}" -eq "1" ]; then
exit 0
fi
if [ "${INPUT_FILE}" -eq "1" ]; then
tempfile=""
if [ ! -f "${SRC}" ]; then
echo "# Datamodel Input file ${SRC} not available"
exit 1
fi
if ! cat ${SRC} |jq >/dev/null 2>&1; then
echo "# Invalid datamodel json input file"
exit 1
fi
service_name="$(cat ${SRC}|jq -r '.daemon.service_name')"
if [ -z "${service_name}" ]; then
echo "# service_name not defined in service json ...."
exit 1
fi
tempfile=$(mktemp)
cp ${SRC} ${tempfile}
if [ -n "${VENDOR_EXTN}" ]; then
sed -i "s/{BBF_VENDOR_PREFIX}/${VENDOR_EXTN}/g" ${tempfile}
fi
install_dir ${DEST}/etc/bbfdm/services
install_data ${tempfile} ${DEST}/etc/bbfdm/services/${service_name}.json
if [ -f "${tempfile}" ]; then
rm ${tempfile}
fi
exit 0
fi
if [ "${MICRO_SERVICE}" -eq "1" ]; then
if [ -z "${DATA}" ]; then
echo "# service_name[${DATA}] not provided"
@@ -146,23 +179,24 @@ if [ "${MICRO_SERVICE}" -eq "1" ]; then
extn="$(basename ${SRC})"
install_dir ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services
bbfdm_install_dm ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/${DATA}.${extn##*.}
# main micro-service datamodel plugin, create an input file as well
install_dir ${DEST}/${BBFDM_INPUT_PATH}
bbfdm_generate_input ${DEST}/${BBFDM_INPUT_PATH}/ ${DATA}
else
install_dir ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/${DATA}
bbfdm_install_dm ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/${DATA}/$(basename ${SRC})
bbfdm_install_dm ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/${DATA}/$(printf "%02d" ${EXTRA_DATA})$(basename ${SRC})
fi
else
if [ "${PLUGIN}" -eq "1" ]; then
echo "# WARNING: BBFDM_INSTALL_CORE_PLUGIN macro will be deprecated soon. Please use BBFDM_INSTALL_MS_PLUGIN macro instead, specifying 'core' as micro-service name #"
priority="${DATA:-0}"
install_dir ${DEST}/${BBFDM_BASE_DM_PATH}/plugins
install_dir ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/core
if [ "${priority}" -gt "0" ]; then
# install with priority if defined
bbfdm_install_dm ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/plugins/${priority}_$(basename ${SRC})
bbfdm_install_dm ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/core/${priority}_$(basename ${SRC})
elif [ "${priority}" -eq "0" ]; then
bbfdm_install_dm ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/core/$(basename ${SRC})
else
bbfdm_install_dm ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/plugins/$(basename ${SRC})
echo "# Priority should be an unsigned integer"
exit 1
fi
fi
fi

View File

@@ -27,6 +27,7 @@ obj_schema = {
"protocols_t": {
"type": "string",
"enum": [
"none",
"cwmp",
"usp"
]
@@ -227,6 +228,7 @@ event_schema = {
"protocols_t": {
"type": "string",
"enum": [
"none",
"usp"
]
}
@@ -254,6 +256,7 @@ command_schema = {
"protocols_t": {
"type": "string",
"enum": [
"none",
"usp"
]
}

45
blkpg-part/Makefile Normal file
View File

@@ -0,0 +1,45 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2025 IOPSYS Software Solutions AB
include $(TOPDIR)/rules.mk
PKG_NAME:=blkpg-part
PKG_VERSION:=1
PKG_RELEASE:=1
PKG_SOURCE_VERSION:=5a4ec5f53ed904b37fba03f3797fbe2af3077f8d
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/gportay/blkpg-part.git
PKG_MIRROR_HASH:=skip
PKG_MAINTAINER:=Andreas Gnau <andreas.gnau@iopsys.eu>
PKG_LICENSE:=LGPL-2.1-or-later
PKG_LICENSE_FILES:=LICENSE
PKG_BUILD_PARALLEL:=1
PKG_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
MAKE_INSTALL_FLAGS += PREFIX=/usr
define Package/$(PKG_NAME)
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=Disc
TITLE:=User space partition table and disk geometry handling utility
URL:=https://www.portay.io/blkpg-part/
endef
define Package/$(PKG_NAME)/description
blkpg-part creates temporary partitions that are not part of the GPT/MBR.
It makes a partition block device from any consecutive blocks that are
not partitioned. It creates, resizes and deletes partitions on the fly
without writing back the changes to the partition table.
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/blkpg-part $(1)/usr/sbin/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,11 +0,0 @@
if PACKAGE_bridgemngr
menu "Configuration"
config BRIDGEMNGR_BRIDGE_VLAN
bool "Use bridge-vlan backend"
help
Set this option to use bridge-vlan as backend for VLAN objects.
endmenu
endif

View File

@@ -1,61 +0,0 @@
#
# Copyright (C) 2020-2024 iopsys
#
include $(TOPDIR)/rules.mk
PKG_NAME:=bridgemngr
PKG_VERSION:=1.0.5
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/bridgemngr
PKG_SOURCE_VERSION:=c0f2e17f6d4f96aecfe72ab90be885939413176d
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
PKG_LICENSE:=GPL-2.0-only
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
include ../bbfdm/bbfdm.mk
define Package/bridgemngr
CATEGORY:=Utilities
TITLE:=Bridge Manager
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libbbfdm-api
endef
define Package/bridgemngr/description
Package to add Device.Bridging. data model support.
endef
define Package/$(PKG_NAME)/config
source "$(SOURCE)/Config.in"
endef
MAKE_PATH:=src
TARGET_CFLAGS += -DBBF_VENDOR_PREFIX=\\\"$(CONFIG_BBF_VENDOR_PREFIX)\\\"
ifeq ($(CONFIG_BRIDGEMNGR_BRIDGE_VLAN),y)
TARGET_CFLAGS += -DBRIDGE_VLAN_BACKEND
endif
define Package/bridgemngr/install
$(BBFDM_INSTALL_MS_DM) $(PKG_BUILD_DIR)/src/libbridgemngr.so $(1) $(PKG_NAME)
ifeq ($(findstring iopsys,$(CONFIG_BBF_VENDOR_LIST)),iopsys)
$(BBFDM_INSTALL_MS_PLUGIN) $(PKG_BUILD_DIR)/src/libbridgeext.so $(1) $(PKG_NAME)
endif
endef
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
$(CP) ~/git/bridgemngr/* $(PKG_BUILD_DIR)/
endef
endif
$(eval $(call BuildPackage,bridgemngr))

View File

@@ -7,13 +7,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bulkdata
PKG_VERSION:=2.1.12
PKG_VERSION:=2.1.20
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/bulkdata.git
PKG_SOURCE_VERSION:=1c780a8a8f7b5b49aba394da5cfe5ccb10c28652
PKG_SOURCE_VERSION:=a5e57962938ca143ede65d92be90b6e9fce66e15
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -24,12 +24,17 @@ PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/feeds/iopsys/bbfdm/bbfdm.mk
define Package/$(PKG_NAME)
define Package/bulkdata
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=TRx69
TITLE:=BBF BulkData Collection
DEPENDS:=+libubus +libuci +libubox +libjson-c +libcurl +libblobmsg-json +zlib
DEPENDS:=+ubus +libuci +libubox +libjson-c +libcurl +libblobmsg-json +zlib
DEPENDS+=+libbbfdm-api +libbbfdm-ubus
endef
define Package/bulkdata/description
BulkData daemon for TR069 with bbfdm backend.
endef
TARGET_CFLAGS += \
@@ -42,16 +47,15 @@ define Build/Prepare
endef
endif
define Package/$(PKG_NAME)/install
define Package/bulkdata/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bulkdatad $(1)/usr/sbin/
$(INSTALL_DATA) ./files/etc/config/bulkdata $(1)/etc/config/
$(INSTALL_BIN) ./files/etc/init.d/bulkdatad $(1)/etc/init.d/
$(INSTALL_DATA) ./files/etc/uci-defaults/95-bulkdata-translation-options $(1)/etc/uci-defaults/
$(BBFDM_INSTALL_MS_DM) $(PKG_BUILD_DIR)/bbf_plugin/bulkdata.json $(1) $(PKG_NAME)
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) $(PKG_NAME)
endef
$(eval $(call BuildPackage,$(PKG_NAME)))
$(eval $(call BuildPackage,bulkdata))

View File

@@ -0,0 +1,17 @@
{
"daemon": {
"enable": "1",
"service_name": "bulkdata",
"unified_daemon": true,
"proto": "cwmp",
"services": [
{
"parent_dm": "Device.",
"object": "BulkData"
}
],
"config": {
"loglevel": "3"
}
}
}

View File

@@ -1,960 +0,0 @@
{
"json_plugin_version": 2,
"Device.BulkData.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"access": false,
"array": false,
"Enable": {
"type": "boolean",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "boolean",
"mapping": [
{
"type": "uci",
"uci": {
"file": "bulkdata",
"section": {
"name": "bulkdata"
},
"option": {
"name": "enable"
}
}
}
]
},
"Status": {
"type": "string",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"enumerations": [
"Enabled",
"Disabled",
"Error"
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "bulkdata",
"section": {
"name": "bulkdata"
},
"option": {
"name": "enable"
}
}
}
]
},
"MinReportingInterval": {
"type": "unsignedInt",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"default": "0",
"datatype": "unsignedInt",
"unit": "seconds"
},
"Protocols": {
"type": "string",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"default": "HTTP",
"list": {
"datatype": "string",
"enumerations": [
"Streaming",
"File",
"HTTP",
"MQTT"
]
}
},
"EncodingTypes": {
"type": "string",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"default": "JSON,CSV",
"list": {
"datatype": "string",
"enumerations": [
"XML",
"XDR",
"CSV",
"JSON"
]
}
},
"ParameterWildCardSupported": {
"type": "boolean",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"default": "1",
"datatype": "boolean"
},
"MaxNumberOfProfiles": {
"type": "int",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"default": "-1",
"datatype": "int",
"range": [
{
"min": -1
}
]
},
"MaxNumberOfParameterReferences": {
"type": "int",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"default": "-1",
"datatype": "int",
"range": [
{
"min": -1
}
]
},
"ProfileNumberOfEntries": {
"type": "unsignedInt",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"datatype": "unsignedInt",
"mapping": [
{
"type": "uci",
"uci": {
"file": "bulkdata",
"section": {
"type": "profile"
},
"option": {
"name": "@Count"
}
}
}
]
},
"Device.BulkData.Profile.{i}.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"access": true,
"array": true,
"mapping": [
{
"type": "uci",
"uci": {
"file": "bulkdata",
"section": {
"type": "profile"
},
"dmmapfile": "dmmap_bulkdata"
}
}
],
"Enable": {
"type": "boolean",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "boolean",
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "enable"
}
]
},
"Alias": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "Alias",
"range": [
{
"max": 64
}
],
"flags": [
"Unique"
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "alias"
}
]
},
"Name": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"range": [
{
"max": 255
}
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "name"
}
]
},
"NumberOfRetainedFailedReports": {
"type": "int",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "int",
"range": [
{
"min": -1
}
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "nbre_of_retained_failed_reports"
}
]
},
"Protocol": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"enumerations": [
"Streaming",
"File",
"HTTP"
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "protocol"
}
]
},
"EncodingType": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"enumerations": [
"XML",
"XDR",
"CSV",
"JSON"
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "encoding_type"
}
]
},
"ReportingInterval": {
"type": "unsignedInt",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "unsignedInt",
"range": [
{
"min": 1
}
],
"unit": "seconds",
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "reporting_interval"
}
]
},
"TimeReference": {
"type": "dateTime",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "dateTime",
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "time_reference"
}
]
},
"ParameterNumberOfEntries": {
"type": "unsignedInt",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"datatype": "unsignedInt",
"mapping": [
{
"type": "uci",
"uci": {
"file": "bulkdata",
"section": {
"type": "profile_parameter"
},
"option": {
"name": "@Count"
}
}
}
]
},
"Device.BulkData.Profile.{i}.Parameter.{i}.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"access": true,
"array": true,
"mapping": [
{
"type": "uci",
"uci": {
"file": "bulkdata",
"section": {
"type": "profile_parameter"
},
"dmmapfile": "dmmap_bulkdata"
}
}
],
"Name": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"range": [
{
"max": 64
}
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "name"
}
]
},
"Reference": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"range": [
{
"max": 256
}
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "reference"
}
]
}
},
"Device.BulkData.Profile.{i}.CSVEncoding.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"access": false,
"array": false,
"FieldSeparator": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "csv_encoding_field_separator"
}
]
},
"RowSeparator": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "csv_encoding_row_separator"
}
]
},
"EscapeCharacter": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "csv_encoding_escape_character"
}
]
},
"ReportFormat": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"enumerations": [
"ParameterPerRow",
"ParameterPerColumn"
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "csv_encoding_report_format"
}
]
},
"RowTimestamp": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"enumerations": [
"Unix-Epoch",
"ISO-8601",
"None"
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "csv_encoding_row_time_stamp"
}
]
}
},
"Device.BulkData.Profile.{i}.JSONEncoding.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"access": false,
"array": false,
"ReportFormat": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"enumerations": [
"ObjectHierarchy",
"NameValuePair"
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "json_encoding_report_format"
}
]
},
"ReportTimestamp": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"enumerations": [
"Unix-Epoch",
"ISO-8601",
"None"
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "json_encoding_report_time_stamp"
}
]
}
},
"Device.BulkData.Profile.{i}.HTTP.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"access": false,
"array": false,
"URL": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "URL",
"range": [
{
"max": 2048
}
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "http_url"
}
]
},
"Username": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"range": [
{
"max": 256
}
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "http_username"
}
]
},
"Password": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"range": [
{
"max": 256
}
],
"flags": [
"Secure"
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "http_password"
}
]
},
"CompressionsSupported": {
"type": "string",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"default": "GZIP",
"list": {
"datatype": "string",
"enumerations": [
"GZIP",
"Compress",
"Deflate"
]
}
},
"Compression": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"enumerations": [
"GZIP",
"Compress",
"Deflate"
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "http_compression"
}
]
},
"MethodsSupported": {
"type": "string",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"default": "POST,PUT",
"list": {
"datatype": "string",
"enumerations": [
"POST",
"PUT"
]
}
},
"Method": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"enumerations": [
"POST",
"PUT"
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "http_method"
}
]
},
"UseDateHeader": {
"type": "boolean",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "boolean",
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "http_use_date_header"
}
]
},
"RetryEnable": {
"type": "boolean",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "boolean",
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "http_retry_enable"
}
]
},
"RetryMinimumWaitInterval": {
"type": "unsignedInt",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "unsignedInt",
"range": [
{
"min": 1,
"max": 65535
}
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "http_retry_minimum_wait_interval"
}
]
},
"RetryIntervalMultiplier": {
"type": "unsignedInt",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "unsignedInt",
"range": [
{
"min": 1000,
"max": 65535
}
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "http_retry_interval_multiplier"
}
]
},
"RequestURIParameterNumberOfEntries": {
"type": "unsignedInt",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"datatype": "unsignedInt",
"mapping": [
{
"type": "uci",
"uci": {
"file": "bulkdata",
"section": {
"type": "profile_http_request_uri_parameter"
},
"option": {
"name": "@Count"
}
}
}
]
},
"PersistAcrossReboot": {
"type": "boolean",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "boolean",
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "http_persist_across_reboot"
}
]
},
"Device.BulkData.Profile.{i}.HTTP.RequestURIParameter.{i}.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"access": true,
"array": true,
"mapping": [
{
"type": "uci",
"uci": {
"file": "bulkdata",
"section": {
"type": "profile_http_request_uri_parameter"
},
"dmmapfile": "dmmap_bulkdata"
}
}
],
"Name": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"range": [
{
"max": 64
}
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "name"
}
]
},
"Reference": {
"type": "string",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"range": [
{
"max": 256
}
],
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "reference"
}
]
}
}
}
}
}
}

View File

@@ -1,6 +1,6 @@
config bulkdata 'bulkdata'
option enable '0'
#Log levels: Error=1, Warning=2, Info=3, Debug=4
option log_level '3'
#Log levels: As per syslog 0-7, default 6=>LOG_INFO
option loglevel '3'

View File

@@ -6,35 +6,36 @@ STOP=10
USE_PROCD=1
PROG="/usr/sbin/bulkdatad"
validate_global_section() {
uci_validate_section bulkdata bulkdata bulkdata \
'enable:bool:1' \
'loglevel:uinteger:3'
}
start_service() {
local enable
local enable loglevel
config_load bulkdata
config_get_bool enable bulkdata enable 1
validate_global_section
if [ ! -f "/var/state/bulkdatad" ]; then
touch /var/state/bulkdatad
uci -q -c /var/state set bulkdatad.global='global'
uci -q -c /var/state commit bulkdatad
fi
if [ "$enable" -eq "1" ]; then
procd_open_instance "bulkdata"
procd_set_param command "$PROG"
procd_set_param respawn
procd_close_instance "bulkdata"
else
uci -q -c /var/state set bulkdatad.global.status='Disabled'
uci -q -c /var/state commit bulkdatad
fi
procd_open_instance "bulkdata"
procd_set_param command "$PROG"
procd_append_param command -l ${loglevel}
procd_set_param respawn
procd_close_instance "bulkdata"
}
reload_service() {
stop
start
ret=$(ubus call service list '{"name":"bulkdatad"}' | jsonfilter -qe '@.bulkdatad.instances.bulkdata.running')
if [ "$ret" != "true" ]; then
stop
start
else
ubus send bulkdata.reload
fi
return 0
}
service_triggers()
{
service_triggers() {
procd_add_reload_trigger bulkdata
}

View File

@@ -1,75 +0,0 @@
#!/bin/sh
. /lib/functions.sh
PROFILE_COUNT=1
get_next_count()
{
local config="$1"
local default_name="${2}"
local count=${3}
local found=0
if [ -z "$count" ]; then
count=1
fi
while [ "${found}" -ne 1 ]; do
uci -q get "${config}"."${default_name}"_${count} >/dev/null
if [ "$?" -eq 0 ]; then
count=$((count + 1))
else
found=1;
fi
done
echo "${default_name}_${count}"
}
translate_profile_id_to_profile_name() {
local section="${1}"
local profile_id="${2}"
local profile_name="${3}"
local curr_profile_id
config_get curr_profile_id "${section}" profile_id
[ -n "${curr_profile_id}" ] || return
[ "${curr_profile_id}" != "${profile_id}" ] && return
uci -q set bulkdata."${section}".profile_name="${profile_name}"
uci -q set bulkdata."${section}".profile_id=""
}
update_profile_sections() {
local section="${1}"
local default="${2}"
local profile_name
config_get profile_id "${section}" profile_id
[ -n "${profile_id}" ] || return
case "${section}" in
"cfg"*)
profile_name="$(get_next_count bulkdata "${default}" ${PROFILE_COUNT})"
uci_rename bulkdata "${section}" "${profile_name}"
;;
esac
PROFILE_COUNT=$((PROFILE_COUNT + 1))
[ -n "$profile_name" ] && section="${profile_name}"
uci -q set bulkdata."${section}".profile_id=""
config_foreach translate_profile_id_to_profile_name profile_parameter "${profile_id}" "${profile_name}"
config_foreach translate_profile_id_to_profile_name profile_http_request_uri_parameter "${profile_id}" "${profile_name}"
}
config_load bulkdata
config_foreach update_profile_sections profile profile
uci commit bulkdata
exit 0

52
cmph/Makefile Normal file
View File

@@ -0,0 +1,52 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=cmph
PKG_VERSION:=2.0.2
PKG_RELEASE:=1
PKG_SOURCE:=cmph-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/cmph/
PKG_MD5SUM:=51ec5329b47774d251a96eaaafdb409e
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
PKG_FIXUP:=autoreconf
PKG_LICENSE:=LGPLv2
PKG_LICENSE_FILES:=LGPL-2
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=libs
CATEGORY:=Libraries
TITLE:=C Minimal Perfect Hashing library
URL:=https://sourceforge.net/projects/cmph/
endef
define Package/$(PKG_NAME)/description
C Minimal Perfect Hashing (CMPH) library allows the creation of minimal perfect hash functions for large data sets.
endef
define Build/Configure
$(call Build/Configure/Default)
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
$(INSTALL_DATA) $(PKG_BUILD_DIR)/src/cmph.h $(1)/usr/include/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/src/cmph_time.h $(1)/usr/include/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/src/cmph_types.h $(1)/usr/include/
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/src/.libs/libcmph.a $(1)/usr/lib/
$(CP) $(PKG_BUILD_DIR)/src/.libs/libcmph.so* $(1)/usr/lib/
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/src/.libs/libcmph.so* $(1)/usr/lib/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ddnsmngr
PKG_VERSION:=1.0.8
PKG_VERSION:=1.0.12
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/ddnsmngr.git
PKG_SOURCE_VERSION:=68c54ad5b537a7dfff7c939707bfe8f1a3023c46
PKG_SOURCE_VERSION:=44af9a7b3fec3929f8554af9633a5b8068189b48
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -28,7 +28,8 @@ define Package/$(PKG_NAME)
CATEGORY:=Utilities
SUBMENU:=TRx69
TITLE:=Dynamic DNS manager
DEPENDS:=+libbbfdm-api +DDNSMNGR_BACKEND_DDNSSCRIPT:ddns-scripts +DDNSMNGR_BACKEND_INADYN:inadyn
DEPENDS:=+DDNSMNGR_BACKEND_DDNSSCRIPT:ddns-scripts +DDNSMNGR_BACKEND_INADYN:inadyn
DEPENDS+=+libbbfdm-api +libbbfdm-ubus +dm-service
MENU:=1
endef
@@ -70,6 +71,7 @@ ifeq ($(CONFIG_DDNSMNGR_BACKEND_INADYN),y)
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/inadyn/server/* $(1)/etc/ddnsmngr/servers
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/inadyn/usr/libexec/rpcd/ddnsmngr $(1)/usr/libexec/rpcd/ddnsmngr
endif
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) $(PKG_NAME)
$(BBFDM_INSTALL_MS_DM) $(PKG_BUILD_DIR)/src/libddnsmngr.so $(1) $(PKG_NAME)
endef

View File

@@ -0,0 +1,16 @@
{
"daemon": {
"enable": "1",
"service_name": "ddnsmngr",
"unified_daemon": false,
"services": [
{
"parent_dm": "Device.",
"object": "DynamicDNS"
}
],
"config": {
"loglevel": "3"
}
}
}

View File

@@ -1,22 +1,23 @@
#
# Copyright (C) 2021-2023 IOPSYS Software Solutions AB
# Copyright (C) 2021-2024 IOPSYS Software Solutions AB
# Copyright (C) 2025 Genexis AB
#
include $(TOPDIR)/rules.mk
PKG_NAME:=decollector
PKG_VERSION:=6.1.0.0
PKG_VERSION:=6.2.1.7
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=2efa50c2bb5b8d5ed3e72c27395a7f2516bcbd44
PKG_SOURCE_VERSION:=ca92325ece080389ffb405c95048b64071eda653
PKG_SOURCE_URL:=https://dev.iopsys.eu/multi-ap/decollector.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@iopsys.eu>
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@genexis.eu>
PKG_LICENSE:=BSD-3-Clause

View File

@@ -2,13 +2,13 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=dectmngr
PKG_RELEASE:=3
PKG_VERSION:=3.6.9
PKG_VERSION:=3.7.10
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/dectmngr.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=c5254120c2c8b43936e2f9f4f9a3827784d60a43
PKG_SOURCE_VERSION:=1f851980a6ba616df54f79930225f8bcd563b711
PKG_MIRROR_HASH:=skip
endif
@@ -28,7 +28,7 @@ include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
CATEGORY:=Utilities
TITLE:=DECT Manager
DEPENDS:= +libubox +ubus +uci +libxml2 +libjson-c +gpiod-tools
DEPENDS:= +libubox +ubus +uci +libxml2 +libjson-c +gpiod-tools +voicemngr
endef
define Package/$(PKG_NAME)/description
@@ -56,11 +56,14 @@ endif
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/etc
$(INSTALL_DIR) $(1)/etc/dspg
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
$(INSTALL_BIN) $(PKG_BUILD_DIR)/app/dectmngr $(1)/usr/sbin/
$(STRIP) $(1)/usr/sbin/dectmngr
ifeq ($(CONFIG_TARGET_airoha),)
$(CP) ./firmware/common/* $(1)/etc/dspg/
endif
$(CP) ./files/etc/* $(1)/etc/
$(INSTALL_DATA) ./files/lib/upgrade/keep.d/dect $(1)/lib/upgrade/keep.d/dect
endef

View File

@@ -1,3 +1,6 @@
config dect 'global'
option log_dect_cmbs 'syslog'
option log_level 'realtime,warning,error'
option log_dect_cmbs 'syslog'
option log_level 'realtime,warning,error'
config dect 'base'
option enable '1'

View File

@@ -11,6 +11,25 @@ LOG_PATH=/var/log/dectmngr
DB_PATH=/etc/dect
DCX81_UART_DT_ALIAS=/proc/device-tree/aliases/dcx81-uart
get_extension_shift() {
local dect_exts
get_dect_extension() {
local ext=$1
local type
config_get type $ext type
[ "$type" == "dect" ] && echo $ext
}
config_load "asterisk"
dect_exts=$(config_foreach get_dect_extension "extension" |sort |head -n1)
echo "${dect_exts#extension}"
}
# Ask dectmngr to exit nicely and wait for it to clean up, which is a slow process.
stop_and_wait_dectmngr() {
dect_pid=$(pidof $PROG)
@@ -38,13 +57,53 @@ get_dcx81_device() {
device_name_line="$(grep '^DEVNAME=' "$uevent_file")" || return 1
readonly device="/dev/${device_name_line##DEVNAME=}"
[ -c "$device" ] || return 1
printf "%s" "$device"
printf "%s" "$(basename $device)"
return 0
fi
done
return 1
}
check_dcx81_firmware() {
local dcx81_uart=$1
local fw_link="/lib/firmware/dcx81_firmware"
local fw_file
[ -L "$fw_link" ] || return
fw_file=$(readlink -f $fw_link)
[ -f "$fw_file" ] || return
# the symbolic link is not needed
rm -f $fw_link
eval $(/sbin/cmbs_tcx -comname "$dcx81_uart" -fw_version |grep DCX81_FW_Version)
[ -n "$DCX81_FW_Version" ] || return
if echo $(basename $fw_file) | grep -qi "$DCX81_FW_Version" ; then
logger -t "$PROG" "DCX81 running expected $DCX81_FW_Version"
return;
fi
logger -t "$PROG" "DCX81 firmware upgrading to $fw_file"
/sbin/cmbs_tcx -comname "$dcx81_uart" -fwu "$fw_file" 2>&1 >/dev/null &
echo -n "Updrading DCX81 firmware.." >/dev/console
local wait_time=0
while pidof cmbs_tcx >/dev/null && [ "$wait_time" -lt "200" ] ; do
sleep 5
wait_time=$(($wait_time + 5))
echo -n "." >/dev/console
done
if pidof cmbs_tcx >/dev/null ; then
killall -9 cmbs_tcx
logger -t "$PROG" "DCX81 firmware upgrade timeout"
else
logger -t "$PROG" "DCX81 firmware upgrade done"
fi
}
start_service() {
local opt_ext=
local rfpi=
@@ -59,9 +118,13 @@ start_service() {
local dcx81_uart_device
if ! dcx81_uart_device="$(get_dcx81_device)"; then
logger -t "$PROG" -p daemon.warning "Could not determine DCX81 UART device. Falling back to default ttyH0."
dcx81_uart_device=/dev/ttyH0
dcx81_uart_device="ttyH0"
fi
check_dcx81_firmware $dcx81_uart_device
opt_ext="-extensionShift $(get_extension_shift)"
rfpi=$(db -q get hw.board.dect_rfpi)
[ -n "$rfpi" -a ${#rfpi} -eq 14 ] && opt_ext="$opt_ext -rfpi $rfpi"
@@ -77,24 +140,27 @@ start_service() {
config_load dect
config_get log_dect_cmbs global log_dect_cmbs syslog
config_get pcm_slot_start global pcm_slot_start
config_get pcm_fsync global pcm_fsync
[ -n "$pcm_fsync" ] && opt_ext="$opt_ext -sync $pcm_fsync"
[ -n "$pcm_slot_start" ] && opt_ext="$opt_ext -slotsShift $pcm_slot_start"
procd_open_instance
# dectmngr takes expects device without /dev
readonly dcx81_uart_device_wo_dev="${dcx81_uart_device##/dev/}"
case "$log_dect_cmbs" in
none)
echo "Starting dectmngr with cmbs logging disabled"
procd_set_param command "$PROG" -comname "$dcx81_uart_device_wo_dev" $opt_ext
procd_set_param command "$PROG" -comname "$dcx81_uart_device" $opt_ext
rm -f $LOG_PATH/*
;;
file)
echo "Starting dectmngr with cmbs logging enabled to file"
procd_set_param command "$PROG" -comname "$dcx81_uart_device_wo_dev" -log $LOG_PATH/dect-cmbs.log $opt_ext
procd_set_param command "$PROG" -comname "$dcx81_uart_device" -log $LOG_PATH/dect-cmbs.log $opt_ext
;;
*)
echo "Starting dectmngr with cmbs logging enabled to syslog"
procd_set_param command "$PROG" -comname "$dcx81_uart_device_wo_dev" -syslog $opt_ext
procd_set_param command "$PROG" -comname "$dcx81_uart_device" -syslog $opt_ext
rm -f $LOG_PATH/*
;;
esac

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dhcpmngr
PKG_VERSION:=1.0.3
PKG_VERSION:=1.0.6
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/dhcpmngr.git
PKG_SOURCE_VERSION:=93f756f80a9391afd9b01f2608e031c4db3ca48b
PKG_SOURCE_VERSION:=986f66608959f4f589009d580b046e250d8c620d
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -28,9 +28,11 @@ define Package/dhcpmngr
SECTION:=net
CATEGORY:=Network
TITLE:=Package to add Device.DHCPv4 and v6 data model support.
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api +odhcpd
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c
DEPENDS+=+libbbfdm-api +libbbfdm-ubus +dm-service
DEPENDS+=+DNSMNGR_DNS_SD:umdns
DEPENDS+=+DNSMNGR_BACKEND_DNSMASQ:dnsmasq
DEPENDS+=+DNSMNGR_BACKEND_UNBOUND:odhcpd
endef
define Package/dhcpmngr/description
@@ -50,6 +52,7 @@ ifeq ($(CONFIG_DNSMNGR_BACKEND_UNBOUND),y)
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DATA) ./files/etc/uci-defaults/unbound.odhcpd.uci_default $(1)/etc/uci-defaults/16-set-unbound-as-odhcpd-leasetrigger
endif
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) $(PKG_NAME)
$(BBFDM_INSTALL_MS_DM) $(PKG_BUILD_DIR)/src/libdhcpmngr.so $(1) $(PKG_NAME)
endef

View File

@@ -0,0 +1,20 @@
{
"daemon": {
"enable": "1",
"service_name": "dhcpmngr",
"unified_daemon": false,
"services": [
{
"parent_dm": "Device.",
"object": "DHCPv4"
},
{
"parent_dm": "Device.",
"object": "DHCPv6"
}
],
"config": {
"loglevel": "3"
}
}
}

View File

@@ -10,7 +10,6 @@ uci -q get dhcp.odhcpd >/dev/null 2>&1 && {
[ -e /usr/lib/unbound/odhcpd.sh ] && [ -e /usr/sbin/unbound ] && {
# then set unbound script as leasetrigger in dhcp UCI
uci -q set dhcp.odhcpd.leasetrigger='/usr/lib/unbound/odhcpd.sh'
uci commit dhcp
}
}
}

Binary file not shown.

View File

@@ -0,0 +1,76 @@
#
# Copyright (c) 2023 Genexis B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
#
include $(TOPDIR)/rules.mk
PKG_NAME:=datamodels
PKG_VERSION:=1.0.0
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=utils
CATEGORY:=Genexis
TITLE:=GeneOS Datamodel
URL:=http://www.genexis.eu
PKG_LICENSE:=GENEXIS
PKG_LICENSE_URL:=
endef
define Package/$(PKG_NAME)/description
This package contains GeneOS datamodel.
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) -rf ./src/* $(PKG_BUILD_DIR)/
cd $(PKG_BUILD_DIR); \
npm install better-sqlite3 quickjs && \
node ./scripts/json2code.js && \
node ./scripts/qjs-handlers-validate.js
endef
TARGET_CFLAGS += $(FPIC) -I$(PKG_BUILD_DIR)
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR)\
PROJECT_ROOT="$(PKG_BUILD_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
EXTRA_CFLAGS="$(TARGET_CFLAGS)" \
all
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/dm_types.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/dm_node.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/dm.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/libdm.so $(1)/usr/lib/
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/bbfdm
$(INSTALL_DIR) $(1)/usr/lib/dmf_handlers
$(INSTALL_BIN) $(PKG_BUILD_DIR)/default.db $(1)/etc/bbfdm/default_dm.db
$(INSTALL_BIN) $(PKG_BUILD_DIR)/libdm.so $(1)/usr/lib/
# Copy only .js handler files recursively, preserving folder structure (skip hidden files/folders)
( cd $(PKG_BUILD_DIR)/dm-files; \
find . -type d -not -path './.*' -exec $(INSTALL_DIR) $(1)/usr/lib/dmf_handlers/{} \; ; \
find . -type f -name '*.js' -not -path './.*' -exec $(INSTALL_BIN) {} $(1)/usr/lib/dmf_handlers/{} \; )
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

Binary file not shown.

View File

@@ -0,0 +1,41 @@
#
# Copyright (c) 2023 Genexis B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
#
PROG = libdm.so
SRCS = dm_node.c
# the next files are generated
SRCS += dm.c
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
CC = $(CROSS_COMPILE)gcc
STRIP = $(CROSS_COMPILE)strip
CFLAGS = -I$(STAGING_DIR)/usr/include $(EXTRA_CFLAGS)
CFLAGS += -MMD -MP
LDFLAGS = -shared
CFLAGS += -Wall -Werror -fpic
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $^ $(LDFLAGS) -o $@
%.o: %.c
$(CC) $(CFLAGS) -c $^ -o $@
clean:
rm -f $(PROG) *.o core $(DEPS) dm.c dm.h
-include $(DEPS)

View File

@@ -0,0 +1,443 @@
[
{
"object": "Device.Bridging.",
"access": "readOnly",
"parameters": [
{
"name": "MaxBridgeEntries",
"access": "readOnly",
"dataType": "unsignedInt",
"const" : "4094"
},
{
"name": "MaxDBridgeEntries",
"access": "readOnly",
"dataType": "unsignedInt",
"const" : "4094"
},
{
"name": "MaxQBridgeEntries",
"access": "readOnly",
"dataType": "unsignedInt",
"const" : "4094"
},
{
"name": "MaxVLANEntries",
"access": "readOnly",
"dataType": "unsignedInt",
"const" : "4094"
},
{
"name": "BridgeNumberOfEntries",
"access": "readOnly",
"dataType": "unsignedInt"
}
]
},
{
"object": "Device.Bridging.Bridge.{i}.",
"uniqueKeys": "Name,Alias",
"access": "readWrite",
"uci": "network.device",
"parameters": [
{
"name": "Enable",
"access": "readWrite",
"dataType": "boolean",
"uci": "enabled",
"uci-default": "true"
},
{
"name": "Name",
"access": "readOnly",
"dataType": "string(:64)",
"set_on_create": "bridge_",
"db": true
},
{
"name": "Alias",
"access": "readWrite",
"dataType": "string(:64)"
},
{
"name": "Status",
"access": "readOnly",
"dataType": "enum",
"enum": [
"Disabled",
"Enabled",
"Error"
],
"default": "Disabled"
},
{
"name": "Standard",
"access": "readWrite",
"dataType": "enum",
"enum": [
"802.1D-2004",
"802.1Q-2005",
"802.1Q-2011"
],
"default": "802.1Q-2011"
},
{
"name": "PortNumberOfEntries",
"access": "readOnly",
"dataType": "unsignedInt"
},
{
"name": "VLANNumberOfEntries",
"access": "readOnly",
"dataType": "unsignedInt"
},
{
"name": "VLANPortNumberOfEntries",
"access": "readOnly",
"dataType": "unsignedInt"
}
]
},
{
"object": "Device.Bridging.Bridge.{i}.STP.",
"access": "readOnly",
"parameters": [
{
"name": "Enable",
"access": "readWrite",
"dataType": "boolean",
"uci": "stp"
},
{
"name": "Status",
"access": "readOnly",
"dataType": "enum",
"enum": [
"Disabled",
"Enabled",
"Error_Misconfigured",
"Error"
],
"default": "Disabled"
},
{
"name": "Protocol",
"access": "readWrite",
"dataType": "enum",
"enum": [
"STP",
"RSTP"
]
},
{
"name": "BridgePriority",
"access": "readWrite",
"dataType": "unsignedInt(0:61440)",
"default": "32768"
},
{
"name": "HelloTime",
"access": "readWrite",
"dataType": "unsignedInt(100:1000)",
"default": "200"
},
{
"name": "MaxAge",
"access": "readWrite",
"dataType": "unsignedInt(600:4000)",
"default": "2000"
},
{
"name": "ForwardingDelay",
"access": "readWrite",
"dataType": "unsignedInt(4:30)",
"default": "15"
}
]
},
{
"object": "Device.Bridging.Bridge.{i}.Port.{i}.",
"uniqueKeys": "Alias,Name",
"access": "readWrite",
"parameters": [
{
"name": "Enable",
"access": "readWrite",
"dataType": "boolean"
},
{
"name": "Status",
"access": "readOnly",
"dataType": "enum",
"enum": [
"Up",
"Down",
"Unknown",
"Dormant",
"NotPresent",
"LowerLayerDown",
"Error"
],
"default": "Down"
},
{
"name": "Alias",
"access": "readWrite",
"dataType": "string(:64)"
},
{
"name": "Name",
"access": "readOnly",
"dataType": "string(:64)",
"set_on_create": "port_",
"db": "true",
"flags": [
"linker"
],
"js-value": "ifname"
},
{
"name": "LastChange",
"access": "readOnly",
"dataType": "unsignedInt",
"const": "0"
},
{
"name": "LowerLayers",
"access": "readWrite",
"dataType": "pathRef[]",
"pathRef": [
"Device.Bridging.Bridge.{i}.Port."
],
"js-value": "ssidPath"
},
{
"name": "ManagementPort",
"access": "readWrite",
"dataType": "boolean"
},
{
"name": "PriorityRegeneration",
"access": "readWrite",
"dataType": "unsignedInt(0:7)[]",
"default": "0,1,2,3,4,5,6,7"
},
{
"name": "{BBF_VENDOR_PREFIX}EgressPriorityRegeneration",
"access": "readWrite",
"dataType": "unsignedInt(0:7)[]"
},
{
"name": "Type",
"access": "readWrite",
"dataType": "enum",
"enum": [
"ProviderNetworkPort",
"CustomerNetworkPort",
"CustomerEdgePort",
"CustomerVLANPort",
"VLANUnawarePort"
],
"default": "CustomerVLANPort"
},
{
"name": "PVID",
"access": "readWrite",
"dataType": "int(1:4094)",
"default": "1"
},
{
"name": "TPID",
"access": "readWrite",
"dataType": "unsignedInt",
"default": "33024"
}
]
},
{
"object": "Device.Bridging.Bridge.{i}.Port.{i}.Stats.",
"access": "readOnly",
"parameters": [
{
"name": "BytesSent",
"dataType": "unsignedLong"
},
{
"name": "BytesReceived",
"dataType": "unsignedLong"
},
{
"name": "PacketsSent",
"dataType": "unsignedLong"
},
{
"name": "PacketsReceived",
"dataType": "unsignedLong"
},
{
"name": "ErrorsSent",
"dataType": "StatsCounter32"
},
{
"name": "ErrorsReceived",
"dataType": "StatsCounter32"
},
{
"name": "UnicastPacketsSent",
"dataType": "unsignedLong"
},
{
"name": "DiscardPacketsSent",
"dataType": "StatsCounter32"
},
{
"name": "DiscardPacketsReceived",
"dataType": "StatsCounter32"
},
{
"name": "MulticastPacketsSent",
"dataType": "unsignedLong"
},
{
"name": "UnicastPacketsReceived",
"dataType": "unsignedLong"
},
{
"name": "MulticastPacketsReceived",
"dataType": "unsignedLong"
},
{
"name": "BroadcastPacketsSent",
"dataType": "unsignedLong"
},
{
"name": "BroadcastPacketsReceived",
"dataType": "unsignedLong"
},
{
"name": "UnknownProtoPacketsReceived",
"dataType": "StatsCounter32"
}
]
},
{
"object": "Device.Bridging.Bridge.{i}.VLAN.{i}.",
"uniqueKeys": "Alias,VLANID",
"access": "readWrite",
"parameters": [
{
"name": "Enable",
"access": "readWrite",
"dataType": "boolean"
},
{
"name": "Name",
"access": "readWrite",
"dataType": "string(:64)",
"set_on_create": "vlan_"
},
{
"name": "Alias",
"access": "readWrite",
"dataType": "string(:64)"
},
{
"name": "VLANID",
"access": "readWrite",
"dataType": "int(0:4094)"
}
]
},
{
"object": "Device.Bridging.Bridge.{i}.VLANPort.{i}.",
"uniqueKeys": "Alias,VLAN",
"access": "readWrite",
"parameters": [
{
"name": "Enable",
"access": "readWrite",
"dataType": "boolean"
},
{
"name": "Alias",
"access": "readWrite",
"dataType": "string(:64)"
},
{
"name": "VLAN",
"access": "readWrite",
"dataType": "pathRef",
"pathRef": [
"Device.Bridging.Bridge.{i}.VLAN."
]
},
{
"name": "Port",
"access": "readWrite",
"dataType": "pathRef",
"pathRef": [
"Device.Bridging.Bridge.{i}.Port."
]
},
{
"name": "Untagged",
"access": "readWrite",
"dataType": "boolean"
}
]
},
{
"object": "Device.Bridging.ProviderBridge.{i}.",
"uniqueKeys": "Alias",
"access": "readWrite",
"parameters": [
{
"name": "Enable",
"access": "readWrite",
"dataType": "boolean"
},
{
"name": "Status",
"access": "readOnly",
"dataType": "enum",
"enum": [
"Disabled",
"Enabled",
"Error_Misconfigured",
"Error"
],
"default": "Disabled"
},
{
"name": "Alias",
"access": "readWrite",
"dataType": "string(:64)"
},
{
"name": "Type",
"access": "readWrite",
"dataType": "enum",
"enum": [
"S-VLAN",
"PE"
]
},
{
"name": "SVLANcomponent",
"access": "readWrite",
"dataType": "pathRef",
"pathRef": [
"Device.Bridging.Bridge."
]
},
{
"name": "CVLANcomponents",
"access": "readWrite",
"dataType": "pathRef[]",
"pathRef": [
"Device.Bridging.Bridge."
]
}
]
}
]

View File

@@ -0,0 +1,166 @@
/*
* Copyright (c) 2025 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
import {
getUciOption, getUciByType, setUci, addUci, delUci
} from '../uci.js';
import * as dm from '../dm_consts.js';
import { getBridgeDeviceType } from './common.js';
function clearUnusedDevice(oldPorts, newPorts, devices) {
oldPorts?.forEach(port => {
if (port.includes('.') && !newPorts?.includes(port)) {
const dev = devices?.find(x => x.name === port);
if (dev?.['.name']) delUci('network', dev['.name']);
}
});
}
function applyBridge(bri, ports, VLANs, VLANPorts) {
const ifnames = [];
const devices = getUciByType('network', 'device')?.filter(x => x.type !== undefined);
const portsVal = getUciOption('network', bri._key, 'ports');
if (portsVal) delUci('network', bri._key, null, 'ports');
// get ports ethernet ifnames
for (const port of ports || []) {
if (port.ManagementPort || !port.LowerLayers.includes('Ethernet.Interface') || !port.Enable) {
continue;
}
let ifname = _dm_linker_value(port.LowerLayers);
if (!ifname) {
_log_error(`ifname not found for port: ${port.LowerLayers}`);
continue;
}
// check vlan
const portPath = `Device.Bridging.Bridge.${bri['.index']}.Port.${port['.index']}`;
const vp = VLANPorts?.find(x => x.Port === portPath);
if (!vp?.VLAN) {
ifnames.push(ifname);
continue;
}
// get index of the vlan
const [, indices] = _dm_node(vp.VLAN);
const vlanIdx = indices[indices.length - 1];
const vlan = VLANs?.find(x => x['.index'] === vlanIdx);
if (!vlan || vlan.VLANID <= 0) {
ifnames.push(ifname);
continue;
}
const eth = ifname;
ifname = `${ifname}.${vlan.VLANID}`;
const dev = devices?.find(x => x.name === ifname);
let devName;
if (dev) {
devName = dev['.name'];
} else {
devName = `br_${bri['.index']}_port_${vp['.index']}`;
addUci('network', 'device', devName, {
ifname: eth,
name: ifname,
vid: vlan.VLANID,
});
}
const uciConfigs = {};
// Handle Type parameter - determine device type based on port Type or default behavior
let deviceType = '';
if (port.Type) {
deviceType = getBridgeDeviceType(port.Type);
if (deviceType) uciConfigs.type = deviceType;
} else if (!vp.Untagged) {
uciConfigs.type = '8021q';
deviceType = '8021q';
}
// Handle TPID parameter
if (port.TPID) {
// If TPID is explicitly set, use it and derive device type if needed
uciConfigs.tpid = port.TPID;
// Set device type based on TPID if not already set
if (!deviceType) {
if (port.TPID === '33024') {
uciConfigs.type = '8021q';
} else if (port.TPID === '34984') {
uciConfigs.type = '8021ad';
}
}
}
uciConfigs.disabled = vlan.Enable && vp.Enable ? '0' : '1';
uciConfigs.ingress_qos_mapping = port.PriorityRegeneration !== '0,1,2,3,4,5,6,7'
? port.PriorityRegeneration.split(',').map((p, i) => `${i}:${p}`)
: '';
uciConfigs.egress_qos_mapping = port.X_IOPSYS_EU_EgressPriorityRegeneration !== ''
? port.X_IOPSYS_EU_EgressPriorityRegeneration.split(',').map((p, i) => `${i}:${p}`)
: '';
setUci('network', devName, uciConfigs);
ifnames.push(ifname);
}
clearUnusedDevice(portsVal, ifnames, devices);
if (ifnames.length > 0) {
setUci('network', bri._key, { ports: ifnames });
}
}
export function applyDeviceBridgingBridgePort(ports, bri) {
const vlans = _dm_get(dm.DM_DEVICE_BRIDGING_BRIDGE_VLAN, bri['.index']);
const vlanPorts = _dm_get(dm.DM_DEVICE_BRIDGING_BRIDGE_VLANPORT, bri['.index']);
applyBridge(bri, ports, vlans, vlanPorts);
}
export function applyDeviceBridgingBridgeVLAN(vlans, bri) {
const ports = _dm_get(dm.DM_DEVICE_BRIDGING_BRIDGE_PORT, bri['.index']);
const vlanPorts = _dm_get(dm.DM_DEVICE_BRIDGING_BRIDGE_VLANPORT, bri['.index']);
applyBridge(bri, ports, vlans, vlanPorts);
}
export function applyDeviceBridgingBridgeVLANPort(vlanPorts, bri) {
const ports = _dm_get(dm.DM_DEVICE_BRIDGING_BRIDGE_PORT, bri['.index']);
const vlans = _dm_get(dm.DM_DEVICE_BRIDGING_BRIDGE_VLAN, bri['.index']);
applyBridge(bri, ports, vlans, vlanPorts);
}
export function initDeviceBridgingBridge(bri) {
setUci('network', bri._key, {
type: 'bridge',
name: bri.Name,
enabled: '0',
});
// create empty interface for the bridge
addUci('network', 'interface', `itf_${bri._key}`, {
device: bri.Name,
bridge_empty: '1',
});
}
export const filterDeviceBridgingBridge = uci => uci.type === 'bridge';
export function deinitDeviceBridgingBridge(uci) {
const ports = getUciOption('network', uci, 'ports');
ports?.forEach(port => {
if (port.includes('.')) {
const dev = getUciByType('network', 'device', { match: { name: port } });
if (dev) delUci('network', dev[0]['.name']);
}
});
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright (c) 2025 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
import { getUciByType } from '../uci.js';
import { getBridgePortType, getTPIDFromDeviceType } from './common.js';
function importBridge(dev, devices, bridges) {
const briPorts = [];
const briVLAN = [];
const briVLANPort = [];
// create the management port first
briPorts.push({
Alias: `cpe-${dev.name}`,
Enable: 1,
Name: dev.name,
ManagementPort: 1,
PVID: 1,
TPID: 37120,
Type: 'CustomerVLANPort',
});
bridges.push({
Name: dev.name,
Alias: `cpe-${dev.name}`,
Enable: 1,
'Port.': briPorts,
'VLAN.': briVLAN,
'VLANPort.': briVLANPort,
_key: dev['.name'],
});
const ethPorts = devices.filter(x => x.ifname?.startsWith('eth'));
for (const portName of (dev.ports || [])) {
let portIndex = ethPorts.findIndex(x => x.ifname === portName);
if (portIndex >= 0) {
// Regular ethernet port
const ethDevice = ethPorts[portIndex];
const portType = getBridgePortType(ethDevice.type) || 'CustomerVLANPort';
const tpid = getTPIDFromDeviceType(ethDevice.type, ethDevice.tpid);
briPorts.push({
Enable: 1,
Name: ethDevice['.name'],
Alias: `cpe-${ethDevice['.name']}`,
TPID: tpid,
PVID: 1,
Type: portType,
LowerLayers: `Device.Ethernet.Interface.${portIndex + 1}`,
_key: ethDevice['.name'],
});
} else {
// vlan device
const device = devices.find(x => x.name === portName);
if (!device) {
_log_error('device not found', portName);
continue;
}
if (device.type === '8021q' || device.type === 'untagged' || device.type === '8021ad' || device.type === 'transparent') {
let vlanIndex = briVLAN.findIndex(x => x.VLANID === device.vid);
if (vlanIndex < 0) {
briVLAN.push({ Enable: 1, VLANID: device.vid });
vlanIndex = briVLAN.length;
} else {
vlanIndex += 1;
}
// Get the base ethernet device to determine the correct port index
const baseEthDevice = ethPorts.find(x => device.ifname === x.ifname);
const basePortIndex = baseEthDevice ? ethPorts.indexOf(baseEthDevice) : 0;
const portType = getBridgePortType(device.type) || 'CustomerVLANPort';
const tpid = getTPIDFromDeviceType(device.type, device.tpid);
briPorts.push({
Enable: 1,
Name: device['.name'],
Alias: `cpe-${device['.name']}`,
TPID: tpid,
PVID: device.vid,
Type: portType,
LowerLayers: `Device.Ethernet.Interface.${basePortIndex + 1}`,
_key: device['.name'],
});
briVLANPort.push({
Enable: 1,
VLAN: `Device.Bridging.Bridge.${bridges.length}.VLAN.${vlanIndex}`,
Port: `Device.Bridging.Bridge.${bridges.length}.Port.${briPorts.length}`,
Untagged: device.type === 'untagged' ? 1 : 0,
_key: device['.name'],
});
} else {
_log_error('unknown device type:', device.type);
}
}
}
if (briPorts.length > 1) {
const indexes = Array.from({ length: briPorts.length - 1 }, (v, i) => i + 2);
briPorts[0].LowerLayers = indexes.map(i => `Device.Bridging.Bridge.${bridges.length}.Port.${i}`).join(',');
}
}
export function importDeviceBridgingBridge() {
const bridges = [];
const devices = getUciByType('network', 'device');
devices?.forEach(dev => {
if (dev.type === 'bridge') {
importBridge(dev, devices, bridges);
}
});
return bridges;
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2025 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
import * as std from 'std';
import { isTrue } from '../utils.js';
import { getUciByType } from '../uci.js';
function setMgmtPortLowerLayers(bri) {
if (!bri) return 0;
const portPath = `Device.Bridging.Bridge.${bri['.index']}.Port.`;
const mgmtPort = _dm_instances(portPath, '(ManagementPort="true" OR ManagementPort=1)');
if (mgmtPort.length !== 1) return 0;
const nonMgmtPort = _dm_instances(portPath, '(ManagementPort="false" OR ManagementPort=0)');
_dm_update(`${mgmtPort[0]}.LowerLayers`, nonMgmtPort.join(','));
return 0;
}
export function changedDeviceBridgingBridgePort(bri) {
return setMgmtPortLowerLayers(bri);
}
export function changedDeviceBridgingBridgePortManagementPort(bri) {
return setMgmtPortLowerLayers(bri);
}
export function getDeviceBridgingBridgeStatus(bri) {
const enable = _dm_get(`Device.Bridging.Bridge.${bri['.index']}.Enable`);
return enable ? 'Enabled' : 'Disabled';
}
export function getDeviceBridgingBridgeSTPStatus(bri) {
const stpState = std.loadFile(`/sys/class/net/${bri.Name}/bridge/stp_state`)?.trim();
return stpState === '1' ? 'Enabled' : 'Disabled';
}
export function getDeviceBridgingBridgePortStatus(bri, port) {
if (!port['.db']) return 'Up';
const enable = _dm_get(`Device.Bridging.Bridge.${bri['.index']}.Port.${port['.index']}.Enable`);
return enable ? 'Up' : 'Down';
}
export function infoDeviceBridgingBridgePort(path, port) {
const mgmtPort = _dm_get(`${path}.ManagementPort`);
if (typeof mgmtPort === 'undefined' || mgmtPort) return;
const lower = _dm_get(`${path}.LowerLayers`);
if (lower) {
port.ifname = _dm_linker_value(lower);
}
}
// Helper function to read network statistics
function getNetworkStat(port, statName) {
return std.loadFile(`/sys/class/net/${port.ifname}/statistics/${statName}`)?.trim();
}
export const getDeviceBridgingBridgePortStatsBytesSent = (bri, port) =>
getNetworkStat(port, 'tx_bytes');
export const getDeviceBridgingBridgePortStatsBytesReceived = (bri, port) =>
getNetworkStat(port, 'rx_bytes');
export const getDeviceBridgingBridgePortStatsPacketsSent = (bri, port) =>
getNetworkStat(port, 'tx_packets');
export const getDeviceBridgingBridgePortStatsPacketsReceived = (bri, port) =>
getNetworkStat(port, 'rx_packets');
export const getDeviceBridgingBridgePortStatsErrorsSent = (bri, port) =>
getNetworkStat(port, 'tx_errors');
export const getDeviceBridgingBridgePortStatsErrorsReceived = (bri, port) =>
getNetworkStat(port, 'rx_errors');
export const getDeviceBridgingBridgePortStatsDiscardPacketsSent = (bri, port) =>
getNetworkStat(port, 'tx_dropped');
export const getDeviceBridgingBridgePortStatsDiscardPacketsReceived = (bri, port) =>
getNetworkStat(port, 'rx_dropped');
export const getDeviceBridgingBridgePortStatsMulticastPacketsReceived = (bri, port) =>
getNetworkStat(port, 'multicast');
export const getDeviceBridgingBridgePortStatsUnicastPacketsSent = (bri, port) =>
getNetworkStat(port, 'tx_unicast_packets');
export const getDeviceBridgingBridgePortStatsUnicastPacketsReceived = (bri, port) =>
getNetworkStat(port, 'rx_unicast_packets');
export const getDeviceBridgingBridgePortStatsMulticastPacketsSent = (bri, port) =>
getNetworkStat(port, 'tx_multicast_packets');
export const getDeviceBridgingBridgePortStatsBroadcastPacketsSent = (bri, port) =>
getNetworkStat(port, 'tx_broadcast_packets');
export const getDeviceBridgingBridgePortStatsBroadcastPacketsReceived = (bri, port) =>
getNetworkStat(port, 'rx_broadcast_packets');
export const getDeviceBridgingBridgePortStatsUnknownProtoPacketsReceived = (bri, port) =>
getNetworkStat(port, 'rx_unknown_packets');
export function getDeviceBridgingBridgePort(bri) {
const networkName = bri.Name.startsWith('br-') ? bri.Name.slice(3) : bri.Name;
const wifiIfaces = getUciByType('wireless', 'wifi-iface', { match: { multi_ap: '2' } });
wifiIfaces?.forEach(x => {
const ssid = getUciByType('dmmap_wireless', 'ssid',
{ match: { device: x.device, ssid: x.ssid}, confdir: '/etc/bbfdm/dmmap'});
if (Array.isArray(ssid) && ssid.length > 0) {
x.ssidPath = _dm_linker_path("Device.WiFi.SSID.", "Name", ssid[0].name) ?? '';
}
});
return wifiIfaces?.filter(x => x.network === networkName);
}
export function setDeviceBridgingBridgePortManagementPort(val, bri, port) {
if (isTrue(val)) {
_db_set(`Device.Bridging.Bridge.${bri['.index']}.Port.${port['.index']}.Name`, bri.Name);
}
return 1;
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2025 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
export const bridgePortTypeMap = [
{ portType: 'CustomerNetworkPort', devType: '8021ad' },
{ portType: 'CustomerVLANPort', devType: '8021q' },
{ portType: 'CustomerVLANPort', devType: 'untagged' },
{ portType: 'CustomerVLANPort', devType: '' },
{ portType: 'CustomerVLANPort', devType: undefined },
{ portType: 'VLANUnawarePort', devType: 'transparent' }
];
export function getBridgePortType(devType) {
const mapping = bridgePortTypeMap.find(map => map.devType === devType);
return mapping ? mapping.portType : null;
}
export function getBridgeDeviceType(portType) {
const mapping = bridgePortTypeMap.find(map => map.portType === portType);
return mapping ? mapping.devType : null;
}
export function getDefaultTPID(deviceType) {
switch (deviceType) {
case '8021q':
return '33024';
case '8021ad':
return '34984';
default:
return '37120';
}
}
export function getTPIDFromDeviceType(deviceType, explicitTPID) {
// If explicit TPID is set, use it
if (explicitTPID && explicitTPID !== '') {
return parseInt(explicitTPID, 10);
}
// Default TPID based on device type
switch (deviceType) {
case '8021q':
return 33024;
case '8021ad':
return 34984;
case 'untagged':
case 'transparent':
case '':
case undefined:
default:
return 37120;
}
}

View File

@@ -0,0 +1,126 @@
/* eslint-disable no-undef */
/*
* Wrapper around the native QuickJS C binding `_uci_call` which speaks to
* libuci directly (see qjs_uci_api.c). The exported helpers mimic the public
* API of the original uci.js module so that existing call-sites can switch to
* this implementation by simply importing uci2.js.
*/
export function uciBool(val) {
// by default enable is true if it is not defined
return (val === undefined || val === '1' || val === 'true' || val === 'enable' || val === 'yes');
}
function callUci(method, args) {
const [ret, res] = _uci_call(method, args);
if (ret !== 0) {
// Returning undefined on error keeps behaviour consistent with the
// original helpers which silently return undefined.
return [ret, undefined];
}
return [ret, res];
}
export function getUci(args) {
const [, res] = callUci('get', args);
if (res) {
if (res.values) {
if (!args.section) {
return Object.values(res.values);
}
return res.values;
}
if (res.value !== undefined) {
return res.value;
}
}
return undefined;
}
export function getUciOption(config, section, option, extraArgs) {
let args = { config, section, option };
if (extraArgs) {
args = { ...args, ...extraArgs };
}
return getUci(args);
}
export function getUciByType(config, type, extraArgs) {
let args = { config, type };
if (extraArgs) {
args = { ...args, ...extraArgs };
}
return getUci(args);
}
export function getUciSection(config, section, extraArgs) {
let args = { config, section };
if (extraArgs) {
args = { ...args, ...extraArgs };
}
return getUci(args);
}
export function setUci(cfg, section, values, type, match, extraArgs) {
let args = { config: cfg, section };
if (type) args.type = type;
if (values) args.values = values;
if (match) args.match = match;
if (extraArgs) args = { ...args, ...extraArgs };
const [ret] = callUci('set', args);
return ret;
}
export function addUci(cfg, type, name, values, extraArgs) {
let args = { config: cfg, type };
if (name) args.name = name;
if (values) args.values = values;
if (extraArgs) args = { ...args, ...extraArgs };
const [, res] = callUci('add', args);
return res || undefined;
}
export function delUci(cfg, section, type, option, options, match, extraArgs) {
let args = { config: cfg };
if (section) args.section = section;
if (type) args.type = type;
if (option) args.option = option;
if (options) args.options = options;
if (match) args.match = match;
if (extraArgs) args = { ...args, ...extraArgs };
const [, res] = callUci('delete', args);
return res || undefined;
}
export function delUciOption(config, section, option, match, extraArgs) {
let args = { config, section, option };
if (match) args.match = match;
if (extraArgs) args = { ...args, ...extraArgs };
const [, res] = callUci('delete', args);
return res || undefined;
}
export function uciChanges(cfg, extraArgs) {
let args = { config: cfg };
if (extraArgs) args = { ...args, ...extraArgs };
const [, res] = callUci('changes', args);
return res && res.changes ? res.changes : undefined;
}
export function commitUci(cfg, extraArgs) {
let args = { config: cfg };
if (extraArgs) args = { ...args, ...extraArgs };
const [ret] = callUci('commit', args);
return ret;
}
export function revertUci(cfg, extraArgs) {
let args = { config: cfg };
if (extraArgs) args = { ...args, ...extraArgs };
const [ret] = callUci('revert', args);
return ret;
}

View File

@@ -0,0 +1,268 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
/* eslint-disable no-undef */
/* eslint-disable no-bitwise */
import * as os from 'os';
import * as std from 'std';
export function macAddressToBase64(macAddress) {
// Split the MAC address into an array of bytes using the colon separator
const bytes = macAddress.split(':');
// Convert the bytes from hexadecimal to decimal
const decimalBytes = bytes.map((byte) => parseInt(byte, 16));
// Convert the decimal bytes into an array of 8-bit binary strings
const binaryBytes = decimalBytes.map((byte) => byte.toString(2).padStart(8, '0'));
// Concatenate the binary strings into a single string
const binaryString = binaryBytes.join('');
// Split the binary string into groups of 6 bits
const base64Chars = [];
for (let i = 0; i < binaryString.length; i += 6) {
base64Chars.push(binaryString.slice(i, i + 6));
}
// Convert each group of 6 bits to a decimal number
const decimalBase64 = base64Chars.map((char) => parseInt(char, 2));
// Create the base64 character set
const base64CharacterSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
// Map the decimal numbers to their corresponding base64 characters
const base64String = decimalBase64.map((num) => base64CharacterSet.charAt(num)).join('');
return base64String;
}
export function tr181Path(path, uciPath, keyName, keyVal) {
if (!keyVal) {
return '';
}
const [uciConfig, uciType] = uciPath.split('.');
const args = { config: uciConfig, type: uciType };
const [, res] = _ubus_call('uci', 'get', args);
if (!res || !res.values) {
_log_error('tr181Path: invalid result');
return '';
}
let insts = Object.values(res.values);
if (uciConfig === 'network' && uciType === 'interface') {
insts = insts.filter((x) => x.device !== 'lo' && !x.device?.startsWith('@') && x.proto !== 'dhcpv6');
}
const index = insts.findIndex((x) => x[keyName] === keyVal);
if (index < 0) {
return '';
}
if (path.startsWith('Device.')) {
return `${path}${index + 1}`;
}
return `Device.${path}${index + 1}`;
}
export function tr181IPInterface(uci) {
return tr181Path('IP.Interface.', 'network.interface', '.name', uci);
}
export function prefixLengthToSubnetMask(prefixLength) {
if (!prefixLength) {
return '';
}
const mask = 0xFFFFFFFF << (32 - prefixLength);
const subnetMask = [
(mask >>> 24) & 0xFF,
(mask >>> 16) & 0xFF,
(mask >>> 8) & 0xFF,
mask & 0xFF,
].join('.');
return subnetMask;
}
export function fileExists(path) {
let exists = false;
if (path !== '') {
// eslint-disable-next-line no-unused-vars
const [obj, err] = os.stat(path);
exists = (err === 0);
}
return exists;
}
export function waitUntilFileExists(path, timeoutMs = 10000) {
const startTime = Date.now();
while (!fileExists(path) && (Date.now() - startTime < timeoutMs)) {
os.sleep(100);
}
return fileExists(path);
}
export function runCommand(command) {
const fp = std.popen(command, 'r');
if (fp) {
const result = fp.readAsString();
if (fp.close() === 0)
return result;
else
return undefined;
}
return undefined;
}
export function fileExistsWithRegex(directory, regex) {
const [files, err] = os.readdir(directory);
if (err) {
_log_warn(`fileExistsWithRegex(): Could not read directory: ${directory}`);
}
for (let i = 0; i < files.length; i += 1) {
if (regex.test(files[i])) {
return true;
}
}
return false;
}
export function isIPv4Address(addr) {
return addr?.includes('.');
}
export function isIPv6Address(addr) {
return addr?.includes(':');
}
// find the pathname in LowerLayers
export function findPathInLowerlayer(path, inst, instKey) {
const lowerlayer = _dm_get(`${path}.LowerLayers`);
if (lowerlayer === '') {
return false;
}
if (lowerlayer.includes(instKey)) {
if (lowerlayer.includes(inst)) {
return true;
}
} else {
const layers = lowerlayer.split(',');
if (layers.find((x) => findPathInLowerlayer(x, inst, instKey))) {
return true;
}
}
return false;
}
export function hex2a(hex) {
let i = 0;
let str = '';
for (i = 0; i < hex.length; i += 2) {
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
}
return str;
}
export function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
export function lowercaseFirstLetter(string) {
return string.charAt(0).toLowerCase() + string.slice(1);
}
export function getIfnameOperState(ifname) {
if (!ifname) {
return 'Down';
}
const res = std.loadFile(`/sys/class/net/${ifname}/operstate`);
if (res) {
return capitalizeFirstLetter(res.trim());
}
return 'Down';
}
export function getIfnameState(ifname, name) {
if (!ifname) {
return '';
}
const res = std.loadFile(`/sys/class/net/${ifname}/${name}`);
return res?.trim();
}
export function strToHex(str) {
if (!str) {
return '';
}
let hex = '';
for (let i = 0; i < str.length; i += 1) {
hex += str.charCodeAt(i).toString(16);
}
return hex;
}
// transform the object of following object:
// {
// 'SSIDtoVIDMapping.1.SSID': 'abc',
// 'SSIDtoVIDMapping.1.VID': 100,
// 'SSIDtoVIDMapping.2.SSID': 'xyz',
// 'SSIDtoVIDMapping.2.VID': 200,
// Enable: 'true'
// }
// into:
// {
// SSIDtoVIDMapping: [ { SSID: 'abc', VID: 100 }, { SSID: 'xyz', VID: 200 } ],
// Enable: 'true'
// }
export function transformInputObject(obj) {
const result = {};
Object.entries(obj).forEach(([key, value]) => {
const splitKey = key.split('.');
if (splitKey.length < 3) {
result[key] = value; // add invalid keys directly to the result
return;
}
const mainKey = splitKey[0];
const index = parseInt(splitKey[1], 10) - 1;
const prop = splitKey[2];
if (!result[mainKey]) {
result[mainKey] = [];
}
if (!result[mainKey][index]) {
result[mainKey][index] = {};
}
result[mainKey][index][prop] = value;
});
return result;
}
export function isTrue(val) {
return val === 'true' || val === '1' || val === true;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,290 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifndef DM_NODE_H
#define DM_NODE_H
#include "dm_types.h"
enum NODE_FLAG {
FLAG_NONE = 0x0,
FLAG_COUNTER = 0x40,
FLAG_HAS_MIN = 0x80,
FLAG_HAS_MAX = 0x100,
FLAG_HAS_ORDER = 0x400,
FLAG_WRITABLE = 0x800,
FLAG_CONFIDENTIAL = 0x1000,
FLAG_CWMP_ONLY = 0x4000,
FLAG_USP_ONLY = 0x8000,
FLAG_INTERNAL= 0x10000,
};
enum DM_UCI_MAP_TYPE {
DM_UCI_MAP_TYPE_NONE = 0,
DM_UCI_MAP_TYPE_SIMPLE = 0x01, // simple value 2 value
DM_UCI_MAP_TYPE_DISABLE = 0x02, // uci disable bool type
DM_UCI_MAP_TYPE_TABLE = 0x04, // a JSON object is used for mapping, {uci: dm}
DM_UCI_MAP_TYPE_INTERFACE = 0x08, // ip interface
DM_UCI_MAP_TYPE_JS = 0x10, // js code
};
struct dm_uci_map {
unsigned int type;
const char *map;
const char *key;
};
struct dm_node_info {
enum DM_NODE_TYPE type;
dm_node_id_t node_id;
const char *const name;
const struct dm_node_info *const parent;
const char *const table_name; // if NULL the value is not stored in the database
const char *pathname;
enum NODE_FLAG flag;
dm_node_id_t depends_node_id;
};
struct dm_parameter {
struct dm_node_info node;
enum DM_DATA_TYPE data_type;
long min;
long max;
int list;
union {
// for enum data type
const char **enum_strings;
// for counter data type
dm_node_id_t counter_object;
// for path data type
const dm_node_id_t *paths;
} data;
const char *set_on_create;
const char *js_val;
const char *const_val;
const char *default_val;
const char *default_uci_val;
struct dm_uci_map map;
};
struct command_arg {
const char *name;
enum DM_DATA_TYPE type;
int min;
int max;
int list;
const char **enum_values;
int mandatory;
};
struct dm_command {
struct dm_node_info node;
int async;
const struct command_arg *inputs;
int inputs_cnt;
const struct command_arg *outputs;
int outputs_cnt;
};
struct event_arg {
const char *name;
enum DM_DATA_TYPE type;
};
struct dm_event {
struct dm_node_info node;
const struct event_arg *args;
int args_cnt;
const char *ubus_event;
};
struct dm_object {
struct dm_node_info node;
int param_num;
const struct dm_node_info *const *const param_list;
int command_num;
const struct dm_node_info *const *const command_list;
int object_num;
const struct dm_node_info *const *const event_list;
int event_num;
const struct dm_node_info *const *const object_list;
int paths_refs_num;
const struct dm_node_info *const *const paths_refs_list;
const char *key_param_names;
struct dm_uci_map map;
const char *js_val;
int fixed_objects;
};
const struct dm_node_info *dm_node_get_root(void);
const struct dm_node_info *dm_node_get_info(dm_node_id_t id);
/**
* This function will look up a parameter by ID
* @pre None
* @post valid dm_parameter pointer returned or NULL if error
* @param id The actual id for which we want to retrieve a
* pointer to the dm_parameter struct
* @return NULL in case id is out of range or if id does not point
* to a parameter node, a pointer to the dm_parameter struct otherwise
*/
const struct dm_parameter *dm_node_get_parameter(dm_node_id_t id);
const struct dm_command *dm_node_get_command(dm_node_id_t id);
const struct dm_event *dm_node_get_event(dm_node_id_t id);
/**
* This function will look up a command by ID
* @pre None
* @post valid dm_command pointer returned or NULL if error
* @param id The actual id for which we want to retrieve a
* pointer to the dm_parameter struct
* @return NULL in case id is out of range or if id does not point
* to a command node, a pointer to the dm_command struct otherwise
*/
const struct dm_command *dm_node_get_command(dm_node_id_t id);
/**
* This function will look up an object by ID
* @pre None
* @post valid dm_object pointer returned or NULL if error
* @param id The actual id for which we want to retrieve a
* pointer to the dm_object struct
* @return NULL in case id is out of range or if id does not point
* to an object node, a pointer to the dm_object struct otherwise
* Note that if the id points to an object list a pointer to the
* first object is returned
*/
const struct dm_object *dm_node_get_object(dm_node_id_t id);
int dm_node_is_valid(dm_node_id_t id);
int dm_node_is_parameter(dm_node_id_t id);
int dm_node_is_command(dm_node_id_t id);
int dm_node_is_event(dm_node_id_t id);
int dm_node_is_writable(dm_node_id_t id);
int dm_node_is_object(dm_node_id_t id);
int dm_node_is_objectlist(dm_node_id_t id);
int dm_node_is_counter(dm_node_id_t id);
int dm_node_is_text_type(dm_node_id_t id);
int dm_node_is_bool_type(dm_node_id_t id);
int dm_node_is_ul_type(dm_node_id_t id);
int dm_node_is_unsigned_type(dm_node_id_t id);
int dm_node_is_confidential(dm_node_id_t id);
int dm_node_is_cwmp_only(dm_node_id_t id);
int dm_node_is_usp_only(dm_node_id_t id);
int dm_node_is_internal(dm_node_id_t id);
dm_node_id_t dm_node_counter_id(dm_node_id_t id);
int dm_node_has_db(dm_node_id_t id);
const char *dm_node_object_keys(dm_node_id_t id);
int dm_node_is_fixed_objects(dm_node_id_t id);
int dm_node_max_data_size(dm_node_id_t id);
int dm_node_param_mem_size(dm_node_id_t node_id);
const char *get_param_xsd_type(enum DM_DATA_TYPE type);
const char *dm_node_name(dm_node_id_t id);
dm_node_id_t dm_node_id_parent(dm_node_id_t id);
int dm_node_parent(const dm_node_t *node, dm_node_t *parent);
// get first multi-instance parent
int dm_node_i_parent(const dm_node_t *node, dm_node_t *parent);
dm_node_id_t dm_node_i_parent_id(const dm_node_id_t id);
int dm_node_index_cnt(dm_node_id_t id);
enum DM_DATA_TYPE dm_node_data_type(dm_node_id_t id);
dm_node_id_t dm_node_get_apply_depends(dm_node_id_t id);
dm_node_id_t dm_node_get_extends(dm_node_id_t id);
/*
Get the full name of a node.
@param node[in] Node ID whose name we want to retrieve
@param name[out] Location where the node name is written
@param name_len[in] Amount of space available in name
@return 0 in case of success, -1 in case of failure
*/
int dm_node2name(const dm_node_t *node, char *name, int name_len);
int dm_node2name_with_index(const dm_node_t *node, char *name, int name_len, const char *index_replacement);
int dm_name2node(const struct dm_node_info *parent, const char *name, dm_node_t *node);
int dm_path2node(const char *path, dm_node_t *node);
int dm_node_verify_param_data(dm_node_id_t id, const char *data);
// is parameter ancestor is the ancestor or parent of parameter id
int dm_node_is_ancestor(dm_node_id_t id, dm_node_id_t ancestor);
// is parameter data type a list (comman separated)
int dm_node_is_param_list(dm_node_id_t id);
dm_index_t dm_node_last_index(const dm_node_t *node);
int dm_node_is_index_complete(const dm_node_t *node);
/** Compare if two nodes are identical.
Two nodes are considered identical if their id, their index arrays and the cnt is the same
@param node1[in] first node for the comparison
@param node2[in] second node for the comparison
@return 1 if identical, 0 if not identical
*/
int dm_node_equal(const dm_node_t *node1, const dm_node_t *node2);
int dm_node_has_path(dm_node_id_t node_id, dm_node_id_t path);
// return 0-(max-1) for valid string, -1 for unknown enum string
int dm_node_get_enum_index(dm_node_id_t id, const char *enum_str);
// return the enum string for valid index: 0-(max-1), otherwise return NULL
const char *dm_node_get_enum_str(dm_node_id_t id, int index);
/** Remove path name from the path names separated with comma
@param paths path names separated with with comma
@param node node of path name that is to be removed
@return 0 if successful, -1 for failure
*/
int tr181_paths_remove(dm_path_t paths, const dm_node_t *node);
/** Append one path name to the path names separated with comma
@param paths path names separated with with comma
@param node node of path name that is to be appended
@return 0 if successful, -1 for failure
*/
int tr181_paths_add(dm_path_t paths, const dm_node_t *node);
// Find the "Order" parameter node from all its child nodes
int dm_node_find_order_param(const dm_node_t *obj_node, dm_node_t *order_node);
/** Return the database table for a node
@param node The node for which the database table is returned
@return pointer to the name of the database table (NULL if the node is not in the database
*/
const char *dm_node_get_table_name(const struct dm_node_info *node);
// Get child node id by its name
dm_node_id_t dm_node_get_child_id(dm_node_id_t id, const char *name);
// get child node by name
int dm_node_get_child(const dm_node_t *node, const char *name, dm_node_t *child);
const char *dm_node_str(const dm_node_t *node);
const char *dm_node_id_str(const dm_node_id_t id);
// compare if the nodes are compatible, this is if node1 and node2 have the same id and
// all indexes of node1 are a subset of node2 or vice versa
int dm_node_compatible(const dm_node_t *node1, const dm_node_t *node2);
// get the string xsd type of the data type
const char *dm_node_get_param_xsd_type(dm_node_id_t id);
/** Get the output argument type of the command node
@param [in] id node id
@param [in] arg_name argument name of the command
@return pointer of const string if successful, NULL for failure
*/
const struct command_arg *dm_node_get_command_output_arg(dm_node_id_t id, const char *arg_name);
// return 1 if verified, otherwise 0.
int dm_node_verify_command_input(dm_node_id_t id, const char *input_name, const char *input_value);
// Compare the command argument pathname with index (index part will be skipped for comparision)
// ex, "result.{i}.abc" == "result.100.abc"
// return 0 if equal, otherwise 1
int dm_node_compare_command_arg_name(const char* str1, const char* str2);
#endif

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifndef DM_TYPES_H
#define DM_TYPES_H
#define MAX_DM_NODE_DEPTH 8
#define INVALID_DM_INDEX ((dm_index_t)0)
#define INVALID_DM_NODE_ID ((dm_node_id_t)-1)
typedef unsigned int dm_node_id_t;
typedef unsigned int dm_index_t;
typedef dm_index_t dm_index_path_t[MAX_DM_NODE_DEPTH];
typedef struct
{
dm_index_path_t index;
} node_index_path_t;
typedef struct
{
dm_node_id_t id;
dm_index_path_t index;
int cnt;
} dm_node_t;
#define dm_init_node(id) \
{ \
id, {0}, 0 \
}
typedef unsigned int dm_uint_t;
typedef int dm_int_t;
typedef int dm_bool_t;
typedef char dm_enum_t[128];
typedef char dm_ip_t[64];
// IPv4 or IPv6 routing prefix in Classless Inter-Domain Routing (CIDR) notation [RFC4632].
// This is specified as an IP address followed by an appended "/n" suffix,
// where n (the prefix size) is an integer in the range 0-32 (for IPv4) or 0-128 (for IPv6)
// that indicates the number of (leftmost) '1' bits of the routing prefix.
// If the IP address part is unspecified or inapplicable, it MUST be an empty string unless
// otherwise specified by the parameter definition. In this case the IP prefix will be of the form "/n".
// IPv4 example: 192.168.1.0/24
// IPv6 example: 2001:edff:fe6a:f76::/64
typedef char dm_ip_prefix_t[64];
typedef char dm_mac_t[20]; // 18 would suffice but there can be word access when getting a value; hence rounded up to 20 */
typedef char dm_date_time_t[64];
typedef char dm_url_t[260];
typedef unsigned long dm_ulong_t;
typedef unsigned long long dm_ulonglong_t;
typedef char dm_path_t[1024];
typedef char dm_domain_t[256];
#define dm_true 1
#define dm_false 0
enum DM_DATA_TYPE {
DM_DATA_INT = 0,
DM_DATA_LONG,
DM_DATA_UINT,
DM_DATA_ULONG,
DM_DATA_BOOLEAN,
DM_DATA_STRING,
DM_DATA_HEXBINARY,
DM_DATA_BASE64,
DM_DATA_IP,
DM_DATA_IPV4,
DM_DATA_IPV6,
DM_DATA_IP_PREFIX,
DM_DATA_IPV6_PREFIX,
DM_DATA_MAC,
DM_DATA_DATETIME,
DM_DATA_ENUM,
DM_DATA_URL,
DM_PATH_NAME,
DM_DATA_UNKNOWN
};
enum DM_NODE_TYPE {
DM_NODE_PARAMETER = 0,
DM_NODE_OBJECT,
DM_NODE_OBJECT_LIST,
DM_NODE_COMMAND,
DM_NODE_EVENT
};
#endif

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,508 @@
/* eslint-disable no-await-in-loop */
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
const assert = require('assert');
const fs = require('fs');
const xml2js = require('xml2js');
const util = require('util');
const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);
const parser = new xml2js.Parser();
const parseXML = util.promisify(parser.parseString);
const cwmpTr181XmlFile = 'tr-181-2-19-1-cwmp-full.xml';
const uspTr181XmlFile = 'tr-181-2-19-1-usp-full.xml';
const uspTr181VendorExtXmlFile = 'tr-181-vendor-extensions-usp.xml';
const Tr104USPXmlFile = 'tr-104-2-0-2-usp-full.xml';
const Tr104CWMPXmlFile = 'tr-104-2-0-2-cwmp-full.xml';
let cwmpModel;
let uspModel;
let uspVendorExtModel;
let tr181 = true;
async function saveFile(file, obj) {
await writeFile(file, JSON.stringify(obj, null, 4));
console.log('saved file:', file);
}
function getRange(attr) {
if (typeof attr[0] !== 'object') {
return '';
}
if (attr[0].range) {
const range = attr[0].range[0].$;
return `(${range.minInclusive ?? ''}:${range.maxInclusive ?? ''})`;
}
return '';
}
function objParent(obj) {
let parent;
if (obj.endsWith('}.')) {
parent = obj.slice(0, -5);
} else {
parent = obj.slice(0, -1);
}
return parent.substring(0, parent.lastIndexOf('.'));
}
function parsePathRef(obj, ref) {
let path = obj.$.name;
ref = ref.trim().replace(/\n$/, '');
if (ref.startsWith('.')) {
if (path.startsWith('Device.Services.VoiceService.') && !path.endsWith('()')) {
return `Device.Services.VoiceService.{i}${ref}`;
}
return `Device${ref}`;
}
if (ref.startsWith('#')) {
while (ref.startsWith('#')) {
path = objParent(path);
ref = ref.slice(1);
}
return path + ref;
}
if (ref.startsWith('Device.')) {
return ref;
}
return path + ref;
}
function getParamType(obj, res, syntaxType) {
const intTypes = [
'int',
'long',
'unsignedInt',
'unsignedLong',
];
const intType = intTypes.find((x) => Object.keys(syntaxType).includes(x));
if (intType) {
res.dataType = `${intType}${getRange(syntaxType[intType])}`;
} else if (syntaxType.boolean) {
res.dataType = 'boolean';
} else if (syntaxType.dateTime) {
res.dataType = 'dateTime';
} else if (syntaxType.string) {
const attr = syntaxType.string[0];
if (typeof attr === 'object') {
if (attr.enumeration) {
res.dataType = 'enum';
res.enum = attr.enumeration.map((x) => x.$.value);
} else if (attr.pathRef) {
res.dataType = 'pathRef';
if (attr.pathRef[0].$.targetParent) {
res.pathRef = attr.pathRef[0].$.targetParent.split(' ').filter((x) => x).map((x) => parsePathRef(obj, x));
}
} else if (attr.enumerationRef) {
res.dataType = 'enum';
res.enumerationRef = parsePathRef(obj, attr.enumerationRef[0].$.targetParam);
} else if (attr.size) {
res.dataType = `string(${attr.size[0].$?.minLength ?? ''}:${attr.size[0].$?.maxLength ?? ''})`;
} else if (attr.pattern) {
// handle it as enum
res.dataType = 'enum';
res.enum = attr.pattern.map((x) => x.$.value);
} else {
assert(false, `unknown string type: ${JSON.stringify(syntaxType, null, 2)}`);
}
} else {
res.dataType = 'string';
}
} else if (syntaxType.dataType) {
res.dataType = syntaxType.dataType[0].$.ref;
if (res.dataType === 'Alias') {
res.dataType = 'string(:64)';
} else if (res.dataType === 'DiagnosticsState') {
res.dataType = 'enum';
res.enum = ['None', 'Requested', 'Canceled', 'Complete', 'Error'];
} else if (res.dataType === 'StatsCounter64') {
res.dataType = 'unsignedLong';
}
} else if (syntaxType.hexBinary) {
res.dataType = 'hexBinary';
const { size } = syntaxType.hexBinary[0];
if (size) {
res.dataType += `(${size[0].$?.minLength ?? ''}:${size[0].$?.maxLength ?? ''})`;
}
} else if (syntaxType.base64) {
res.dataType = 'base64';
const { size } = syntaxType.base64[0];
if (size) {
res.dataType += `(${size[0].$?.minLength ?? ''}:${size[0].$?.maxLength ?? ''})`;
}
} else if (syntaxType.decimal) {
res.dataType = 'decimal';
const { size } = syntaxType.decimal[0];
if (size) {
res.dataType += `(${size[0].$?.minLength ?? ''}:${size[0].$?.maxLength ?? ''})`;
}
} else {
console.log(`unknown datatype:\n ${JSON.stringify(syntaxType, null, 4)}`);
res.dataType = 'unknown';
}
if (syntaxType.list) {
res.dataType += '[]';
}
}
function getParamObj(obj, param, proto) {
const res = {
name: param.$.name,
};
if (proto) {
res.proto = proto;
}
res.access = param.$.access;
const syntaxType = param.syntax[0];
getParamType(obj, res, syntaxType);
if (syntaxType.$?.hidden) {
res.hidden = true;
}
if (syntaxType.default && syntaxType.default[0].$?.value) {
const def = syntaxType.default[0].$?.value;
if (def !== 'false' && def !== '') {
res.default = syntaxType.default[0].$?.value;
}
}
return res;
}
let allObjects = [];
function generateCWMPObjects(objs) {
objs.forEach((obj) => {
const o = allObjects.find((x) => x.object === obj.$.name);
if (o) {
const params = obj.parameter.map((param) => getParamObj(obj, param, 'cwmp'));
o.parameters = o.parameters.concat(params);
} else {
allObjects.push({
object: obj.$.name,
proto: 'cwmp',
fixedObject: obj.$['dmr:fixedObject'],
uniqueKeys: obj.uniqueKey?.map((x) => x.parameter[0].$.ref).join(','),
// numEntriesParameter: obj.$.numEntriesParameter,
access: obj.$.access,
parameters: obj.parameter?.map((param) => (
getParamObj(obj, param, 'cwmp'))) ?? [],
});
}
});
}
function getCommandInput(cmdInfo) {
if (!cmdInfo.input) {
return [];
}
const objParams = [];
if (cmdInfo.input[0].object) {
cmdInfo.input[0].object.forEach((obj) => {
obj.parameter.forEach((p) => {
const inputParams = {
parameter: obj.$.name + p.$.name,
mandatory: p.$.mandatory === 'true',
};
getParamType(cmdInfo, inputParams, p.syntax[0]);
objParams.push(inputParams);
});
});
}
const params = cmdInfo.input[0].parameter?.map((p) => {
const inputParams = {
parameter: p.$.name,
mandatory: p.$.mandatory === 'true',
};
getParamType(cmdInfo, inputParams, p.syntax[0]);
return inputParams;
});
return objParams.concat(params ?? []);
}
function getCommandOutput(cmdInfo) {
if (!cmdInfo.output) {
return [];
}
const outParams = cmdInfo.output[0].parameter?.map((p) => {
const outputs = {
parameter: p.$.name,
};
getParamType(cmdInfo, outputs, p.syntax[0]);
return outputs;
}) ?? [];
const outObjs = cmdInfo.output[0].object?.map((obj) => {
const outputs = {
object: obj.$.name,
};
outputs.parameters = obj.parameter?.map((p) => {
const outs = {
parameter: p.$.name,
};
getParamType(cmdInfo, outs, p.syntax[0]);
return outs;
});
return outputs;
}) ?? [];
return outParams.concat(outObjs);
}
function generateUSPObjects(objs) {
objs.forEach((obj) => {
const o = allObjects.find((x) => x.object === obj.$.name);
if (o) {
delete o.proto;
obj.parameter?.forEach((p) => {
const param = o.parameters.find((x) => x.name === p.$.name);
if (param) {
delete param.proto;
} else {
o.parameters.push(getParamObj(obj, p, 'usp'));
}
});
if (obj.command) {
const cmds = obj.command.map((cmd) => ({
name: cmd.$.name,
async: !!cmd.$.async,
input: getCommandInput(cmd),
output: getCommandOutput(cmd),
}));
if (o.commands) {
o.commands = o.commands.concat(cmds);
} else {
o.commands = cmds;
}
}
if (obj.event) {
const events = obj.event.map((ev) => ({
name: ev.$.name,
parameter: ev.parameter?.map((p) => p.$.name),
}));
if (o.events) {
o.events = o.events.concat(events);
} else {
o.events = events;
}
}
} else {
const cwmpObj = cwmpModel.object.find((x) => x.$.name === obj.$.name);
const newObj = {
object: obj.$.name,
proto: cwmpObj ? undefined : 'usp',
uniqueKeys: obj.uniqueKey?.map((x) => x.parameter[0].$.ref).join(','),
// numEntriesParameter: obj.$.numEntriesParameter,
access: obj.$.access,
fixedObject: obj.$['dmr:fixedObject'],
parameters: obj.parameter?.map((param) => (
getParamObj(obj, param, (cwmpObj && cwmpObj.parameter?.find((x) => x.$.name === param.$.name)) ? undefined : 'usp'))) ?? [],
};
if (obj.command) {
newObj.commands = obj.command.map((cmd) => ({
name: cmd.$.name,
async: !!cmd.$.async,
input: getCommandInput(cmd),
output: getCommandOutput(cmd),
}));
}
if (obj.event) {
newObj.events = obj.event.map((ev) => ({
name: ev.$.name,
parameter: ev.parameter?.map((p) => p.$.name),
}));
}
allObjects.push(newObj);
}
});
}
function mergeProfileObjs(obj1, obj2) {
if (!obj1) {
return obj2;
}
if (!obj2) {
return obj1;
}
obj2.forEach((obj) => {
const o = obj1.find((x) => x.object === obj.object);
if (o) {
if (o.parameter) {
o.parameter = o.parameter.concat(obj.parameter ?? []);
} else {
o.parameter = obj.parameter;
}
if (o.command) {
o.command = o.command.concat(obj.command ?? []);
} else {
o.command = obj.command;
}
if (o.event) {
o.event = o.event.concat(obj.event ?? []);
} else {
o.event = obj.event;
}
} else {
obj1.push(obj);
}
});
return obj1;
}
function parseProfileObjects(model, profileName) {
const profile = model.profile.find((x) => x.$.name === profileName);
if (!profile) {
return [];
}
// assert(profile, `profile not found ${profileName}`);
const objs = profile.object?.map((o) => ({
object: o.$.ref,
parameter: o.parameter?.map((p) => p.$.ref),
command: o.command?.map((c) => c.$.ref),
event: o.event?.map((e) => e.$.ref),
}));
const exts = profile.$.extends ?? profile.$.base;
if (exts) {
let res = objs;
exts.split(' ').forEach((ext) => {
const extObjs = parseProfileObjects(model, ext);
res = mergeProfileObjs(res, extObjs);
});
return res;
}
return objs;
}
async function getProfileObjects(model, profileName) {
const profileObjs = parseProfileObjects(model, profileName);
const objs = [];
profileObjs.forEach((obj) => {
const targetObj = model.object.find((o) => o.$.name === obj.object);
assert(targetObj, `object not found ${obj.object}`);
const keys = targetObj.uniqueKey?.map((x) => x.parameter[0].$.ref);
targetObj.parameter = targetObj.parameter?.filter((x) => obj.parameter?.includes(x.$.name) || (keys?.includes(x.$.name)));
targetObj.command = targetObj.command?.filter((x) => obj.command?.includes(x.$.name));
objs.push(targetObj);
});
return objs;
}
async function loadXMLModel(file) {
const xmlData = await readFile(file, 'utf8');
const jsonData = await parseXML(xmlData);
const [model] = jsonData['dm:document'].model;
return model;
}
function printUsage() {
console.log('Usage:\nnode makeDM.js <tr181|tr104> [profile]');
}
(async () => {
try {
if (process.argv.length < 3 || (process.argv[2] !== 'tr181' && process.argv[2] !== 'tr104')) {
printUsage();
process.exit(-1);
}
if (process.argv[2] === 'tr104') {
tr181 = false;
}
if (tr181 && fs.existsSync(uspTr181VendorExtXmlFile)) {
uspVendorExtModel = await loadXMLModel(uspTr181VendorExtXmlFile);
} else if (tr181) {
console.warn(`Optional vendor extension file '${uspTr181VendorExtXmlFile}' not found, skipping.`);
}
if (tr181) {
cwmpModel = await loadXMLModel(cwmpTr181XmlFile);
uspModel = await loadXMLModel(uspTr181XmlFile);
} else {
cwmpModel = await loadXMLModel(Tr104CWMPXmlFile);
uspModel = await loadXMLModel(Tr104USPXmlFile);
cwmpModel.object.forEach((obj) => {
obj.$.name = `Device.Services.${obj.$.name}`;
});
cwmpModel.profile.forEach((prof) => {
prof.object?.forEach((obj) => {
obj.$.ref = `Device.Services.${obj.$.ref}`;
});
});
uspModel.object.forEach((obj) => {
obj.$.name = `Device.Services.${obj.$.name}`;
});
uspModel.profile.forEach((prof) => {
prof.object?.forEach((obj) => {
obj.$.ref = `Device.Services.${obj.$.ref}`;
});
});
}
if (process.argv.length === 3) {
generateCWMPObjects(cwmpModel.object);
generateUSPObjects(uspModel.object);
if (tr181 && uspVendorExtModel) {
generateUSPObjects(uspVendorExtModel.object);
}
const fileName = `${tr181 ? 'tr181' : 'tr104'}-full-objects.json`;
await saveFile(fileName, allObjects);
process.exit(0);
}
for (const arg of process.argv.slice(3)) {
// profile
const profile = arg;
const cwmpObjects = await getProfileObjects(cwmpModel, profile);
const uspObjects = await getProfileObjects(uspModel, profile);
generateCWMPObjects(cwmpObjects);
generateUSPObjects(uspObjects);
await saveFile(`${profile}.json`, allObjects);
allObjects = [];
}
} catch (error) {
console.error(`Error while reading file: ${error}`);
console.log(error.stack);
}
})();

View File

@@ -0,0 +1,88 @@
// This script is used to load and validate the js handlers code in dm-file.
(function () {
const fs = require('fs');
const path = require('path');
const { spawnSync } = require('child_process');
// Root directory (dm-files) relative to this script
const dmFilesRoot = path.resolve(__dirname, '../dm-files');
/**
* Recursively walk a directory and collect all *.js files that do not start with a dot.
* @param {string} dir - directory to walk
* @param {string[]} out - accumulator for file paths
*/
function collectJsFiles(dir, out) {
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
// Skip hidden files/directories (starting with ".")
if (entry.name.startsWith('.')) {
continue;
}
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
collectJsFiles(fullPath, out);
} else if (entry.isFile() && fullPath.endsWith('.js')) {
out.push(fullPath);
}
}
}
/**
* Validate a single JavaScript file with QuickJS (qjs).
* Exits the process with -1 on failure.
* @param {string} filePath - absolute path of the JS file
*/
function validateWithQjs(filePath) {
// Extract directory and filename for proper working directory
const fileDir = path.dirname(filePath);
const fileName = path.basename(filePath);
// Capture stdout/stderr so we can print them on failure
// Set the working directory to the file's directory
const result = spawnSync('qjs', [fileName], {
encoding: 'utf8',
cwd: fileDir
});
if (result.status === 0) {
return; // Validated successfully
}
// Show QuickJS output so user sees error details
console.error(`\n===== QuickJS validation failed: ${filePath} =====`);
if (result.stdout) {
console.error(result.stdout.trim());
}
if (result.stderr) {
console.error(result.stderr.trim());
}
console.error('===============================================');
process.exit(-1);
}
function main() {
if (!fs.existsSync(dmFilesRoot)) {
console.error(`dm-files directory not found at: ${dmFilesRoot}`);
process.exit(-1);
}
const jsFiles = [];
collectJsFiles(dmFilesRoot, jsFiles);
if (jsFiles.length === 0) {
console.log('No JavaScript files found to validate.');
return;
}
console.log(`Validating ${jsFiles.length} JavaScript file(s) with QuickJS...`);
jsFiles.forEach(validateWithQjs);
console.log('All files validated successfully.');
}
// Execute when run directly (not required when imported)
if (require.main === module) {
main();
}
})();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

BIN
dm-framework/dm-agent/._Makefile Executable file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,64 @@
#
# Copyright (c) 2023 Genexis B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
#
include $(TOPDIR)/rules.mk
PKG_NAME:=bridgemngr
PKG_VERSION:=1.0.0
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
PLATFORM_CONFIG:=$(TOPDIR)/.config
include $(INCLUDE_DIR)/package.mk
include ../../bbfdm/bbfdm.mk
define Package/$(PKG_NAME)
DEPENDS:=+dm-api +datamodels +libubox +libubus +ubus
CATEGORY:=Genexis
TITLE:=GeneOS agent
URL:=http://www.genexis.eu
PKG_LICENSE:=GENEXIS
PKG_LICENSE_URL:=
endef
define Package/$(PKG_NAME)/description
This package contains GeneOS agent.
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) -rf ./src/* $(PKG_BUILD_DIR)/
endef
TARGET_CFLAGS += $(FPIC) -I$(PKG_BUILD_DIR)
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR)\
PROJECT_ROOT="$(PKG_BUILD_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
EXTRA_CFLAGS="$(TARGET_CFLAGS)" \
all
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_BIN) ./files/etc/init.d/bridging $(1)/etc/init.d/
$(INSTALL_DATA) ./files/etc/config/bridging $(1)/etc/config/
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) $(PKG_NAME)
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
# $(INSTALL_BIN) ./files/etc/init.d/dm-agent $(1)/etc/init.d/dm-agent
$(INSTALL_BIN) $(PKG_BUILD_DIR)/dm-agent $(1)/usr/sbin
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -0,0 +1,17 @@
{
"daemon": {
"enable": "1",
"service_name": "bridgemngr",
"dm-framework": true,
"unified_daemon": false,
"services": [
{
"parent_dm": "Device.",
"object": "Bridging"
}
],
"config": {
"loglevel": "3"
}
}
}

View File

@@ -0,0 +1,33 @@
#L2 filter UCI file
config chain 'qos_output'
option target 'qos_output'
option table 'nat'
option chain 'OUTPUT'
option policy 'RETURN'
config chain 'dscp2pbits'
option target 'dscp2pbits'
option table 'broute'
option chain 'BROUTING'
option policy 'RETURN'
config chain 'qos'
option target 'qos'
option table 'broute'
option chain 'BROUTING'
option policy 'RETURN'
config chain 'prevlanxlate'
option target 'prevlanxlate'
option table 'broute'
option chain 'BROUTING'
option policy 'RETURN'
option append 'false'
config chain 'mcsnooping'
option target 'mcsnooping'
option table 'broute'
option chain 'BROUTING'
option policy 'RETURN'
option append 'false'

View File

@@ -0,0 +1,94 @@
#!/bin/sh /etc/rc.common
# Start after bdmf shell, wanconf, and switch-script but before the network-script
START=20
STOP=10
USE_PROCD=1
. /lib/functions.sh
handle_ebtables_chain() {
local sid="$1"
local table
local chain
local target
local policy
local append
local enabled
local ret
config_get table "$sid" table filter
config_get chain "$sid" chain
config_get policy "$sid" policy RETURN
config_get target "$sid" target
config_get_bool append "$sid" append 1
config_get_bool enabled "$sid" enabled 1
[ "$enabled" = "0" ] && return
[ -z "${chain}" -o -z "${target}" ] && return
if [ "$append" != "0" ]; then
append="-A"
else
append="-I"
fi
ebtables --concurrent -t "$table" -N "$target" -P "$policy" 2> /dev/null
ret=$?
if [ $ret -eq 0 ]; then
ebtables --concurrent -t "$table" ${append} "$chain" -j "$target"
else
ebtables --concurrent -t "$table" -D "$chain" -j "$target"
ebtables --concurrent -t "$table" ${append} "$chain" -j "$target"
fi
}
handle_ebtables_rule() {
local sid="$1"
local table
local chain
local target
local match
local value
local enabled
local ret
config_get table "$sid" table filter
config_get chain "$sid" chain
config_get match "$sid" match
config_get value "$sid" value
config_get target "$sid" target RETURN
config_get_bool append "$sid" append 1
config_get_bool enabled "$sid" enabled 1
[ "$enabled" = "0" ] && return
[ -z "${chain}" -o -z "${target}" ] && return
if [ "$append" != "0" ]; then
append="-A"
else
append="-I"
fi
ebtables --concurrent -t "$table" -D "$chain" ${match} -j "$target" ${value} 2> /dev/null
ebtables --concurrent -t "$table" ${append} "$chain" ${match} -j "$target" ${value}
}
start_service() {
ubus -t 30 wait_for network.device uci
config_load bridging
config_foreach handle_ebtables_chain chain
config_foreach handle_ebtables_rule rule
}
reload_service() {
stop
start
}
service_triggers() {
procd_add_reload_trigger bridging
}

Binary file not shown.

View File

@@ -0,0 +1,37 @@
#
# Copyright (c) 2023 Genexis B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
#
PROG = dm-agent
SRCS = dm_agent.c
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
CC = $(CROSS_COMPILE)gcc
STRIP = $(CROSS_COMPILE)strip
CFLAGS = -Wall -Werror $(EXTRA_CFLAGS)
CFLAGS += -MMD -MP -std=gnu99
LDFLAGS += -ldm -ldmapi -lubus -luci -lubox -ljson-c -lblobmsg_json
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $^ $(LDFLAGS) -o $@
%.o: %.c
$(CC) -c $(CFLAGS) $^ -o $@
clean:
rm -f $(PROG) *.o core $(DEPS)
-include $(DEPS)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,75 @@
#
# Copyright (c) 2023 Genexis B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dm-api
PKG_VERSION:=1.0
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
PLATFORM_CONFIG:=$(TOPDIR)/.config
AUTO_CONF_H:=$(PKG_BUILD_DIR)/autoconf.h
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
CATEGORY:=Genexis
TITLE:=dm-api
PKG_BUILD_DEPENDS:=datamodels
DEPENDS:=+libsqlite3 \
+libjson-c +libstdcpp +quickjs \
+libubus +libubox +libuci
# Depedencies for RG products
URL:=http://www.genexis.eu
PKG_LICENSE:=GENEXIS
PKG_LICENSE_URL:=
endef
define Package/$(PKG_NAME)/description
This package contains api for the dm-framework
endef
define Build/Prepare
$(CP) -rf ./src/* $(PKG_BUILD_DIR)/
endef
TARGET_CFLAGS += $(FPIC) -I$(PKG_BUILD_DIR)
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR)\
PROJECT_ROOT="$(PKG_BUILD_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
EXTRA_CFLAGS="$(TARGET_CFLAGS)" \
all
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/core/dm_api.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/core/dm_linker.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/core/dbmgr.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/include/dm_log.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/utils/dm_list.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/libdmapi.so $(1)/usr/lib/
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/sbin/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/libdmapi.so $(1)/usr/lib/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -0,0 +1,64 @@
#
# Copyright (c) 2023 Genexis B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
#
PROG = libdmapi.so
SRCS = \
core/dm_api.c \
core/dm_linker.c \
core/dbmgr.c \
core/inode_buf.c \
core/dm_apply.c \
core/dm_import.c \
core/db_upgrade.c \
utils/dm_list.c \
utils/dm_log.c \
utils/ubus_client.c \
utils/utils.c \
quickjs/qjs.c \
quickjs/qjs_log.c \
quickjs/qjs_dm_api.c \
quickjs/qjs_uci_api.c \
quickjs/qjs_ubus_api.c
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
CC = $(CROSS_COMPILE)gcc
STRIP = $(CROSS_COMPILE)strip
CFLAGS += \
-I core \
-I $(STAGING_DIR)/usr/include $(EXTRA_CFLAGS) \
-I handlers/common \
-I handlers/tr181 \
-I include \
-I utils \
-I quickjs
CFLAGS += -MMD -MP -std=gnu99
LDFLAGS = -shared
CFLAGS += -Wall -Werror -fpic
LDFLAGS += -lquickjs -lsqlite3 -latomic
# END for src from mgmt-agent
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $^ $(LDFLAGS) -o $@
%.o: %.c
$(CC) -c $(CFLAGS) $^ -o $@
clean:
rm -f $(PROG) *.o core $(DEPS)
-include $(DEPS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifndef DB_UPGRADE_H
#define DB_UPGRADE_H
int get_db_user_version(const char *db_path, int *user_version);
int upgrade_db(const char *curr_db, const char *new_db, int new_version);
#endif

View File

@@ -0,0 +1,684 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#include "dbmgr.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dm.h"
#include "dm_log.h"
#include "dm_node.h"
#include "sqlite3.h"
#define MAX_SQL_STATEMENT_LEN 4096
static sqlite3 *transaction_db = NULL;
static char sql_statement[MAX_SQL_STATEMENT_LEN];
// sqlite busy handler: the SQLITE_BUSY could happen when one process trys to access db
// (read out of session in our case) while another process is in the process of commiting
// a transaction. the busy time is normally short within 100 ms.
static int db_busy_handler(void *context, int count)
{
dmlog_debug("db_busy_handler %s, %d", sql_statement, count);
// non-zero means retry..
return 1;
}
static char *_get_node_rel_path_name(const struct dm_node_info *head,
const struct dm_node_info *node)
{
static char _path_name[512] = {'\0'};
if (node != NULL && node != head) {
_get_node_rel_path_name(head, node->parent);
}
if ((node == head) || (node == NULL)) /* end of recursion make sure pathname is the empty string */
{
memset(_path_name, 0, sizeof(_path_name));
} else {
strcat(_path_name, node->name);
strcat(_path_name, "_");
}
return _path_name;
}
static const char *get_node_rel_path_name(const struct dm_node_info *head,
const struct dm_node_info *node)
{
char *name = _get_node_rel_path_name(head, node);
int len = strlen(name);
// remove last '_'
if (len > 0) {
name[len - 1] = '\0';
}
return name;
}
static const char *get_table_field_name(const struct dm_node_info *node)
{
const struct dm_node_info *p = node;
while (p->parent != dm_node_get_root()) {
if (p->type == DM_NODE_OBJECT_LIST) {
break;
}
p = p->parent;
}
return get_node_rel_path_name(p, node);
}
static const char *get_int_str(int i)
{
static char digit[16];
sprintf(digit, "%d", i);
return digit;
}
static void get_db_index_condition(const struct dm_node_info *info, char *buf, const dm_index_t indexes[], int *cnt)
{
if (info == NULL) {
return;
}
if (info != dm_node_get_root()) {
get_db_index_condition(info->parent, buf, indexes, cnt);
}
if (info->type == DM_NODE_OBJECT_LIST && indexes[*cnt] > 0) {
if (*cnt > 0) {
strcat(buf, " AND ");
}
strcat(buf, "\"IndexOf");
strcat(buf, info->name);
strcat(buf, "\"");
strcat(buf, "=");
strcat(buf, get_int_str(indexes[*cnt]));
(*cnt)++;
}
}
static void get_db_index_field(const struct dm_node_info *info, char *buf, int *cnt)
{
if (info == NULL)
return;
if (info != dm_node_get_root())
get_db_index_field(info->parent, buf, cnt);
if (info->type == DM_NODE_OBJECT_LIST) {
if (*cnt > 0) {
strcat(buf, ",");
}
strcat(buf, "\"IndexOf");
strcat(buf, info->name);
strcat(buf, "\"");
(*cnt)++;
}
}
static const char *get_query_sql(const dm_node_t *node, int max_in_list)
{
const struct dm_node_info *info = dm_node_get_info(node->id);
if (info == NULL) {
dmlog_error("get_query_sql, node id not found");
return NULL;
}
strcpy(sql_statement, "select ");
if (dm_node_is_parameter(node->id)) {
if (max_in_list)
strcat(sql_statement, "MAX(");
strcat(sql_statement, "\"");
strcat(sql_statement, get_table_field_name(info));
strcat(sql_statement, "\"");
if (max_in_list)
strcat(sql_statement, ")");
} else if (dm_node_is_objectlist(node->id)) {
const char *node_name = dm_node_name(node->id);
if (node_name == NULL)
return NULL;
strcat(sql_statement, "\"IndexOf");
strcat(sql_statement, node_name);
strcat(sql_statement, "\"");
} else {
return NULL;
}
strcat(sql_statement, " FROM ");
strcat(sql_statement, dm_node_get_table_name(info));
if (node->cnt > 0) {
strcat(sql_statement, " WHERE ");
int cnt = 0;
if (max_in_list) {
// start from parant of the object.
info = dm_node_get_info(dm_node_id_parent(dm_node_id_parent(node->id)));
}
get_db_index_condition(info, sql_statement, node->index, &cnt);
}
strcat(sql_statement, ";");
return sql_statement;
}
static const char *get_query_all_indexes_sql(const dm_node_t *node, const char *keys, int sort)
{
const struct dm_node_info *info = dm_node_get_info(node->id);
if (info == NULL) {
dmlog_error("get_query_all_indexes_sql, node id not found");
return NULL;
}
if (dm_node_is_counter(node->id)) {
dm_node_id_t counter = dm_node_counter_id(node->id);
if (counter == INVALID_DM_NODE_ID) {
dmlog_error("invalid counter id %d", counter);
return NULL;
}
info = dm_node_get_info(counter);
if (info == NULL) {
dmlog_error("info is NULL");
return NULL;
}
strcpy(sql_statement, "select COUNT(\"IndexOf");
strcat(sql_statement, info->name);
strcat(sql_statement, "\")");
} else {
strcpy(sql_statement, "select");
strcat(sql_statement, " IndexOf");
strcat(sql_statement, info->name);
int index_cnt = dm_node_index_cnt(node->id);
if (index_cnt > 1 && node->cnt < index_cnt - 1) {
const struct dm_node_info *pinfo = dm_node_get_info(dm_node_i_parent_id(node->id));
if (pinfo) {
strcat(sql_statement, ",IndexOf");
strcat(sql_statement, pinfo->name);
} else {
dmlog_error("get_query_all_indexes_sql, invalid node: %s", dm_node_str(node));
}
}
struct dm_object *obj = (struct dm_object *)info;
if (obj->key_param_names != NULL) {
strcat(sql_statement, ",_key");
char *tmp = strdup(obj->key_param_names);
char *key = strtok(tmp, ",");
while (key != NULL) {
strcat(sql_statement, ",\"");
strcat(sql_statement, key);
strcat(sql_statement, "\"");
key = strtok(NULL, ",");
}
free(tmp);
}
}
strcat(sql_statement, " FROM ");
strcat(sql_statement, dm_node_get_table_name(info));
if (dm_node_index_cnt(info->parent->node_id) > 0 && node->cnt > 0) {
strcat(sql_statement, " WHERE ");
int cnt = 0;
get_db_index_condition(info->parent, sql_statement, node->index, &cnt);
if (keys != NULL && keys[0] != '\0') {
strcat(sql_statement, " AND ");
}
} else if (keys != NULL && keys[0] != '\0') {
strcat(sql_statement, " WHERE ");
}
if (keys != NULL && keys[0] != '\0') {
strcat(sql_statement, keys);
}
if (sort && info->flag & FLAG_HAS_ORDER)
strcat(sql_statement, " ORDER BY \"Order\"");
strcat(sql_statement, ";");
return sql_statement;
}
// The SQL standard specifies that single-quotes in strings are escaped
// by putting two single quotes in a row.
static void strcat_str_data(char *dest, const char *data)
{
int len = strlen(dest);
for (; *data != '\0'; data++, len++) {
if (*data == '\'') {
dest[len] = '\'';
len++;
dest[len] = '\'';
} else {
dest[len] = *data;
}
}
dest[len] = '\0';
}
static const char *get_update_sql(const dm_node_t *node, const char *data)
{
const struct dm_node_info *info = dm_node_get_info(node->id);
if (info == NULL) {
dmlog_error("get_update_sql, node id not found");
return NULL;
}
strcpy(sql_statement, "UPDATE ");
strcat(sql_statement, dm_node_get_table_name(info));
strcat(sql_statement, " SET \"");
strcat(sql_statement, get_table_field_name(info));
strcat(sql_statement, "\" = ");
strcat(sql_statement, "\'");
if (strchr(data, '\'') != NULL)
// containing single quotes, needs special handling.
strcat_str_data(sql_statement, (const char *)data);
else
strcat(sql_statement, (const char *)data);
strcat(sql_statement, "\'");
if (node->cnt > 0) {
strcat(sql_statement, " WHERE ");
int cnt = 0;
get_db_index_condition(info, sql_statement, node->index, &cnt);
}
strcat(sql_statement, ";");
return sql_statement;
}
static int db_next_index_callback(void *context, int argc, char *argv[], char *cols[])
{
(void)argc;
(void)cols;
int *next_index = (int *)context;
if (argv[0]) {
*next_index = atoi(argv[0]);
}
return 0;
}
static int exec_sql(const char *sql, sqlite_callback callback, void *context)
{
if (transaction_db == NULL) {
dmlog_error("db is not opened");
return -1;
}
char *err_msg = NULL;
int ret = sqlite3_exec(transaction_db, sql, callback, context, &err_msg);
if (ret != SQLITE_OK) {
dmlog_error("SQL command(%s) error: %s", sql, err_msg);
sqlite3_free(err_msg);
return -1;
}
return 0;
}
// sql in transaction
static int exec_trans_sql(const char *sql, sqlite_callback callback, void *context)
{
return exec_sql(sql, callback, context);
}
static int get_object_next_index(const dm_node_t *node)
{
const struct dm_node_info *info = dm_node_get_info(node->id);
if (info == NULL)
return -1;
const struct dm_node_info *p = info->parent;
while (p != dm_node_get_root() && p->parent != dm_node_get_root()) {
if (p->type == DM_NODE_OBJECT_LIST) {
break;
}
p = p->parent;
}
strcpy(sql_statement, "select ");
strcat(sql_statement, "\"NextIndexOf");
strcat(sql_statement, get_node_rel_path_name(p, info));
strcat(sql_statement, "\" FROM ");
if (p->parent == dm_node_get_root()) {
strcat(sql_statement, dm_node_get_root()->name);
strcat(sql_statement, "_");
strcat(sql_statement, p->name);
} else {
const char *tb = dm_node_get_table_name(p);
if (tb == NULL) {
dmlog_error("no db table for node %s", dm_node_str(node));
return -1;
}
strcat(sql_statement, tb);
if (dm_node_index_cnt(node->id) > 1) {
strcat(sql_statement, " WHERE ");
int cnt = 0;
get_db_index_condition(info->parent, sql_statement, node->index, &cnt);
}
}
strcat(sql_statement, ";");
int next_index = -1;
exec_sql(sql_statement, db_next_index_callback, &next_index);
return next_index;
}
static int update_object_next_index(const dm_node_t *node, int next_index)
{
const struct dm_node_info *info = dm_node_get_info(node->id);
if (info == NULL)
return -1;
const struct dm_node_info *p = info->parent;
while (p != dm_node_get_root() && p->parent != dm_node_get_root()) {
if (p->type == DM_NODE_OBJECT_LIST) {
break;
}
p = p->parent;
}
strcpy(sql_statement, "UPDATE ");
if (p->parent == dm_node_get_root()) {
strcat(sql_statement, dm_node_get_root()->name);
strcat(sql_statement, "_");
strcat(sql_statement, p->name);
} else {
strcat(sql_statement, dm_node_get_table_name(p));
}
strcat(sql_statement, " SET \"NextIndexOf");
strcat(sql_statement, get_node_rel_path_name(p, info));
strcat(sql_statement, "\" = ");
strcat(sql_statement, get_int_str(next_index));
if (dm_node_index_cnt(node->id) > 1) {
strcat(sql_statement, " WHERE ");
int cnt = 0;
get_db_index_condition(info->parent, sql_statement, node->index, &cnt);
}
strcat(sql_statement, ";");
return exec_trans_sql(sql_statement, NULL, NULL);
}
static const char *get_insert_sql(const dm_node_t *node, int new_index)
{
int i;
int cnt = 0;
const struct dm_node_info *info = dm_node_get_info(node->id);
if (info == NULL) {
dmlog_error("get_insert_sql, node id not found");
return NULL;
}
strcpy(sql_statement, "insert INTO ");
strcat(sql_statement, dm_node_get_table_name(info));
strcat(sql_statement, " (");
get_db_index_field(info, sql_statement, &cnt);
strcat(sql_statement, ") VALUES(");
cnt = dm_node_index_cnt(node->id);
for (i = 0; i < cnt - 1; i++) {
strcat(sql_statement, get_int_str(node->index[i]));
strcat(sql_statement, ",");
}
strcat(sql_statement, get_int_str(new_index));
strcat(sql_statement, ");");
return sql_statement;
}
static const char *get_delete_sql_condition(const dm_node_t *node)
{
static char condition[256];
const struct dm_node_info *info = dm_node_get_info(node->id);
if (info == NULL) {
dmlog_error("get_delete_sql_condition, node id not found");
return NULL;
}
if (node->cnt > 0) {
strcpy(condition, " WHERE ");
int cnt = 0;
get_db_index_condition(info, condition, node->index, &cnt);
} else {
return NULL;
}
return condition;
}
int dbmgr_init(const char *db_file)
{
int ret = sqlite3_open_v2(db_file, &transaction_db, SQLITE_OPEN_READWRITE, NULL);
if (SQLITE_OK != ret || transaction_db == NULL) {
dmlog_error("sqlite3_open_v2 failed");
return -1;
}
sqlite3_busy_timeout(transaction_db, SQLITE_BUSY_TIMEOUT);
sqlite3_busy_handler(transaction_db, db_busy_handler, NULL);
dmlog_info("dbmgr_init OK");
return 0;
}
int dbmgr_finalize(void)
{
if (transaction_db) {
sqlite3_close(transaction_db);
transaction_db = NULL;
}
return 0;
}
int dbmgr_tranx_begin(void)
{
dmlog_debug("dbmgr_tranx_begin");
return exec_trans_sql("BEGIN;", NULL, NULL);
}
int dbmgr_tranx_revert(void)
{
dmlog_debug("dbmgr_tranx_revert");
return exec_trans_sql("ROLLBACK;", NULL, NULL);
}
int dbmgr_tranx_commit(void)
{
dmlog_debug("dbmgr_tranx_commit");
int ret = exec_trans_sql("COMMIT;", NULL, NULL);
if (ret != 0) {
dmlog_error("dbmgr_tranx_commit, sql COMMIT; failed");
return -1;
}
return 0;
}
static int db_get_data_callback(void *context, int cnt, char *data[], char *names[])
{
if (cnt <= 0 || data[0] == NULL) {
dmlog_debug("db_get_data_callback, no data");
return 0;
}
char **val = context;
*val = strdup(data[0]);
return 0;
}
static int _dbmgr_get(const dm_node_t *node, char **value, int get_max_in_list)
{
const char *sql = get_query_sql(node, get_max_in_list);
if (sql == NULL) {
return -1;
}
return exec_sql(sql, db_get_data_callback, value);
}
int dbmgr_get(const dm_node_t *node, char **value)
{
int retval = _dbmgr_get(node, value, 0);
return retval;
}
int dbmgr_get_child(const dm_node_t *node, const char *child_name, char **value)
{
dm_node_t child_node = *node;
child_node.id = dm_node_get_child_id(node->id, child_name);
return dbmgr_get(&child_node, value);
}
int dbmgr_get_max(const dm_node_t *node, unsigned int *max)
{
char *value = NULL;
if (_dbmgr_get(node, &value, 1) < 0 || value == NULL) {
return -1;
}
*max = atoi(value);
free(value);
return 0;
}
int dbmgr_set(const dm_node_t *node, const char *data)
{
const char *sql = get_update_sql(node, data);
int ret = exec_trans_sql(sql, NULL, NULL);
if (ret != 0)
return -1;
return 0;
}
int dbmgr_set_uint(const dm_node_t *node, unsigned int data)
{
char *str;
asprintf(&str, "%u", data);
int ret = dbmgr_set(node, str);
free(str);
return ret;
}
int dbmgr_get_next_free_index(const dm_node_t *node)
{
return get_object_next_index(node);
}
int dbmgr_add(const dm_node_t *node)
{
int next_index = get_object_next_index(node);
if (next_index <= 0) {
dmlog_error("dbmgr_add Error: next_index is %d", next_index);
return 0;
}
const char *sql = get_insert_sql(node, next_index);
int ret = exec_trans_sql(sql, NULL, NULL);
if (ret != 0)
return -1;
if (update_object_next_index(node, next_index + 1) != 0) {
return 0; // 0 means invalid index
}
return next_index;
}
static int delete_db_instances(const struct dm_node_info *info, const char *conditions)
{
if (info == NULL) {
dmlog_info("delete_db_instances node not found");
return -1;
}
const char *table_name = dm_node_get_table_name(info);
if (info->type == DM_NODE_OBJECT_LIST && table_name) {
strcpy(sql_statement, "DELETE FROM ");
strcat(sql_statement, table_name);
if (conditions != NULL && *conditions != '\0') {
strcat(sql_statement, conditions);
}
strcat(sql_statement, ";");
return exec_trans_sql(sql_statement, NULL, NULL);
}
return 0;
}
int dbmgr_del(const dm_node_t *node)
{
return delete_db_instances(dm_node_get_info(node->id), get_delete_sql_condition(node));
}
int dbmgr_query_indexes(const dm_node_t *node, const char *keys, sqlite_callback cb, void *context, int sort)
{
const char *sql = get_query_all_indexes_sql(node, keys, sort);
return exec_sql(sql, cb, context);
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifndef DBMGR_H
#define DBMGR_H
#include "dm_types.h"
typedef int (*sqlite_callback)(void *, int, char *[], char *[]);
int dbmgr_init(const char *db_file);
int dbmgr_finalize(void);
int dbmgr_tranx_begin(void);
int dbmgr_tranx_revert(void);
int dbmgr_tranx_commit(void);
int dbmgr_get(const dm_node_t *node, char **value);
int dbmgr_get_child(const dm_node_t *node, const char *child_name, char **value);
int dbmgr_get_max(const dm_node_t *node, unsigned int *max);
int dbmgr_set(const dm_node_t *node, const char *data);
int dbmgr_set_uint(const dm_node_t *node, unsigned int data);
int dbmgr_add(const dm_node_t *node);
int dbmgr_del(const dm_node_t *node);
int dbmgr_query_indexes(const dm_node_t *node, const char *keys, sqlite_callback cb, void *context,
int sort);
int dbmgr_get_next_free_index(const dm_node_t *node);
#endif /* DBMGR_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,265 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef DM_API_H
#define DM_API_H
#include <json-c/json.h>
#include "dm_types.h"
#include "dm_node.h"
struct dm_uci_context {
int id;
const char *savedir;
};
/** Initialize dmapi.
* @return 0 in case of success, or < 0 in case of error
*/
int dmapi_init(const char *service_name);
// Transaction action when session is end
enum TRANX_ACTION {
TRANX_NO_ACTION = 0,
TRANX_ROLLBACK,
TRANX_COMMIT,
TRANX_COMMIT_AND_APPLY
};
/** Start a session.
* Only one session can be started and active
* While starting the session the lock is taken to avoid race conditions
* @pre dmapi_init should be called successfully
* @return 0 in case of success, or a nonzero value in case of error
*/
int dmapi_session_start();
/** End a session.
* Only one session can be started and active
* @pre dmapi_session_start should be called successfully
* @param action[in] one of the actions defined in TRANX_ACTION
* @return 0 in case of success, or a nonzero value in case of error
*/
int dmapi_session_end(int action);
/** Apply changes in a session.
* @pre dmapi_session_start should be called successfully
* @return 0 in case of success, or a nonzero value in case of error
*/
int dmapi_session_apply(void);
/** Commits a transaction in a session.
* @pre dmapi_session_start should be called successfully
* and have modified parameters or objects by calling
* dmapi_xxx_set/add/del
* @return 0 in case of success, or a nonzero value in case of error
*/
int dmapi_session_commit(void);
/** Revert changes made in current session.
* @pre dmapi_session_start should be called successfully
* and have modified parameters or objects by calling
* dmapi_xxx_set/add/del
* @return 0 in case of success, or a nonzero value in case of error
*/
int dmapi_session_revert(void);
/** Check if session in the dmapi context is valid and active.
* @pre dmapi_init should be called successfully
* @return 1 if active, or 0 when invalid or not started
*/
int dmapi_in_session(void);
/** Delete a dmapi communication context.
* @pre dmapi_init should be called successfully
* @return none
*/
void dmapi_quit(void);
/** Enable or disable feature of "session on the fly"
* With this feature enabled, session will be started automatically when set/add/del APIs are called,
* so you don't have to call dmapi_session_start explicitly before modifying data models.
* but you still need to end the session explicitly by calling dmapi_session_end.
* @param enable: 0: disable, 1: enable
* @pre dmapi_init should be called successfully
* @return none
*/
void dmapi_set_session_on_fly(int enable);
/** Set UCI savedir
* @param savedir: UCI savedir
* @pre dmapi_init should be called successfully
* @return none
*/
void dmapi_set_uci_savedir(const char *savedir);
/** Enable or disable feature of "Auto reference deletion" when deleting objects
* this feature should be not enabled by cwmp client.
* @param enable: 0: disable, 1: enable
* @pre dmapi_init should be called successfully
* @return none
*/
void dmapi_set_dm_auto_del(int enable);
/** Get parameter value of specific parameter node.
*
* @pre dmapi_init should be called successfully
*
* @param[in] node - pointer to parameter node
* @param[out] value - pointer to pointer to save the result, the value must be freed after use.
*
* @return 0 in case of success, or a nonzero value in case of error
*/
int dmapi_param_get(const dm_node_t *node, char **value);
/** Set parameter value of specific parameter node.
*
* @pre dmapi_session_start should be called successfully
*
* @param[in] node - pointer to parameter node
* @param[in] param_data - pointer to string parameter value to set
*
* @return 0 in case of success, or a nonzero value in case of error
*/
int dmapi_param_set(const dm_node_t *node, const char *param_data);
/** Add specific object node.
*
* @pre dmapi_session_start should be called successfully
*
* @param[in] node - pointer to object node, the index of the node will be updated upon success
*
* @return 0 in case of success, or a nonzero value in case of error
*/
int dmapi_object_add(dm_node_t *node);
/** Delete specific object node.
*
* @pre dmapi_session_start should be called successfully
*
* @param[in] node - pointer to object node
*
* @return 0 in case of success, or a nonzero value in case of error
*/
int dmapi_object_del(const dm_node_t *node);
/** Operate on the command node.
*
* @param[in] node - pointer to multi-object node as input
* @param[in] args - arguments in json format.
* @param[out] json_input - input of the command as json string format.
* @param[out] output - output of the command as json_object.
*
* @return 0 in case of success, -1 in case of error
*/
int dmapi_operate(const dm_node_t *node, const char *json_input, struct json_object **json_output);
/** Check if an object instance exist
* @param[in] node - node as input
* @param[in] db_only - if the node should be in db or not
* @return 1 if exist, otherwise return 0
*/
int dmapi_node_exist(const dm_node_t *node, int db_only);
typedef void *dm_nodelist_h;
#define DM_INVALID_NODELIST ((dm_nodelist_h)NULL)
// macro to iterate the node list
#define nodelist_for_each_node(node, list) \
for ((node) = dm_nodelist_first((list)); (node) != NULL; (node) = dm_nodelist_next((list)))
/** Get all instances of a multi-object node, node must be a multi-object type.
* @param node[in] pointer to multi-object node as input
* @return handle of instances list in case of success, NULL value in case of error
*/
dm_nodelist_h dm_nodelist_get(const dm_node_t *node);
// for only db
dm_nodelist_h dm_nodelist_get_db(const dm_node_t *node);
/** Get all instances of a multi-object node, node must be a multi-object type.
* @param node[in] pointer to multi-object node as input
* @param keys[in] sql condition
* @param only_db[in] true if only get db instance.
* @return handle of instances list in case of success, NULL value in case of error
*/
dm_nodelist_h dm_nodelist_find(const dm_node_t *node,
const char *keys, int only_db);
/** Wrapper interface for dm_nodelist_find to find only one node as expected.
* If more than one are found, the first one will be the result
* @param node[in] pointer to multi-object node as input
* @param keys[in] sql condition
* @param only_db[in] true if only get db instance.
* @param result[out] as output
* @return 0 if not found, or a nonzero value when found
*/
int dm_nodelist_find_first(const dm_node_t *node,
const char *keys, dm_node_t *result, int only_db);
/** Free a node list.
* @pre dm_nodelist_get or dm_nodelist_find should be called successfully
* @param list[in] handler of node list as input
* @return none
*/
void dm_nodelist_free(dm_nodelist_h list);
/** Get first instance of node instance list.
* @pre dm_nodelist_get or dm_nodelist_find should be called successfully
* @param list[in] handler of node list as input
* @return node pointer on success, NULL when node does not exist
*/
const dm_node_t *dm_nodelist_first(dm_nodelist_h list);
/** Get next instance of node instance list.
* @pre dm_nodelist_get or dm_nodelist_find should be called successfully
* @param list[in] handler of node list as input
* @return node pointer on success, NULL when node does not exist
*/
const dm_node_t *dm_nodelist_next(dm_nodelist_h list);
/** Get count of instance in the list.
* @pre dm_nodelist_get or dm_nodelist_find should be called successfully
* @param[in] list handler of node list as input
* @return number of instances
*/
int dm_nodelist_cnt(dm_nodelist_h list);
/** Get each node by index, scope is from [0 - (max_cnt-1)].
* @pre dm_nodelist_get or dm_nodelist_find should be called successfully
* @param list_h[in] handler of node list as input
* @param i[in] index value as input
* @return node pointer
*/
const dm_node_t *dm_nodelist_node(dm_nodelist_h list_h, int i);
/** Get node index by sequence number, scope is from [0 - (max_cnt-1)].
* @pre dm_nodelist_get or dm_nodelist_find should be called successfully
* @param list_h[in] handler of node list as input
* @param i[in] index value as input
* @return index of node
*/
dm_index_t dm_nodelist_index(dm_nodelist_h list_h, int i);
const char *dm_nodelist_key(dm_nodelist_h list_h, int i, const char *key);
void dmapi_dump_node_buffer(const dm_node_t *node);
int dmapi_handle_ubus_event(dm_node_id_t id, const char *json_event_str, struct json_object **res);
#endif /* for dmapi_H */
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,725 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#include "dm_apply.h"
#include <quickjs/quickjs-libc.h>
#include <stdlib.h>
#include <string.h>
#include "dbmgr.h"
#include "dm_api.h"
#include "dm_list.h"
#include "dm_log.h"
#include "dm_node.h"
#include "qjs_uci_api.h"
#include "qjs.h"
#include "ubus_client.h"
typedef struct {
const char* key;
int order;
} key_order_pair;
// datamodel change list during the session
static dm_list_h changed_node_list = NULL;
static dm_list_h apply_uci_list = NULL;
void add_apply_package(char *package)
{
if (!package) {
return;
}
if (apply_uci_list == NULL) {
apply_uci_list = dm_list_create(NULL);
}
// add the uci package name to the apply list
if (!dm_list_contains(apply_uci_list, (const void*)package)) {
dmlog_debug("add uci package to apply: %s", package);
dm_list_append(apply_uci_list, package);
} else {
free(package);
}
}
void del_apply_package(char *package)
{
if (!package || !apply_uci_list) {
return;
}
dmlog_debug("remove uci package to apply: %s", package);
dm_list_remove(apply_uci_list, package);
}
void dm_apply_reset_changes(void)
{
if (changed_node_list) {
dm_list_free(changed_node_list);
changed_node_list = NULL;
}
if (apply_uci_list) {
dm_list_free(apply_uci_list);
apply_uci_list = NULL;
}
}
static int node_change_cmp(const void *change1, const void *change2)
{
struct node_change *n1 = (struct node_change *)change1;
struct node_change *n2 = (struct node_change *)change2;
return !(dm_node_compatible(&n1->node, &n2->node) && (n1->redirected == n2->redirected));
}
static dm_node_id_t find_parent_with_apply_handler(const struct dm_node_info *node_info)
{
if (node_info == NULL) {
return INVALID_DM_NODE_ID;
}
if (qjs_has_apply_handler(node_info->node_id)) {
return node_info->node_id;
}
return find_parent_with_apply_handler(node_info->parent);
}
int dm_appy_add_change(enum DATAMODEL_ACTION action, const dm_node_t *node)
{
dmlog_debug("add change %s", dm_node_str(node));
if (changed_node_list == NULL) {
changed_node_list = dm_list_create(node_change_cmp);
}
struct node_change *pchange = calloc(1, sizeof(struct node_change));
pchange->action = action;
pchange->node = *node;
const struct dm_node_info * info = dm_node_get_info(node->id);
const char *uci_map;
const struct dm_parameter *param = NULL;
// special handling for "Order" parameter
if (info->type == DM_NODE_PARAMETER && info->flag & FLAG_HAS_ORDER) {
// Order parameter,
param = (const struct dm_parameter *)info;
const struct dm_object *pobj = dm_node_get_object(dm_node_i_parent_id(node->id));
if (param->map.map == NULL && pobj->map.map) {
pchange->node.cnt--;
goto end;
}
}
if (info->type == DM_NODE_PARAMETER) {
param = (const struct dm_parameter *)info;
uci_map = param->map.map;
} else {
const struct dm_object *obj = (const struct dm_object *)info;
uci_map = obj->map.map;
}
if (uci_map == NULL && !qjs_has_apply_handler(node->id)) {
// look for parent handler
const dm_node_id_t pid = dm_node_i_parent_id(node->id);
if (pid != INVALID_DM_NODE_ID) {
const struct dm_object *pobj = dm_node_get_object(pid);
if (pobj && pobj->map.map) {
if (param && param->data_type == DM_PATH_NAME && param->data.paths &&
dm_node_get_info(param->data.paths[0])->depends_node_id == pid) {
goto end;
}
dmlog_debug("skip apply for %s", dm_node_str(node));
free(pchange);
return 0;
}
}
dm_node_id_t id = find_parent_with_apply_handler(info->parent);
if (id == INVALID_DM_NODE_ID) {
dmlog_debug("ignored node change for apply %s", dm_node_str(node));
free(pchange);
return 0;
}
pchange->node.id = id;
pchange->node.cnt = dm_node_index_cnt(id);
}
dm_node_id_t depend = dm_node_get_apply_depends(pchange->node.id);
if (depend != INVALID_DM_NODE_ID) {
pchange->node.id = depend;
pchange->redirected = 1;
}
end:
if (dm_list_contains(changed_node_list, (const void*)pchange)) {
free(pchange);
return 0;
}
if (dm_node_is_objectlist(pchange->node.id)) {
pchange->node.cnt = dm_node_index_cnt(pchange->node.id) - 1;
}
dm_list_append(changed_node_list, pchange);
dmlog_debug("added node change %s", dm_node_str(&pchange->node));
return 0;
}
static char *get_package_name(const char *uci_path)
{
char *dot_position = strchr(uci_path, '.');
if (dot_position == NULL) {
dmlog_error("missing dot in the uci_path: %s", uci_path);
return NULL;
}
int length = dot_position - uci_path;
char *result = (char *)malloc(length + 1); // +1 for the null-terminator
strncpy(result, uci_path, length);
result[length] = '\0';
return result;
}
static char *get_package_type(const char *uci_path)
{
char *dot_position = strchr(uci_path, '.');
if (dot_position == NULL) {
dmlog_error("missing dot in the uci_path: %s", uci_path);
return NULL;
}
size_t length = strlen(dot_position + 1) + 1;
char *substring = malloc(length);
strncpy(substring, dot_position + 1, length);
substring[length - 1] = '\0';
return substring;
}
static dm_nodelist_h find_refer_instances(const dm_node_t *node, const dm_node_t *ref_node)
{
dm_path_t path;
dm_node2name(ref_node, path, sizeof(dm_path_t));
const struct dm_object *obj = dm_node_get_object(node->id);
// find the parameter that refers to the "ref_node"
for (int i = 0; i < obj->param_num; i++) {
const struct dm_parameter *param = (const struct dm_parameter*)obj->param_list[i];
if (param->data_type == DM_PATH_NAME && param->data.paths[0] == ref_node->id) {
const struct dm_node_info *param_info = dm_node_get_info(param->node.node_id);
char *search = NULL;
asprintf(&search, "%s='%s'", param_info->name, path);
dmlog_debug("search key: %s", search);
dm_nodelist_h res = dm_nodelist_find(node, search, 1);
free(search);
return res;
}
}
return DM_INVALID_NODELIST;
}
static void apply_param_uci_map(const dm_node_t *node, const dm_node_t *parent, const struct dm_uci_map *map)
{
dmlog_debug("apply_param_uci_map: %s", dm_node_str(node));
char *val = NULL;
if (dbmgr_get(node, &val) < 0 || val == NULL) {
return;
}
char *uci_path = NULL;
char *uci_pkg = NULL;
if (map->map) {
if (parent && strchr(map->map, '.') == NULL) {
char *uci_key = NULL;
dm_node_t key_node;
const struct dm_object *obj = dm_node_get_object(parent->id);
if (dm_node_get_child(parent, "_key", &key_node) < 0) {
dmlog_error("failed to get _key %s", dm_node_str(parent));
goto end;
}
if (dbmgr_get(&key_node, &uci_key) < 0 || uci_key == NULL) {
dmlog_error("failed to call dbmgr_get %s", dm_node_str(&key_node));
goto end;
}
if (obj->map.map == NULL) {
dmlog_error("missing uci map %s", dm_node_str(parent));
free(uci_key);
goto end;
}
uci_pkg = get_package_name(obj->map.map);
asprintf(&uci_path, "%s.%s.%s", uci_pkg, uci_key, map->map);
free(uci_key);
} else {
uci_path = strdup(map->map);
uci_pkg = get_package_name(map->map);
}
if (map->type == DM_UCI_MAP_TYPE_SIMPLE || map->type == DM_UCI_MAP_TYPE_INTERFACE) {
if (dm_node_data_type(node->id) == DM_PATH_NAME) {
// the the uci to the section name of the corresponding pathname
if (val[0] == '\0') {
dm_uci_set(uci_path, val);
} else {
char *key = NULL;
dm_node_t ref_node;
dm_path2node(val, &ref_node);
dbmgr_get_child(&ref_node, "_key", &key);
if (key != NULL) {
dm_uci_set(uci_path, key);
free(key);
} else {
dmlog_error("failed to get key of node %s", val);
}
}
} else {
if (dm_node_is_bool_type(node->id)) {
if (strcmp(val, "1") == 0 || strcmp(val, "true") == 0)
dm_uci_set(uci_path, "1");
else
dm_uci_set(uci_path, "0");
} else {
dm_uci_set(uci_path, val);
}
}
} else if (map->type == DM_UCI_MAP_TYPE_DISABLE) {
if (strcmp(val, "1") == 0 || strcmp(val, "true") == 0)
dm_uci_set(uci_path, "0");
else
dm_uci_set(uci_path, "1");
} else {
dmlog_debug("not support apply uci type: %s", dm_node_str(node));
}
free(uci_path);
}
qjs_call_apply_param_handler(node, val);
add_apply_package(uci_pkg);
end:
free(val);
return;
}
struct dm_inst_key {
const char *key;
dm_node_t node;
};
static int dm_inst_list_cmp(const void *item1, const void *item2)
{
struct dm_inst_key *inst1 = (struct dm_inst_key *)item1;
struct dm_inst_key *inst2 = (struct dm_inst_key *)item2;
if (strcmp((const char*)inst1->key, (const char*)inst2->key) == 0) {
return 0;
}
return 1;
}
static void free_dm_inst_list(dm_list_h list)
{
int cnt = dm_list_cnt(list);
for (int i = 0; i < cnt; i++) {
struct dm_inst_key *inst = dm_list_get(list, i);
free((char *)inst->key);
}
dm_list_free(list);
}
static dm_list_h get_obj_key_list(dm_nodelist_h list)
{
const dm_node_t *n = NULL;
dm_list_h key_list = dm_list_create(dm_inst_list_cmp);
nodelist_for_each_node(n, list)
{
char *key = NULL;
if (dbmgr_get_child(n, "_key", &key) == 0 && key != NULL) {
struct dm_inst_key *ins = malloc(sizeof(struct dm_inst_key));
ins->key = key;
ins->node = *n;
dm_list_append(key_list, ins);
} else {
dmlog_error("failed to get key for node: %s", dm_node_str(n));
}
}
return key_list;
}
static int apply_obj_uci_map(const dm_node_t *node, const struct dm_uci_map *map)
{
int ret = 0;
char *pkg_name = get_package_name(map->map);
char *type = get_package_type(map->map);
dm_nodelist_h list = dm_nodelist_get_db(node);
dm_list_h keys = get_obj_key_list(list);
dm_list_h sect_list = dm_list_create(NULL);
char *uci_key = NULL;
if (map->key != NULL && dm_node_index_cnt(node->id) > 1) {
dm_node_t parent;
dm_node_i_parent(node, &parent);
dbmgr_get_child(&parent, "_key", &uci_key);
}
json_object *json_list = NULL;
if (dm_uci_get_section_list(pkg_name, type, NULL, 0, &json_list) == 0 && json_list != NULL) {
json_object_object_foreach(json_list, key, val) {
if (!qjs_uci_filter(node, val)) {
continue;
}
const char *key_val = NULL;
if (map->key != NULL) {
json_object *val_obj;
if (json_object_object_get_ex(val, map->key, &val_obj)) {
key_val = json_object_get_string(val_obj);
}
}
if (uci_key && strcmp(uci_key, key_val) != 0) {
continue;
}
struct dm_inst_key inst;
inst.key = key;
if (!dm_list_contains(keys, &inst)) {
// special handling for user: set "deleted" instead of deleting
if (strcmp(pkg_name, "users") == 0 && strcmp(type, "user") == 0) {
char *tmp;
asprintf(&tmp, "%s.%s.deleted", pkg_name, key);
dm_uci_set(tmp, "1");
free(tmp);
} else {
dmlog_debug("uci-map: del uci: %s.%s", pkg_name, key);
if (qjs_call_uci_deinit_handler(node, key) == 0) {
dm_uci_del(pkg_name, key);
} else {
dmlog_debug("uci-map: skipped deleting %s", key);
}
}
} else {
dm_list_append(sect_list, strdup(key));
}
}
json_object_put(json_list);
}
int key_cnt = dm_list_cnt(keys);
for (int i = 0; i < key_cnt; i++) {
struct dm_inst_key *inst = dm_list_get(keys, i);
if (!dm_list_contains(sect_list, (const void*)inst->key)) {
// add section for the new instance
dmlog_debug("uci-map: add uci: %s.%s", pkg_name, type);
name_val_t opt_val;
int opt_cnt = 0;
if (uci_key != NULL && map->key) {
opt_val.name = map->key;
opt_val.value = uci_key;
opt_cnt = 1;
}
if (dm_uci_add(pkg_name, type, inst->key, &opt_val, opt_cnt) < 0) {
dmlog_error("failed to add new uci section");
ret = -1;
}
qjs_call_uci_init_handler(&inst->node);
}
}
if (pkg_name) {
add_apply_package(pkg_name);
pkg_name = NULL;
}
free(type);
if (pkg_name) {
free(pkg_name);
}
if (uci_key) {
free(uci_key);
}
dm_nodelist_free(list);
free_dm_inst_list(keys);
dm_list_free(sect_list);
return ret;
}
static int compare_order(const void* a, const void* b) {
key_order_pair* pair_a = (key_order_pair*)a;
key_order_pair* pair_b = (key_order_pair*)b;
return pair_a->order - pair_b->order;
}
static void reorder_uci_sections(const char *pkg, key_order_pair *pairs, int cnt)
{
qsort(pairs, cnt, sizeof(key_order_pair), compare_order);
struct blob_buf b;
memset(&b, 0, sizeof(b));
blob_buf_init(&b, 0);
blobmsg_add_string(&b, "config", pkg);
void *a = blobmsg_open_array(&b, "sections");
for (int i = 0; i < cnt; ++i) {
blobmsg_add_string(&b, NULL, pairs[i].key);
}
blobmsg_close_array(&b, a);
ubus_client_call("uci", "order", b.head, NULL, NULL);
blob_buf_free(&b);
add_apply_package((char*)pkg);
}
// reorder the uci sections according to the "Order" value
static void apply_order(const dm_node_t *node, const char *uci_map)
{
dmlog_info("apply_order, %s, %s", dm_node_str(node), uci_map);
dm_nodelist_h list = dm_nodelist_get_db(node);
int cnt = dm_nodelist_cnt(list);
if (cnt <= 1) {
dm_nodelist_free(list);
return;
}
key_order_pair* pairs = calloc(cnt, sizeof(key_order_pair));
for (int i = 0; i < cnt; i++) {
char* order_str = NULL;
dbmgr_get_child(dm_nodelist_node(list, i), "Order", &order_str);
if (order_str == NULL) {
dmlog_error("apply_order, failed to get Order");
goto exit;
}
pairs[i].order = atoi(order_str);
free(order_str);
pairs[i].key = dm_nodelist_key(list, i, "_key");
if (pairs[i].key == NULL) {
dmlog_error("apply_order, unexpected empty key value");
goto exit;
}
}
char *pkg = get_package_name(uci_map);
reorder_uci_sections(pkg, pairs, cnt);
exit:
for (int i = 0; i < cnt; i++) {
if (pairs[i].key) {
JS_FreeCString(qjs_ctx(), pairs[i].key);
}
}
free(pairs);
dm_nodelist_free(list);
}
static void apply_extended_obj(const dm_node_t *node, const char *path, dm_node_id_t id)
{
dmlog_debug("apply_extended_obj: %s, %s", dm_node_str(node), path);
dm_node_t ref_node;
if (path == NULL) {
return;
}
if (path[0] == '\0') {
// call the deinit handler for the extended object
dm_node_t n = {id};
char *uci_key = NULL;
dbmgr_get_child(node, "_key", &uci_key);
if (uci_key) {
qjs_call_uci_deinit_handler(&n, uci_key);
free(uci_key);
}
return;
}
if (dm_path2node(path, &ref_node) != 0) {
dmlog_error("apply_order, invalid path: %s", path);
return;
}
const struct dm_object *obj = dm_node_get_object(ref_node.id);
for (int i = 0; i < obj->param_num; i++) {
const struct dm_parameter *param = (const struct dm_parameter *)obj->param_list[i];
if (param->node.table_name == NULL) {
continue;
}
if (param->map.map == NULL && !qjs_has_apply_handler(node->id)) {
continue;
}
dm_node_t n = ref_node;
n.id = obj->param_list[i]->node_id;
apply_param_uci_map(&n, node, &param->map);
}
}
void dm_apply_node(struct node_change *change)
{
const dm_node_t *node = &change->node;
dm_node_t *pparent = NULL;
const struct dm_object *parent_obj = NULL;
dm_node_t parent_node;
if (dm_node_i_parent(node, &parent_node) == 0) {
pparent = &parent_node;
parent_obj = dm_node_get_object(parent_node.id);
}
if (parent_obj && parent_obj->map.map && parent_obj->node.depends_node_id != INVALID_DM_NODE_ID) {
// apply to the referenced object that it "extends"
dm_node_t refer_node = parent_node;
refer_node.id = parent_obj->node.depends_node_id;
refer_node.cnt--;
dm_nodelist_h res = find_refer_instances(&refer_node, &parent_node);
const dm_node_t *pnode = NULL;
nodelist_for_each_node(pnode, res) {
if (qjs_has_apply_handler(node->id)) {
qjs_call_apply_obj_handler(node, pnode);
}
else if (dm_node_is_parameter(node->id)) {
const struct dm_parameter *param = dm_node_get_parameter(node->id);
apply_param_uci_map(node, pnode, &param->map);
}
}
dm_nodelist_free(res);
return;
}
if (dm_node_is_parameter(node->id)) {
const struct dm_parameter *param = dm_node_get_parameter(node->id);
if (param->data_type == DM_PATH_NAME && param->data.paths) {
if (pparent && dm_node_get_info(param->data.paths[0])->depends_node_id == pparent->id) {
char *val = NULL;
dbmgr_get(node, &val);
apply_extended_obj(pparent, val, param->data.paths[0]);
return;
}
}
if (param->map.map != NULL || qjs_has_apply_handler(node->id)) {
apply_param_uci_map(node, pparent, &param->map);
if (param->node.flag & FLAG_HAS_ORDER) {
const struct dm_object *pobj = dm_node_get_object(dm_node_i_parent_id(node->id));
if (pobj && pobj->map.map) {
dm_node_t pnode;
dm_node_i_parent(node, &pnode);
apply_order(&pnode, pobj->map.map);
}
}
}
} else if (dm_node_is_objectlist(node->id)) {
const struct dm_object *obj = dm_node_get_object(node->id);
if (obj->map.map != NULL && obj->map.type == DM_UCI_MAP_TYPE_SIMPLE ) {
if (obj->node.depends_node_id == INVALID_DM_NODE_ID) {
apply_obj_uci_map(node, &obj->map);
}
} else if (qjs_has_apply_handler(node->id)) {
qjs_call_apply_obj_handler(node, node);
}
} else if (qjs_has_apply_handler(node->id)) {
qjs_call_apply_obj_handler(node, node);
} else {
dmlog_error("dm_apply_node, node is not handled: %s", dm_node_str(node));
}
}
static int commit_changes()
{
int ret = 0;
if (changed_node_list == NULL)
return 0;
int i;
int cnt = dm_list_cnt(changed_node_list);
for (i = 0; i < cnt; i++) {
struct node_change *change = (struct node_change *)dm_list_get(changed_node_list, i);
dmlog_debug("apply node: %s", dm_node_str(&change->node));
if (change->redirected) {
qjs_call_apply_obj_handler(&change->node, &change->node);
} else {
dm_apply_node(change);
}
dmlog_debug("end of apply node: %s", dm_node_str(&change->node));
}
return ret;
}
// reset parameters that are confidential in db.
static void reset_confidentials()
{
if (changed_node_list == NULL)
return;
int i;
// dbmgr_tranx_begin();
int cnt = dm_list_cnt(changed_node_list);
for (i = 0; i < cnt; i++) {
struct node_change *change = (struct node_change *)dm_list_get(changed_node_list, i);
if (dm_node_is_confidential(change->node.id)) {
if (dbmgr_set(&change->node, "") < 0) {
dmlog_error("failed to reset confidentail parameter: %s", dm_node_str(&change->node));
}
}
}
// dbmgr_tranx_commit();
}
int dm_apply_reset(void)
{
dm_apply_reset_changes();
return 0;
}
// static int reload_service(const char *svc)
// {
// struct blob_buf bb = {};
// if (svc == NULL) {
// return 0;
// }
// blob_buf_init(&bb, 0);
// blobmsg_add_string(&bb, "config", svc);
// int ret = ubus_client_call("uci", "commit", bb.head, NULL, NULL);
// if (ret != 0) {
// dmlog_error("failed to reload service %s", svc);
// } else {
// dmlog_info("reloaded service %s", svc);
// }
// blob_buf_free(&bb);
// return ret;
// }
int dm_apply_do_apply()
{
// int i;
commit_changes();
// the commit will be done in the bbf_config daemon
// int cnt = dm_list_cnt(apply_uci_list);
// for (i = 0; i < cnt; i++) {
// char *pkg_name = dm_list_get(apply_uci_list, i);
// dm_uci_commit(pkg_name);
// }
// cnt = dm_list_cnt(apply_uci_list);
// for (i = 0; i < cnt; i++) {
// char *pkg_name = dm_list_get(apply_uci_list, i);
// reload_service(pkg_name);
// }
reset_confidentials();
dm_apply_reset();
return 0;
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifndef DM_APPLY_H
#define DM_APPLY_H
#include <quickjs/quickjs.h>
#include "dm_node.h"
enum DATAMODEL_ACTION {
DATA_MODEL_ADD,
DATA_MODEL_SET,
DATA_MODEL_DELETE
};
struct node_change {
dm_node_t node;
enum DATAMODEL_ACTION action;
int redirected;
};
int dm_appy_add_change(enum DATAMODEL_ACTION action, const dm_node_t *node);
void dm_apply_reset_changes(void);
int dm_apply_reset(void);
int dm_apply_do_apply();
void dm_apply_node(struct node_change *change);
void add_apply_package(char *package);
#endif /* DM_APPLY_H */

View File

@@ -0,0 +1,373 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "qjs_uci_api.h"
#include "dbmgr.h"
#include "dm.h"
#include "dm_log.h"
#include "dm_node.h"
#include "ubus_client.h"
#include "dm_api.h"
#include "qjs.h"
#include "dm_list.h"
static char* get_tr181_pathname(const char *pn, const char *uci_path, const char *uci_val)
{
json_object *values;
if (uci_val == NULL || uci_val[0] == '\0') {
return NULL;
}
char *path = strdup(uci_path);
char *config = strtok(path, ".");
char *type = strtok(NULL, ".");
if (dm_uci_get_section_list(config, type, NULL, 0, &values) < 0 || values == NULL) {
dmlog_error("get_tr181_pathname, dm_uci_get_section_list failed");
free(path);
return NULL;
}
free(path);
int is_network_interface = 0;
dm_list_h itf_dev_list = NULL;
// special handling for network interface
if (strcmp(uci_path, "network.interface") == 0) {
is_network_interface = 1;
itf_dev_list = dm_list_create(NULL);
}
int index = 1;
// Iterate over all keys in the 'values' object
json_object_object_foreach(values, key, value) {
(void)key;
struct json_object *name_value = NULL;
struct json_object *anonymous = NULL;
if (json_object_object_get_ex(value, ".anonymous", &anonymous)
&& json_object_get_boolean(anonymous)) {
json_object_object_get_ex(value, "name", &name_value);
} else {
json_object_object_get_ex(value, ".name", &name_value);
}
if (is_network_interface) {
// special handling for network interface: skip the loopback and dhcpv6 interfaces.
struct json_object *dev_value;
if (json_object_object_get_ex(value, "device", &dev_value)) {
const char *dev_name = json_object_get_string(dev_value);
if (strcmp(dev_name, "lo") == 0) {
continue;
}
if (dm_list_contains(itf_dev_list, (const void*)dev_name)) {
continue;
}
dm_list_append(itf_dev_list, strdup(dev_name));
}
}
if (strcmp(json_object_get_string(name_value), uci_val) == 0) {
// Found the object with the given name, return its index
char *ret_val = NULL;
asprintf(&ret_val, "%s%d", pn, index);
json_object_put(values);
return ret_val;
} else {
index++;
}
}
if (is_network_interface) {
dm_list_free(itf_dev_list);
}
json_object_put(values);
return NULL;
}
static int import_pathname(const dm_node_t *node, char *uci_value)
{
const struct dm_parameter * param = dm_node_get_parameter(node->id);
if (param->data.paths) {
dm_node_t ref_node = *node;
ref_node.id = param->data.paths[0];
const struct dm_object *obj = dm_node_get_object(ref_node.id);
if (obj && obj->map.map) {
dm_path_t pathname;
ref_node.cnt = dm_node_index_cnt(ref_node.id) - 1;
if (dm_node2name(&ref_node, pathname, sizeof(pathname)) < 0) {
dmlog_error("import_pathname, invalid node");
return -1;
}
// trim the last {i}.
int len = strlen(pathname);
pathname[len - 4] = '\0';
char *pn = get_tr181_pathname(pathname, obj->map.map, uci_value);
if (pn) {
int ret = dmapi_param_set(node, pn);
free(pn);
return ret;
} else {
dmlog_error("import_pathname, get_tr181_pathname failed");
return -1;
}
}
}
return -1;
}
static int importParam(const dm_node_t *node, const struct dm_uci_map *map)
{
char * val = NULL;
if (map->type == DM_UCI_MAP_TYPE_JS) {
JSValue result = qjs_eval_buf(map->map, strlen(map->map), "eval-import-js", JS_EVAL_TYPE_GLOBAL);
if (!JS_IsUndefined(result) && !JS_IsException(result)) {
const char *result_cstr = JS_ToCString(qjs_ctx(), result);
dmapi_param_set(node, result_cstr);
JS_FreeCString(qjs_ctx(), result_cstr);
JS_FreeValue(qjs_ctx(), result);
} else {
dmlog_error("failed to import js: %s", map->map);
}
return 0;
} else {
if (node->cnt == 0 || strchr(map->map, '.') != NULL) {
// uci option with full path
dm_uci_get(map->map, &val);
} else {
// uci option from the js object.
char *buf;
asprintf(&buf, "_arg['%s']", map->map);
JSValue result = qjs_eval_buf(buf, strlen(buf), "eval-uci-js", JS_EVAL_TYPE_GLOBAL);
free(buf);
if (!JS_IsException(result) && !JS_IsUndefined(result)) {
const char *result_cstr = JS_ToCString(qjs_ctx(), result);
val = strdup(result_cstr);
JS_FreeCString(qjs_ctx(), result_cstr);
}
JS_FreeValue(qjs_ctx(), result);
}
}
const struct dm_parameter * param = dm_node_get_parameter(node->id);
if (val == NULL) {
// uci option not present, use the default value defined in JSON if exist.
if (param->default_uci_val) {
dmapi_param_set(node, param->default_uci_val);
}
return 0;
}
if (map->type == DM_UCI_MAP_TYPE_DISABLE) {
if (*val == '0') {
dmapi_param_set(node, "true");
} else {
dmapi_param_set(node, "false");
}
} else if (param->data_type == DM_DATA_BOOLEAN) {
if (*val == '1' || !strcmp(val, "true") || !strcmp(val, "yes")) {
dmapi_param_set(node, "true");
} else {
dmapi_param_set(node, "false");
}
} else if (map->type == DM_UCI_MAP_TYPE_INTERFACE) {
char *pn = get_tr181_pathname("Device.IP.Interface.", "network.interface", val);
if (pn) {
dmapi_param_set(node, pn);
free(pn);
} else {
dmlog_error("import_pathname for network interface failed %s, %s", val, dm_node_str(node));
}
} else {
if (dm_node_data_type(node->id) == DM_PATH_NAME) {
import_pathname(node, val);
} else {
if (param->data_type == DM_DATA_ENUM && param->data.enum_strings) {
// convert the uci case to the tr181 case, ex 'udp' => 'UDP', 'up' => 'Up'
int i = 0;
while (param->data.enum_strings[i]) {
if (strcasecmp(param->data.enum_strings[i], val) == 0) {
dmapi_param_set(node, param->data.enum_strings[i]);
break;
}
i++;
}
if (!param->data.enum_strings[i]) {
dmlog_error("uci value %s not found in the enum, %s", val, dm_node_str(node));
}
} else {
dmapi_param_set(node, val);
}
}
}
free(val);
return 0;
}
static int import_dm_obj(const dm_node_t *node, JSValue js_values);
static int handle_obj_uci_map(const dm_node_t *node, const struct dm_uci_map *map)
{
int ret;
char *path = strdup(map->map);
char *config = strtok(path, ".");
char *type = strtok(NULL, ".");
json_object *values_obj;
if (map->key != NULL && dm_node_index_cnt(node->id) > 1) {
dm_node_t parent;
dm_node_i_parent(node, &parent);
const struct dm_object *obj = dm_node_get_object(parent.id);
if (obj->map.map == NULL || obj->map.type != DM_UCI_MAP_TYPE_SIMPLE) {
dmlog_error("handle_obj_uci_map missing parent map uci: %s", dm_node_str(node));
return -1;
}
char *key_val = NULL;
if (dbmgr_get_child(&parent, "_key", &key_val) < 0 || key_val == NULL) {
dmlog_error("handle_obj_uci_map dbmgr_get_child failed: %s", dm_node_str(node));
return -1;
}
name_val_t match = {map->key, key_val};
ret = dm_uci_get_section_list(config, type, &match, 1, &values_obj);
free(key_val);
} else {
ret = dm_uci_get_section_list(config, type, NULL, 0, &values_obj);
}
free(path);
if (ret != 0 || values_obj == NULL) {
dmlog_warn("dm_uci_get_section_list failed, uci: %s", map->map);
// uci could be missing, skip the error
return 0;
}
int obj_index = 0;
json_object_object_foreach(values_obj, key, val) {
(void)key;
if (!qjs_uci_filter(node, val)) {
continue;
}
dm_node_t new_inst = *node;
if (dmapi_object_add(&new_inst) < 0) {
dmlog_error("failed to add new instance");
ret = -1;
break;
}
json_object *name_obj;
if (json_object_object_get_ex(val, ".name", &name_obj)) {
dm_node_t key_node = new_inst;
key_node.id = dm_node_get_child_id(new_inst.id, "_key");
if (dmapi_param_set(&key_node, json_object_get_string(name_obj)) < 0) {
dmlog_error("failed to set param value");
ret = -1;
}
} else {
dmlog_error("failed to get uci name");
ret = -1;
break;
}
JSValue js_val = json_object_to_jsvalue(val);
JS_SetPropertyStr(qjs_ctx(), qjs_global(), "_arg", js_val);
JS_SetPropertyStr(qjs_ctx(), js_val, ".index", JS_NewInt32(qjs_ctx(), obj_index));
obj_index++;
ret = import_dm_obj(&new_inst, js_val);
if (ret < 0) {
dmlog_error("failed to import node %s", dm_node_str(&new_inst));
// break;
}
}
json_object_put(values_obj);
return 0;
}
extern int update_dm_value(JSContext *ctx, const char *key, JSValue value);
static int import_dm_obj(const dm_node_t *node, JSValue js_values) {
if (qjs_has_import_handler(node->id)) {
int ret = 0;
dm_path_t node_path;
dm_node2name(node, node_path, sizeof(dm_path_t));
if (dm_node_is_object(node->id)) {
strcat(node_path, ".");
}
JSValue input_val = js_values;
JSValue js_val = qjs_call_import_handler(node, input_val);
if (!JS_IsException(js_val) && !JS_IsUndefined(js_val)) {
int len = strlen(node_path);
if (node_path[len-2] == '}') {
node_path[len-4] = '\0';
}
const char *imported_val = get_js_value_str(js_val);
free_js_cstr(imported_val);
ret = update_dm_value(qjs_ctx(), node_path, js_val);
if (ret < 0) {
dmlog_error("update_dm_value failed");
}
}
JS_FreeValue(qjs_ctx(), js_val);
return ret;
}
if (dm_node_is_parameter(node->id)) {
if (dm_node_is_confidential(node->id) || !dm_node_has_db(node->id)) {
return 0;
}
const struct dm_parameter * param = dm_node_get_parameter(node->id);
if (param->map.map == NULL) {
return 0;
}
return importParam(node, &param->map);
}
if (dm_node_is_objectlist(node->id) && !dm_node_is_index_complete(node)) {
const struct dm_object *obj = dm_node_get_object(node->id);
if (obj->map.map != NULL && obj->map.type == DM_UCI_MAP_TYPE_SIMPLE) {
return handle_obj_uci_map(node, &obj->map);
} else {
dmlog_debug("ignored import for object: %s", dm_node_str(node));
}
return 0;
}
if (dm_node_is_object(node->id) || dm_node_is_objectlist(node->id)) {
const struct dm_object * obj = dm_node_get_object(node->id);
for (int i = 0; i < obj->param_num; i++) {
dm_node_t param_node = *node;
param_node.id = obj->param_list[i]->node_id;
if (import_dm_obj(&param_node, js_values) < 0) {
dmlog_error("import param failed: %s", dm_node_str(&param_node));
}
}
for (int i = 0; i < obj->object_num; i++) {
dm_node_t node_obj = *node;
node_obj.id = obj->object_list[i]->node_id;
if (import_dm_obj(&node_obj, js_values) < 0) {
dmlog_debug("import object failed: %s", dm_node_str(&node_obj));
}
}
}
return 0;
}
int importDM()
{
dm_node_t root_node = dm_init_node(DM_DEVICE);
return import_dm_obj(&root_node, JS_UNDEFINED);
}

View File

@@ -0,0 +1,624 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <uci.h>
#include <stdint.h>
#include "dm_api.h"
#include "dm_node.h"
#include "dm_log.h"
#include "dm.h"
#include "dbmgr.h"
#define LOCK_FILE "/var/lock/bbfdm_reference_db.lock"
#define UCI_PACKAGE "bbfdm_reference_db"
extern const dm_node_id_t dm_linker_nodes[];
// Forward declarations
static char *calculate_hash(const char *input);
static int process_linker_node(struct uci_context *ctx, struct uci_package *pkg,
const char *service_hash, const dm_node_t *node);
static int clear_service_entries(struct uci_context *ctx, struct uci_package *pkg,
const char *service_hash);
static int ensure_uci_sections(struct uci_context *ctx, struct uci_package *pkg);
// FNV-1 32-bit parameters
#define FNV_OFFSET_BASIS 0x811C9DC5U
#define FNV_PRIME 0x1000193U
/*
* Calculate 8-character uppercase hex hash using the FNV-1 algorithm.
* Returns malloc-ed string (must be freed by caller) or NULL on error.
*/
static char *calculate_hash(const char *input) {
if (!input) {
return NULL;
}
uint32_t hash = FNV_OFFSET_BASIS;
const unsigned char *ptr = (const unsigned char *)input;
while (*ptr) {
hash *= FNV_PRIME;
hash ^= (uint32_t)(*ptr);
ptr++;
}
char *result = malloc(9); // 8 chars + null terminator
if (!result) {
return NULL;
}
snprintf(result, 9, "%08X", hash);
return result;
}
/**
* Check if a node ID is in the linker nodes array
*/
int is_linker_node(dm_node_id_t node_id) {
for (int i = 0; dm_linker_nodes[i] != INVALID_DM_NODE_ID; i++) {
if (dm_linker_nodes[i] == node_id) {
return 1;
}
}
return 0;
}
int object_has_linker_param(dm_node_id_t object_id) {
const struct dm_object *obj = dm_node_get_object(object_id);
if (!obj) {
return 0;
}
for (int i = 0; i < obj->param_num; i++) {
const struct dm_node_info *info = obj->param_list[i];
if (is_linker_node(info->node_id)) {
return 1;
}
}
return 0;
}
/**
* Process a single linker parameter node
*/
static int process_linker_node(struct uci_context *ctx, struct uci_package *pkg,
const char *service_hash, const dm_node_t *node) {
const struct dm_parameter *param = dm_node_get_parameter(node->id);
if (!param) return -1;
// Check if this parameter is a linker node
if (!is_linker_node(node->id)) {
dmlog_error("Not a linker parameter %s", dm_node_str(node));
return 0; // Not a linker parameter
}
// Get the parent object path
dm_node_t parent_node;
if (dm_node_i_parent(node, &parent_node) != 0) {
dmlog_error("Failed to get parent node for %s", dm_node_str(node));
return -1;
}
// Get parent path
dm_path_t parent_path;
if (dm_node2name(&parent_node, parent_path, sizeof(parent_path)) != 0) {
dmlog_error("Failed to get parent path for %s", dm_node_str(&parent_node));
return -1;
}
// Get current path (same as parent for leaf parameters)
dm_path_t current_path;
if (dm_node2name(&parent_node, current_path, sizeof(current_path)) != 0) {
dmlog_error("Failed to get current path for %s", dm_node_str(&parent_node));
return -1;
}
// Get parameter value
char *key_value = NULL;
if (dbmgr_get(node, &key_value) != 0 || !key_value) {
dmlog_debug("No value found for linker parameter %s", dm_node_str(node));
return 0;
}
// Compose linker string directly from parent_path, keeping instance numbers intact
const char *key_name = param->node.name;
size_t len_linker = strlen(parent_path) + strlen(key_name) + strlen(key_value) + 6; // extra for [==].
char *linker_string = malloc(len_linker);
if (!linker_string) {
dmlog_error("Failed to allocate memory for linker string");
free(key_value);
return -1;
}
dm_node_t parent_node_with_index = parent_node;
parent_node_with_index.cnt = 0;
dm_path_t parent_path_with_index;
if (dm_node2name_with_index(&parent_node_with_index, parent_path_with_index, sizeof(parent_path_with_index), "*") != 0) {
dmlog_error("Failed to get parent path for %s", dm_node_str(&parent_node));
return -1;
}
parent_path_with_index[strlen(parent_path_with_index) - 2] = '\0';
snprintf(linker_string, len_linker, "%s[%s==%s].", parent_path_with_index, key_name, key_value);
// Calculate hashes
char *hash_path = calculate_hash(linker_string);
char *hash_value = calculate_hash(current_path);
if (!hash_path || !hash_value) {
dmlog_error("Failed to calculate hashes for %s", linker_string);
free(linker_string);
free(key_value);
free(hash_path);
free(hash_value);
return -1;
}
// Update UCI sections
struct uci_section *ref_path_section = uci_lookup_section(ctx, pkg, "reference_path");
struct uci_section *ref_value_section = uci_lookup_section(ctx, pkg, "reference_value");
struct uci_section *service_section = uci_lookup_section(ctx, pkg, service_hash);
if (!ref_path_section || !ref_value_section || !service_section) {
dmlog_error("Failed to find required UCI sections");
free(linker_string);
free(key_value);
free(hash_path);
free(hash_value);
return -1;
}
// Set reference_path option
struct uci_ptr ptr;
memset(&ptr, 0, sizeof(ptr));
ptr.package = pkg->e.name;
ptr.section = "reference_path";
ptr.option = hash_path;
ptr.value = current_path;
uci_set(ctx, &ptr);
// Set reference_value option
memset(&ptr, 0, sizeof(ptr));
ptr.package = pkg->e.name;
ptr.section = "reference_value";
ptr.option = hash_value;
ptr.value = (strlen(key_value) > 0) ? key_value : "#";
uci_set(ctx, &ptr);
// Add to service section lists
memset(&ptr, 0, sizeof(ptr));
ptr.package = pkg->e.name;
ptr.section = service_hash;
ptr.option = "reference_path";
ptr.value = hash_path;
uci_add_list(ctx, &ptr);
memset(&ptr, 0, sizeof(ptr));
ptr.package = pkg->e.name;
ptr.section = service_hash;
ptr.option = "reference_value";
ptr.value = hash_value;
uci_add_list(ctx, &ptr);
// dmlog_debug("Processed linker: %s -> %s (path_hash=%s, value_hash=%s)",
// linker_string, current_path, hash_path, hash_value);
// Cleanup
free(linker_string);
free(key_value);
free(hash_path);
free(hash_value);
return 0;
}
/**
* Process all linker nodes by iterating through the linker nodes array
*/
static int process_all_linker_nodes(struct uci_context *ctx, struct uci_package *pkg,
const char *service_hash) {
// Iterate through all linker nodes
for (int i = 0; dm_linker_nodes[i] != INVALID_DM_NODE_ID; i++) {
dm_node_id_t linker_id = dm_linker_nodes[i];
// Check if this is a parameter node
if (!dm_node_is_parameter(linker_id)) {
continue;
}
// Get all instances of multi-instance objects that contain this linker parameter
const struct dm_parameter *param = dm_node_get_parameter(linker_id);
if (!param || !param->node.parent) {
continue;
}
// Find the object that contains this parameter
dm_node_id_t parent_id = param->node.parent->node_id;
// Only handle multi-instance objects; skip single-instance objects
if (dm_node_is_objectlist(parent_id)) {
dm_node_t parent_node = {0};
parent_node.id = parent_id;
// For multi-index nodes, bypass inode buffer and go directly to DB
dm_nodelist_h list = dm_nodelist_find(&parent_node, NULL, 1);
if (list != DM_INVALID_NODELIST) {
const dm_node_t *instance_node;
nodelist_for_each_node(instance_node, list) {
// dmlog_debug("processing linker node %s", dm_node_str(instance_node));
// Create the parameter node for this instance
dm_node_t param_node = *instance_node;
param_node.id = linker_id;
// Process this linker parameter instance
process_linker_node(ctx, pkg, service_hash, &param_node);
}
dm_nodelist_free(list);
}
}
}
return 0;
}
/**
* Clear existing entries for this service
*/
static int clear_service_entries(struct uci_context *ctx, struct uci_package *pkg,
const char *service_hash) {
struct uci_section *service_section = uci_lookup_section(ctx, pkg, service_hash);
if (!service_section) {
return 0; // Section doesn't exist yet
}
// Clear the lists
struct uci_ptr ptr;
memset(&ptr, 0, sizeof(ptr));
ptr.package = pkg->e.name;
ptr.section = service_hash;
ptr.option = "reference_path";
uci_delete(ctx, &ptr);
memset(&ptr, 0, sizeof(ptr));
ptr.package = pkg->e.name;
ptr.section = service_hash;
ptr.option = "reference_value";
uci_delete(ctx, &ptr);
return 0;
}
/**
* Ensure required UCI sections exist
*/
static int ensure_uci_sections(struct uci_context *ctx, struct uci_package *pkg) {
struct uci_ptr ptr;
// Ensure reference_path section exists
memset(&ptr, 0, sizeof(ptr));
ptr.package = pkg->e.name;
ptr.section = "reference_path";
ptr.value = "reference_path";
if (uci_set(ctx, &ptr) != UCI_OK) {
return -1;
}
// Ensure reference_value section exists
memset(&ptr, 0, sizeof(ptr));
ptr.package = pkg->e.name;
ptr.section = "reference_value";
ptr.value = "reference_value";
if (uci_set(ctx, &ptr) != UCI_OK) {
return -1;
}
return 0;
}
/**
* Main API function to refresh linker nodes
*/
int dm_refresh_linker_nodes(const char *service_name) {
dmlog_debug("dm_refresh_linker_nodes start");
if (!service_name) {
dmlog_error("Service name is required");
return -1;
}
// Step 1: Open and lock the reference database
int lock_fd = open(LOCK_FILE, O_CREAT | O_RDWR, 0644);
if (lock_fd < 0) {
dmlog_error("Failed to open lock file: %s", LOCK_FILE);
return -1;
}
if (flock(lock_fd, LOCK_EX) != 0) {
dmlog_error("Failed to acquire exclusive lock");
close(lock_fd);
return -1;
}
// Step 2: Calculate service hash
char *service_hash = calculate_hash(service_name);
if (!service_hash) {
dmlog_error("Failed to calculate service hash");
close(lock_fd);
return -1;
}
dmlog_debug("service_hash: %s", service_hash);
// Step 3: Initialize UCI context and point to /var/state for runtime reference DB
struct uci_context *ctx = uci_alloc_context();
if (!ctx) {
dmlog_error("Failed to allocate UCI context");
free(service_hash);
close(lock_fd);
return -1;
}
// Use /var/state as configuration directory
uci_set_confdir(ctx, "/var/state");
// Load or create the UCI package
struct uci_package *pkg = NULL;
if (uci_load(ctx, UCI_PACKAGE, &pkg) != UCI_OK) {
// Package doesn't exist, create it
struct uci_ptr ptr;
memset(&ptr, 0, sizeof(ptr));
ptr.package = UCI_PACKAGE;
if (uci_set(ctx, &ptr) != UCI_OK) {
dmlog_error("Failed to create UCI package: %s", UCI_PACKAGE);
uci_free_context(ctx);
free(service_hash);
close(lock_fd);
return -1;
}
pkg = ptr.p;
}
// Step 4: Ensure required sections exist
if (ensure_uci_sections(ctx, pkg) != 0) {
dmlog_error("Failed to ensure UCI sections");
uci_free_context(ctx);
free(service_hash);
close(lock_fd);
return -1;
}
// Create service section
struct uci_ptr ptr;
memset(&ptr, 0, sizeof(ptr));
ptr.package = pkg->e.name;
ptr.section = service_hash;
ptr.value = "service";
uci_set(ctx, &ptr);
// Step 5: Clear existing entries for this service
clear_service_entries(ctx, pkg, service_hash);
// Step 6: Process all linker nodes
if (process_all_linker_nodes(ctx, pkg, service_hash) != 0) {
dmlog_error("Failed to process linker nodes");
uci_free_context(ctx);
free(service_hash);
close(lock_fd);
return -1;
}
// Step 7: Commit changes
if (uci_commit(ctx, &pkg, false) != UCI_OK) {
dmlog_error("Failed to commit UCI changes");
uci_free_context(ctx);
free(service_hash);
close(lock_fd);
return -1;
}
// Cleanup
uci_free_context(ctx);
free(service_hash);
// Step 8: Release lock
flock(lock_fd, LOCK_UN);
close(lock_fd);
dmlog_info("Successfully refreshed linker nodes for service: %s", service_name);
return 0;
}
/*
* Resolve the linker parameter value for a given object instance path.
* The object_path should include the instance number, for example
* "Device.IP.Interface.1"
* On success, *value will point to a malloc()'d string that must be freed
* by the caller. The function returns 0 on success or -1 on error.
*/
int dm_resolve_linker(const char *object_path, char **value) {
if (!object_path || !value) {
dmlog_error("Invalid arguments to dm_resolve_linker");
return -1;
}
*value = NULL;
/* Calculate the hash used as option name in the reference_value section */
char *hash_str = calculate_hash(object_path);
if (!hash_str) {
dmlog_error("Failed to calculate hash for %s", object_path);
return -1;
}
struct uci_context *ctx = uci_alloc_context();
if (!ctx) {
dmlog_error("Failed to allocate UCI context");
free(hash_str);
return -1;
}
/* reference DB lives in /var/state */
uci_set_confdir(ctx, "/var/state");
struct uci_package *pkg = NULL;
if (uci_load(ctx, UCI_PACKAGE, &pkg) != UCI_OK || !pkg) {
dmlog_error("Failed to load UCI package %s", UCI_PACKAGE);
uci_free_context(ctx);
free(hash_str);
return -1;
}
struct uci_section *ref_value_section = uci_lookup_section(ctx, pkg, "reference_value");
if (!ref_value_section) {
dmlog_error("reference_value section not found in %s", UCI_PACKAGE);
uci_free_context(ctx);
free(hash_str);
return -1;
}
const char *str_val = uci_lookup_option_string(ctx, ref_value_section, hash_str);
if (!str_val) {
dmlog_debug("No linker value found for %s (hash=%s)", object_path, hash_str);
uci_free_context(ctx);
free(hash_str);
return -1;
}
/* Allocate and copy result for caller */
if (strcmp(str_val, "#") == 0) {
/* '#' is used to represent an empty string */
*value = strdup("");
} else {
*value = strdup(str_val);
}
if (!*value) {
uci_free_context(ctx);
free(hash_str);
return -1;
}
uci_free_context(ctx);
free(hash_str);
return 0;
}
/**
* Resolve the object path for a given linker value.
*
* This helper reconstructs the deterministic linker string of the form
* "<base_path>[<key_name>==<key_value>]."
* that was generated by dm_refresh_linker_nodes() and uses its hash to
* look up the real object path from the reference database.
*
* If no matching entry exists in the database the function will fall
* back to returning the linker string itself, exactly mimicking the
* behaviour of legacy _bbfdm_get_references().
*
* The caller is responsible for freeing the returned string.
*
* @param base_path Base object path ending with a dot (e.g. "Device.WiFi.SSID.")
* @param key_name Parameter name that acts as linker key (e.g. "Name")
* @param key_value Desired value of the linker key
* @param object_path [out] malloc-allocated string holding either the
* resolved object path (e.g. "Device.WiFi.SSID.4")
* (NULL when no match is found)
* @return 0 when resolved, -1 if no match/error
*/
int dm_resolve_linker_path(const char *base_path,
const char *key_name,
const char *key_value,
char **object_path) {
if (!base_path || !key_name || !key_value || !object_path) {
dmlog_error("Invalid arguments to dm_resolve_linker_path");
return -1;
}
if (strlen(base_path) == 0 || strlen(key_name) == 0 || strlen(key_value) == 0) {
dmlog_error("base_path, key_name and key_value must not be empty");
return -1;
}
*object_path = NULL;
/* Compose the linker string that was used as basis for the reference hash */
size_t linker_len = strlen(base_path) + strlen(key_name) + strlen(key_value) + 6; /* "[==]." */
char *linker_string = malloc(linker_len);
if (!linker_string) {
return -1;
}
snprintf(linker_string, linker_len, "%s[%s==%s].", base_path, key_name, key_value);
/* Calculate hash for use as option name inside reference_path section */
char *hash_path = calculate_hash(linker_string);
if (!hash_path) {
free(linker_string);
return -1;
}
/* Open UCI context pointing to runtime reference DB (/var/state) */
struct uci_context *ctx = uci_alloc_context();
if (!ctx) {
dmlog_error("Failed to allocate UCI context");
free(linker_string);
free(hash_path);
return -1;
}
uci_set_confdir(ctx, "/var/state");
struct uci_package *pkg = NULL;
if (uci_load(ctx, UCI_PACKAGE, &pkg) != UCI_OK || !pkg) {
dmlog_error("Failed to load UCI package %s", UCI_PACKAGE);
uci_free_context(ctx);
free(linker_string);
free(hash_path);
return -1;
}
struct uci_section *ref_path_section = uci_lookup_section(ctx, pkg, "reference_path");
if (!ref_path_section) {
dmlog_error("reference_path section not found in %s", UCI_PACKAGE);
uci_free_context(ctx);
free(linker_string);
free(hash_path);
return -1;
}
const char *uci_path = uci_lookup_option_string(ctx, ref_path_section, hash_path);
int ret = -1; /* default: not resolved */
if (uci_path) {
/* Matching object path found */
*object_path = strdup(uci_path);
if (*object_path)
ret = 0;
} else {
/* No match. Leave *object_path NULL and return error */
ret = -1;
}
uci_free_context(ctx);
free(linker_string);
free(hash_path);
return ret;
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifndef DM_LINKER_H
#define DM_LINKER_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* Refresh linker nodes for a given service
*
* This function walks through the entire data model tree and updates the
* UCI reference database with linker parameter information for the specified
* service. It creates a deterministic mapping between object paths and their
* linker parameter values.
*
* The function:
* 1. Takes an exclusive lock on the reference database
* 2. Calculates a service hash from the service name
* 3. Prepares the UCI package with required sections
* 4. Walks through all multi-instance objects looking for linker parameters
* 5. Builds linker strings and generates hashes
* 6. Updates the UCI reference database
* 7. Commits changes and releases the lock
*
* @param service_name The UBus object name of the service (e.g., "bbfdm.core")
* @return 0 on success, -1 on error
*/
int dm_refresh_linker_nodes(const char *service_name);
/**
* Check if a node ID is a linker node
*
* This function checks if the given node ID is in the linker nodes array.
*
* @param node_id The node ID to check
* @return 1 if the node is a linker node, 0 otherwise
*/
int is_linker_node(dm_node_id_t node_id);
/**
* Check if an object has a linker parameter
*
* This function checks if the given object has any parameters that are linker nodes.
*
* @param object_id The object ID to check
* @return 1 if the object has a linker parameter, 0 otherwise
*/
int object_has_linker_param(dm_node_id_t object_id);
/**
* Resolve the linker parameter value for a given object instance path
*
* This helper looks up the reference database that was populated by
* dm_refresh_linker_nodes() and returns the value of the linker
* parameter belonging to the supplied object path.
*
* The caller is responsible for freeing the returned string.
*
* @param object_path Full object path including instance number
* (e.g. "Device.IP.Interface.1")
* @param value[out] Pointer that will receive the malloc-allocated value
* @return 0 on success, -1 on failure
*/
int dm_resolve_linker(const char *object_path, char **value);
/*
* Resolve object path from a linker value.
* Returns 0 and sets *object_path on success.
* Returns -1 and leaves *object_path NULL if no matching object path exists
* or on error.
*/
int dm_resolve_linker_path(const char *base_path, const char *key_name, const char *key_value, char **object_path);
#ifdef __cplusplus
}
#endif
#endif /* DM_LINKER_H */

View File

@@ -0,0 +1,478 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "inode_buf.h"
#include "dm_log.h"
#include "qjs.h"
#include "utils.h"
#define GROWTH_FACTOR 2
#define DB_INFO_TIMEOUT 2000
extern void dmapi_refresh_instance_buf(const dm_node_t *node);
static struct inode_entry *inode_g = NULL;
dm_inst_array_t* dm_inst_array_create(size_t initial_capacity) {
dm_inst_array_t *array = calloc(1, sizeof(dm_inst_array_t));
if (initial_capacity <= 0) {
initial_capacity = 1;
}
array->data = calloc(initial_capacity, sizeof(inst_entry_t));
array->size = 0;
array->capacity = initial_capacity;
return array;
}
static void get_all_i_node(dm_node_id_t id, dm_node_id_t *nodes_id, int *cnt)
{
if (!dm_node_is_objectlist(id)) {
id = dm_node_i_parent_id(id);
if (id == INVALID_DM_NODE_ID) {
*cnt = 0;
return;
}
}
nodes_id[0] = id;
*cnt = 1;
dm_node_id_t p = dm_node_i_parent_id(id);
while (p != INVALID_DM_NODE_ID) {
nodes_id[*cnt] = p;
(*cnt)++;
if (*cnt >= MAX_DM_NODE_DEPTH) {
dmlog_info("too long inode");
// panic
break;
}
p = dm_node_i_parent_id(p);
}
}
static struct inode_entry *find_inode_entry(struct inode_entry *head, const dm_node_id_t key)
{
struct inode_entry *current = head;
while (current != NULL) {
if (current->key == key) {
return current;
}
current = current->next;
}
return NULL;
}
static inst_entry_t* dm_inst_array_find(dm_inst_array_t *array, unsigned int index) {
if (array == NULL) {
return NULL;
}
for (size_t i = 0; i < array->size; i++) {
if (array->data[i].index == index) {
return &array->data[i];
}
}
return NULL;
}
static inst_entry_t *find_inst(struct inode_entry *entry, unsigned int index, int *db)
{
inst_entry_t *inst = dm_inst_array_find(entry->insts, index);
if (inst == NULL) {
inst = dm_inst_array_find(entry->dyn_insts, index);
if (db && inst) {
*db = 0;
}
} else if (db) {
*db = 1;
}
return inst;
}
static void free_inode(struct inode_entry *inode);
void dm_inst_array_free(dm_inst_array_t *array) {
if (array == NULL) {
return;
}
for (size_t i = 0; i < array->size; i++) {
JS_FreeValue(qjs_ctx(), array->data[i].value);
free_inode(array->data[i].inode);
}
if (array->data){
free(array->data);
}
free(array);
}
static void free_insts(struct inode_entry *entry)
{
dm_inst_array_free(entry->insts);
dm_inst_array_free(entry->dyn_insts);
entry->insts = NULL;
entry->dyn_insts = NULL;
}
static void free_inode(struct inode_entry *inode)
{
if (inode == NULL) {
return;
}
struct inode_entry *current = inode;
struct inode_entry *next;
while (current != NULL) {
next = current->next;
free_insts(current);
free(current);
current = next;
}
}
int inode_buf_get_js_values(const dm_node_t *node, JSValue values[])
{
int cnt = 0;
dm_node_id_t nodes_id[MAX_DM_NODE_DEPTH];
get_all_i_node(node->id, nodes_id, &cnt);
struct inode_entry **inode = &inode_g;
dm_node_t curr_node;
curr_node.cnt = 0;
int index_i = 0;
for (int i = cnt - 1; i >= 0; i--) {
if (index_i >= node->cnt) {
// not complete index: A.1.B.1.C.{i}.
return index_i;
}
curr_node.id = nodes_id[i];
struct inode_entry *entry = find_inode_entry(*inode, nodes_id[i]);
if (entry == NULL) {
dmapi_refresh_instance_buf(&curr_node);
entry = find_inode_entry(*inode, nodes_id[i]);
}
if (entry == NULL) {
dmlog_error("inode_buf_get_js_values, inode_entry %s not found, %s", dm_node_str(&curr_node), dm_node_str(node));
return -1;
}
int db = 0;
inst_entry_t *inst = find_inst(entry, node->index[index_i], &db);
if (inst == NULL) {
dmlog_error("inode_buf_get_js_values, nst_entry not found %s, %d", dm_node_str(node), node->index[index_i]);
return -1;
}
values[index_i++] = inst->value;
inode = &inst->inode;
curr_node.index[curr_node.cnt] = inst->index;
curr_node.cnt++;
if (db && qjs_has_info_handler(curr_node.id)) {
if (inst->value_time == 0) {
qjs_call_info_handler(&curr_node, inst->value);
inst->value_time = get_uptime_msecs();
} else {
unsigned int now = get_uptime_msecs();
if ((now - inst->value_time) >= DB_INFO_TIMEOUT) {
qjs_call_info_handler(&curr_node, inst->value);
inst->value_time = now;
}
}
}
}
return cnt;
}
struct inode_entry *inode_buf_find(const dm_node_t *node, int *retry)
{
int cnt = 0;
dm_node_id_t nodes_id[MAX_DM_NODE_DEPTH];
get_all_i_node(node->id, nodes_id, &cnt);
struct inode_entry *inode = inode_g;
int index_i = 0;
for (int i = cnt - 1; i >= 0; i--) {
struct inode_entry *entry = find_inode_entry(inode, nodes_id[i]);
if (entry == NULL) {
if (retry) {
*retry = 1;
}
return NULL;
}
if (entry->key == node->id) {
return entry;
}
if (index_i >= node->cnt) {
if (retry) {
*retry = 0;
}
dmlog_error("inode_buf_find, invalid node(missing index) %s", dm_node_str(node));
return NULL;
}
inst_entry_t *inst = find_inst(entry, node->index[index_i], NULL);
if (inst == NULL) {
dmlog_error("inode_buf_find, instance not found %s", dm_node_str(node));
if (retry) {
*retry = 0;
}
return NULL;
}
inode = inst->inode;
index_i++;
}
return NULL;
}
static void create_inode_inst(struct inode_entry **inode, const dm_node_id_t key, dm_inst_array_t *insts, int dynamic)
{
struct inode_entry *entry = calloc(1, sizeof(struct inode_entry));
entry->key = key;
if (dynamic) {
entry->dyn_insts = insts;
entry->dyn_time = get_uptime_msecs();
} else {
entry->insts = insts;
}
entry->next = *inode;
*inode = entry;
}
static void resize_if_needed(dm_inst_array_t *array) {
if (array->size >= array->capacity) {
size_t new_cap = array->capacity * GROWTH_FACTOR;
inst_entry_t *new_data = realloc(array->data, new_cap * sizeof(inst_entry_t));
if (new_data == NULL) {
/* keep original buffer; log and return to avoid losing pointer */
dmlog_error("resize_if_needed: realloc failed (cap=%zu)", new_cap);
return;
}
array->data = new_data;
array->capacity = new_cap;
}
}
void dm_inst_array_append(dm_inst_array_t *array, inst_entry_t *value) {
resize_if_needed(array);
array->data[array->size++] = *value;
}
int dm_inst_array_remove(dm_inst_array_t *array, unsigned int index) {
if (!array) {
return 0;
}
for (size_t i = 0; i < array->size; i++) {
if (array->data[i].index == index) {
JS_FreeValue(qjs_ctx(), array->data[i].value);
free_inode(array->data[i].inode);
for (size_t j = i; j < array->size - 1; j++) {
array->data[j] = array->data[j + 1];
}
array->size--;
return 1;
}
}
return 0;
}
int inode_buf_append_db_inst(const dm_node_t *node, inst_entry_t *inst)
{
dm_inst_array_t * arr = dm_inst_array_create(1);
dm_inst_array_append(arr, inst);
return inode_buf_add_inst(node, arr, 0, 1);
}
int inode_buf_del_db_inst(const dm_node_t *node)
{
int retry;
struct inode_entry *entry = inode_buf_find(node, &retry);
if (!entry) {
if (retry == 0) {
return -1;
}
dm_node_t n = *node;
n.cnt = node->cnt - 1;
dmapi_refresh_instance_buf(&n);
entry = inode_buf_find(node, &retry);
}
if (!entry) {
dmlog_error("inode_buf_del_db_inst, node not found: %s", dm_node_str(node));
return -1;
}
if (dm_inst_array_remove(entry->insts, dm_node_last_index(node))) {
// dmlog_debug("removed instance from buffer: %s", dm_node_str(node));
return 0;
}
dmlog_error("inode_buf_del_db_inst, instance not found: %s", dm_node_str(node));
return -1;
}
static void update_instances(struct inode_entry *inode, dm_inst_array_t *insts, int dynamic)
{
if (dynamic) {
dm_inst_array_free(inode->dyn_insts);
inode->dyn_insts = insts;
inode->dyn_time = get_uptime_msecs();
} else {
dm_inst_array_free(inode->insts);
inode->insts = insts;
}
}
int inode_buf_add_inst(const dm_node_t *node, dm_inst_array_t *insts, int dynamic, int append)
{
dm_node_id_t nodes_id[MAX_DM_NODE_DEPTH];
int cnt;
get_all_i_node(node->id, nodes_id, &cnt);
struct inode_entry **inode = &inode_g;
int index_i = 0;
dm_node_t curr_node;
curr_node.cnt = 0;
// dmlog_debug("inode_buf_add_inst %s, inst_cnt: %d, dynamic: %d", dm_node_str(node), insts->size, dynamic);
for (int i = cnt - 1; i >= 0; i--) {
curr_node.id = nodes_id[i];
struct inode_entry *entry = find_inode_entry(*inode, nodes_id[i]);
if (entry == NULL && i != 0) {
dmapi_refresh_instance_buf(&curr_node);
entry = find_inode_entry(*inode, nodes_id[i]);
}
if (entry == NULL) {
if (i == 0) {
// create the instance
if (!append) {
create_inode_inst(inode, nodes_id[i], insts, dynamic);
} else {
// dmlog_debug("first time to add instance, refresh all");
dm_inst_array_free(insts);
dmapi_refresh_instance_buf(node);
}
return 0;
} else {
dmlog_error("inode buffer not found: %s", dm_node_str(&curr_node));
return -1;
}
} else {
if (i == 0) {
if (!append) {
update_instances(entry, insts, dynamic);
} else {
// currently only append one instance.
dm_inst_array_append(entry->insts, &insts->data[0]);
if (insts->data) {
free(insts->data);
}
free(insts);
}
return 0;
}
}
inst_entry_t *inst = find_inst(entry, node->index[index_i], NULL);
if (inst == NULL) {
dmlog_error("inode_buf_add_inst inst_entry not found");
return -1;
}
index_i++;
inode = &inst->inode;
curr_node.index[curr_node.cnt] = inst->index;
curr_node.cnt++;
}
dmlog_error("failed to add instance buffer for %s", dm_node_str(node));
return -1;
}
int inode_buf_update_param_value(const dm_node_t *node, const char *value)
{
JSValue args[MAX_DM_NODE_DEPTH];
int ret = inode_buf_get_js_values(node, args);
if (ret != node->cnt) {
dmlog_error("inode_buf_update_param_value failed, node:%s, ret: %d", dm_node_str(node), ret);
return -1;
}
const struct dm_node_info *info = dm_node_get_info(node->id);
JS_SetPropertyStr(qjs_ctx(), args[ret - 1], info->name, JS_NewString(qjs_ctx(), value));
return 0;
}
void inode_buf_free_all()
{
free_inode(inode_g);
inode_g = NULL;
}
static void print_inst_array(dm_inst_array_t *arr, int ident)
{
if (arr == NULL) {
dmlog_info("no instances");
return;
}
for (int i = 0; i < arr->size; i++) {
const char *str = get_js_value_str(arr->data[i].value);
dmlog_info("idx:%d", arr->data[i].index);
dmlog_info("val: \n%s", str);
free_js_cstr(str);
}
}
static void print_inode_insts(struct inode_entry *inode, int level)
{
dmlog_info("db instances:");
print_inst_array(inode->insts, level);
dmlog_info("dynamic instances (created time:%d)", inode->dyn_time);
print_inst_array(inode->dyn_insts, level);
}
void inode_buf_dump(const dm_node_t *node)
{
dmlog_info("node buffer: %s", dm_node_str(node));
struct inode_entry *entry = inode_buf_find(node, NULL);
if (!entry) {
dmlog_info("node buffer not found: %s", dm_node_str(node));
return;
}
if (dm_node_is_index_complete(node)) {
int db;
inst_entry_t *inst = find_inst(entry, node->index[node->cnt-1], &db);
if (!inst) {
dmlog_info("node buffer (inst) not found: %s", dm_node_str(node));
return;
} else {
dmlog_info("instance buffer (db:%d):", db);
dmlog_info("index: %d", inst->index);
const char *str = get_js_value_str(inst->value);
dmlog_info("value: %s", str);
free_js_cstr(str);
}
} else {
dmlog_info("inode buffer:");
print_inode_insts(entry, 0);
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifndef I_NODE_BUF_H
#define I_NODE_BUF_H
#include <time.h>
#include <quickjs/quickjs.h>
#include "dm_node.h"
/*
Buffer for Multi-object instance.
An example of buffer is as following:
inode_entry * head -+
|
v
inode_entry [Device.IP.Interface.{i}.] -> [Device.Ethernet.Link.{i}.]
| |
v v
inst_entry [instance 1] -> [instance 2] ...
|
v
inode_entry [Device.IP.Interface.{i}.IPv4Address.{i}.] -> [Device.IP.Interface.{i}.IPv46ddress.{i}.]
|
v
inst_entry [instance 1] -> [instance 2]
*/
struct inode_entry;
typedef struct {
unsigned int index;
JSValue value; // key value for the instance
struct inode_entry *inode; // head of child inode buf (in recursive)
unsigned int value_time;
} inst_entry_t;
typedef struct {
inst_entry_t *data;
size_t size;
size_t capacity;
} dm_inst_array_t;
dm_inst_array_t* dm_inst_array_create(size_t initial_capacity);
void dm_inst_array_append(dm_inst_array_t *array, inst_entry_t *value);
struct inode_entry {
dm_node_id_t key;
dm_inst_array_t *insts;
dm_inst_array_t *dyn_insts;
struct inode_entry *next;
unsigned int dyn_time;
};
/** Buffer new db instances for the multi-instance object.
* @param[in] node node of instance
* @param[in] insts instance array
* @param[in] cnt length of instance array
* @param[in] dynamic if the instances are dynamic or in db
* @return 0 in case of success, or a nonzero value in case of error
*/
int inode_buf_add_inst(const dm_node_t *node, dm_inst_array_t *insts, int dynamic, int append);
/** Get instance values for the node
* @param[in] node node of instance
* @param[in] values values to store the result
* @return number of values found in case of success, or -1 in case of error
*/
int inode_buf_get_js_values(const dm_node_t *node, JSValue values[]);
/** find inode buffer according to node
* @param[in] node node of instance
* @param[in] retry can be retried or not
* @return pointer of inode_entry if found, otherwise NULL
*/
struct inode_entry *inode_buf_find(const dm_node_t *node, int *retry);
/** Free all the buffer
* @return none
*/
void inode_buf_free_all(void);
int inode_buf_append_db_inst(const dm_node_t *node, inst_entry_t *inst);
int inode_buf_del_db_inst(const dm_node_t *node);
int inode_buf_update_param_value(const dm_node_t *node, const char *value);
void inode_buf_dump(const dm_node_t *node);
#endif

View File

@@ -0,0 +1,20 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifndef DMLOG_H
#define DMLOG_H
void dmlog_init(const char *name, int log_level);
void dmlog_info(const char *fmt, ...);
void dmlog_warn(const char *fmt, ...);
void dmlog_error(const char *fmt, ...);
void dmlog_debug(const char *fmt, ...);
void dmlog_close();
#endif /* DMLOG_H */

View File

@@ -0,0 +1,50 @@
/*
* QuickJS UCI helper public API
*
* Provides initialisation helpers for the shared libuci context used by
* qjs_uci_api.c as well as the QuickJS registration entry point.
*/
#ifndef QJS_UCI_API_H
#define QJS_UCI_API_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Initialise the shared libuci context.
* Safe to call multiple times subsequent calls are no-ops.
* Returns 0 on success, -1 on failure.
*/
int qjs_uci_global_init(void);
/* Set the directory where libuci stores pending changes (may be NULL). */
void qjs_uci_global_set_savedir(const char *save_dir);
/* Free the shared libuci context at shutdown (optional). */
void qjs_uci_global_cleanup(void);
/* Register the _uci_call() C binding with QuickJS. */
int qjs_uci_api_init(void);
#include <json-c/json.h>
/* Simple name/value helper used by dm_uci_* helpers */
typedef struct {
const char *name;
const char *value;
} name_val_t;
int dm_uci_get(const char *uci_path, char **value);
int dm_uci_set(const char *uci_path, const char *value);
int dm_uci_add(const char *config, const char *type, const char *section_name, name_val_t *opt_values, int value_cnt);
int dm_uci_del(const char *config, const char *section);
int dm_uci_get_section_list(const char *config, const char *type, name_val_t *match, int match_cnt, struct json_object **res);
int dm_uci_commit(const char *config);
#ifdef __cplusplus
}
#endif
#endif /* QJS_UCI_API_H */

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifndef QJS_H
#define QJS_H
#include <uci.h>
#include <json-c/json.h>
#include <quickjs/quickjs.h>
#include "dm_node.h"
int qjs_init(void);
void qjs_register_c_api(const char *name, JSCFunction func, int param_len);
int qjs_has_get_handler(dm_node_id_t id);
int qjs_has_set_handler(dm_node_id_t id);
int qjs_call_set_handler(const dm_node_t *node, const char *value);
int qjs_has_import_handler(dm_node_id_t id);
int qjs_has_apply_handler(dm_node_id_t id);
int qjs_has_changed_handler(dm_node_id_t id);
int qjs_has_info_handler(dm_node_id_t id);
int qjs_has_key_handler(dm_node_id_t id);
int qjs_call_get_handler(const dm_node_t *node, char **res);
int qjs_call_apply_param_handler(const dm_node_t *node, const char *value);
int qjs_call_apply_obj_handler(const dm_node_t *node, const dm_node_t *ext_node);
JSValue qjs_call_import_handler(const dm_node_t *node, JSValue values);
int qjs_call_operate_handler(const dm_node_t *node, const char *json_input, json_object **json_output);
JSValue qjs_call_get_instance_handler(const dm_node_t *node, int start_index);
int qjs_call_changed_handler(const dm_node_t *node);
int qjs_call_info_handler(const dm_node_t *node, JSValue obj);
int qjs_call_key_handler(const dm_node_t *node, char **res);
JSContext *qjs_ctx();
JSValue qjs_global();
int qjs_array_len(JSValue arr);
const char *get_js_value_str(JSValue value);
const char *qjs_get_property_str(JSValue obj, const char *prop_name);
void free_js_cstr(const char *str);
void qjs_log_exception();
JSValue qjs_eval_buf(const void *buf, int buf_len, const char *filename, int eval_flags);
JSValue json_object_to_jsvalue(json_object *json_obj);
int qjs_uci_filter(const dm_node_t *node, json_object *obj);
int qjs_call_event_handler(dm_node_id_t node_id, const char *ubus_json_msg, struct json_object **res);
int qjs_call_uci_init_handler(const dm_node_t *node);
int qjs_call_uci_deinit_handler(const dm_node_t *node, const char *uci_section);
#endif

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifndef QJS_API_H
#define QJS_API_H
int qjs_dm_api_init(void);
int qjs_ubus_api_init(void);
int qjs_log_api_init(void);
#endif

View File

@@ -0,0 +1,580 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#include <quickjs/quickjs-libc.h>
#include <quickjs/quickjs.h>
#include <string.h>
#include "dbmgr.h"
#include "dm_api.h"
#include "dm_apply.h"
#include "dm_log.h"
#include "dm_node.h"
#include "dm_types.h"
#include "qjs.h"
#include "qjs_api.h"
#include "inode_buf.h"
#include "dm_linker.h"
JSValue get_object(const dm_node_t *node, int only_db)
{
int i;
if (dm_node_is_parameter(node->id)) {
char *value = NULL;
if (only_db) {
if (dbmgr_get(node, &value) < 0 || value == NULL) {
dmlog_error("dbmgr_get failed to get param: %s", dm_node_str(node));
return JS_UNDEFINED;
}
} else {
if (dmapi_param_get(node, &value) < 0 || value == NULL) {
dmlog_error("dmapi_param_get failed to get param: %s", dm_node_str(node));
return JS_UNDEFINED;
}
}
JSValue param;
enum DM_DATA_TYPE type = dm_node_data_type(node->id);
if (dm_node_is_param_list(node->id)) {
param = JS_NewString(qjs_ctx(), value);
} else if (type == DM_DATA_BOOLEAN) {
if (strcmp(value, "1") == 0 || strcmp(value, "true") == 0) {
param = JS_NewBool(qjs_ctx(), 1);
} else {
param = JS_NewBool(qjs_ctx(), 0);
}
} else if (type == DM_DATA_INT) {
param = JS_NewInt32(qjs_ctx(), atoi(value));
} else if (type == DM_DATA_UINT || type == DM_DATA_ULONG) {
param = JS_NewUint32(qjs_ctx(), strtoul (value, NULL, 0));
} else {
param = JS_NewString(qjs_ctx(), value);
}
free(value);
return param;
} else if (dm_node_is_object(node->id) || (dm_node_is_objectlist(node->id) && dm_node_is_index_complete(node))) {
const struct dm_object *obj = dm_node_get_object(node->id);
JSValue obj_val = JS_NewObject(qjs_ctx());
for (i = 0; i < obj->param_num; i++) {
dm_node_t param_node = *node;
param_node.id = obj->param_list[i]->node_id;
if (only_db && !dm_node_has_db(param_node.id)) {
continue;
}
JSValue param_val = get_object(&param_node, only_db);
if (JS_IsException(param_val)) {
JS_FreeValue(qjs_ctx(), obj_val);
return JS_UNDEFINED;
} else {
JS_SetPropertyStr(qjs_ctx(), obj_val, obj->param_list[i]->name, param_val);
}
}
if (dm_node_is_objectlist(node->id)) {
JS_SetPropertyStr(qjs_ctx(), obj_val, ".index", JS_NewUint32(qjs_ctx(), node->index[node->cnt - 1]));
}
for (i = 0; i < obj->object_num; i++) {
dm_node_t obj_node = *node;
obj_node.id = obj->object_list[i]->node_id;
if (dm_node_is_objectlist(obj_node.id)
&& only_db && !dm_node_has_db(obj_node.id)) {
continue;
}
JSValue child_obj = get_object(&obj_node, only_db);
if (JS_IsUndefined(child_obj)) {
JS_FreeValue(qjs_ctx(), obj_val);
return JS_UNDEFINED;
} else {
JS_SetPropertyStr(qjs_ctx(), obj_val, obj->object_list[i]->name, child_obj);
}
}
return obj_val;
} else if (dm_node_is_objectlist(node->id)) {
dm_nodelist_h list = dm_nodelist_find(node, NULL, only_db);
JSValue arr = JS_NewArray(qjs_ctx());
// JS_SetPropertyStr(qjs_ctx(), res, node->name, arr);
for (i = 0; i < dm_nodelist_cnt(list); i++) {
const dm_node_t *n = dm_nodelist_node(list, i);
JSValue ins_val = get_object(n, only_db);
if (JS_IsUndefined(ins_val)) {
JS_FreeValue(qjs_ctx(), arr);
/* free node list before returning to avoid leak */
dm_nodelist_free(list);
return JS_UNDEFINED;
} else {
// add index into the objecct
// JS_SetPropertyStr(qjs_ctx(), ins_val, "index", JS_NewInt32(qjs_ctx(), n->index[n->cnt - 1]));
JS_DefinePropertyValueUint32(qjs_ctx(), arr, i, ins_val, JS_PROP_C_W_E);
}
}
dm_nodelist_free(list);
return arr;
} else {
dmlog_error("get_object, unknown node: %s", dm_node_str(node));
return JS_UNDEFINED;
}
}
static JSValue _dm_get(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
int only_db = 1;
dm_node_t node;
if (argc < 1) {
dmlog_info("_dm_get, missing argument");
return JS_UNDEFINED;
}
if (JS_IsString(argv[0])) {
const char *path = JS_ToCString(ctx, argv[0]);
if (dm_path2node(path, &node) < 0) {
dmlog_error("_dm_get, invalid pathname: %s", path);
JS_FreeCString(ctx, path);
return JS_UNDEFINED;
}
JS_FreeCString(ctx, path);
if (argc >= 2) {
only_db = JS_ToBool(ctx, argv[1]);
}
} else if (JS_IsNumber(argv[0])) {
JS_ToUint32(ctx, &node.id, argv[0]);
if (argc >= 2) {
if (JS_IsNumber(argv[1])) {
node.cnt = 1;
JS_ToUint32(ctx, &node.index[0], argv[1]);
} else if (JS_IsArray(ctx, argv[1])) {
JSValue length = JS_GetPropertyStr(ctx, argv[1], "length");
JS_ToInt32(ctx, &node.cnt , length);
JS_FreeValue(ctx, length);
for (unsigned int i = 0; i < node.cnt; i++) {
JSValue index_val = JS_GetPropertyUint32(ctx, argv[1], i);
JS_ToUint32(ctx, &node.index[i], index_val);
JS_FreeValue(ctx, index_val);
}
} else {
dmlog_error("_dm_get, invalid index");
return JS_UNDEFINED;
}
} else {
node.cnt = 0;
}
} else {
dmlog_error("_dm_get, invalid parameter");
return JS_UNDEFINED;
}
JSValue val = get_object(&node, only_db);
if (JS_IsException(val)) {
return JS_UNDEFINED;
}
return val;
}
static JSValue _set_param_value(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv, int only_db)
{
int ret = -1;
dm_node_t node;
if (argc < 2) {
dmlog_info("_dm_set, missing argument");
return JS_NewInt32(ctx, ret);
}
const char *value = NULL;
if (JS_IsString(argv[0])) {
const char *path = JS_ToCString(ctx, argv[0]);
if (dm_path2node(path, &node) < 0) {
dmlog_error("_dm_set, invalid pathname: %s", path);
JS_FreeCString(ctx, path);
return JS_NewInt32(ctx, ret);
}
JS_FreeCString(ctx, path);
value = JS_ToCString(ctx, argv[1]);
} else if (JS_IsNumber(argv[0])) {
JS_ToUint32(ctx, &node.id, argv[0]);
if (dm_node_index_cnt(node.id) > 0) {
if (JS_IsNumber(argv[1])) {
node.cnt = 1;
JS_ToUint32(ctx, &node.index[0], argv[1]);
} else if (JS_IsArray(ctx, argv[1])) {
JSValue length = JS_GetPropertyStr(ctx, argv[1], "length");
JS_ToInt32(ctx, &node.cnt , length);
JS_FreeValue(ctx, length);
for (unsigned int i = 0; i < node.cnt; i++) {
JSValue index_val = JS_GetPropertyUint32(ctx, argv[1], i);
JS_ToUint32(ctx, &node.index[i], index_val);
JS_FreeValue(ctx, index_val);
}
} else {
dmlog_error("_dm_get, invalid index");
return JS_NewInt32(ctx, ret);
}
value = JS_ToCString(ctx, argv[2]);
} else {
node.cnt = 0;
value = JS_ToCString(ctx, argv[1]);
}
} else {
dmlog_error("_dm_get, invalid parameter");
return JS_NewInt32(ctx, ret);
}
if (value != NULL) {
if (only_db) {
// dbmgr_tranx_begin();
ret = dbmgr_set(&node, value);
if (dm_node_index_cnt(node.id) > 0) {
ret |= inode_buf_update_param_value(&node, value);
}
// dbmgr_tranx_commit();
} else {
dmapi_param_set(&node, value);
}
JS_FreeCString(ctx, value);
} else {
dmlog_error("_dm_set, missing value");
return JS_NewInt32(ctx, -1);
}
return JS_NewInt32(ctx, ret);
}
static JSValue _db_set(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
return _set_param_value(ctx, this_val, argc, argv, 1);
}
static JSValue _dm_set(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
return _set_param_value(ctx, this_val, argc, argv, 0);
}
static JSValue _dm_node_id(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
dm_node_t node;
if (argc < 1 || !JS_IsString(argv[0])) {
dmlog_info("_dm_node_id, invalid argument");
return JS_UNDEFINED;
}
const char *path = JS_ToCString(ctx, argv[0]);
if (dm_path2node(path, &node) < 0) {
dmlog_info("_dm_node_id, invalid pathname: %s", path);
return JS_NewInt32(ctx, -1);
}
JS_FreeCString(ctx, path);
return JS_NewUint32(ctx, node.id);
}
static JSValue _dm_node(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
dm_node_t node;
if (argc < 1 || !JS_IsString(argv[0])) {
dmlog_info("_dm_node, invalid argument");
return JS_UNDEFINED;
}
JSValue arr = JS_NewArray(qjs_ctx());
const char *path = JS_ToCString(ctx, argv[0]);
if (dm_path2node(path, &node) < 0) {
dmlog_info("_dm_node, invalid pathname: %s", path);
JS_DefinePropertyValueUint32(qjs_ctx(), arr, 0, JS_NewInt32(ctx, -1), JS_PROP_C_W_E);
JS_DefinePropertyValueUint32(qjs_ctx(), arr, 1, JS_NewArray(qjs_ctx()), JS_PROP_C_W_E);
} else {
JS_DefinePropertyValueUint32(qjs_ctx(), arr, 0, JS_NewUint32(ctx, node.id), JS_PROP_C_W_E);
JSValue index_arr = JS_NewArray(qjs_ctx());
for (int i = 0; i < node.cnt; i++) {
JS_DefinePropertyValueUint32(qjs_ctx(), index_arr, i, JS_NewUint32(ctx, node.index[i]), JS_PROP_C_W_E);
}
JS_DefinePropertyValueUint32(qjs_ctx(), arr, 1, index_arr, JS_PROP_C_W_E);
}
JS_FreeCString(ctx, path);
return arr;
}
static JSValue _dm_instances(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
int only_db = 1;
dm_node_t node;
const char *keys = NULL;
if (argc < 1) {
dmlog_info("_dm_node, invalid argument");
return JS_UNDEFINED;
}
JSValue arr = JS_NewArray(qjs_ctx());
const char *path = JS_ToCString(ctx, argv[0]);
if (dm_path2node(path, &node) < 0) {
dmlog_info("_dm_node, invalid pathname: %s", path);
JS_FreeCString(ctx, path);
return arr;
}
JS_FreeCString(ctx, path);
if (argc >= 2 && JS_IsString(argv[1])) {
keys = JS_ToCString(ctx, argv[1]);
}
if (argc >= 3) {
only_db = JS_ToBool(ctx, argv[2]);
}
dm_nodelist_h list = dm_nodelist_find(&node, keys, only_db);
if (keys != NULL) {
JS_FreeCString(ctx, keys);
}
const dm_node_t *pnode = NULL;
int i = 0;
nodelist_for_each_node(pnode, list)
{
dm_path_t path;
dm_node2name(pnode, path, sizeof(path));
JS_DefinePropertyValueUint32(qjs_ctx(), arr, i++, JS_NewString(ctx, path), JS_PROP_C_W_E);
}
dm_nodelist_free(list);
return arr;
}
int update_dm_value(JSContext *ctx, const char *key, JSValue value)
{
if (JS_IsString(value) || JS_IsNumber(value) || JS_IsBool(value)) {
dm_node_t node;
if (dm_path2node(key, &node) < 0) {
dmlog_error("update_dm_value, invalid pathname: %s", key);
return -1;
}
if (!dm_node_is_parameter(node.id) || !dm_node_is_index_complete(&node)) {
dmlog_error("update_dm_value, unexpected parameter: %s", key);
return -1;
}
const char *value_str = JS_ToCString(ctx, value);
if (dm_node_is_bool_type(node.id)) {
if (*value_str == '1' || !strcmp(value_str, "true")) {
dmapi_param_set(&node, "true");
} else {
dmapi_param_set(&node, "false");
}
} else {
dmapi_param_set(&node, value_str);
}
JS_FreeCString(ctx, value_str);
} else if (JS_IsArray(ctx, value)) {
dm_node_t node;
if (dm_path2node(key, &node) < 0) {
dmlog_error("update_dm_value, invalid pathname: %s", key);
return -1;
}
// multi-instance node is expected.
if (!dm_node_is_objectlist(node.id)) {
dmlog_error("update_dm_value, unexpected multi-instance object: %s", key);
return -1;
}
uint32_t len;
JSValue length = JS_GetPropertyStr(ctx, value, "length");
JS_ToUint32(ctx, &len, length);
JS_FreeValue(ctx, length);
for (unsigned int i = 0; i < len; i++) {
if (dmapi_object_add(&node) < 0) {
dmlog_error("update_dm_value, failed to add instance %s", key);
return -1;
}
dm_path_t path;
dm_node2name(&node, path, sizeof(path));
strlcat(path, ".", sizeof(path));
// new path as the new key
JSValue inst_val = JS_GetPropertyUint32(ctx, value, i);
if (update_dm_value(ctx, path, inst_val) < 0) {
dmlog_error("update_dm_value, failed to update instance %s", path);
JS_FreeValue(ctx, inst_val);
return -1;
}
JS_FreeValue(ctx, inst_val);
}
} else if (JS_IsObject(value)) {
uint32_t len, i;
JSPropertyEnum *tab;
if (JS_GetOwnPropertyNames(ctx, &tab, &len, value,
JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY) < 0) {
dmlog_error("_dm_update, JS_GetOwnPropertyNames failed");
return -1;
}
for (i = 0; i < len; i++) {
JSValue child_val = JS_GetProperty(ctx, value, tab[i].atom);
const char *child_key = JS_AtomToCString(ctx, tab[i].atom);
char *new_key = NULL;
asprintf(&new_key, "%s%s", key, child_key);
update_dm_value(ctx, new_key, child_val);
free(new_key);
/* release converted atom string */
JS_FreeCString(ctx, child_key);
JS_FreeValue(ctx, child_val);
}
js_free(ctx, tab);
} else if (JS_IsUndefined(value)) {
dmlog_debug("update_dm_value, skip update value for %s", key);
}
return 0;
}
static JSValue _dm_update(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
if (argc < 2) {
dmlog_info("_dm_update, invalid argument");
return JS_UNDEFINED;
}
const char *path = JS_ToCString(ctx, argv[0]);
int ret = update_dm_value(ctx, path, argv[1]);
/* release path string allocated by QuickJS */
JS_FreeCString(ctx, path);
return JS_NewInt32(ctx, ret);
}
static JSValue _dm_apply(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
dm_node_t node;
if (argc < 1) {
dmlog_info("_dm_apply, missing argument");
return JS_UNDEFINED;
}
if (JS_IsString(argv[0])) {
const char *path = JS_ToCString(ctx, argv[0]);
if (dm_path2node(path, &node) < 0) {
dmlog_error("_dm_apply, invalid pathname: %s", path);
JS_FreeCString(ctx, path);
return JS_UNDEFINED;
}
JS_FreeCString(ctx, path);
} else if (JS_IsNumber(argv[0])) {
JS_ToUint32(ctx, &node.id, argv[0]);
if (argc >= 2) {
if (JS_IsNumber(argv[1])) {
node.cnt = 1;
JS_ToUint32(ctx, &node.index[0], argv[1]);
} else if (JS_IsArray(ctx, argv[1])) {
JSValue length = JS_GetPropertyStr(ctx, argv[1], "length");
JS_ToInt32(ctx, &node.cnt , length);
JS_FreeValue(ctx, length);
for (unsigned int i = 0; i < node.cnt; i++) {
JSValue index_val = JS_GetPropertyUint32(ctx, argv[1], i);
JS_ToUint32(ctx, &node.index[i], index_val);
JS_FreeValue(ctx, index_val);
}
} else {
dmlog_error("_dm_apply, invalid index");
return JS_UNDEFINED;
}
} else {
node.cnt = 0;
}
} else {
dmlog_error("_dm_apply, invalid parameter");
return JS_UNDEFINED;
}
struct node_change change;
change.node = node;
change.redirected = 0;
change.action = DATA_MODEL_SET;
dm_apply_node(&change);
return JS_NewInt32(ctx, 0);
}
static JSValue _dm_resolve(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
if (argc < 1 || !JS_IsString(argv[0])) {
dmlog_info("_dm_resolve, invalid argument");
return JS_UNDEFINED;
}
const char *path = JS_ToCString(ctx, argv[0]);
char *val = NULL;
if (dm_resolve_linker(path, &val) != 0 || val == NULL) {
JS_FreeCString(ctx, path);
return JS_UNDEFINED;
}
JSValue js_val = JS_NewString(ctx, val);
free(val);
JS_FreeCString(ctx, path);
return js_val;
}
static JSValue _dm_resolve_path(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
if (argc < 3 || !JS_IsString(argv[0]) || !JS_IsString(argv[1]) || !JS_IsString(argv[2])) {
dmlog_info("_dm_resolve_path, invalid argument");
return JS_UNDEFINED;
}
const char *base_path = JS_ToCString(ctx, argv[0]);
const char *key_name = JS_ToCString(ctx, argv[1]);
const char *key_value = JS_ToCString(ctx, argv[2]);
char *obj_path = NULL;
if (dm_resolve_linker_path(base_path, key_name, key_value, &obj_path) != 0 || obj_path == NULL) {
JS_FreeCString(ctx, base_path);
JS_FreeCString(ctx, key_name);
JS_FreeCString(ctx, key_value);
return JS_UNDEFINED;
}
JSValue js_val = JS_NewString(ctx, obj_path);
free(obj_path);
JS_FreeCString(ctx, base_path);
JS_FreeCString(ctx, key_name);
JS_FreeCString(ctx, key_value);
return js_val;
}
int qjs_dm_api_init()
{
qjs_register_c_api("_dm_get", _dm_get, 1);
qjs_register_c_api("_dm_set", _dm_set, 2);
qjs_register_c_api("_db_set", _db_set, 2);
qjs_register_c_api("_dm_node_id", _dm_node_id, 1);
qjs_register_c_api("_dm_node", _dm_node, 1);
qjs_register_c_api("_dm_instances", _dm_instances, 1);
qjs_register_c_api("_dm_update", _dm_update, 1);
qjs_register_c_api("_dm_apply", _dm_apply, 1);
qjs_register_c_api("_dm_linker_value", _dm_resolve, 1);
qjs_register_c_api("_dm_linker_path", _dm_resolve_path, 3);
return 0;
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#include <quickjs/quickjs.h>
#include "dm_log.h"
#include "qjs.h"
#include "qjs_api.h"
enum LOG_TYPE {
QJS_LOG_INFO,
QJS_LOG_ERROR,
QJS_LOG_DEBUG
};
static JSValue _log(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv, enum LOG_TYPE type)
{
// keep it simple at the moment: syslog for each parameter independently.
for (int i = 0; i < argc; i++) {
JSValue json = JS_JSONStringify(ctx, argv[i], JS_UNDEFINED, JS_UNDEFINED);
const char *msg = JS_ToCString(ctx, json);
if (type == QJS_LOG_INFO) {
dmlog_info(msg);
} else if (type == QJS_LOG_ERROR) {
dmlog_error(msg);
} else {
dmlog_debug(msg);
}
JS_FreeCString(ctx, msg);
JS_FreeValue(ctx, json);
}
return JS_UNDEFINED;
}
static JSValue _log_info(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
return _log(ctx, this_val, argc, argv, QJS_LOG_INFO);
}
static JSValue _log_error(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
return _log(ctx, this_val, argc, argv, QJS_LOG_ERROR);
}
static JSValue _log_debug(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
return _log(ctx, this_val, argc, argv, QJS_LOG_DEBUG);
}
int qjs_log_api_init()
{
qjs_register_c_api("_log_info", _log_info, 1);
qjs_register_c_api("_log_error", _log_error, 1);
qjs_register_c_api("_log_debug", _log_debug, 1);
return 0;
}

View File

@@ -0,0 +1,267 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#include <json-c/json.h>
#include <quickjs/quickjs-libc.h>
#include <quickjs/quickjs.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "dm_log.h"
#include "qjs.h"
#include "qjs_api.h"
#include "ubus_client.h"
#include "dm_apply.h"
struct ubus_event_data {
struct uloop_timeout tm;
struct ubus_event_handler ev;
struct blob_attr *msg;
int res;
};
struct invoke_cb_arg {
JSContext *ctx;
JSValue res;
};
static void ubus_invoke_cb(struct ubus_request *req, int type, struct blob_attr *msg)
{
struct invoke_cb_arg *arg = (struct invoke_cb_arg *)req->priv;
if (!msg)
return;
char *json_str = blobmsg_format_json(msg, true);
if (json_str == NULL) {
dmlog_error("blobmsg_format_json failed");
return;
}
// dmlog_debug("ubus_invoke_cb: %s", json_str);
arg->res = JS_ParseJSON(arg->ctx, json_str, strlen(json_str), "ubus_invoke_cb");
if (JS_IsException(arg->res)) {
dmlog_error("JS_ParseJSON failed %s", json_str);
}
free(json_str);
}
static JSValue _ubus_call(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
int ret = -1;
const char *path = JS_ToCString(ctx, argv[0]);
const char *method = JS_ToCString(ctx, argv[1]);
struct invoke_cb_arg arg;
arg.ctx = ctx;
arg.res = JS_UNDEFINED;
// dmlog_debug("ubus %s: %s, argc: %d", path, method, argc);
if (argc > 2) {
struct blob_buf bb = {};
if (!JS_IsObject(argv[2])) {
dmlog_error("_ubus_call, object is expected as ubus arguments");
goto end;
}
JSValue json = JS_JSONStringify(ctx, argv[2], JS_UNDEFINED, JS_UNDEFINED);
if (JS_IsException(json)) {
dmlog_error("JS_ParseJSON failed");
goto end;
}
blob_buf_init(&bb, 0);
const char *str = JS_ToCString(ctx, json);
if (!blobmsg_add_json_from_string(&bb, str)) {
dmlog_error("blobmsg_add_json_from_string failed");
JS_FreeCString(ctx, str);
JS_FreeValue(ctx, json);
goto end;
}
ret = ubus_client_call(path, method, bb.head, ubus_invoke_cb, &arg);
blob_buf_free(&bb);
if (strcmp(path, "uci") == 0 &&
(strcmp(method, "set") == 0 || strcmp(method, "add") == 0 || strcmp(method, "delete") == 0)) {
dmlog_debug("ubus uci %s: args: %s", method, str);
if (ret == 0) {
JSValue val = JS_GetPropertyStr(ctx, argv[2], "config");
if (JS_IsString(val)) {
const char *config = JS_ToCString(ctx, val);
add_apply_package(strdup(config));
JS_FreeCString(ctx, config);
}
JS_FreeValue(ctx, val);
}
}
JS_FreeCString(ctx, str);
JS_FreeValue(ctx, json);
} else {
ret = ubus_client_call(path, method, NULL, ubus_invoke_cb, &arg);
}
if (ret != 0 || JS_IsException(arg.res)) {
ret = -1;
}
end:
JS_FreeCString(ctx, path);
JS_FreeCString(ctx, method);
JSValue arr = JS_NewArray(ctx);
JS_SetPropertyUint32(ctx, arr, 0, JS_NewInt32(ctx, ret));
JS_SetPropertyUint32(ctx, arr, 1, arg.res);
return arr;
}
static void ubus_listen_timeout(struct uloop_timeout *timeout)
{
uloop_end();
}
static bool compare_blob_msg(struct blob_attr *src_attr, struct blob_attr *dst_attr)
{
if (!src_attr || !dst_attr)
return false;
int src_type = blob_id(src_attr);
int dst_type = blob_id(dst_attr);
if (src_type != dst_type)
return false;
void *src_val = blobmsg_data(src_attr);
void *dst_val = blobmsg_data(dst_attr);
switch (src_type) {
case BLOBMSG_TYPE_STRING:
if (src_val == NULL && dst_val == NULL)
return true;
if (src_val && dst_val && strcmp((char *)src_val, (char*)dst_val) == 0)
return true;
break;
default:
break;
}
return false;
}
static bool validate_blob_message(struct blob_attr *src, struct blob_attr *dst)
{
if (!src || !dst)
return false;
size_t src_len = (size_t)blobmsg_data_len(src);
size_t dst_len = (size_t)blobmsg_data_len(dst);
if (dst_len < src_len)
return false;
bool res = true;
struct blob_attr *src_attr, *dst_attr;
__blob_for_each_attr(src_attr, blobmsg_data(src), src_len) {
bool matched = false;
__blob_for_each_attr(dst_attr, blobmsg_data(dst), dst_len) {
if (strcmp(blobmsg_name(src_attr), blobmsg_name(dst_attr)) != 0) {
continue;
}
matched = compare_blob_msg(src_attr, dst_attr);
break;
}
if (matched == false) {
res = false;
break;
}
}
return res;
}
static void ubus_receive_event(struct ubus_context *ctx, struct ubus_event_handler *ev,
const char *type, struct blob_attr *msg)
{
struct ubus_event_data *data;
if (!msg || !ev)
return;
data = container_of(ev, struct ubus_event_data, ev);
// skip the check if the content of event to check (data->msg) is empty.
if (data->msg == NULL || validate_blob_message(data->msg, msg) == true) {
data->res = 0;
uloop_end();
}
return;
}
static JSValue _ubus_wait_event(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
if (argc < 2) {
dmlog_info("_ubus_wait_event, missing argument");
return JS_NewInt32(ctx, -1);
}
unsigned int timeout = 100;
struct blob_attr *msg = NULL;
JS_ToUint32(ctx, &timeout, argv[1]);
struct blob_buf b;
memset(&b, 0, sizeof(b));
struct ubus_context *ubus_ctx = ubus_connect(NULL);
if (!ubus_ctx) {
return JS_NewInt32(ctx, -1);
}
const char *event = JS_ToCString(ctx, argv[0]);
blob_buf_init(&b, 0);
if (argc > 2) {
JSValue json_val = JS_JSONStringify(ctx, argv[2], JS_UNDEFINED, JS_UNDEFINED);
const char *json_str = JS_ToCString(ctx, json_val);
blobmsg_add_json_from_string(&b, json_str);
JS_FreeCString(ctx, json_str);
msg = b.head;
}
struct ubus_event_data data = {
.tm.cb = ubus_listen_timeout,
.ev.cb = ubus_receive_event,
.msg = msg,
.res = -1,
};
uloop_init();
ubus_add_uloop(ubus_ctx);
if (ubus_register_event_handler(ubus_ctx, &data.ev, event) == 0) {
uloop_timeout_set(&data.tm, timeout * 1000);
uloop_run();
uloop_done();
ubus_unregister_event_handler(ubus_ctx, &data.ev);
} else {
dmlog_error("_ubus_wait_event, failed to register event");
}
JS_FreeCString(ctx, event);
blob_buf_free(&b);
ubus_free(ubus_ctx);
return JS_NewInt32(ctx, data.res);
}
int qjs_ubus_api_init()
{
ubus_client_init();
qjs_register_c_api("_ubus_call", _ubus_call, 2);
qjs_register_c_api("_ubus_wait_event", _ubus_wait_event, 2);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,157 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#include <string.h>
#include <stdlib.h>
#include "dm_list.h"
#include "dm_log.h"
#define DEFAULT_LIST_BUF_SIZE 128
#define MAX_LIST_BUF_SIZE 1024 * 256
struct dm_list {
unsigned int cnt;
unsigned int buf_size;
void **mem_ptr;
list_item_cmp cmp;
};
// default compare for string.
static int list_str_cmp(const void *item1, const void *item2)
{
if (strcmp((const char*)item1, (const char*)item2) == 0) {
return 0;
}
return 1;
}
dm_list_h dm_list_create(list_item_cmp cmp_cb)
{
struct dm_list *list = calloc(1, sizeof(struct dm_list));
if (list == NULL)
return NULL;
if (cmp_cb == NULL) {
list->cmp = list_str_cmp;
} else {
list->cmp = cmp_cb;
}
return (dm_list_h)list;
}
int dm_list_append(dm_list_h list, void *item)
{
if (list == NULL)
return -1;
if (list->buf_size == 0) {
list->buf_size = DEFAULT_LIST_BUF_SIZE;
list->mem_ptr = (void **)calloc(DEFAULT_LIST_BUF_SIZE, sizeof(void *));
if (list->mem_ptr == NULL)
return -1;
} else if (list->buf_size <= list->cnt) {
// Check if the memory required to allocate is not out of bounds.
if (list->buf_size > MAX_LIST_BUF_SIZE / 2)
return -1;
else {
// double buffer
void *new_mem = realloc((void *)list->mem_ptr, 2 * (list->buf_size) * sizeof(void *));
if (new_mem == NULL)
return -1;
list->buf_size *= 2;
list->mem_ptr = (void **)new_mem;
}
}
list->mem_ptr[list->cnt] = item;
list->cnt++;
return 0;
}
int dm_list_cnt(dm_list_h list)
{
if (list == NULL)
return 0;
return list->cnt;
}
void *dm_list_get(dm_list_h list, int i)
{
if (list == NULL || i >= list->cnt)
return NULL;
return list->mem_ptr[i];
}
int dm_list_contains(dm_list_h list, const void *item)
{
int cnt = dm_list_cnt(list);
for (int i = 0; i < cnt; i++) {
void *val = dm_list_get(list, i);
if (val && list->cmp(val, item) == 0) {
return 1;
}
}
return 0;
}
int dm_list_remove(dm_list_h list, void *item)
{
int cnt = dm_list_cnt(list);
for (int i = 0; i < cnt; i++) {
void *val = dm_list_get(list, i);
if (val && list->cmp(val, item) == 0) {
free(val);
list->mem_ptr[i] = NULL;
return 0;
}
}
return -1;
}
void dm_list_free(dm_list_h list)
{
if (list == NULL)
return;
int i;
for (i = 0; i < list->cnt; i++)
if (list->mem_ptr[i])
free(list->mem_ptr[i]);
if (list->mem_ptr)
free(list->mem_ptr);
free(list);
}
void dm_list_dump(dm_list_h list)
{
int cnt = dm_list_cnt(list);
for (int i = 0; i < cnt; i++) {
char *val = dm_list_get(list, i);
if (val) {
dmlog_debug("dm-list val: %s", val);
}
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifndef DM_LIST_H
#define DM_LIST_H
struct dm_list;
typedef struct dm_list *dm_list_h;
// return 0 if equal, otherwise 1
typedef int (*list_item_cmp)(const void *item1, const void *item2);
/**
* Create a list
* @param cmp_cb item compare callback (optional if dm_list_contains will not be called)
* @return a valid handle if successful, otherwise return NULL
*/
dm_list_h dm_list_create(list_item_cmp cmp_cb);
/**
* Append an item to the list
* @param list handle create by dm_list_create
* @item pointer of item, the memory must be allocated by user using malloc.
* memory of item will be not free'd until dm_list_free or dm_list_del(not implemented yet) is called.
* @return 0 if successful, otherwise return -1
*/
int dm_list_append(dm_list_h list, void *item);
/**
* Get count of items in the list
* @param list handle create by dm_list_create
* @return number of items
*/
int dm_list_cnt(dm_list_h list);
/**
* Get item in the list by index
* @param list handle create by dm_list_create
* @param i, index of item to get, valid scope is [0, cnt-1]
* @return pointer of item if index is valid, otherwise return NULL
*/
void *dm_list_get(dm_list_h list, int i);
/**
* check if a item is already in the list
* @param list handle create by dm_list_create
* @param item, item to check
* @return 1 if exist, otherwise return 0
*/
int dm_list_contains(dm_list_h list, const void *item);
/**
* remove a item from the list
* @param list handle create by dm_list_create
* @param item, item to remove
* @return 0 if successful, otherwise return -1
*/
int dm_list_remove(dm_list_h list, void *item);
/**
* Free the list, including all items in the list
* @param list handle create by dm_list_create
* @return none
*/
void dm_list_free(dm_list_h list);
// only works when the value is string type
void dm_list_dump(dm_list_h list);
#endif

Some files were not shown because too many files have changed in this diff Show More