mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-24 11:05:02 +08:00
Compare commits
3950 Commits
dependency
...
dmf-dbg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4828d4c1a | ||
|
|
f480b001c7 | ||
|
|
df45b0a720 | ||
|
|
24646d3367 | ||
|
|
53e743d0b2 | ||
|
|
952bcc924a | ||
|
|
c541463faf | ||
|
|
506da7e733 | ||
|
|
6662cee5c9 | ||
|
|
5f8c187880 | ||
|
|
b8f99bbe64 | ||
|
|
42df10c708 | ||
|
|
7369ee4c20 | ||
|
|
dc3aa2ec9d | ||
|
|
312d28bec4 | ||
|
|
45a754f567 | ||
|
|
491f2ca07d | ||
|
|
2d5f9229f2 | ||
|
|
16536b9bc3 | ||
|
|
f552b68f10 | ||
|
|
7c444911f7 | ||
|
|
7a12fb28b1 | ||
|
|
a430d76517 | ||
|
|
b48c7e14dc | ||
|
|
269d72c30a | ||
|
|
f19082aa1e | ||
|
|
43f0296ea2 | ||
|
|
6418f9fa8f | ||
|
|
58ecaf9c15 | ||
|
|
0f8887f676 | ||
|
|
a1193cc6b8 | ||
|
|
392a41b38a | ||
|
|
c3128d3a14 | ||
|
|
4d88e123a9 | ||
|
|
fb050cae2e | ||
|
|
90af4f350b | ||
|
|
605f0faacc | ||
|
|
065772401b | ||
|
|
886000a830 | ||
|
|
0b5a84e33a | ||
|
|
a2763cd075 | ||
|
|
4a8b27ed95 | ||
|
|
6eef7e4b21 | ||
|
|
a0bde81de4 | ||
|
|
5e04f9312b | ||
|
|
a1e7f80ae0 | ||
|
|
ed5169b94c | ||
|
|
c64701e6b2 | ||
|
|
db6672c9ee | ||
|
|
05c4d0d3d1 | ||
|
|
6535fe465c | ||
|
|
2703db3f2e | ||
|
|
bb603cb492 | ||
|
|
f8d7788d6f | ||
|
|
97df4367eb | ||
|
|
21fbf0253c | ||
|
|
ced2b4187f | ||
|
|
bfdd27f72a | ||
|
|
6f1953e4a4 | ||
|
|
fd816f8ee1 | ||
|
|
cbdc083db5 | ||
|
|
eb1897a730 | ||
|
|
546450566e | ||
|
|
5fb51c6fd9 | ||
|
|
5d84d0ae29 | ||
|
|
340709b527 | ||
|
|
38bef28d00 | ||
|
|
ba53aeda7d | ||
|
|
bd63c5a090 | ||
|
|
89c1fbb38a | ||
|
|
d6ff1d851b | ||
|
|
107b1576e8 | ||
|
|
47694dc23e | ||
|
|
002836769c | ||
|
|
cafb9f09ba | ||
|
|
a440adbef9 | ||
|
|
2ba04321b3 | ||
|
|
9126f2ef7d | ||
|
|
ed01ddf670 | ||
|
|
7e360f7b30 | ||
|
|
e15dcd3b25 | ||
|
|
9ee00a3c82 | ||
|
|
ba94d88f0d | ||
|
|
041e51edf3 | ||
|
|
6ca5af0790 | ||
|
|
6d32d6e8b3 | ||
|
|
2b4f9029f8 | ||
|
|
8c3bf8763e | ||
|
|
1c6243113c | ||
|
|
eedf8d2761 | ||
|
|
bf8b4de5da | ||
|
|
fd208e0e5f | ||
|
|
5b090176a1 | ||
|
|
93b1952f50 | ||
|
|
ddcfeeb339 | ||
|
|
8cea3573f7 | ||
|
|
8ac0f69992 | ||
|
|
65dea29e5f | ||
|
|
2cecb4f75a | ||
|
|
a47d302ec7 | ||
|
|
a9b3a392dd | ||
|
|
397611aff5 | ||
|
|
21c9fafc4d | ||
|
|
41efd7d712 | ||
|
|
f1e37ac0d8 | ||
|
|
ab6d3935d1 | ||
|
|
db529f651e | ||
|
|
975bf57de0 | ||
|
|
6fb3a1b91d | ||
|
|
57ae4eb344 | ||
|
|
dc79aa56f9 | ||
|
|
8334b65ad4 | ||
|
|
e9caa2e7cd | ||
|
|
49a31dbd49 | ||
|
|
31f223f7a0 | ||
|
|
8e33d24256 | ||
|
|
e6df8f9ad0 | ||
|
|
2c3e9ce606 | ||
|
|
616e15b9c4 | ||
|
|
93d2d09dcc | ||
|
|
ece7e8f22c | ||
|
|
879b473d20 | ||
|
|
ac9da0ec6f | ||
|
|
7c5046d9d8 | ||
|
|
69ccc34b2c | ||
|
|
87a6852c1a | ||
|
|
b0d1ada967 | ||
|
|
09cccc39cc | ||
|
|
7227cbd8da | ||
|
|
c57b0322b0 | ||
|
|
db626422dc | ||
|
|
26ffa55453 | ||
|
|
adc2b26a78 | ||
|
|
51e3ad0404 | ||
|
|
d9448a0de4 | ||
|
|
84eff7c8e0 | ||
|
|
53d940586e | ||
|
|
712435786a | ||
|
|
e57bbc0306 | ||
|
|
cc4aa5a415 | ||
|
|
7e502d79c8 | ||
|
|
cbbc3b3725 | ||
|
|
dcfe80ad8e | ||
|
|
c8bbe8725a | ||
|
|
71828eb20b | ||
|
|
90fd7f326d | ||
|
|
1263451924 | ||
|
|
c74662e1dd | ||
|
|
34482e3c86 | ||
|
|
96be0f9fab | ||
|
|
971d1ca37e | ||
|
|
99821b5010 | ||
|
|
c68b1c01eb | ||
|
|
a053e7752f | ||
|
|
558bd40b9f | ||
|
|
432969f0bf | ||
|
|
a7dfecba54 | ||
|
|
0ba1417643 | ||
|
|
29d6ad2fbd | ||
|
|
f7ef772ebf | ||
|
|
d0c9d595c8 | ||
|
|
912d98f496 | ||
|
|
8fb1b55e57 | ||
|
|
c5e79244c7 | ||
|
|
499f77d498 | ||
|
|
480c954677 | ||
|
|
9a5564bca4 | ||
|
|
67ee062946 | ||
|
|
7ecdc3ccb4 | ||
|
|
36490a7cda | ||
|
|
1d31c5f795 | ||
|
|
9a934269ae | ||
|
|
82e8c63c88 | ||
|
|
4fe71d66d3 | ||
|
|
74eac091ff | ||
|
|
94cf651a6c | ||
|
|
08f909388c | ||
|
|
148d25caf0 | ||
|
|
8d8cc94cdf | ||
|
|
0d6c7b2f70 | ||
|
|
0623e7017f | ||
|
|
013f820b12 | ||
|
|
9fd4584cdb | ||
|
|
3b3035441e | ||
|
|
38f36f3bdf | ||
|
|
b27646211b | ||
|
|
70b5c78d22 | ||
|
|
2356ed6075 | ||
|
|
39d484817e | ||
|
|
a73c089c2a | ||
|
|
22d9f90528 | ||
|
|
ac93499202 | ||
|
|
4dfc3455fb | ||
|
|
5bc00d53fd | ||
|
|
6ec25f158c | ||
|
|
9817ca11b5 | ||
|
|
ca49dfac97 | ||
|
|
44238e2033 | ||
|
|
e1d4bddbcf | ||
|
|
c6a739ddc0 | ||
|
|
38f657fa84 | ||
|
|
f5488143cd | ||
|
|
cebbf0f860 | ||
|
|
dcac2bd261 | ||
|
|
82c6cca440 | ||
|
|
2a952644c5 | ||
|
|
fac25dc016 | ||
|
|
623e1dc34e | ||
|
|
ed30787ca4 | ||
|
|
d68e0847c4 | ||
|
|
08cb598de4 | ||
|
|
2763ba7656 | ||
|
|
2591116be3 | ||
|
|
06876807c1 | ||
|
|
65344ebdc5 | ||
|
|
7dc743630c | ||
|
|
a8d7adbd1f | ||
|
|
ba215d1d6f | ||
|
|
fdfa1526b8 | ||
|
|
a93bde6fb5 | ||
|
|
4135fbe369 | ||
|
|
e4e63ba991 | ||
|
|
832947703c | ||
|
|
14e5601aed | ||
|
|
d3b2d4d9bf | ||
|
|
8741d7d82e | ||
|
|
910538aad7 | ||
|
|
5f36441b11 | ||
|
|
075728ce3e | ||
|
|
21687b6dc9 | ||
|
|
b5c2667d68 | ||
|
|
589c856cb7 | ||
|
|
e819a32cd7 | ||
|
|
bc8c70f7d0 | ||
|
|
fb17c3f51b | ||
|
|
0dfd361033 | ||
|
|
6d31feaa00 | ||
|
|
9df2d4b15e | ||
|
|
b91ae7f7f0 | ||
|
|
6df1768244 | ||
|
|
0a7245d2f9 | ||
|
|
6166ba0041 | ||
|
|
02577401c7 | ||
|
|
eccfd8970a | ||
|
|
7097827eb8 | ||
|
|
29e9ba389a | ||
|
|
4c6f70342a | ||
|
|
4708da4734 | ||
|
|
55aba515ff | ||
|
|
b1c9ce0d25 | ||
|
|
d3ae8b5020 | ||
|
|
ca962744b8 | ||
|
|
31c7500042 | ||
|
|
e71ee20840 | ||
|
|
38763bfc0d | ||
|
|
a43e3530c9 | ||
|
|
86ede4ab6b | ||
|
|
d234e7adcc | ||
|
|
e7e5ede6b9 | ||
|
|
476aee97a6 | ||
|
|
784c6553d8 | ||
|
|
e2883f0f45 | ||
|
|
30d01926a8 | ||
|
|
f6510849d6 | ||
|
|
d49e72be07 | ||
|
|
35e9ed9b1b | ||
|
|
e66516242a | ||
|
|
4affd50d2c | ||
|
|
06dec89452 | ||
|
|
130dbeacd5 | ||
|
|
d576d81b1f | ||
|
|
ee6edfa5a9 | ||
|
|
2f8c5e3f53 | ||
|
|
5c0010edf8 | ||
|
|
001eb7e0a3 | ||
|
|
a2209f555b | ||
|
|
8c09e8658e | ||
|
|
1d85f324a4 | ||
|
|
65926415ad | ||
|
|
50e865df53 | ||
|
|
cf352e9990 | ||
|
|
ecec95ca57 | ||
|
|
9a051abbf1 | ||
|
|
d3b5d8d598 | ||
|
|
3c4bbfb6d6 | ||
|
|
0122493c01 | ||
|
|
6098c3ab56 | ||
|
|
252c98c4ef | ||
|
|
5ea17980c8 | ||
|
|
3ba06fa10f | ||
|
|
013086f558 | ||
|
|
3a8f8d604f | ||
|
|
8612f5d4f6 | ||
|
|
6aef37d406 | ||
|
|
753dc05320 | ||
|
|
74878254b7 | ||
|
|
4f2697217a | ||
|
|
e36a9bc381 | ||
|
|
a52d654c4f | ||
|
|
6cf5641ea7 | ||
|
|
bce378a665 | ||
|
|
9952f6e580 | ||
|
|
7d0b38b9a7 | ||
|
|
3a503ea955 | ||
|
|
13cac21c60 | ||
|
|
f251701534 | ||
|
|
5b882870c9 | ||
|
|
25f3acf2fd | ||
|
|
c1fe6b05a6 | ||
|
|
4ee9169771 | ||
|
|
7172201515 | ||
|
|
c366451def | ||
|
|
5874a005c6 | ||
|
|
ffab63b86f | ||
|
|
929dd55d21 | ||
|
|
3636e217a6 | ||
|
|
b99d4413dc | ||
|
|
f2f6f6b787 | ||
|
|
f2ea1049e0 | ||
|
|
ba837ff98a | ||
|
|
324244d26b | ||
|
|
0cded2b974 | ||
|
|
27f0f7454f | ||
|
|
3ff559907b | ||
|
|
d73f8975cf | ||
|
|
3ddf258a74 | ||
|
|
cd2c817223 | ||
|
|
370c5938aa | ||
|
|
ddd88a894c | ||
|
|
459f2571ec | ||
|
|
c555b48d16 | ||
|
|
6a0f353c93 | ||
|
|
21e742d9f7 | ||
|
|
f4654e78c5 | ||
|
|
72c3e3c8ce | ||
|
|
1adf7b669f | ||
|
|
39ec8635c3 | ||
|
|
5a3fbb7902 | ||
|
|
5ecc3945f9 | ||
|
|
8a52715ad1 | ||
|
|
8333a499d0 | ||
|
|
941a46dae6 | ||
|
|
86d7bf8c67 | ||
|
|
4ef5d86feb | ||
|
|
c97637fd5f | ||
|
|
033613f999 | ||
|
|
b18f6dc39c | ||
|
|
5f5b171d5a | ||
|
|
469e9d1196 | ||
|
|
53b824d2e0 | ||
|
|
4df9b5ab94 | ||
|
|
130cf8fd53 | ||
|
|
bfd327ca02 | ||
|
|
bcea816742 | ||
|
|
ee6a27dc76 | ||
|
|
78eb76e913 | ||
|
|
21c3354b31 | ||
|
|
dcfa48d1f7 | ||
|
|
56d352fc83 | ||
|
|
56093ef532 | ||
|
|
60f1d0edbf | ||
|
|
c2021e765a | ||
|
|
83c31acbc7 | ||
|
|
9380411fa6 | ||
|
|
2a47619b32 | ||
|
|
f2c665a0cf | ||
|
|
1dca89c130 | ||
|
|
63d3ca365b | ||
|
|
fa4f08aa29 | ||
|
|
858dd78ff7 | ||
|
|
eb0e19355d | ||
|
|
4015982a87 | ||
|
|
0b6e35e36b | ||
|
|
cca03dc995 | ||
|
|
3d69811bf4 | ||
|
|
5a7e44cd04 | ||
|
|
b883f2b310 | ||
|
|
97a845fda2 | ||
|
|
21cdf07e54 | ||
|
|
13094c3a1b | ||
|
|
d3cb6a70da | ||
|
|
19570e553d | ||
|
|
50e2add3ab | ||
|
|
e33340ea8d | ||
|
|
6b882610c2 | ||
|
|
383dedb443 | ||
|
|
a8a2066675 | ||
|
|
73dfc49647 | ||
|
|
083cbd7b56 | ||
|
|
e87bcbb819 | ||
|
|
f8561996ab | ||
|
|
01d320300e | ||
|
|
3faecd3979 | ||
|
|
984962e34e | ||
|
|
6140bfa09c | ||
|
|
2cbb433cbd | ||
|
|
c676cde1fb | ||
|
|
363c2ff155 | ||
|
|
2a2650b43e | ||
|
|
a5c13c4ae7 | ||
|
|
bf40d37745 | ||
|
|
8889d06568 | ||
|
|
e7d2f54bda | ||
|
|
1e31d2accd | ||
|
|
1e08854dce | ||
|
|
cb27d96fe6 | ||
|
|
943667adc6 | ||
|
|
89b2c6ab19 | ||
|
|
760cd38113 | ||
|
|
1abc312d2c | ||
|
|
09abf6d6b1 | ||
|
|
fa203d73e0 | ||
|
|
880741d8c3 | ||
|
|
42bd6390b5 | ||
|
|
c9856f2a5b | ||
|
|
c086f72400 | ||
|
|
a50c380722 | ||
|
|
2755d6be1c | ||
|
|
359db9ddc3 | ||
|
|
e4f3daf1ed | ||
|
|
557ea195ba | ||
|
|
1c14d9f652 | ||
|
|
b8ebda638c | ||
|
|
db089a3920 | ||
|
|
4110c22f64 | ||
|
|
5b07fcce33 | ||
|
|
2219f2efba | ||
|
|
ba3b00c784 | ||
|
|
9598258993 | ||
|
|
32ab2eb2cc | ||
|
|
63c27601e5 | ||
|
|
f2d4b6ff7d | ||
|
|
e945226956 | ||
|
|
9a7ff0bbf2 | ||
|
|
97830621a6 | ||
|
|
1c77fb2e76 | ||
|
|
67c4a3c317 | ||
|
|
7f17359913 | ||
|
|
b6212b90d8 | ||
|
|
74cbe1062a | ||
|
|
2be4eeebb7 | ||
|
|
a49407ad79 | ||
|
|
24737321b0 | ||
|
|
3a72a7ee61 | ||
|
|
d9b6136916 | ||
|
|
537e1758c3 | ||
|
|
c6bbe14c6f | ||
|
|
8af265a689 | ||
|
|
193a6cf502 | ||
|
|
d6c148f7e3 | ||
|
|
afdc0006b5 | ||
|
|
2cb0f6e159 | ||
|
|
db72ee376e | ||
|
|
2bbeb83eb2 | ||
|
|
f718adf692 | ||
|
|
2aaf56ac6d | ||
|
|
426cc077e0 | ||
|
|
879e549581 | ||
|
|
78f6198d0a | ||
|
|
6ddaa150b4 | ||
|
|
9188a99c99 | ||
|
|
352a56448e | ||
|
|
5c7fea694f | ||
|
|
5474007dcf | ||
|
|
320d155a96 | ||
|
|
73f91e09db | ||
|
|
36d2b24bae | ||
|
|
f9010d9ef1 | ||
|
|
aeda3280b3 | ||
|
|
5e3b30daa8 | ||
|
|
ee2165b184 | ||
|
|
1b7fa8ba15 | ||
|
|
052dc52801 | ||
|
|
4373ec21aa | ||
|
|
892e0f3599 | ||
|
|
d9a742b734 | ||
|
|
9e1a8de1bd | ||
|
|
73c8e7eb75 | ||
|
|
41ba4fcedc | ||
|
|
b673daf265 | ||
|
|
06b9f7eb00 | ||
|
|
092026794e | ||
|
|
0bc9dd365f | ||
|
|
f4eb3ec090 | ||
|
|
7596b3b4f4 | ||
|
|
d546e1699f | ||
|
|
fe4a859af6 | ||
|
|
7ecce240d0 | ||
|
|
a8dd08cf33 | ||
|
|
9a38439d11 | ||
|
|
06c977c39d | ||
|
|
1e352925ef | ||
|
|
9b6a9158af | ||
|
|
fd49d9a203 | ||
|
|
093d1b95da | ||
|
|
52ef85a910 | ||
|
|
ca8f2f91ab | ||
|
|
3553cca81c | ||
|
|
bdeea206e3 | ||
|
|
34cb916d59 | ||
|
|
5f253a5d5c | ||
|
|
948f727a0b | ||
|
|
7b4be698fc | ||
|
|
3f079d7543 | ||
|
|
52d5bf6db6 | ||
|
|
d80d41a6f6 | ||
|
|
4b8d721af8 | ||
|
|
a2b051c773 | ||
|
|
2aa49112f3 | ||
|
|
60b21cb3ce | ||
|
|
55e9299da5 | ||
|
|
6df78961ab | ||
|
|
6a65a15b0d | ||
|
|
2a1f9a00d4 | ||
|
|
211de47076 | ||
|
|
af3cf465bc | ||
|
|
c1a8c1aa86 | ||
|
|
08fb82fae4 | ||
|
|
0c4485ea15 | ||
|
|
064b655fa9 | ||
|
|
d71d4914d5 | ||
|
|
2a7f21a8f8 | ||
|
|
d720da1852 | ||
|
|
e9f40eba08 | ||
|
|
3d68c3b9f7 | ||
|
|
f5ad0195bc | ||
|
|
85818a7778 | ||
|
|
b6e5749b7f | ||
|
|
2a1323bfd0 | ||
|
|
0c56d3ab39 | ||
|
|
c59c53aa47 | ||
|
|
90c3949696 | ||
|
|
14ca35a64b | ||
|
|
cf148f6c06 | ||
|
|
c3e0426c36 | ||
|
|
c7f3e52f92 | ||
|
|
1605577538 | ||
|
|
69ba712cb3 | ||
|
|
634d40fa01 | ||
|
|
088ed56c50 | ||
|
|
d49c758d04 | ||
|
|
187492a827 | ||
|
|
0a375e6ac4 | ||
|
|
226c5b4685 | ||
|
|
e72352d7e1 | ||
|
|
322d80f151 | ||
|
|
8e4d3920d9 | ||
|
|
241afdc4fd | ||
|
|
4ee68f7a84 | ||
|
|
11b13af489 | ||
|
|
5abf23d711 | ||
|
|
38c7075422 | ||
|
|
dead11036c | ||
|
|
e708d6caec | ||
|
|
3a7c4119ff | ||
|
|
b1fc7a09be | ||
|
|
7c0a37c8a8 | ||
|
|
bfdd241330 | ||
|
|
cdc8972031 | ||
|
|
f668c5cc33 | ||
|
|
ed0373f188 | ||
|
|
74f37ee761 | ||
|
|
3970668d0e | ||
|
|
fe833164de | ||
|
|
eca57960a0 | ||
|
|
41c8325aae | ||
|
|
c118da628d | ||
|
|
0714c79917 | ||
|
|
d01f484999 | ||
|
|
d161ccf816 | ||
|
|
e18da4e996 | ||
|
|
4aca931a23 | ||
|
|
81b0f6e7fe | ||
|
|
93873874bb | ||
|
|
88ca4b3011 | ||
|
|
a3bd6392a1 | ||
|
|
ed01591374 | ||
|
|
c48d4923d6 | ||
|
|
3dbc47b54f | ||
|
|
d6ef40fd0f | ||
|
|
b94dbcdbdf | ||
|
|
d0be4f8056 | ||
|
|
5e392d0832 | ||
|
|
acc92dfb1f | ||
|
|
5e13161b70 | ||
|
|
20034609e0 | ||
|
|
58ddcd7499 | ||
|
|
81755b83ad | ||
|
|
b96e7077fc | ||
|
|
1b0a792b56 | ||
|
|
4e093e59f3 | ||
|
|
9400526e47 | ||
|
|
a2733b66b7 | ||
|
|
40251b2371 | ||
|
|
980779a583 | ||
|
|
ad31d21380 | ||
|
|
525b56ebc5 | ||
|
|
abc15029e6 | ||
|
|
d992340d98 | ||
|
|
e5fa525364 | ||
|
|
39622c277c | ||
|
|
98a6c9bd62 | ||
|
|
409cecd943 | ||
|
|
54c92d5b42 | ||
|
|
2ef97edd43 | ||
|
|
e19c743888 | ||
|
|
81b5ade110 | ||
|
|
c0cfca286e | ||
|
|
584b0b9721 | ||
|
|
d5634eb756 | ||
|
|
38304c4d90 | ||
|
|
b92064f72b | ||
|
|
38814a8f89 | ||
|
|
9d5ff37aca | ||
|
|
68dec1aa1b | ||
|
|
f3bbafc15c | ||
|
|
1789bd5afd | ||
|
|
8e5bbbd37f | ||
|
|
95bd27f079 | ||
|
|
7a9cd965a0 | ||
|
|
67673fa604 | ||
|
|
9f54857be0 | ||
|
|
a733e610b4 | ||
|
|
f48ada800e | ||
|
|
868785688e | ||
|
|
e9ccbaa772 | ||
|
|
0b6b0e6ca2 | ||
|
|
47e0ecff71 | ||
|
|
3123202381 | ||
|
|
9a1861aeb2 | ||
|
|
bba41922cc | ||
|
|
373611b687 | ||
|
|
9576104e83 | ||
|
|
57f14e5e58 | ||
|
|
d51a6fe3c6 | ||
|
|
05b0f91ae0 | ||
|
|
aea7fe15e6 | ||
|
|
c6c5e53dc8 | ||
|
|
03d6f8ab44 | ||
|
|
06ad490dd8 | ||
|
|
439e1ac346 | ||
|
|
d62639e761 | ||
|
|
a1569f010d | ||
|
|
a513907df7 | ||
|
|
2e9942589a | ||
|
|
6d6962e02e | ||
|
|
4ded4e8708 | ||
|
|
d48a389d86 | ||
|
|
adcd7faafc | ||
|
|
2acea2c6dd | ||
|
|
b8fc40e336 | ||
|
|
86d9d8721b | ||
|
|
f031977f41 | ||
|
|
87a782f70e | ||
|
|
f293c57de0 | ||
|
|
9f354e1294 | ||
|
|
44527f36a8 | ||
|
|
0d3f63ccda | ||
|
|
8839edb8f3 | ||
|
|
f8a3b236aa | ||
|
|
c55ab35b14 | ||
|
|
b5397361d0 | ||
|
|
15f4bc772c | ||
|
|
b97c158e53 | ||
|
|
b727004b4a | ||
|
|
a81e572f00 | ||
|
|
e1c819724f | ||
|
|
e75042bfe5 | ||
|
|
da50843b37 | ||
|
|
ad43f26119 | ||
|
|
b1110c426b | ||
|
|
27e2c1ef7e | ||
|
|
e7a8dd7683 | ||
|
|
932b345e2b | ||
|
|
1567b1facb | ||
|
|
0dfbdd2d02 | ||
|
|
8ba85e2e40 | ||
|
|
4e976e89b7 | ||
|
|
4203eefe9f | ||
|
|
3940dbbd43 | ||
|
|
f84c374a16 | ||
|
|
a116104811 | ||
|
|
8454c2a092 | ||
|
|
e7e6a40d26 | ||
|
|
34e6281473 | ||
|
|
e3c9182bbc | ||
|
|
5cac9516c0 | ||
|
|
d67a40b6a0 | ||
|
|
4c0582b1a0 | ||
|
|
9e7ef97e14 | ||
|
|
114cbf2cf4 | ||
|
|
c38e706e01 | ||
|
|
ef3ef93a5c | ||
|
|
1bb792a893 | ||
|
|
8c1e4ef6aa | ||
|
|
5cf3c68b96 | ||
|
|
75a5058d15 | ||
|
|
930565f528 | ||
|
|
3d3397703f | ||
|
|
fc2b5a2380 | ||
|
|
0aa0cb6424 | ||
|
|
61b74b5bd3 | ||
|
|
1d8add390d | ||
|
|
797e8cae82 | ||
|
|
083960ee2e | ||
|
|
3f59dd1c89 | ||
|
|
823b5936f8 | ||
|
|
368fe2aafa | ||
|
|
8f1b18e4d4 | ||
|
|
f3b6dbfceb | ||
|
|
b5ac400fd6 | ||
|
|
ae1189c0d2 | ||
|
|
4e57074351 | ||
|
|
bbd0f972c6 | ||
|
|
50ceda4cd4 | ||
|
|
0f5f018e99 | ||
|
|
eff826ac39 | ||
|
|
62aed7d759 | ||
|
|
4d72fddff8 | ||
|
|
eb18ec1e2b | ||
|
|
82a5082538 | ||
|
|
4ec80e072d | ||
|
|
c4f4edd39d | ||
|
|
b02342e752 | ||
|
|
562733b291 | ||
|
|
9f6d7d44ed | ||
|
|
84faa7f55b | ||
|
|
b939c6988e | ||
|
|
9a28469028 | ||
|
|
64123c0f62 | ||
|
|
923a3e2f08 | ||
|
|
c92e073ec5 | ||
|
|
6cdabddc23 | ||
|
|
a0eab2f7b9 | ||
|
|
cb4b5c0c7c | ||
|
|
bc4bb6b9ea | ||
|
|
c41ed55d5f | ||
|
|
4860a1a5a8 | ||
|
|
973a0c689a | ||
|
|
89d03dc3b9 | ||
|
|
510dedb352 | ||
|
|
caf9074ab8 | ||
|
|
0676d5b990 | ||
|
|
fb0413467b | ||
|
|
148aa95651 | ||
|
|
daf54622d8 | ||
|
|
22aa3ff065 | ||
|
|
eb06147743 | ||
|
|
aaa8171f06 | ||
|
|
8037020206 | ||
|
|
3ab1e18f7d | ||
|
|
d28738ecbf | ||
|
|
247eea7a77 | ||
|
|
404bb37ced | ||
|
|
722ddf9f88 | ||
|
|
c0b146a3fe | ||
|
|
7acc13dd85 | ||
|
|
14449614a2 | ||
|
|
1e218554de | ||
|
|
05017194b5 | ||
|
|
6f709c0623 | ||
|
|
dd4907e86d | ||
|
|
b1eb97b7d7 | ||
|
|
d9b86df719 | ||
|
|
e656deb8f5 | ||
|
|
e8f1b2167a | ||
|
|
cfceae73ff | ||
|
|
6c7aa21626 | ||
|
|
52f554b84d | ||
|
|
70c823e303 | ||
|
|
1f94ad341b | ||
|
|
e02ad277f7 | ||
|
|
a8a5f99769 | ||
|
|
d161ef2238 | ||
|
|
64d1873eba | ||
|
|
29a123446a | ||
|
|
e7374d6bce | ||
|
|
7dd517dba7 | ||
|
|
c7a6bdb4a0 | ||
|
|
5e009f97e9 | ||
|
|
d2a43566bc | ||
|
|
ab2b11e343 | ||
|
|
67db9fcc48 | ||
|
|
db855e4c38 | ||
|
|
b3b7d666b1 | ||
|
|
dda4099874 | ||
|
|
6c4f2842b8 | ||
|
|
fcad858660 | ||
|
|
8bd1e237ef | ||
|
|
1e4af81108 | ||
|
|
6dbd4fbade | ||
|
|
cd6a127fb9 | ||
|
|
cb3653ebe9 | ||
|
|
765201ded3 | ||
|
|
54f75846ca | ||
|
|
090795699d | ||
|
|
551033461a | ||
|
|
2c3a493457 | ||
|
|
e0bf63926a | ||
|
|
c6e8454989 | ||
|
|
16f1276346 | ||
|
|
5d223f5909 | ||
|
|
83541d7e03 | ||
|
|
76042997ca | ||
|
|
e47abdff8f | ||
|
|
3eaa20c12e | ||
|
|
7ffb8b398f | ||
|
|
5b449b886c | ||
|
|
13b00ca74d | ||
|
|
8b9e1a0f94 | ||
|
|
9e3ee55e12 | ||
|
|
6a9eee1af5 | ||
|
|
d9d2fc882f | ||
|
|
7df39bd465 | ||
|
|
317c1bdff0 | ||
|
|
ac5602443f | ||
|
|
9816a42f00 | ||
|
|
12f70a7d91 | ||
|
|
f3959d1ffd | ||
|
|
b8c4404ba6 | ||
|
|
b699f89d41 | ||
|
|
6b26936300 | ||
|
|
386412064c | ||
|
|
84ac60736f | ||
|
|
2d037f5e73 | ||
|
|
3cebe495c5 | ||
|
|
1e2dd935f5 | ||
|
|
425bf39763 | ||
|
|
367a9b7ef3 | ||
|
|
125b7d6f57 | ||
|
|
7d08926622 | ||
|
|
396e0c6ca8 | ||
|
|
ab794f7469 | ||
|
|
e0cda7f5d0 | ||
|
|
ce6a87ffe7 | ||
|
|
9a83b05eac | ||
|
|
bfb9c65610 | ||
|
|
acea025b63 | ||
|
|
01b5c29100 | ||
|
|
8c6c12fe53 | ||
|
|
f9b36e5b0b | ||
|
|
a95afbb928 | ||
|
|
f4cf83b813 | ||
|
|
94f7110729 | ||
|
|
72de1d65c0 | ||
|
|
6a45c379c2 | ||
|
|
a2522dfff0 | ||
|
|
4312fa6a16 | ||
|
|
62dd45321e | ||
|
|
258744a16e | ||
|
|
b574d39642 | ||
|
|
deaa91514b | ||
|
|
801dee5cfa | ||
|
|
bf26939fb4 | ||
|
|
1c7945e834 | ||
|
|
d52f95fc35 | ||
|
|
9325f1a724 | ||
|
|
dfcc8ff111 | ||
|
|
8366ad85e7 | ||
|
|
c56cb30b3b | ||
|
|
c088fd5959 | ||
|
|
40bd23290f | ||
|
|
8c7f2bc2bd | ||
|
|
94181840b0 | ||
|
|
803afb7753 | ||
|
|
6f253a35de | ||
|
|
c56853b477 | ||
|
|
6640412546 | ||
|
|
8b58c13823 | ||
|
|
c36493a852 | ||
|
|
f2cd1c5573 | ||
|
|
d4a631f0cb | ||
|
|
c0208dab2e | ||
|
|
8dca6b8e44 | ||
|
|
4b1a7859aa | ||
|
|
6f28d90916 | ||
|
|
285e24455d | ||
|
|
d0c26b4bb7 | ||
|
|
a71d90d2c7 | ||
|
|
78e1468f51 | ||
|
|
9a1e1dbd1a | ||
|
|
3ef21188b1 | ||
|
|
65daa6c56a | ||
|
|
eb63f5d74f | ||
|
|
7da09349ec | ||
|
|
b2a28a12f6 | ||
|
|
0fe5d2a232 | ||
|
|
b50f9946bb | ||
|
|
bf28778432 | ||
|
|
d6dad64328 | ||
|
|
46003fddd5 | ||
|
|
2e7fc5fa14 | ||
|
|
7fb9b397ef | ||
|
|
cbe66d6c96 | ||
|
|
57d477c1da | ||
|
|
8e774faa3e | ||
|
|
6129323ca3 | ||
|
|
6d6ecdfe92 | ||
|
|
b66ae8d605 | ||
|
|
ed97af82b5 | ||
|
|
464f037768 | ||
|
|
024442da10 | ||
|
|
b0049df366 | ||
|
|
7115c1734e | ||
|
|
9b93ffef76 | ||
|
|
225b89ab4f | ||
|
|
d4464bf430 | ||
|
|
50731e00ef | ||
|
|
f9d3d22c14 | ||
|
|
607f3c5334 | ||
|
|
925c58aeaa | ||
|
|
447acf3b27 | ||
|
|
5bff6c3854 | ||
|
|
70f4086ecc | ||
|
|
b3bafdbba9 | ||
|
|
5788d7d284 | ||
|
|
a0c226d6ea | ||
|
|
921657f464 | ||
|
|
217ee3fa77 | ||
|
|
0aef613006 | ||
|
|
63e2bb8f6d | ||
|
|
ea0059a932 | ||
|
|
a95a6d804a | ||
|
|
3fbdd08037 | ||
|
|
e04040c4ea | ||
|
|
20a85cce5f | ||
|
|
2be7a59ff0 | ||
|
|
3102c0f981 | ||
|
|
8693a8f2c9 | ||
|
|
9bc4656525 | ||
|
|
544000177c | ||
|
|
2b1dbf7e36 | ||
|
|
641ec8a9eb | ||
|
|
c18929dbae | ||
|
|
a592f34216 | ||
|
|
4e2adf77cb | ||
|
|
9fba09f00a | ||
|
|
12d377b3bd | ||
|
|
cd1f81c8d9 | ||
|
|
f6774fd554 | ||
|
|
ea248061f3 | ||
|
|
1e2894dd46 | ||
|
|
92b607bd0e | ||
|
|
b766ea958a | ||
|
|
a7074db9f8 | ||
|
|
5c819b2018 | ||
|
|
c526df5143 | ||
|
|
31ed2ae746 | ||
|
|
702065eb3d | ||
|
|
c418266af6 | ||
|
|
9c8d80d763 | ||
|
|
007a8cb8bf | ||
|
|
2fc7d55d6c | ||
|
|
b3bdcea137 | ||
|
|
4673347125 | ||
|
|
f827f9f408 | ||
|
|
6a8aed5d3f | ||
|
|
5e54477cd1 | ||
|
|
ba9fcda886 | ||
|
|
c848d93316 | ||
|
|
d00c8f1ea0 | ||
|
|
9788a135aa | ||
|
|
899e6b1417 | ||
|
|
6f7f14b241 | ||
|
|
cc0d1b5910 | ||
|
|
0b6cd8154b | ||
|
|
c4cae5d6b4 | ||
|
|
f58959842b | ||
|
|
b813c155bc | ||
|
|
98e53ae941 | ||
|
|
4d993266b3 | ||
|
|
8da27926a1 | ||
|
|
7fae7acc91 | ||
|
|
47708d34df | ||
|
|
ab322f1194 | ||
|
|
aab45b16b0 | ||
|
|
586920d8a8 | ||
|
|
ac8a1c69ae | ||
|
|
604cd52a79 | ||
|
|
37109a8531 | ||
|
|
136db7b085 | ||
|
|
c177d59b7b | ||
|
|
fa9611f4f5 | ||
|
|
859e2958c0 | ||
|
|
0dda22833d | ||
|
|
ccb40910e2 | ||
|
|
eddaa9233c | ||
|
|
a09f5a3ba6 | ||
|
|
ed78a58455 | ||
|
|
b130d50bb3 | ||
|
|
7ab286753d | ||
|
|
bc6aadb0ed | ||
|
|
fd9c8b0922 | ||
|
|
2c9b9cadfe | ||
|
|
fb1ac0994d | ||
|
|
5ba8e293eb | ||
|
|
801ed0eb9f | ||
|
|
54503f98d4 | ||
|
|
903ff637e7 | ||
|
|
82ef5f6b6e | ||
|
|
398f09a1ce | ||
|
|
f29de07d0d | ||
|
|
8524f719c1 | ||
|
|
0a73e686f5 | ||
|
|
615b3d0507 | ||
|
|
4df8574fb6 | ||
|
|
e39d51a37b | ||
|
|
598b5c8e4a | ||
|
|
135e31a3e2 | ||
|
|
8e4810baa1 | ||
|
|
acd0a7ba24 | ||
|
|
032bb6bf2e | ||
|
|
083bcd79f9 | ||
|
|
30a7c285b1 | ||
|
|
5d03bbfd20 | ||
|
|
1a167f8854 | ||
|
|
06b6b64d4c | ||
|
|
26999d2381 | ||
|
|
9fba0888eb | ||
|
|
1ce4ba836f | ||
|
|
6493720c11 | ||
|
|
dd0dec6ac4 | ||
|
|
cbfc98d85e | ||
|
|
086763919a | ||
|
|
62cbccd274 | ||
|
|
b0a8549453 | ||
|
|
757ab29b57 | ||
|
|
82eb62a9e1 | ||
|
|
66bed5a044 | ||
|
|
12449bf471 | ||
|
|
5c4f315083 | ||
|
|
0a88793328 | ||
|
|
4ea26f9bec | ||
|
|
85542591d0 | ||
|
|
91ef8ff9a2 | ||
|
|
13aa279c39 | ||
|
|
eadb87d369 | ||
|
|
f250bc3c79 | ||
|
|
eaaf653b0f | ||
|
|
4a30355aab | ||
|
|
2abd075e59 | ||
|
|
aec10de11f | ||
|
|
50e53a5b15 | ||
|
|
6a89907ddb | ||
|
|
3dae593802 | ||
|
|
5b2d26a839 | ||
|
|
3fa318c58f | ||
|
|
7dab64d1e0 | ||
|
|
99d1900c79 | ||
|
|
16bffe35f7 | ||
|
|
3efb822b6e | ||
|
|
a3463ec253 | ||
|
|
a76e7d641d | ||
|
|
ab75eaa19d | ||
|
|
2d50afe767 | ||
|
|
916ea44e1d | ||
|
|
59bbbd822e | ||
|
|
8b67c32fd8 | ||
|
|
0852b1c635 | ||
|
|
38f0ec2180 | ||
|
|
67567aeed5 | ||
|
|
5315408948 | ||
|
|
5f255090f5 | ||
|
|
2e8a62001e | ||
|
|
52add3fc14 | ||
|
|
964a1008fd | ||
|
|
5fd9145a27 | ||
|
|
988717574c | ||
|
|
23ea6da091 | ||
|
|
927442fb89 | ||
|
|
4db0f00c26 | ||
|
|
c710784038 | ||
|
|
5072d9025a | ||
|
|
b5a963c1bf | ||
|
|
608b4a2b8a | ||
|
|
ae5a982dc4 | ||
|
|
3ec6b54d46 | ||
|
|
6a34e2da97 | ||
|
|
627a4c4ad6 | ||
|
|
abbab7118c | ||
|
|
31e6887d42 | ||
|
|
fc37507afb | ||
|
|
e160b6795a | ||
|
|
5ace2f5cc9 | ||
|
|
0e54c37963 | ||
|
|
e9e118fa12 | ||
|
|
9af1de3b43 | ||
|
|
b74c2d2d17 | ||
|
|
ee779c0fd8 | ||
|
|
36fb5d5343 | ||
|
|
0d2f443da0 | ||
|
|
5dc696f7e6 | ||
|
|
6ae56f6737 | ||
|
|
76af31b457 | ||
|
|
7838b7b5c3 | ||
|
|
f98664f398 | ||
|
|
89b1584816 | ||
|
|
da0234f66b | ||
|
|
45af6700f5 | ||
|
|
c60bc158a4 | ||
|
|
b2895d8908 | ||
|
|
eb10bd6b6b | ||
|
|
af0a111b81 | ||
|
|
fc9e35c18f | ||
|
|
7d619a85b3 | ||
|
|
ded9e8d248 | ||
|
|
4b5a232a9e | ||
|
|
bbe85d77a3 | ||
|
|
172581b794 | ||
|
|
2b965738cb | ||
|
|
47fe2abfe0 | ||
|
|
5068f2ae2d | ||
|
|
479df88a67 | ||
|
|
be93ce6e1e | ||
|
|
f41f010aa9 | ||
|
|
72aa9ac89a | ||
|
|
77a4bee249 | ||
|
|
54bd79427e | ||
|
|
1d773de3ca | ||
|
|
791881dd85 | ||
|
|
fc7c6e123d | ||
|
|
e3af6258f5 | ||
|
|
0bf9cc31d0 | ||
|
|
c3a0c839a8 | ||
|
|
4b84c570b5 | ||
|
|
57a8f7e98a | ||
|
|
0483212986 | ||
|
|
96ad10a2b0 | ||
|
|
a7fbef8753 | ||
|
|
1443111081 | ||
|
|
9c78c6e78d | ||
|
|
0aa3452fdb | ||
|
|
2ca261f10d | ||
|
|
bbe62b4c7b | ||
|
|
fd08ddde07 | ||
|
|
6020c2d64b | ||
|
|
012efefbad | ||
|
|
a18d9af782 | ||
|
|
5bc6d6aaa9 | ||
|
|
bedb6b8afb | ||
|
|
3eeb24fea8 | ||
|
|
645d6d9beb | ||
|
|
20cf6d1654 | ||
|
|
5bbab3b822 | ||
|
|
0a73c8150b | ||
|
|
8619514bdb | ||
|
|
1ad9254588 | ||
|
|
2bff75633e | ||
|
|
fa9bfb428e | ||
|
|
ab2766f79b | ||
|
|
bcdb31c830 | ||
|
|
32203771f6 | ||
|
|
2ff18658c9 | ||
|
|
29979d3559 | ||
|
|
7e56b7eca4 | ||
|
|
7d7c89d24f | ||
|
|
07701b459b | ||
|
|
6c6d1eae5f | ||
|
|
58a91d6a7d | ||
|
|
b033b53958 | ||
|
|
f5df102fd9 | ||
|
|
d1f16dc432 | ||
|
|
0884ecd15e | ||
|
|
787570e7c7 | ||
|
|
33387c8e40 | ||
|
|
1b63c05762 | ||
|
|
c816ee7358 | ||
|
|
71c92846d2 | ||
|
|
fdf005fd8f | ||
|
|
ddac1730e6 | ||
|
|
c5e76fe6d4 | ||
|
|
eb7df8993c | ||
|
|
0c0e09fb2d | ||
|
|
834921f50b | ||
|
|
f161417d64 | ||
|
|
98689253d0 | ||
|
|
2be2045403 | ||
|
|
332793e0a8 | ||
|
|
736f77087e | ||
|
|
274d25094d | ||
|
|
636249c142 | ||
|
|
7bf598573b | ||
|
|
09588fe45e | ||
|
|
3f95d1f3f1 | ||
|
|
87425e5db9 | ||
|
|
a7f1342ad7 | ||
|
|
680c4b8f2a | ||
|
|
c897647054 | ||
|
|
d4715fd1ad | ||
|
|
8c2a7cfeac | ||
|
|
b898b5761b | ||
|
|
c298b611d2 | ||
|
|
b43fd6a3c0 | ||
|
|
53fc9f5782 | ||
|
|
7e975f95b5 | ||
|
|
3ee64793cc | ||
|
|
45bb27cff4 | ||
|
|
b15d45731e | ||
|
|
f043b4e0d9 | ||
|
|
328bc26684 | ||
|
|
7a06a9e479 | ||
|
|
77f50aaa16 | ||
|
|
ca646f8243 | ||
|
|
b7efd787cb | ||
|
|
91e9278cba | ||
|
|
1b1598273d | ||
|
|
272b7fce34 | ||
|
|
72f0044f1a | ||
|
|
a22a2c4386 | ||
|
|
a7a3352bca | ||
|
|
38e12b5b95 | ||
|
|
10f3015d32 | ||
|
|
3e14637e3d | ||
|
|
a03c7f0681 | ||
|
|
2053e3281f | ||
|
|
625fd2a488 | ||
|
|
99178dacd1 | ||
|
|
947fe9ef99 | ||
|
|
d99da1039b | ||
|
|
94e507b607 | ||
|
|
eb7fe9572d | ||
|
|
4f9dae3d0e | ||
|
|
dc650533f4 | ||
|
|
6521b012b3 | ||
|
|
c75fb703d2 | ||
|
|
ab250abfdb | ||
|
|
37111f2233 | ||
|
|
c4fa5713a2 | ||
|
|
657b2c7b65 | ||
|
|
b702ff6564 | ||
|
|
fb1dc90367 | ||
|
|
e57b39b430 | ||
|
|
cc0e87a0cd | ||
|
|
dd5bc10c72 | ||
|
|
092c7d139b | ||
|
|
137114d62a | ||
|
|
01f88ce2a8 | ||
|
|
243aba8c51 | ||
|
|
5211e526ec | ||
|
|
c5483f81db | ||
|
|
d8f4afdca5 | ||
|
|
6ef90dcd9d | ||
|
|
9eb14ac309 | ||
|
|
949b5db030 | ||
|
|
f42c062c08 | ||
|
|
42e23d0162 | ||
|
|
8794818492 | ||
|
|
412c88fb33 | ||
|
|
855d29af0c | ||
|
|
f9757c7f7a | ||
|
|
74eea33f1d | ||
|
|
0e9146a5c5 | ||
|
|
895c05669b | ||
|
|
7cd7719f9b | ||
|
|
c76e6142c2 | ||
|
|
dc63e6da74 | ||
|
|
affb07b513 | ||
|
|
4ea324f493 | ||
|
|
156acb308d | ||
|
|
e9237858b1 | ||
|
|
42cf056d57 | ||
|
|
a16bde6dae | ||
|
|
8b24b648c7 | ||
|
|
df9f5f97af | ||
|
|
8766ee44d6 | ||
|
|
1ab0c5b13d | ||
|
|
90dfcd0ad3 | ||
|
|
72e4b4f0cb | ||
|
|
633519ac3a | ||
|
|
7b4db3d325 | ||
|
|
305dd1d6a2 | ||
|
|
5a4eb4d297 | ||
|
|
8f81c1c4c3 | ||
|
|
5d6ae3fc2d | ||
|
|
faf133212e | ||
|
|
3c170edee3 | ||
|
|
736885c999 | ||
|
|
b9d8faff99 | ||
|
|
74fec650f6 | ||
|
|
c24ffb6b7c | ||
|
|
280c4e2592 | ||
|
|
88b31df121 | ||
|
|
fdd67171bd | ||
|
|
826d023608 | ||
|
|
925f6217ce | ||
|
|
7c12473940 | ||
|
|
44315a3d75 | ||
|
|
ebcbc1b2b5 | ||
|
|
1fb471872f | ||
|
|
5a890b32dc | ||
|
|
8cc10e6634 | ||
|
|
11f68bdac7 | ||
|
|
6751b6667b | ||
|
|
7b1786d7fe | ||
|
|
04fb442a7a | ||
|
|
0e4f81b7f4 | ||
|
|
b7e0196aa7 | ||
|
|
2fdfb8900d | ||
|
|
251a9925d2 | ||
|
|
59e8c4d89f | ||
|
|
49930e3f6a | ||
|
|
4021324465 | ||
|
|
b6930a2056 | ||
|
|
1821af8963 | ||
|
|
f33d9e7d53 | ||
|
|
879e38773b | ||
|
|
c4d0b985e3 | ||
|
|
6a8c438907 | ||
|
|
0e38151087 | ||
|
|
3766d14b0c | ||
|
|
9fcfe8f85d | ||
|
|
6c7c2e456c | ||
|
|
23fb6bc837 | ||
|
|
191bab4b36 | ||
|
|
3f9665531b | ||
|
|
3535170fa1 | ||
|
|
2129df6d5f | ||
|
|
f6fdaafe42 | ||
|
|
b2d07e6e30 | ||
|
|
1ae6eb33e9 | ||
|
|
f0d9a40f59 | ||
|
|
4ef5f5427d | ||
|
|
7ac03aa9d0 | ||
|
|
07c69b34ea | ||
|
|
d2c3cda897 | ||
|
|
8456cf37e3 | ||
|
|
2f1d7d5f6c | ||
|
|
6e87362a85 | ||
|
|
36de4ee5a2 | ||
|
|
63b6ff0f27 | ||
|
|
78e9f55363 | ||
|
|
9845ba6d83 | ||
|
|
d0c1e957f9 | ||
|
|
8c4a5584b9 | ||
|
|
0100fa1c93 | ||
|
|
38118de339 | ||
|
|
95b9097a3e | ||
|
|
8765ea2733 | ||
|
|
b3f019ed98 | ||
|
|
bd92591b7b | ||
|
|
e6178dfa65 | ||
|
|
2412a29226 | ||
|
|
c80b487052 | ||
|
|
4ca4047418 | ||
|
|
c30151607a | ||
|
|
6df48c0f7f | ||
|
|
d67c459153 | ||
|
|
47f5aade80 | ||
|
|
e06e1db9b0 | ||
|
|
6bfc426e63 | ||
|
|
04be1d3efd | ||
|
|
4b57a9dcd5 | ||
|
|
0a065403d5 | ||
|
|
0b598ddfb1 | ||
|
|
b5ef7c7278 | ||
|
|
8ed348342c | ||
|
|
aeb966b798 | ||
|
|
0d9ca4aa94 | ||
|
|
3529860fd2 | ||
|
|
a03ee39fd7 | ||
|
|
dca448d139 | ||
|
|
8947c5b8c7 | ||
|
|
572570b0f1 | ||
|
|
95d200bf3d | ||
|
|
3f58dd2dd2 | ||
|
|
c60672a710 | ||
|
|
16b6469277 | ||
|
|
cf18df1a94 | ||
|
|
ce6766ba9f | ||
|
|
0f517dd0e7 | ||
|
|
d3be3f9c4f | ||
|
|
efd1537a07 | ||
|
|
33c9290916 | ||
|
|
853c6a8452 | ||
|
|
5526fdb02c | ||
|
|
df05c3a3d6 | ||
|
|
40d414f791 | ||
|
|
0cf8492eab | ||
|
|
4619bf1722 | ||
|
|
6c52598bfb | ||
|
|
69330c5799 | ||
|
|
67781c7f18 | ||
|
|
482ddb50e8 | ||
|
|
6b937f3248 | ||
|
|
04ddc46cd5 | ||
|
|
51ce00eebe | ||
|
|
611c1414dc | ||
|
|
5ad1bea18b | ||
|
|
57339f81be | ||
|
|
82762ede0d | ||
|
|
4e324f3d18 | ||
|
|
8ab10fb3a1 | ||
|
|
f9a9543726 | ||
|
|
62223cebfd | ||
|
|
6104c14cfd | ||
|
|
6fb7284483 | ||
|
|
7c373c2edb | ||
|
|
82390070c1 | ||
|
|
c5bfa7332a | ||
|
|
e0e9dffee8 | ||
|
|
b5cfd5410e | ||
|
|
7b0e49753e | ||
|
|
6a04e6e29a | ||
|
|
9b2ca1bf90 | ||
|
|
2f2089e114 | ||
|
|
b78a542d28 | ||
|
|
08ce89a394 | ||
|
|
e4416db22b | ||
|
|
b5e195499a | ||
|
|
eb1d8deeff | ||
|
|
cb37cc60b9 | ||
|
|
83277d8a0c | ||
|
|
e28f1a653c | ||
|
|
c23c0248e1 | ||
|
|
82c064d4d9 | ||
|
|
5dc2d1ea7b | ||
|
|
f072dc5ba3 | ||
|
|
370af9b5fa | ||
|
|
aff71647aa | ||
|
|
b6ffbdae70 | ||
|
|
214c588bc1 | ||
|
|
da91ccda1c | ||
|
|
1d64b9e958 | ||
|
|
bbe507c740 | ||
|
|
c36da1cf8e | ||
|
|
54172e7065 | ||
|
|
5a145b69f8 | ||
|
|
20d861bd21 | ||
|
|
dc2ba58371 | ||
|
|
e800a445ae | ||
|
|
eadfc0feb3 | ||
|
|
bf5a6f6c3b | ||
|
|
4862dec4d9 | ||
|
|
56960ef0c0 | ||
|
|
3d5c8467c2 | ||
|
|
3fb8a697a0 | ||
|
|
c165587b54 | ||
|
|
e661570fbd | ||
|
|
28ff0a01df | ||
|
|
86075ea908 | ||
|
|
9ed638eb6b | ||
|
|
4054f8d273 | ||
|
|
d44a9e2634 | ||
|
|
e0cdb4020d | ||
|
|
74dadc162f | ||
|
|
e53c25807f | ||
|
|
ca64bded7c | ||
|
|
0709b46a63 | ||
|
|
e3be97f48e | ||
|
|
82f0db990f | ||
|
|
b2d17c0704 | ||
|
|
47fd6bd077 | ||
|
|
8837dc7a6c | ||
|
|
e35f05d037 | ||
|
|
5b3d595030 | ||
|
|
dfa9e7357e | ||
|
|
1a63ffbe5a | ||
|
|
5238b0776a | ||
|
|
28cfda6b96 | ||
|
|
eeae93881d | ||
|
|
5ef2db2754 | ||
|
|
d3a1612294 | ||
|
|
ee619a99a6 | ||
|
|
31c4944988 | ||
|
|
94aeedd9b0 | ||
|
|
3fbe2bd73b | ||
|
|
ff6f46dbd2 | ||
|
|
dc312da663 | ||
|
|
c0b8538dfe | ||
|
|
9935c43076 | ||
|
|
0b5b7d4984 | ||
|
|
23387f0fcc | ||
|
|
afe7a13e3c | ||
|
|
5eb7f17b84 | ||
|
|
9b7b0184c8 | ||
|
|
3f64f35b50 | ||
|
|
58e0b0556a | ||
|
|
0f69d96b8f | ||
|
|
3cc7151326 | ||
|
|
4191852fcb | ||
|
|
e049486b44 | ||
|
|
5fc945c32e | ||
|
|
a021f7984e | ||
|
|
9a3fbe874e | ||
|
|
b1b86e7093 | ||
|
|
5ea3018b02 | ||
|
|
3f336a21f4 | ||
|
|
ac28911137 | ||
|
|
c04d6e5414 | ||
|
|
0745ab63cf | ||
|
|
bce42023b1 | ||
|
|
b852055460 | ||
|
|
f1acd2b4b1 | ||
|
|
77c62b3059 | ||
|
|
206305fa40 | ||
|
|
9a7f798933 | ||
|
|
3cabbb6919 | ||
|
|
ab0645fe4c | ||
|
|
60adf6e369 | ||
|
|
5ca12a752e | ||
|
|
5fe6420620 | ||
|
|
fd5ae2b847 | ||
|
|
d1f3854b99 | ||
|
|
f444ba6651 | ||
|
|
2214fd99e8 | ||
|
|
35c5d54a76 | ||
|
|
4fd6d70b71 | ||
|
|
f67d771ea4 | ||
|
|
0fc5cc4442 | ||
|
|
9b1d5753eb | ||
|
|
34d5a178ae | ||
|
|
6cfb68796e | ||
|
|
dcdf4e82e5 | ||
|
|
9f3e2ae06d | ||
|
|
0793dccefa | ||
|
|
5d7350279b | ||
|
|
44d242d4aa | ||
|
|
bae25db654 | ||
|
|
a66aacb48d | ||
|
|
b7d861466a | ||
|
|
f17c3d4763 | ||
|
|
3ed8832a85 | ||
|
|
11f8d68cc3 | ||
|
|
52551d7357 | ||
|
|
9d777db805 | ||
|
|
1f3c68ad79 | ||
|
|
34be7d88b0 | ||
|
|
62dc2e55d5 | ||
|
|
492579a5d1 | ||
|
|
025ce42f56 | ||
|
|
6fef055c62 | ||
|
|
eae6b6b8eb | ||
|
|
23d4e3cf18 | ||
|
|
41bcbe55b9 | ||
|
|
63e9af8cc2 | ||
|
|
40ef251948 | ||
|
|
ad7d90c070 | ||
|
|
3b165d9e2f | ||
|
|
190e3cb3a0 | ||
|
|
8a759a67e4 | ||
|
|
d6edbf4e57 | ||
|
|
c8ab92f6dc | ||
|
|
6e2209f6e0 | ||
|
|
fadc9ffcf4 | ||
|
|
10b627f68c | ||
|
|
34e29aaf84 | ||
|
|
016dbef779 | ||
|
|
d95dae7282 | ||
|
|
b274be6adc | ||
|
|
975008a951 | ||
|
|
893c292150 | ||
|
|
3857f5d3ee | ||
|
|
e09277cdc2 | ||
|
|
37c24c0625 | ||
|
|
354d7e8c22 | ||
|
|
2409d8f4e0 | ||
|
|
df0e96d9ac | ||
|
|
fae8008269 | ||
|
|
a6a3599455 | ||
|
|
86983e9c9c | ||
|
|
b2c5d21322 | ||
|
|
161c89060e | ||
|
|
d14dbe80c9 | ||
|
|
c7a08a2f04 | ||
|
|
b104b1997a | ||
|
|
06ac5624ab | ||
|
|
7572e4eb1e | ||
|
|
eb34cb7cb2 | ||
|
|
6fc3ff4750 | ||
|
|
cbed9517bc | ||
|
|
2ca9158f15 | ||
|
|
5b77f36ae4 | ||
|
|
289d805bdc | ||
|
|
ed159425a5 | ||
|
|
f701de6e47 | ||
|
|
8f159de428 | ||
|
|
54aa763d01 | ||
|
|
df39cf1e4f | ||
|
|
3a74eb3d86 | ||
|
|
46603ce0f2 | ||
|
|
3c6f3ab3bf | ||
|
|
02761cabac | ||
|
|
72ff019c46 | ||
|
|
f2256e36a1 | ||
|
|
0772483396 | ||
|
|
4956969ef5 | ||
|
|
ed6901fe74 | ||
|
|
f981f1ea39 | ||
|
|
04bc5acf53 | ||
|
|
35c49cb4b7 | ||
|
|
bcd4ad4c24 | ||
|
|
c3f99c0914 | ||
|
|
67a85ccf49 | ||
|
|
7df3657de8 | ||
|
|
0d4b589f86 | ||
|
|
fb608ea6ff | ||
|
|
3b05ec8666 | ||
|
|
9463798787 | ||
|
|
92f1e90079 | ||
|
|
8b60cb2457 | ||
|
|
0527428f6c | ||
|
|
508ff7d041 | ||
|
|
53cdb49ba8 | ||
|
|
cdb76b1c18 | ||
|
|
8ed6bd1bfc | ||
|
|
028efc13c9 | ||
|
|
115234d93b | ||
|
|
34afbc348d | ||
|
|
8842b7e8b8 | ||
|
|
b10d8e0ec6 | ||
|
|
1ec66d5732 | ||
|
|
084691a29a | ||
|
|
d083dc041e | ||
|
|
c0c30ca012 | ||
|
|
65fbf9958d | ||
|
|
c0a6739981 | ||
|
|
81fdef1991 | ||
|
|
dc0dbb29ff | ||
|
|
aa98c2fff5 | ||
|
|
5c935f03fe | ||
|
|
b44e25c8ee | ||
|
|
822f5624b1 | ||
|
|
60f2fdd7cb | ||
|
|
6518f92be7 | ||
|
|
f674d32c4e | ||
|
|
e81c9f80cd | ||
|
|
e1fffddf85 | ||
|
|
1ddc202fd0 | ||
|
|
9ed4bea12e | ||
|
|
cebc62066b | ||
|
|
ebba65c729 | ||
|
|
0373547a79 | ||
|
|
1076ca4bd8 | ||
|
|
fda5aed59c | ||
|
|
1393125ceb | ||
|
|
8557dbc1a7 | ||
|
|
c4ca2ec55c | ||
|
|
3090636827 | ||
|
|
804e2c1568 | ||
|
|
1a2b31e159 | ||
|
|
37e930f183 | ||
|
|
c2560af1e9 | ||
|
|
1d24d5c4f7 | ||
|
|
ce5e7a3f61 | ||
|
|
a1a7bd02f5 | ||
|
|
1068ffa0eb | ||
|
|
628887b426 | ||
|
|
ec7ba74900 | ||
|
|
e383d1d145 | ||
|
|
abe813b656 | ||
|
|
d690cf904c | ||
|
|
fe82de8bd5 | ||
|
|
7a943dc49a | ||
|
|
bc2278e89b | ||
|
|
2996f2313c | ||
|
|
d95c7288e9 | ||
|
|
43f7c0d23e | ||
|
|
616273eb43 | ||
|
|
aeca902517 | ||
|
|
652cd1c78a | ||
|
|
7ab19c15d9 | ||
|
|
35226f843c | ||
|
|
b8b02aabd3 | ||
|
|
6784f696af | ||
|
|
350b9ce7c8 | ||
|
|
5cbe7033c8 | ||
|
|
c15b4aa0c3 | ||
|
|
e7ff39bfc8 | ||
|
|
196ea82509 | ||
|
|
be38a9cdca | ||
|
|
aa4424b97f | ||
|
|
a1b4b34b39 | ||
|
|
b0ea1a6a53 | ||
|
|
ad9742abb4 | ||
|
|
53c8950947 | ||
|
|
edd89d2aaf | ||
|
|
718860f30e | ||
|
|
025533f734 | ||
|
|
8644a80d80 | ||
|
|
e8c51b6977 | ||
|
|
51305266e8 | ||
|
|
832c0753ce | ||
|
|
453fc865ee | ||
|
|
dead9fca70 | ||
|
|
7f048bbf57 | ||
|
|
6ae1e846ee | ||
|
|
4286dec1a1 | ||
|
|
6d3399ccb8 | ||
|
|
a3b547ab80 | ||
|
|
f80b0b3eac | ||
|
|
09b8975174 | ||
|
|
9cdba3b3e0 | ||
|
|
e6eba50913 | ||
|
|
7e6a3f4a1f | ||
|
|
faff3b9337 | ||
|
|
11e613ce05 | ||
|
|
04413be781 | ||
|
|
fa95755642 | ||
|
|
72f6521710 | ||
|
|
2a9012763e | ||
|
|
c06016bc5b | ||
|
|
b946c2842a | ||
|
|
356c6c76d2 | ||
|
|
27f466ae8d | ||
|
|
3f0f5ba019 | ||
|
|
1e4c3cec94 | ||
|
|
e21a57e76c | ||
|
|
7abe44c412 | ||
|
|
c24a0ccd66 | ||
|
|
9926d0fa80 | ||
|
|
b598e31ca3 | ||
|
|
0faae8cfad | ||
|
|
4535954699 | ||
|
|
e9d0a81e8e | ||
|
|
d6333aa476 | ||
|
|
5b702e1991 | ||
|
|
cb2ce4a8a3 | ||
|
|
82ab0e5367 | ||
|
|
d8506b4239 | ||
|
|
5ded1fc682 | ||
|
|
8f4010d0cf | ||
|
|
2319f033f7 | ||
|
|
9bf0b5ff70 | ||
|
|
c414fc6259 | ||
|
|
43d3d72620 | ||
|
|
800597ae2b | ||
|
|
291bef2007 | ||
|
|
39f1bbe436 | ||
|
|
43b5e66431 | ||
|
|
d21c3f33b6 | ||
|
|
a58b047723 | ||
|
|
9ef7c35ee0 | ||
|
|
3d4708bd68 | ||
|
|
7536b725b4 | ||
|
|
8101ef0c5a | ||
|
|
80d027ba12 | ||
|
|
fb0310b8f6 | ||
|
|
8482cb4ddc | ||
|
|
1700c3fa19 | ||
|
|
63fd69ad75 | ||
|
|
548be0303f | ||
|
|
8b39953242 | ||
|
|
6d0de809ec | ||
|
|
8c2a353096 | ||
|
|
a5d275147d | ||
|
|
12b6711a73 | ||
|
|
b0fd3e8295 | ||
|
|
80a7f348ad | ||
|
|
a56049b5db | ||
|
|
53e6168c8c | ||
|
|
b17e5140ce | ||
|
|
95d1a7cc30 | ||
|
|
b8b2dcb6fe | ||
|
|
504d124486 | ||
|
|
380daf4a00 | ||
|
|
248fadbf9d | ||
|
|
78a272d633 | ||
|
|
9174ce4b47 | ||
|
|
ec4dd70279 | ||
|
|
97093db976 | ||
|
|
2aba8381a8 | ||
|
|
5ce0a2213c | ||
|
|
d3599d5ed3 | ||
|
|
98939b4868 | ||
|
|
89df7486bd | ||
|
|
e9b42e1008 | ||
|
|
72578c94e5 | ||
|
|
2f20ec448d | ||
|
|
ddfab6f729 | ||
|
|
5ea154d45d | ||
|
|
1beb50b0f3 | ||
|
|
1539bd4698 | ||
|
|
10895fcdfd | ||
|
|
5f36059857 | ||
|
|
b04ae36466 | ||
|
|
1d433ee82a | ||
|
|
2ec27f40be | ||
|
|
d99b63f6cf | ||
|
|
37a064dc55 | ||
|
|
f8375dd9e0 | ||
|
|
38c523375b | ||
|
|
8bdc8a0bb7 | ||
|
|
ecaf8ab2e9 | ||
|
|
dbeaf1111d | ||
|
|
cb8f4d060b | ||
|
|
013b26e692 | ||
|
|
1db3d69571 | ||
|
|
272493dc31 | ||
|
|
75215e4909 | ||
|
|
d3b21a3ae7 | ||
|
|
9e9b46f4a2 | ||
|
|
b73f43e200 | ||
|
|
911f9a28b5 | ||
|
|
f76e77585c | ||
|
|
1ba45eb368 | ||
|
|
adfcc9a55c | ||
|
|
d3247ed266 | ||
|
|
3cc1dc5bb7 | ||
|
|
214901dfe6 | ||
|
|
ed6b6e169d | ||
|
|
295e8c2d9e | ||
|
|
ea4b3432c0 | ||
|
|
c2ebd96aab | ||
|
|
d80d488656 | ||
|
|
7e26836e48 | ||
|
|
64e5753381 | ||
|
|
78642492bf | ||
|
|
388fb57b7a | ||
|
|
fdde24d9e9 | ||
|
|
70a24dfa69 | ||
|
|
403af75f87 | ||
|
|
40444a3fe9 | ||
|
|
559215189a | ||
|
|
57ac13c87e | ||
|
|
018939d301 | ||
|
|
e1cf78ef2b | ||
|
|
b5eb3a0433 | ||
|
|
dd8b1c3635 | ||
|
|
c53a7a0368 | ||
|
|
3feaa262be | ||
|
|
7496af52d7 | ||
|
|
293f1f7d47 | ||
|
|
3f3533134c | ||
|
|
b505d6af02 | ||
|
|
3aac39c4f7 | ||
|
|
b1417f539d | ||
|
|
5f234ade12 | ||
|
|
1564d8b8c4 | ||
|
|
e64aba2c2c | ||
|
|
7129467410 | ||
|
|
504cc025a2 | ||
|
|
6906fada68 | ||
|
|
649e2a7a76 | ||
|
|
24c455cdc6 | ||
|
|
69806152aa | ||
|
|
1a22bc45c1 | ||
|
|
02a87fb94c | ||
|
|
55ba31c7d3 | ||
|
|
da34a6f7c1 | ||
|
|
6a4b29d6f6 | ||
|
|
dd55c60bd6 | ||
|
|
f735ec7d3e | ||
|
|
3e15668da5 | ||
|
|
75117cba49 | ||
|
|
0a1bf10fc3 | ||
|
|
6865aa2ff7 | ||
|
|
46292ef117 | ||
|
|
af74715a84 | ||
|
|
ad6a3fcf99 | ||
|
|
bed61fea08 | ||
|
|
0a34d99b6e | ||
|
|
6dbfa5897c | ||
|
|
9eee63b031 | ||
|
|
21106d98d0 | ||
|
|
8727a7a809 | ||
|
|
99612516b6 | ||
|
|
198f30b1ae | ||
|
|
fbc8a916ac | ||
|
|
4f295d01af | ||
|
|
e8554bcd03 | ||
|
|
749e095b04 | ||
|
|
45f47de514 | ||
|
|
174ba8951a | ||
|
|
d59793c752 | ||
|
|
6b93fd6e27 | ||
|
|
35b45c4045 | ||
|
|
cc61f8ab1f | ||
|
|
19a224d375 | ||
|
|
82e5b81fda | ||
|
|
ba493b07e7 | ||
|
|
8521b7133d | ||
|
|
153409f3b5 | ||
|
|
0a41cfeeac | ||
|
|
47b90c4939 | ||
|
|
4385b647c1 | ||
|
|
322c381ed4 | ||
|
|
88d5b5ac57 | ||
|
|
52835de6c9 | ||
|
|
39edba2ab3 | ||
|
|
bac9790dab | ||
|
|
eba395c22f | ||
|
|
9f59d9ce20 | ||
|
|
6110a9f8b7 | ||
|
|
111dc5950b | ||
|
|
f1f96516d0 | ||
|
|
0ed837ffda | ||
|
|
98bd33aa29 | ||
|
|
56af888ded | ||
|
|
9fa2e983ad | ||
|
|
c3e17f0df8 | ||
|
|
ddbd9a5b70 | ||
|
|
2f6c5433ce | ||
|
|
4bd1e59c20 | ||
|
|
598f3cbf8b | ||
|
|
4c7899dc1e | ||
|
|
97f5d60d7c | ||
|
|
16aeb4e6fe | ||
|
|
45d3cce3e6 | ||
|
|
8e5f474c1f | ||
|
|
aa1adcad3c | ||
|
|
570cd68d15 | ||
|
|
e3947e44bd | ||
|
|
9a1a93c25e | ||
|
|
c9ea556273 | ||
|
|
aee2c22afe | ||
|
|
f6bf0f3a96 | ||
|
|
3fc9f450f9 | ||
|
|
c26327306b | ||
|
|
5c10cfcb99 | ||
|
|
67f114cf29 | ||
|
|
2658e12c52 | ||
|
|
0a454a0967 | ||
|
|
9800d4a335 | ||
|
|
e3d00ebb68 | ||
|
|
c9fefe95aa | ||
|
|
fdb22bff37 | ||
|
|
3eba14e0a6 | ||
|
|
f2b5016920 | ||
|
|
3eedd0dd23 | ||
|
|
555babf34c | ||
|
|
ec165a9042 | ||
|
|
d4b2d251d6 | ||
|
|
78aecb52ca | ||
|
|
8eb17ec066 | ||
|
|
01c1899208 | ||
|
|
bec7eeaa33 | ||
|
|
dc49178002 | ||
|
|
ddf59c0756 | ||
|
|
6dc1e0de1c | ||
|
|
4dd401a0cb | ||
|
|
e60ef9d02e | ||
|
|
9f2a6f3265 | ||
|
|
36db9285f6 | ||
|
|
559ea53e69 | ||
|
|
f7ade9751e | ||
|
|
963e1ecc6c | ||
|
|
35ca583dc1 | ||
|
|
8b12debefe | ||
|
|
a0caa174d0 | ||
|
|
8bd2d74316 | ||
|
|
e6015f5db2 | ||
|
|
a227490dcb | ||
|
|
c0c5cf032d | ||
|
|
25c09589f2 | ||
|
|
22b273faf0 | ||
|
|
fd850636a5 | ||
|
|
2568cba699 | ||
|
|
2968ad5dd8 | ||
|
|
6311e0f8b0 | ||
|
|
7449779f37 | ||
|
|
459bc4f9ff | ||
|
|
a574514a41 | ||
|
|
ceb70ecefb | ||
|
|
bc0e021b3c | ||
|
|
19d372a4ad | ||
|
|
8a08dd3916 | ||
|
|
a672e1708f | ||
|
|
4b4407c3f9 | ||
|
|
2d1c7428b6 | ||
|
|
ad28f56744 | ||
|
|
a8c1c6b25f | ||
|
|
4a89da8067 | ||
|
|
386649b0bb | ||
|
|
e050489073 | ||
|
|
94895ef110 | ||
|
|
4c93c01d22 | ||
|
|
9228b44a94 | ||
|
|
7ace7892b1 | ||
|
|
f4dfdc46f1 | ||
|
|
cc8b0f70d6 | ||
|
|
d943a0e0d1 | ||
|
|
c25c241008 | ||
|
|
59aad46280 | ||
|
|
65a754935e | ||
|
|
99f0cc9a01 | ||
|
|
371e27e92e | ||
|
|
724c62684f | ||
|
|
040123d2b1 | ||
|
|
c5f26d1217 | ||
|
|
55e87e47f1 | ||
|
|
bb9b397caa | ||
|
|
e1c9006b2d | ||
|
|
b7a95f200f | ||
|
|
fb15ed7deb | ||
|
|
9535b226ce | ||
|
|
48e6c149a6 | ||
|
|
068307171c | ||
|
|
b7957f5dd4 | ||
|
|
4c40999c71 | ||
|
|
ff786da6a2 | ||
|
|
25955bfeca | ||
|
|
b9f25bcd90 | ||
|
|
b8dfa5eebe | ||
|
|
10719b6c92 | ||
|
|
cdb029dcb8 | ||
|
|
55fa399ea6 | ||
|
|
c0bdff6a1c | ||
|
|
48d35004d4 | ||
|
|
e95cc9a39d | ||
|
|
c260fb4c61 | ||
|
|
4b279a83a9 | ||
|
|
3cebc8aee5 | ||
|
|
58035970a4 | ||
|
|
707a62b678 | ||
|
|
2c738bb96c | ||
|
|
fa24932e7c | ||
|
|
b8fc416fed | ||
|
|
7ad065a756 | ||
|
|
54a54d048c | ||
|
|
28fef8f5ea | ||
|
|
92a1c1e25d | ||
|
|
34c5ae9c71 | ||
|
|
1c68b9bba0 | ||
|
|
6b7d2d7c69 | ||
|
|
3482a3e94f | ||
|
|
b96d6a5a1b | ||
|
|
01625e3382 | ||
|
|
8243861c49 | ||
|
|
744c5828a5 | ||
|
|
a33b438ddc | ||
|
|
445e50f011 | ||
|
|
e845aa2a51 | ||
|
|
39aebfc782 | ||
|
|
6441d2fd01 | ||
|
|
36f02fa5f8 | ||
|
|
e80ca4319b | ||
|
|
350186614e | ||
|
|
6caec3ea06 | ||
|
|
f45ec2b32b | ||
|
|
c361b4e589 | ||
|
|
ef4e5fbef6 | ||
|
|
d9fe7d6927 | ||
|
|
920832c5c7 | ||
|
|
a1a1dafb2f | ||
|
|
45eda81ccc | ||
|
|
83db5d1e2d | ||
|
|
71e7a8121f | ||
|
|
0368ef0498 | ||
|
|
34b8267b03 | ||
|
|
13e8f80a5d | ||
|
|
f9bbd87b5d | ||
|
|
b5150eb926 | ||
|
|
ab078ad644 | ||
|
|
676244b0c7 | ||
|
|
c1b990837d | ||
|
|
7dc38d0a4a | ||
|
|
6fdb0e1e4c | ||
|
|
4712d9be73 | ||
|
|
724c060372 | ||
|
|
45e996e2fa | ||
|
|
66f4780410 | ||
|
|
f2b3838451 | ||
|
|
17e67528cc | ||
|
|
6dfd959020 | ||
|
|
65d4d6538d | ||
|
|
63efd921ed | ||
|
|
2bbe7b1eef | ||
|
|
9c6f6acf6c | ||
|
|
6bc1456655 | ||
|
|
663412be0b | ||
|
|
272d4defc0 | ||
|
|
c7f81e4ad8 | ||
|
|
03ec0f2964 | ||
|
|
53d76aaa4d | ||
|
|
43a68cb1ed | ||
|
|
8f8c6405ea | ||
|
|
1efa6ec0aa | ||
|
|
13bbdaa1e8 | ||
|
|
feeed40395 | ||
|
|
f8022eb73b | ||
|
|
07e1c78029 | ||
|
|
d1ea18952f | ||
|
|
3b0097078d | ||
|
|
9b4c941cd4 | ||
|
|
50bee657ba | ||
|
|
8412f5d2d6 | ||
|
|
eabf5b6e8f | ||
|
|
3dd525d5ff | ||
|
|
a828671570 | ||
|
|
084cb9742a | ||
|
|
f3e4a9717c | ||
|
|
b63033eeab | ||
|
|
c52754d80e | ||
|
|
6adb45d944 | ||
|
|
2478ca8fd9 | ||
|
|
c6492dfeee | ||
|
|
5fcd32a7e8 | ||
|
|
73e7efddae | ||
|
|
a934358614 | ||
|
|
620ba60f2e | ||
|
|
f89b0b1797 | ||
|
|
bafb6f304c | ||
|
|
20e5110ac5 | ||
|
|
083ffd8a3f | ||
|
|
cf8c202d01 | ||
|
|
71bbb8281c | ||
|
|
3b3d7150bd | ||
|
|
130e5c567d | ||
|
|
ba61b6c8dd | ||
|
|
b3715aee80 | ||
|
|
4064c9b98c | ||
|
|
fea576c258 | ||
|
|
189bfe4013 | ||
|
|
2370c6e82e | ||
|
|
bfda6d619e | ||
|
|
930d777931 | ||
|
|
9565fa70d2 | ||
|
|
add4061e7f | ||
|
|
15e0d8e40d | ||
|
|
a1309b2552 | ||
|
|
283f148f74 | ||
|
|
21292de648 | ||
|
|
628872d2fd | ||
|
|
6608a10538 | ||
|
|
7eaf58237a | ||
|
|
f952712b5e | ||
|
|
03d5798ea0 | ||
|
|
4a049cfecd | ||
|
|
d36c76f4de | ||
|
|
fb04949dc3 | ||
|
|
0969cc7a24 | ||
|
|
12dff011cc | ||
|
|
5572cc2ede | ||
|
|
91f5827a4f | ||
|
|
aec92583ea | ||
|
|
63f4adcc97 | ||
|
|
82df16a8c4 | ||
|
|
237f30c3f7 | ||
|
|
2dac7741d4 | ||
|
|
0cff7d0e94 | ||
|
|
5e5abdfd21 | ||
|
|
0a755e5ea5 | ||
|
|
792e3ad20d | ||
|
|
336c5047c6 | ||
|
|
9c999de243 | ||
|
|
9a71a0bc84 | ||
|
|
7fb76b6dcd | ||
|
|
4f924bec0e | ||
|
|
ea4301bf28 | ||
|
|
99fcfcfa7e | ||
|
|
81218bc62d | ||
|
|
a71a0d4036 | ||
|
|
db578ec144 | ||
|
|
9410758de0 | ||
|
|
7b05468390 | ||
|
|
6d43b68d0b | ||
|
|
ae1fb54a3c | ||
|
|
313462e3ab | ||
|
|
be56713329 | ||
|
|
caae6916ae | ||
|
|
4e1db4f14f | ||
|
|
d2298b6097 | ||
|
|
8b1ef3cd74 | ||
|
|
05da8b4210 | ||
|
|
33cd29a47d | ||
|
|
f35b198c05 | ||
|
|
2bba5ad425 | ||
|
|
cbcb5278db | ||
|
|
be032908b0 | ||
|
|
e4d7967cd5 | ||
|
|
2fd0e37395 | ||
|
|
155ed6e0e1 | ||
|
|
4f70901a8c | ||
|
|
faf81a70fd | ||
|
|
680f324a34 | ||
|
|
718c2bdd81 | ||
|
|
d5ef59f028 | ||
|
|
881b8edaa9 | ||
|
|
2b5c30f203 | ||
|
|
1e5ff3a2fd | ||
|
|
7604786437 | ||
|
|
be752464bc | ||
|
|
fe47e30520 | ||
|
|
1623fb6559 | ||
|
|
002dceac35 | ||
|
|
b0b2874fdf | ||
|
|
378ef51ea8 | ||
|
|
241fd05d5c | ||
|
|
3267082ac3 | ||
|
|
fbc67e547c | ||
|
|
57b0cde173 | ||
|
|
222116d122 | ||
|
|
4e51f87eb0 | ||
|
|
a0fa00fd93 | ||
|
|
60989716fb | ||
|
|
a50f99634e | ||
|
|
822a6ff7a1 | ||
|
|
110da023b1 | ||
|
|
03fcf31e97 | ||
|
|
96e990ad3e | ||
|
|
6709beee6c | ||
|
|
644856890b | ||
|
|
208ebe92a8 | ||
|
|
752648d604 | ||
|
|
8f5e73321f | ||
|
|
5c83a98cb3 | ||
|
|
8711c64ff6 | ||
|
|
b6477e8b84 | ||
|
|
6f24ad440c | ||
|
|
640d24ea66 | ||
|
|
60b06dd739 | ||
|
|
501966b150 | ||
|
|
32e6e38103 | ||
|
|
adce72980b | ||
|
|
695351633d | ||
|
|
a2b4aedce5 | ||
|
|
37dd1361b0 | ||
|
|
68042169ff | ||
|
|
f110bdbe68 | ||
|
|
923e714017 | ||
|
|
81dd8f8afa | ||
|
|
73d855e682 | ||
|
|
a5606ed518 | ||
|
|
ca2a495790 | ||
|
|
695b7374bc | ||
|
|
f9df86feec | ||
|
|
8686249557 | ||
|
|
a8d529f9ea | ||
|
|
4715de6308 | ||
|
|
b41ec4ff65 | ||
|
|
b3de88d2c4 | ||
|
|
063314c91d | ||
|
|
e72b600326 | ||
|
|
594b13f5f9 | ||
|
|
fdb1dbbba0 | ||
|
|
d89055f64b | ||
|
|
13ffeac51b | ||
|
|
d94c6e9995 | ||
|
|
639694c0fb | ||
|
|
6f629b7393 | ||
|
|
d4af4ca030 | ||
|
|
237cead03b | ||
|
|
d440af07b1 | ||
|
|
a09346bfc0 | ||
|
|
c9f90a6cf5 | ||
|
|
e0d07b5205 | ||
|
|
1c035c5523 | ||
|
|
38e49fc09f | ||
|
|
1ff2a366fa | ||
|
|
263b785fcb | ||
|
|
c1475dd5f1 | ||
|
|
3411ece8a8 | ||
|
|
5912c00a4b | ||
|
|
e39acfeeae | ||
|
|
b0ddc52e97 | ||
|
|
b7ea6fdfcf | ||
|
|
28fdf33411 | ||
|
|
96b753c367 | ||
|
|
e34ed69b9b | ||
|
|
d75d44795c | ||
|
|
97ce9d60e0 | ||
|
|
391dbe06cc | ||
|
|
81ae6221ac | ||
|
|
a96302230c | ||
|
|
a5b5b160e2 | ||
|
|
21d327d4fe | ||
|
|
2241f360b4 | ||
|
|
3d951f5453 | ||
|
|
9db96d7296 | ||
|
|
7a8b81f261 | ||
|
|
edd2f92dae | ||
|
|
f9fbb07f0a | ||
|
|
29418e36d8 | ||
|
|
2420391455 | ||
|
|
5221858e30 | ||
|
|
1a40a6e747 | ||
|
|
85715416a5 | ||
|
|
2133c53a5c | ||
|
|
f2a5d2987d | ||
|
|
cef675a672 | ||
|
|
78cf48518c | ||
|
|
10d36df0b6 | ||
|
|
b2e5e5ee8d | ||
|
|
14cb91a952 | ||
|
|
aba3bcbe99 | ||
|
|
95691b3de6 | ||
|
|
c6abc34868 | ||
|
|
e9e50f7402 | ||
|
|
ec66d57a7a | ||
|
|
8eb1f7b729 | ||
|
|
4d1fe3c052 | ||
|
|
93a42e1cb9 | ||
|
|
93cffa2d20 | ||
|
|
14a32ff704 | ||
|
|
1d1318dad2 | ||
|
|
cacf1e9610 | ||
|
|
cd80edc69d | ||
|
|
778bd98197 | ||
|
|
2c0e2a559f | ||
|
|
f76e8eb150 | ||
|
|
9084ce08b3 | ||
|
|
eebe898c37 | ||
|
|
ea3b3aec05 | ||
|
|
2a820a9e33 | ||
|
|
f5d77f5b19 | ||
|
|
ea4a0acac7 | ||
|
|
9655bf7740 | ||
|
|
2dce686767 | ||
|
|
6d93558c6e | ||
|
|
363c2c39aa | ||
|
|
a5f7ef04f4 | ||
|
|
7f4eeaeb1a | ||
|
|
a352b4f8fe | ||
|
|
a41e1d7299 | ||
|
|
01ce50ba59 | ||
|
|
b606530f0e | ||
|
|
0cdf15fec5 | ||
|
|
edb05ae692 | ||
|
|
889f2637fc | ||
|
|
1792c8b615 | ||
|
|
24173b4beb | ||
|
|
f59bed5f48 | ||
|
|
3a1915a027 | ||
|
|
67d8787dfa | ||
|
|
8eb41f7b94 | ||
|
|
3725fdf26a | ||
|
|
9aa65e3489 | ||
|
|
c945d0d4a6 | ||
|
|
63c8f8af95 | ||
|
|
18acbe65c4 | ||
|
|
af48c7c682 | ||
|
|
d961a590b4 | ||
|
|
e7426d5e71 | ||
|
|
e485a0514e | ||
|
|
05448a3cae | ||
|
|
be22778704 | ||
|
|
89cfa4dc0d | ||
|
|
1a69381038 | ||
|
|
0f6108a0c0 | ||
|
|
2dc1e6044a | ||
|
|
2234822346 | ||
|
|
0739cef329 | ||
|
|
572b370aec | ||
|
|
0fc7964afa | ||
|
|
10f287a885 | ||
|
|
f47a2c3ef3 | ||
|
|
bb9d1621a5 | ||
|
|
be88de9f0e | ||
|
|
d752daecbe | ||
|
|
f8482fd2ca | ||
|
|
6150acc420 | ||
|
|
b11e959fe7 | ||
|
|
76c8fbbfbc | ||
|
|
81f0e8d255 | ||
|
|
8b3ede859b | ||
|
|
82b8245f6a | ||
|
|
ba6a218a09 | ||
|
|
7db489d987 | ||
|
|
b718d566d7 | ||
|
|
c6808a3524 | ||
|
|
74b9435ba4 | ||
|
|
1e81fee38a | ||
|
|
330f8b6e71 | ||
|
|
3fbc1ea845 | ||
|
|
fdc4a07242 | ||
|
|
fc7595c072 | ||
|
|
36e7d3d221 | ||
|
|
ff11531d8c | ||
|
|
5f967edb5b | ||
|
|
22daedac3c | ||
|
|
7a1760a20f | ||
|
|
472bd4c27c | ||
|
|
b37ea343f1 | ||
|
|
0ea80c5b06 | ||
|
|
ae60472790 | ||
|
|
42f019a136 | ||
|
|
ccd87ca8bc | ||
|
|
23f74d3982 | ||
|
|
9dfbdbbb00 | ||
|
|
b5e1379c8d | ||
|
|
ce48719df9 | ||
|
|
84f2faff38 | ||
|
|
74c1017a0c | ||
|
|
510712bf86 | ||
|
|
7743425e9c | ||
|
|
50984f8f84 | ||
|
|
82fed513a8 | ||
|
|
adfaa19180 | ||
|
|
cf8b29665c | ||
|
|
43bfdc8994 | ||
|
|
b29b3a12e3 | ||
|
|
38d2c7dc25 | ||
|
|
cc3a8f55e6 | ||
|
|
a6616bb17d | ||
|
|
ad06a9f4ea | ||
|
|
d150800f1b | ||
|
|
e8b716b2a1 | ||
|
|
442ce5ce83 | ||
|
|
72f18d7acf | ||
|
|
fa905db20f | ||
|
|
de1745f4ce | ||
|
|
f6697c9003 | ||
|
|
44d9e704b3 | ||
|
|
ed9ec3b702 | ||
|
|
07f10c42dc | ||
|
|
9b45e4c9a1 | ||
|
|
d3d8bd14aa | ||
|
|
4dfe44af20 | ||
|
|
9ae9af2acf | ||
|
|
2d11f25204 | ||
|
|
2cd4776649 | ||
|
|
0aae8679c5 | ||
|
|
3bb34b88a6 | ||
|
|
8efb6e952a | ||
|
|
3ef04dbd25 | ||
|
|
9d4eade8c1 | ||
|
|
9c145bc34b | ||
|
|
2317e6b072 | ||
|
|
f12f17c6c4 | ||
|
|
23358a7f8c | ||
|
|
ef32f8b0f9 | ||
|
|
7e81d58f78 | ||
|
|
213f7850bc | ||
|
|
89a86c3629 | ||
|
|
83f4e57fe2 | ||
|
|
0ffe19196c | ||
|
|
ec9fb0cddc | ||
|
|
c1ffc565e5 | ||
|
|
dca4cd0e63 | ||
|
|
0a00f07d26 | ||
|
|
6b75585b9d | ||
|
|
59583925b5 | ||
|
|
39c594531a | ||
|
|
21d167b543 | ||
|
|
4439dd777a | ||
|
|
1b17f255cd | ||
|
|
bd7ffb6ed0 | ||
|
|
d56bd71f04 | ||
|
|
5dea0ad170 | ||
|
|
caf0bcabf4 | ||
|
|
ad6c736f5c | ||
|
|
4c5443fff8 | ||
|
|
c4c3ce2c76 | ||
|
|
f2e3dd3835 | ||
|
|
3f8a60c2fd | ||
|
|
1d62545b4d | ||
|
|
33b331d724 | ||
|
|
ac51e3b0cd | ||
|
|
6af817414a | ||
|
|
c94f060196 | ||
|
|
302daba0a6 | ||
|
|
0cfd475bc7 | ||
|
|
8bcb3d8d18 | ||
|
|
e70a2d5387 | ||
|
|
1004eab7c3 | ||
|
|
21512b44ff | ||
|
|
121bec3a3b | ||
|
|
6227fca86e | ||
|
|
21d3c577c8 | ||
|
|
286e5ce814 | ||
|
|
077337b0ea | ||
|
|
c08342b404 | ||
|
|
6ab6152d66 | ||
|
|
e3e11645b9 | ||
|
|
71abbd7024 | ||
|
|
239336f39f | ||
|
|
adfda085d7 | ||
|
|
9034a41e93 | ||
|
|
8011700c3a | ||
|
|
a4b6d1c15d | ||
|
|
885ace494e | ||
|
|
139382c930 | ||
|
|
f77697fa15 | ||
|
|
0d230c1d96 | ||
|
|
ed4fdc13c9 | ||
|
|
a729eb4e75 | ||
|
|
f4efc133f9 | ||
|
|
c2aa56adff | ||
|
|
1530b0b9e4 | ||
|
|
c0c8f92d6b | ||
|
|
da99f3b66c | ||
|
|
4ec0b703f4 | ||
|
|
81f48dc776 | ||
|
|
0927fbaf35 | ||
|
|
a61770b99d | ||
|
|
2668e9d634 | ||
|
|
a9e482d9af | ||
|
|
71cdb3e11c | ||
|
|
ecd30ae17d | ||
|
|
a28ff87eca | ||
|
|
117bca46df | ||
|
|
2657260054 | ||
|
|
69c4c6cb31 | ||
|
|
2df5b55ed7 | ||
|
|
ecacb13edf | ||
|
|
3bf7d2557c | ||
|
|
df8d9ff1ef | ||
|
|
10564d779c | ||
|
|
b64f41dc6b | ||
|
|
cddf178691 | ||
|
|
67083c4ab4 | ||
|
|
063a97a7d0 | ||
|
|
3920ab6523 | ||
|
|
406c8ef73c | ||
|
|
8651b12aa6 | ||
|
|
3bc76dc1bb | ||
|
|
71d96711bd | ||
|
|
96966f447c | ||
|
|
4efe0b0e53 | ||
|
|
6f48560b97 | ||
|
|
bdb3d1847e | ||
|
|
f2cb3f4442 | ||
|
|
3df0e75b3f | ||
|
|
0afc1b9dd5 | ||
|
|
8e1a3b1184 | ||
|
|
854c2aa507 | ||
|
|
30282db3d5 | ||
|
|
6c9f034d29 | ||
|
|
d19c85ebde | ||
|
|
dfa0414918 | ||
|
|
30a4b1b745 | ||
|
|
ebbe691ecc | ||
|
|
ec9495cd41 | ||
|
|
c736b6244a | ||
|
|
ec4bd3cd91 | ||
|
|
d685b60f45 | ||
|
|
01f98c52c9 | ||
|
|
89af5bba92 | ||
|
|
f3edc9b7eb | ||
|
|
8ec904fac2 | ||
|
|
1d10770ed5 | ||
|
|
01f738b2b3 | ||
|
|
dc0b80097b | ||
|
|
ee283c2e1b | ||
|
|
d1f4dfbb71 | ||
|
|
28603606d6 | ||
|
|
0e06579c71 | ||
|
|
89afb954da | ||
|
|
01899c924a | ||
|
|
41453f0f97 | ||
|
|
dd12c2574f | ||
|
|
f7087bb8c7 | ||
|
|
16ce80d9ee | ||
|
|
02f85d54d0 | ||
|
|
c80da485c9 | ||
|
|
38e95765a3 | ||
|
|
1141ca1ef9 | ||
|
|
f0b1a32208 | ||
|
|
28dda87cfb | ||
|
|
f5be820ad5 | ||
|
|
8820cbe1b1 | ||
|
|
11293bb304 | ||
|
|
5dcf58e7dd | ||
|
|
91d345c7fb | ||
|
|
dc4c8bafc2 | ||
|
|
98287d382b | ||
|
|
fbaa28712d | ||
|
|
84a5b3f99f | ||
|
|
4ebffa9cfb | ||
|
|
ed33a61be7 | ||
|
|
99eb4bf546 | ||
|
|
0745796112 | ||
|
|
ebcf8b4b61 | ||
|
|
01f11f1ad0 | ||
|
|
df1537cd0c | ||
|
|
b370f1c242 | ||
|
|
c71de4a811 | ||
|
|
30e8ff5884 | ||
|
|
454eba7e5e | ||
|
|
8305d28285 | ||
|
|
cf4731761d | ||
|
|
bd81dfd51b | ||
|
|
e5a41d343b | ||
|
|
97c7eacf69 | ||
|
|
d1ceed52f2 | ||
|
|
6aef44ea9b | ||
|
|
fbf0aa29a3 | ||
|
|
8a9c147952 | ||
|
|
ac30cad2ed | ||
|
|
1ae87be0ac | ||
|
|
b93ebe260b | ||
|
|
7160fadf56 | ||
|
|
f06a0e93b7 | ||
|
|
7a54b81daf | ||
|
|
bd50a960ec | ||
|
|
64d3e07dd2 | ||
|
|
9401cea337 | ||
|
|
99c15dfe30 | ||
|
|
ce43197f45 | ||
|
|
047e533140 | ||
|
|
8c70ba4f00 | ||
|
|
a3760e2082 | ||
|
|
00f9133ae3 | ||
|
|
184dcd5b97 | ||
|
|
66163d3945 | ||
|
|
8bdfd3ea51 | ||
|
|
0689c0f91a | ||
|
|
7baea620ec | ||
|
|
a14dbdfb9c | ||
|
|
7c706a045b | ||
|
|
c346df2802 | ||
|
|
27ccd1582d | ||
|
|
7c3d1f919c | ||
|
|
3f398d1016 | ||
|
|
c6b9c83194 | ||
|
|
16843b0260 | ||
|
|
61cba7f7f7 | ||
|
|
2fb2b24201 | ||
|
|
9c838d993c | ||
|
|
0e1451bcd2 | ||
|
|
0c3299f631 | ||
|
|
c07da46687 | ||
|
|
f81fc0b77b | ||
|
|
ee67f14abd | ||
|
|
e5c76f17f6 | ||
|
|
546b14bed3 | ||
|
|
c4523c6040 | ||
|
|
072d786a14 | ||
|
|
2703fead62 | ||
|
|
c3922b7f3b | ||
|
|
ac1abfa6c3 | ||
|
|
40b8dd2869 | ||
|
|
578a4815ff | ||
|
|
68db860632 | ||
|
|
a804d28cef | ||
|
|
81a0b6345e | ||
|
|
3568f7c38d | ||
|
|
7ba3ca8af4 | ||
|
|
17b4588e03 | ||
|
|
0c7040bab0 | ||
|
|
cab73a2760 | ||
|
|
0b7165a05e | ||
|
|
792981e80f | ||
|
|
d9faf65cb5 | ||
|
|
11b83611ba | ||
|
|
3a2674270b | ||
|
|
a3d9850ae4 | ||
|
|
edb39ef5d8 | ||
|
|
e63d02dbb8 | ||
|
|
81104955be | ||
|
|
8f30e41569 | ||
|
|
1d49d924fe | ||
|
|
b24d674d6a | ||
|
|
5779233ec1 | ||
|
|
8c768bb802 | ||
|
|
bc51e940da | ||
|
|
1793cecba3 | ||
|
|
17dcae26d4 | ||
|
|
1858923fec | ||
|
|
2a392a4b98 | ||
|
|
a6ce979c65 | ||
|
|
ed3659afe6 | ||
|
|
4abb86d20b | ||
|
|
e762a9a87b | ||
|
|
85fe1dbc92 | ||
|
|
8489b6c3b6 | ||
|
|
d7e070db29 | ||
|
|
8bca63207f | ||
|
|
358e5721fe | ||
|
|
807b7ed64d | ||
|
|
89bc51cace | ||
|
|
f3b90dfa4c | ||
|
|
79894a4580 | ||
|
|
2a98ed289a | ||
|
|
e9f64893ac | ||
|
|
caa0653bfe | ||
|
|
bcb5366e68 | ||
|
|
b1158f5f60 | ||
|
|
a400700c49 | ||
|
|
b571fd47c9 | ||
|
|
8b952700ef | ||
|
|
23579fc961 | ||
|
|
76b388bb75 | ||
|
|
0c7d3eaee4 | ||
|
|
3986be824a | ||
|
|
ba7b94d4e5 | ||
|
|
e1520fdd48 | ||
|
|
8d20d4ba45 | ||
|
|
723c52bcf5 | ||
|
|
6e3490b985 | ||
|
|
81bfe4cc1b | ||
|
|
653cd5bb97 | ||
|
|
910c8e61e2 | ||
|
|
72a41b6d14 | ||
|
|
66303b874d | ||
|
|
65d1d7932c | ||
|
|
cfad5f2223 | ||
|
|
b47ff7b8c8 | ||
|
|
e5704ad7f2 | ||
|
|
729eeaba54 | ||
|
|
e5da615f25 | ||
|
|
6c41215c19 | ||
|
|
0b5d47b559 | ||
|
|
7eba12fb54 | ||
|
|
c0495af6e1 | ||
|
|
d04f1930d1 | ||
|
|
852eaf8fc9 | ||
|
|
9ce866a484 | ||
|
|
517e3d9f11 | ||
|
|
8f09187cba | ||
|
|
85c139d7b7 | ||
|
|
2c1aeae4e3 | ||
|
|
9d098e087f | ||
|
|
afb2d7f798 | ||
|
|
cb43510264 | ||
|
|
b78d6684bf | ||
|
|
a83ddcc563 | ||
|
|
c02eff7d9d | ||
|
|
c6c7d1177e | ||
|
|
b6c1bf5568 | ||
|
|
1b8de9ca51 | ||
|
|
c3199c3ea2 | ||
|
|
0e1ac637ac | ||
|
|
0975f022c5 | ||
|
|
93656b57db | ||
|
|
eab01d27dd | ||
|
|
435aafe744 | ||
|
|
b6dc071e35 | ||
|
|
df7872e3f0 | ||
|
|
fcd0e77ba8 | ||
|
|
f2f3f34859 | ||
|
|
69d2a50e2e | ||
|
|
2c51c4e23e | ||
|
|
581f1eb5db | ||
|
|
95bb5a5b48 | ||
|
|
9d56c142ad | ||
|
|
0aec0c5019 | ||
|
|
fae611801e | ||
|
|
7e0e2fcf9f | ||
|
|
955c461e1c | ||
|
|
2c6616ef05 | ||
|
|
3202e0fbba | ||
|
|
84b83560b4 | ||
|
|
7a61ff27bf | ||
|
|
d930fdd86d | ||
|
|
80d7e57441 | ||
|
|
a9fa5d9465 | ||
|
|
e5028b2980 | ||
|
|
f0d7922c40 | ||
|
|
8aeadf5fdc | ||
|
|
680c01b121 | ||
|
|
c08679e6c0 | ||
|
|
955ed436a1 | ||
|
|
157a7d3946 | ||
|
|
a4ad40ab4a | ||
|
|
298045a822 | ||
|
|
853ffee425 | ||
|
|
8e979cacc1 | ||
|
|
3b14454efe | ||
|
|
799050d650 | ||
|
|
7664dc719d | ||
|
|
bcc93577df | ||
|
|
a3cd8b5e03 | ||
|
|
24999bd690 | ||
|
|
b2c3d32b51 | ||
|
|
28280c4faf | ||
|
|
e0a4b0e62a | ||
|
|
033b7b9e33 | ||
|
|
fea3bd90b4 | ||
|
|
d6c6cb791f | ||
|
|
fb6a66096e | ||
|
|
cbb6862e18 | ||
|
|
a38c7d903a | ||
|
|
b6e9f80d2a | ||
|
|
de40c67ff2 | ||
|
|
1da95ba8c2 | ||
|
|
d038e4c845 | ||
|
|
d8c0622287 | ||
|
|
953c01f40f | ||
|
|
97aeb16ee1 | ||
|
|
600419c979 | ||
|
|
01918f89c4 | ||
|
|
9d4985297b | ||
|
|
c2d48fa22d | ||
|
|
5cd4ce1d8d | ||
|
|
043e8a78b5 | ||
|
|
ecf76ddb06 | ||
|
|
d93d8d7d1d | ||
|
|
abed3a87ff | ||
|
|
e7fb499f20 | ||
|
|
69e902f7b9 | ||
|
|
0d5aae21d7 | ||
|
|
87efa30939 | ||
|
|
3807a83701 | ||
|
|
6dbebc8e88 | ||
|
|
178953ef25 | ||
|
|
f772c65219 | ||
|
|
704ddf9311 | ||
|
|
993fedb1b1 | ||
|
|
7168b5f1e0 | ||
|
|
8fb0cbfb9e | ||
|
|
9298fbeb33 | ||
|
|
c708007d0b | ||
|
|
2b88d9775a | ||
|
|
7b056cd783 | ||
|
|
218d613ed1 | ||
|
|
921a116893 | ||
|
|
d982df14eb | ||
|
|
abf5ccfc9e | ||
|
|
d6c2c87675 | ||
|
|
1abf717fc6 | ||
|
|
adb318f735 | ||
|
|
dcf4d539e9 | ||
|
|
f84ba19f44 | ||
|
|
8bde4af2d3 | ||
|
|
ff49277c70 | ||
|
|
d04fbc72d6 | ||
|
|
bff308e8c9 | ||
|
|
6ca6f97237 | ||
|
|
7b8d9cfff9 | ||
|
|
a842ea4105 | ||
|
|
97fea4bad0 | ||
|
|
2b39193d48 | ||
|
|
5bef6dfff6 | ||
|
|
6062346802 | ||
|
|
e0516db95c | ||
|
|
3287ec7c75 | ||
|
|
6359d50427 | ||
|
|
22744c65c5 | ||
|
|
5fb534e31b | ||
|
|
e39e1806ec | ||
|
|
d30c1615ca | ||
|
|
1c752ef851 | ||
|
|
7cbcdbc43c | ||
|
|
0fcd253304 | ||
|
|
ee9528cfa6 | ||
|
|
be03425493 | ||
|
|
60206d37fc | ||
|
|
7a7719d10e | ||
|
|
67e43d1fd7 | ||
|
|
c496d0bc1c | ||
|
|
350a814e95 | ||
|
|
91da2b0c5b | ||
|
|
e7a589a524 | ||
|
|
bd943a5eeb | ||
|
|
dafd42d2e8 | ||
|
|
3e8f59a75c | ||
|
|
a522817e1f | ||
|
|
dc4065b68b | ||
|
|
a51633f9da | ||
|
|
402b17bec2 | ||
|
|
32c232cdbe | ||
|
|
9cf5186546 | ||
|
|
dc9e060ee5 | ||
|
|
0a271e8449 | ||
|
|
b7fc922820 | ||
|
|
413bf32059 | ||
|
|
d5ccc91d7f | ||
|
|
7dab676e68 | ||
|
|
9d9f5980d3 | ||
|
|
e0fb31082b | ||
|
|
d4bae2ec02 | ||
|
|
fdc123c60b | ||
|
|
842d3b416d | ||
|
|
c75d6dfc5b | ||
|
|
a199588e9f | ||
|
|
d34a1e379e | ||
|
|
339a34490b | ||
|
|
b16d125624 | ||
|
|
12b0229129 | ||
|
|
de6c9598ba | ||
|
|
cc94b288d7 | ||
|
|
6795490c6a | ||
|
|
c36f7967ae | ||
|
|
7006566087 | ||
|
|
2870af12ed | ||
|
|
4d2cb43980 | ||
|
|
08397bed23 | ||
|
|
b1a5ff1206 | ||
|
|
129dc2cf22 | ||
|
|
db2176be45 | ||
|
|
176bbf7566 | ||
|
|
13c0240e55 | ||
|
|
1990bb5c87 | ||
|
|
5687972623 | ||
|
|
e43f9a3b87 | ||
|
|
e7b2f63e4d | ||
|
|
c4c94d544b | ||
|
|
b179460524 | ||
|
|
0e3291c267 | ||
|
|
8d901ea47f | ||
|
|
b5579e9e54 | ||
|
|
7b0eceb68a | ||
|
|
e9c4415255 | ||
|
|
64e1cfb9d1 | ||
|
|
0a3fefb3ab | ||
|
|
7de9e6c348 | ||
|
|
3472f88614 | ||
|
|
e58207edf0 | ||
|
|
54402f6602 | ||
|
|
28c2060dd0 | ||
|
|
06ac881ea8 | ||
|
|
4350dad6ca | ||
|
|
c7443c7c2d | ||
|
|
a22898c92b | ||
|
|
39dbb175b9 | ||
|
|
ef22cee7a0 | ||
|
|
27e9f13529 | ||
|
|
158927eb5f | ||
|
|
f6966c07af | ||
|
|
7f9972a43b | ||
|
|
1b10c4e030 | ||
|
|
6c4b157002 | ||
|
|
0230678f60 | ||
|
|
5cf4ea6045 | ||
|
|
13062d1ba0 | ||
|
|
4ce3134b14 | ||
|
|
e18842ac85 | ||
|
|
2a87ab3bf4 | ||
|
|
e0534180ba | ||
|
|
eaaba91dd2 | ||
|
|
15d3510256 | ||
|
|
7847ed2c93 | ||
|
|
aaae999e3e | ||
|
|
77d1d82a89 | ||
|
|
fb324be411 | ||
|
|
d3b5a45c4c | ||
|
|
0d43ed56ba | ||
|
|
391887f09d | ||
|
|
630e2131b8 | ||
|
|
a73368eb2c | ||
|
|
920a7d0346 | ||
|
|
8ff5a2870f | ||
|
|
cf306ffaeb | ||
|
|
9702bdf7e5 | ||
|
|
7f4e2c0675 | ||
|
|
9a3777dde9 | ||
|
|
964cff4e75 | ||
|
|
97398cb1f6 | ||
|
|
c1d6a3f19e | ||
|
|
cd507fc16d | ||
|
|
b07f22de1f | ||
|
|
b12efc747b | ||
|
|
505c95f23b | ||
|
|
ff2f9a084e | ||
|
|
272bdc559c | ||
|
|
995764bd31 | ||
|
|
7b483aa6e5 | ||
|
|
8b3267a444 | ||
|
|
262e344ac3 | ||
|
|
3676754e61 | ||
|
|
e8800e61b8 | ||
|
|
b58d43d19a | ||
|
|
dc6f85134d | ||
|
|
10a022c0ae | ||
|
|
f8c2a15174 | ||
|
|
5384408a63 | ||
|
|
71ea7517a7 | ||
|
|
306aabe4ea | ||
|
|
21b15495da | ||
|
|
96c2a4885a | ||
|
|
6e992b3a8b | ||
|
|
4d17441d44 | ||
|
|
41f83bb782 | ||
|
|
80fbdf2afe | ||
|
|
a0477ff19d | ||
|
|
73e6a19070 | ||
|
|
1811f4e42f | ||
|
|
177d4b43b2 | ||
|
|
c86a387a17 | ||
|
|
c8c1bb2a47 | ||
|
|
45f4468736 | ||
|
|
43fe6e522b | ||
|
|
b731667227 | ||
|
|
302a93121a | ||
|
|
212872b353 | ||
|
|
1d894d390b | ||
|
|
9b3611b287 | ||
|
|
de8c4dbc02 | ||
|
|
e8c3370f35 | ||
|
|
c37809e629 | ||
|
|
376b69eef1 | ||
|
|
92cde1ab5f | ||
|
|
f722c70859 | ||
|
|
ed1194be9d | ||
|
|
ef0c49d853 | ||
|
|
44ad141311 | ||
|
|
28e8fda73b | ||
|
|
44c6d5e7e6 | ||
|
|
6a8734ad4f | ||
|
|
91cd49c655 | ||
|
|
cb7256eba9 | ||
|
|
82fe2012eb | ||
|
|
26d9c43c7a | ||
|
|
a88061f8bf | ||
|
|
a92372c236 | ||
|
|
f4a33e75bd | ||
|
|
7c8b92e588 | ||
|
|
cd29e81357 | ||
|
|
da85372764 | ||
|
|
5b7a4d13ca | ||
|
|
86a553c697 | ||
|
|
769d814a6a | ||
|
|
51b076831a | ||
|
|
316a861269 | ||
|
|
d88eb8054b | ||
|
|
7d3387b095 | ||
|
|
f3059ca516 | ||
|
|
ae94f3390f | ||
|
|
5b3ad47604 | ||
|
|
e5bda20934 | ||
|
|
a6bde81c24 | ||
|
|
d1f74be5d5 | ||
|
|
8f3a5ca899 | ||
|
|
e5826116c1 | ||
|
|
a3bbe22c4d | ||
|
|
d850fa30bc | ||
|
|
ae9aa435db | ||
|
|
5ab73e5ff8 | ||
|
|
663afa1332 | ||
|
|
d343d53c36 | ||
|
|
c22193831e | ||
|
|
ac99059cd1 | ||
|
|
ecf1e6780f | ||
|
|
c3cdc2e859 | ||
|
|
b5e675774e | ||
|
|
5f116f84a2 | ||
|
|
e16f723dd0 | ||
|
|
c392ca42b9 | ||
|
|
3b5f77d70d | ||
|
|
5a44065b48 | ||
|
|
3c030ea40d | ||
|
|
00d9c04d22 | ||
|
|
7502a9418d | ||
|
|
ecbf78e517 | ||
|
|
024e9d6291 | ||
|
|
d7f607aaa4 | ||
|
|
bd5b448d38 | ||
|
|
10ee5827b9 | ||
|
|
bc0e86f2de | ||
|
|
6584bcb6d5 | ||
|
|
adc3dee346 | ||
|
|
8f3027c10a | ||
|
|
7f542aef0c | ||
|
|
bb213672f7 | ||
|
|
c0bdd69f42 | ||
|
|
05d96f2adf | ||
|
|
702f18b133 | ||
|
|
ffb2ca218f | ||
|
|
cdcc69a881 | ||
|
|
cdcafdb724 | ||
|
|
ec7175267e | ||
|
|
64d58681ea | ||
|
|
7355dcb205 | ||
|
|
82afbb191c | ||
|
|
62d586fc60 | ||
|
|
227a65b4c3 | ||
|
|
9e28ed1733 | ||
|
|
95471502d7 | ||
|
|
b00207e894 | ||
|
|
e508592575 | ||
|
|
d911030e19 | ||
|
|
b69a074909 | ||
|
|
5639e84185 | ||
|
|
406de53d91 | ||
|
|
6c6abcd25a | ||
|
|
32ea5ee333 | ||
|
|
4f8e7d9899 | ||
|
|
331441e450 | ||
|
|
1ab88ddc70 | ||
|
|
57733d7f69 | ||
|
|
f99105089a | ||
|
|
649d57c9d3 | ||
|
|
2e61d61460 | ||
|
|
f92d060e06 | ||
|
|
242948948b | ||
|
|
ddd2f3a7da | ||
|
|
aa7ac703b4 | ||
|
|
f91fdd322e | ||
|
|
e39818e9d1 | ||
|
|
e62f24cc8e | ||
|
|
dc20f7f5f0 | ||
|
|
f6fa3f1a0b | ||
|
|
60ae096737 | ||
|
|
fc0ad5ba69 | ||
|
|
8ae1aa6d8c | ||
|
|
0e774b253c | ||
|
|
a853005c4d | ||
|
|
19b0491590 | ||
|
|
dd153fb261 | ||
|
|
87ef9d3f67 | ||
|
|
fb24ea7fef | ||
|
|
fd5b6a249b | ||
|
|
287db84d6d | ||
|
|
6c59af0c91 | ||
|
|
8072d96785 | ||
|
|
7a552e7faf | ||
|
|
21bef13eff | ||
|
|
379d09248d | ||
|
|
31e356de22 | ||
|
|
58afb75fd5 | ||
|
|
f6cf333457 | ||
|
|
5e71c0b886 | ||
|
|
7fb146dea4 | ||
|
|
669c87149f | ||
|
|
9c2a82ea90 | ||
|
|
1e74f24e1c | ||
|
|
e82b011f20 | ||
|
|
09211031ac | ||
|
|
7a877b0c45 | ||
|
|
814e17842f | ||
|
|
5340619a96 | ||
|
|
9e65220253 | ||
|
|
3cd58f18cc | ||
|
|
36a51d0a77 | ||
|
|
52ae39fa32 | ||
|
|
139c5a7d6e | ||
|
|
28fa1ed6f9 | ||
|
|
116b9c4e70 | ||
|
|
e728729917 | ||
|
|
ed1c6c4cbb | ||
|
|
84f10fa947 | ||
|
|
6c2439841d | ||
|
|
428071241f | ||
|
|
8c651abc6d | ||
|
|
5a1a0af706 | ||
|
|
a79b121895 | ||
|
|
f859973f32 | ||
|
|
a9706e0d73 | ||
|
|
9953e9ee9b | ||
|
|
0b680a8f67 | ||
|
|
ef3e1681f9 | ||
|
|
e28995fa4e | ||
|
|
aee1acab41 | ||
|
|
0c7aa209b5 | ||
|
|
827d2768d6 | ||
|
|
60e4467f88 | ||
|
|
81950e5334 | ||
|
|
d8c7ebb2d6 | ||
|
|
5de90c7a9c | ||
|
|
5d7e5772a8 | ||
|
|
0f886bbdf1 | ||
|
|
2275c00b9f | ||
|
|
00c6f60f2e | ||
|
|
6fd65dddc8 | ||
|
|
4c7577bf1c | ||
|
|
d162e82d20 | ||
|
|
49f95c3d05 | ||
|
|
f361dbd5e7 | ||
|
|
bce4779702 | ||
|
|
a715e0a659 | ||
|
|
f288578904 | ||
|
|
1231fc226c | ||
|
|
1d189552b2 | ||
|
|
ce4d398492 | ||
|
|
b553bc34bf | ||
|
|
ddb3e69af8 | ||
|
|
fc6a687322 | ||
|
|
d7c553457c | ||
|
|
2a82271322 | ||
|
|
a2b454ccb6 | ||
|
|
cb17e5b375 | ||
|
|
c54cb80862 | ||
|
|
bf1d366ce7 | ||
|
|
346319892c | ||
|
|
060a1ccfbb | ||
|
|
74a8169050 | ||
|
|
15bb04abd1 | ||
|
|
51b2ffd607 | ||
|
|
091c4b81f9 | ||
|
|
c68554a42c | ||
|
|
10de78cd1a | ||
|
|
6bd995e445 | ||
|
|
087e0e3750 | ||
|
|
c3f5c269aa | ||
|
|
4ef1ac4703 | ||
|
|
b9c58a99a5 | ||
|
|
4bec432070 | ||
|
|
e2556a0f3d | ||
|
|
f265b9fe7b | ||
|
|
c2bf977fb6 | ||
|
|
44030e710a | ||
|
|
e0028e8079 | ||
|
|
9c14d21609 | ||
|
|
d690e1a7a5 | ||
|
|
bfacccba18 | ||
|
|
8b93d6ce3a | ||
|
|
69d12b567d | ||
|
|
4fbede4cb2 | ||
|
|
e758208a17 | ||
|
|
a5f04ddb5f | ||
|
|
48913ed4bf | ||
|
|
a8e8d4b109 | ||
|
|
3a968d1914 | ||
|
|
58f4ad8e5a | ||
|
|
549d681fab | ||
|
|
5313770972 | ||
|
|
9046c71d00 | ||
|
|
87a71c7389 | ||
|
|
834bab34ab | ||
|
|
a04593f02d | ||
|
|
f7456c22f9 | ||
|
|
34e5487f75 | ||
|
|
a49e91f18e | ||
|
|
ff55ae40f9 | ||
|
|
3bdc11c5c4 | ||
|
|
2cd976f5b9 | ||
|
|
cc306932e8 | ||
|
|
d3927168b2 | ||
|
|
96ede99d63 | ||
|
|
86e90969e3 | ||
|
|
99024c3111 | ||
|
|
93777c899c | ||
|
|
d4bf893482 | ||
|
|
9da34a4fff | ||
|
|
f7e6238928 | ||
|
|
9192b863ea | ||
|
|
0ef4d4e6b1 | ||
|
|
af22e1abc3 | ||
|
|
b9e6f56110 | ||
|
|
d8454fab29 | ||
|
|
8abeee9d23 | ||
|
|
1164e33371 | ||
|
|
15a65a071e | ||
|
|
ecddbb5992 | ||
|
|
4dbf7ac1da | ||
|
|
f071d28911 | ||
|
|
16e834d0f6 | ||
|
|
881711bb11 | ||
|
|
6961bbb4a7 | ||
|
|
591f9d9dde | ||
|
|
d942f2c606 | ||
|
|
01819a7f72 | ||
|
|
c8969996c7 | ||
|
|
0bb0ade1ec | ||
|
|
52c338366b | ||
|
|
0dae8c3786 | ||
|
|
cbbe02096f | ||
|
|
fae6a213ac | ||
|
|
5e57b31c45 | ||
|
|
eb5437892d | ||
|
|
12e2a84ad1 | ||
|
|
0b11d79816 | ||
|
|
56fffd6b9c | ||
|
|
0c28e45434 | ||
|
|
72f48f9230 | ||
|
|
787810e8ab | ||
|
|
15f2cd62e6 | ||
|
|
6153f47f95 | ||
|
|
1ec4f0f0da | ||
|
|
c0e5dfae7f | ||
|
|
d3766ede6c | ||
|
|
f03743634f | ||
|
|
5419eb07d2 | ||
|
|
34c0b3bb9e | ||
|
|
d664b70bf6 | ||
|
|
dd674c2d93 | ||
|
|
19ff43afe2 | ||
|
|
2f80620644 | ||
|
|
67555eed9f | ||
|
|
8e7738a153 | ||
|
|
5ca4dabf49 | ||
|
|
e6042743cb | ||
|
|
7353a6bfe7 | ||
|
|
deef704d42 | ||
|
|
a1e93540c5 | ||
|
|
d37e6944f5 | ||
|
|
794c6f09b4 | ||
|
|
39f2dab3f2 | ||
|
|
a53706b95b | ||
|
|
53e13bc58c | ||
|
|
9ed7feed87 | ||
|
|
4b05713ae7 | ||
|
|
08a31cccad | ||
|
|
5ed51849bb | ||
|
|
677c712117 | ||
|
|
04fb03e1f4 | ||
|
|
d6cddef202 | ||
|
|
c4a417a4b0 | ||
|
|
8e6d97453d | ||
|
|
60d606e0fb | ||
|
|
5c1afe5b78 | ||
|
|
aefcd070d6 | ||
|
|
2a8316d7a1 | ||
|
|
cf16fa7a6f | ||
|
|
ee58c5e429 | ||
|
|
a17b91452c | ||
|
|
185fd76b46 | ||
|
|
07eb27b1dd | ||
|
|
548ae9605b | ||
|
|
a4f4add21b | ||
|
|
fe8f39cd5a | ||
|
|
77626b51b0 | ||
|
|
d10ca5330e | ||
|
|
c2e77a5fbe | ||
|
|
93b9aa8312 | ||
|
|
937ad7c0fc | ||
|
|
cb6d5bdc36 | ||
|
|
df3d450671 | ||
|
|
16951b9c31 | ||
|
|
cd9149efad | ||
|
|
c4965c9c05 | ||
|
|
d439066686 | ||
|
|
826aeb477e | ||
|
|
63b776f97d | ||
|
|
a7383806cd | ||
|
|
81d15db29c | ||
|
|
07bf2de658 | ||
|
|
5c94394a6b | ||
|
|
224a40f7b4 | ||
|
|
f7bc58530b | ||
|
|
c11bf82271 | ||
|
|
4bf446929a | ||
|
|
85c916aa6d | ||
|
|
a142950c90 | ||
|
|
0f28109363 | ||
|
|
e2c593662d | ||
|
|
749713615c | ||
|
|
e6ff986010 | ||
|
|
7f8869cdae | ||
|
|
9a5658fa23 | ||
|
|
9874a26de2 | ||
|
|
ee54c28426 | ||
|
|
71d8a2ac30 | ||
|
|
b35cc044b4 | ||
|
|
8d80e4d38f | ||
|
|
55afb62ba0 | ||
|
|
07a8753149 | ||
|
|
5d3027c777 | ||
|
|
8c2421018a | ||
|
|
a4f7d4650b | ||
|
|
ab92e503bc | ||
|
|
f0f3560789 | ||
|
|
a7577d8975 | ||
|
|
243e034156 | ||
|
|
ea242d4e4d | ||
|
|
2c154d09e6 | ||
|
|
62166c5465 | ||
|
|
89264fa175 | ||
|
|
6091b22937 | ||
|
|
e0f2f11174 | ||
|
|
1df0c1472f | ||
|
|
cc5348a282 | ||
|
|
d18a1b6788 | ||
|
|
8553a5c00f | ||
|
|
67d2e0fe01 | ||
|
|
423c7e7f7a | ||
|
|
ff6a0e67da | ||
|
|
65f8a28962 | ||
|
|
ccd154cfa5 | ||
|
|
7b987fa396 | ||
|
|
3f4a439de4 | ||
|
|
a1cc37d3a6 | ||
|
|
8af85b8883 | ||
|
|
55b69db576 | ||
|
|
07f2cc555e | ||
|
|
6b6383c237 | ||
|
|
03344e0df5 | ||
|
|
75ed0c7a18 | ||
|
|
0d076595f8 | ||
|
|
1ba2d5ab89 | ||
|
|
ec6533707f | ||
|
|
f868713ed9 | ||
|
|
1ef8245cf9 | ||
|
|
0385a0b715 | ||
|
|
5dd35e99e2 | ||
|
|
43dd5bf8c7 | ||
|
|
98ea973e61 | ||
|
|
f7d0cc8dbd | ||
|
|
0afb94dc77 | ||
|
|
3835cc0bc9 | ||
|
|
7b766ea7f1 | ||
|
|
4efacdaee5 | ||
|
|
fb91a7f70f | ||
|
|
47f47ac097 | ||
|
|
b4cb466f4e | ||
|
|
9a1cd147d0 | ||
|
|
c67e429387 | ||
|
|
a5e6d08394 | ||
|
|
a37729d885 | ||
|
|
2efa706f67 | ||
|
|
1911881b94 | ||
|
|
8c9f390b89 | ||
|
|
9dacae709b | ||
|
|
363fb57b3e | ||
|
|
99ed84be4d | ||
|
|
930611301b | ||
|
|
e06e0a6599 | ||
|
|
9de5fe3362 | ||
|
|
c9fded45b7 | ||
|
|
545a54eb9f | ||
|
|
b979bf4891 | ||
|
|
d2111b2bad | ||
|
|
ffb839b1d0 | ||
|
|
360e48a3cf | ||
|
|
71198a83de | ||
|
|
87eb713593 | ||
|
|
5fbc3e9efb | ||
|
|
6140efcb5a | ||
|
|
108c98c8bb | ||
|
|
887fb46dbd | ||
|
|
1b65330af4 | ||
|
|
cf709c995f | ||
|
|
6a1b7d91a1 | ||
|
|
a1bbf877a1 | ||
|
|
ac24516ec0 | ||
|
|
aab79b15f1 | ||
|
|
39fd5323b0 | ||
|
|
ba6f732628 | ||
|
|
ada4e7cfd5 | ||
|
|
c9d73a6bcb | ||
|
|
e91fc5169c | ||
|
|
452b1e548a | ||
|
|
630c3ec7ba | ||
|
|
c808bb188d | ||
|
|
dce4728377 | ||
|
|
38d77bcf5c | ||
|
|
e99cdc434f | ||
|
|
225bf15ae7 | ||
|
|
dd69c0b4b1 | ||
|
|
cc7d076dc8 | ||
|
|
1d1c621821 | ||
|
|
d70db5ef94 | ||
|
|
656ead95cb | ||
|
|
d13ee35789 | ||
|
|
0534b9c616 | ||
|
|
db3147076e | ||
|
|
3c67fbf70b | ||
|
|
49d6c61a8a | ||
|
|
549746bffd | ||
|
|
bc73d859a2 | ||
|
|
998ea1fa85 | ||
|
|
020606132e | ||
|
|
d693cb2fbb | ||
|
|
9cf572e22e | ||
|
|
1759f36740 | ||
|
|
c3666a7b40 | ||
|
|
c691dd210a | ||
|
|
d3c5f0d78a | ||
|
|
62dc66831a | ||
|
|
1ba9025809 | ||
|
|
da2a5a6a9d | ||
|
|
da9bd48dd5 | ||
|
|
56a49d4628 | ||
|
|
152a15d147 | ||
|
|
47f938f0fd | ||
|
|
56f653c84b | ||
|
|
5527f66c11 | ||
|
|
aadc11e7f4 | ||
|
|
15e7f35459 | ||
|
|
8569ef77fc | ||
|
|
e3c1e47040 | ||
|
|
c722f70f10 | ||
|
|
e6a6703b73 | ||
|
|
dddd927d30 | ||
|
|
f9a31cd9dc | ||
|
|
abeedffa94 | ||
|
|
bda286a27d | ||
|
|
3039f3725e | ||
|
|
21d63db2f8 | ||
|
|
6ec7d8c06b | ||
|
|
09949f6823 | ||
|
|
e870ac2161 | ||
|
|
2415a92f08 | ||
|
|
f3be07599e | ||
|
|
2593f9d472 | ||
|
|
7d8396f21c | ||
|
|
84c8f673c5 | ||
|
|
e3ed5f9581 | ||
|
|
e904e57bc8 | ||
|
|
3fcb150330 | ||
|
|
928cde7e3c | ||
|
|
f2aa11ba83 | ||
|
|
dd18b4ff9a | ||
|
|
875ed0fc12 | ||
|
|
affdd43f7a | ||
|
|
9de9248d5a | ||
|
|
31a89052f8 | ||
|
|
0248cd1e38 | ||
|
|
6f21f9bb4b | ||
|
|
0f87f89b71 | ||
|
|
ab65dba802 | ||
|
|
6c40e135e9 | ||
|
|
893deb57d0 | ||
|
|
c3b450a679 | ||
|
|
62573f47dc | ||
|
|
71bf9943b7 | ||
|
|
d0fe5d68e3 | ||
|
|
612ea61b0e | ||
|
|
53b6001a51 | ||
|
|
ad8cee56df | ||
|
|
ae8c079e8c | ||
|
|
68d1b91701 | ||
|
|
3389378868 | ||
|
|
6a6c123a63 | ||
|
|
64c0fa39a0 | ||
|
|
c19fd6cd11 | ||
|
|
6dd17390d7 | ||
|
|
59e724dcf2 | ||
|
|
cc71eb3ef5 | ||
|
|
d4ac43a3bf | ||
|
|
56fa7db0a7 | ||
|
|
1b58259562 | ||
|
|
23d564116c | ||
|
|
a5aeba560e | ||
|
|
58688bd436 | ||
|
|
3682edfe7b | ||
|
|
feb1932e25 | ||
|
|
696dc1f798 | ||
|
|
4ad3a464fe | ||
|
|
b75f473a5a | ||
|
|
26023599c1 | ||
|
|
5f276201b3 | ||
|
|
f9072e9a21 | ||
|
|
3638e0efa2 | ||
|
|
fa613814d5 | ||
|
|
9b673e44dc | ||
|
|
44f0bc818e | ||
|
|
5d64b987aa | ||
|
|
da4f911bd9 | ||
|
|
8c0ae77797 | ||
|
|
613656d485 | ||
|
|
570f421c3d | ||
|
|
1c538249ea | ||
|
|
2b94cae86b | ||
|
|
c2d92def50 | ||
|
|
32628e4165 | ||
|
|
2501484ac2 | ||
|
|
87b565d552 | ||
|
|
56af686410 | ||
|
|
90fd7508b6 | ||
|
|
5f8cbe5393 | ||
|
|
94433b4502 | ||
|
|
e311e64900 | ||
|
|
973b11e33b | ||
|
|
fd3f544210 | ||
|
|
078bcd16c1 | ||
|
|
4c5073ad03 | ||
|
|
2660d8ad2e | ||
|
|
588478e981 | ||
|
|
0f9326cff6 | ||
|
|
e01fc47ab6 | ||
|
|
a35893a722 | ||
|
|
f372cd51b6 | ||
|
|
4c227280fb | ||
|
|
13d8a7a607 | ||
|
|
8f9afae970 | ||
|
|
079abea853 | ||
|
|
83fb67c9a2 | ||
|
|
2391836769 | ||
|
|
d275e37d3b | ||
|
|
773dc75531 | ||
|
|
a9dbead1b3 | ||
|
|
dd4d6e3d94 | ||
|
|
105fbe6b1f | ||
|
|
242a030470 | ||
|
|
7babfc6995 | ||
|
|
b29e32fcb7 | ||
|
|
dcd2fb51c7 | ||
|
|
69d07fe12b | ||
|
|
e4acdd529b | ||
|
|
5c375c19fc | ||
|
|
d00a3d313e | ||
|
|
d8e1e75dd1 | ||
|
|
c1dae8f69f | ||
|
|
64f08670b5 | ||
|
|
4890420a25 | ||
|
|
5c94741584 | ||
|
|
9934ee03c6 | ||
|
|
63a2edb417 | ||
|
|
9a9bef4935 | ||
|
|
0078265697 | ||
|
|
3a7d8b1c51 | ||
|
|
30bfe70fb3 | ||
|
|
243642c35e | ||
|
|
63201030d2 | ||
|
|
ff96e85487 | ||
|
|
da24d924a3 | ||
|
|
7fce1eda88 | ||
|
|
c79ff0f80f | ||
|
|
3aa34e53bc | ||
|
|
fd632de0d9 | ||
|
|
2df2eb0b9e | ||
|
|
2cc92999a6 | ||
|
|
f0bf41c302 | ||
|
|
6972d6d283 | ||
|
|
88a2fa13f2 | ||
|
|
1756adc4b8 | ||
|
|
4187ed6f9d | ||
|
|
ed3c62e3c9 | ||
|
|
4bf4158244 | ||
|
|
4c95640376 | ||
|
|
7142dd0632 | ||
|
|
68f6cbc200 | ||
|
|
68d3ed8556 | ||
|
|
e901bc12ba | ||
|
|
dfc004dc6e | ||
|
|
c6d3812b92 | ||
|
|
574c79ae92 | ||
|
|
8b4f3f97f2 | ||
|
|
69ae0f7bf0 | ||
|
|
28c321f158 | ||
|
|
02d7c0f529 | ||
|
|
88c28dc57f | ||
|
|
b2e2441e7b | ||
|
|
d8f85e7acb | ||
|
|
c8cb95b3ed | ||
|
|
1b44b25ebd | ||
|
|
3f23c85333 | ||
|
|
6bfe20624c | ||
|
|
a03eb1aa6a | ||
|
|
d7e50ff2ab | ||
|
|
9d46a90f65 | ||
|
|
ea6d08a7e5 | ||
|
|
b8ddd40178 | ||
|
|
de59b0b4f2 | ||
|
|
fd8e528bf2 | ||
|
|
f564df8ccc | ||
|
|
c746d2570d | ||
|
|
6f1e638de8 | ||
|
|
f5087667f1 | ||
|
|
2b35f223c1 | ||
|
|
f3e9a95442 | ||
|
|
a7f395b78a | ||
|
|
7f23d16dbe | ||
|
|
4bad4e85c4 | ||
|
|
7db0583db1 | ||
|
|
1a6bdab29e | ||
|
|
991984e134 | ||
|
|
4099551ad2 | ||
|
|
5c654616cf | ||
|
|
1b864150db | ||
|
|
6cd2562140 | ||
|
|
083e36f321 | ||
|
|
d4f8c95dea | ||
|
|
35f978ed06 | ||
|
|
6595f891c1 | ||
|
|
bdd7b77952 | ||
|
|
29f63a5b48 | ||
|
|
c904d6097c | ||
|
|
1826aeed60 | ||
|
|
e120749b02 | ||
|
|
3c46f47c36 | ||
|
|
2fa416f872 | ||
|
|
df014b142a | ||
|
|
073e41c9e3 | ||
|
|
02d5148c4d | ||
|
|
ed96a273a0 | ||
|
|
a6d4d56922 | ||
|
|
c3645ffd3e | ||
|
|
f3379af93a | ||
|
|
b86771d08f | ||
|
|
d96d43b1a4 | ||
|
|
5e69f3d66d | ||
|
|
193e74d69b | ||
|
|
cc4cb1f904 | ||
|
|
d59a76796f | ||
|
|
dff67bb214 | ||
|
|
086c29f1c8 | ||
|
|
07e7f218d2 | ||
|
|
da3facef06 | ||
|
|
c6a16aa2a6 | ||
|
|
913ea35d98 | ||
|
|
2405cdd43b | ||
|
|
8ada6569f2 | ||
|
|
0edd8400e7 | ||
|
|
e654ea7788 | ||
|
|
6735d199a0 | ||
|
|
2f06fbd258 | ||
|
|
25220fb547 | ||
|
|
30bb56e9bf | ||
|
|
e62792d397 | ||
|
|
7f81a5167b | ||
|
|
1c3cb6b72a | ||
|
|
2b0aec400a | ||
|
|
4e8f85ffc6 | ||
|
|
dd1fc7ff7d | ||
|
|
97ef5bcc7b | ||
|
|
976244d57f | ||
|
|
a019ac2c4a | ||
|
|
5fff839b53 | ||
|
|
bc21aa4590 | ||
|
|
b4a23934ef | ||
|
|
aa1e866263 | ||
|
|
677007f613 | ||
|
|
a25b0672e0 | ||
|
|
d7403f5711 | ||
|
|
e6427ae2f8 | ||
|
|
245dbaacda | ||
|
|
0c313fef05 | ||
|
|
92032fd1ac | ||
|
|
b40c4279fa | ||
|
|
874151f4d3 | ||
|
|
97f2517211 | ||
|
|
81c30ab502 | ||
|
|
9c9f230054 | ||
|
|
f5f791b0b7 | ||
|
|
6563c53a63 | ||
|
|
473ea18680 | ||
|
|
0fcabc3ab5 | ||
|
|
183a363c00 | ||
|
|
a5d9464b7e | ||
|
|
f81a48aeaa | ||
|
|
15a68f1807 | ||
|
|
a59e08e629 | ||
|
|
45129bb230 | ||
|
|
89123cee31 | ||
|
|
04676cf26b | ||
|
|
76f525ed98 | ||
|
|
9a02ad5175 | ||
|
|
fec2851814 | ||
|
|
aac0616aac | ||
|
|
adfc80948c | ||
|
|
7107087ba2 | ||
|
|
cfc2d5bb57 | ||
|
|
79f65638b1 | ||
|
|
18a28dbec3 | ||
|
|
12254b050b | ||
|
|
5db896e32a | ||
|
|
6e23e2cde5 | ||
|
|
11d02e4dc6 | ||
|
|
3a8e56603c | ||
|
|
558f56017e | ||
|
|
17e325ff16 | ||
|
|
abf7e7a8e1 | ||
|
|
e2377d482c | ||
|
|
cd9891b0ba | ||
|
|
05938b6ddd | ||
|
|
fbeaed38a1 | ||
|
|
f470be09ff | ||
|
|
e306650990 | ||
|
|
ffca576b3a | ||
|
|
de19106bb7 | ||
|
|
fd9193056a | ||
|
|
ec884b9adf | ||
|
|
9aed3b5e63 | ||
|
|
a231c9f993 | ||
|
|
bee450ea77 | ||
|
|
977d6f51f1 | ||
|
|
73c40d2b96 | ||
|
|
77d75b2256 | ||
|
|
5ef3575e54 | ||
|
|
1c873d34ea | ||
|
|
ba961a1407 | ||
|
|
d36930c8ce | ||
|
|
6d6f61ee80 | ||
|
|
9a84f43534 | ||
|
|
76070242ff | ||
|
|
8c876537e3 | ||
|
|
34edbde3e1 | ||
|
|
f24366bdf3 | ||
|
|
6840ad8afb | ||
|
|
d923e8bd28 | ||
|
|
3728f3a143 | ||
|
|
c00c03f28f | ||
|
|
3c3469efbe | ||
|
|
88f1ec5788 | ||
|
|
7a1ff2b8d1 | ||
|
|
4b0b880102 | ||
|
|
8654d2ad4b | ||
|
|
050a5d4853 | ||
|
|
07693e7c1b | ||
|
|
60c29e3107 | ||
|
|
615a104b7b | ||
|
|
ab75188733 | ||
|
|
c76daa8c81 | ||
|
|
796e985d05 | ||
|
|
9bc985e87f | ||
|
|
e85e676c65 | ||
|
|
55aa77e670 | ||
|
|
d81b7bd07b | ||
|
|
6add41b654 | ||
|
|
e5933d2938 | ||
|
|
8b4e7586ad | ||
|
|
d70c637aa4 | ||
|
|
c296cc2963 | ||
|
|
721fcb8b38 | ||
|
|
e26a9affbd | ||
|
|
f009a030a8 | ||
|
|
17ba40e8f6 | ||
|
|
495df7354d | ||
|
|
f012724dc5 | ||
|
|
ee77040781 | ||
|
|
e04a463e62 | ||
|
|
180d8d1168 | ||
|
|
2af7a8d044 | ||
|
|
5a6126270e | ||
|
|
488c89a6d1 | ||
|
|
ca5d16257a | ||
|
|
07b1902fe2 | ||
|
|
bcfe608301 | ||
|
|
63f448f4a8 | ||
|
|
5438c3c5da | ||
|
|
111ff9835a | ||
|
|
7cc4c33911 | ||
|
|
c61723b711 | ||
|
|
c065b8e819 | ||
|
|
885b7ff1eb | ||
|
|
ffd9ad17e2 | ||
|
|
051da80708 | ||
|
|
56aff208ba | ||
|
|
1c65f4f321 | ||
|
|
b2755d8586 | ||
|
|
9618a41d25 | ||
|
|
61eaa026a2 | ||
|
|
9ec67031b3 | ||
|
|
acc9158c33 | ||
|
|
827f47e4db | ||
|
|
e3eacc0ba8 | ||
|
|
ed9437058e | ||
|
|
191c284d97 | ||
|
|
dba98d50f7 | ||
|
|
7cf6c6f068 | ||
|
|
f6f20450a6 | ||
|
|
a003467b00 | ||
|
|
26b3432f9a | ||
|
|
f20c7ffb24 | ||
|
|
9a16c6d418 | ||
|
|
3033462d89 | ||
|
|
fe126b0de0 | ||
|
|
c64586ead5 | ||
|
|
63f1addeea | ||
|
|
1bbd034a73 | ||
|
|
8dd1190033 | ||
|
|
f3443ca88a | ||
|
|
ff0a886664 | ||
|
|
8ab7956b95 | ||
|
|
e261a216b3 | ||
|
|
8b6fb31b63 | ||
|
|
465b8e36fc | ||
|
|
af9f09493d | ||
|
|
127f9e867d | ||
|
|
8b493581e1 | ||
|
|
65edb4ab06 | ||
|
|
6ce65b0160 | ||
|
|
4e5eaad00d | ||
|
|
a11151fdd9 | ||
|
|
bd4bfd211b | ||
|
|
8d624c4951 | ||
|
|
f5dd4c185f | ||
|
|
8e1fc7dcb0 | ||
|
|
f8a0d6e54b | ||
|
|
2fd02bac1d | ||
|
|
8ccf13aca4 | ||
|
|
b21bc6c919 | ||
|
|
ba537e82cc | ||
|
|
0c8654a3b9 | ||
|
|
ac019660bd | ||
|
|
a3ccf301ca | ||
|
|
a4f8dfe53e | ||
|
|
853ba5bb3e | ||
|
|
a06fe38ed8 | ||
|
|
223461213e | ||
|
|
f5526d0a25 | ||
|
|
d551173c68 | ||
|
|
26a3790bbd | ||
|
|
755442556d | ||
|
|
164e9f21c9 | ||
|
|
9a5643cf43 | ||
|
|
671e8189c0 | ||
|
|
c31158a7ad | ||
|
|
9e46a57443 | ||
|
|
161cd71da8 | ||
|
|
1b6126456b | ||
|
|
f69864554a | ||
|
|
61a5751e0b | ||
|
|
78d3dfec15 | ||
|
|
f5ed3a7ff1 | ||
|
|
681041b7c3 | ||
|
|
264e1daf5c | ||
|
|
c19ee4f050 | ||
|
|
d225c215ee | ||
|
|
adcba33657 | ||
|
|
29ec062b90 | ||
|
|
4feecbd438 | ||
|
|
525f5c11b0 | ||
|
|
d9800428c0 | ||
|
|
339ff22025 | ||
|
|
4d94374162 | ||
|
|
4b1cc22250 | ||
|
|
fcdd71177b | ||
|
|
d100832548 | ||
|
|
3eb4b07880 | ||
|
|
6214cbb4e7 | ||
|
|
e183005a9f | ||
|
|
960d44942c | ||
|
|
d2aca948fb | ||
|
|
bf9b057ef3 | ||
|
|
703105b4cf | ||
|
|
99dd785dfd | ||
|
|
9f02022353 | ||
|
|
6bcd934ab3 | ||
|
|
1888c1ead8 | ||
|
|
6557ba4cd6 | ||
|
|
db998e69e3 | ||
|
|
e9d563ce03 | ||
|
|
b33a390839 | ||
|
|
53f80fbf10 | ||
|
|
96fc14c22f | ||
|
|
476a593656 | ||
|
|
dd9b7a8774 | ||
|
|
3f214bb959 | ||
|
|
f02b097ba3 | ||
|
|
431d29733d | ||
|
|
352f1d0cbc | ||
|
|
4fde49b43a | ||
|
|
a4576e43e9 | ||
|
|
6d7a8e5417 | ||
|
|
d05c0fa6e3 | ||
|
|
02b3f1d091 | ||
|
|
759a12b759 | ||
|
|
4f7c30f13a | ||
|
|
902b3bb8bc | ||
|
|
ece17326c8 | ||
|
|
497d17dafc | ||
|
|
36ef73caaa | ||
|
|
6142d82806 | ||
|
|
adf314079b | ||
|
|
036e57ac4e | ||
|
|
f2393cd8f1 | ||
|
|
ae91e016f5 | ||
|
|
1adfc0815f | ||
|
|
acdf50d88d | ||
|
|
30804d3556 | ||
|
|
5307d393f6 | ||
|
|
75a6c7479c | ||
|
|
8c20ef4ec7 | ||
|
|
98bebf3da1 | ||
|
|
4d8d09523e | ||
|
|
0b5a69bc31 | ||
|
|
641f9eaad2 | ||
|
|
269b13e868 | ||
|
|
b96a5d307f | ||
|
|
cb25e6708d | ||
|
|
60e3c70e57 | ||
|
|
e0ba2b94dd | ||
|
|
559c1996b9 | ||
|
|
33d951b0ec | ||
|
|
c270d3cf09 | ||
|
|
00a687cd4a | ||
|
|
24ecfe7f34 | ||
|
|
b5ff544f79 | ||
|
|
d3153244e4 | ||
|
|
2227c01289 | ||
|
|
f0407b8a37 | ||
|
|
62935f5016 | ||
|
|
3b7b6fd627 | ||
|
|
d68a6add62 | ||
|
|
12b6a72a48 | ||
|
|
812fad8c5b | ||
|
|
0a4f296858 | ||
|
|
62d3efd67e | ||
|
|
e6780b20fb | ||
|
|
84af7641ec | ||
|
|
a0195bf457 | ||
|
|
17ba9d0d6f | ||
|
|
71963c914f | ||
|
|
374892c869 | ||
|
|
af5a788d3e | ||
|
|
36f4a69b2e | ||
|
|
214bb6939f | ||
|
|
abd741b9e6 | ||
|
|
c33fd589fb | ||
|
|
b1750ac6ba | ||
|
|
de51136608 | ||
|
|
3da3e6b86d | ||
|
|
fdba0d497a | ||
|
|
4092c0e43f | ||
|
|
4b06b07acf | ||
|
|
6636e7ff47 |
@@ -1,78 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2019 iopsys Software Solutions AB. All rights reserved.
|
||||
#
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# version 2 as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=ated
|
||||
PKG_VERSION:=1.2.2
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_VERSION:=f614cba983d827d5185c60a6a5a35530621d44d2
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/mediatek/ated.git
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
PKG_LICENSE:=GPLv2
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
# support parallel build
|
||||
#PKG_BUILD_PARALLEL:=1
|
||||
|
||||
#re create configure scripts if not present.
|
||||
#PKG_FIXUP:=autoreconf
|
||||
|
||||
# run install target when cross compiling. basically, make install DESTDIR=$(PKG_INSTALL_DIR)
|
||||
# this way we don't need to pick out the resulting files from the build dir.
|
||||
PKG_INSTALL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/ated
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=Daemon for handling wifi calibration
|
||||
URL:=
|
||||
DEPENDS:= libc
|
||||
endef
|
||||
|
||||
define Package/ated/description
|
||||
Daemon for handling wifi calibration
|
||||
endef
|
||||
|
||||
#TARGET_CFLAGS += -I$(LINUX_DIR)/include -I$(LINUX_DIR)/arch/mips/include
|
||||
|
||||
MAKE_FLAGS += \
|
||||
v=2 \
|
||||
m=3
|
||||
|
||||
|
||||
#TARGET_CPPFLAGS := \
|
||||
# -I$(STAGING_DIR)/usr/include/bcm963xx/shared/opensource/include/bcm963xx \
|
||||
# -I$(STAGING_DIR)/usr/include/bcm963xx/bcmdrivers/opensource/include/bcm963xx \
|
||||
# $(TARGET_CPPFLAGS)
|
||||
|
||||
# we donot wwant to have any install.
|
||||
define Build/Install/Default
|
||||
endef
|
||||
|
||||
define Package/ated/install
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ated $(1)/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ated))
|
||||
@@ -1,27 +0,0 @@
|
||||
config BBF_VENDOR_EXTENSION
|
||||
bool "Enable Vendor Extension"
|
||||
default y
|
||||
|
||||
config BBF_VENDOR_LIST
|
||||
string "Vendor List"
|
||||
default "iopsys"
|
||||
|
||||
config BBF_VENDOR_PREFIX
|
||||
string "Vendor Prefix"
|
||||
default "X_IOPSYS_EU_"
|
||||
|
||||
config BBF_TR104
|
||||
bool "Enable TR-104 Data Model Support"
|
||||
default y
|
||||
|
||||
config BBF_TR143
|
||||
bool "Enable TR-143 Data Model Support"
|
||||
default y
|
||||
|
||||
config BBFDM_ENABLE_JSON_PLUGIN
|
||||
bool "Enable json plugin to extend datamodel"
|
||||
default y
|
||||
|
||||
config BBFDM_ENABLE_DOTSO_PLUGIN
|
||||
bool "Enable shared library plugin to extend datamodel"
|
||||
default y
|
||||
185
bbf/Makefile
185
bbf/Makefile
@@ -1,185 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2022 IOPSYS
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=libbbfdm
|
||||
PKG_VERSION:=6.6.35
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/bbf.git
|
||||
PKG_SOURCE_VERSION:=0159ecf5d84805d76dff8cb80831334e200989c7
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
PKG_RELEASE=$(PKG_SOURCE_VERSION)
|
||||
|
||||
PKG_LICENSE:=LGPL-2.1
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
PKG_FIXUP:=autoreconf
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/libbbf_api
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
SUBMENU:=TRx69
|
||||
TITLE:=Library for libbbfdm API
|
||||
endef
|
||||
|
||||
define Package/libbbfdm/default
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
SUBMENU:=TRx69
|
||||
TITLE:=Library for broadband forum data model support
|
||||
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libtrace +libcurl
|
||||
endef
|
||||
|
||||
define Package/libbbfdm
|
||||
$(Package/libbbfdm/default)
|
||||
TITLE += (internal)
|
||||
VARIANT:=internal
|
||||
endef
|
||||
|
||||
define Package/libbbfdm-mbedtls
|
||||
$(Package/libbbfdm/default)
|
||||
TITLE += (mbedtls)
|
||||
DEPENDS += +PACKAGE_libbbfdm-mbedtls:libmbedtls
|
||||
VARIANT:=mbedtls
|
||||
DEFAULT_VARIANT:=1
|
||||
endef
|
||||
|
||||
define Package/libbbfdm-openssl
|
||||
$(Package/libbbfdm/default)
|
||||
TITLE += (openssl)
|
||||
DEPENDS += +PACKAGE_libbbfdm-openssl:libopenssl
|
||||
CONFLICTS := libbbfdm-mbedtls
|
||||
VARIANT:=openssl
|
||||
endef
|
||||
|
||||
define Package/libbbfdm-wolfssl
|
||||
$(Package/libbbfdm/default)
|
||||
TITLE += (wolfssl)
|
||||
DEPENDS += +PACKAGE_libbbfdm-wolfssl:libwolfssl
|
||||
CONFLICTS := libbbfdm-mbedtls libbbfdm-openssl
|
||||
VARIANT:=wolfssl
|
||||
endef
|
||||
|
||||
define Package/libbbfdm/config
|
||||
source "$(SOURCE)/Config_bbfdm.in"
|
||||
endef
|
||||
|
||||
define Package/libbbf_api/description
|
||||
Library contains the API(UCI, UBUS, JSON, CLI and Browse) of libbbfdm
|
||||
endef
|
||||
|
||||
define Package/libbbfdm/description
|
||||
Library contains the data model tree. It includes TR181, TR104 and TR143 data models
|
||||
endef
|
||||
|
||||
USE_LOCAL=$(shell ls ./src/ 2>/dev/null >/dev/null && echo 1)
|
||||
ifneq ($(USE_LOCAL),)
|
||||
define Build/Prepare
|
||||
$(CP) ./src/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
endif
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-D_GNU_SOURCE \
|
||||
-Wall -Werror \
|
||||
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-tr181
|
||||
|
||||
ifeq ($(CONFIG_BBF_TR104),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-tr104
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BBF_TR143),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-tr143
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BBF_VENDOR_EXTENSION),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-vendor-extension
|
||||
|
||||
CONFIGURE_ARGS += \
|
||||
BBF_VENDOR_LIST="$(CONFIG_BBF_VENDOR_LIST)" \
|
||||
BBF_VENDOR_PREFIX="$(CONFIG_BBF_VENDOR_PREFIX)"
|
||||
|
||||
endif ##CONFIG_BBF_VENDOR_EXTENSION
|
||||
|
||||
ifeq ($(CONFIG_BBFDM_ENABLE_JSON_PLUGIN),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-json-plugin
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BBFDM_ENABLE_DOTSO_PLUGIN),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-shared-library
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_VARIANT),openssl)
|
||||
CONFIGURE_ARGS += --enable-libopenssl
|
||||
TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include/
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_VARIANT),wolfssl)
|
||||
CONFIGURE_ARGS += --enable-libwolfssl
|
||||
TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include/wolfssl
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_VARIANT),mbedtls)
|
||||
CONFIGURE_ARGS += --enable-libmbedtls
|
||||
TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include/
|
||||
endif
|
||||
|
||||
define Package/libbbf_api/install
|
||||
$(INSTALL_DIR) $(1)/lib
|
||||
endef
|
||||
|
||||
define Package/libbbfdm/default/install
|
||||
$(INSTALL_DIR) $(1)/lib
|
||||
$(INSTALL_DIR) $(1)/usr/share/bbfdm
|
||||
$(INSTALL_DIR) $(1)/etc/bbfdm
|
||||
$(INSTALL_DIR) $(1)/etc/bbfdm/dmmap
|
||||
$(INSTALL_DIR) $(1)/etc/bbfdm/json
|
||||
$(INSTALL_DIR) $(1)/usr/lib/bbfdm
|
||||
$(CP) $(PKG_BUILD_DIR)/bin/.libs/libbbfdm.so* $(1)/lib/
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/* $(1)/usr/share/bbfdm
|
||||
endef
|
||||
|
||||
define Package/libbbfdm/default/prerm
|
||||
#!/bin/sh
|
||||
rm -rf /etc/bbfdm/dmmap/*
|
||||
exit 0
|
||||
endef
|
||||
|
||||
Package/libbbfdm-openssl/prerm = $(Package/libbbfdm/default/prerm)
|
||||
Package/libbbfdm-wolfssl/prerm = $(Package/libbbfdm/default/prerm)
|
||||
Package/libbbfdm-mbedtls/prerm = $(Package/libbbfdm/default/prerm)
|
||||
|
||||
Package/libbbfdm-openssl/install = $(Package/libbbfdm/default/install)
|
||||
Package/libbbfdm-wolfssl/install = $(Package/libbbfdm/default/install)
|
||||
Package/libbbfdm-mbedtls/install = $(Package/libbbfdm/default/install)
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(INSTALL_DIR) $(1)/usr/include
|
||||
$(INSTALL_DIR) $(1)/usr/include/libbbfdm
|
||||
$(INSTALL_DIR) $(1)/usr/include/libbbf_api
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/include/*.h $(1)/usr/include/
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/*.h $(1)/usr/include/libbbfdm/
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbf_api/*.h $(1)/usr/include/libbbf_api/
|
||||
$(CP) $(PKG_BUILD_DIR)/bin/.libs/libbbfdm.{a,so*} $(1)/usr/lib/
|
||||
touch $(1)/usr/lib/libbbf_api.so
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,libbbf_api))
|
||||
$(eval $(call BuildPackage,libbbfdm))
|
||||
$(eval $(call BuildPackage,libbbfdm-openssl))
|
||||
$(eval $(call BuildPackage,libbbfdm-wolfssl))
|
||||
$(eval $(call BuildPackage,libbbfdm-mbedtls))
|
||||
10
bbfdm/Config_bbfdmd.in
Normal file
10
bbfdm/Config_bbfdmd.in
Normal file
@@ -0,0 +1,10 @@
|
||||
if PACKAGE_bbfdmd
|
||||
|
||||
config BBF_VENDOR_PREFIX
|
||||
string "Vendor Prefix"
|
||||
default "X_IOWRT_EU_"
|
||||
|
||||
config BBF_OBFUSCATION_KEY
|
||||
string "Obfuscation key"
|
||||
default "371d530c95a17d1ca223a29b7a6cdc97e1135c1e0959b51106cca91a0b148b5e42742d372a359760742803f2a44bd88fca67ccdcfaeed26d02ce3b6049cb1e04"
|
||||
endif
|
||||
217
bbfdm/Makefile
Normal file
217
bbfdm/Makefile
Normal file
@@ -0,0 +1,217 @@
|
||||
#
|
||||
# Copyright (C) 2023 IOPSYS
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=bbfdm
|
||||
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:=1615b42e405faceceac825f9c0387a58b90785ae
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
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
|
||||
|
||||
define Package/libbbfdm-api
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
SUBMENU:=TRx69
|
||||
TITLE:=BBF datamodel library, provides API to extend datamodel using DotSO plugins
|
||||
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libcurl
|
||||
ABI_VERSION:=1.0
|
||||
endef
|
||||
|
||||
define Package/libbbfdm-ubus
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
SUBMENU:=TRx69
|
||||
TITLE:=BBF datamodel ubus library, provides API to expose datamodel over ubus
|
||||
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api
|
||||
endef
|
||||
|
||||
define Package/bbfdmd
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
SUBMENU:=TRx69
|
||||
TITLE:=Datamodel ubus backend to expose core tree
|
||||
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api +libopenssl +libbbfdm-ubus +bbf_configmngr
|
||||
endef
|
||||
|
||||
define Package/dm-service
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
SUBMENU:=TRx69
|
||||
TITLE:=Datamodel ubus backend to expose micro-service tree
|
||||
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api +libbbfdm-ubus +bbf_configmngr
|
||||
endef
|
||||
|
||||
define Package/bbf_configmngr
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
SUBMENU:=TRx69
|
||||
TITLE:= BBF Config Manager
|
||||
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json
|
||||
endef
|
||||
|
||||
define Package/bbfdmd/config
|
||||
source "$(SOURCE)/Config_bbfdmd.in"
|
||||
endef
|
||||
|
||||
# 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
|
||||
Library contains the API(UCI, UBUS, JSON, CLI and Browse) of libbbfdm
|
||||
endef
|
||||
|
||||
define Package/libbbfdm-ubus/description
|
||||
Library contains the APIs to expose data model over ubus
|
||||
endef
|
||||
|
||||
define Package/bbfdmd/description
|
||||
Daemon to expose Datamodel core tree
|
||||
endef
|
||||
|
||||
define Package/dm-service/description
|
||||
Daemon to expose Datamodel micro-service tree
|
||||
endef
|
||||
|
||||
define Package/bbf_configmngr/description
|
||||
Daemon for handling bbf reload services via ubus bbf.config
|
||||
endef
|
||||
|
||||
ifeq ($(USE_LOCAL),1)
|
||||
define Build/Prepare
|
||||
$(CP) ~/git/bbfdm/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
endif
|
||||
|
||||
CMAKE_OPTIONS += \
|
||||
-DBBF_VENDOR_PREFIX:String="$(CONFIG_BBF_VENDOR_PREFIX)" \
|
||||
-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/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
|
||||
$(CP) $(PKG_BUILD_DIR)/utilities/files/usr/libexec/rpcd/bbf.diag $(1)/usr/libexec/rpcd/bbf.diag
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/share/bbfdm/scripts/
|
||||
$(CP) $(PKG_BUILD_DIR)/utilities/files/usr/share/bbfdm/scripts/bbf_api $(1)/usr/share/bbfdm/scripts/
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/bbfdm/certificates
|
||||
echo "$(CONFIG_BBF_OBFUSCATION_KEY)" > $(1)/etc/bbfdm/.secure_hash
|
||||
endef
|
||||
|
||||
define Package/libbbfdm-ubus/install
|
||||
$(INSTALL_DIR) $(1)/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/libbbfdm-ubus/libbbfdm-ubus.so $(1)/lib/
|
||||
endef
|
||||
|
||||
define Package/bbfdmd/install
|
||||
$(INSTALL_DIR) $(1)/etc/bbfdm/dmmap
|
||||
$(INSTALL_DIR) $(1)/usr/share/bbfdm
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) ./files/etc/config/bbfdm $(1)/etc/config/bbfdm
|
||||
$(INSTALL_CONF) ./files/etc/config/schedules $(1)/etc/config/schedules
|
||||
|
||||
$(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
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
|
||||
$(INSTALL_BIN) ./files/etc/hotplug.d/iface/85-bbfdm-sysctl $(1)/etc/hotplug.d/iface/85-bbfdm-sysctl
|
||||
|
||||
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
|
||||
$(INSTALL_DATA) ./files/lib/upgrade/keep.d/bbf $(1)/lib/upgrade/keep.d/bbf
|
||||
|
||||
$(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
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/ruleng
|
||||
$(INSTALL_BIN) ./files/etc/ruleng/bbfdm.json $(1)/etc/ruleng
|
||||
endef
|
||||
|
||||
define Package/dm-service/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/etc/init.d/bbfdm.services $(1)/etc/init.d/
|
||||
|
||||
$(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
|
||||
$(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
|
||||
$(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
|
||||
#!/bin/sh
|
||||
rm -rf /etc/bbfdm/dmmap/*
|
||||
exit 0
|
||||
endef
|
||||
|
||||
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/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/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
|
||||
|
||||
$(eval $(call BuildPackage,bbf_configmngr))
|
||||
$(eval $(call BuildPackage,libbbfdm-api))
|
||||
$(eval $(call BuildPackage,libbbfdm-ubus))
|
||||
$(eval $(call BuildPackage,bbfdmd))
|
||||
$(eval $(call BuildPackage,dm-service))
|
||||
38
bbfdm/README.md
Normal file
38
bbfdm/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# BBFDM configuration options and utilities
|
||||
|
||||
bbfdm provides few compile time configuration options and compile time help utility called [bbfdm.mk](./bbfdm.mk), this document aimed to explain the available usages and best practices.
|
||||
|
||||
## Compilation options
|
||||
|
||||
| Configuration option | Description | Default Value |
|
||||
| ----------------------- | ------------- | ----------- |
|
||||
| CONFIG_BBF_VENDOR_LIST | List of vendor extension directories | iopsys |
|
||||
| CONFIG_BBF_VENDOR_PREFIX | Prefix for Vendor extension datamodel objects/parameters | X_IOPSYS_EU_ |
|
||||
| CONFIG_BBF_MAX_OBJECT_INSTANCES | Maximum number of instances per object | 255 |
|
||||
| BBF_OBFUSCATION_KEY | Hash used to encode/decode in `bbf.secure` object | 371d530c95a17d1ca223a29b7a6cdc97e1135c1e0959b51106cca91a0b148b5e42742d372a359760742803f2a44bd88fca67ccdcfaeed26d02ce3b6049cb1e04 |
|
||||
|
||||
|
||||
#### BBF_OBFUSCATION_KEY
|
||||
|
||||
`bbfdm` provides an ubus object called `bbf.secure` to allow encoding/decoding the values, `bbf.secure` currently support following methods internally to encode/decode
|
||||
|
||||
- Encode/Decode using a predefined SHA512 Hash key
|
||||
- Encode/Decode using a private/public RSA key pair
|
||||
|
||||
The `BBF_OBFUSCATION_KEY` compile time configuration option used to defined the SHA512 HASH, if this option is undefined, then it usages a default value as mention in the above table.
|
||||
|
||||
User must override this parameter with their own hash value, to generate a hash user can run below command and copy the hash value to this option.
|
||||
|
||||
ex: User wants to use 'Sup3rS3cur3Passw0rd' as passkey, then can get the SHA512 sum with
|
||||
|
||||
```bash
|
||||
$ echo -n "Sup3rS3cur3Passw0rd" | sha512sum
|
||||
371d530c95a17d1ca223a29b7a6cdc97e1135c1e0959b51106cca91a0b148b5e42742d372a359760742803f2a44bd88fca67ccdcfaeed26d02ce3b6049cb1e04 -
|
||||
```
|
||||
|
||||
> Note: Additionally, user can install RSA private key in '/etc/bbfdm/certificates/private_key.pem' path, if private key is present `bbf.secure` shall use rsa private certificate for encrypt/decrypt function. In case of key not present in the pre-defined path, hash will be used for the same.
|
||||
|
||||
## Helper utility (bbfdm.mk)
|
||||
|
||||
bbfdm provides a helper utility [bbfdm.mk](./bbfdm.mk) to install datamodel plugins in bbfdm core or in microservice directory.
|
||||
|
||||
92
bbfdm/bbfdm.mk
Normal file
92
bbfdm/bbfdm.mk
Normal file
@@ -0,0 +1,92 @@
|
||||
#
|
||||
# Copyright (C) 2023 IOPSYS
|
||||
#
|
||||
|
||||
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
|
||||
|
||||
# Utility to install the plugin in bbfdm core path with priority.
|
||||
# Its now possible to overwrite/remove core datamodel with plugin, so, if some
|
||||
# datamodel objects/parameters are present in more than one plugin, order in
|
||||
# which they loaded into memory becomes crucial, this Utility help to configure
|
||||
# a priority order in which they gets loaded in memory.
|
||||
#
|
||||
# ARGS:
|
||||
# $1 => Plugin artifact
|
||||
# $2 => package install directory
|
||||
# $3 => Priority of the installed plugin (Optional)
|
||||
#
|
||||
# Note:
|
||||
# - Last loaded plugin gets the highest priority
|
||||
#
|
||||
# Example:
|
||||
# BBFDM_INSTALL_CORE_PLUGIN ./files/etc/bbfdm/json/CWMPManagementServer.json $(1)
|
||||
#
|
||||
# Example to install plugin with priority:
|
||||
# BBFDM_INSTALL_CORE_PLUGIN ./files/etc/bbfdm/json/CWMPManagementServer.json $(1) 01
|
||||
#
|
||||
BBFDM_INSTALL_CORE_PLUGIN:=$(BBFDM_DIR)/tools/bbfdm.sh -p
|
||||
|
||||
|
||||
# Utility to install the micro-service datamodel
|
||||
# Use Case:
|
||||
# user wants to run a datamodel micro-service, it required to install the
|
||||
# DotSO/JSON plugin into a bbf shared directory, this utility helps in
|
||||
# installing the DotSO/JSON plugin in bbfdm shared directory, and auto-generate
|
||||
# input file for the micro-service
|
||||
#
|
||||
# ARGS:
|
||||
# $1 => DotSo or Json plugin with complete path
|
||||
# $2 => package install directory
|
||||
# $3 => service name
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# Example:
|
||||
# BBFDM_INSTALL_MS_DM $(PKG_BUILD_DIR)/libcwmp.so $(1) $(PKG_NAME)
|
||||
#
|
||||
BBFDM_INSTALL_MS_DM:=$(BBFDM_DIR)/tools/bbfdm.sh -m
|
||||
|
||||
|
||||
# Utility to install a plugins in datamodel micro-service
|
||||
#
|
||||
# ARGS:
|
||||
# $1 => DotSo or Json plugin with complete path
|
||||
# $2 => package install directory
|
||||
# $3 => service name
|
||||
#
|
||||
# Note:
|
||||
# - Use the service_name/PKG_NAME of the service in which this has to run
|
||||
#
|
||||
# Example:
|
||||
# BBFDM_INSTALL_MS_PLUGIN $(PKG_BUILD_DIR)/libxmpp.so $(1) icwmp
|
||||
#
|
||||
BBFDM_INSTALL_MS_PLUGIN:=$(BBFDM_DIR)/tools/bbfdm.sh -m -p
|
||||
|
||||
# Utility to install the helper scripts in default bbfdm script path
|
||||
#
|
||||
# Use Case:
|
||||
# User want to install some script for running diagnostics
|
||||
#
|
||||
# ARGS:
|
||||
# $1 => Script with complete path
|
||||
# $2 => package install directory
|
||||
#
|
||||
# Note:
|
||||
# - Use with -d option to install script in bbf.diag directory
|
||||
#
|
||||
# Example:
|
||||
# BBFDM_INSTALL_SCRIPT $(PKG_BUILD_DIR)/download $(1)
|
||||
# BBFDM_INSTALL_SCRIPT -d $(PKG_BUILD_DIR)/ipping $(1)
|
||||
#
|
||||
BBFDM_INSTALL_SCRIPT:=$(BBFDM_DIR)/tools/bbfdm.sh -s
|
||||
|
||||
|
||||
BBFDM_REGISTER_SERVICES:=$(BBFDM_DIR)/tools/bbfdm.sh -t
|
||||
54
bbfdm/bbfdm_service.json
Normal file
54
bbfdm/bbfdm_service.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
23
bbfdm/files/etc/bbfdm/critical_services.json
Normal file
23
bbfdm/files/etc/bbfdm/critical_services.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"usp": [
|
||||
"firewall",
|
||||
"network",
|
||||
"dhcp",
|
||||
"time",
|
||||
"wireless",
|
||||
"ieee1905",
|
||||
"mapcontroller",
|
||||
"mosquitto",
|
||||
"nginx",
|
||||
"netmode"
|
||||
],
|
||||
"cwmp": [
|
||||
"firewall",
|
||||
"network",
|
||||
"dhcp",
|
||||
"mapcontroller",
|
||||
"wireless",
|
||||
"time",
|
||||
"netmode"
|
||||
]
|
||||
}
|
||||
12
bbfdm/files/etc/config/bbfdm
Normal file
12
bbfdm/files/etc/config/bbfdm
Normal file
@@ -0,0 +1,12 @@
|
||||
config bbfdmd 'bbfdmd'
|
||||
option enable '1'
|
||||
option debug '0'
|
||||
option loglevel '3'
|
||||
|
||||
config micro_services 'micro_services'
|
||||
option enable '1'
|
||||
option enable_core '0'
|
||||
|
||||
|
||||
config reload_handler 'reload_handler'
|
||||
option log_level '1'
|
||||
2
bbfdm/files/etc/config/schedules
Normal file
2
bbfdm/files/etc/config/schedules
Normal file
@@ -0,0 +1,2 @@
|
||||
config global 'global'
|
||||
option enable '1'
|
||||
17
bbfdm/files/etc/hotplug.d/iface/85-bbfdm-sysctl
Normal file
17
bbfdm/files/etc/hotplug.d/iface/85-bbfdm-sysctl
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ "$ACTION" = "ifup" ] || exit 0
|
||||
|
||||
apply_sysctl_configuration() {
|
||||
local sysctl_conf
|
||||
|
||||
sysctl_conf="/etc/bbfdm/sysctl.conf"
|
||||
|
||||
[ -f "${sysctl_conf}" ] || touch "${sysctl_conf}"
|
||||
|
||||
sysctl -e -p "${sysctl_conf}" >&-
|
||||
}
|
||||
|
||||
|
||||
ubus -t 10 wait_for network.device
|
||||
apply_sysctl_configuration
|
||||
41
bbfdm/files/etc/init.d/bbf_configd
Normal file
41
bbfdm/files/etc/init.d/bbf_configd
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=80
|
||||
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
|
||||
mkdir -p /tmp/bbfdm/.usp
|
||||
mkdir -p /tmp/bbfdm/.bbfdm
|
||||
}
|
||||
|
||||
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 -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
|
||||
}
|
||||
127
bbfdm/files/etc/init.d/bbfdm.services
Normal file
127
bbfdm/files/etc/init.d/bbfdm.services
Normal file
@@ -0,0 +1,127 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=97
|
||||
STOP=05
|
||||
|
||||
USE_PROCD=1
|
||||
PROG=/usr/sbin/dm-service
|
||||
DM_AGENT_PROG=/usr/sbin/dm-agent
|
||||
|
||||
BBFDM_MICROSERVICE_DIR="/etc/bbfdm/services"
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
log() {
|
||||
echo "${@}"|logger -t bbfdmd.services -p info
|
||||
}
|
||||
|
||||
validate_bbfdm_micro_service_section()
|
||||
{
|
||||
uci_validate_section bbfdm micro_services "micro_services" \
|
||||
'enable:bool:true' \
|
||||
'enable_core:bool:false'
|
||||
}
|
||||
|
||||
_add_microservice()
|
||||
{
|
||||
local name path loglevel
|
||||
local enable enable_core unified_daemon dm_framework
|
||||
local daemon_prog
|
||||
|
||||
# Check enable from micro-service
|
||||
path="${1}"
|
||||
enable_core="${2}"
|
||||
|
||||
name="$(basename ${path})"
|
||||
name="${name//.json}"
|
||||
|
||||
json_load_file "${path}"
|
||||
json_select daemon
|
||||
|
||||
json_get_var enable enable 1
|
||||
if [ "${enable}" -eq "0" ]; then
|
||||
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 4
|
||||
|
||||
procd_open_instance "${name}"
|
||||
|
||||
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"
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
fi
|
||||
|
||||
procd_set_param respawn
|
||||
procd_close_instance "${name}"
|
||||
}
|
||||
|
||||
configure_bbfdm_micro_services()
|
||||
{
|
||||
local enable enable_core
|
||||
|
||||
config_load bbfdm
|
||||
validate_bbfdm_micro_service_section || {
|
||||
log "Validation of micro_service section failed"
|
||||
return 1;
|
||||
}
|
||||
|
||||
[ "${enable}" -eq "0" ] && return 0
|
||||
|
||||
if [ -d "${BBFDM_MICROSERVICE_DIR}" ]; then
|
||||
FILES="$(ls -1 ${BBFDM_MICROSERVICE_DIR}/*.json)"
|
||||
|
||||
for file in $FILES;
|
||||
do
|
||||
[ -e "$file" ] || continue
|
||||
|
||||
_add_microservice $file "${enable_core}"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
_start_single_service()
|
||||
{
|
||||
local service file
|
||||
|
||||
service="${1}"
|
||||
|
||||
if [ -d "${BBFDM_MICROSERVICE_DIR}" ]; then
|
||||
file="$(ls -1 ${BBFDM_MICROSERVICE_DIR}/${service}.json)"
|
||||
[ -e "$file" ] || return
|
||||
|
||||
_add_microservice $file "0"
|
||||
fi
|
||||
}
|
||||
|
||||
start_service()
|
||||
{
|
||||
if [ -n "${1}" ]; then
|
||||
_start_single_service "${1}"
|
||||
else
|
||||
configure_bbfdm_micro_services
|
||||
fi
|
||||
}
|
||||
56
bbfdm/files/etc/init.d/bbfdmd
Normal file
56
bbfdm/files/etc/init.d/bbfdmd
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=97
|
||||
STOP=06
|
||||
|
||||
USE_PROCD=1
|
||||
PROG=/usr/sbin/bbfdmd
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
log() {
|
||||
echo "${@}"|logger -t bbfdmd.init -p info
|
||||
}
|
||||
|
||||
validate_bbfdm_bbfdmd_section()
|
||||
{
|
||||
uci_validate_section bbfdm bbfdmd "bbfdmd" \
|
||||
'enable:bool:true' \
|
||||
'debug:bool:false' \
|
||||
'loglevel:uinteger:4'
|
||||
}
|
||||
|
||||
configure_bbfdmd()
|
||||
{
|
||||
local enable debug
|
||||
local jlog jrefresh jtimeout jlevel
|
||||
|
||||
config_load bbfdm
|
||||
validate_bbfdm_bbfdmd_section || {
|
||||
log "Validation of bbfdmd section failed"
|
||||
return 1;
|
||||
}
|
||||
|
||||
[ "${enable}" -eq 0 ] && return 0
|
||||
|
||||
procd_set_param command ${PROG}
|
||||
procd_append_param command -l "${loglevel}"
|
||||
|
||||
if [ "${debug}" -eq 1 ]; then
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
fi
|
||||
}
|
||||
|
||||
start_service()
|
||||
{
|
||||
procd_open_instance "bbfdm"
|
||||
configure_bbfdmd
|
||||
procd_set_param respawn
|
||||
procd_close_instance "bbfdm"
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
procd_add_reload_trigger "bbfdm"
|
||||
}
|
||||
66
bbfdm/files/etc/ruleng/bbfdm.json
Normal file
66
bbfdm/files/etc/ruleng/bbfdm.json
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
11
bbfdm/files/etc/uci-defaults/91-fix-bbfdmd-enabled-option
Normal file
11
bbfdm/files/etc/uci-defaults/91-fix-bbfdmd-enabled-option
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
# rename bbfdmd enabled option to enable
|
||||
val="$(uci -q get bbfdm.bbfdmd.enabled)"
|
||||
if [ -n "${val}" ]; then
|
||||
uci -q set bbfdm.bbfdmd.enabled=""
|
||||
uci -q set bbfdm.bbfdmd.enable="${val}"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
58
bbfdm/files/etc/uci-defaults/96-sysctl-translation
Executable file
58
bbfdm/files/etc/uci-defaults/96-sysctl-translation
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
|
||||
bbfdm_sysctl_conf="/etc/bbfdm/sysctl.conf"
|
||||
|
||||
update_device_section() {
|
||||
local section="${1}"
|
||||
local dev_name="${2}"
|
||||
local ipv6="${3}"
|
||||
local name
|
||||
|
||||
# Get name value
|
||||
config_get name "${section}" name
|
||||
|
||||
# Retrun if the name value is different to the dev_name value
|
||||
[ "${name}" != "${dev_name}" ] && return
|
||||
|
||||
if [ "${ipv6}" = "0" ]; then
|
||||
ipv6="1"
|
||||
else
|
||||
ipv6="0"
|
||||
fi
|
||||
|
||||
# Add ipv6 option
|
||||
uci -q set network.${section}.ipv6="${ipv6}"
|
||||
}
|
||||
|
||||
parse_bbfdm_sysctl_conf_file() {
|
||||
# Check if the file exists
|
||||
[ -f "${bbfdm_sysctl_conf}" ] || return
|
||||
|
||||
# Create a temporary file
|
||||
tmpfile=$(mktemp)
|
||||
|
||||
# Load network config
|
||||
config_load network
|
||||
|
||||
# Read each line of the file
|
||||
while read -r line; do
|
||||
if echo "$line" | grep -Eq '^net\.ipv6\.conf\.(.+)\.disable_ipv6=([0-1])$'; then
|
||||
name=$(echo "$line" | sed -n 's/^net\.ipv6\.conf\.\(.*\)\.disable_ipv6=[0-1]$/\1/p')
|
||||
value=$(echo "$line" | sed -n 's/^net\.ipv6\.conf\.\(.*\)\.disable_ipv6=\([0-1]\)$/\2/p')
|
||||
|
||||
config_foreach update_device_section device "${name}" "${value}"
|
||||
else
|
||||
# If the line doesn't match, preserve it in the temporary file
|
||||
echo "$line" >> "$tmpfile"
|
||||
fi
|
||||
done < "${bbfdm_sysctl_conf}"
|
||||
|
||||
# Replace the original file with the modified content
|
||||
mv "$tmpfile" "${bbfdm_sysctl_conf}"
|
||||
}
|
||||
|
||||
parse_bbfdm_sysctl_conf_file
|
||||
|
||||
exit 0
|
||||
2
bbfdm/files/etc/uci-defaults/ruleng.bbfdm
Normal file
2
bbfdm/files/etc/uci-defaults/ruleng.bbfdm
Normal file
@@ -0,0 +1,2 @@
|
||||
uci -q set ruleng.bbfdm=rule
|
||||
uci -q set ruleng.bbfdm.recipe='/etc/ruleng/bbfdm.json'
|
||||
1
bbfdm/files/lib/upgrade/keep.d/bbf
Normal file
1
bbfdm/files/lib/upgrade/keep.d/bbf
Normal file
@@ -0,0 +1 @@
|
||||
/etc/bbfdm/sysctl.conf
|
||||
203
bbfdm/tools/bbfdm.sh
Executable file
203
bbfdm/tools/bbfdm.sh
Executable file
@@ -0,0 +1,203 @@
|
||||
#!/bin/bash
|
||||
|
||||
BBFDM_BASE_DM_PATH="usr/share/bbfdm"
|
||||
BBFDM_INPUT_PATH="etc/bbfdm/micro_services"
|
||||
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 ":mpsdtv:" opt; do
|
||||
case ${opt} in
|
||||
m)
|
||||
MICRO_SERVICE=1
|
||||
;;
|
||||
p)
|
||||
PLUGIN=1
|
||||
;;
|
||||
s)
|
||||
SCRIPT=1
|
||||
;;
|
||||
d)
|
||||
DIAG=1
|
||||
;;
|
||||
t)
|
||||
INPUT_FILE=1
|
||||
;;
|
||||
v)
|
||||
VENDOR_EXTN=${OPTARG}
|
||||
;;
|
||||
?)
|
||||
echo "Invalid option: ${OPTARG}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
SRC="${1}"
|
||||
shift
|
||||
DEST="${1}"
|
||||
shift
|
||||
DATA="${1}"
|
||||
shift
|
||||
EXTRA_DATA="${1}"
|
||||
|
||||
|
||||
install_bin() {
|
||||
if ! install -m0755 ${1} ${2}; then
|
||||
echo "Failed to install bin ${1} => ${2}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
install_dir() {
|
||||
if ! install -d -m0755 ${1}; then
|
||||
echo "Failed to create directory ${1}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
install_data() {
|
||||
if ! install -m0644 ${1} ${2}; then
|
||||
echo "Failed to install ${1} => ${2}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Installing datamodel
|
||||
bbfdm_install_dm()
|
||||
{
|
||||
local src dest minfile
|
||||
|
||||
src="$1"
|
||||
dest="$2"
|
||||
minfile=""
|
||||
|
||||
if [ -z ${src} ] || [ -z "${dest}" ] || [ -z "${TOOLS}" ]; then
|
||||
echo "Invalid input option for 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"
|
||||
if ! ${TOOLS}/validate_plugins.py ${src}; then
|
||||
echo "Validation of the plugin failed ${src}"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "## Install python3-jsonschema to verify datamodel plugins"
|
||||
fi
|
||||
fi
|
||||
|
||||
install_bin ${src} ${dest}
|
||||
|
||||
if [ -f "${minfile}" ]; then
|
||||
rm ${minfile}
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -z "$SRC" ] || [ -z "${DEST}" ] ; then
|
||||
echo "# BBFDM Null value in src[${SRC}], dest[${DEST}]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${SCRIPT}" -eq "1" ]; then
|
||||
if [ "${DIAG}" -eq "1" ]; then
|
||||
install_dir ${DEST}/${BBFDM_BASE_DM_PATH}/scripts/bbf_diag
|
||||
install_bin ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/scripts/bbf_diag/
|
||||
else
|
||||
install_dir ${DEST}/${BBFDM_BASE_DM_PATH}/scripts
|
||||
install_bin ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/scripts/
|
||||
fi
|
||||
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"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${PLUGIN}" -ne "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##*.}
|
||||
else
|
||||
install_dir ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/${DATA}
|
||||
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}/micro_services/core
|
||||
|
||||
if [ "${priority}" -gt "0" ]; then
|
||||
# install with priority if defined
|
||||
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
|
||||
echo "# Priority should be an unsigned integer"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
333
bbfdm/tools/validate_plugins.py
Executable file
333
bbfdm/tools/validate_plugins.py
Executable file
@@ -0,0 +1,333 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Copyright (C) 2024 iopsys Software Solutions AB
|
||||
# Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
|
||||
|
||||
import sys
|
||||
import json
|
||||
from jsonschema import validate
|
||||
|
||||
JSON_PLUGIN_VERSION = 0
|
||||
|
||||
obj_schema = {
|
||||
"definitions": {
|
||||
"type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"object"
|
||||
]
|
||||
},
|
||||
"map_type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"uci",
|
||||
"ubus"
|
||||
]
|
||||
},
|
||||
"protocols_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"none",
|
||||
"cwmp",
|
||||
"usp"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"type" : {"$ref": "#/definitions/type_t"},
|
||||
"version" : {"type": "string"},
|
||||
"protocols" : {"type" : "array", "items" : {"$ref": "#/definitions/protocols_t"}},
|
||||
"uniqueKeys" : {"type" : "array"},
|
||||
"access" : {"type" : "boolean"},
|
||||
"array" : {"type" : "boolean"},
|
||||
"mapping" : {"type" : "object", "properties" : {
|
||||
"type" : {"$ref": "#/definitions/map_type_t"},
|
||||
"uci" : {"type" : "object", "properties" : {
|
||||
"file" : {"type": "string"},
|
||||
"section" : {"type": "object", "properties" : {
|
||||
"type" : {"type": "string"}
|
||||
}
|
||||
},
|
||||
"dmmapfile" : {"type": "string"}
|
||||
}
|
||||
},
|
||||
"ubus" : {"type" : "object", "properties" : {
|
||||
"object" : {"type": "string"},
|
||||
"method" : {"type": "string"},
|
||||
"args" : {"type": "object"},
|
||||
"key" : {"type": "string"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"protocols",
|
||||
"array",
|
||||
"access"
|
||||
]
|
||||
}
|
||||
|
||||
obj_schema_v1 = {
|
||||
"definitions": {
|
||||
"type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"object"
|
||||
]
|
||||
},
|
||||
"map_type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"uci",
|
||||
"ubus"
|
||||
]
|
||||
},
|
||||
"protocols_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"cwmp",
|
||||
"usp",
|
||||
"none"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"type" : {"$ref": "#/definitions/type_t"},
|
||||
"version" : {"type": "string"},
|
||||
"protocols" : {"type" : "array", "items" : {"$ref": "#/definitions/protocols_t"}},
|
||||
"uniqueKeys" : {"type" : "array"},
|
||||
"access" : {"type" : "boolean"},
|
||||
"array" : {"type" : "boolean"},
|
||||
"mapping" : {"type" : "array", "items" : {
|
||||
"type" : "object", "properties" : {
|
||||
"type" : {"$ref": "#/definitions/map_type_t"},
|
||||
"uci" : {"type" : "object", "properties" : {
|
||||
"file" : {"type": "string"},
|
||||
"section" : {"type": "object", "properties" : {
|
||||
"type" : {"type": "string"}
|
||||
}
|
||||
},
|
||||
"dmmapfile" : {"type": "string"}
|
||||
}
|
||||
},
|
||||
"ubus" : {"type" : "object", "properties" : {
|
||||
"object" : {"type": "string"},
|
||||
"method" : {"type": "string"},
|
||||
"args" : {"type": "object"},
|
||||
"key" : {"type": "string"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"protocols",
|
||||
"array",
|
||||
"access"
|
||||
]
|
||||
}
|
||||
|
||||
param_schema = {
|
||||
"definitions": {
|
||||
"type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"string",
|
||||
"unsignedInt",
|
||||
"unsignedLong",
|
||||
"int",
|
||||
"long",
|
||||
"boolean",
|
||||
"dateTime",
|
||||
"hexBinary",
|
||||
"base64",
|
||||
"decimal"
|
||||
]
|
||||
},
|
||||
"map_type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"uci",
|
||||
"ubus",
|
||||
"procfs",
|
||||
"sysfs",
|
||||
"json",
|
||||
"uci_sec"
|
||||
]
|
||||
},
|
||||
"protocols_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"cwmp",
|
||||
"usp",
|
||||
"none"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"type" : {"$ref": "#/definitions/type_t"},
|
||||
"protocols" : {"type" : "array", "items" : {"$ref": "#/definitions/protocols_t"}},
|
||||
"read" : {"type" : "boolean"},
|
||||
"write" : {"type" : "boolean"},
|
||||
"mapping" : {"type" : "array", "items" : {"type": "object", "properties" : {
|
||||
"type" : {"$ref": "#/definitions/map_type_t"},
|
||||
"uci" : {"type" : "object", "properties" : {
|
||||
"file" : {"type": "string"},
|
||||
"section" : {"type": "object", "properties" : {
|
||||
"type" : {"type": "string"},
|
||||
"index" : {"type": "string"}
|
||||
}
|
||||
},
|
||||
"option" : {"type": "object", "properties" : {
|
||||
"name" : {"type": "string"} }
|
||||
}
|
||||
}
|
||||
},
|
||||
"ubus" : {"type" : "object", "properties" : {
|
||||
"object" : {"type": "string"},
|
||||
"method" : {"type": "string"},
|
||||
"args" : {"type": "object"},
|
||||
"key" : {"type": "string"}
|
||||
}
|
||||
},
|
||||
"procfs" : {"type" : "object", "properties" : {
|
||||
"file" : {"type": "string"}
|
||||
}
|
||||
},
|
||||
"sysfs" : {"type" : "object", "properties" : {
|
||||
"file" : {"type": "string"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"protocols",
|
||||
"read",
|
||||
"write"
|
||||
]
|
||||
}
|
||||
|
||||
event_schema = {
|
||||
"definitions": {
|
||||
"type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"event"
|
||||
]
|
||||
},
|
||||
"protocols_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"none",
|
||||
"usp"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"type" : {"$ref": "#/definitions/type_t"},
|
||||
"version" : {"type": "string"},
|
||||
"protocols" : {"type" : "array", "items" : {"$ref": "#/definitions/protocols_t"}}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"protocols"
|
||||
]
|
||||
}
|
||||
|
||||
command_schema = {
|
||||
"definitions": {
|
||||
"type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"command"
|
||||
]
|
||||
},
|
||||
"protocols_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"none",
|
||||
"usp"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"type" : {"$ref": "#/definitions/type_t"},
|
||||
"async" : {"type" : "boolean"},
|
||||
"protocols" : {"type" : "array", "items" : {"$ref": "#/definitions/protocols_t"}},
|
||||
"input" : {"type" : "object"},
|
||||
"output" : {"type" : "object"}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"async",
|
||||
"protocols"
|
||||
]
|
||||
}
|
||||
|
||||
def print_validate_json_usage():
|
||||
print("Usage: " + sys.argv[0] + " <dm json file>")
|
||||
print("Examples:")
|
||||
print(" - " + sys.argv[0] + " datamodel.json")
|
||||
print(" ==> Validate the json file")
|
||||
print("")
|
||||
exit(1)
|
||||
|
||||
def parse_value( key , value ):
|
||||
|
||||
if key.endswith('.') and not key.startswith('Device.'):
|
||||
print(key + " is not a valid path")
|
||||
exit(1)
|
||||
|
||||
if key.endswith('.') and (JSON_PLUGIN_VERSION == 1 or JSON_PLUGIN_VERSION == 2):
|
||||
__schema = obj_schema_v1
|
||||
elif key.endswith('.'):
|
||||
__schema = obj_schema
|
||||
elif key.endswith('!'):
|
||||
__schema = event_schema
|
||||
elif key.endswith('()'):
|
||||
__schema = command_schema
|
||||
else:
|
||||
__schema = param_schema
|
||||
|
||||
validate(instance = value, schema = __schema)
|
||||
|
||||
for k, v in value.items():
|
||||
if k != "list" and k != "mapping" and k != "input" and k != "output" and isinstance(v, dict):
|
||||
parse_value(k, v)
|
||||
|
||||
### main ###
|
||||
if len(sys.argv) < 2:
|
||||
print_validate_json_usage()
|
||||
|
||||
json_file = open(sys.argv[1], "r", encoding='utf-8')
|
||||
try:
|
||||
json_data = json.loads(json_file.read())
|
||||
except ValueError:
|
||||
print(sys.argv[1] + " file has a wrong JSON format!!!!!")
|
||||
exit(1)
|
||||
|
||||
for __key, __value in json_data.items():
|
||||
|
||||
if __key == "json_plugin_version":
|
||||
|
||||
if not isinstance(__value, int) or __value not in [0, 1, 2]:
|
||||
raise ValueError("Invalid value for json_plugin_version")
|
||||
|
||||
JSON_PLUGIN_VERSION = __value
|
||||
continue
|
||||
|
||||
parse_value(__key , __value)
|
||||
|
||||
print("JSON File is Valid")
|
||||
45
blkpg-part/Makefile
Normal file
45
blkpg-part/Makefile
Normal 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)))
|
||||
@@ -1,40 +1,40 @@
|
||||
#
|
||||
# Copyright (C) 2022 iopsys Software Solutions AB
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=bulkdata
|
||||
PKG_VERSION:=2.0.3
|
||||
PKG_VERSION:=2.1.20
|
||||
|
||||
LOCAL_DEV:=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/bulkdata.git
|
||||
PKG_SOURCE_VERSION:=85d7486a21a9eb0e0f345b587b3ac506edcb72fe
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/bulkdata.git
|
||||
PKG_SOURCE_VERSION:=a5e57962938ca143ede65d92be90b6e9fce66e15
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
endif
|
||||
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
PKG_LICENSE:=GPL-2.0-only
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
PKG_BUILD_DEPENDS:=bbf
|
||||
|
||||
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
|
||||
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 += \
|
||||
@@ -47,12 +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_BIN) $(PKG_BUILD_DIR)/bulkdatad $(1)/usr/sbin/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/bbfdm
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bbf_plugin/*.so $(1)/usr/lib/bbfdm
|
||||
$(CP) ./files/* $(1)/
|
||||
$(INSTALL_DATA) ./files/etc/config/bulkdata $(1)/etc/config/
|
||||
$(INSTALL_BIN) ./files/etc/init.d/bulkdatad $(1)/etc/init.d/
|
||||
|
||||
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) $(PKG_NAME)
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
$(eval $(call BuildPackage,bulkdata))
|
||||
|
||||
17
bulkdata/bbfdm_service.json
Normal file
17
bulkdata/bbfdm_service.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -1,34 +1,41 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
START=60
|
||||
STOP=10
|
||||
|
||||
USE_PROCD=1
|
||||
PROG="/usr/sbin/bulkdatad"
|
||||
|
||||
start_service() {
|
||||
local enable=$(uci -q get bulkdata.bulkdata.enable)
|
||||
|
||||
[ "$enable" != "1" ] && {
|
||||
return 0
|
||||
}
|
||||
|
||||
procd_open_instance
|
||||
procd_set_param command "$PROG"
|
||||
procd_set_param respawn "3" "7" "0"
|
||||
procd_close_instance
|
||||
validate_global_section() {
|
||||
uci_validate_section bulkdata bulkdata bulkdata \
|
||||
'enable:bool:1' \
|
||||
'loglevel:uinteger:3'
|
||||
}
|
||||
|
||||
boot() {
|
||||
start
|
||||
start_service() {
|
||||
local enable loglevel
|
||||
|
||||
validate_global_section
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -1,17 +1,17 @@
|
||||
#
|
||||
# Copyright (C) 2021 IOPSYS
|
||||
# Copyright (C) 2021-2023 IOPSYS
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=wfa-capi
|
||||
PKG_VERSION:=1.1.2
|
||||
PKG_NAME:=capiagent
|
||||
PKG_VERSION:=2.1.1
|
||||
|
||||
LOCAL_DEV=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=ce29c2d69d0ca96b61f2de5d1ba107c8d31cb5ef
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/wfa-capi.git
|
||||
PKG_SOURCE_VERSION:=136cab3a9f1eec0132db9fa3f7bb1c8748ce1449
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/multi-ap/capiagent.git
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
endif
|
||||
@@ -24,18 +24,18 @@ PKG_LICENSE_FILES:=LICENSE
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
|
||||
#define Package/wfa-capi/config
|
||||
#define Package/capiagent/config
|
||||
# source "$(SOURCE)/Config.in"
|
||||
#endef
|
||||
|
||||
define Package/wfa-capi
|
||||
TITLE+= wfa-capi (agent daemon for Wi-Fi Alliance's CAPI commands)
|
||||
define Package/capiagent
|
||||
TITLE+= capiagent (daemon implementing Wi-Fi Alliance's CAPI commands)
|
||||
DEPENDS= +libubox +libuci +libubus +libnl-genl +libeasy +libwifi \
|
||||
+libjson-c +libblobmsg-json +ubus +libieee1905
|
||||
+libjson-c +libblobmsg-json +ubus +libieee1905 +libwifiutils
|
||||
endef
|
||||
|
||||
define Package/wfa-capi/description
|
||||
This package provides agent for WiFi Alliance's CAPI specification.
|
||||
define Package/capiagent/description
|
||||
This package provides agent for the WiFi Alliance's CAPI specification.
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
@@ -46,7 +46,7 @@ TARGET_CFLAGS += \
|
||||
MAKE_PATH:=src
|
||||
|
||||
|
||||
define Package/wfa-capi/install
|
||||
define Package/capiagent/install
|
||||
$(CP) ./files/* $(1)/
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_DIR) $(1)/lib/wifi/capi
|
||||
@@ -54,4 +54,4 @@ define Package/wfa-capi/install
|
||||
$(CP) $(PKG_BUILD_DIR)/src/scripts/* $(1)/lib/wifi/capi
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,wfa-capi))
|
||||
$(eval $(call BuildPackage,capiagent))
|
||||
35
capiagent/files/etc/init.d/capiagent
Executable file
35
capiagent/files/etc/init.d/capiagent
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=98
|
||||
STOP=20
|
||||
|
||||
USE_PROCD=1
|
||||
|
||||
start_service() {
|
||||
if [ -e "/etc/config/mapagent" -o -e "/etc/config/mapcontroller" ]; then
|
||||
config_load mapagent
|
||||
config_get_bool agent_enabled agent enabled 1
|
||||
config_load mapcontroller
|
||||
config_get_bool controller_enabled controller enabled 1
|
||||
|
||||
if [ $agent_enabled -eq 1 -o $controller_enabled -eq 1 ]; then
|
||||
procd_open_instance
|
||||
procd_set_param command "/usr/sbin/capiagent" "-p 9000"
|
||||
procd_set_param limits core="unlimited"
|
||||
#procd_set_param respawn
|
||||
#procd_set_param stdout 1
|
||||
#procd_set_param stderr 1
|
||||
procd_close_instance
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
procd_add_reload_trigger "capiagent"
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
52
cmph/Makefile
Normal file
52
cmph/Makefile
Normal 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)))
|
||||
|
||||
64
csmngr/Makefile
Normal file
64
csmngr/Makefile
Normal file
@@ -0,0 +1,64 @@
|
||||
#
|
||||
# Copyright (C) 2020-2024 IOPSYS Software Solutions AB
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=csmngr
|
||||
PKG_VERSION:=1.0.2
|
||||
|
||||
LOCAL_DEV=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=5e50fe388fff29b08d895c1c580152cccfa290ad
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/csmngr.git
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
endif
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@iopsys.eu>
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
PKG_CONFIG_DEPENDS := \
|
||||
CONFIG_PACKAGE_libwifiutils \
|
||||
CONFIG_PACKAGE_libwifi
|
||||
|
||||
PKG_BUILD_DEPENDS := libwifi
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
|
||||
MAKE_PATH:=src
|
||||
|
||||
define Package/csmngr
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=WiFi channel selection manager
|
||||
DEPENDS:=+libwifiutils +libwifi +libuci +libubox +ubus +libnl-genl
|
||||
endef
|
||||
|
||||
define Package/csmngr/description
|
||||
WiFi Auto Channel Selection manager.
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-I$(STAGING_DIR)/usr/include \
|
||||
-I$(STAGING_DIR)/usr/include/libnl3 \
|
||||
-D_GNU_SOURCE
|
||||
|
||||
ifeq ($(LOCAL_DEV),1)
|
||||
define Build/Prepare
|
||||
rsync -r --exclude=.* ~/git/csmngr/ $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
endif
|
||||
|
||||
define Package/csmngr/install
|
||||
$(CP) ./files/* $(1)/
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/csmngr $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,csmngr))
|
||||
6
ethmngr/files/ethmngr.init → csmngr/files/etc/init.d/csmngr
Normal file → Executable file
6
ethmngr/files/ethmngr.init → csmngr/files/etc/init.d/csmngr
Normal file → Executable file
@@ -4,12 +4,13 @@ START=95
|
||||
STOP=10
|
||||
|
||||
USE_PROCD=1
|
||||
PROG=/usr/sbin/ethmngr
|
||||
PROG=/usr/sbin/csmngr
|
||||
|
||||
start_service() {
|
||||
procd_open_instance
|
||||
procd_set_param command ${PROG}
|
||||
procd_set_param respawn
|
||||
# procd_set_param stderr 1 #for debugging only
|
||||
# procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
@@ -17,3 +18,4 @@ reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
16
ddnsmngr/Config.in
Normal file
16
ddnsmngr/Config.in
Normal file
@@ -0,0 +1,16 @@
|
||||
if PACKAGE_ddnsmngr
|
||||
choice
|
||||
prompt "Select backend for dynamic DNS management"
|
||||
default DDNSMNGR_BACKEND_DDNSSCRIPT
|
||||
depends on PACKAGE_ddnsmngr
|
||||
help
|
||||
Select which package to use for dynamic DNS support
|
||||
|
||||
config DDNSMNGR_BACKEND_DDNSSCRIPT
|
||||
bool "Use ddns_script"
|
||||
|
||||
config DDNSMNGR_BACKEND_INADYN
|
||||
bool "Use inadyn"
|
||||
|
||||
endchoice
|
||||
endif
|
||||
79
ddnsmngr/Makefile
Normal file
79
ddnsmngr/Makefile
Normal file
@@ -0,0 +1,79 @@
|
||||
#
|
||||
# Copyright (C) 2024 IOPSYS
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ddnsmngr
|
||||
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:=44af9a7b3fec3929f8554af9633a5b8068189b48
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
endif
|
||||
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
PKG_CONFIG_DEPENDS:=CONFIG_DDNSMNGR_BACKEND_DDNSSCRIPT CONFIG_DDNSMNGR_BACKEND_INADYN
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(TOPDIR)/feeds/iopsys/bbfdm/bbfdm.mk
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
SUBMENU:=TRx69
|
||||
TITLE:=Dynamic DNS manager
|
||||
DEPENDS:=+DDNSMNGR_BACKEND_DDNSSCRIPT:ddns-scripts +DDNSMNGR_BACKEND_INADYN:inadyn
|
||||
DEPENDS+=+libbbfdm-api +libbbfdm-ubus +dm-service
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/config
|
||||
source "$(SOURCE)/Config.in"
|
||||
endef
|
||||
|
||||
MAKE_PATH:=src
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
Manage dynamic DNS updation and provides Device.DynamicDNS. datamodel object based on TR181-2.16
|
||||
endef
|
||||
|
||||
ifeq ($(LOCAL_DEV),1)
|
||||
define Build/Prepare
|
||||
$(CP) -rf ~/git/ddnsmngr/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
endif
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/etc/ddnsmngr/ddns
|
||||
$(INSTALL_DIR) $(1)/etc/ddnsmngr/servers
|
||||
$(INSTALL_DIR) $(1)/usr/lib/ddnsmngr
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_DIR) $(1)/usr/libexec/rpcd
|
||||
$(INSTALL_DATA) ./files/etc/config/ddnsmngr $(1)/etc/config/ddnsmngr
|
||||
$(INSTALL_BIN) ./files/etc/uci-defaults/01-ddns-config-migrate $(1)/etc/uci-defaults/
|
||||
$(INSTALL_BIN) ./files/etc/init.d/ddnsmngr $(1)/etc/init.d/ddnsmngr
|
||||
ifeq ($(CONFIG_DDNSMNGR_BACKEND_DDNSSCRIPT),y)
|
||||
$(INSTALL_BIN) ./files/usr/lib/ddns_script/ddnsmngr_service.sh $(1)/usr/lib/ddnsmngr/
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns-script/usr/lib/ddnsmngr/ddnsmngr_updater.sh $(1)/usr/lib/ddnsmngr/
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/ddns-script/server/* $(1)/etc/ddnsmngr/servers
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns-script/usr/libexec/rpcd/ddnsmngr $(1)/usr/libexec/rpcd/ddnsmngr
|
||||
endif
|
||||
ifeq ($(CONFIG_DDNSMNGR_BACKEND_INADYN),y)
|
||||
$(INSTALL_BIN) ./files/usr/lib/inadyn/ddnsmngr_service.sh $(1)/usr/lib/ddnsmngr/
|
||||
$(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
|
||||
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
16
ddnsmngr/bbfdm_service.json
Normal file
16
ddnsmngr/bbfdm_service.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"daemon": {
|
||||
"enable": "1",
|
||||
"service_name": "ddnsmngr",
|
||||
"unified_daemon": false,
|
||||
"services": [
|
||||
{
|
||||
"parent_dm": "Device.",
|
||||
"object": "DynamicDNS"
|
||||
}
|
||||
],
|
||||
"config": {
|
||||
"loglevel": "3"
|
||||
}
|
||||
}
|
||||
}
|
||||
23
ddnsmngr/files/etc/config/ddnsmngr
Normal file
23
ddnsmngr/files/etc/config/ddnsmngr
Normal file
@@ -0,0 +1,23 @@
|
||||
config ddnsmngr 'global'
|
||||
option configfile '/var/run/ddnsmngr/ddnsmngr.json'
|
||||
option ddns_dateformat '%F %R'
|
||||
option ddns_rundir '/var/run/ddnsmngr'
|
||||
option ddns_logdir '/var/log/ddnsmngr'
|
||||
option ddns_loglines '250'
|
||||
option upd_privateip '0'
|
||||
option use_curl '1'
|
||||
|
||||
config server 'ddns_server_1'
|
||||
option enabled '1'
|
||||
option service 'dynu.com'
|
||||
option name 'dynu.com'
|
||||
|
||||
config server 'ddns_server_2'
|
||||
option enabled '1'
|
||||
option service 'dyndns.org'
|
||||
option name 'dyndns.org'
|
||||
|
||||
config server 'ddns_server_3'
|
||||
option enabled '1'
|
||||
option service 'zoneedit.com'
|
||||
option name 'zoneedit.com'
|
||||
26
ddnsmngr/files/etc/init.d/ddnsmngr
Normal file
26
ddnsmngr/files/etc/init.d/ddnsmngr
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=80
|
||||
STOP=10
|
||||
USE_PROCD=1
|
||||
|
||||
. /usr/lib/ddnsmngr/ddnsmngr_service.sh
|
||||
|
||||
start_service() {
|
||||
start_ddnsmngr_service
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
stop_ddnsmngr_service
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
sleep 1
|
||||
start
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger ddnsmngr
|
||||
add_ddnsmngr_triggers
|
||||
}
|
||||
170
ddnsmngr/files/etc/uci-defaults/01-ddns-config-migrate
Normal file
170
ddnsmngr/files/etc/uci-defaults/01-ddns-config-migrate
Normal file
@@ -0,0 +1,170 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
|
||||
cl_id=1
|
||||
srv_id=1
|
||||
|
||||
function get_ddns_config_option() {
|
||||
local val
|
||||
|
||||
val="$(uci -q get ddns.${1}.${2})"
|
||||
|
||||
if [ -z "${val}" ] && [ -n "${3}" ]; then
|
||||
val="${3}"
|
||||
fi
|
||||
|
||||
echo "${val}"
|
||||
}
|
||||
|
||||
function config_supported_service() {
|
||||
if ! uci -q get ddnsmngr.global >/dev/null 2>&1; then
|
||||
uci -q set ddnsmngr.global="ddnsmngr"
|
||||
fi
|
||||
|
||||
servers=""
|
||||
|
||||
for i in $(find /etc/ddnsmngr/servers/ -name '*.json' | cut -d'/' -f 5 | sed "s/.json//")
|
||||
do
|
||||
if [ -z "${servers}" ]; then
|
||||
servers="${i}"
|
||||
else
|
||||
servers="${servers},${i}"
|
||||
fi
|
||||
done
|
||||
|
||||
uci -q set ddnsmngr.global.supported_services="${servers}"
|
||||
}
|
||||
|
||||
function migrate_service_section() {
|
||||
client_sec=""
|
||||
enabled="$(get_ddns_config_option ${1} enabled "0")"
|
||||
service_name="$(get_ddns_config_option ${1} service_name)"
|
||||
interface="$(get_ddns_config_option ${1} interface)"
|
||||
ip_network="$(get_ddns_config_option ${1} ip_network)"
|
||||
username="$(get_ddns_config_option ${1} username)"
|
||||
password="$(get_ddns_config_option ${1} password)"
|
||||
lookup_host="$(get_ddns_config_option ${1} lookup_host)"
|
||||
use_ipv6="$(get_ddns_config_option ${1} use_ipv6 "0")"
|
||||
force_ipversion="$(get_ddns_config_option ${1} force_ipversion "0")"
|
||||
use_https="$(get_ddns_config_option ${1} use_https "0")"
|
||||
force_dnstcp="$(get_ddns_config_option ${1} force_dnstcp "0")"
|
||||
|
||||
if [ -z "${service_name}" ]; then
|
||||
uci -q delete ddns."${1}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# check server file is present in device
|
||||
if [ ! -f "/etc/ddnsmngr/servers/${service_name}.json" ]; then
|
||||
uci -q delete ddns."${1}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if client section is already added for this service
|
||||
clients=$(uci -q show ddnsmngr | grep "=client")
|
||||
client_count=$(echo "${clients}" | wc -l)
|
||||
|
||||
tmp=0
|
||||
while [ $tmp -lt $client_count ]
|
||||
do
|
||||
mngr_serv="$(uci -q get ddnsmngr.@client[$tmp].service_name)"
|
||||
mngr_intf="$(uci -q get ddnsmngr.@client[$tmp].interface)"
|
||||
mngr_netw="$(uci -q get ddnsmngr.@client[$tmp].ip_network)"
|
||||
mngr_user="$(uci -q get ddnsmngr.@client[$tmp].username)"
|
||||
mngr_ipv6="$(uci -q get ddnsmngr.@client[$tmp].use_ipv6)"
|
||||
mngr_forceip="$(uci -q get ddnsmngr.@client[$tmp].force_ipversion)"
|
||||
mngr_https="$(uci -q get ddnsmngr.@client[$tmp].use_https)"
|
||||
mngr_dnstcp="$(uci -q get ddnsmngr.@client[$tmp].force_dnstcp)"
|
||||
|
||||
[ -z "${mngr_ipv6}" ] && mngr_ipv6="0"
|
||||
[ -z "${mngr_forceip}" ] && mngr_forceip="0"
|
||||
[ -z "${mngr_https}" ] && mngr_https="0"
|
||||
[ -z "${mngr_dnstcp}" ] && mngr_dnstcp="0"
|
||||
|
||||
if [ "${mngr_serv}" == "${service_name}" ] && [ "${mngr_intf}" == "${interface}" ] && \
|
||||
[ "${mngr_netw}" == "${ip_network}" ] && [ "${mngr_user}" == "${username}" ] && \
|
||||
[ "${mngr_ipv6}" == "${use_ipv6}" ] && [ "${mngr_forceip}" == "${force_ipversion}" ] && \
|
||||
[ "${mngr_https}" == "${use_https}" ] && [ "${mngr_dnstcp}" == "${force_dnstcp}" ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
tmp=$(( tmp + 1 ))
|
||||
done
|
||||
|
||||
if [ $tmp -ne $client_count ]; then
|
||||
i=0
|
||||
for client in $clients; do
|
||||
if [ $i -eq $tmp ]; then
|
||||
client_sec="$(echo $client | cut -d'=' -f 1 | cut -d'.' -f 2)"
|
||||
break
|
||||
fi
|
||||
i=$(( i + 1 ))
|
||||
done
|
||||
|
||||
if [ $enabled -eq 1 ]; then
|
||||
uci -q set ddnsmngr."${client_sec}".enabled="1"
|
||||
fi
|
||||
else
|
||||
client_sec=ddns_mig_client_"${cl_id}"
|
||||
|
||||
uci -q set ddnsmngr."${client_sec}"="client"
|
||||
uci -q set ddnsmngr."${client_sec}".enabled="${enabled}"
|
||||
uci -q set ddnsmngr."${client_sec}".service_name="${service_name}"
|
||||
uci -q set ddnsmngr."${client_sec}".interface="${interface}"
|
||||
uci -q set ddnsmngr."${client_sec}".ip_network="${ip_network}"
|
||||
uci -q set ddnsmngr."${client_sec}".username="${username}"
|
||||
uci -q set ddnsmngr."${client_sec}".password="${password}"
|
||||
uci -q set ddnsmngr."${client_sec}".use_ipv6="${use_ipv6}"
|
||||
uci -q set ddnsmngr."${client_sec}".force_ipversion="${force_ipversion}"
|
||||
uci -q set ddnsmngr."${client_sec}".use_https="${use_https}"
|
||||
uci -q set ddnsmngr."${client_sec}".force_dnstcp="${force_dnstcp}"
|
||||
|
||||
cl_id=$(( cl_id + 1 ))
|
||||
|
||||
# add server section if not added
|
||||
servers=$(uci -q show ddnsmngr | grep "service=\'${service_name}\'")
|
||||
if [ -z "${servers}" ]; then
|
||||
server_sec=ddns_mig_server_"${srv_id}"
|
||||
uci -q set ddnsmngr."${server_sec}"="server"
|
||||
uci -q set ddnsmngr."${server_sec}".enabled="1"
|
||||
uci -q set ddnsmngr."${server_sec}".service="${service_name}"
|
||||
uci -q set ddnsmngr."${server_sec}".name="${service_name}"
|
||||
|
||||
srv_id=$(( srv_id + 1 ))
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# if lookup_host is set then add host section
|
||||
if [ -n "${lookup_host}" ] && [ -n "${client_sec}" ]; then
|
||||
# check number of hosts present for this client
|
||||
host_count=$(uci -q show ddnsmngr | grep "dm_parent=\'${client_sec}\'" | wc -l)
|
||||
host_ix=$(( host_count + 1 ))
|
||||
host_sec="${client_sec}"_host_"${host_ix}"
|
||||
|
||||
uci -q set ddnsmngr."${host_sec}"="host"
|
||||
uci -q set ddnsmngr."${host_sec}".enabled="${enabled}"
|
||||
uci -q set ddnsmngr."${host_sec}".lookup_host="${lookup_host}"
|
||||
uci -q set ddnsmngr."${host_sec}".dm_parent="${client_sec}"
|
||||
fi
|
||||
|
||||
uci -q delete ddns."${1}"
|
||||
}
|
||||
|
||||
function migrate_ddns_config() {
|
||||
if [ ! -f "/etc/config/ddnsmngr" ]; then
|
||||
# Create ddnsmngr config file
|
||||
touch /etc/config/ddnsmngr
|
||||
fi
|
||||
|
||||
config_supported_service
|
||||
|
||||
config_load ddns
|
||||
config_foreach migrate_service_section service
|
||||
|
||||
uci -q commit ddns
|
||||
uci -q commit ddnsmngr
|
||||
}
|
||||
|
||||
migrate_ddns_config
|
||||
169
ddnsmngr/files/usr/lib/ddns_script/ddnsmngr_service.sh
Normal file
169
ddnsmngr/files/usr/lib/ddns_script/ddnsmngr_service.sh
Normal file
@@ -0,0 +1,169 @@
|
||||
#! /bin/sh
|
||||
|
||||
RUNDIR="/var/run/ddnsmngr"
|
||||
LOGDIR="/var/log/ddnsmngr"
|
||||
PROG="/usr/lib/ddnsmngr/ddnsmngr_updater.sh"
|
||||
CONFIGFILE="/var/run/ddnsmngr/ddnsmngr.json"
|
||||
CLIENT_INTFS=""
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
log() {
|
||||
echo "$*"|logger -t ddnsmngr.init -p debug
|
||||
}
|
||||
|
||||
validate_host_section() {
|
||||
uci_validate_section ddnsmngr host "${1}" \
|
||||
'enabled:bool:0' \
|
||||
'lookup_host:string' \
|
||||
'dm_parent:string'
|
||||
}
|
||||
|
||||
validate_client_section() {
|
||||
uci_validate_section ddnsmngr client "${1}" \
|
||||
'enabled:bool:0' \
|
||||
'service_name:string' \
|
||||
'interface:string' \
|
||||
'ip_network:string' \
|
||||
'username:string' \
|
||||
'password:string' \
|
||||
'use_https:bool:0' \
|
||||
'force_dnstcp:bool:0' \
|
||||
'use_ipv6:bool:0' \
|
||||
'force_ipversion:bool:0'
|
||||
}
|
||||
|
||||
add_object() {
|
||||
local enabled lookup_host dm_parent use_ipv6 force_ipversion proc_info_file
|
||||
local service_name interface ip_network username password use_https force_dnstcp
|
||||
|
||||
validate_host_section "${1}" || {
|
||||
log "Validation of host section failed"
|
||||
return 0
|
||||
}
|
||||
|
||||
if [ "${enabled}" -ne 1 ] || [ -z "${dm_parent}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
validate_client_section "${dm_parent}" || {
|
||||
log "Validation of client section failed"
|
||||
return 0
|
||||
}
|
||||
|
||||
if [ "${enabled}" -ne 1 ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
service_name=$(uci -q get ddnsmngr.${dm_parent}.service_name)
|
||||
if [ -z "${service_name}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
service_section=$(uci -q show ddnsmngr | grep "service=\'${service_name}\'" | cut -d'.' -f 2 | head -1)
|
||||
if [ -z "${service_section}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
service_enabled=$(uci -q get ddnsmngr.${service_section}.enabled)
|
||||
if [ "${service_enabled}" -ne 1 ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
json_add_object
|
||||
json_add_string "interface" "${interface}"
|
||||
json_add_string "service_name" "${service_name}"
|
||||
json_add_string "username" "${username}"
|
||||
json_add_string "password" "${password}"
|
||||
json_add_string "lookup_host" "${lookup_host}"
|
||||
json_add_string "ip_network" "${ip_network}"
|
||||
json_add_string "proc_info_file" "${1}"
|
||||
json_add_string "use_ipv6" "${use_ipv6}"
|
||||
json_add_string "force_ipversion" "${force_ipversion}"
|
||||
json_add_string "use_https" "${use_https}"
|
||||
json_add_string "force_dnstcp" "${force_dnstcp}"
|
||||
json_close_object
|
||||
|
||||
if [ -z "${interface}" ]; then
|
||||
if [ "${use_ipv6}" -eq 0 ]; then
|
||||
interface="wan"
|
||||
else
|
||||
interface="wan6"
|
||||
fi
|
||||
fi
|
||||
|
||||
for intf in $CLIENT_INTFS; do
|
||||
if [ "${intf}" == "${interface}" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
CLIENT_INTFS="${CLIENT_INTFS} ${interface}"
|
||||
}
|
||||
|
||||
start_ddnsmngr_service() {
|
||||
run_dir=$(uci -q get ddnsmngr.global.ddns_rundir)
|
||||
log_dir=$(uci -q get ddnsmngr.global.ddns_logdir)
|
||||
|
||||
if [ -n "${run_dir}" ]; then
|
||||
RUNDIR="${run_dir}"
|
||||
fi
|
||||
|
||||
if [ -n "${log_dir}" ]; then
|
||||
LOGDIR="${log_dir}"
|
||||
fi
|
||||
|
||||
mkdir -p "${RUNDIR}"
|
||||
mkdir -p "${LOGDIR}"
|
||||
|
||||
conf_file=$(uci -q get ddnsmngr.global.configfile)
|
||||
if [ -n "${conf_file}" ]; then
|
||||
CONFIGFILE="${conf_file}"
|
||||
fi
|
||||
|
||||
touch "${CONFIGFILE}"
|
||||
|
||||
if [ ! -f "${CONFIGFILE}" ]; then
|
||||
log "Can not create ${CONFIGFILE}, exit"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
json_init
|
||||
json_add_array "services"
|
||||
|
||||
config_load ddnsmngr
|
||||
config_foreach add_object host
|
||||
|
||||
json_close_array
|
||||
json_dump > "${CONFIGFILE}"
|
||||
|
||||
procd_open_instance ddnsmngr
|
||||
procd_set_param command "$PROG"
|
||||
procd_append_param command -c "${CONFIGFILE}"
|
||||
procd_append_param command -- start
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
stop_ddnsmngr_service() {
|
||||
conf_file=$(uci -q get ddnsmngr.global.configfile)
|
||||
if [ -n "${conf_file}" ]; then
|
||||
CONFIGFILE="${conf_file}"
|
||||
fi
|
||||
|
||||
if [ ! -f "${CONFIGFILE}" ]; then
|
||||
log "${CONFIGFILE} not found, can't stop services if running any"
|
||||
fi
|
||||
|
||||
"$PROG" -c "${CONFIGFILE}" -- stop
|
||||
return 0
|
||||
}
|
||||
|
||||
add_ddnsmngr_triggers() {
|
||||
procd_open_trigger
|
||||
for intf in $CLIENT_INTFS; do
|
||||
# No need to handle other ifevents like ifupdate etc
|
||||
procd_add_interface_trigger "interface.*.up" $intf /etc/init.d/ddnsmngr restart
|
||||
procd_add_interface_trigger "interface.*.down" $intf /etc/init.d/ddnsmngr restart
|
||||
done
|
||||
procd_close_trigger
|
||||
}
|
||||
311
ddnsmngr/files/usr/lib/inadyn/ddnsmngr_service.sh
Normal file
311
ddnsmngr/files/usr/lib/inadyn/ddnsmngr_service.sh
Normal file
@@ -0,0 +1,311 @@
|
||||
#!/bin/sh
|
||||
|
||||
PROG="/usr/sbin/inadyn"
|
||||
CONFIGPATH="/tmp/inadyn_config"
|
||||
PIDPATH="/etc/inadyn_pid"
|
||||
CLIENT_INTFS=""
|
||||
CONFIG_FILES=""
|
||||
SERVER_PATH="/etc/ddnsmngr/servers"
|
||||
|
||||
FORMAT="custom [SECTION] {\n\tusername\t= [USER]\n\tpassword\t= [PWD]\n\tddns-server\t= [SERV]\n\tddns-path\t= [URI]\n\tssl\t\t= [SSL]\n\thostname\t= [NAME]\n\tcheckip-command\t= [CMD]\n\tddns-response\t= [RESPONSES]\n}"
|
||||
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
log() {
|
||||
echo "$*"|logger -t ddnsmngr.init -p debug
|
||||
}
|
||||
|
||||
get_service_data() {
|
||||
local provider="$1"
|
||||
shift
|
||||
local dir="$1"
|
||||
shift
|
||||
local ipv6="$1"
|
||||
shift
|
||||
|
||||
local name data url answer script
|
||||
|
||||
[ $# -ne 2 ] && {
|
||||
return 1
|
||||
}
|
||||
|
||||
[ -f "${dir}/${provider}.json" ] || {
|
||||
eval "$1=\"\""
|
||||
eval "$2=\"\""
|
||||
return 1
|
||||
}
|
||||
|
||||
json_load_file "${dir}/${provider}.json"
|
||||
json_get_var name "name"
|
||||
if [ "$ipv6" -eq "1" ]; then
|
||||
json_select "ipv6"
|
||||
else
|
||||
json_select "ipv4"
|
||||
fi
|
||||
json_get_var data "url"
|
||||
json_get_var answer "answer"
|
||||
json_select ".."
|
||||
json_cleanup
|
||||
|
||||
response=""
|
||||
if [ -n "${answer}" ]; then
|
||||
answer=$(echo "${answer}" | sed 's/|/ /g')
|
||||
for ans in $answer; do
|
||||
if [ -z "${response}" ]; then
|
||||
response="${ans}"
|
||||
else
|
||||
response="${response}, ${ans}"
|
||||
fi
|
||||
done
|
||||
response="{ ${response} }"
|
||||
fi
|
||||
|
||||
eval "$1=\"$data\""
|
||||
eval "$2=\"$response\""
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
generate_inadyn_config() {
|
||||
json_load "${1}"
|
||||
json_get_var service_name service_name
|
||||
json_get_var use_ipv6 use_ipv6
|
||||
json_get_var interface interface
|
||||
json_get_var username username
|
||||
json_get_var password password
|
||||
json_get_var host lookup_host
|
||||
json_get_var conf_file config_file
|
||||
json_get_var conf_dir config_dir
|
||||
json_get_var server_address server_address
|
||||
json_cleanup
|
||||
|
||||
if [ -z "${service_name}" ] || [ -z "${host}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${conf_file}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${conf_dir}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# First look into custom path to load the url otherwise default path
|
||||
get_service_data "${service_name}" "${SERVER_PATH}" "${use_ipv6}" server_url server_answer
|
||||
|
||||
if [ -z "${server_url}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Need to pick proto, server address and request uri separately from the url
|
||||
# format http://[server_address]/[update_Request_uri]
|
||||
proto=$(echo $server_url | cut -d':' -f 1)
|
||||
serv=$(echo $server_url | cut -d'/' -f 3 | cut -d'@' -f 2)
|
||||
uri=${server_url#*$serv}
|
||||
|
||||
if [ -z $proto ] || [ -z $serv ] || [ -z $uri ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
path=$(echo "$uri" | sed 's/&/\\&/g')
|
||||
update_uri=$(echo $path | sed -e "s#\[DOMAIN\]#%h#g" -e "s#\[PASSWORD\]#%p#g" \
|
||||
-e "s#\[USERNAME\]#%u#g" -e "s#\[IP\]#%i#g")
|
||||
|
||||
if [ -z "${interface}" ]; then
|
||||
if [ "${use_ipv6}" -eq 0 ]; then
|
||||
interface="wan"
|
||||
else
|
||||
interface="wan6"
|
||||
fi
|
||||
fi
|
||||
|
||||
# now get the physical interface name
|
||||
intf=$(ifstatus "${interface}" | jsonfilter -e '@.device')
|
||||
if [ -z "${intf}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# command to get ip of the interface
|
||||
if [ "${use_ipv6}" -eq 0 ]; then
|
||||
get_ip="\"ifstatus ${interface} | jsonfilter -e '@[\\\\\"ipv4-address\\\\\"][0].address'\""
|
||||
else
|
||||
get_ip="\"ifstatus ${interface} | jsonfilter -e '@[\\\\\"ipv6-address\\\\\"][0].address'\""
|
||||
fi
|
||||
|
||||
if [ "${proto}" = "http" ]; then
|
||||
ssl="false"
|
||||
else
|
||||
ssl="true"
|
||||
fi
|
||||
|
||||
inadyn_ver=$(inadyn -v)
|
||||
user_agent="inadyn/${inadyn_ver}"
|
||||
|
||||
config_file="${conf_dir}/${conf_file}"
|
||||
touch "${config_file}"
|
||||
|
||||
echo "iface = ${intf}" > "${config_file}"
|
||||
echo "period = 600" >> "${config_file}"
|
||||
echo "user-agent = ${user_agent}" >> "${config_file}"
|
||||
|
||||
if [ "${use_ipv6}" -eq 1 ]; then
|
||||
echo "allow-ipv6 = true" >> "${config_file}"
|
||||
fi
|
||||
|
||||
if [ -z "${password}" ]; then
|
||||
FORMAT=$(echo "${FORMAT}" | sed 's/\\tpassword\\t= \[PWD\]\\n//g')
|
||||
fi
|
||||
|
||||
if [ -z "${server_answer}" ]; then
|
||||
FORMAT=$(echo "${FORMAT}" | sed 's/\\tddns-response\\t= \[RESPONSES\]\\n//g')
|
||||
fi
|
||||
|
||||
config=$(echo $FORMAT | sed -e "s#\[SECTION\]#$conf_file#g" -e "s#\[PWD\]#$password#g" \
|
||||
-e "s#\[USER\]#$username#g" -e "s#\[SERV\]#$serv#g" \
|
||||
-e "s#\[URI\]#\"$update_uri\"#g" -e "s#\[SSL\]#$ssl#g" \
|
||||
-e "s#\[NAME\]#$host#g" -e "s#\[CMD\]#$get_ip#g" \
|
||||
-e "s#\[RESPONSES\]#$server_answer#g")
|
||||
|
||||
echo -e "\n\n${config}" >> "${config_file}"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
validate_host_section() {
|
||||
uci_validate_section ddnsmngr host "${1}" \
|
||||
'enabled:bool:0' \
|
||||
'lookup_host:string' \
|
||||
'dm_parent:string'
|
||||
}
|
||||
|
||||
validate_client_section() {
|
||||
uci_validate_section ddnsmngr client "${1}" \
|
||||
'enabled:bool:0' \
|
||||
'service_name:string' \
|
||||
'interface:string' \
|
||||
'ip_network:string' \
|
||||
'username:string' \
|
||||
'password:string' \
|
||||
'use_https:bool:0' \
|
||||
'force_dnstcp:bool:0' \
|
||||
'use_ipv6:bool:0' \
|
||||
'force_ipversion:bool:0'
|
||||
}
|
||||
|
||||
add_object() {
|
||||
local enabled lookup_host dm_parent use_ipv6 force_ipversion
|
||||
local service_name interface ip_network username password use_https force_dnstcp
|
||||
|
||||
validate_host_section "${1}" || {
|
||||
log "Validation of host section failed"
|
||||
return
|
||||
}
|
||||
|
||||
if [ "${enabled}" -ne 1 ] || [ -z "${dm_parent}" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
validate_client_section "${dm_parent}" || {
|
||||
log "Validation of client section failed"
|
||||
return
|
||||
}
|
||||
|
||||
if [ "${enabled}" -ne 1 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
service_name=$(uci -q get ddnsmngr.${dm_parent}.service_name)
|
||||
if [ -z "${service_name}" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
service_section=$(uci show ddnsmngr | grep "service=\'${service_name}\'" | cut -d'.' -f 2 | head -1)
|
||||
if [ -z "${service_section}" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
service_enabled=$(uci -q get ddnsmngr.${service_section}.enabled)
|
||||
if [ "${service_enabled}" -ne 1 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
json_init
|
||||
json_add_string "interface" "${interface}"
|
||||
json_add_string "service_name" "${service_name}"
|
||||
json_add_string "username" "${username}"
|
||||
json_add_string "password" "${password}"
|
||||
json_add_string "lookup_host" "${lookup_host}"
|
||||
json_add_string "ip_network" "${ip_network}"
|
||||
json_add_string "use_ipv6" "${use_ipv6}"
|
||||
json_add_string "force_ipversion" "${force_ipversion}"
|
||||
json_add_string "use_https" "${use_https}"
|
||||
json_add_string "force_dnstcp" "${force_dnstcp}"
|
||||
json_add_string "config_file" "${1}"
|
||||
json_add_string "config_dir" "${CONFIGPATH}"
|
||||
|
||||
json_str=$(json_dump)
|
||||
json_cleanup
|
||||
|
||||
generate_inadyn_config "${json_str}"
|
||||
|
||||
if [ "$?" -ne 0 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
CONFIG_FILES="${CONFIG_FILES} ${1}"
|
||||
|
||||
if [ -z "${interface}" ]; then
|
||||
if [ "${use_ipv6}" -eq 0 ]; then
|
||||
interface="wan"
|
||||
else
|
||||
interface="wan6"
|
||||
fi
|
||||
fi
|
||||
|
||||
for intf in $CLIENT_INTFS; do
|
||||
if [ "${intf}" == "${interface}" ]; then
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
CLIENT_INTFS="${CLIENT_INTFS} ${interface}"
|
||||
}
|
||||
|
||||
start_ddnsmngr_service() {
|
||||
rm -rf $CONFIGPATH
|
||||
mkdir $CONFIGPATH
|
||||
mkdir -p $PIDPATH
|
||||
|
||||
config_load ddnsmngr
|
||||
config_foreach add_object host
|
||||
|
||||
i=1
|
||||
for conf in $CONFIG_FILES; do
|
||||
instance="ddnsmngr_${i}"
|
||||
i=$(( i + 1 ))
|
||||
|
||||
procd_open_instance $instance
|
||||
procd_set_param command "$PROG"
|
||||
procd_append_param command -f "${CONFIGPATH}/${conf}"
|
||||
procd_append_param command -l debug
|
||||
procd_append_param command -P "${PIDPATH}/${conf}"
|
||||
procd_append_param command -n -C
|
||||
procd_close_instance
|
||||
done
|
||||
}
|
||||
|
||||
stop_ddnsmngr_service() {
|
||||
rm -rf $CONFIGPATH
|
||||
return 0
|
||||
}
|
||||
|
||||
add_ddnsmngr_triggers() {
|
||||
procd_open_trigger
|
||||
for intf in $CLIENT_INTFS; do
|
||||
# No need to handle other ifevents like ifupdate etc
|
||||
procd_add_interface_trigger "interface.*.up" $intf /etc/init.d/ddnsmngr restart
|
||||
done
|
||||
procd_close_trigger
|
||||
}
|
||||
7
decollector/Config.in
Normal file
7
decollector/Config.in
Normal file
@@ -0,0 +1,7 @@
|
||||
menu "Configuration"
|
||||
|
||||
config DECOLLECTOR_EASYMESH_VERSION
|
||||
int "Support Easymesh version"
|
||||
default 6
|
||||
|
||||
endmenu
|
||||
81
decollector/Makefile
Normal file
81
decollector/Makefile
Normal file
@@ -0,0 +1,81 @@
|
||||
#
|
||||
# Copyright (C) 2021-2024 IOPSYS Software Solutions AB
|
||||
# Copyright (C) 2025 Genexis AB
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=decollector
|
||||
PKG_VERSION:=6.2.1.7
|
||||
|
||||
LOCAL_DEV=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
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@genexis.eu>
|
||||
|
||||
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/decollector
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=WiFi DataElements Collector Proxy
|
||||
DEPENDS:=+libuci +libubox +ubus +libpthread +libnl-genl \
|
||||
+libeasy +libwifiutils +libieee1905 +ieee1905-map-plugin
|
||||
endef
|
||||
|
||||
define Package/decollector/description
|
||||
It implements the WiFi DataElements Agent as defined in the Wi-Fi Alliance's
|
||||
DataElements specification.
|
||||
endef
|
||||
|
||||
|
||||
define Package/decollector/config
|
||||
source "$(SOURCE)/Config.in"
|
||||
endef
|
||||
|
||||
ifneq (,$(findstring ALPHA,$(CONFIG_VERSION_CODE)))
|
||||
MAKE_FLAGS += DEBUG=1
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring BETA,$(CONFIG_VERSION_CODE)))
|
||||
MAKE_FLAGS += DEBUG=1
|
||||
endif
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-I$(STAGING_DIR)/usr/include \
|
||||
-I$(STAGING_DIR)/usr/include/libnl3 \
|
||||
-D_GNU_SOURCE
|
||||
|
||||
ifeq ($(LOCAL_DEV),1)
|
||||
define Build/Prepare
|
||||
rsync -r --exclude=.* ~/git/decollector/ $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
endif
|
||||
|
||||
MAKE_PATH:=src
|
||||
|
||||
TARGET_CFLAGS += -DEASYMESH_VERSION=$(CONFIG_DECOLLECTOR_EASYMESH_VERSION)
|
||||
|
||||
EXECS := \
|
||||
$(if $(CONFIG_PACKAGE_decollector),decollector)
|
||||
|
||||
MAKE_FLAGS += EXECS="$(EXECS)"
|
||||
|
||||
define Package/decollector/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) ./files/decollector.init $(1)/etc/init.d/decollector
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/decollector $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,decollector))
|
||||
@@ -17,10 +17,13 @@ start_service() {
|
||||
|
||||
config_load mapcontroller
|
||||
config_get en controller enabled "0"
|
||||
config_get collect_int controller de_collect_interval
|
||||
|
||||
[ -n "$collect_int" -a $collect_int -lt 30 ] && collect_int=""
|
||||
|
||||
[ $en -gt 0 ] && {
|
||||
procd_open_instance
|
||||
procd_set_param command "$PROG" "-d"
|
||||
procd_set_param command "$PROG" "-d" "${collect_int:+-t $collect_int}"
|
||||
#procd_set_param stdout 1
|
||||
#procd_set_param stderr 1
|
||||
procd_set_param respawn
|
||||
@@ -1,20 +1,14 @@
|
||||
#
|
||||
# Copyright (C) 2021 IOPSYS Software Solutions AB
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=dectmngr
|
||||
PKG_RELEASE:=3
|
||||
PKG_VERSION:=3.5.1
|
||||
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:=8c94908eb230dc453dd2f5575be6c06b086b2e7d
|
||||
PKG_SOURCE_VERSION:=1f851980a6ba616df54f79930225f8bcd563b711
|
||||
PKG_MIRROR_HASH:=skip
|
||||
endif
|
||||
|
||||
@@ -34,7 +28,7 @@ include $(INCLUDE_DIR)/package.mk
|
||||
define Package/$(PKG_NAME)
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=DECT Manager
|
||||
DEPENDS:= +libubox +ubus +uci +libxml2 +libjson-c
|
||||
DEPENDS:= +libubox +ubus +uci +libxml2 +libjson-c +gpiod-tools +voicemngr
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
@@ -62,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
|
||||
|
||||
@@ -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'
|
||||
|
||||
Binary file not shown.
@@ -6,31 +6,124 @@ START=70
|
||||
STOP=12
|
||||
|
||||
USE_PROCD=1
|
||||
NAME=dectmngr
|
||||
PROG=/usr/sbin/dectmngr
|
||||
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() {
|
||||
pidof $NAME && killall -q $NAME
|
||||
dect_pid=$(pidof $PROG)
|
||||
[ -n "$dect_pid" ] && kill $dect_pid
|
||||
|
||||
pidof $NAME && sleep 2 # wait for the process to stop gracefully
|
||||
while pidof $NAME; do
|
||||
killall -q -9 $NAME
|
||||
pidof $PROG > /dev/null 2>&1 && sleep 2 # wait for the process to stop gracefully
|
||||
while pidof $PROG > /dev/null 2>&1; do
|
||||
dect_pid=$(pidof $PROG)
|
||||
[ -n "$dect_pid" ] && kill -9 $dect_pid
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
has_dect() {
|
||||
[ -f "$DCX81_UART_DT_ALIAS" ]
|
||||
}
|
||||
|
||||
get_dcx81_device() {
|
||||
readonly dcx81_uart_dt_node="/proc/device-tree/$(cat "$DCX81_UART_DT_ALIAS" 2>/dev/null)"
|
||||
[ -e "$dcx81_uart_dt_node" ] || return 1
|
||||
for tty_dt_node in /sys/class/tty/*/device/of_node; do
|
||||
if [ "$tty_dt_node" -ef "$dcx81_uart_dt_node" ]; then
|
||||
readonly uevent_file="${tty_dt_node%%/device/of_node}/uevent"
|
||||
local device_name_line
|
||||
device_name_line="$(grep '^DEVNAME=' "$uevent_file")" || return 1
|
||||
readonly device="/dev/${device_name_line##DEVNAME=}"
|
||||
[ -c "$device" ] || return 1
|
||||
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=
|
||||
local model_id=
|
||||
local rxtun=
|
||||
|
||||
test $(db get hw.board.hasDect) = "0" && return
|
||||
if ! has_dect; then
|
||||
logger -t "$PROG" "Not starting because no DECT hardware is available."
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo 1 > /sys/class/gpio/gpio14/value
|
||||
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="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"
|
||||
@@ -47,20 +140,30 @@ 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
|
||||
if [ "$log_dect_cmbs" = "none" ]; then
|
||||
|
||||
case "$log_dect_cmbs" in
|
||||
none)
|
||||
echo "Starting dectmngr with cmbs logging disabled"
|
||||
procd_set_param command $PROG -comname ttyH0 $opt_ext
|
||||
procd_set_param command "$PROG" -comname "$dcx81_uart_device" $opt_ext
|
||||
rm -f $LOG_PATH/*
|
||||
elif [ "$log_dect_cmbs" = "file" ]; then
|
||||
;;
|
||||
file)
|
||||
echo "Starting dectmngr with cmbs logging enabled to file"
|
||||
procd_set_param command $PROG -comname ttyH0 -log $LOG_PATH/dect-cmbs.log $opt_ext
|
||||
else
|
||||
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 ttyH0 -syslog $opt_ext
|
||||
procd_set_param command "$PROG" -comname "$dcx81_uart_device" -syslog $opt_ext
|
||||
rm -f $LOG_PATH/*
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
procd_set_param respawn 6 2 3
|
||||
procd_set_param term_timeout 20
|
||||
@@ -69,9 +172,8 @@ start_service() {
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
test $(db get hw.board.hasDect) = "0" && return
|
||||
has_dect || return 0
|
||||
|
||||
echo 0 > /sys/class/gpio/gpio14/value
|
||||
stop_and_wait_dectmngr
|
||||
}
|
||||
|
||||
@@ -79,18 +181,13 @@ reload_service() {
|
||||
ubus call dect reload
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
service_triggers() {
|
||||
procd_add_config_trigger "config.change" "asterisk" /etc/init.d/dectmngr restart
|
||||
procd_add_config_trigger "config.change" "dect" /etc/init.d/dectmngr reload
|
||||
}
|
||||
|
||||
boot() {
|
||||
echo 14 > /sys/class/gpio/export
|
||||
echo out > /sys/class/gpio/gpio14/direction
|
||||
|
||||
[ ! -d $LOG_PATH ] && mkdir -p $LOG_PATH
|
||||
[ ! -d $DB_PATH ] && mkdir -p $DB_PATH
|
||||
start
|
||||
}
|
||||
|
||||
|
||||
BIN
dectmngr/firmware/common/04130013.bin
Normal file
BIN
dectmngr/firmware/common/04130013.bin
Normal file
Binary file not shown.
59
dhcpmngr/Makefile
Normal file
59
dhcpmngr/Makefile
Normal file
@@ -0,0 +1,59 @@
|
||||
#
|
||||
# Copyright (C) 2024 IOPSYS Software Solutions AB
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=dhcpmngr
|
||||
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:=986f66608959f4f589009d580b046e250d8c620d
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
endif
|
||||
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include ../bbfdm/bbfdm.mk
|
||||
|
||||
MAKE_PATH:=src
|
||||
|
||||
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
|
||||
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
|
||||
Package to add Device.DHCPv4. and Device.DHCPv6. data model support.
|
||||
endef
|
||||
|
||||
ifeq ($(LOCAL_DEV),1)
|
||||
define Build/Prepare
|
||||
$(CP) -rf ~/git/dhcpmngr/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
endif
|
||||
|
||||
define Package/dhcpmngr/install
|
||||
$(INSTALL_DIR) $(1)/etc/udhcpc.user.d
|
||||
$(INSTALL_BIN) ./files/etc/udhcpc.user.d/udhcpc_lease_start_time.user $(1)/etc/udhcpc.user.d/udhcpc_lease_start_time.user
|
||||
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
|
||||
|
||||
$(eval $(call BuildPackage,dhcpmngr))
|
||||
20
dhcpmngr/bbfdm_service.json
Normal file
20
dhcpmngr/bbfdm_service.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
17
dhcpmngr/files/etc/uci-defaults/unbound.odhcpd.uci_default
Normal file
17
dhcpmngr/files/etc/uci-defaults/unbound.odhcpd.uci_default
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
# update odhcpd uci to use unbound's script as leasetrigger
|
||||
uci -q get dhcp.odhcpd >/dev/null 2>&1 && {
|
||||
maindhcp="$(uci -q get dhcp.odhcpd.maindhcp)"
|
||||
|
||||
# if odhcpd is the main dhcp
|
||||
[ "$maindhcp" = "1" ] || [ "$maindhcp" = "true" ] || [ "$maindhcp" = "on" ] && {
|
||||
# if unbound daemon and unbound script file is present
|
||||
[ -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'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
leasestarttime="$(awk -F'.' '{print $1}' /proc/uptime 2> /dev/null)"
|
||||
target_file=/tmp/dhcp_client_info
|
||||
target_str="$INTERFACE $lease $leasestarttime"
|
||||
|
||||
# if this interface is present in file, then replace it
|
||||
if grep -q "$INTERFACE" "$target_file" 2> /dev/null; then
|
||||
# replace the whole line if pattern matches
|
||||
sed -i "/${INTERFACE}/c\\${target_str}" "$target_file"
|
||||
else
|
||||
# interface info was not present, append it to the file
|
||||
echo "$target_str" >> "$target_file"
|
||||
fi
|
||||
BIN
dm-framework/datamodels/._Makefile
Executable file
BIN
dm-framework/datamodels/._Makefile
Executable file
Binary file not shown.
76
dm-framework/datamodels/Makefile
Normal file
76
dm-framework/datamodels/Makefile
Normal 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)))
|
||||
BIN
dm-framework/datamodels/src/._qjs-handlers-validate.js
Executable file
BIN
dm-framework/datamodels/src/._qjs-handlers-validate.js
Executable file
Binary file not shown.
41
dm-framework/datamodels/src/Makefile
Normal file
41
dm-framework/datamodels/src/Makefile
Normal 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)
|
||||
BIN
dm-framework/datamodels/src/dm-files/Bridge/._VLANBridge.json
Executable file
BIN
dm-framework/datamodels/src/dm-files/Bridge/._VLANBridge.json
Executable file
Binary file not shown.
443
dm-framework/datamodels/src/dm-files/Bridge/VLANBridge.json
Normal file
443
dm-framework/datamodels/src/dm-files/Bridge/VLANBridge.json
Normal 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."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
166
dm-framework/datamodels/src/dm-files/Bridge/bridge-apply.js
Normal file
166
dm-framework/datamodels/src/dm-files/Bridge/bridge-apply.js
Normal 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']);
|
||||
}
|
||||
});
|
||||
}
|
||||
125
dm-framework/datamodels/src/dm-files/Bridge/bridge-import.js
Normal file
125
dm-framework/datamodels/src/dm-files/Bridge/bridge-import.js
Normal 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;
|
||||
}
|
||||
133
dm-framework/datamodels/src/dm-files/Bridge/bridge.js
Normal file
133
dm-framework/datamodels/src/dm-files/Bridge/bridge.js
Normal 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;
|
||||
}
|
||||
61
dm-framework/datamodels/src/dm-files/Bridge/common.js
Executable file
61
dm-framework/datamodels/src/dm-files/Bridge/common.js
Executable 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;
|
||||
}
|
||||
}
|
||||
126
dm-framework/datamodels/src/dm-files/uci.js
Executable file
126
dm-framework/datamodels/src/dm-files/uci.js
Executable 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;
|
||||
}
|
||||
268
dm-framework/datamodels/src/dm-files/utils.js
Normal file
268
dm-framework/datamodels/src/dm-files/utils.js
Normal 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;
|
||||
}
|
||||
1507
dm-framework/datamodels/src/dm_node.c
Normal file
1507
dm-framework/datamodels/src/dm_node.c
Normal file
File diff suppressed because it is too large
Load Diff
290
dm-framework/datamodels/src/dm_node.h
Normal file
290
dm-framework/datamodels/src/dm_node.h
Normal 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
|
||||
97
dm-framework/datamodels/src/dm_types.h
Normal file
97
dm-framework/datamodels/src/dm_types.h
Normal 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
|
||||
BIN
dm-framework/datamodels/src/scripts/._json2code.js
Executable file
BIN
dm-framework/datamodels/src/scripts/._json2code.js
Executable file
Binary file not shown.
BIN
dm-framework/datamodels/src/scripts/._qjs-handlers-validate.js
Executable file
BIN
dm-framework/datamodels/src/scripts/._qjs-handlers-validate.js
Executable file
Binary file not shown.
1219
dm-framework/datamodels/src/scripts/json2code.js
Executable file
1219
dm-framework/datamodels/src/scripts/json2code.js
Executable file
File diff suppressed because it is too large
Load Diff
508
dm-framework/datamodels/src/scripts/makeDM.js
Normal file
508
dm-framework/datamodels/src/scripts/makeDM.js
Normal 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);
|
||||
}
|
||||
})();
|
||||
88
dm-framework/datamodels/src/scripts/qjs-handlers-validate.js
Normal file
88
dm-framework/datamodels/src/scripts/qjs-handlers-validate.js
Normal 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();
|
||||
}
|
||||
})();
|
||||
128822
dm-framework/datamodels/src/scripts/tr-181-2-19-1-cwmp-full.xml
Executable file
128822
dm-framework/datamodels/src/scripts/tr-181-2-19-1-cwmp-full.xml
Executable file
File diff suppressed because it is too large
Load Diff
138669
dm-framework/datamodels/src/scripts/tr-181-2-19-1-usp-full.xml
Executable file
138669
dm-framework/datamodels/src/scripts/tr-181-2-19-1-usp-full.xml
Executable file
File diff suppressed because it is too large
Load Diff
57941
dm-framework/datamodels/src/scripts/tr181-full-objects.json
Normal file
57941
dm-framework/datamodels/src/scripts/tr181-full-objects.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
dm-framework/dm-agent/._Makefile
Executable file
BIN
dm-framework/dm-agent/._Makefile
Executable file
Binary file not shown.
BIN
dm-framework/dm-agent/._bbfdm_service.json
Executable file
BIN
dm-framework/dm-agent/._bbfdm_service.json
Executable file
Binary file not shown.
64
dm-framework/dm-agent/Makefile
Normal file
64
dm-framework/dm-agent/Makefile
Normal 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)))
|
||||
17
dm-framework/dm-agent/bbfdm_service.json
Normal file
17
dm-framework/dm-agent/bbfdm_service.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
33
dm-framework/dm-agent/files/etc/config/bridging
Normal file
33
dm-framework/dm-agent/files/etc/config/bridging
Normal 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'
|
||||
94
dm-framework/dm-agent/files/etc/init.d/bridging
Executable file
94
dm-framework/dm-agent/files/etc/init.d/bridging
Executable 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
|
||||
}
|
||||
BIN
dm-framework/dm-agent/src/._dm_agent.c
Executable file
BIN
dm-framework/dm-agent/src/._dm_agent.c
Executable file
Binary file not shown.
37
dm-framework/dm-agent/src/Makefile
Normal file
37
dm-framework/dm-agent/src/Makefile
Normal 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)
|
||||
1683
dm-framework/dm-agent/src/dm_agent.c
Normal file
1683
dm-framework/dm-agent/src/dm_agent.c
Normal file
File diff suppressed because it is too large
Load Diff
75
dm-framework/dm-api/Makefile
Normal file
75
dm-framework/dm-api/Makefile
Normal 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)))
|
||||
64
dm-framework/dm-api/src/Makefile
Normal file
64
dm-framework/dm-api/src/Makefile
Normal 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)
|
||||
BIN
dm-framework/dm-api/src/core/._dm_api.c
Executable file
BIN
dm-framework/dm-api/src/core/._dm_api.c
Executable file
Binary file not shown.
BIN
dm-framework/dm-api/src/core/._dm_api.h
Executable file
BIN
dm-framework/dm-api/src/core/._dm_api.h
Executable file
Binary file not shown.
BIN
dm-framework/dm-api/src/core/._dm_import.c
Executable file
BIN
dm-framework/dm-api/src/core/._dm_import.c
Executable file
Binary file not shown.
BIN
dm-framework/dm-api/src/core/._dm_linker.c
Executable file
BIN
dm-framework/dm-api/src/core/._dm_linker.c
Executable file
Binary file not shown.
BIN
dm-framework/dm-api/src/core/._dm_linker.h
Executable file
BIN
dm-framework/dm-api/src/core/._dm_linker.h
Executable file
Binary file not shown.
2053
dm-framework/dm-api/src/core/db_upgrade.c
Normal file
2053
dm-framework/dm-api/src/core/db_upgrade.c
Normal file
File diff suppressed because it is too large
Load Diff
17
dm-framework/dm-api/src/core/db_upgrade.h
Normal file
17
dm-framework/dm-api/src/core/db_upgrade.h
Normal 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
|
||||
684
dm-framework/dm-api/src/core/dbmgr.c
Normal file
684
dm-framework/dm-api/src/core/dbmgr.c
Normal 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);
|
||||
}
|
||||
39
dm-framework/dm-api/src/core/dbmgr.h
Normal file
39
dm-framework/dm-api/src/core/dbmgr.h
Normal 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 */
|
||||
1607
dm-framework/dm-api/src/core/dm_api.c
Normal file
1607
dm-framework/dm-api/src/core/dm_api.c
Normal file
File diff suppressed because it is too large
Load Diff
265
dm-framework/dm-api/src/core/dm_api.h
Normal file
265
dm-framework/dm-api/src/core/dm_api.h
Normal 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
|
||||
725
dm-framework/dm-api/src/core/dm_apply.c
Normal file
725
dm-framework/dm-api/src/core/dm_apply.c
Normal 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, ¶m->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, ¶m->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, ¶m->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;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user