Compare commits
605 Commits
SDXLEMUR
...
developmen
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce20da12c1 | ||
|
|
b5d6f4af28 | ||
|
|
74ce62e5fc | ||
|
|
8b34baa4b3 | ||
|
|
75d8535cb2 | ||
|
|
509130448d | ||
|
|
cfa8dccec1 | ||
|
|
5a5d4dd984 | ||
|
|
08a1cd8d7b | ||
|
|
64f06fc056 | ||
|
|
223418bcf8 | ||
|
|
3acdd470c5 | ||
|
|
331b69a7db | ||
|
|
b14f3d7ded | ||
|
|
02dafc73ad | ||
|
|
6d6a3775c4 | ||
|
|
d6dfa5efd7 | ||
|
|
a82c63d6b7 | ||
|
|
1442ce21eb | ||
|
|
20c2f37452 | ||
|
|
1773301af8 | ||
|
|
5d7df898f3 | ||
|
|
e054ada872 | ||
|
|
789cb0bc3a | ||
|
|
19544e28f3 | ||
|
|
96dd20a758 | ||
|
|
6bd2c7ea52 | ||
|
|
029d657d08 | ||
|
|
5daf4bb388 | ||
|
|
45aaafb4fb | ||
|
|
b2f8e4ed5b | ||
|
|
e97785f601 | ||
|
|
fe5ce0aa37 | ||
|
|
b5586f1b00 | ||
|
|
c7c2190ce3 | ||
|
|
07746de9d0 | ||
|
|
1416edc3c4 | ||
|
|
c31f435537 | ||
|
|
13e325cb67 | ||
|
|
95463202dd | ||
|
|
38a0736110 | ||
|
|
da1563ce21 | ||
|
|
92570427ae | ||
|
|
ed4ec61e52 | ||
|
|
dd59450e99 | ||
|
|
27f17eb874 | ||
|
|
87d9593f93 | ||
|
|
f0c750ddff | ||
|
|
f629917ac9 | ||
|
|
4a91546563 | ||
|
|
27b455df06 | ||
|
|
e7c57e1c2a | ||
|
|
23df41eac4 | ||
|
|
5cdd8ebad6 | ||
|
|
ef65d3d524 | ||
|
|
4a327bfcd8 | ||
|
|
5ed245a3df | ||
|
|
e2ea01f64a | ||
|
|
629d9a35bc | ||
|
|
8e99618f2a | ||
|
|
0e60336199 | ||
|
|
09daba4ad5 | ||
|
|
f0151d7967 | ||
|
|
30a300dbd3 | ||
|
|
7f3a026cc5 | ||
|
|
4fe009cf28 | ||
|
|
752fce41b4 | ||
|
|
e75ff823a3 | ||
|
|
0c3956b5eb | ||
|
|
c47f32da66 | ||
|
|
6efe370805 | ||
|
|
619502a100 | ||
|
|
384c055278 | ||
|
|
03440b2693 | ||
|
|
0ccb6bbf1b | ||
|
|
1e725e940b | ||
|
|
45af7b6ee7 | ||
|
|
2a6fc2cf2d | ||
|
|
7fa78309ce | ||
|
|
c61e8e8122 | ||
|
|
8209bac12e | ||
|
|
db3055afbf | ||
|
|
709be1f447 | ||
|
|
81da81cb40 | ||
|
|
b158d40352 | ||
|
|
b499f5cc0b | ||
|
|
f6b46cde99 | ||
|
|
abcb75b097 | ||
|
|
0469b43b7c | ||
|
|
dacf583d13 | ||
|
|
7277bdeb07 | ||
|
|
c2d4f9f0f6 | ||
|
|
5afecaeaba | ||
|
|
9349df0abc | ||
|
|
5db402136c | ||
|
|
73bb838b38 | ||
|
|
8f97a577d2 | ||
|
|
03a092acfe | ||
|
|
2662079349 | ||
|
|
473f9969dd | ||
|
|
a8730bf9e9 | ||
|
|
8ff9a630ae | ||
|
|
87098a4319 | ||
|
|
a3dd95ec30 | ||
|
|
559d260eb0 | ||
|
|
b5141a63ac | ||
|
|
4d5d79c352 | ||
|
|
1e2125e558 | ||
|
|
f7af2cb687 | ||
|
|
5e5444e890 | ||
|
|
0e4815ccbb | ||
|
|
f4c980ce71 | ||
|
|
f9f428e372 | ||
|
|
c42907e346 | ||
|
|
721bbd9bfb | ||
|
|
677cdbb66d | ||
|
|
9d3768dccf | ||
|
|
99295a5061 | ||
|
|
e5aa61f31f | ||
|
|
1d5faf38d1 | ||
|
|
c4a340bd36 | ||
|
|
80752d3a02 | ||
|
|
7165798338 | ||
|
|
0fab14e75b | ||
|
|
45100c60ca | ||
|
|
35b6710b46 | ||
|
|
dbe0a8da95 | ||
|
|
03e1863b59 | ||
|
|
9910092ff5 | ||
|
|
3e1f3e09e7 | ||
|
|
a09cfe6b2c | ||
|
|
571b3a0c4b | ||
|
|
efcbfea866 | ||
|
|
d87f254c6b | ||
|
|
94b59a50c4 | ||
|
|
f7c64cc374 | ||
|
|
8e54c6e0b3 | ||
|
|
75f5e15d4e | ||
|
|
2f800c7399 | ||
|
|
ee528bb68b | ||
|
|
63dbeeb073 | ||
|
|
bd2f8fcede | ||
|
|
ecd800df44 | ||
|
|
ba817e535c | ||
|
|
aac8079bc6 | ||
|
|
11f9ee2bbf | ||
|
|
96c39048b2 | ||
|
|
1f86858913 | ||
|
|
38638fb1ec | ||
|
|
ca5827c693 | ||
|
|
f8a612d072 | ||
|
|
1a43b740b4 | ||
|
|
d68dd62d51 | ||
|
|
cacde36ca4 | ||
|
|
a0301f4cd2 | ||
|
|
54e6407507 | ||
|
|
2418b3eec9 | ||
|
|
810865290b | ||
|
|
aa08a8ee28 | ||
|
|
2a4d8b6d56 | ||
|
|
113eda4f6c | ||
|
|
8866e35d4b | ||
|
|
8e80ba5c91 | ||
|
|
36874b12f0 | ||
|
|
0ce398b6e5 | ||
|
|
d05491c8a1 | ||
|
|
70f1134b69 | ||
|
|
e66a2c5721 | ||
|
|
5ecb93a5e1 | ||
|
|
44b21671bc | ||
|
|
7d3da6e073 | ||
|
|
3f05beee37 | ||
|
|
99dbf135e9 | ||
|
|
41b47533a4 | ||
|
|
209d782172 | ||
|
|
0eb6b4d502 | ||
|
|
21e144966f | ||
|
|
13fe12413e | ||
|
|
133100eee7 | ||
|
|
148b6a6861 | ||
|
|
fa4ed2876b | ||
|
|
efc3ea460a | ||
|
|
ba34463acd | ||
|
|
61a14f6b39 | ||
|
|
bda5e8622d | ||
|
|
8dc578a364 | ||
|
|
a75c2c9da7 | ||
|
|
6394731663 | ||
|
|
d3c6605936 | ||
|
|
b6466dc910 | ||
|
|
6608d084b5 | ||
|
|
59be0e546f | ||
|
|
e820fe3623 | ||
|
|
74971330f6 | ||
|
|
3f86da0e33 | ||
|
|
6d80afb010 | ||
|
|
19d6b984bd | ||
|
|
6ac3f137fd | ||
|
|
c4e2bfb714 | ||
|
|
3d0a760e13 | ||
|
|
f412e318ed | ||
|
|
3b2f4df801 | ||
|
|
5112fd5280 | ||
|
|
e7ab42b2c1 | ||
|
|
e99adb0a3e | ||
|
|
4cef2d3d86 | ||
|
|
eedbe783ae | ||
|
|
64d117fb9e | ||
|
|
498a38f030 | ||
|
|
901fed57c5 | ||
|
|
a9b961c763 | ||
|
|
8de5a5f917 | ||
|
|
c63b28f196 | ||
|
|
7b956bbcc2 | ||
|
|
f06995bda7 | ||
|
|
d4d2aa9b11 | ||
|
|
51ac84705c | ||
|
|
dc16a3c9fe | ||
|
|
c9ec7f7617 | ||
|
|
cd60b7b6db | ||
|
|
3352a86548 | ||
|
|
430d9445ac | ||
|
|
cf9387c736 | ||
|
|
f956fbaf37 | ||
|
|
f2a451e862 | ||
|
|
85136894e0 | ||
|
|
139170b3ca | ||
|
|
cdf655af16 | ||
|
|
9650309978 | ||
|
|
fb24db4cfe | ||
|
|
4936d144a4 | ||
|
|
d2d18cc10a | ||
|
|
6b2b424bcd | ||
|
|
83d61aeae1 | ||
|
|
0f9fbfa2ab | ||
|
|
4f99c66cec | ||
|
|
1875ac86b3 | ||
|
|
28d1c1ce71 | ||
|
|
07d06d4480 | ||
|
|
8cd7d09a55 | ||
|
|
80f2975243 | ||
|
|
a80af985fd | ||
|
|
18ec2896cc | ||
|
|
f2767682c5 | ||
|
|
d4f13f11b6 | ||
|
|
4010a26b40 | ||
|
|
429d34d48a | ||
|
|
8fcbbbb6b2 | ||
|
|
cb0cfd7e60 | ||
|
|
4fddc32f3b | ||
|
|
608cc1c19f | ||
|
|
cc5792d192 | ||
|
|
250233ef26 | ||
|
|
c77d720a43 | ||
|
|
cfe126bcb0 | ||
|
|
1d59769366 | ||
|
|
050b5aa049 | ||
|
|
995c3c3e21 | ||
|
|
d346826ae5 | ||
|
|
3c9472b5ee | ||
|
|
152e74bafb | ||
|
|
ad2af11429 | ||
|
|
5c2b385e18 | ||
|
|
45f445cf28 | ||
|
|
02583b04ed | ||
|
|
059c613bde | ||
|
|
e94b199b6e | ||
|
|
2fe55cf223 | ||
|
|
d28fadc1ba | ||
|
|
5134a3bd38 | ||
|
|
e54d5e0552 | ||
|
|
29198d22d2 | ||
|
|
9d0667af58 | ||
|
|
7694f1adf9 | ||
|
|
1b5d272940 | ||
|
|
49df6b784a | ||
|
|
d73fa42d06 | ||
|
|
a8043e6d95 | ||
|
|
1f5c2b8540 | ||
|
|
f0121bcb4a | ||
|
|
efdac9581c | ||
|
|
7cf49c7862 | ||
|
|
450372f1c6 | ||
|
|
040a50d8be | ||
|
|
6ccac640bc | ||
|
|
404924884c | ||
|
|
6319aca987 | ||
|
|
8ba98f10cb | ||
|
|
ec55b990a9 | ||
|
|
a7365470f8 | ||
|
|
634e2bbb29 | ||
|
|
bae23b5587 | ||
|
|
b8f9feef20 | ||
|
|
397e0de45a | ||
|
|
622d0d9361 | ||
|
|
5b765953c4 | ||
|
|
492f837fee | ||
|
|
fa0139c447 | ||
|
|
a2464e9793 | ||
|
|
adcd4a553d | ||
|
|
dc81d00d6d | ||
|
|
bd97f2e652 | ||
|
|
13117829e8 | ||
|
|
41e18cb5eb | ||
|
|
ad3b364245 | ||
|
|
0bb14ae09c | ||
|
|
f133866286 | ||
|
|
7810aed7d9 | ||
|
|
929b572e94 | ||
|
|
f7de652f13 | ||
|
|
1fcbf71900 | ||
|
|
cef9ba16c2 | ||
|
|
c06a2a7b54 | ||
|
|
06b3c92f6e | ||
|
|
dcbb99f5bd | ||
|
|
c049d9c10a | ||
|
|
48ba5f786c | ||
|
|
5507b63ab7 | ||
|
|
7f2196af64 | ||
|
|
828049b537 | ||
|
|
075e6a529b | ||
|
|
ef9ebc3ed5 | ||
|
|
d45581f140 | ||
|
|
dc4c42e4ac | ||
|
|
097b45945f | ||
|
|
c6b30a6c2a | ||
|
|
38fd92ad4b | ||
|
|
3acde3d007 | ||
|
|
1133c3113a | ||
|
|
f0a75e3e9b | ||
|
|
13ba36f560 | ||
|
|
e5d1850253 | ||
|
|
5d29af2f85 | ||
|
|
729529a564 | ||
|
|
97e45f66c6 | ||
|
|
259d50ee69 | ||
|
|
a3f01dd33e | ||
|
|
a9920c6ea4 | ||
|
|
cc12a388e5 | ||
|
|
d939a33333 | ||
|
|
576231f0b1 | ||
|
|
366fa94c9b | ||
|
|
7b60eb6495 | ||
|
|
442cf882c3 | ||
|
|
775674cbed | ||
|
|
78d9bdabff | ||
|
|
35be8163bd | ||
|
|
0c6194e00c | ||
|
|
47c1ea44ad | ||
|
|
c4e1b9483c | ||
|
|
871bc0f645 | ||
|
|
ae46149862 | ||
|
|
0f64341f65 | ||
|
|
db83597a33 | ||
|
|
c3fea1014b | ||
|
|
d108469062 | ||
|
|
b0fc66689e | ||
|
|
e569e47416 | ||
|
|
9e4f9fc159 | ||
|
|
501ead5a2c | ||
|
|
994f831818 | ||
|
|
8b80f3bd35 | ||
|
|
d7555208d3 | ||
|
|
3317793099 | ||
|
|
999a9c7d37 | ||
|
|
dcd8cd6ab7 | ||
|
|
f4dba6cce0 | ||
|
|
1f315e8ca6 | ||
|
|
7acb2e170f | ||
|
|
1449a36ef8 | ||
|
|
96095fcb09 | ||
|
|
2ad7b54a97 | ||
|
|
e03d882626 | ||
|
|
944fd61748 | ||
|
|
15adb7b260 | ||
|
|
299f7b450f | ||
|
|
15556419cd | ||
|
|
daa0f9295c | ||
|
|
007b268b03 | ||
|
|
fe88898f2f | ||
|
|
0e74abe7db | ||
|
|
8666d450c4 | ||
|
|
c8b53ae3f3 | ||
|
|
df6b4114a8 | ||
|
|
476c949e6c | ||
|
|
0298242849 | ||
|
|
3e8449e06b | ||
|
|
38a551ef5c | ||
|
|
78cc255af6 | ||
|
|
5de2e4dc41 | ||
|
|
214bc89832 | ||
|
|
aed53a49ed | ||
|
|
b981b4a519 | ||
|
|
45e8ef8272 | ||
|
|
f145802509 | ||
|
|
52f68bc54c | ||
|
|
9facd17476 | ||
|
|
3670e3ee8d | ||
|
|
e035b2a37c | ||
|
|
bb4d75f560 | ||
|
|
46f8e1af8b | ||
|
|
0f8ec6d242 | ||
|
|
29196f7f9b | ||
|
|
293940e3f0 | ||
|
|
a6a293116e | ||
|
|
075046300b | ||
|
|
c0cc14bfcb | ||
|
|
ac472a2f5c | ||
|
|
b9d88c21c0 | ||
|
|
4af2890b43 | ||
|
|
f9b1161a82 | ||
|
|
f137ae6074 | ||
|
|
96bdfd5109 | ||
|
|
66c9fc6da9 | ||
|
|
b83ea53091 | ||
|
|
7cf7083767 | ||
|
|
f24bfc0478 | ||
|
|
3c37a3b9af | ||
|
|
12dde2e40a | ||
|
|
545b381004 | ||
|
|
6a0a41b8b9 | ||
|
|
acae974583 | ||
|
|
b5b18b9cd0 | ||
|
|
a174267dd8 | ||
|
|
cea5899666 | ||
|
|
d53d7af8d6 | ||
|
|
6df1dfc132 | ||
|
|
3e3810ba18 | ||
|
|
74b7c11cab | ||
|
|
12c8430670 | ||
|
|
b5c7bfe567 | ||
|
|
6ed4a3e1e4 | ||
|
|
c8faf539c1 | ||
|
|
b5f299dfb2 | ||
|
|
0cf8fd10a9 | ||
|
|
03f42b03bc | ||
|
|
76891cce61 | ||
|
|
be9ee7def5 | ||
|
|
c0394cf215 | ||
|
|
35eedffe95 | ||
|
|
28c39a4829 | ||
|
|
15ca383d34 | ||
|
|
c9a3c9966c | ||
|
|
aa049aaa89 | ||
|
|
a990ce2773 | ||
|
|
e19bb58e92 | ||
|
|
276702911c | ||
|
|
76ff7eeafd | ||
|
|
df589bcb7e | ||
|
|
7877276498 | ||
|
|
624a74be0d | ||
|
|
7a636798d6 | ||
|
|
705d461342 | ||
|
|
69a6f7b62d | ||
|
|
7a2ec5d02c | ||
|
|
a37177a3af | ||
|
|
e154dee562 | ||
|
|
2055ab69dc | ||
|
|
8c0b758cb3 | ||
|
|
40d57e9930 | ||
|
|
79d0e4db3f | ||
|
|
2ca21c6087 | ||
|
|
191067031f | ||
|
|
735fcfb9a8 | ||
|
|
9a9b47c294 | ||
|
|
3a35becca8 | ||
|
|
b7b8bb2838 | ||
|
|
5b89d9098c | ||
|
|
67de104199 | ||
|
|
d0abbb2812 | ||
|
|
a2ff2799b5 | ||
|
|
e191a0009c | ||
|
|
25be4b30db | ||
|
|
f7d237856e | ||
|
|
c7d238e65f | ||
|
|
0bb0720c6b | ||
|
|
e7cb821fa1 | ||
|
|
4e361eb336 | ||
|
|
368825c13a | ||
|
|
7f4b651ed7 | ||
|
|
151ec22f95 | ||
|
|
f3fb31acfa | ||
|
|
f9da788193 | ||
|
|
1aca8c892f | ||
|
|
b90cb9b460 | ||
|
|
2652c15aef | ||
|
|
3a2ca5c1ab | ||
|
|
dd8e4d1bba | ||
|
|
2d0af5b2ae | ||
|
|
c307ccd8a8 | ||
|
|
0b24fabb48 | ||
|
|
b5bf9a4fb9 | ||
|
|
26de7b7b6c | ||
|
|
861085cb26 | ||
|
|
f7e89663ee | ||
|
|
0adddef63a | ||
|
|
ae23d55274 | ||
|
|
b811265921 | ||
|
|
b4ef80c116 | ||
|
|
061fb6abe6 | ||
|
|
1af3ee2d5e | ||
|
|
823a5fa342 | ||
|
|
687d684937 | ||
|
|
3f54d58422 | ||
|
|
77c4fa6667 | ||
|
|
78c673ed4d | ||
|
|
044bab364f | ||
|
|
46c1d92f90 | ||
|
|
69e22c5f6c | ||
|
|
f93a4d8082 | ||
|
|
2feecf15e1 | ||
|
|
af8aee60ff | ||
|
|
148fb5df1b | ||
|
|
a9f8ae753b | ||
|
|
7594aa095b | ||
|
|
6633e7f70b | ||
|
|
f08a40bdbd | ||
|
|
7ddbd1430f | ||
|
|
94bab21696 | ||
|
|
30adb3e744 | ||
|
|
badfb5e182 | ||
|
|
0a77e5e497 | ||
|
|
7d36748dce | ||
|
|
37ffbdc320 | ||
|
|
661a3c3f44 | ||
|
|
6fbcc3c28d | ||
|
|
21be826fba | ||
|
|
b032ad738d | ||
|
|
b70ada6b9c | ||
|
|
e276ac479f | ||
|
|
63e6c62c5c | ||
|
|
e0e31824f6 | ||
|
|
2165713141 | ||
|
|
c43728856f | ||
|
|
8ac1dda904 | ||
|
|
c28748016c | ||
|
|
934b8eec41 | ||
|
|
75668f3692 | ||
|
|
b6d140782b | ||
|
|
49e86fd69b | ||
|
|
214931a454 | ||
|
|
fd40f3caaa | ||
|
|
56aafcbd61 | ||
|
|
812e096354 | ||
|
|
5d92fdeadf | ||
|
|
224f63c1a8 | ||
|
|
202606166a | ||
|
|
5832fdef18 | ||
|
|
0f9eaf6df5 | ||
|
|
cb02197463 | ||
|
|
e16cf97a6d | ||
|
|
d2390a7ece | ||
|
|
cb021d2410 | ||
|
|
f26dfb33b5 | ||
|
|
4f66e2150f | ||
|
|
2a010a19c1 | ||
|
|
c9b63a21e7 | ||
|
|
eb4eace916 | ||
|
|
4f39f39e9a | ||
|
|
477d393116 | ||
|
|
042b76b89d | ||
|
|
b8ed7f2ba8 | ||
|
|
e7ef610f05 | ||
|
|
9f855ba473 | ||
|
|
4215168042 | ||
|
|
fd4666a546 | ||
|
|
c986872719 | ||
|
|
f46597e14e | ||
|
|
ae95ad41c6 | ||
|
|
0c5a7e99d4 | ||
|
|
fb7d5b91ed | ||
|
|
beb73521cd | ||
|
|
761017ccae | ||
|
|
ebb824eae2 | ||
|
|
0ffb28341b | ||
|
|
53d590eddb | ||
|
|
4a8bff4138 | ||
|
|
d764b70ec4 | ||
|
|
b027378c9d | ||
|
|
fca83ab616 | ||
|
|
bfd4b31fea | ||
|
|
88d300303c | ||
|
|
65ceb39c1f | ||
|
|
14b45941b0 | ||
|
|
f6290708bf | ||
|
|
7c413fe5a0 | ||
|
|
70e9af1273 | ||
|
|
155e8dd9bb | ||
|
|
b1cd03ec72 | ||
|
|
3965081d97 | ||
|
|
9ea53d593d | ||
|
|
b4bc15f8ef | ||
|
|
e6a0c00ce8 | ||
|
|
f6739360ee | ||
|
|
f1b08de405 | ||
|
|
9ca4451ef4 | ||
|
|
08b799a906 | ||
|
|
744871a90b | ||
|
|
79f835fd0f | ||
|
|
5e8bcd1d3f | ||
|
|
5f387e7b17 | ||
|
|
bf0c2028b1 | ||
|
|
0858b03da2 | ||
|
|
408cf583dd | ||
|
|
ff23e5cfac |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Windows Zone.Identifier files (created when downloading files from internet)
|
||||
*:Zone.Identifier
|
||||
*Zone.Identifier
|
||||
1
.obsidian/app.json
vendored
Normal file
1
.obsidian/app.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
.obsidian/appearance.json
vendored
Normal file
1
.obsidian/appearance.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
31
.obsidian/core-plugins.json
vendored
Normal file
31
.obsidian/core-plugins.json
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"file-explorer": true,
|
||||
"global-search": true,
|
||||
"switcher": true,
|
||||
"graph": true,
|
||||
"backlink": true,
|
||||
"canvas": true,
|
||||
"outgoing-link": true,
|
||||
"tag-pane": true,
|
||||
"properties": false,
|
||||
"page-preview": true,
|
||||
"daily-notes": true,
|
||||
"templates": true,
|
||||
"note-composer": true,
|
||||
"command-palette": true,
|
||||
"slash-command": false,
|
||||
"editor-status": true,
|
||||
"bookmarks": true,
|
||||
"markdown-importer": false,
|
||||
"zk-prefixer": false,
|
||||
"random-note": false,
|
||||
"outline": true,
|
||||
"word-count": true,
|
||||
"slides": false,
|
||||
"audio-recorder": false,
|
||||
"workspaces": false,
|
||||
"file-recovery": true,
|
||||
"publish": false,
|
||||
"sync": true,
|
||||
"webviewer": false
|
||||
}
|
||||
173
.obsidian/workspace.json
vendored
Normal file
173
.obsidian/workspace.json
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
{
|
||||
"main": {
|
||||
"id": "cfbe859ecf56fae0",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "b83a784c3a7d92c5",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "f1014514d48382b8",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "README.md",
|
||||
"mode": "source",
|
||||
"source": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "README"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "vertical"
|
||||
},
|
||||
"left": {
|
||||
"id": "d0cb12d3f48108e9",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "a8a7e64788ca4c59",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "7d7f951eade08e15",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "file-explorer",
|
||||
"state": {
|
||||
"sortOrder": "alphabetical",
|
||||
"autoReveal": false
|
||||
},
|
||||
"icon": "lucide-folder-closed",
|
||||
"title": "Files"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "7febcdc7d3c2deea",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "search",
|
||||
"state": {
|
||||
"query": "",
|
||||
"matchingCase": false,
|
||||
"explainSearch": false,
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical"
|
||||
},
|
||||
"icon": "lucide-search",
|
||||
"title": "Search"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "12bb71ef9436a043",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "bookmarks",
|
||||
"state": {},
|
||||
"icon": "lucide-bookmark",
|
||||
"title": "Bookmarks"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 300
|
||||
},
|
||||
"right": {
|
||||
"id": "3bcff15aa34346c5",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "249aae86eddbae79",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "60b3bb238ff8dd44",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "backlink",
|
||||
"state": {
|
||||
"file": "README.md",
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical",
|
||||
"showSearch": false,
|
||||
"searchQuery": "",
|
||||
"backlinkCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
},
|
||||
"icon": "links-coming-in",
|
||||
"title": "Backlinks for README"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "168425d9c5df2b15",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outgoing-link",
|
||||
"state": {
|
||||
"file": "README.md",
|
||||
"linksCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
},
|
||||
"icon": "links-going-out",
|
||||
"title": "Outgoing links from README"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "cb0c34fa52269a79",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "tag",
|
||||
"state": {
|
||||
"sortOrder": "frequency",
|
||||
"useHierarchy": true,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-tags",
|
||||
"title": "Tags"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "edfdf272173ebc96",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outline",
|
||||
"state": {
|
||||
"file": "README.md",
|
||||
"followCursor": false,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-list",
|
||||
"title": "Outline of README"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 300,
|
||||
"collapsed": true
|
||||
},
|
||||
"left-ribbon": {
|
||||
"hiddenItems": {
|
||||
"switcher:Open quick switcher": false,
|
||||
"graph:Open graph view": false,
|
||||
"canvas:Create new canvas": false,
|
||||
"daily-notes:Open today's daily note": false,
|
||||
"templates:Insert template": false,
|
||||
"command-palette:Open command palette": false
|
||||
}
|
||||
},
|
||||
"active": "f1014514d48382b8",
|
||||
"lastOpenFiles": []
|
||||
}
|
||||
245
README.md
245
README.md
@@ -1,40 +1,61 @@
|
||||
# RGMII Toolkit
|
||||
Software deployment Toolkit for Quectel RM5xxx series 5G modems utilizing an m.2 to RJ45 adapter (RGMII)
|
||||
Current Branch: **development-SDXPINN**
|
||||
|
||||
Current Branch: **Development**
|
||||
>:checkered_flag: Hint: Start by checking out the ipk-source directory, each package is broken down into its contents. Inside, root represents the structure copied starting at / and control includes metadata and scripts to be ran before and after installation. The build-ipk.sh will produce an ipk based on the control and root directories next to it.
|
||||
|
||||
Please PR to this branch instead of main :)
|
||||
# SDXPINN OpenWRT Repository
|
||||
|
||||
Fork development, and PR development to development :)
|
||||
This branch of the repository serves as both an opkg source and feed for the custom packages I make available for Quectel cellular modules with the SDXPINN system. This source is preloaded into my custom firmware for the RM551E-GL found here: https://mega.nz/file/GUkk0RpD#7JsFymzKBBKplxLs5tqc5-m7rBmrB2QPfTfMtf1ZQ4g
|
||||
|
||||
Flash with QFlash, QFIL, or qfirehose. At first boot a script will automaticly set the module to PCIe RC mode and USB ECM mode then reboot so wait for that reboot after flash to proceed. From there either by Ethernet or USB ECM visit http://192.168.224.1/ or ssh root@192.168.224.1 Password: iamromulan
|
||||
|
||||
> :warning: Custom firmware is only available for the RM551E-GL for now. An RM550V-GLAA firmware will be available soon.
|
||||
|
||||
[](https://www.youtube.com/watch?v=SdNEyDfTIKk)
|
||||
[Watch on YouTube](https://www.youtube.com/watch?v=SdNEyDfTIKk)
|
||||
|
||||
|
||||
#### [JUMP TO HOW TO USE](#how-to-use)
|
||||
**Currently:** This will allow you to install or if already installed, update, remove, or modify:
|
||||
- Simple Admin: A simple web interface for managing your Quectel m.2 modem through it's gateway address
|
||||
- It will install socat-at-bridge: sets up ttyOUT and ttyOUT2 for AT commands. You'll be able to use the `atcmd` command as well for an interactive at command session from adb, ssh, or ttyd
|
||||
- It will install simplefirewall: A simple firewall that blocks definable incoming ports and a TTL mangle option/modifier. As of now only the TTL is controllable through Simple Admin. You can edit port block options and TTL from the 3rd option in the toolkit
|
||||
- Tailscale: A magic VPN for accessing Simple Admin, SSH, and ttyd on the go. The Toolkit installs the Tailscale client directly to the modem and allows you to login and configure other settings. Head over to tailscale.com to sign up for a free account and learn more.
|
||||
- Schedule a Daily Reboot at a specified time
|
||||
- A fix for certain modems that don't start in CFUN=1 mode
|
||||
- Entware/OPKG: A package installer/manager/repo
|
||||
- Run `opkg help` to see how to use it
|
||||
- These packages are installable: https://bin.entware.net/armv7sf-k3.2/Packages.html
|
||||
- TTYd: A shell session right from your browser
|
||||
- Currently this uses port 443 but SSL/TLS is not in use (http only for now)
|
||||
- Entware/OPKG is required so it will install it if it isn't installed
|
||||
- This will replace the stock Quectel login and passwd binaries with ones from entware
|
||||
|
||||
|
||||
# :warning: Known issues with Packages
|
||||
|
||||
**My goal** is for this to also include any new useful scripts or software for this modem and others that support RGMII mode.
|
||||
## Screenshots
|
||||
Currently there is know vulnerability with QuecManager that allows cgi scripts to be executed unauthenticated. It is not recommended to expose uhttpd to the public internet, and to only used in a controlled, trusted local environment for now. Please see [Issue #175](https://github.com/iamromulan/quectel-rgmii-toolkit/issues/175) for more info.
|
||||
# RC PCIe Toolkit
|
||||
If you prefer starting from factory firmware you may use the toolkit script here to deploy my repo and other fixes via adb. It has been a while since I last visited this deployment script so open an issue if you see something wrong. See the wiki for info on adb.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
Software deployment Toolkit for Quectel RM5xxx series 5G modems utilizing an m.2 to RJ45 adapter (RC PCIe)
|
||||
|
||||
# Devleopment Branch: the below commands will download the beta/work in progress toolkit
|
||||
# The below commands will download the toolkit for RM55x modems/SDXPINN platform
|
||||
|
||||
# Current state:
|
||||
The toolkit will do the following:
|
||||
1. AT Commands
|
||||
- Needs tested.
|
||||
|
||||
2. Install sdxpinn-mount-fix/run me after a flash!
|
||||
- Installs sdxpinn-mount-fix so you can have a usable filesystem.
|
||||
- You won't get far without this installed
|
||||
|
||||
|
||||
3. TTL Setup
|
||||
- Will allow you to set a TTL value
|
||||
|
||||
4. Install Basic Packages/enable luci/add iamromulan's feed to opkg
|
||||
- Adds this repo as a source for opkg/software to get packages
|
||||
- Installs the public key for this repo
|
||||
- Installs a few basic packages: atinout luci-app-atinout-mod sdxpinn-console-menu shadow-login luci-app-ttyd mc mc-skins
|
||||
- Starts and enables the SSH server and uhttpd web server (Luci)
|
||||
|
||||
5. Set root password
|
||||
- Runs the passwd utility so you can set your password for root
|
||||
|
||||
6. Tailscale Management
|
||||
- Will let you install tailscale
|
||||
- Installs my updated ipks
|
||||
- Will let you configure tailscale
|
||||
- No web server yet
|
||||
|
||||
7. Install Speedtest.net CLI app (speedtest command)
|
||||
- Will install the speedtest command (speedtest.net test)
|
||||
- After install type speedtest to use it
|
||||
|
||||
## How to Use
|
||||
**To run the Toolkit:**
|
||||
@@ -44,95 +65,116 @@ Fork development, and PR development to development :)
|
||||
- Run `adb shell ping 8.8.8.8` to make sure the shell can access the internet. If you get an error, make sure the modem is connected to a cellular network and make sure `AT+QMAPWAC=1` as covered in the troubleshooting section: [I Can't get internet access from the Ethernet port (Common)](https://github.com/iamromulan/quectel-rgmii-configuration-notes/tree/main?tab=readme-ov-file#i-cant-get-internet-access-from-the-ethernet-port-common)
|
||||
- If you don't get an error you should be getting replies back endlessly, press `CTRL-C` to stop it.
|
||||
- Simply Copy/Paste this into your Command Prompt/Shell
|
||||
```bash
|
||||
adb shell "cd /tmp && wget -O RMxxx_rgmii_toolkit.sh https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/development/RMxxx_rgmii_toolkit.sh && chmod +x RMxxx_rgmii_toolkit.sh && ./RMxxx_rgmii_toolkit.sh" && cd /
|
||||
```
|
||||
|
||||
**Or, if you want to stay in the modems shell when you are done**
|
||||
|
||||
```
|
||||
adb root
|
||||
adb shell
|
||||
```
|
||||
Then run
|
||||
```
|
||||
cd /tmp && wget -O RMxxx_rgmii_toolkit.sh https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/development/RMxxx_rgmii_toolkit.sh && chmod +x RMxxx_rgmii_toolkit.sh && ./RMxxx_rgmii_toolkit.sh && cd /
|
||||
cd /tmp && wget -O rcPCIe_SDXPINN_toolkit.sh https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/SDXPINN/rcPCIe_SDXPINN_toolkit.sh && chmod +x rcPCIe_SDXPINN_toolkit.sh && ./rcPCIe_SDXPINN_toolkit.sh && cd /
|
||||
```
|
||||
**You should see:**
|
||||

|
||||
|
||||
## Tailscale Installation and Config
|
||||
|
||||
> :warning: Your modem must already be connected to the internet for this to install
|
||||
### Installation:
|
||||
Open up the toolkit main menu and **press 4** to enter the Tailscale menu
|
||||
|
||||

|
||||
|
||||
**Press 1, wait for it to install. This is a very large file for the system so give it some time.**
|
||||
|
||||
**Once done and it says Tailscale installed successfully press 2/enter to configure it.**
|
||||
|
||||

|
||||
|
||||
If you want to, enable the Tailscale Web UI on port 8088 for configuration from the browser later by **pressing 1/enter**.
|
||||
|
||||
To do it in the toolkit:
|
||||
First time connecting you'll be given a link to login with
|
||||
- Press 3 to just connect only.
|
||||
- Press 4 to connect and enable SSH access (remote command line) over tailscale.
|
||||
- Press 5 to reconnect with SSH off while connected with SSH on
|
||||
- Press 6 to disconnect
|
||||
- Press 7 to Logout
|
||||
|
||||
That's it! From another device running tailscale you should be able to access your modem through the IP assigned to it by your tailnet. To access SSH from another device on the tailnet, open a terminal/command prompt and type
|
||||
|
||||
tailscale ssh root@(IP or Hostname)
|
||||
IP or Hostname being the IP or hostname assigned to it in your tailnet
|
||||
|
||||
- Note that your SSH client must be able to give you a link to sign in with upon connecting. That's how the session is authorized. Works fine in Windows CMD or on Android use JuiceSSH.
|
||||
## Advanced/Beta
|
||||
|
||||
### Entware/OPKG installation
|
||||
|
||||
|
||||
It isn't perfect yet so it goes here under Advanced/Beta for now.
|
||||
Here's what you gotta know about going into it:
|
||||
# Useful AT Commands
|
||||
|
||||
- After installing, the `opkg` command will work
|
||||
- You can run `opkg list` to see a list of installable packages, or head over to https://bin.entware.net/armv7sf-k3.2/Packages.html
|
||||
- Everything opkg does is installed to /opt
|
||||
- `/opt` is actually located at `/usrdata/opt` to save space but is
|
||||
mounted at `/opt`
|
||||
- Anything `opkg` installs will not be available in the system path by
|
||||
default but you can get around this either:
|
||||
You can send more than one command at once by sperating them with ``;`` and not including the AT part. ``AT+QENG="servingcell";+QCAINFO`` for example to see the info from both ``AT+QENG="servingcell"`` and ``AT+QCAINFO``
|
||||
|
||||
#### Temporarily:
|
||||
Run this at the start of each adb shell or SSH shell session
|
||||
|
||||
export PATH=/opt/bin:/opt/sbin:$PATH
|
||||
## PCIe RC Ethernet mode setup
|
||||
|
||||
#### Permanently:
|
||||
Symbolic linking each binary installed by the package to `/bin` and `/sbin` from `/opt/bin` and `/opt/sbin`
|
||||
For example, if you were to install zerotier:
|
||||
For use with a board like the [Rework.Network PoE 2.5gig RJ45 sled](https://rework.network/collections/lte-home-gateway/products/5g2phy)
|
||||
|
||||
opkg install zerotier
|
||||
ln -sf /opt/bin/zerotier-one /bin
|
||||
ln -sf /opt/bin/zerotier-cli /bin
|
||||
ln -sf /opt/bin/zerotier-idtool /bin
|
||||
### For x70 modems (RM550/551)
|
||||
|
||||
Now you can run those 3 binaries from the shell anytime since they are linked in a place already part of the system path.
|
||||
For BETA versions of firmware: the adb value 2 trick still works so one and done:
|
||||
|
||||
``AT+QCFG="pcie/mode",1;+QCFG="usbnet",1;+QCFG="usbcfg",0x2C7C,0x0122,1,1,1,1,1,2,0;+CFUN=1,1``
|
||||
|
||||
OR if you are running the latest non-beta firmware
|
||||
|
||||
``AT+QCFG="pcie/mode",1;+QCFG="usbnet",1``
|
||||
|
||||
Then unlock ADB:
|
||||
|
||||
Ask the modem for its adb code by sending: ``AT+QADBKEY?``
|
||||
|
||||
It'll respond with something like ``+QADBKEY: 29229988``
|
||||
|
||||
Take that number and paste it in this generator: https://onecompiler.com/python/3znepjcsq (hint: where it says STDIN)
|
||||
|
||||
You should get something like
|
||||
|
||||
``AT+QADBKEY="mrX4zOPwdSIEjfM"``
|
||||
|
||||
Send that command to the modem and adb will be able to be turned on with the next command
|
||||
|
||||
Now you can turn it on with the usbcfg command ``AT+QCFG="usbcfg"``
|
||||
|
||||
***Be super careful, this controls what ports are on/off over USB.***
|
||||
|
||||
Run it and you will get the current settings. Something like this:
|
||||
|
||||
``+QCFG: "usbcfg",0x2C7C,0x0122,1,1,1,1,1,0,0``
|
||||
|
||||
Send ``AT+QCFG="usbcfg",0x2C7C,0x0122,1,1,1,1,1,1,0`` to enable adb
|
||||
|
||||
Now you can reboot: ``AT+CFUN=1,1``
|
||||
|
||||
|
||||
|
||||
This will do the following:
|
||||
|
||||
- Enable PCIe RC mode (Driver selection is automatic now)
|
||||
- Set to ECM mode via USB and AP mode connection behavior
|
||||
- Force Enables ADB Access
|
||||
- Reboots after all the above
|
||||
|
||||
Tip: APN automatic selection will somtimes choose the wrong APN. You may need to set your APN after powering up with the SIM inserted.
|
||||
|
||||
## The List
|
||||
- ``AT+CFUN=1,1`` (reboot)
|
||||
- ``AT+CFUN=0;CFUN=1`` (Disconnect then reconnect)(tip: run this after chnaging APN and you don't have to reboot)
|
||||
- ``AT+QMAPWAC? ``(get current status of auto connect, 0=disabled 1=enabled)
|
||||
- ``AT+QMAPWAC=1`` (enable auto connect internet for ethernet)
|
||||
- ``AT+QMAPWAC=0`` (disable auto connect for ethernet; use when you want internet over USB to work; IPPT must be disabled)
|
||||
- ``AT+QUIMSLOT?`` (get active sim slot; 1=Slot 1; 2=Slot 2)
|
||||
- ``AT+QUIMSLOT=1`` (switch to sim slot 1)
|
||||
- ``AT+QUIMSLOT=2`` (switch to sim slot 2)
|
||||
- ``AT+CGDCONT?`` (Get active APN profle st 1 through 8)
|
||||
- ``AT+QMBNCFG="AutoSel",0;+QMBNCFG="Deactivate"`` (Disable Automatic APN selection)(You will need to set your APN when you switch SIMs or Slots)(Can also set APN after you switch the run ``AT+CFUN=0;CFUN=1``
|
||||
- ``AT+CGDCONT=1,"IPV4V6","APNHERE"`` (Sets APN profile 1 to APNHERE using both IPV4 and IPV6)
|
||||
- ``AT+GSN`` (Show current IMEI)
|
||||
- ``AT+EGMR=0,7`` (Show current IMEI)
|
||||
- ``AT+EGMR=1,7,"IMEIGOESHERE"`` (sets/repairs IMEI)
|
||||
- ``AT+QCFG="usbcfg",0x2C7C,0x0801,1,1,1,1,1,2,0`` (enables adb bypasses adb key)
|
||||
- ``AT+QENG="servingcell"`` (shows anchor band and network connection status)
|
||||
- ``AT+QCAINFO`` (Show all connected bands/CA info)
|
||||
- ``AT+QNWPREFCFG="mode_pref"`` (Check what the current network search mode is set to)
|
||||
- ``AT+QNWPREFCFG="mode_pref",AUTO`` (Set network search mode to automatic)
|
||||
- ``AT+QNWPREFCFG="mode_pref",NR5G:LTE`` (Set network search mode to 5GNR and 4GLTE only)
|
||||
- ``AT+QNWPREFCFG="mode_pref",NR5G`` (Set network search mode to 5GNR only)
|
||||
- ``AT+QNWPREFCFG="mode_pref",LTE`` (Set network search mode to 4GLTE only)
|
||||
- ``AT+QNWPREFCFG="nr5g_disable_mode"`` (Check to see if SA or NSA NR5G is disabled)
|
||||
- ``AT+QNWPREFCFG="nr5g_disable_mode",0`` (Enable Both SA and NSA 5GNR)
|
||||
- ``AT+QNWPREFCFG="nr5g_disable_mode",1`` (Disable SA 5GNR only)
|
||||
- ``AT+QNWPREFCFG="nr5g_disable_mode",2`` (Disable NSA 5GNR only)
|
||||
- ``AT+QNWPREFCFG="nr5g_band"`` (Get current SA 5GNR bandlock settings)
|
||||
- ``AT+QNWPREFCFG="nsa_nr5g_band"`` (Get current NSA 5GNR bandlock settings)
|
||||
- ``AT+QNWPREFCFG="nr5g_band",1:2:3:4:5:6`` (Example: Lock to SA 5G/NR bands n1,n2,n3,n4,n5, and n6)
|
||||
- ``AT+QNWPREFCFG="nsa_nr5g_band",1:2:3:4:5:6`` (Example: Lock to SA 5G/NR bands n1,n2,n3,n4,n5, and n6)
|
||||
- ``AT+QNWPREFCFG="lte_band"`` (Get current 4GLTE bandlock settings)
|
||||
- ``AT+QNWPREFCFG="lte_band",1:2:3:4:5:6`` (Example: Lock to 4G/LTE bands 1,2,3,4,5, and 6)
|
||||
- ``AT+QMAP="WWAN"`` (Show currently assigned IPv4 and IPv6 from the provider)
|
||||
- ``AT+QMAP="LANIP"`` (Show current DHCP range and Gateway address for VLAN0)
|
||||
- ``AT+QMAP="LANIP",IP_start_range,IP_end_range,Gateway_IP `` (Set IPv4 Start/End range and Gateway IP of DHCP for VLAN0)
|
||||
- ``AT+QMAP="DHCPV4DNS","disable"`` (disable the onboard DNS proxy; recommended for IPPT)
|
||||
- ``AT+QMAP="MPDN_rule",0,1,0,1,1,"FF:FF:FF:FF:FF:FF"``
|
||||
(:warning: On the RM551E-GL you must specify the ethernet devices MAC address instead of FF:FF:FF...)
|
||||
- ``AT+QMAP="MPDN_rule",0`` (turn off IPPT/clear MPDN rule 0; Remember to run AT+QMAPWAC=1 and reboot after)
|
||||
|
||||
I plan to create a watchdog service for /opt/bin and /opt/sbin that will automaticly link new packages to /bin or /sbin later on in order to combat this.
|
||||
|
||||
### TTYd installation
|
||||
|
||||
It isn't perfect yet so it goes here under Advanced/Beta for now.
|
||||
Here's what you gotta know about going into it:
|
||||
|
||||
- This listens on port 443 for http requests (no SSL/TLS yet)
|
||||
- This will automaticly install entware and patch the login and passwd binaries with ones from entware
|
||||
- It will ask you to set a password for the `root` user account
|
||||
- TTYd doesn't seem to be too mobile friendly for now but I optimized it the best i could for now so it is at least usable through a smartphone browser. Hopefully the startup script can be improved even more later.
|
||||
|
||||
## Acknowledgements
|
||||
### GitHub Users/Individuals:
|
||||
@@ -144,15 +186,12 @@ Thank You to:
|
||||
|
||||
[rbflurry](https://github.com/rbflurry/) for inital Simple Admin fixes
|
||||
|
||||
[dr-dolomite](https://github.com/dr-dolomite) for some major stat page improvements and this repos first approved external PR!
|
||||
[dr-dolomite](https://github.com/dr-dolomite) for simpleadmin 2.0 and QuecManager!
|
||||
|
||||
[tarunVreddy](https://github.com/tarunVreddy) for helping with the SA band aggregation parse
|
||||
|
||||
### Existing projects:
|
||||
Simpleadmin heavily uses the AT Command Parsing Scripts (Basically a copy with new changes and tweaks) of Dairyman's Rooter Source https://github.com/ofmodemsandmen/ROOterSource2203
|
||||
|
||||
Tailscale was obtained through Tailscale's static build page. Since these modems have a 32-bit ARM processor on-board I used the arm package. https://pkgs.tailscale.com/stable/#static
|
||||
|
||||
Entware/opkg was obtained through [Entware's wiki](https://github.com/Entware/Entware/wiki/Alternative-install-vs-standard) and the installer heavily modified by [iamromulan](https://github.com/iamromulan) for use with Quectel modems
|
||||
|
||||
TTYd was obtained from the [TTYd Project](https://github.com/tsl0922/ttyd)
|
||||
|
||||
@@ -1,938 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Define toolkit paths
|
||||
GITUSER="iamromulan"
|
||||
GITTREE="development"
|
||||
GITMAINTREE="main"
|
||||
GITDEVTREE="development"
|
||||
TMP_DIR="/tmp"
|
||||
USRDATA_DIR="/usrdata"
|
||||
SOCAT_AT_DIR="/usrdata/socat-at-bridge"
|
||||
SOCAT_AT_SYSD_DIR="/usrdata/socat-at-bridge/systemd_units"
|
||||
SIMPLE_ADMIN_DIR="/usrdata/simpleadmin"
|
||||
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
||||
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
|
||||
TAILSCALE_DIR="/usrdata/tailscale"
|
||||
TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd"
|
||||
# AT Command Script Variables and Functions
|
||||
DEVICE_FILE="/dev/smd7"
|
||||
TIMEOUT=4 # Set a timeout for the response
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
|
||||
# Basic AT commands without socat bridge for fast responce commands only
|
||||
start_listening() {
|
||||
cat "$DEVICE_FILE" > /tmp/device_readout &
|
||||
CAT_PID=$!
|
||||
}
|
||||
|
||||
send_at_command() {
|
||||
echo -e "\e[1;31mThis only works for basic quick responding commands!\e[0m" # Red
|
||||
echo -e "\e[1;36mType 'install' to simply type atcmd in shell from now on\e[0m"
|
||||
echo -e "\e[1;36mThe installed version is much better than this portable version\e[0m"
|
||||
echo -e "\e[1;32mEnter AT command (or type 'exit' to quit): \e[0m"
|
||||
read at_command
|
||||
if [ "$at_command" = "exit" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$at_command" = "install" ]; then
|
||||
install_update_at_socat
|
||||
echo -e "\e[1;32mInstalled. Type atcmd from adb shell or ssh to start an AT Command session\e[0m"
|
||||
return 1
|
||||
fi
|
||||
echo -e "${at_command}\r" > "$DEVICE_FILE"
|
||||
}
|
||||
|
||||
wait_for_response() {
|
||||
local start_time=$(date +%s)
|
||||
local current_time
|
||||
local elapsed_time
|
||||
|
||||
echo -e "\e[1;32mCommand sent, waiting for response...\e[0m"
|
||||
while true; do
|
||||
if grep -qe "OK" -e "ERROR" /tmp/device_readout; then
|
||||
echo -e "\e[1;32mResponse received:\e[0m"
|
||||
cat /tmp/device_readout
|
||||
return 0
|
||||
fi
|
||||
current_time=$(date +%s)
|
||||
elapsed_time=$((current_time - start_time))
|
||||
if [ "$elapsed_time" -ge "$TIMEOUT" ]; then
|
||||
echo -e "\e[1;31mError: Response timed out.\e[0m" # Red
|
||||
echo -e "\e[1;32mIf the responce takes longer than a second or 2 to respond this will not work\e[0m" # Green
|
||||
echo -e "\e[1;36mType install to install the better version of this that will work.\e[0m" # Cyan
|
||||
return 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
kill "$CAT_PID"
|
||||
wait "$CAT_PID" 2>/dev/null
|
||||
rm -f /tmp/device_readout
|
||||
}
|
||||
|
||||
send_at_commands() {
|
||||
if [ -c "$DEVICE_FILE" ]; then
|
||||
while true; do
|
||||
start_listening
|
||||
send_at_command
|
||||
if [ $? -eq 1 ]; then
|
||||
cleanup
|
||||
break
|
||||
fi
|
||||
wait_for_response
|
||||
cleanup
|
||||
done
|
||||
else
|
||||
echo -e "\e[1;31mError: Device $DEVICE_FILE does not exist!\e[0m"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check for existing Entware/opkg installation, install if not installed
|
||||
ensure_entware_installed() {
|
||||
remount_rw
|
||||
if [ ! -f "/opt/bin/opkg" ]; then
|
||||
echo -e "\e[1;32mInstalling Entware/OPKG\e[0m"
|
||||
cd /tmp && wget -O installentware.sh "https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/installentware.sh" && chmod +x installentware.sh && ./installentware.sh
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mEntware/OPKG installation failed. Please check your internet connection or the repository URL.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
cd /
|
||||
else
|
||||
echo -e "\e[1;32mEntware/OPKG is already installed.\e[0m"
|
||||
if [ "$(readlink /bin/login)" != "/opt/bin/login" ]; then
|
||||
opkg update && opkg install shadow-login shadow-passwd shadow-useradd
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mPackage installation failed. Please check your internet connection and try again.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Replace the login and passwd binaries and set home for root to a writable directory
|
||||
rm /opt/etc/shadow
|
||||
rm /opt/etc/passwd
|
||||
cp /etc/shadow /opt/etc/
|
||||
cp /etc/passwd /opt/etc
|
||||
mkdir -p /usrdata/root/bin
|
||||
touch /usrdata/root/.profile
|
||||
echo "# Set PATH for all shells" > /usrdata/root/.profile
|
||||
echo "export PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin" >> /usrdata/root/.profile
|
||||
chmod +x /usrdata/root/.profile
|
||||
sed -i '1s|/home/root:/bin/sh|/usrdata/root:/bin/bash|' /opt/etc/passwd
|
||||
rm /bin/login /usr/bin/passwd
|
||||
ln -sf /opt/bin/login /bin
|
||||
ln -sf /opt/bin/passwd /usr/bin/
|
||||
ln -sf /opt/bin/useradd /usr/bin/
|
||||
echo -e "\e[1;31mPlease set the root password.\e[0m"
|
||||
/opt/bin/passwd
|
||||
|
||||
# Install basic and useful utilities
|
||||
opkg install mc htop dfc lsof
|
||||
ln -sf /opt/bin/mc /bin
|
||||
ln -sf /opt/bin/htop /bin
|
||||
ln -sf /opt/bin/dfc /bin
|
||||
ln -sf /opt/bin/lsof /bin
|
||||
fi
|
||||
|
||||
if [ ! -f "/usrdata/root/.profile" ]; then
|
||||
opkg update && opkg install shadow-useradd
|
||||
mkdir -p /usrdata/root/bin
|
||||
touch /usrdata/root/.profile
|
||||
echo "# Set PATH for all shells" > /usrdata/root/.profile
|
||||
echo "export PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin" >> /usrdata/root/.profile
|
||||
chmod +x /usrdata/root/.profile
|
||||
sed -i '1s|/home/root:/bin/sh|/usrdata/root:/bin/bash|' /opt/etc/passwd
|
||||
fi
|
||||
fi
|
||||
if [ ! -f "/opt/sbin/useradd" ]; then
|
||||
echo "useradd does not exist. Installing shadow-useradd..."
|
||||
opkg install shadow-useradd
|
||||
else
|
||||
echo "useradd already exists. Continuing..."
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
#Uninstall Entware if the Users chooses
|
||||
uninstall_entware() {
|
||||
echo -e '\033[31mInfo: Starting Entware/OPKG uninstallation...\033[0m'
|
||||
|
||||
# Stop services
|
||||
systemctl stop rc.unslung.service
|
||||
/opt/etc/init.d/rc.unslung stop
|
||||
rm /lib/systemd/system/multi-user.target.wants/rc.unslung.service
|
||||
rm /lib/systemd/system/rc.unslung.service
|
||||
|
||||
systemctl stop opt.mount
|
||||
rm /lib/systemd/system/multi-user.target.wants/start-opt-mount.service
|
||||
rm /lib/systemd/system/opt.mount
|
||||
rm /lib/systemd/system/start-opt-mount.service
|
||||
|
||||
# Unmount /opt if mounted
|
||||
mountpoint -q /opt && umount /opt
|
||||
|
||||
# Remove Entware installation directory
|
||||
rm -rf /usrdata/opt
|
||||
rm -rf /opt
|
||||
|
||||
# Reload systemctl daemon
|
||||
systemctl daemon-reload
|
||||
|
||||
# Optionally, clean up any modifications to /etc/profile or other system files
|
||||
# Restore original link to login binary compiled by Quectel
|
||||
rm /bin/login
|
||||
ln /bin/login.shadow /bin/login
|
||||
|
||||
echo -e '\033[32mInfo: Entware/OPKG has been uninstalled successfully.\033[0m'
|
||||
}
|
||||
|
||||
# function to configure the fetures of simplefirewall
|
||||
configure_simple_firewall() {
|
||||
if [ ! -f "$SIMPLE_FIREWALL_SCRIPT" ]; then
|
||||
echo -e "\033[0;31mSimplefirewall is not installed, would you like to install it?\033[0m"
|
||||
echo -e "\033[0;32m1) Yes\033[0m"
|
||||
echo -e "\033[0;31m2) No\033[0m"
|
||||
read -p "Enter your choice (1-2): " install_choice
|
||||
|
||||
case $install_choice in
|
||||
1)
|
||||
install_simple_firewall
|
||||
;;
|
||||
2)
|
||||
return
|
||||
;;
|
||||
*)
|
||||
echo -e "\033[0;31mInvalid choice. Please select either 1 or 2.\033[0m"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
echo -e "\e[1;32mConfigure Simple Firewall:\e[0m"
|
||||
echo -e "\e[38;5;208m1) Configure incoming port block\e[0m"
|
||||
echo -e "\e[38;5;27m2) Configure TTL\e[0m"
|
||||
read -p "Enter your choice (1-2): " menu_choice
|
||||
|
||||
case $menu_choice in
|
||||
1)
|
||||
# Original ports configuration code with exit option
|
||||
current_ports_line=$(grep '^PORTS=' "$SIMPLE_FIREWALL_SCRIPT")
|
||||
ports=$(echo "$current_ports_line" | cut -d'=' -f2 | tr -d '()' | tr ' ' '\n' | grep -o '[0-9]\+')
|
||||
echo -e "\e[1;32mCurrent configured ports:\e[0m"
|
||||
echo "$ports" | awk '{print NR") "$0}'
|
||||
|
||||
while true; do
|
||||
echo -e "\e[1;32mEnter a port number to add/remove, or type 'done' or 'exit' to finish:\e[0m"
|
||||
read port
|
||||
if [ "$port" = "done" ] || [ "$port" = "exit" ]; then
|
||||
if [ "$port" = "exit" ]; then
|
||||
echo -e "\e[1;31mExiting without making changes...\e[0m"
|
||||
return
|
||||
fi
|
||||
break
|
||||
elif ! echo "$port" | grep -qE '^[0-9]+$'; then
|
||||
echo -e "\e[1;31mInvalid input: Please enter a numeric value.\e[0m"
|
||||
elif echo "$ports" | grep -q "^$port\$"; then
|
||||
ports=$(echo "$ports" | grep -v "^$port\$")
|
||||
echo -e "\e[1;32mPort $port removed.\e[0m"
|
||||
else
|
||||
ports=$(echo "$ports"; echo "$port" | grep -o '[0-9]\+')
|
||||
echo -e "\e[1;32mPort $port added.\e[0m"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$port" != "exit" ]; then
|
||||
new_ports_line="PORTS=($(echo "$ports" | tr '\n' ' '))"
|
||||
sed -i "s/$current_ports_line/$new_ports_line/" "$SIMPLE_FIREWALL_SCRIPT"
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
# TTL configuration code
|
||||
ttl_value=$(cat /usrdata/simplefirewall/ttlvalue)
|
||||
if [ "$ttl_value" -eq 0 ]; then
|
||||
echo -e "\e[1;31mTTL is not set.\e[0m"
|
||||
else
|
||||
echo -e "\e[1;32mTTL value is set to $ttl_value.\e[0m"
|
||||
fi
|
||||
|
||||
echo -e "\e[1;31mType 'exit' to cancel.\e[0m"
|
||||
read -p "What do you want the TTL value to be: " new_ttl_value
|
||||
if [ "$new_ttl_value" = "exit" ]; then
|
||||
echo -e "\e[1;31mExiting TTL configuration...\e[0m"
|
||||
return
|
||||
elif ! echo "$new_ttl_value" | grep -qE '^[0-9]+$'; then
|
||||
echo -e "\e[1;31mInvalid input: Please enter a numeric value.\e[0m"
|
||||
return
|
||||
else
|
||||
/usrdata/simplefirewall/ttl-override stop
|
||||
echo "$new_ttl_value" > /usrdata/simplefirewall/ttlvalue
|
||||
/usrdata/simplefirewall/ttl-override start
|
||||
echo -e "\033[0;32mTTL value updated to $new_ttl_value.\033[0m"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo -e "\e[1;31mInvalid choice. Please select either 1 or 2.\e[0m"
|
||||
;;
|
||||
esac
|
||||
|
||||
systemctl restart simplefirewall
|
||||
echo -e "\e[1;32mFirewall configuration updated.\e[0m"
|
||||
}
|
||||
|
||||
set_simpleadmin_passwd(){
|
||||
ensure_entware_installed
|
||||
opkg update
|
||||
opkg install libaprutil
|
||||
wget -O /usrdata/root/bin/htpasswd https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/htpasswd && chmod +x /usrdata/root/bin/htpasswd
|
||||
wget -O /usrdata/root/bin/simplepasswd https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/simplepasswd && chmod +x /usrdata/root/bin/simplepasswd
|
||||
echo -e "\e[1;32mTo change your simpleadmin (admin) password in the future...\e[0m"
|
||||
echo -e "\e[1;32mIn the console type simplepasswd and press enter\e[0m"
|
||||
/usrdata/root/bin/simplepasswd
|
||||
|
||||
}
|
||||
|
||||
set_root_passwd() {
|
||||
echo -e "\e[1;31mPlease set the root/console password.\e[0m"
|
||||
/opt/bin/passwd
|
||||
}
|
||||
|
||||
# Function to install/update Simple Admin
|
||||
install_simple_admin() {
|
||||
while true; do
|
||||
echo -e "\e[1;32mWhat version of Simple Admin do you want to install? This will start a webserver on port 80/443 on test build\e[0m"
|
||||
echo -e "\e[1;32m1) Stable current version, (Main Branch)\e[0m"
|
||||
echo -e "\e[1;31m2) Install Test Build (Development Branch)\e[0m"
|
||||
echo -e "\e[0;33m3) Return to Main Menu\e[0m"
|
||||
echo -e "\e[1;32mSelect your choice: \e[0m"
|
||||
read choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
echo -e "\e[1;32mYou are using the development toolkit; Use the one from main if you want the stable version right now\e[0m"
|
||||
break
|
||||
;;
|
||||
2)
|
||||
ensure_entware_installed
|
||||
echo -e "\e[1;31m2) Installing simpleadmin from the development test branch\e[0m"
|
||||
mkdir /usrdata/simpleupdates > /dev/null 2>&1
|
||||
mkdir /usrdata/simpleupdates/scripts > /dev/null 2>&1
|
||||
wget -O /usrdata/simpleupdates/scripts/update_socat-at-bridge.sh https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleupdates/scripts/update_socat-at-bridge.sh && chmod +x /usrdata/simpleupdates/scripts/update_socat-at-bridge.sh
|
||||
echo -e "\e[1;32mInstalling/updating dependency: socat-at-bridge\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
/usrdata/simpleupdates/scripts/update_socat-at-bridge.sh
|
||||
echo -e "\e[1;32m Dependency: socat-at-bridge has been updated/installed.\e[0m"
|
||||
sleep 1
|
||||
wget -O /usrdata/simpleupdates/scripts/update_simplefirewall.sh https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleupdates/scripts/update_simplefirewall.sh && chmod +x /usrdata/simpleupdates/scripts/update_simplefirewall.sh
|
||||
echo -e "\e[1;32mInstalling/updating dependency: simplefirewall\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
/usrdata/simpleupdates/scripts/update_simplefirewall.sh
|
||||
echo -e "\e[1;32m Dependency: simplefirewall has been updated/installed.\e[0m"
|
||||
sleep 1
|
||||
set_simpleadmin_passwd
|
||||
wget -O /usrdata/simpleupdates/scripts/update_simpleadmin.sh https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleupdates/scripts/update_simpleadmin.sh && chmod +x /usrdata/simpleupdates/scripts/update_simpleadmin.sh
|
||||
echo -e "\e[1;32mInstalling/updating: Simpleadmin content\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
/usrdata/simpleupdates/scripts/update_simpleadmin.sh
|
||||
echo -e "\e[1;32mSimpleadmin content has been updated/installed.\e[0m"
|
||||
sleep 1
|
||||
break
|
||||
;;
|
||||
3)
|
||||
echo "Returning to main menu..."
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Invalid choice. Please try again."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Function to Uninstall Simpleadmin and dependencies
|
||||
uninstall_simpleadmin_components() {
|
||||
echo -e "\e[1;32mStarting the uninstallation process for Simpleadmin components.\e[0m"
|
||||
echo -e "\e[1;32mNote: Uninstalling certain components may affect the functionality of others.\e[0m"
|
||||
remount_rw
|
||||
|
||||
# Uninstall Simple Firewall
|
||||
echo -e "\e[1;32mDo you want to uninstall Simplefirewall?\e[0m"
|
||||
echo -e "\e[1;31mIf you do, the TTL part of simpleadmin will no longer work.\e[0m"
|
||||
echo -e "\e[1;32m1) Yes\e[0m"
|
||||
echo -e "\e[1;31m2) No\e[0m"
|
||||
read -p "Enter your choice (1 or 2): " choice_simplefirewall
|
||||
if [ "$choice_simplefirewall" -eq 1 ]; then
|
||||
echo "Uninstalling Simplefirewall..."
|
||||
systemctl stop simplefirewall
|
||||
systemctl stop ttl-override
|
||||
rm -f /lib/systemd/system/simplefirewall.service
|
||||
rm -f /lib/systemd/system/ttl-override.service
|
||||
systemctl daemon-reload
|
||||
rm -rf "$SIMPLE_FIREWALL_DIR"
|
||||
echo "Simplefirewall uninstalled."
|
||||
fi
|
||||
|
||||
# Uninstall socat-at-bridge
|
||||
echo -e "\e[1;32mDo you want to uninstall socat-at-bridge?\e[0m"
|
||||
echo -e "\e[1;31mIf you do, AT commands and the stat page will no longer work. atcmd won't either.\e[0m"
|
||||
echo -e "\e[1;32m1) Yes\e[0m"
|
||||
echo -e "\e[1;31m2) No\e[0m"
|
||||
read -p "Enter your choice (1 or 2): " choice_socat_at_bridge
|
||||
if [ "$choice_socat_at_bridge" -eq 1 ]; then
|
||||
echo -e "\033[0;32mRemoving installed AT Socat Bridge services...\033[0m"
|
||||
systemctl stop at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl disable at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl stop socat-smd11 > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-from-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN > /dev/null 2>&1
|
||||
rm /lib/systemd/system/at-telnet-daemon.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN2.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN2.service > /dev/null 2>&1
|
||||
systemctl daemon-reload > /dev/null 2>&1
|
||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||
rm -rf "/usrdata/micropython" > /dev/null 2>&1
|
||||
rm -rf "/usrdata/at-telnet" > /dev/null 2>&1
|
||||
echo -e "\033[0;32mAT Socat Bridge services removed!...\033[0m"
|
||||
fi
|
||||
|
||||
# Uninstall ttyd
|
||||
echo -e "\e[1;32mDo you want to uninstall ttyd (simpleadmin console)?\e[0m"
|
||||
echo -e "\e[1;31mWarning: Do not uninstall if you are currently using ttyd to do this!!!\e[0m"
|
||||
echo -e "\e[1;32m1) Yes\e[0m"
|
||||
echo -e "\e[1;31m2) No\e[0m"
|
||||
read -p "Enter your choice (1 or 2): " choice_simpleadmin
|
||||
if [ "$choice_simpleadmin" -eq 1 ]; then
|
||||
echo -e "\e[1;34mUninstalling ttyd...\e[0m"
|
||||
systemctl stop ttyd
|
||||
rm -rf /usrdata/ttyd
|
||||
rm /lib/systemd/system/ttyd.service
|
||||
rm /lib/systemd/system/multi-user.target.wants/ttyd.service
|
||||
rm /bin/ttyd
|
||||
echo -e "\e[1;32mttyd has been uninstalled.\e[0m"
|
||||
fi
|
||||
|
||||
echo "Uninstalling the rest of Simpleadmin..."
|
||||
|
||||
# Check if Lighttpd service is installed and remove it if present
|
||||
if [ -f "/lib/systemd/system/lighttpd.service" ]; then
|
||||
echo "Lighttpd detected, uninstalling Lighttpd and its modules..."
|
||||
systemctl stop lighttpd
|
||||
opkg --force-remove --force-removal-of-dependent-packages remove lighttpd-mod-authn_file lighttpd-mod-auth lighttpd-mod-cgi lighttpd-mod-openssl lighttpd-mod-proxy lighttpd
|
||||
rm -rf $LIGHTTPD_DIR
|
||||
fi
|
||||
|
||||
systemctl stop simpleadmin_generate_status
|
||||
systemctl stop simpleadmin_httpd
|
||||
rm -f /lib/systemd/system/simpleadmin_httpd.service
|
||||
rm -f /lib/systemd/system/simpleadmin_generate_status.service
|
||||
systemctl daemon-reload
|
||||
rm -rf "$SIMPLE_ADMIN_DIR"
|
||||
echo "The rest of Simpleadmin and Lighttpd (if present) uninstalled."
|
||||
remount_ro
|
||||
|
||||
echo "Uninstallation process completed."
|
||||
}
|
||||
|
||||
# Function for Tailscale Submenu
|
||||
tailscale_menu() {
|
||||
while true; do
|
||||
echo -e "\e[1;32mTailscale Menu\e[0m"
|
||||
echo -e "\e[1;32m1) Install/Update Tailscale\e[0m"
|
||||
echo -e "\e[1;36m2) Configure Tailscale\e[0m"
|
||||
echo -e "\e[1;31m3) Return to Main Menu\e[0m"
|
||||
read -p "Enter your choice: " tailscale_choice
|
||||
|
||||
case $tailscale_choice in
|
||||
1) install_update_tailscale;;
|
||||
2) configure_tailscale;;
|
||||
3) break;;
|
||||
*) echo "Invalid option";;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Function to install, update, or remove Tailscale
|
||||
install_update_tailscale() {
|
||||
echo -e "\e[1;31m2) Installing tailscale from the $GITTREE branch\e[0m"
|
||||
mkdir /usrdata/simpleupdates > /dev/null 2>&1
|
||||
mkdir /usrdata/simpleupdates/scripts > /dev/null 2>&1
|
||||
wget -O /usrdata/simpleupdates/scripts/update_tailscale.sh https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleupdates/scripts/update_tailscale.sh && chmod +x /usrdata/simpleupdates/scripts/update_tailscale.sh
|
||||
echo -e "\e[1;32mInstalling/updating: Tailscale\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
remount_rw
|
||||
/usrdata/simpleupdates/scripts/update_tailscale.sh
|
||||
echo -e "\e[1;32m Tailscale has been updated/installed.\e[0m"
|
||||
}
|
||||
|
||||
# Function to Configure Tailscale
|
||||
configure_tailscale() {
|
||||
while true; do
|
||||
echo "Configure Tailscale"
|
||||
echo -e "\e[38;5;40m1) Enable Tailscale Web UI at http://192.168.225.1:8088 (Gateway on port 8088)\e[0m" # Green
|
||||
echo -e "\e[38;5;196m2) Disable Tailscale Web UI\e[0m" # Red
|
||||
echo -e "\e[38;5;27m3) Connect to Tailnet\e[0m" # Brown
|
||||
echo -e "\e[38;5;87m4) Connect to Tailnet with SSH ON\e[0m" # Light cyan
|
||||
echo -e "\e[38;5;105m5) Reconnect to Tailnet with SSH OFF\e[0m" # Light magenta
|
||||
echo -e "\e[38;5;172m6) Disconnect from Tailnet (reconnects at reboot)\e[0m" # Light yellow
|
||||
echo -e "\e[1;31m7) Logout from tailscale account\e[0m"
|
||||
echo -e "\e[38;5;27m8) Return to Tailscale Menu\e[0m"
|
||||
read -p "Enter your choice: " config_choice
|
||||
|
||||
case $config_choice in
|
||||
1)
|
||||
remount_rw
|
||||
cd /lib/systemd/system/
|
||||
wget -O tailscale-webui.service https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/systemd/tailscale-webui.service
|
||||
wget -O tailscale-webui-trigger.service https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/systemd/tailscale-webui-trigger.service
|
||||
ln -sf /lib/systemd/system/tailscale-webui-trigger.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl daemon-reload
|
||||
echo "Tailscale Web UI Enabled"
|
||||
echo "Starting Web UI..."
|
||||
systemctl start tailscale-webui
|
||||
echo "Web UI started!"
|
||||
remount_ro
|
||||
;;
|
||||
2)
|
||||
remount_rw
|
||||
systemctl stop tailscale-webui
|
||||
systemctl disable tailscale-webui-trigger
|
||||
rm /lib/systemd/system/multi-user.target.wants/tailscale-webui.service
|
||||
rm /lib/systemd/system/multi-user.target.wants/tailscale-webui-trigger.service
|
||||
rm /lib/systemd/system/tailscale-webui.service
|
||||
rm /lib/systemd/system/tailscale-webui-trigger.service
|
||||
systemctl daemon-reload
|
||||
echo "Tailscale Web UI Stopped and Disabled"
|
||||
remount_ro
|
||||
;;
|
||||
3) $TAILSCALE_DIR/tailscale up --accept-dns=false --reset;;
|
||||
4) $TAILSCALE_DIR/tailscale up --ssh --accept-dns=false --reset;;
|
||||
5) $TAILSCALE_DIR/tailscale up --accept-dns=false --reset;;
|
||||
6) $TAILSCALE_DIR/tailscale down;;
|
||||
7) $TAILSCALE_DIR/tailscale logout;;
|
||||
8) break;;
|
||||
*) echo "Invalid option";;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Function to manage Daily Reboot Timer
|
||||
manage_reboot_timer() {
|
||||
# Remount root filesystem as read-write
|
||||
mount -o remount,rw /
|
||||
|
||||
# Check if the rebootmodem service, timer, or trigger already exists
|
||||
if [ -f /lib/systemd/system/rebootmodem.service ] || [ -f /lib/systemd/system/rebootmodem.timer ] || [ -f /lib/systemd/system/rebootmodem-trigger.service ]; then
|
||||
echo -e "\e[1;32mThe rebootmodem service/timer/trigger is already installed.\e[0m"
|
||||
echo -e "\e[1;32m1) Change\e[0m" # Green
|
||||
echo -e "\e[1;31m2) Remove\e[0m" # Red
|
||||
read -p "Enter your choice (1 for Change, 2 for Remove): " reboot_choice
|
||||
|
||||
case $reboot_choice in
|
||||
2)
|
||||
# Stop and disable timer and trigger service by removing symlinks
|
||||
systemctl stop rebootmodem.timer
|
||||
systemctl stop rebootmodem-trigger.service
|
||||
|
||||
# Remove symbolic links and files
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/rebootmodem-trigger.service
|
||||
rm -f /lib/systemd/system/rebootmodem.service
|
||||
rm -f /lib/systemd/system/rebootmodem.timer
|
||||
rm -f /lib/systemd/system/rebootmodem-trigger.service
|
||||
rm -f "$USRDATA_DIR/reboot_modem.sh"
|
||||
|
||||
# Reload systemd to apply changes
|
||||
systemctl daemon-reload
|
||||
|
||||
echo -e "\e[1;32mRebootmodem service, timer, trigger, and script removed successfully.\e[0m"
|
||||
;;
|
||||
1)
|
||||
printf "Enter the new time for daily reboot (24-hour format in Coordinated Universal Time, HH:MM): "
|
||||
read new_time
|
||||
|
||||
# Validate the new time format using grep
|
||||
if ! echo "$new_time" | grep -qE '^([01]?[0-9]|2[0-3]):[0-5][0-9]$'; then
|
||||
echo "Invalid time format. Exiting."
|
||||
exit 1
|
||||
else
|
||||
# Remove old symlinks and script
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/rebootmodem-trigger.service
|
||||
rm -f "$USRDATA_DIR/reboot_modem.sh"
|
||||
|
||||
# Set the user time to the new time and recreate the service, timer, trigger, and script
|
||||
user_time=$new_time
|
||||
create_service_and_timer
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo -e "\e[1;31mInvalid choice. Exiting.\e[0m"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
printf "Enter the time for daily reboot (24-hour format in UTC, HH:MM): "
|
||||
read user_time
|
||||
|
||||
# Validate the time format using grep
|
||||
if ! echo "$user_time" | grep -qE '^([01]?[0-9]|2[0-3]):[0-5][0-9]$'; then
|
||||
echo "Invalid time format. Exiting."
|
||||
exit 1
|
||||
else
|
||||
create_service_and_timer
|
||||
fi
|
||||
fi
|
||||
|
||||
# Remount root filesystem as read-only
|
||||
mount -o remount,ro /
|
||||
}
|
||||
|
||||
# Function to create systemd service and timer files with the user-specified time for the reboot timer
|
||||
create_service_and_timer() {
|
||||
remount_rw
|
||||
# Define the path for the modem reboot script
|
||||
MODEM_REBOOT_SCRIPT="$USRDATA_DIR/reboot_modem.sh"
|
||||
|
||||
# Create the modem reboot script
|
||||
echo "#!/bin/sh
|
||||
/bin/echo -e 'AT+CFUN=1,1 \r' > /dev/smd7" > "$MODEM_REBOOT_SCRIPT"
|
||||
|
||||
# Make the script executable
|
||||
chmod +x "$MODEM_REBOOT_SCRIPT"
|
||||
|
||||
# Create the systemd service file for reboot
|
||||
echo "[Unit]
|
||||
Description=Reboot Modem Daily
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/sh /usrdata/reboot_modem.sh
|
||||
Restart=no
|
||||
RemainAfterExit=no" > /lib/systemd/system/rebootmodem.service
|
||||
|
||||
# Create the systemd timer file with the user-specified time
|
||||
echo "[Unit]
|
||||
Description=Starts rebootmodem.service daily at the specified time
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* $user_time:00
|
||||
Persistent=false" > /lib/systemd/system/rebootmodem.timer
|
||||
|
||||
# Create a trigger service that starts the timer at boot
|
||||
echo "[Unit]
|
||||
Description=Trigger the rebootmodem timer at boot
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/systemctl start rebootmodem.timer
|
||||
RemainAfterExit=yes" > /lib/systemd/system/rebootmodem-trigger.service
|
||||
|
||||
# Create symbolic links for the trigger service in the wanted directory
|
||||
ln -sf /lib/systemd/system/rebootmodem-trigger.service /lib/systemd/system/multi-user.target.wants/
|
||||
|
||||
# Reload systemd to recognize the new timer and trigger service
|
||||
systemctl daemon-reload
|
||||
sleep 2s
|
||||
|
||||
# Start the trigger service, which will start the timer
|
||||
systemctl start rebootmodem-trigger.service
|
||||
remount_ro
|
||||
|
||||
# Confirmation
|
||||
echo -e "\e[1;32mRebootmodem-trigger service created and started successfully.\e[0m"
|
||||
echo -e "\e[1;32mReboot schedule set successfully. The modem will reboot daily at $user_time UTC.\e[0m"
|
||||
}
|
||||
|
||||
manage_cfun_fix() {
|
||||
cfun_service_path="/lib/systemd/system/cfunfix.service"
|
||||
cfun_fix_script="/usrdata/cfun_fix.sh"
|
||||
|
||||
mount -o remount,rw /
|
||||
|
||||
if [ -f "$cfun_service_path" ]; then
|
||||
echo -e "\e[1;32mThe CFUN fix is already installed. Do you want to remove it?\e[0m" # Green
|
||||
echo -e "\e[1;32m1) Yes\e[0m" # Green
|
||||
echo -e "\e[1;31m2) No\e[0m" # Red
|
||||
read -p "Enter your choice: " choice
|
||||
|
||||
if [ "$choice" = "1" ]; then
|
||||
echo "Removing CFUN fix..."
|
||||
systemctl stop cfunfix.service
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/cfunfix.service
|
||||
rm -f "$cfun_service_path"
|
||||
rm -f "$cfun_fix_script"
|
||||
systemctl daemon-reload
|
||||
echo "CFUN fix has been removed."
|
||||
else
|
||||
echo "Returning to main menu..."
|
||||
fi
|
||||
else
|
||||
echo -e "\e[1;32mInstalling CFUN fix...\e[0m"
|
||||
|
||||
# Create the CFUN fix script
|
||||
echo "#!/bin/sh
|
||||
/bin/echo -e 'AT+CFUN=1 \r' > /dev/smd7" > "$cfun_fix_script"
|
||||
chmod +x "$cfun_fix_script"
|
||||
|
||||
# Create the systemd service file to execute the CFUN fix script at boot
|
||||
echo "[Unit]
|
||||
Description=CFUN Fix Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=$cfun_fix_script
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target" > "$cfun_service_path"
|
||||
|
||||
ln -sf "$cfun_service_path" "/lib/systemd/system/multi-user.target.wants/"
|
||||
systemctl daemon-reload
|
||||
mount -o remount,ro /
|
||||
echo -e "\e[1;32mCFUN fix has been installed and will execute at every boot.\e[0m"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
install_sshd() {
|
||||
if [ -d "/usrdata/sshd" ]; then
|
||||
echo -e "\e[1;31mSSHD is currently installed.\e[0m"
|
||||
echo -e "Do you want to update or uninstall?"
|
||||
echo -e "1.) Update"
|
||||
echo -e "2.) Uninstall"
|
||||
read -p "Select an option (1 or 2): " sshd_choice
|
||||
|
||||
case $sshd_choice in
|
||||
1)
|
||||
echo -e "\e[1;31m2) Installing sshd from the $GITTREE branch\e[0m"
|
||||
;;
|
||||
2)
|
||||
echo -e "\e[1;31mUninstalling SSHD...\e[0m"
|
||||
systemctl stop sshd
|
||||
rm /lib/systemd/system/sshd.service
|
||||
opkg remove openssh-server-pam
|
||||
echo -e "\e[1;32mSSHD has been uninstalled successfully.\e[0m"
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
echo -e "\e[1;31mInvalid option. Please select 1 or 2.\e[0m"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Proceed with installation or updating if not uninstalling
|
||||
ensure_entware_installed
|
||||
mkdir /usrdata/simpleupdates > /dev/null 2>&1
|
||||
mkdir /usrdata/simpleupdates/scripts > /dev/null 2>&1
|
||||
wget -O /usrdata/simpleupdates/scripts/update_sshd.sh https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleupdates/scripts/update_sshd.sh && chmod +x /usrdata/simpleupdates/scripts/update_sshd.sh
|
||||
echo -e "\e[1;32mInstalling/updating: SSHd\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
/usrdata/simpleupdates/scripts/update_sshd.sh
|
||||
echo -e "\e[1;32m SSHd has been updated/installed.\e[0m"
|
||||
}
|
||||
|
||||
|
||||
# Main menu
|
||||
while true; do
|
||||
echo " .%+: "
|
||||
echo " .*@@@-. "
|
||||
echo " :@@@@- "
|
||||
echo " @@@@#. "
|
||||
echo " -@@@@#. "
|
||||
echo " :. %@@@@: -# "
|
||||
echo " .+- #@@@@%.+@- "
|
||||
echo " .#- . +@@@@# #@- "
|
||||
echo " -@*@*@% @@@@@::@@= "
|
||||
echo ".+%@@@@@@@@@%=. =@@@@# #@@- .. "
|
||||
echo " .@@@@@: :@@@@@ =@@@..%= "
|
||||
echo " -::@-.+. @@@@@.=@@@- =@- "
|
||||
echo " .@- .@@@@@:.@@@* @@. "
|
||||
echo " .%- -@@@@@:=@@@@ @@# "
|
||||
echo " .#- .%@@@@@@#. +@@@@@.#@@@@ @@@."
|
||||
echo " .*- .@@@@@@@@@@=. @@@@@@ @@@@@ @@@:"
|
||||
echo " :. .%@@@@@@@@@@@%. .@@@@@+:@@@@@ @@@-"
|
||||
echo " -@@@@@@@@@@@@@@@..@@@@@@.-@@@@@ .@@@-"
|
||||
echo " -@@@@@@@@@@%. .@@@@@@. @@@@@+ =@@@="
|
||||
echo " =@@@@@@@@* .@@@@@@. @@@@@@..@@@@-"
|
||||
echo " #@@@@@@@@-*@@@@@%..@@@@@@+ #@@@@-"
|
||||
echo " @@@@@@:.-@@@@@@. @@@@@@= %@@@@@."
|
||||
echo " .@@@@. *@@@@@@- .+@@@@@@-.@@@@@@+ "
|
||||
echo " %@@. =@@@@@*. +@@@@@@%.-@@@@@@% "
|
||||
echo " .@@ .@@@@@= :@@@@@@@@..@@@@@@@= "
|
||||
echo " =@.+@@@@@. -@@@@@@@*.:@@@@@@@*. "
|
||||
echo " %.*@@@@= .@@@@@@@-.:@@@@@@@+. "
|
||||
echo " ..@@@@= .@@@@@@: #@@@@@@@: "
|
||||
echo " .@@@@ +@@@@..%@@@@@+. "
|
||||
echo " .@@@. @@@@.:@@@@+. "
|
||||
echo " @@@. @@@. @@@* .@. "
|
||||
echo " :@@@ %@@..@@#. *@ "
|
||||
echo " -*: .@@* :@@. @@. -..@@ "
|
||||
echo " =@@@@@@.*@- :@% @* =@:=@# "
|
||||
echo " .@@@-+@@@@:%@..%- ...@%:@@: "
|
||||
echo " .@@. @@-%@: .%@@*@@%. "
|
||||
echo " :@@ :+ *@ *@@#*@@@. "
|
||||
echo " =@@@.@@@@ "
|
||||
echo " .*@@@:=@@@@: "
|
||||
echo " .@@@@:.@@@@@: "
|
||||
echo " .@@@@#.-@@@@@. "
|
||||
echo " #@@@@: =@@@@@- "
|
||||
echo " .@@@@@..@@@@@@* "
|
||||
echo " -@@@@@. @@@@@@#. "
|
||||
echo " -@@@@@ @@@@@@% "
|
||||
echo " @@@@@. #@@@@@@. "
|
||||
echo " :@@@@# =@@@@@@% "
|
||||
echo " @@@@@: @@@@@@@: "
|
||||
echo " *@@@@ @@@@@@@. "
|
||||
echo " .@@@@ @@@@@@@ "
|
||||
echo " #@@@. @@@@@@* "
|
||||
echo " @@@# @@@@@@@ "
|
||||
echo " .@@+=@@@@@@. "
|
||||
echo " *@@@@@@ "
|
||||
echo " :@@@@@= "
|
||||
echo " .@@@@@@. "
|
||||
echo " :@@@@@*. "
|
||||
echo " .=@@@@@- "
|
||||
echo " :+##+. "
|
||||
|
||||
echo -e "\e[92m"
|
||||
echo "Welcome to iamromulan's RGMII Toolkit script for Quectel RMxxx Series modems!"
|
||||
echo "Visit https://github.com/iamromulan for more!"
|
||||
echo -e "\e[0m"
|
||||
echo "Select an option:"
|
||||
echo -e "\e[0m"
|
||||
echo -e "\e[96m1) Send AT Commands\e[0m" # Cyan
|
||||
echo -e "\e[93m2) Install Simple Admin\e[0m" # Yellow
|
||||
echo -e "\e[95m3) Set Simpleadmin (admin) password\e[0m" # Light Purple
|
||||
echo -e "\e[94m4) Set Console/ttyd (root) password\e[0m" # Light Blue
|
||||
echo -e "\e[91m5) Uninstall Simple Admin\e[0m" # Light Red
|
||||
echo -e "\e[95m6) Simple Firewall Management\e[0m" # Light Purple
|
||||
echo -e "\e[94m7) Tailscale Management\e[0m" # Light Blue
|
||||
echo -e "\e[92m8) Install/Change or remove Daily Reboot Timer\e[0m" # Light Green
|
||||
echo -e "\e[96m9) Install/Uninstall CFUN 0 Fix\e[0m" # Cyan (repeated color for additional options)
|
||||
echo -e "\e[91m10) Uninstall Entware/OPKG\e[0m" # Light Red
|
||||
echo -e "\e[92m11) Install Speedtest.net CLI app (speedtest command)\e[0m" # Light Green
|
||||
echo -e "\e[92m12) Install Fast.com CLI app (fast command)(tops out at 40Mbps)\e[0m" # Light Green
|
||||
echo -e "\e[92m13) Install OpenSSH Server\e[0m" # Light Green
|
||||
echo -e "\e[93m14) Exit\e[0m" # Yellow (repeated color for exit option)
|
||||
read -p "Enter your choice: " choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
send_at_commands
|
||||
;;
|
||||
2)
|
||||
install_simple_admin
|
||||
;;
|
||||
3) set_simpleadmin_passwd
|
||||
;;
|
||||
4)
|
||||
set_root_passwd
|
||||
;;
|
||||
5)
|
||||
uninstall_simpleadmin_components
|
||||
;;
|
||||
6)
|
||||
configure_simple_firewall
|
||||
;;
|
||||
|
||||
7)
|
||||
tailscale_menu
|
||||
;;
|
||||
8)
|
||||
manage_reboot_timer
|
||||
;;
|
||||
9)
|
||||
manage_cfun_fix
|
||||
;;
|
||||
10)
|
||||
echo -e "\033[31mAre you sure you want to uninstall entware?\033[0m"
|
||||
echo -e "\033[31m1) Yes\033[0m"
|
||||
echo -e "\033[31m2) No\033[0m"
|
||||
read -p "Select an option (1 or 2): " user_choice
|
||||
|
||||
case $user_choice in
|
||||
1)
|
||||
# If yes, uninstall existing entware
|
||||
echo -e "\033[31mUninstalling existing entware...\033[0m"
|
||||
uninstall_entware # Assuming uninstall_entware is a defined function or command
|
||||
echo -e "\033[31mEntware has been uninstalled.\033[0m"
|
||||
;;
|
||||
2)
|
||||
# If no, exit the script
|
||||
echo -e "\033[31mUninstallation cancelled.\033[0m"
|
||||
exit # Use 'exit' to terminate the script outside a loop
|
||||
;;
|
||||
*)
|
||||
# Handle invalid input
|
||||
echo -e "\033[31mInvalid option. Please select 1 or 2.\033[0m"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
11)
|
||||
ensure_entware_installed
|
||||
echo -e "\e[1;32mInstalling Speedtest.net CLI (speedtest command)\e[0m"
|
||||
remount_rw
|
||||
mkdir /usrdata/root
|
||||
mkdir /usrdata/root/bin
|
||||
cd /usrdata/root/bin
|
||||
wget https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-armhf.tgz
|
||||
tar -xzf ookla-speedtest-1.2.0-linux-armhf.tgz
|
||||
rm ookla-speedtest-1.2.0-linux-armhf.tgz
|
||||
rm speedtest.md
|
||||
cd /
|
||||
ln -sf /usrdata/root/bin/speedtest /bin
|
||||
remount_ro
|
||||
echo -e "\e[1;32mSpeedtest CLI (speedtest command) installed!!\e[0m"
|
||||
echo -e "\e[1;32mTry running the command 'speedtest'\e[0m"
|
||||
echo -e "\e[1;32mNote that it will not work unless you login to the root account first\e[0m"
|
||||
echo -e "\e[1;32mNormaly only an issue in adb, ttyd and ssh you are forced to login\e[0m"
|
||||
echo -e "\e[1;32mIf in adb just type login and then try to run the speedtest command\e[0m"
|
||||
;;
|
||||
12)
|
||||
echo -e "\e[1;32mInstalling fast.com CLI (fast command)\e[0m"
|
||||
remount_rw
|
||||
mkdir /usrdata/root
|
||||
mkdir /usrdata/root/bin
|
||||
cd /usrdata/root/bin
|
||||
wget -O fast https://github.com/ddo/fast/releases/download/v0.0.4/fast_linux_arm && chmod +x fast
|
||||
cd /
|
||||
ln -sf /usrdata/root/bin/fast /bin
|
||||
remount_ro
|
||||
echo -e "\e[1;32mFast.com CLI (speedtest command) installed!!\e[0m"
|
||||
echo -e "\e[1;32mTry running the command 'fast'\e[0m"
|
||||
echo -e "\e[1;32mThe fast.com test tops out at 40Mbps on the modem\e[0m"
|
||||
;;
|
||||
13)
|
||||
install_sshd
|
||||
;;
|
||||
14)
|
||||
echo -e "\e[1;32mGoodbye!\e[0m"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo -e "\e[1;31mInvalid option\e[0m"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
6
custom/RM551E-GL/R01/ipk-source/sdxpinn-firstboot/CONTROL/control
Executable file
6
custom/RM551E-GL/R01/ipk-source/sdxpinn-firstboot/CONTROL/control
Executable file
@@ -0,0 +1,6 @@
|
||||
Package: sdxpinn-firstboot
|
||||
Version: 1.0
|
||||
Architecture: sdxpinn
|
||||
Maintainer: Cameron Thompson iamromulan@github.com
|
||||
Source: github.com/iamromulan
|
||||
Description: A first boot init after a flash or factory reset
|
||||
5
custom/RM551E-GL/R01/ipk-source/sdxpinn-firstboot/CONTROL/postinst
Executable file
5
custom/RM551E-GL/R01/ipk-source/sdxpinn-firstboot/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/ash
|
||||
|
||||
service first-boot enable
|
||||
|
||||
exit 0
|
||||
74
custom/RM551E-GL/R01/ipk-source/sdxpinn-firstboot/build-ipk
Executable file
74
custom/RM551E-GL/R01/ipk-source/sdxpinn-firstboot/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
31
custom/RM551E-GL/R01/ipk-source/sdxpinn-firstboot/root/etc/init.d/first-boot
Executable file
31
custom/RM551E-GL/R01/ipk-source/sdxpinn-firstboot/root/etc/init.d/first-boot
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
START=99
|
||||
STOP=15
|
||||
USE_PROCD=1
|
||||
start_service() {
|
||||
# Create log file
|
||||
touch /usrdata/first-boot.log
|
||||
|
||||
# Redirect all output to log file
|
||||
exec >>/usrdata/first-boot.log 2>&1
|
||||
|
||||
echo "Starting first boot script: $(date)"
|
||||
|
||||
echo "Remounting the real rootfs as rw"
|
||||
mount -o remount,rw /real_rootfs
|
||||
|
||||
echo "Sending AT Commands"
|
||||
atcmd 'AT+QCFG="usbnet",1'
|
||||
atcmd 'AT+QCFG="pcie/mode",1'
|
||||
|
||||
echo "Disabling first-boot service"
|
||||
service first-boot disable
|
||||
|
||||
echo "Restarting modem"
|
||||
atcmd 'AT+CFUN=1,1'
|
||||
|
||||
echo "Removing first-boot service"
|
||||
rm /real_rootfs/etc/init.d/first-boot
|
||||
|
||||
echo "First boot script completed: $(date)"
|
||||
}
|
||||
6
custom/RM551E-GL/R01/ipk-source/sdxpinn-patch/CONTROL/control
Executable file
6
custom/RM551E-GL/R01/ipk-source/sdxpinn-patch/CONTROL/control
Executable file
@@ -0,0 +1,6 @@
|
||||
Package: sdxpinn-patch
|
||||
Version: 2.5
|
||||
Architecture: all
|
||||
Maintainer: Cameron Thompson iamromulan@github.com
|
||||
Source: github.com/iamromulan
|
||||
Description: A general first system patch for SDXPINN OpenWRT
|
||||
5
custom/RM551E-GL/R01/ipk-source/sdxpinn-patch/CONTROL/postinst
Executable file
5
custom/RM551E-GL/R01/ipk-source/sdxpinn-patch/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/ash
|
||||
|
||||
echo "Complete"
|
||||
|
||||
exit 0
|
||||
211
custom/RM551E-GL/R01/ipk-source/sdxpinn-patch/CONTROL/preinst
Executable file
211
custom/RM551E-GL/R01/ipk-source/sdxpinn-patch/CONTROL/preinst
Executable file
@@ -0,0 +1,211 @@
|
||||
#!/bin/ash
|
||||
|
||||
clean_distfeeds() {
|
||||
# Define the list of items to comment out
|
||||
items_to_comment=$(cat <<EOF
|
||||
src/gz openwrt_core https://downloads.openwrt.org/releases/22.03.5/targets/sdx75/generic/packages
|
||||
src/gz openwrt_qtiagm https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtiagm
|
||||
src/gz openwrt_qtiargs https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtiargs
|
||||
src/gz openwrt_qtiaudio https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtiaudio
|
||||
src/gz openwrt_qtiaudioprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtiaudioprop
|
||||
src/gz openwrt_qtibsp https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtibsp
|
||||
src/gz openwrt_qtibspprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtibspprop
|
||||
src/gz openwrt_qtibt https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtibt
|
||||
src/gz openwrt_qtibtprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtibtprop
|
||||
src/gz openwrt_qticore https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qticore
|
||||
src/gz openwrt_qticoreinternal https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qticoreinternal
|
||||
src/gz openwrt_qticoreprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qticoreprop
|
||||
src/gz openwrt_qtictainternal https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtictainternal
|
||||
src/gz openwrt_qtidata https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtidata
|
||||
src/gz openwrt_qtidatainternal https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtidatainternal
|
||||
src/gz openwrt_qtidataprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtidataprop
|
||||
src/gz openwrt_qtiipq https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtiipq
|
||||
src/gz openwrt_qtiipqezmesh https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtiipqezmesh
|
||||
src/gz openwrt_qtiipqprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtiipqprop
|
||||
src/gz openwrt_qtilocation https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtilocation
|
||||
src/gz openwrt_qtilocationinternal https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtilocationinternal
|
||||
src/gz openwrt_qtilocationprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtilocationprop
|
||||
src/gz openwrt_qtimsdcprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtimsdcprop
|
||||
src/gz openwrt_qtinternal https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtinternal
|
||||
src/gz openwrt_qtipal https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtipal
|
||||
src/gz openwrt_qtiperfprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtiperfprop
|
||||
src/gz openwrt_qtippatprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtippatprop
|
||||
src/gz openwrt_qtiquectel https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtiquectel
|
||||
src/gz openwrt_qtiquectelprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtiquectelprop
|
||||
src/gz openwrt_qtirilprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtirilprop
|
||||
src/gz openwrt_qtisecurity https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtisecurity
|
||||
src/gz openwrt_qtisecurityinternal https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtisecurityinternal
|
||||
src/gz openwrt_qtisecurityprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtisecurityprop
|
||||
src/gz openwrt_qtisensorsinternal https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtisensorsinternal
|
||||
src/gz openwrt_qtisensorsprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtisensorsprop
|
||||
src/gz openwrt_qtissdk https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtissdk
|
||||
src/gz openwrt_qtissmgr https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtissmgr
|
||||
src/gz openwrt_qtissmgrprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtissmgrprop
|
||||
src/gz openwrt_qtiwlan https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtiwlan
|
||||
src/gz openwrt_qtiwlanprop https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/qtiwlanprop
|
||||
EOF
|
||||
)
|
||||
|
||||
# Define the list of items to ensure are uncommented
|
||||
items_to_keep=$(cat <<EOF
|
||||
src/gz openwrt_base https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/base
|
||||
src/gz openwrt_luci https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/luci
|
||||
src/gz openwrt_packages https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/packages
|
||||
src/gz openwrt_routing https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/routing
|
||||
src/gz openwrt_telephony https://downloads.openwrt.org/releases/22.03.5/packages/aarch64_cortex-a53/telephony/
|
||||
EOF
|
||||
)
|
||||
|
||||
# Input file to process
|
||||
INPUT_FILE="/etc/opkg/distfeeds.conf"
|
||||
# Backup the original file
|
||||
cp "$INPUT_FILE" "${INPUT_FILE}.bak"
|
||||
|
||||
# Create a temporary file for the modified content
|
||||
TEMP_FILE="${INPUT_FILE}.tmp"
|
||||
: > "$TEMP_FILE" # Clear/create the temp file
|
||||
|
||||
# Process each line in the input file
|
||||
while IFS= read -r line || [ -n "$line" ]; do
|
||||
# Skip empty lines
|
||||
[ -z "$line" ] && continue
|
||||
|
||||
# Skip malformed lines
|
||||
echo "$line" | grep -qE '^(#[[:space:]]*)?src/gz ' || continue
|
||||
|
||||
# Remove any existing comment marks for comparison
|
||||
clean_line=$(echo "$line" | sed 's/^#[[:space:]]*//')
|
||||
|
||||
# Check if line should be commented
|
||||
if echo "$items_to_comment" | grep -Fxq "$clean_line"; then
|
||||
echo "# $clean_line" >> "$TEMP_FILE"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if line should be kept uncommented
|
||||
if echo "$items_to_keep" | grep -Fxq "$clean_line"; then
|
||||
echo "$clean_line" >> "$TEMP_FILE"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Preserve other lines as-is
|
||||
echo "$line" >> "$TEMP_FILE"
|
||||
done < "$INPUT_FILE"
|
||||
|
||||
# Add any missing items_to_keep entries
|
||||
echo "$items_to_keep" | while IFS= read -r keep_item; do
|
||||
[ -z "$keep_item" ] && continue
|
||||
if ! grep -Fxq "$keep_item" "$TEMP_FILE"; then
|
||||
echo "$keep_item" >> "$TEMP_FILE"
|
||||
fi
|
||||
done
|
||||
|
||||
# Replace the original file with the modified one
|
||||
mv "$TEMP_FILE" "$INPUT_FILE"
|
||||
|
||||
echo "Processed '$INPUT_FILE'. Backup saved as '${INPUT_FILE}.bak'."
|
||||
}
|
||||
|
||||
|
||||
repo_iamromulanSDXPINN_check() {
|
||||
# Define the repository and key details
|
||||
STABLE_REPO_LINE="src/gz iamromulan-SDXPINN-repo https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/SDXPINN/opkg-feed"
|
||||
DEV_REPO_LINE="src/gz iamromulan-SDXPINN-repo https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/development-SDXPINN/opkg-feed"
|
||||
FEEDS_FILE="/etc/opkg/customfeeds.conf"
|
||||
PUBLIC_KEY_URL="https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/SDXPINN/opkg-feed/iamromulan-SDXPINN-repo.key"
|
||||
TMP_KEY="/tmp/iamromulan-SDXPINN-repo.key"
|
||||
KEYS_DIR="/etc/opkg/keys"
|
||||
|
||||
# Remove duplicate and development repo lines
|
||||
if grep -q "iamromulan-SDXPINN-repo" "$FEEDS_FILE"; then
|
||||
echo "Cleaning up duplicate or development repo entries in $FEEDS_FILE."
|
||||
sed -i "/iamromulan-SDXPINN-repo/d" "$FEEDS_FILE"
|
||||
fi
|
||||
|
||||
# Add the stable repository to customfeeds.conf
|
||||
echo "Adding stable repository to $FEEDS_FILE."
|
||||
echo "$STABLE_REPO_LINE" >> "$FEEDS_FILE" || {
|
||||
echo "Error: Could not add repository to $FEEDS_FILE."
|
||||
return 1
|
||||
}
|
||||
|
||||
# Download the key temporarily for verification
|
||||
curl -fsSL "$PUBLIC_KEY_URL" -o "$TMP_KEY" || {
|
||||
echo "Error: Failed to download public key from $PUBLIC_KEY_URL."
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if the key already exists in /etc/opkg/keys/
|
||||
local key_installed=0
|
||||
for key in "$KEYS_DIR"/*; do
|
||||
if cmp -s "$TMP_KEY" "$key"; then
|
||||
echo "Public key already installed: $(basename "$key")."
|
||||
key_installed=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# If the key is not installed, add it
|
||||
if [ "$key_installed" -eq 0 ]; then
|
||||
echo "Installing public key..."
|
||||
opkg-key add "$TMP_KEY" || {
|
||||
echo "Error: Failed to add public key."
|
||||
rm -f "$TMP_KEY"
|
||||
return 1
|
||||
}
|
||||
echo "Public key installed successfully."
|
||||
fi
|
||||
|
||||
# Clean up temporary key file
|
||||
rm -f "$TMP_KEY"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
noprerm_mount_fix() {
|
||||
|
||||
if [ -f /real_rootfs/usr/lib/opkg/info/sdxpinn-mount-fix.prerm ]; then
|
||||
mount -o remount,rw /real_rootfs
|
||||
sleep 1
|
||||
rm /real_rootfs/usr/lib/opkg/info/sdxpinn-mount-fix.prerm
|
||||
sleep 1
|
||||
mount -o remount,ro /real_rootfs
|
||||
fi
|
||||
|
||||
if [ -f /usr/lib/opkg/info/sdxpinn-mount-fix.prerm ]; then
|
||||
rm /usr/lib/opkg/info/sdxpinn-mount-fix.prerm
|
||||
fi
|
||||
}
|
||||
|
||||
opkg_arch_patch() {
|
||||
if [ ! -f /etc/opkg/arch.conf ]; then
|
||||
cat > /etc/opkg/arch.conf << 'EOF'
|
||||
arch all 1
|
||||
arch noarch 1
|
||||
arch sdxpinn 2
|
||||
arch aarch64_cortex-a53 10
|
||||
arch aarch64_generic 20
|
||||
EOF
|
||||
else
|
||||
for arch in "all 1" "noarch 1" "sdxpinn 2" "aarch64_cortex-a53 10" "aarch64_generic 20"; do
|
||||
if ! grep -q "^arch $arch$" /etc/opkg/arch.conf; then
|
||||
echo "arch $arch" >> /etc/opkg/arch.conf
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Begin Patch Process
|
||||
echo -e "\e[92mBegining sdxpinn-patch process...\e[0m"
|
||||
echo -e "\e[92mEnsuring distfeeds is clean of any non-working sources and has stock OpenWRT ones...\e[0m"
|
||||
clean_distfeeds
|
||||
echo -e "\e[92mEnsuring iamromulan's SDXPINN repo is listed in customfeeds and public key is installed...\e[0m"
|
||||
repo_iamromulanSDXPINN_check
|
||||
echo -e "\e[92miamromulan's SDXPINN repo source and key is installed.\e[0m"
|
||||
echo -e "\e[92mEnsuring mount-fix does not have a prerm\e[0m"
|
||||
noprerm_mount_fix
|
||||
echo -e "\e[92mEnsuring opkg reconizes needed archs\e[0m"
|
||||
opkg_arch_patch
|
||||
echo -e "\e[92msdxpinn-patch process complete.\e[0m"
|
||||
exit 0
|
||||
5
custom/RM551E-GL/R01/ipk-source/sdxpinn-patch/CONTROL/prerm
Executable file
5
custom/RM551E-GL/R01/ipk-source/sdxpinn-patch/CONTROL/prerm
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/ash
|
||||
|
||||
echo -e "\e[38;5;196mINFO: This package can not be removed by opkg\e[0m"
|
||||
echo -e "\e[38;5;40mINFO: This package can be upgraded...\e[0m"
|
||||
exit 0
|
||||
74
custom/RM551E-GL/R01/ipk-source/sdxpinn-patch/build-ipk
Executable file
74
custom/RM551E-GL/R01/ipk-source/sdxpinn-patch/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
2
|
||||
BIN
custom/RM551E-GL/R01/ipk/sdxpinn-firstboot_1.0_sdxpinn.ipk
Normal file
BIN
custom/RM551E-GL/R01/ipk/sdxpinn-firstboot_1.0_sdxpinn.ipk
Normal file
Binary file not shown.
BIN
custom/RM551E-GL/R01/ipk/sdxpinn-patch_2.5_all.ipk
Normal file
BIN
custom/RM551E-GL/R01/ipk/sdxpinn-patch_2.5_all.ipk
Normal file
Binary file not shown.
6
custom/RM551E-GL/R02/ipk-source/sdxpinn-firstboot/CONTROL/control
Executable file
6
custom/RM551E-GL/R02/ipk-source/sdxpinn-firstboot/CONTROL/control
Executable file
@@ -0,0 +1,6 @@
|
||||
Package: sdxpinn-firstboot
|
||||
Version: 1.0
|
||||
Architecture: sdxpinn
|
||||
Maintainer: Cameron Thompson iamromulan@github.com
|
||||
Source: github.com/iamromulan
|
||||
Description: A first boot init after a flash or factory reset
|
||||
5
custom/RM551E-GL/R02/ipk-source/sdxpinn-firstboot/CONTROL/postinst
Executable file
5
custom/RM551E-GL/R02/ipk-source/sdxpinn-firstboot/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/ash
|
||||
|
||||
service first-boot enable
|
||||
|
||||
exit 0
|
||||
74
custom/RM551E-GL/R02/ipk-source/sdxpinn-firstboot/build-ipk
Executable file
74
custom/RM551E-GL/R02/ipk-source/sdxpinn-firstboot/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
31
custom/RM551E-GL/R02/ipk-source/sdxpinn-firstboot/root/etc/init.d/first-boot
Executable file
31
custom/RM551E-GL/R02/ipk-source/sdxpinn-firstboot/root/etc/init.d/first-boot
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
START=99
|
||||
STOP=15
|
||||
USE_PROCD=1
|
||||
start_service() {
|
||||
# Create log file
|
||||
touch /usrdata/first-boot.log
|
||||
|
||||
# Redirect all output to log file
|
||||
exec >>/usrdata/first-boot.log 2>&1
|
||||
|
||||
echo "Starting first boot script: $(date)"
|
||||
|
||||
echo "Remounting the real rootfs as rw"
|
||||
mount -o remount,rw /real_rootfs
|
||||
|
||||
echo "Sending AT Commands"
|
||||
atcmd 'AT+QCFG="usbnet",1'
|
||||
atcmd 'AT+QCFG="pcie/mode",1'
|
||||
|
||||
echo "Disabling first-boot service"
|
||||
service first-boot disable
|
||||
|
||||
echo "Restarting modem"
|
||||
atcmd 'AT+CFUN=1,1'
|
||||
|
||||
echo "Removing first-boot service"
|
||||
rm /real_rootfs/etc/init.d/first-boot
|
||||
|
||||
echo "First boot script completed: $(date)"
|
||||
}
|
||||
6
custom/RM551E-GL/R02/ipk-source/sdxpinn-patch/CONTROL/control
Executable file
6
custom/RM551E-GL/R02/ipk-source/sdxpinn-patch/CONTROL/control
Executable file
@@ -0,0 +1,6 @@
|
||||
Package: sdxpinn-patch
|
||||
Version: 2.5
|
||||
Architecture: all
|
||||
Maintainer: Cameron Thompson iamromulan@github.com
|
||||
Source: github.com/iamromulan
|
||||
Description: A general first system patch for SDXPINN OpenWRT
|
||||
5
custom/RM551E-GL/R02/ipk-source/sdxpinn-patch/CONTROL/postinst
Executable file
5
custom/RM551E-GL/R02/ipk-source/sdxpinn-patch/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/ash
|
||||
|
||||
echo "Complete"
|
||||
|
||||
exit 0
|
||||
213
custom/RM551E-GL/R02/ipk-source/sdxpinn-patch/CONTROL/preinst
Executable file
213
custom/RM551E-GL/R02/ipk-source/sdxpinn-patch/CONTROL/preinst
Executable file
@@ -0,0 +1,213 @@
|
||||
#!/bin/ash
|
||||
|
||||
clean_distfeeds() {
|
||||
# Define the list of items to comment out
|
||||
items_to_comment=$(cat <<EOF
|
||||
src/gz openwrt_core https://downloads.openwrt.org/releases/23.05.4/targets/sdx75/generic/packages
|
||||
src/gz openwrt_qtiagm https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtiagm
|
||||
src/gz openwrt_qtiargs https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtiargs
|
||||
src/gz openwrt_qtiaudio https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtiaudio
|
||||
src/gz openwrt_qtiaudioprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtiaudioprop
|
||||
src/gz openwrt_qtibsp https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtibsp
|
||||
src/gz openwrt_qtibspprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtibspprop
|
||||
src/gz openwrt_qtibt https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtibt
|
||||
src/gz openwrt_qtibtprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtibtprop
|
||||
src/gz openwrt_qticore https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qticore
|
||||
src/gz openwrt_qticoreinternal https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qticoreinternal
|
||||
src/gz openwrt_qticoreprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qticoreprop
|
||||
src/gz openwrt_qtictainternal https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtictainternal
|
||||
src/gz openwrt_qtidata https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtidata
|
||||
src/gz openwrt_qtidatainternal https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtidatainternal
|
||||
src/gz openwrt_qtidataprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtidataprop
|
||||
src/gz openwrt_qtiemergencyalertprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtiemergencyalertprop
|
||||
src/gz openwrt_qtigplv2 https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtigplv2
|
||||
src/gz openwrt_qtiipq https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtiipq
|
||||
src/gz openwrt_qtiipqezmesh https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtiipqezmesh
|
||||
src/gz openwrt_qtiipqprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtiipqprop
|
||||
src/gz openwrt_qtilocation https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtilocation
|
||||
src/gz openwrt_qtilocationinternal https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtilocationinternal
|
||||
src/gz openwrt_qtilocationprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtilocationprop
|
||||
src/gz openwrt_qtimsdcprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtimsdcprop
|
||||
src/gz openwrt_qtinternal https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtinternal
|
||||
src/gz openwrt_qtipal https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtipal
|
||||
src/gz openwrt_qtiperfprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtiperfprop
|
||||
src/gz openwrt_qtippatprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtippatprop
|
||||
src/gz openwrt_qtiquectel https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtiquectel
|
||||
src/gz openwrt_qtiquectelprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtiquectelprop
|
||||
src/gz openwrt_qtirilprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtirilprop
|
||||
src/gz openwrt_qtisecurity https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtisecurity
|
||||
src/gz openwrt_qtisecurityinternal https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtisecurityinternal
|
||||
src/gz openwrt_qtisecurityprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtisecurityprop
|
||||
src/gz openwrt_qtisensorsinternal https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtisensorsinternal
|
||||
src/gz openwrt_qtisensorsprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtisensorsprop
|
||||
src/gz openwrt_qtissdk https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtissdk
|
||||
src/gz openwrt_qtissmgr https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtissmgr
|
||||
src/gz openwrt_qtissmgrprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtissmgrprop
|
||||
src/gz openwrt_qtiwlan https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtiwlan
|
||||
src/gz openwrt_qtiwlanprop https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/qtiwlanprop
|
||||
EOF
|
||||
)
|
||||
|
||||
# Define the list of items to ensure are uncommented
|
||||
items_to_keep=$(cat <<EOF
|
||||
src/gz openwrt_base https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/base
|
||||
src/gz openwrt_luci https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/luci
|
||||
src/gz openwrt_packages https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/packages
|
||||
src/gz openwrt_routing https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/routing
|
||||
src/gz openwrt_routing https://downloads.openwrt.org/releases/23.05.4/packages/aarch64_cortex-a53/telephony
|
||||
EOF
|
||||
)
|
||||
|
||||
# Input file to process
|
||||
INPUT_FILE="/etc/opkg/distfeeds.conf"
|
||||
# Backup the original file
|
||||
cp "$INPUT_FILE" "${INPUT_FILE}.bak"
|
||||
|
||||
# Create a temporary file for the modified content
|
||||
TEMP_FILE="${INPUT_FILE}.tmp"
|
||||
: > "$TEMP_FILE" # Clear/create the temp file
|
||||
|
||||
# Process each line in the input file
|
||||
while IFS= read -r line || [ -n "$line" ]; do
|
||||
# Skip empty lines
|
||||
[ -z "$line" ] && continue
|
||||
|
||||
# Skip malformed lines
|
||||
echo "$line" | grep -qE '^(#[[:space:]]*)?src/gz ' || continue
|
||||
|
||||
# Remove any existing comment marks for comparison
|
||||
clean_line=$(echo "$line" | sed 's/^#[[:space:]]*//')
|
||||
|
||||
# Check if line should be commented
|
||||
if echo "$items_to_comment" | grep -Fxq "$clean_line"; then
|
||||
echo "# $clean_line" >> "$TEMP_FILE"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if line should be kept uncommented
|
||||
if echo "$items_to_keep" | grep -Fxq "$clean_line"; then
|
||||
echo "$clean_line" >> "$TEMP_FILE"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Preserve other lines as-is
|
||||
echo "$line" >> "$TEMP_FILE"
|
||||
done < "$INPUT_FILE"
|
||||
|
||||
# Add any missing items_to_keep entries
|
||||
echo "$items_to_keep" | while IFS= read -r keep_item; do
|
||||
[ -z "$keep_item" ] && continue
|
||||
if ! grep -Fxq "$keep_item" "$TEMP_FILE"; then
|
||||
echo "$keep_item" >> "$TEMP_FILE"
|
||||
fi
|
||||
done
|
||||
|
||||
# Replace the original file with the modified one
|
||||
mv "$TEMP_FILE" "$INPUT_FILE"
|
||||
|
||||
echo "Processed '$INPUT_FILE'. Backup saved as '${INPUT_FILE}.bak'."
|
||||
}
|
||||
|
||||
|
||||
repo_iamromulanSDXPINN_check() {
|
||||
# Define the repository and key details
|
||||
STABLE_REPO_LINE="src/gz iamromulan-SDXPINN-repo https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/SDXPINN/opkg-feed"
|
||||
DEV_REPO_LINE="src/gz iamromulan-SDXPINN-repo https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/development-SDXPINN/opkg-feed"
|
||||
FEEDS_FILE="/etc/opkg/customfeeds.conf"
|
||||
PUBLIC_KEY_URL="https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/SDXPINN/opkg-feed/iamromulan-SDXPINN-repo.key"
|
||||
TMP_KEY="/tmp/iamromulan-SDXPINN-repo.key"
|
||||
KEYS_DIR="/etc/opkg/keys"
|
||||
|
||||
# Remove duplicate and development repo lines
|
||||
if grep -q "iamromulan-SDXPINN-repo" "$FEEDS_FILE"; then
|
||||
echo "Cleaning up duplicate or development repo entries in $FEEDS_FILE."
|
||||
sed -i "/iamromulan-SDXPINN-repo/d" "$FEEDS_FILE"
|
||||
fi
|
||||
|
||||
# Add the stable repository to customfeeds.conf
|
||||
echo "Adding stable repository to $FEEDS_FILE."
|
||||
echo "$STABLE_REPO_LINE" >> "$FEEDS_FILE" || {
|
||||
echo "Error: Could not add repository to $FEEDS_FILE."
|
||||
return 1
|
||||
}
|
||||
|
||||
# Download the key temporarily for verification
|
||||
curl -fsSL "$PUBLIC_KEY_URL" -o "$TMP_KEY" || {
|
||||
echo "Error: Failed to download public key from $PUBLIC_KEY_URL."
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if the key already exists in /etc/opkg/keys/
|
||||
local key_installed=0
|
||||
for key in "$KEYS_DIR"/*; do
|
||||
if cmp -s "$TMP_KEY" "$key"; then
|
||||
echo "Public key already installed: $(basename "$key")."
|
||||
key_installed=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# If the key is not installed, add it
|
||||
if [ "$key_installed" -eq 0 ]; then
|
||||
echo "Installing public key..."
|
||||
opkg-key add "$TMP_KEY" || {
|
||||
echo "Error: Failed to add public key."
|
||||
rm -f "$TMP_KEY"
|
||||
return 1
|
||||
}
|
||||
echo "Public key installed successfully."
|
||||
fi
|
||||
|
||||
# Clean up temporary key file
|
||||
rm -f "$TMP_KEY"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
noprerm_mount_fix() {
|
||||
|
||||
if [ -f /real_rootfs/usr/lib/opkg/info/sdxpinn-mount-fix.prerm ]; then
|
||||
mount -o remount,rw /real_rootfs
|
||||
sleep 1
|
||||
rm /real_rootfs/usr/lib/opkg/info/sdxpinn-mount-fix.prerm
|
||||
sleep 1
|
||||
mount -o remount,ro /real_rootfs
|
||||
fi
|
||||
|
||||
if [ -f /usr/lib/opkg/info/sdxpinn-mount-fix.prerm ]; then
|
||||
rm /usr/lib/opkg/info/sdxpinn-mount-fix.prerm
|
||||
fi
|
||||
}
|
||||
|
||||
opkg_arch_patch() {
|
||||
if [ ! -f /etc/opkg/arch.conf ]; then
|
||||
cat > /etc/opkg/arch.conf << 'EOF'
|
||||
arch all 1
|
||||
arch noarch 1
|
||||
arch sdxpinn 2
|
||||
arch aarch64_cortex-a53 10
|
||||
arch aarch64_generic 20
|
||||
EOF
|
||||
else
|
||||
for arch in "all 1" "noarch 1" "sdxpinn 2" "aarch64_cortex-a53 10" "aarch64_generic 20"; do
|
||||
if ! grep -q "^arch $arch$" /etc/opkg/arch.conf; then
|
||||
echo "arch $arch" >> /etc/opkg/arch.conf
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Begin Patch Process
|
||||
echo -e "\e[92mBegining sdxpinn-patch process...\e[0m"
|
||||
echo -e "\e[92mEnsuring distfeeds is clean of any non-working sources and has stock OpenWRT ones...\e[0m"
|
||||
clean_distfeeds
|
||||
echo -e "\e[92mEnsuring iamromulan's SDXPINN repo is listed in customfeeds and public key is installed...\e[0m"
|
||||
repo_iamromulanSDXPINN_check
|
||||
echo -e "\e[92miamromulan's SDXPINN repo source and key is installed.\e[0m"
|
||||
echo -e "\e[92mEnsuring mount-fix does not have a prerm\e[0m"
|
||||
noprerm_mount_fix
|
||||
echo -e "\e[92mEnsuring opkg reconizes needed archs\e[0m"
|
||||
opkg_arch_patch
|
||||
echo -e "\e[92msdxpinn-patch process complete.\e[0m"
|
||||
exit 0
|
||||
5
custom/RM551E-GL/R02/ipk-source/sdxpinn-patch/CONTROL/prerm
Executable file
5
custom/RM551E-GL/R02/ipk-source/sdxpinn-patch/CONTROL/prerm
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/ash
|
||||
|
||||
echo -e "\e[38;5;196mINFO: This package can not be removed by opkg\e[0m"
|
||||
echo -e "\e[38;5;40mINFO: This package can be upgraded...\e[0m"
|
||||
exit 0
|
||||
74
custom/RM551E-GL/R02/ipk-source/sdxpinn-patch/build-ipk
Executable file
74
custom/RM551E-GL/R02/ipk-source/sdxpinn-patch/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
2
|
||||
BIN
custom/RM551E-GL/R02/ipk/sdxpinn-firstboot_1.0_sdxpinn.ipk
Normal file
BIN
custom/RM551E-GL/R02/ipk/sdxpinn-firstboot_1.0_sdxpinn.ipk
Normal file
Binary file not shown.
10
custom/RM551E-GL/README.md
Normal file
10
custom/RM551E-GL/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# For preping a firmware before capture of the mtd block
|
||||
|
||||
This directory is for custom firmware development. It contains special versions of ipks intended to be installed as apart of a custom firmware.
|
||||
|
||||
This is mostly here to help me simplify the firmware creation process
|
||||
|
||||
R01 is for R01 firmware on OpenWRT 22.03.5
|
||||
R02 is for R02 firmware on OpenWRT 23.05.4
|
||||
|
||||
~iamromulan
|
||||
@@ -1,167 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Modified by iamromulan to set up a proper entware environment for Quectel RM5xx series m.2 modems
|
||||
TYPE='generic'
|
||||
#|---------|-----------------|
|
||||
#| TARGET | Quectel Modem |
|
||||
#| ARCH | armv7sf-k3.2 |
|
||||
#| LOADER | ld-linux.so.3 |
|
||||
#| GLIBC | 2.27 |
|
||||
#|---------|-----------------|
|
||||
unset LD_LIBRARY_PATH
|
||||
unset LD_PRELOAD
|
||||
ARCH=armv7sf-k3.2
|
||||
LOADER=ld-linux.so.3
|
||||
GLIBC=2.27
|
||||
PRE_OPKG_PATH=$(which opkg)
|
||||
|
||||
# Remount filesystem as read-write
|
||||
mount -o remount,rw /
|
||||
|
||||
create_opt_mount() {
|
||||
# Bind /usrdata/opt to /opt
|
||||
echo -e '\033[32mInfo: Setting up /opt mount to /usrdata/opt...\033[0m'
|
||||
cat <<EOF > /lib/systemd/system/opt.mount
|
||||
[Unit]
|
||||
Description=Bind /usrdata/opt to /opt
|
||||
|
||||
[Mount]
|
||||
What=/usrdata/opt
|
||||
Where=/opt
|
||||
Type=none
|
||||
Options=bind
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl start opt.mount
|
||||
|
||||
# Additional systemd service to ensure opt.mount starts at boot
|
||||
echo -e '\033[32mInfo: Creating service to start opt.mount at boot...\033[0m'
|
||||
cat <<EOF > /lib/systemd/system/start-opt-mount.service
|
||||
[Unit]
|
||||
Description=Ensure opt.mount is started at boot
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/systemctl start opt.mount
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
ln -s /lib/systemd/system/start-opt-mount.service /lib/systemd/system/multi-user.target.wants/start-opt-mount.service
|
||||
}
|
||||
|
||||
if [ -n "$PRE_OPKG_PATH" ]; then
|
||||
# Automatically rename the existing opkg binary
|
||||
mv "$PRE_OPKG_PATH" "${PRE_OPKG_PATH}_old"
|
||||
echo -e "\033[32mFactory/Already existing opkg has been renamed to opkg_old.\033[0m"
|
||||
else
|
||||
echo "Info: no existing opkg binary detected, proceeding with installation"
|
||||
fi
|
||||
|
||||
echo -e '\033[32mInfo: Creating /opt mount pointed to /usrdata/opt ...\033[0m'
|
||||
create_opt_mount
|
||||
echo -e '\033[32mInfo: Proceeding with main installation ...\033[0m'
|
||||
# no need to create many folders. entware-opt package creates most
|
||||
for folder in bin etc lib/opkg tmp var/lock
|
||||
do
|
||||
if [ -d "/opt/$folder" ]; then
|
||||
echo -e '\033[31mWarning: Folder /opt/$folder exists!\033[0m'
|
||||
echo -e '\033[31mWarning: If something goes wrong please clean /opt folder and try again.\033[0m'
|
||||
else
|
||||
mkdir -p /opt/$folder
|
||||
fi
|
||||
done
|
||||
|
||||
echo -e '\033[32mInfo: Opkg package manager deployment...\033[0m'
|
||||
URL=http://bin.entware.net/${ARCH}/installer
|
||||
wget $URL/opkg -O /opt/bin/opkg
|
||||
chmod 755 /opt/bin/opkg
|
||||
wget $URL/opkg.conf -O /opt/etc/opkg.conf
|
||||
|
||||
echo -e '\033[32mInfo: Basic packages installation...\033[0m'
|
||||
/opt/bin/opkg update
|
||||
/opt/bin/opkg install entware-opt
|
||||
|
||||
# Fix for multiuser environment
|
||||
chmod 777 /opt/tmp
|
||||
|
||||
for file in passwd group shells shadow gshadow; do
|
||||
if [ $TYPE = 'generic' ]; then
|
||||
if [ -f /etc/$file ]; then
|
||||
ln -sf /etc/$file /opt/etc/$file
|
||||
else
|
||||
[ -f /opt/etc/$file.1 ] && cp /opt/etc/$file.1 /opt/etc/$file
|
||||
fi
|
||||
else
|
||||
if [ -f /opt/etc/$file.1 ]; then
|
||||
cp /opt/etc/$file.1 /opt/etc/$file
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
[ -f /etc/localtime ] && ln -sf /etc/localtime /opt/etc/localtime
|
||||
|
||||
# Create and enable rc.unslung service
|
||||
echo -e '\033[32mInfo: Creating rc.unslung (Entware init.d service)...\033[0m'
|
||||
cat <<EOF > /lib/systemd/system/rc.unslung.service
|
||||
[Unit]
|
||||
Description=Start Entware services
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
# Add a delay to give /opt time to mount
|
||||
ExecStartPre=/bin/sleep 5
|
||||
ExecStart=/opt/etc/init.d/rc.unslung start
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
ln -s /lib/systemd/system/rc.unslung.service /lib/systemd/system/multi-user.target.wants/rc.unslung.service
|
||||
systemctl start rc.unslung.service
|
||||
echo -e '\033[32mInfo: Congratulations!\033[0m'
|
||||
echo -e '\033[32mInfo: If there are no errors above then Entware was successfully initialized.\033[0m'
|
||||
echo -e '\033[32mInfo: Add /opt/bin & /opt/sbin to $PATH variable\033[0m'
|
||||
ln -sf /opt/bin/opkg /bin
|
||||
echo -e '\033[32mInfo: Patching Quectel Login Binary\033[0m'
|
||||
opkg update && opkg install shadow-login shadow-passwd shadow-useradd
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mPackage installation failed. Please check your internet connection and try again.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Replace the login and passwd binaries and set home for root to a writable directory
|
||||
rm /opt/etc/shadow
|
||||
rm /opt/etc/passwd
|
||||
cp /etc/shadow /opt/etc/
|
||||
cp /etc/passwd /opt/etc
|
||||
mkdir /usrdata/root
|
||||
mkdir /usrdata/root/bin
|
||||
touch /usrdata/root/.profile
|
||||
echo "# Set PATH for all shells" > /usrdata/root/.profile
|
||||
echo "export PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin" >> /usrdata/root/.profile
|
||||
chmod +x /usrdata/root/.profile
|
||||
sed -i '1s|/home/root:/bin/sh|/usrdata/root:/bin/bash|' /opt/etc/passwd
|
||||
rm /bin/login /usr/bin/passwd
|
||||
ln -sf /opt/bin/login /bin
|
||||
ln -sf /opt/bin/passwd /usr/bin/
|
||||
ln -sf /opt/bin/useradd /usr/bin/
|
||||
echo -e "\e[1;31mPlease set the root password.\e[0m"
|
||||
/usr/bin/passwd
|
||||
|
||||
# Install basic and useful utilites
|
||||
opkg install mc htop dfc lsof
|
||||
ln -sf /opt/bin/mc /bin
|
||||
ln -sf /opt/bin/htop /bin
|
||||
ln -sf /opt/bin/dfc /bin
|
||||
ln -sf /opt/bin/lsof /bin
|
||||
# Remount filesystem as read-only
|
||||
mount -o remount,ro /
|
||||
13
ipk-source/atinout_aarch64_cortex-a53/CONTROL/control
Executable file
13
ipk-source/atinout_aarch64_cortex-a53/CONTROL/control
Executable file
@@ -0,0 +1,13 @@
|
||||
Package: atinout
|
||||
Version: 0.9.1
|
||||
Depends: libc
|
||||
Source: feeds/kiddin9/atinout
|
||||
SourceName: atinout
|
||||
License: GPLv2
|
||||
LicenseFiles: LICENSE
|
||||
Section: net
|
||||
SourceDateEpoch: 1691250335
|
||||
Maintainer: Adrian Guenter <a@gntr.me>
|
||||
Architecture: aarch64_cortex-a53
|
||||
Installed-Size: 3571
|
||||
Description: Atinout is a program that will execute AT commands in sequence and capture the response from the modem.
|
||||
5
ipk-source/atinout_aarch64_cortex-a53/CONTROL/postinst
Executable file
5
ipk-source/atinout_aarch64_cortex-a53/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_postinst $0 $@
|
||||
4
ipk-source/atinout_aarch64_cortex-a53/CONTROL/prerm
Executable file
4
ipk-source/atinout_aarch64_cortex-a53/CONTROL/prerm
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_prerm $0 $@
|
||||
74
ipk-source/atinout_aarch64_cortex-a53/build-ipk
Executable file
74
ipk-source/atinout_aarch64_cortex-a53/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/etc/config/
|
||||
/etc/atinout/
|
||||
BIN
ipk-source/atinout_aarch64_cortex-a53/root/usr/bin/atinout
Executable file
BIN
ipk-source/atinout_aarch64_cortex-a53/root/usr/bin/atinout
Executable file
Binary file not shown.
7
ipk-source/kmod-wireguard/CONTROL/control
Executable file
7
ipk-source/kmod-wireguard/CONTROL/control
Executable file
@@ -0,0 +1,7 @@
|
||||
Package: kmod-wireguard
|
||||
Depends: sdxpinn-patch
|
||||
Version: 1
|
||||
Architecture: sdxpinn
|
||||
Maintainer: Cameron Thompson iamromulan@github.com
|
||||
Source: github.com/iamromulan
|
||||
Description: Wireguard is compiled into the kernel
|
||||
5
ipk-source/kmod-wireguard/CONTROL/postinst
Executable file
5
ipk-source/kmod-wireguard/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/ash
|
||||
|
||||
echo "kmod-wireguard registration Complete"
|
||||
|
||||
exit 0
|
||||
74
ipk-source/kmod-wireguard/build-ipk
Executable file
74
ipk-source/kmod-wireguard/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
1
ipk-source/kmod-wireguard/root/tmp/kmod-wireguard.reg
Normal file
1
ipk-source/kmod-wireguard/root/tmp/kmod-wireguard.reg
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,14 @@
|
||||
Package: libucode20230711
|
||||
Version: 2024.07.22~b610860d-r3
|
||||
Depends: libc, libjson-c5
|
||||
Provides: libucode
|
||||
Source: https://dl.openwrt.ai/packages-24.10/aarch64_cortex-a53/base/libucode20230711_2025.02.10~a8a11aea-r1_aarch64_cortex-a53.ipk
|
||||
SourceName: ucode
|
||||
License: ISC
|
||||
Section: libs
|
||||
SourceDateEpoch: 1729600843
|
||||
ABIVersion: 20230711
|
||||
Maintainer: Jo-Philipp Wich <jo@mein.io>
|
||||
Architecture: aarch64_cortex-a53
|
||||
Installed-Size: 204800
|
||||
Description: The libucode package provides the shared runtime library for the ucode interpreter.
|
||||
5
ipk-source/libucode20230711_aarch64_cortex-a53/CONTROL/postinst
Executable file
5
ipk-source/libucode20230711_aarch64_cortex-a53/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_postinst $0 $@
|
||||
4
ipk-source/libucode20230711_aarch64_cortex-a53/CONTROL/prerm
Executable file
4
ipk-source/libucode20230711_aarch64_cortex-a53/CONTROL/prerm
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_prerm $0 $@
|
||||
74
ipk-source/libucode20230711_aarch64_cortex-a53/build-ipk
Executable file
74
ipk-source/libucode20230711_aarch64_cortex-a53/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
Binary file not shown.
1
ipk-source/luci-app-argon-config/CONTROL/conffiles
Executable file
1
ipk-source/luci-app-argon-config/CONTROL/conffiles
Executable file
@@ -0,0 +1 @@
|
||||
/etc/config/argon
|
||||
12
ipk-source/luci-app-argon-config/CONTROL/control
Executable file
12
ipk-source/luci-app-argon-config/CONTROL/control
Executable file
@@ -0,0 +1,12 @@
|
||||
Package: luci-app-argon-config
|
||||
Version: 0.9-1
|
||||
Depends: libc, luci-compat, luci-lib-ipkg
|
||||
Recommends: luci-theme-argon
|
||||
Source: github.com/jerrykuku/luci-app-argon-config/releases/tag/v0.9
|
||||
SourceName: luci-app-argon-config
|
||||
Section: luci
|
||||
SourceDateEpoch: 1650782942
|
||||
Maintainer: github.com/jerrykuku
|
||||
Architecture: all
|
||||
Installed-Size: 3586
|
||||
Description: LuCI page for Argon Config
|
||||
5
ipk-source/luci-app-argon-config/CONTROL/postinst
Executable file
5
ipk-source/luci-app-argon-config/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_postinst $0 $@
|
||||
7
ipk-source/luci-app-argon-config/CONTROL/postinst-pkg
Executable file
7
ipk-source/luci-app-argon-config/CONTROL/postinst-pkg
Executable file
@@ -0,0 +1,7 @@
|
||||
[ -n "${IPKG_INSTROOT}" ] || {
|
||||
(. /etc/uci-defaults/luci-argon-config) && rm -f /etc/uci-defaults/luci-argon-config
|
||||
rm -f /tmp/luci-indexcache
|
||||
rm -rf /tmp/luci-modulecache/
|
||||
killall -HUP rpcd 2>/dev/null
|
||||
exit 0
|
||||
}
|
||||
4
ipk-source/luci-app-argon-config/CONTROL/prerm
Executable file
4
ipk-source/luci-app-argon-config/CONTROL/prerm
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_prerm $0 $@
|
||||
74
ipk-source/luci-app-argon-config/build-ipk
Executable file
74
ipk-source/luci-app-argon-config/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
9
ipk-source/luci-app-argon-config/root/etc/config/argon
Normal file
9
ipk-source/luci-app-argon-config/root/etc/config/argon
Normal file
@@ -0,0 +1,9 @@
|
||||
config global
|
||||
option primary '#5e72e4'
|
||||
option dark_primary '#483d8b'
|
||||
option blur '10'
|
||||
option blur_dark '10'
|
||||
option transparency '0.5'
|
||||
option transparency_dark '0.5'
|
||||
option mode 'normal'
|
||||
option bing_background '0'
|
||||
6
ipk-source/luci-app-argon-config/root/etc/uci-defaults/luci-argon-config
Executable file
6
ipk-source/luci-app-argon-config/root/etc/uci-defaults/luci-argon-config
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
sed -i 's/cbi.submit\"] = true/cbi.submit\"] = \"1\"/g' /usr/lib/lua/luci/dispatcher.lua
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
||||
@@ -0,0 +1,10 @@
|
||||
module("luci.controller.argon-config", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access('/www/luci-static/argon/css/cascade.css') then
|
||||
return
|
||||
end
|
||||
|
||||
local page = entry({"admin", "system", "argon-config"}, form("argon-config"), _("Argon Config"), 90)
|
||||
page.acl_depends = { "luci-app-argon-config" }
|
||||
end
|
||||
@@ -0,0 +1,217 @@
|
||||
local nxfs = require 'nixio.fs'
|
||||
local wa = require 'luci.tools.webadmin'
|
||||
local opkg = require 'luci.model.ipkg'
|
||||
local sys = require 'luci.sys'
|
||||
local http = require 'luci.http'
|
||||
local nutil = require 'nixio.util'
|
||||
local name = 'argon'
|
||||
local uci = require 'luci.model.uci'.cursor()
|
||||
|
||||
local fstat = nxfs.statvfs(opkg.overlay_root())
|
||||
local space_total = fstat and fstat.blocks or 0
|
||||
local space_free = fstat and fstat.bfree or 0
|
||||
local space_used = space_total - space_free
|
||||
|
||||
local free_byte = space_free * fstat.frsize
|
||||
|
||||
local primary, dark_primary, blur_radius, blur_radius_dark, blur_opacity, mode
|
||||
if nxfs.access('/etc/config/argon') then
|
||||
primary = uci:get_first('argon', 'global', 'primary')
|
||||
dark_primary = uci:get_first('argon', 'global', 'dark_primary')
|
||||
blur_radius = uci:get_first('argon', 'global', 'blur')
|
||||
blur_radius_dark = uci:get_first('argon', 'global', 'blur_dark')
|
||||
blur_opacity = uci:get_first('argon', 'global', 'transparency')
|
||||
blur_opacity_dark = uci:get_first('argon', 'global', 'transparency_dark')
|
||||
mode = uci:get_first('argon', 'global', 'mode')
|
||||
bing_background = uci:get_first('argon', 'global', 'bing_background')
|
||||
end
|
||||
|
||||
function glob(...)
|
||||
local iter, code, msg = nxfs.glob(...)
|
||||
if iter then
|
||||
return nutil.consume(iter)
|
||||
else
|
||||
return nil, code, msg
|
||||
end
|
||||
end
|
||||
|
||||
local transparency_sets = {
|
||||
0,
|
||||
0.1,
|
||||
0.2,
|
||||
0.3,
|
||||
0.4,
|
||||
0.5,
|
||||
0.6,
|
||||
0.7,
|
||||
0.8,
|
||||
0.9,
|
||||
1
|
||||
}
|
||||
|
||||
-- [[ 模糊设置 ]]--
|
||||
br = SimpleForm('config', translate('Argon Config'), translate('Here you can set the blur and transparency of the login page of argon theme, and manage the background pictures and videos.[Chrome is recommended]'))
|
||||
br.reset = false
|
||||
br.submit = false
|
||||
s = br:section(SimpleSection)
|
||||
|
||||
o = s:option(ListValue, 'bing_background', translate('Wallpaper Source'))
|
||||
o:value('0', translate('Built-in'))
|
||||
o:value('1', translate('Bing Wallpapers'))
|
||||
o.default = bing_background
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, 'mode', translate('Theme mode'))
|
||||
o:value('normal', translate('Follow System'))
|
||||
o:value('light', translate('Force Light'))
|
||||
o:value('dark', translate('Force Dark'))
|
||||
o.default = mode
|
||||
o.rmempty = false
|
||||
o.description = translate('You can choose Theme color mode here')
|
||||
|
||||
o = s:option(Value, 'primary', translate('[Light mode] Primary Color'), translate('A HEX Color ; ( Default: #5e72e4 )'))
|
||||
o.default = primary
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
|
||||
|
||||
o = s:option(ListValue, 'transparency', translate('[Light mode] Transparency'), translate('0 transparent - 1 opaque ; ( Suggest: transparent: 0 or translucent preset: 0.5 )'))
|
||||
for _, v in ipairs(transparency_sets) do
|
||||
o:value(v)
|
||||
end
|
||||
o.default = blur_opacity
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, 'blur', translate('[Light mode] Frosted Glass Radius'), translate('Larger value will more blurred ; ( Suggest: clear: 1 or blur preset: 10 )'))
|
||||
o.default = blur_radius
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, 'dark_primary', translate('[Dark mode] Primary Color'), translate('A HEX Color ; ( Default: #483d8b )'))
|
||||
o.default = dark_primary
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, 'transparency_dark', translate('[Dark mode] Transparency'), translate('0 transparent - 1 opaque ; ( Suggest: Black translucent preset: 0.5 )'))
|
||||
for _, v in ipairs(transparency_sets) do
|
||||
o:value(v)
|
||||
end
|
||||
o.default = blur_opacity_dark
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, 'blur_dark', translate('[Dark mode] Frosted Glass Radius'), translate('Larger value will more blurred ; ( Suggest: clear: 1 or blur preset: 10 )'))
|
||||
o.default = blur_radius_dark
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Button, 'save', translate('Save Changes'))
|
||||
o.inputstyle = 'reload'
|
||||
|
||||
function br.handle(self, state, data)
|
||||
if (state == FORM_VALID and data.blur ~= nil and data.blur_dark ~= nil and data.transparency ~= nil and data.transparency_dark ~= nil and data.mode ~= nil) then
|
||||
nxfs.writefile('/tmp/aaa', data)
|
||||
for key, value in pairs(data) do
|
||||
uci:set('argon','@global[0]',key,value)
|
||||
end
|
||||
uci:commit('argon')
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
ful = SimpleForm('upload', translate('Upload (Free: ') .. wa.byte_format(free_byte) .. ')', translate("You can upload files such as jpg,png,gif,mp4,webm files, To change the login page background."))
|
||||
ful.reset = false
|
||||
ful.submit = false
|
||||
|
||||
sul = ful:section(SimpleSection, '', translate("Upload file to '/www/luci-static/argon/background/'"))
|
||||
fu = sul:option(FileUpload, '')
|
||||
fu.template = 'argon-config/other_upload'
|
||||
um = sul:option(DummyValue, '', nil)
|
||||
um.template = 'argon-config/other_dvalue'
|
||||
|
||||
local dir, fd
|
||||
dir = '/www/luci-static/argon/background/'
|
||||
nxfs.mkdir(dir)
|
||||
http.setfilehandler(
|
||||
function(meta, chunk, eof)
|
||||
if not fd then
|
||||
if not meta then
|
||||
return
|
||||
end
|
||||
|
||||
if meta and chunk then
|
||||
fd = nixio.open(dir .. meta.file, 'w')
|
||||
end
|
||||
|
||||
if not fd then
|
||||
um.value = translate('Create upload file error.')
|
||||
return
|
||||
end
|
||||
end
|
||||
if chunk and fd then
|
||||
fd:write(chunk)
|
||||
end
|
||||
if eof and fd then
|
||||
fd:close()
|
||||
fd = nil
|
||||
um.value = translate('File saved to') .. ' "/www/luci-static/argon/background/' .. meta.file .. '"'
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
if http.formvalue('upload') then
|
||||
local f = http.formvalue('ulfile')
|
||||
if #f <= 0 then
|
||||
um.value = translate('No specify upload file.')
|
||||
end
|
||||
end
|
||||
|
||||
local function getSizeStr(size)
|
||||
local i = 0
|
||||
local byteUnits = {' kB', ' MB', ' GB', ' TB'}
|
||||
repeat
|
||||
size = size / 1024
|
||||
i = i + 1
|
||||
until (size <= 1024)
|
||||
return string.format('%.1f', size) .. byteUnits[i]
|
||||
end
|
||||
|
||||
local inits, attr = {}
|
||||
for i, f in ipairs(glob(dir .. '*')) do
|
||||
attr = nxfs.stat(f)
|
||||
if attr then
|
||||
inits[i] = {}
|
||||
inits[i].name = nxfs.basename(f)
|
||||
inits[i].mtime = os.date('%Y-%m-%d %H:%M:%S', attr.mtime)
|
||||
inits[i].modestr = attr.modestr
|
||||
inits[i].size = getSizeStr(attr.size)
|
||||
inits[i].remove = 0
|
||||
inits[i].install = false
|
||||
end
|
||||
end
|
||||
|
||||
form = SimpleForm('filelist', translate('Background file list'), nil)
|
||||
form.reset = false
|
||||
form.submit = false
|
||||
|
||||
tb = form:section(Table, inits)
|
||||
nm = tb:option(DummyValue, 'name', translate('File name'))
|
||||
mt = tb:option(DummyValue, 'mtime', translate('Modify time'))
|
||||
sz = tb:option(DummyValue, 'size', translate('Size'))
|
||||
btnrm = tb:option(Button, 'remove', translate('Remove'))
|
||||
btnrm.render = function(self, section, scope)
|
||||
self.inputstyle = 'remove'
|
||||
Button.render(self, section, scope)
|
||||
end
|
||||
|
||||
btnrm.write = function(self, section)
|
||||
local v = nxfs.unlink(dir .. nxfs.basename(inits[section].name))
|
||||
if v then
|
||||
table.remove(inits, section)
|
||||
end
|
||||
return v
|
||||
end
|
||||
|
||||
return br, ful, form
|
||||
@@ -0,0 +1,7 @@
|
||||
<%+cbi/valueheader%>
|
||||
<% if self:cfgvalue(section) ~= false then %>
|
||||
<input class="cbi-button cbi-input-<%=self.inputstyle or "button" %>" style="display: <%= display %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> />
|
||||
<% else %>
|
||||
-
|
||||
<% end %>
|
||||
<%+cbi/valuefooter%>
|
||||
@@ -0,0 +1,8 @@
|
||||
<%+cbi/valueheader%>
|
||||
<span style="color: red">
|
||||
<%
|
||||
local val = self:cfgvalue(section) or self.default or ""
|
||||
write(pcdata(val))
|
||||
%>
|
||||
</span>
|
||||
<%+cbi/valuefooter%>
|
||||
@@ -0,0 +1,5 @@
|
||||
<%+cbi/valueheader%>
|
||||
<label class="cbi-value" style="display:inline-block; width: 130px" for="ulfile"><%:Choose local file:%></label>
|
||||
<input class="cbi-input-file" style="width: 400px" type="file" id="ulfile" name="ulfile" accept="image/png, image/jpeg, image/gif, video/mp4, video/webm"/>
|
||||
<input type="submit" class="btn cbi-button cbi-input-apply" name="upload" value="<%:Upload%>" />
|
||||
<%+cbi/valuefooter%>
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-argon-config": {
|
||||
"description": "Grant UCI access for luci-app-argon-config",
|
||||
"read": {
|
||||
"uci": [ "argon" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "argon" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
1
ipk-source/luci-app-atinout-mod/CONTROL/conffiles
Executable file
1
ipk-source/luci-app-atinout-mod/CONTROL/conffiles
Executable file
@@ -0,0 +1 @@
|
||||
/etc/config/atcommands.user
|
||||
12
ipk-source/luci-app-atinout-mod/CONTROL/control
Executable file
12
ipk-source/luci-app-atinout-mod/CONTROL/control
Executable file
@@ -0,0 +1,12 @@
|
||||
Package: luci-app-atinout-mod
|
||||
Version: 1.3.4-20250119
|
||||
Depends: libc, atinout, luci-compat
|
||||
Source: package/luci-app-atinout-mod
|
||||
SourceName: luci-app-atinout-mod
|
||||
License: GPLv3
|
||||
Section: luci
|
||||
SourceDateEpoch: 1636930326
|
||||
Maintainer: OpenWrt LuCI community
|
||||
Architecture: all
|
||||
Installed-Size: 3790
|
||||
Description: Web UI for atinout modded by iamromulan preset for use on SDXPINN
|
||||
5
ipk-source/luci-app-atinout-mod/CONTROL/postinst
Executable file
5
ipk-source/luci-app-atinout-mod/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_postinst $0 $@
|
||||
7
ipk-source/luci-app-atinout-mod/CONTROL/postinst-pkg
Executable file
7
ipk-source/luci-app-atinout-mod/CONTROL/postinst-pkg
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
chmod +x /sbin/set_at_port.sh
|
||||
chmod +x /usr/bin/luci-app-atinout
|
||||
rm -rf /tmp/luci-indexcache
|
||||
rm -rf /tmp/luci-modulecache/
|
||||
/sbin/set_at_port.sh
|
||||
exit 0
|
||||
4
ipk-source/luci-app-atinout-mod/CONTROL/prerm
Executable file
4
ipk-source/luci-app-atinout-mod/CONTROL/prerm
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_prerm $0 $@
|
||||
74
ipk-source/luci-app-atinout-mod/build-ipk
Executable file
74
ipk-source/luci-app-atinout-mod/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
Reboot;AT+CFUN=1,1
|
||||
Disconnect;AT+CFUN=0
|
||||
Connect;AT+CFUN=1
|
||||
Signal Info;AT+QENG="servingcell"
|
||||
CA Info;AT+QCAINFO
|
||||
Get current SIM Slot;AT+QUIMSLOT?
|
||||
Switch to SIM Slot 1;AT+QUIMSLOT=1
|
||||
Switch to SIM Slot 2;AT+QUIMSLOT=2
|
||||
Get current APN List;AT+CGDCONT?
|
||||
Set APN to NRBROADBAND;AT+CGDCONT=1,"IPV4V6","NRBROADBAND"
|
||||
Show Current IMEI;AT+EGMR=0,7
|
||||
Show Current Network Mode;AT+QNWPREFCFG="mode_pref"
|
||||
Set Network Mode to AUTO;AT+QNWPREFCFG="mode_pref",AUTO
|
||||
Set Network Mode to 5G NR/4G LTE Only;AT+QNWPREFCFG="mode_pref",NR5G:LTE
|
||||
Set Network Mode to 5G NR Only;AT+QNWPREFCFG="mode_pref",NR5G
|
||||
Set Network Mode to 4G LTE Only;AT+QNWPREFCFG="mode_pref",LTE
|
||||
Check to see if SA or NSA is disabled;AT+QNWPREFCFG="nr5g_disable_mode"
|
||||
Enable Both SA and NSA;AT+QNWPREFCFG="nr5g_disable_mode",0
|
||||
Disable SA Only;AT+QNWPREFCFG="nr5g_disable_mode",1
|
||||
Disable NSA Only;AT+QNWPREFCFG="nr5g_disable_mode",2
|
||||
Get Currently Enabled 5G/NR SA Bands;AT+QNWPREFCFG="nr5g_band"
|
||||
Get Currently Enabled 5G/NR NSA Bands;AT+QNWPREFCFG="nsa_nr5g_band"
|
||||
Get Currently Enabled 4G/LTE Bands;AT+QNWPREFCFG="lte_band"
|
||||
View assigned IPv4/IPv6 addresses from the provider;AT+QMAP="WWAN"
|
||||
Enable IPPT paste in MAC for FF:FF:FF...;AT+QMAP="MPDN_rule",0,1,0,1,1,"FF:FF:FF:FF:FF:FF"
|
||||
Disable IPPT;AT+QMAP="MPDN_rule",0
|
||||
Set IPv4 DMZ....replace iphere;AT+QMAP="DMZ",1,4,iphere
|
||||
Set IPv6 DMZ....replace iphere;AT+QMAP="DMZ",1,6,iphere
|
||||
Disable IPv4 DMZ;AT+QMAP="DMZ",0,4
|
||||
Disable IPv6 DMZ;AT+QMAP="DMZ",0,6
|
||||
4
ipk-source/luci-app-atinout-mod/root/etc/config/atinout
Normal file
4
ipk-source/luci-app-atinout-mod/root/etc/config/atinout
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
config atinout 'general'
|
||||
option atcport '/dev/smd7'
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
# Copyright 2020-2021 Rafał Wabik (IceG) - From eko.one.pl forum
|
||||
# Licensed to the GNU General Public License v3.0.
|
||||
|
||||
work=false
|
||||
for port in /dev/ttyUSB*
|
||||
do
|
||||
[[ -e $port ]] || continue
|
||||
gcom -d $port info &> /tmp/testusb
|
||||
testUSB=`cat /tmp/testusb | grep "Error\|Can't"`
|
||||
if [ -z "$testUSB" ]; then
|
||||
work=$port
|
||||
break
|
||||
fi
|
||||
done
|
||||
rm -rf /tmp/testusb
|
||||
|
||||
if [ $work != false ]; then
|
||||
uci set atinout.@atinout[0].atcport=$work
|
||||
uci commit atinout
|
||||
fi
|
||||
21
ipk-source/luci-app-atinout-mod/root/sbin/set_at_port.sh
Executable file
21
ipk-source/luci-app-atinout-mod/root/sbin/set_at_port.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
# Copyright 2020-2021 Rafał Wabik (IceG) - From eko.one.pl forum
|
||||
# Licensed to the GNU General Public License v3.0.
|
||||
|
||||
work=false
|
||||
for port in /dev/ttyUSB*
|
||||
do
|
||||
[[ -e $port ]] || continue
|
||||
gcom -d $port info &> /tmp/testusb
|
||||
testUSB=`cat /tmp/testusb | grep "Error\|Can't"`
|
||||
if [ -z "$testUSB" ]; then
|
||||
work=$port
|
||||
break
|
||||
fi
|
||||
done
|
||||
rm -rf /tmp/testusb
|
||||
|
||||
if [ $work != false ]; then
|
||||
uci set atinout.@atinout[0].atcport=$work
|
||||
uci commit atinout
|
||||
fi
|
||||
8
ipk-source/luci-app-atinout-mod/root/usr/bin/luci-app-atinout
Executable file
8
ipk-source/luci-app-atinout-mod/root/usr/bin/luci-app-atinout
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
ARGS=$1
|
||||
DEVPORT=$(uci -q get atinout.general.atcport)
|
||||
|
||||
if [ "$DEVPORT" ]; then
|
||||
echo "${ARGS}" | /usr/bin/atinout - ${DEVPORT} -
|
||||
fi
|
||||
@@ -0,0 +1,49 @@
|
||||
local e=require"luci.util"
|
||||
local e=require"nixio.fs"
|
||||
local e=require"luci.sys"
|
||||
local e=require"luci.http"
|
||||
local e=require"luci.dispatcher"
|
||||
local e=require"luci.http"
|
||||
local t=require"luci.sys"
|
||||
local t=require"luci.model.uci".cursor()
|
||||
module("luci.controller.modem.atc",package.seeall)
|
||||
function index()
|
||||
entry({"admin","modem"},firstchild(),"Modem",30).dependent=false
|
||||
entry({"admin","modem","atc"},alias("admin","modem","atc","atcommand"),translate("AT Commands"),10).acl_depends={"luci-app-atinout-mod"}
|
||||
entry({"admin","modem","atc","atcommand"},template("modem/atcommand"),translate("AT Commands"),10)
|
||||
entry({"admin","modem","atc","atconfig"},cbi("modem/atconfig"),translate("Configuration"),20)
|
||||
entry({"admin","modem","webcmd"},call("webcmd"))
|
||||
entry({"admin","modem","atc","user_atc"},call("useratc"),nil).leaf=true
|
||||
end
|
||||
function webcmd()
|
||||
local t=e.formvalue("cmd")
|
||||
if t then
|
||||
local t=io.popen("/usr/bin/luci-app-atinout "..t:gsub("[$]","\\\$"):gsub("\"","\\\"").." 2>&1")
|
||||
local a=t:read("*a")
|
||||
t:close()
|
||||
e.write(tostring(a))
|
||||
else
|
||||
e.write_json(e.formvalue())
|
||||
end
|
||||
end
|
||||
function uussd(t)
|
||||
local e=nixio.fs.access("/etc/config/atcommands.user")and
|
||||
io.popen("cat /etc/config/atcommands.user")
|
||||
if e then
|
||||
for a in e:lines()do
|
||||
local e=a
|
||||
if e then
|
||||
t[#t+1]={
|
||||
usd=e
|
||||
}
|
||||
end
|
||||
end
|
||||
e:close()
|
||||
end
|
||||
end
|
||||
function useratc()
|
||||
local e={}
|
||||
uussd(e)
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
local e=require"luci.util"
|
||||
local o=require"nixio.fs"
|
||||
local e=require"luci.sys"
|
||||
local e=require"luci.http"
|
||||
local e=require"luci.dispatcher"
|
||||
local e=require"luci.http"
|
||||
local e=require"luci.sys"
|
||||
local e=require"luci.model.uci".cursor()
|
||||
local n="/etc/config/atcommands.user"
|
||||
local t
|
||||
local e
|
||||
local i
|
||||
local a=nixio.fs.glob("/dev/tty[A-Z][A-Z]*")
|
||||
t=Map("atinout",translate("Atinout Configuration"),
|
||||
translate("Configuration panel for atinout."))
|
||||
e=t:section(NamedSection,'general',"atinout",""..translate("AT Commands Terminal Settings"))
|
||||
e.anonymous=true
|
||||
i=e:option(Value,"atcport",translate("AT Command Sending Port"))
|
||||
if a then
|
||||
local e
|
||||
for e in a do
|
||||
i:value(e,e)
|
||||
end
|
||||
end
|
||||
local e=e:option(TextValue,"user_atcommands",translate("User AT Commands"),translate("Each line must have the following format: 'AT Command name;AT Command'. Save to file '/etc/config/atcommands.user'."))
|
||||
e.rows=20
|
||||
e.rmempty=false
|
||||
function e.cfgvalue(e,e)
|
||||
return o.readfile(n)
|
||||
end
|
||||
function e.write(t,t,e)
|
||||
e=e:gsub("\r\n","\n")
|
||||
o.writefile(n,e)
|
||||
end
|
||||
return t
|
||||
@@ -0,0 +1,133 @@
|
||||
<%+header%>
|
||||
<!--
|
||||
This module gives some convinience to access the shell via web, in
|
||||
case that you don't have a uart console or telnet/ssh connection.
|
||||
Hua Shao <nossiac@163.com>
|
||||
-->
|
||||
<h2><%:AT Commands%></h2>
|
||||
<label><%:Web UI for sending AT Commands.%></label>
|
||||
<p></p>
|
||||
<h4><%:Sending commands to modem%></h4>
|
||||
<div class="table" width="100%">
|
||||
|
||||
<div class="tr">
|
||||
<div class="td left" width="23%"><%:User AT Commands%>:</div>
|
||||
|
||||
<div class="td left" style="width:55%;">
|
||||
<select name="ussd" id="pl" onclick="copyFunction()">
|
||||
|
||||
</select>
|
||||
</div>
|
||||
<div class="td left" style="width:55%;"></div>
|
||||
</div>
|
||||
|
||||
<div class="tr">
|
||||
<div class="td left" style="width:23%;"><%:Command to send%>:</div>
|
||||
<div class="td left" ><input type="text" id="code" required size="20" ></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="table" width="100%">
|
||||
<div class="td left" style="width:23%;"><%:Reply%>:
|
||||
<p>
|
||||
<pre id="result" style="visibility: hidden; width:77%;"></pre></div>
|
||||
|
||||
<div class="tr cbi-rowstyle-2">
|
||||
<div class="td right"><div style="float: left;"><div class="ifacebadge"><a href="https://eko.one.pl">e1</a></div></div><input type="button" style="margin-right: 23%"; id="sendcmd" class="btn cbi-button cbi-button-neutral" value="<%:Send Command%>" /></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
window.onload = function readUSER() {
|
||||
|
||||
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "atc", "user_atc")%>', null,
|
||||
function(x, json)
|
||||
{
|
||||
select = document.getElementById('pl');
|
||||
|
||||
var count = Object.keys(json).length;
|
||||
|
||||
|
||||
for(var d=0;d<=count;d++)
|
||||
{
|
||||
var opt = document.createElement('option');
|
||||
|
||||
var s = json[d].usd;
|
||||
var fields = s.split(/;/);
|
||||
var name = fields[0];
|
||||
var code = fields[1];
|
||||
opt.text = name;
|
||||
opt.value = code.trim();
|
||||
opt.innerHTML = name;
|
||||
select.appendChild(opt);
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
function copyFunction() {
|
||||
|
||||
var node = document.getElementById('result');
|
||||
node.style.visibility = 'hidden';
|
||||
|
||||
var x = document.getElementById("pl").value;
|
||||
document.getElementById("code").value = x;
|
||||
document.getElementById("result").innerHTML = "";
|
||||
}
|
||||
|
||||
|
||||
function postcmd(cmd) {
|
||||
(new XHR()).post("<%=luci.dispatcher.build_url("admin", "modem", "webcmd")%>", {"cmd":cmd}, function(x) {
|
||||
console.log(x.response)
|
||||
console.log(x)
|
||||
|
||||
var aStr = x.response;
|
||||
var myre = /(^[ \t]*\n)/gm;
|
||||
var bStr = aStr.replace(myre,"");
|
||||
|
||||
document.getElementById("result").innerHTML = bStr;
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function (ev) {var button = document.getElementById("sendcmd");
|
||||
button.addEventListener("click", function () {
|
||||
|
||||
|
||||
var s = document.getElementById("code").value;
|
||||
if ( s.length == 0 )
|
||||
{
|
||||
document.getElementById("result").innerHTML = "";
|
||||
alert("<%:Please enter a AT Command%>");
|
||||
return false;
|
||||
}
|
||||
|
||||
var cmd = document.getElementById("code");
|
||||
postcmd(cmd.value);
|
||||
cmd.value = "";
|
||||
|
||||
var node = document.getElementById('result');
|
||||
if (node.style.visibility=='visible') {
|
||||
node.style.visibility = 'hidden';
|
||||
}
|
||||
else
|
||||
node.style.visibility = 'visible'
|
||||
|
||||
return true;
|
||||
});
|
||||
}, true);
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<%+footer%>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"luci-app-atinout-mod": {
|
||||
"description": "Grant UCI and file access for luci-app-atinout-mod",
|
||||
"read": {
|
||||
"uci": [ "atinout" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "atinout" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1
ipk-source/luci-app-go-wireguard/CONTROL/conffiles
Executable file
1
ipk-source/luci-app-go-wireguard/CONTROL/conffiles
Executable file
@@ -0,0 +1 @@
|
||||
/etc/config/wireguard
|
||||
11
ipk-source/luci-app-go-wireguard/CONTROL/control
Executable file
11
ipk-source/luci-app-go-wireguard/CONTROL/control
Executable file
@@ -0,0 +1,11 @@
|
||||
Package: luci-app-go-wireguard
|
||||
Version: 4.500-2
|
||||
Depends: libc, wireguard-tools, kmod-wireguard, luci-proto-wireguard, udptunnel, eoip
|
||||
Source: package/rooter/0optionalapps/ext-wireguard
|
||||
SourceName: ext-wireguard
|
||||
Section: utils
|
||||
SourceDateEpoch: 1716401566
|
||||
Maintainer: Created by DM/makefile by Cobia@whirlpool
|
||||
Architecture: all
|
||||
Installed-Size: 23912
|
||||
Description: Install scripts for Wireguard
|
||||
3
ipk-source/luci-app-go-wireguard/CONTROL/postinst
Executable file
3
ipk-source/luci-app-go-wireguard/CONTROL/postinst
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
ln -sf /usr/bin/udptunnel /sbin/udptunnel
|
||||
exit 0
|
||||
74
ipk-source/luci-app-go-wireguard/build-ipk
Executable file
74
ipk-source/luci-app-go-wireguard/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
5
ipk-source/luci-app-go-wireguard/root/etc/config/wireguard
Executable file
5
ipk-source/luci-app-go-wireguard/root/etc/config/wireguard
Executable file
@@ -0,0 +1,5 @@
|
||||
|
||||
config settings 'settings'
|
||||
option enabled '0'
|
||||
option client '0'
|
||||
option server '0'
|
||||
36
ipk-source/luci-app-go-wireguard/root/etc/config/wireguard_recipes
Executable file
36
ipk-source/luci-app-go-wireguard/root/etc/config/wireguard_recipes
Executable file
@@ -0,0 +1,36 @@
|
||||
config wireguard_recipe b_client
|
||||
option _description "Wireguard Client"
|
||||
option _role "client"
|
||||
option client "1"
|
||||
option port "51280"
|
||||
option auto '0'
|
||||
option addresses ''
|
||||
option dns ''
|
||||
option privatekey ''
|
||||
option name ''
|
||||
option keepalive '25'
|
||||
option publickey ''
|
||||
option presharedkey ''
|
||||
option ips ''
|
||||
option ra_ips '1'
|
||||
option endpoint_host ''
|
||||
option sport '51280'
|
||||
option active '0'
|
||||
option udptunnel '0'
|
||||
option mtu '1280'
|
||||
|
||||
config wireguard_recipe b_server
|
||||
option _description "Wireguard Server"
|
||||
option _role "server"
|
||||
option client "0"
|
||||
option port "51280"
|
||||
option auto '0'
|
||||
option addresses ''
|
||||
option publickey ''
|
||||
option privatekey ''
|
||||
option usepre '0'
|
||||
option presharedkey ''
|
||||
option active '0'
|
||||
option udptunnel '0'
|
||||
option udpport '54321'
|
||||
option mtu '1280'
|
||||
92
ipk-source/luci-app-go-wireguard/root/etc/init.d/wireguard
Executable file
92
ipk-source/luci-app-go-wireguard/root/etc/init.d/wireguard
Executable file
@@ -0,0 +1,92 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
. /lib/functions.sh
|
||||
# Copyright (C) 2006 OpenWrt.org
|
||||
|
||||
START=99
|
||||
|
||||
log() {
|
||||
logger -t "WireGuard Init.d : " "$@"
|
||||
}
|
||||
|
||||
chk_zone() {
|
||||
local config=$1
|
||||
|
||||
config_get src $config src
|
||||
config_get dest $config dest
|
||||
if [ $src = "lan" -a $dest = "wg" ]; then
|
||||
uci set firewall."$config".dest="wan"
|
||||
uci commit firewall
|
||||
fi
|
||||
}
|
||||
|
||||
check_config () {
|
||||
log "Check Client Interfaces"
|
||||
uci delete network.wg0
|
||||
uci delete network.wg1
|
||||
uci commit network
|
||||
uci set network.wg0=interface
|
||||
uci set network.wg0.proto="wireguard"
|
||||
uci set network.wg0.auto="0"
|
||||
uci set network.wg0.private_key=""
|
||||
uci set network.wg0.listen_port=""
|
||||
uci add_list network.wg0.addresses=""
|
||||
uci set network.wg1=interface
|
||||
uci set network.wg1.proto="wireguard"
|
||||
uci set network.wg1.auto="0"
|
||||
uci set network.wg1.private_key=""
|
||||
uci set network.wg1.listen_port=""
|
||||
uci add_list network.wg1.addresses=""
|
||||
uci commit network
|
||||
|
||||
uci delete firewall.wgzone
|
||||
uci delete firewall.wgwforward
|
||||
uci delete firewall.wwgforward
|
||||
uci delete firewall.lwgforward
|
||||
uci delete firewall.wglforward
|
||||
uci commit firewall
|
||||
uci set firewall.wgzone=zone
|
||||
uci set firewall.wgzone.name="wg"
|
||||
uci set firewall.wgzone.forward="ACCEPT"
|
||||
uci set firewall.wgzone.output="ACCEPT"
|
||||
uci set firewall.wgzone.network="wg0 wg1"
|
||||
uci set firewall.wgzone.input="ACCEPT"
|
||||
uci set firewall.wgzone.masq="1"
|
||||
uci set firewall.wgzone.mtu_fix="1"
|
||||
uci commit firewall
|
||||
|
||||
config_load firewall
|
||||
config_foreach chk_zone forwarding
|
||||
|
||||
/etc/init.d/firewall restart
|
||||
}
|
||||
|
||||
chk_start() {
|
||||
local config=$1
|
||||
|
||||
config_get auto $config auto
|
||||
uci set wireguard."$config".active="0"
|
||||
uci commit wireguard
|
||||
if [ $auto = '1' ]; then
|
||||
/usr/lib/wireguard/startvpn.sh $config
|
||||
else
|
||||
/usr/lib/wireguard/stopvpn.sh $config
|
||||
fi
|
||||
}
|
||||
|
||||
start() {
|
||||
uci set wireguard.settings.client="0"
|
||||
uci set wireguard.settings.server="0"
|
||||
uci commit wireguard
|
||||
if [ ! -e /etc/openvpn ]; then
|
||||
mkdir /etc/openvpn
|
||||
fi
|
||||
check_config
|
||||
|
||||
config_load wireguard
|
||||
config_foreach chk_start wireguard
|
||||
if [ -e /etc/crontabs/root ]; then
|
||||
sed -i '/wireguard_watchdog/d' /etc/crontabs/root
|
||||
fi
|
||||
echo '* * * * * /usr/bin/wireguard_watchdog' >> /etc/crontabs/root
|
||||
/etc/init.d/cron restart
|
||||
}
|
||||
111
ipk-source/luci-app-go-wireguard/root/usr/lib/lua/luci/controller/wireguard.lua
Executable file
111
ipk-source/luci-app-go-wireguard/root/usr/lib/lua/luci/controller/wireguard.lua
Executable file
@@ -0,0 +1,111 @@
|
||||
-- Copyright 2016-2017 Dan Luedtke <mail@danrl.com>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
module("luci.controller.wireguard", package.seeall)
|
||||
|
||||
I18N = require "luci.i18n"
|
||||
translate = I18N.translate
|
||||
|
||||
function index()
|
||||
local multilock = luci.model.uci.cursor():get("custom", "multiuser", "multi") or "0"
|
||||
local rootlock = luci.model.uci.cursor():get("custom", "multiuser", "root") or "0"
|
||||
if (multilock == "0") or (multilock == "1" and rootlock == "1") then
|
||||
entry({"admin", "vpn", "wireguard"}, cbi("wireguard"), _("Wireguard"), 63)
|
||||
entry( {"admin", "vpn", "wireguard", "client"}, cbi("wireguard-client"), nil ).leaf = true
|
||||
entry( {"admin", "vpn", "wireguard", "server"}, cbi("wireguard-server"), nil ).leaf = true
|
||||
end
|
||||
|
||||
entry( {"admin", "vpn", "wireguard", "wupload"}, call("conf_upload"))
|
||||
entry( {"admin", "vpn", "generateconf"}, call("conf_gen"))
|
||||
entry( {"admin", "vpn", "textconf"}, call("text_gen"))
|
||||
entry( {"admin", "vpn", "wirestatus"}, call("wirestatus"))
|
||||
end
|
||||
|
||||
function conf_upload()
|
||||
local fs = require("nixio.fs")
|
||||
local http = require("luci.http")
|
||||
local util = require("luci.util")
|
||||
local uci = require("luci.model.uci").cursor()
|
||||
local upload = http.formvalue("ovpn_file")
|
||||
local name = http.formvalue("instance_name2")
|
||||
local file = "/etc/openvpn/" ..name.. ".conf"
|
||||
|
||||
if name and upload then
|
||||
local fp
|
||||
|
||||
http.setfilehandler(
|
||||
function(meta, chunk, eof)
|
||||
local data = util.trim(chunk:gsub("\r\n", "\n")) .. "\n"
|
||||
data = util.trim(data:gsub("[\128-\255]", ""))
|
||||
|
||||
if not fp and meta and meta.name == "ovpn_file" then
|
||||
fp = io.open(file, "w")
|
||||
end
|
||||
if fp and data then
|
||||
fp:write(data)
|
||||
end
|
||||
if fp and eof then
|
||||
fp:close()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
if fs.access(file) then
|
||||
os.execute("/usr/lib/wireguard/conf.sh " .. name .. " " .. file)
|
||||
end
|
||||
end
|
||||
http.redirect(luci.dispatcher.build_url('admin/vpn/wireguard'))
|
||||
end
|
||||
|
||||
function conf_gen()
|
||||
os.execute("/usr/lib/wireguard/create.sh")
|
||||
end
|
||||
|
||||
function text_gen()
|
||||
local set = luci.http.formvalue("set")
|
||||
os.execute("/usr/lib/wireguard/text.sh " .. "\"" .. set .. "\"")
|
||||
end
|
||||
|
||||
function wirestatus()
|
||||
local data = { }
|
||||
local last_device = ""
|
||||
|
||||
local wg_dump = io.popen("wg show all dump")
|
||||
if wg_dump then
|
||||
local line
|
||||
for line in wg_dump:lines() do
|
||||
local line = string.split(line, "\t")
|
||||
if not (last_device == line[1]) then
|
||||
last_device = line[1]
|
||||
data[line[1]] = {
|
||||
name = line[1],
|
||||
public_key = line[3],
|
||||
listen_port = line[4],
|
||||
fwmark = line[5],
|
||||
peers = { }
|
||||
}
|
||||
else
|
||||
local peer = {
|
||||
public_key = line[2],
|
||||
endpoint = line[4],
|
||||
allowed_ips = { },
|
||||
latest_handshake = line[6],
|
||||
transfer_rx = line[7],
|
||||
transfer_tx = line[8],
|
||||
persistent_keepalive = line[9]
|
||||
}
|
||||
if not (line[4] == '(none)') then
|
||||
for ipkey, ipvalue in pairs(string.split(line[5], ",")) do
|
||||
if #ipvalue > 0 then
|
||||
table.insert(peer['allowed_ips'], ipvalue)
|
||||
end
|
||||
end
|
||||
end
|
||||
table.insert(data[line[1]].peers, peer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(data)
|
||||
end
|
||||
@@ -0,0 +1,104 @@
|
||||
require("luci.ip")
|
||||
require("luci.model.uci")
|
||||
|
||||
--luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1])
|
||||
|
||||
local m = Map("wireguard", translate("Wireguard Client"), translate("Set up a Wireguard Client"))
|
||||
|
||||
e = m:section(NamedSection, "settings", "")
|
||||
|
||||
m.on_init = function(self)
|
||||
--luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1])
|
||||
end
|
||||
|
||||
btn = e:option(Button, "_btn", translate(" "))
|
||||
btn.inputtitle = translate("Back to Main Page")
|
||||
btn.inputstyle = "apply"
|
||||
btn.redirect = luci.dispatcher.build_url(
|
||||
"admin", "vpn", "wireguard"
|
||||
)
|
||||
function btn.write(self, section, value)
|
||||
luci.http.redirect( self.redirect )
|
||||
end
|
||||
|
||||
|
||||
local s = m:section( NamedSection, arg[1], "wireguard", translate("Client") )
|
||||
|
||||
ip = s:option(Value, "addresses", translate("IP Addresses :"), translate("Comma separated list of IP Addresses that server will accept from this client"));
|
||||
ip.rmempty = true;
|
||||
ip.optional=false;
|
||||
ip.default="10.14.0.2/24";
|
||||
|
||||
port = s:option(Value, "port", translate("Listen Port :"), translate("Client Listen Port"));
|
||||
port.rmempty = true;
|
||||
port.optional=false;
|
||||
port.default="51820";
|
||||
|
||||
ul = s:option(ListValue, "udptunnel", translate("Enable UDP over TCP :"));
|
||||
ul:value("0", translate("No"))
|
||||
ul:value("1", translate("Yes"))
|
||||
ul.default=0
|
||||
|
||||
dns = s:option(Value, "dns", translate("DNS Servers :"), translate("Comma separated list of DNS Servers."));
|
||||
dns.rmempty = true;
|
||||
dns.optional=false;
|
||||
|
||||
mtu = s:option(Value, "mtu", translate("MTU :"), translate("Maximum MTU"));
|
||||
mtu.rmempty = true;
|
||||
mtu.optional=false;
|
||||
mtu.datatype = 'range(1280,1420)';
|
||||
mtu.default="1280";
|
||||
|
||||
pka = s:option(Value, "persistent_keepalive", translate("Persistent Keep Alive :"), translate("Seconds between keep alive messages"));
|
||||
pka.rmempty = true;
|
||||
pka.optional=false;
|
||||
pka.datatype = 'range(1,100)';
|
||||
pka.default="25";
|
||||
|
||||
pkey = s:option(Value, "privatekey", translate("Private Key :"), translate("Private Key supplied by the Server"));
|
||||
pkey.rmempty = true;
|
||||
pkey.optional=false;
|
||||
|
||||
il = s:option(ListValue, "wginter", translate("Interface to Use :"));
|
||||
il:value("0", translate("WG0"))
|
||||
il:value("1", translate("WG1"))
|
||||
il.default="0"
|
||||
|
||||
bl = s:option(ListValue, "auto", translate("Start on Boot :"));
|
||||
bl:value("0", translate("No"))
|
||||
bl:value("1", translate("Yes"))
|
||||
bl.default="0"
|
||||
|
||||
xbl = s:option(ListValue, "forward", translate("All Traffic Through Tunnel :"));
|
||||
xbl:value("0", translate("No"))
|
||||
xbl:value("1", translate("Yes"))
|
||||
xbl.default="1"
|
||||
|
||||
s = m:section( NamedSection, arg[1], "wireguard", translate("Server") )
|
||||
|
||||
name = s:option( Value, "name", translate("Server Name :"), translate("Optional Server name"))
|
||||
|
||||
pukey = s:option(Value, "publickey", translate("Public Key :"), translate("Public Key of the Server"));
|
||||
pukey.rmempty = true;
|
||||
pukey.optional=false;
|
||||
|
||||
prkey = s:option(Value, "presharedkey", translate("Presharedkey :"), translate("PreShared Key from the Server"));
|
||||
prkey.rmempty = true;
|
||||
prkey.optional=false;
|
||||
|
||||
host = s:option(Value, "endpoint_host", translate("Server Address :"), translate("URL or IP Address of Server"));
|
||||
host.rmempty = true;
|
||||
host.optional=false;
|
||||
host.default="";
|
||||
|
||||
sport = s:option(Value, "sport", translate("Listen Port :"), translate("Server Listen Port"));
|
||||
sport.rmempty = true;
|
||||
sport.optional=false;
|
||||
sport.default="51820";
|
||||
|
||||
sip = s:option(Value, "ips", translate("Allowed IP Addresses :"), translate("Comma separated list of IP Addresses that server will accept"));
|
||||
sip.rmempty = true;
|
||||
sip.optional=false;
|
||||
sip.default="10.14.0.0/24";
|
||||
|
||||
return m
|
||||
@@ -0,0 +1,130 @@
|
||||
require("luci.ip")
|
||||
require("luci.model.uci")
|
||||
|
||||
--luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1])
|
||||
|
||||
local m = Map("wireguard", translate("Wireguard Server"), translate("Set up a Wireguard Server"))
|
||||
|
||||
e = m:section(NamedSection, "settings", "")
|
||||
|
||||
m.on_init = function(self)
|
||||
luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1])
|
||||
end
|
||||
|
||||
m.on_after_save = function(self)
|
||||
luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1] .. "&")
|
||||
end
|
||||
|
||||
btn = e:option(Button, "_btn", translate(" "))
|
||||
btn.inputtitle = translate("Back to Main Page")
|
||||
btn.inputstyle = "apply"
|
||||
btn.redirect = luci.dispatcher.build_url(
|
||||
"admin", "vpn", "wireguard"
|
||||
)
|
||||
function btn.write(self, section, value)
|
||||
luci.http.redirect( self.redirect )
|
||||
end
|
||||
|
||||
|
||||
local s = m:section( NamedSection, arg[1], "wireguard", translate("Server") )
|
||||
|
||||
ip = s:option(Value, "addresses", translate("Internal IP Address :"));
|
||||
ip.rmempty = true;
|
||||
ip.optional=false;
|
||||
ip.default="10.14.0.1/32";
|
||||
ip.datatype = "ipaddr"
|
||||
|
||||
host = s:option(Value, "endpoint_host", translate("Server Address :"), translate("URL or IP Address of Server"));
|
||||
host.rmempty = true;
|
||||
host.optional=false;
|
||||
host.default="example.wireguard.org";
|
||||
|
||||
port = s:option(Value, "port", translate("Port :"), translate("Server Listen Port. Default is 51280"));
|
||||
port.rmempty = true;
|
||||
port.optional=false;
|
||||
port.default="51280";
|
||||
|
||||
ul = s:option(ListValue, "udptunnel", "Enable UDP over TCP :");
|
||||
ul:value("0", translate("No"))
|
||||
ul:value("1", translate("Yes"))
|
||||
ul.default=0
|
||||
|
||||
uport = s:option(Value, "udpport", translate("UDP over TCP Port :"), translate("Server Local TCP Port. Default is 54321"));
|
||||
uport.rmempty = true;
|
||||
uport.optional=false;
|
||||
uport.default="54321";
|
||||
uport:depends("udptunnel", "1")
|
||||
|
||||
pkey = s:option(DummyValue, "privatekey", translate("Private Key :"));
|
||||
pkey.optional=false;
|
||||
|
||||
pukey = s:option(DummyValue, "publickey", translate("Public Key :"), translate("Server Public key sent to Clients"));
|
||||
pukey.optional=false;
|
||||
|
||||
pl = s:option(ListValue, "usepre", "Use PreSharedKey :");
|
||||
pl:value("0", translate("No"))
|
||||
pl:value("1", translate("Yes"))
|
||||
pl.default=0
|
||||
|
||||
prkey = s:option(DummyValue, "presharedkey", translate("PreShared Key :"), translate("PreShared Key sent to Client"));
|
||||
prkey.optional=false;
|
||||
prkey:depends("usepre", "1")
|
||||
|
||||
bl = s:option(ListValue, "auto", translate("Start on Boot :"));
|
||||
bl:value("0", translate("No"))
|
||||
bl:value("1", translate("Yes"))
|
||||
bl.default="0"
|
||||
|
||||
xbl = s:option(ListValue, "forward", translate("All Traffic Through Tunnel :"));
|
||||
xbl:value("0", translate("No"))
|
||||
xbl:value("1", translate("Yes"))
|
||||
xbl.default="1"
|
||||
|
||||
|
||||
b3 = s:option(DummyValue, "blank", " ");
|
||||
|
||||
sx = s:option(Value, "_dmy1", translate(" "))
|
||||
sx.template = "wireguard/conf"
|
||||
|
||||
ss = m:section(TypedSection, "custom" .. arg[1], translate("Clients"), translate("Clients of this server"))
|
||||
ss.anonymous = true
|
||||
ss.addremove = true
|
||||
|
||||
name = ss:option(Value, "name", translate("Client Name"))
|
||||
name.optional=false;
|
||||
|
||||
cport = ss:option(Value, "endpoint_port", translate("Listen Port :"), translate("Port sent to Client. Default is 51280"));
|
||||
cport.rmempty = true;
|
||||
cport.optional=false;
|
||||
cport.default="";
|
||||
|
||||
aip = ss:option(Value, "address", translate("Assigned IP Address :"), translate("IP Address assigned to Client"));
|
||||
aip.rmempty = true;
|
||||
aip.optional=false;
|
||||
aip.default="10.14.0.2/32";
|
||||
|
||||
dns = ss:option(Value, "dns", translate("DNS Servers :"), translate("Comma separated list of DNS Servers sent to Client"));
|
||||
dns.rmempty = true;
|
||||
dns.optional=false;
|
||||
dns.default="";
|
||||
|
||||
mtu = ss:option(Value, "mtu", translate("MTU :"), translate("Maximum MTU"));
|
||||
mtu.rmempty = true;
|
||||
mtu.optional=false;
|
||||
mtu.datatype = 'range(1280,1420)';
|
||||
mtu.default="1280";
|
||||
|
||||
aip = ss:option(Value, "allowed_ips", translate("Allowed IP Address :"), translate("Comma separated list of IP Addresses allowed from Client"));
|
||||
aip.rmempty = true;
|
||||
aip.optional=false;
|
||||
aip.default="0.0.0.0/0,::/0";
|
||||
|
||||
pukey = ss:option(DummyValue, "publickey", translate("Public Key :"), translate("Client Public Key"));
|
||||
pukey.optional=false;
|
||||
|
||||
pikey = ss:option(DummyValue, "privatekey", translate("Private Key :"), translate("Private Key sent to Client"));
|
||||
pikey.optional=false;
|
||||
|
||||
b3 = ss:option(DummyValue, "blank", " ");
|
||||
|
||||
return m
|
||||
182
ipk-source/luci-app-go-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard.lua
Executable file
182
ipk-source/luci-app-go-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard.lua
Executable file
@@ -0,0 +1,182 @@
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local testfullps = sys.exec("ps --help 2>&1 | grep BusyBox") --check which ps do we have
|
||||
local psstring = (string.len(testfullps)>0) and "ps w" or "ps axfw" --set command we use to get pid
|
||||
|
||||
local m = Map("wireguard", translate("Wireguard"), translate("Set up a Wireguard VPN Tunnel on your Router"))
|
||||
|
||||
local s = m:section( TypedSection, "wireguard", translate("Instances"), translate("Below is a list of configured Wireguard Instances and their current state") )
|
||||
s.template = "cbi/tblsection"
|
||||
s.template_addremove = "wireguard/cbi-select-input-add"
|
||||
s.addremove = true
|
||||
s.add_select_options = { }
|
||||
|
||||
local cfg = s:option(DummyValue, "config")
|
||||
function cfg.cfgvalue(self, section)
|
||||
local file_cfg = self.map:get(section, "client")
|
||||
if file_cfg == "1" then
|
||||
s.extedit = luci.dispatcher.build_url("admin", "vpn", "wireguard", "client", "%s")
|
||||
else
|
||||
s.extedit = luci.dispatcher.build_url("admin", "vpn", "wireguard", "server", "%s")
|
||||
end
|
||||
end
|
||||
|
||||
uci:load("wireguard_recipes")
|
||||
uci:foreach( "wireguard_recipes", "wireguard_recipe",
|
||||
function(section)
|
||||
s.add_select_options[section['.name']] =
|
||||
section['_description'] or section['.name']
|
||||
end
|
||||
)
|
||||
|
||||
function s.parse(self, section)
|
||||
local recipe = luci.http.formvalue(
|
||||
luci.cbi.CREATE_PREFIX .. self.config .. "." ..
|
||||
self.sectiontype .. ".select"
|
||||
)
|
||||
|
||||
if recipe and not s.add_select_options[recipe] then
|
||||
self.invalid_cts = true
|
||||
else
|
||||
TypedSection.parse( self, section )
|
||||
end
|
||||
end
|
||||
|
||||
function s.create(self, name)
|
||||
local recipe = luci.http.formvalue(
|
||||
luci.cbi.CREATE_PREFIX .. self.config .. "." ..
|
||||
self.sectiontype .. ".select"
|
||||
)
|
||||
local name = luci.http.formvalue(
|
||||
luci.cbi.CREATE_PREFIX .. self.config .. "." ..
|
||||
self.sectiontype .. ".text"
|
||||
)
|
||||
if #name > 3 and not name:match("[^a-zA-Z0-9_]") then
|
||||
local s = uci:section("wireguard", "wireguard", name)
|
||||
if s then
|
||||
local options = uci:get_all("wireguard_recipes", recipe)
|
||||
for k, v in pairs(options) do
|
||||
if k ~= "_role" and k ~= "_description" then
|
||||
if type(v) == "boolean" then
|
||||
v = v and "1" or "0"
|
||||
end
|
||||
uci:set("wireguard", name, k, v)
|
||||
end
|
||||
end
|
||||
uci:save("wireguard")
|
||||
uci:commit("wireguard")
|
||||
if extedit then
|
||||
luci.http.redirect( self.extedit:format(name) )
|
||||
end
|
||||
end
|
||||
elseif #name > 0 then
|
||||
self.invalid_cts = true
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function s.remove(self, name)
|
||||
local cfg_file = "/etc/openvpn/" ..name.. ".conf"
|
||||
local auth_file = "/etc/openvpn/" ..name.. ".auth"
|
||||
if fs.access(cfg_file) then
|
||||
fs.unlink(cfg_file)
|
||||
end
|
||||
if fs.access(auth_file) then
|
||||
fs.unlink(auth_file)
|
||||
end
|
||||
uci:delete("wireguard", name)
|
||||
uci:save("wireguard")
|
||||
uci:commit("wireguard")
|
||||
end
|
||||
|
||||
local port = s:option( DummyValue, "client", translate("Type") )
|
||||
function port.cfgvalue(self, section)
|
||||
local val = AbstractValue.cfgvalue(self, section)
|
||||
if val == nil then
|
||||
val = 0
|
||||
end
|
||||
if val == "1" then
|
||||
return "Client"
|
||||
else
|
||||
return "Server"
|
||||
end
|
||||
end
|
||||
|
||||
local addr = s:option( DummyValue, "addresses", translate("IP Addresses") )
|
||||
function addr.cfgvalue(self, section)
|
||||
local val = AbstractValue.cfgvalue(self, section)
|
||||
return val or "----"
|
||||
end
|
||||
|
||||
local auto = s:option( DummyValue, "udptunnel", translate("UDP over TCP") )
|
||||
function auto.cfgvalue(self, section)
|
||||
local val = AbstractValue.cfgvalue(self, section)
|
||||
if val == nil then
|
||||
val = 0
|
||||
end
|
||||
if val == "1" then
|
||||
return "Yes"
|
||||
else
|
||||
return "No"
|
||||
end
|
||||
end
|
||||
|
||||
local auto = s:option( DummyValue, "auto", translate("Start on Boot") )
|
||||
function auto.cfgvalue(self, section)
|
||||
local val = AbstractValue.cfgvalue(self, section)
|
||||
if val == nil then
|
||||
val = 0
|
||||
end
|
||||
if val == "1" then
|
||||
return "Yes"
|
||||
else
|
||||
return "No"
|
||||
end
|
||||
end
|
||||
|
||||
local active = s:option( DummyValue, "active", translate("Started") )
|
||||
function active.cfgvalue(self, section)
|
||||
local val = AbstractValue.cfgvalue(self, section)
|
||||
if val == nil then
|
||||
val = 0
|
||||
end
|
||||
if val == "1" then
|
||||
return "Yes"
|
||||
else
|
||||
return "No"
|
||||
end
|
||||
end
|
||||
|
||||
local updown = s:option( Button, "_updown", translate("Start/Stop") )
|
||||
updown._state = false
|
||||
updown.redirect = luci.dispatcher.build_url(
|
||||
"admin", "vpn", "wireguard"
|
||||
)
|
||||
function updown.cbid(self, section)
|
||||
local file_cfg = self.map:get(section, "active")
|
||||
if file_cfg == "1" then
|
||||
pid = 1
|
||||
else
|
||||
pid = nil
|
||||
end
|
||||
self._state = pid ~= nil
|
||||
self.option = self._state and "stop" or "start"
|
||||
return AbstractValue.cbid(self, section)
|
||||
end
|
||||
function updown.cfgvalue(self, section)
|
||||
self.title = self._state and "stop" or "start"
|
||||
self.inputstyle = self._state and "reset" or "reload"
|
||||
end
|
||||
function updown.write(self, section, value)
|
||||
if self.option == "stop" then
|
||||
sys.call("/usr/lib/wireguard/stopvpn.sh %s" % section)
|
||||
else
|
||||
sys.call("/usr/lib/wireguard/startvpn.sh %s" % section)
|
||||
end
|
||||
luci.http.redirect( self.redirect )
|
||||
end
|
||||
|
||||
m:section(SimpleSection).template = "wireguard/wireguard"
|
||||
|
||||
return m
|
||||
@@ -0,0 +1,111 @@
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function vpn_add()
|
||||
{
|
||||
var vpn_name = div_add.querySelector("#instance_name1").value.replace(/[^\x00-\x7F]|[\s\.!@#$%^&*()\-+=\[\]{};':"\\|,<>\/?]/g,'');
|
||||
var vpn_template = div_add.querySelector("#instance_template").value;
|
||||
var form = document.getElementsByName('cbi')[0];
|
||||
|
||||
if (!vpn_name || !vpn_name.length)
|
||||
{
|
||||
return info_message(vpn_output, "<%=pcdata(translate("The 'Name' field must not be empty!"))%>", 2000);
|
||||
}
|
||||
|
||||
document.getElementById("instance_name1").value = vpn_name;
|
||||
if (document.getElementById("cbi-wireguard-" + vpn_name) != null)
|
||||
{
|
||||
return info_message(vpn_output, "<%=pcdata(translate("Instance with that name already exists!"))%>", 2000);
|
||||
}
|
||||
|
||||
if (!vpn_template || !vpn_template.length)
|
||||
{
|
||||
return info_message(vpn_output, "<%=pcdata(translate("Please select a valid VPN template!"))%>", 2000);
|
||||
}
|
||||
|
||||
if (form)
|
||||
{
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
function vpn_upload()
|
||||
{
|
||||
var vpn_name = div_upload.querySelector("#instance_name2").value.replace(/[^\x00-\x7F]|[\s\.!@#$%^&*()\-+=\[\]{};':"\\|,<>\/?]/g,'');
|
||||
var vpn_file = document.getElementById("ovpn_file").value;
|
||||
var form = document.getElementsByName('cbi')[0];
|
||||
|
||||
if (!vpn_name || !vpn_name.length)
|
||||
{
|
||||
return info_message(vpn_output, "<%=pcdata(translate("The 'Name' field must not be empty!"))%>", 2000);
|
||||
}
|
||||
|
||||
document.getElementById("instance_name2").value = vpn_name;
|
||||
if (document.getElementById("cbi-wireguard-" + vpn_name) != null)
|
||||
{
|
||||
return info_message(vpn_output, "<%=pcdata(translate("Instance with that name already exists!"))%>", 2000);
|
||||
}
|
||||
|
||||
if (!vpn_file || !vpn_file.length)
|
||||
{
|
||||
return info_message(vpn_output, "<%=pcdata(translate("Please select a valid CONF config file to upload!"))%>", 2000);
|
||||
}
|
||||
|
||||
if (form)
|
||||
{
|
||||
form.enctype = 'multipart/form-data';
|
||||
form.action = '<%=url('admin/vpn/wireguard/wupload')%>';
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
function info_message(output, msg, timeout)
|
||||
{
|
||||
timeout = timeout || 0;
|
||||
output.innerHTML = '<em>' + msg + '</em>';
|
||||
if (timeout > 0)
|
||||
{
|
||||
setTimeout(function(){ output.innerHTML=""}, timeout);
|
||||
}
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<%+wireguard/ovpn_css%>
|
||||
|
||||
<div class="cbi-section-node">
|
||||
<div class="table cbi-section-table">
|
||||
<h4><%:Template based configuration%></h4>
|
||||
<div class="tr cbi-section-table-row" id="div_add">
|
||||
<div class="td left">
|
||||
<input type="text" maxlength="20" placeholder="Instance name" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.text" id="instance_name1" />
|
||||
</div>
|
||||
<div class="td left">
|
||||
<select id="instance_template" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.select">
|
||||
<option value="" selected="selected" disabled="disabled"><%:Select template ...%></option>
|
||||
<%- for k, v in luci.util.kspairs(self.add_select_options) do %>
|
||||
<option value="<%=k%>"><%=luci.xml.pcdata(v)%></option>
|
||||
<% end -%>
|
||||
</select>
|
||||
</div>
|
||||
<div class="td left">
|
||||
<input class="cbi-button cbi-button-add" type="submit" onclick="vpn_add(); return false;" value="<%:Add%>" title="<%:Add template based configuration%>" /><br />
|
||||
</div>
|
||||
</div>
|
||||
<h4><%:Conf configuration file upload%></h4>
|
||||
<div class="tr cbi-section-table-row" id="div_upload">
|
||||
<div class="td left">
|
||||
<input type="text" maxlength="20" placeholder="Instance name" name="instance_name2" id="instance_name2" />
|
||||
</div>
|
||||
<div class="td left">
|
||||
<input type="file" name="ovpn_file" id="ovpn_file" accept="application/x-wireguard-profile,.conf" />
|
||||
</div>
|
||||
<div class="td left">
|
||||
<input class="cbi-button cbi-button-add" type="submit" onclick="vpn_upload(); return false;" value="<%:Upload%>" title="<%:Upload conf file%>" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="vpn-output">
|
||||
<span id="vpn_output"></span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,27 @@
|
||||
<script type="text/javascript" src="<%=resource%>/xhr.js"></script>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
|
||||
function generateconf()
|
||||
{
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "generateconf")%>',
|
||||
null,
|
||||
function(x, rv)
|
||||
{
|
||||
window.open('http://'+window.location.hostname+'/package/wgconf.tar.gz', '_self')
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//]]></script>
|
||||
|
||||
<fieldset class="cbi-section" id="cbi-family">
|
||||
<table width="550" border="0">
|
||||
<tr>
|
||||
<td width="20%"> </td>
|
||||
<td width="17%"><input type="button" type="submit" id="generate" class="cbi-button cbi-button-apply" value="<%:Generate Conf Files%>" onclick="return generateconf()" /></td>
|
||||
<td width="17%"> </td>
|
||||
<td width="46%"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
@@ -0,0 +1,38 @@
|
||||
<style type="text/css">
|
||||
h4
|
||||
{
|
||||
white-space: nowrap;
|
||||
border-bottom: 0px;
|
||||
margin: 10px 5px 5px 5px;
|
||||
}
|
||||
.tr
|
||||
{
|
||||
border: 0px;
|
||||
text-align: left;
|
||||
}
|
||||
.vpn-output
|
||||
{
|
||||
box-shadow: none;
|
||||
margin: 10px 5px 5px 5px;
|
||||
color: #a22;
|
||||
}
|
||||
textarea
|
||||
{
|
||||
border: 1px solid #cccccc;
|
||||
padding: 5px;
|
||||
font-size: 12px;
|
||||
font-family: monospace;
|
||||
resize: none;
|
||||
white-space: pre;
|
||||
overflow-wrap: normal;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
a
|
||||
{
|
||||
line-height: 1.5;
|
||||
}
|
||||
hr
|
||||
{
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,30 @@
|
||||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%+openvpn/ovpn_css%>
|
||||
|
||||
<div class="cbi-section">
|
||||
<h3>
|
||||
<a href="<%=url('admin/vpn/wireguard')%>"><%:Overview%></a> »
|
||||
<%=luci.i18n.translatef("Instance \"%s\"", self.instance)%>
|
||||
</h3>
|
||||
<% if self.mode == "basic" then %>
|
||||
<a href="<%=url('admin/vpn/wireguard/advanced', self.instance, "Service")%>"><%:Switch to advanced configuration%> »</a><p/>
|
||||
<hr />
|
||||
<% elseif self.mode == "advanced" then %>
|
||||
<a href="<%=url('admin/vpn/wireguard/basic', self.instance)%>"><%:Switch to basic configuration%> »</a><p/>
|
||||
<hr />
|
||||
<%:Configuration category%>:
|
||||
<% for i, c in ipairs(self.categories) do %>
|
||||
<% if c == self.category then %>
|
||||
<strong><%=translate(c)%></strong>
|
||||
<% else %>
|
||||
<a href="<%=luci.dispatcher.build_url("admin", "vpn", "wireguard", "advanced", self.instance, c)%>"><%=translate(c)%></a>
|
||||
<% end %>
|
||||
<% if next(self.categories, i) then %>|<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
@@ -0,0 +1,61 @@
|
||||
<%
|
||||
|
||||
%>
|
||||
<script type="text/javascript" src="<%=resource%>/xhr.js"></script>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
|
||||
function uploadc(btn)
|
||||
{
|
||||
var conf = document.getElementById("conf").value;
|
||||
if ( conf == "" )
|
||||
{
|
||||
alert("<%:You must enter a Conf file!!%>");
|
||||
return false;
|
||||
}
|
||||
var iname = document.getElementById("iname").value;
|
||||
if ( iname == "" )
|
||||
{
|
||||
alert("<%:You must enter an Instance name!!%>");
|
||||
return false;
|
||||
}
|
||||
var boot = document.getElementById('boot').checked;
|
||||
bootn = "0";
|
||||
if ( boot == true )
|
||||
{
|
||||
bootn= "1";
|
||||
}
|
||||
confile = bootn + "?" + iname + "?" + conf +"\n?";
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "textconf")%>',
|
||||
{ set: confile },
|
||||
function(x, rv)
|
||||
{
|
||||
window.location.reload(false);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
//]]></script>
|
||||
|
||||
<fieldset class="cbi-section" id="cbi-family">
|
||||
<legend><%:Paste Configuration File Here%></legend>
|
||||
<table id="ctxt" width="700" border="0" style="display:table;">
|
||||
<tr>
|
||||
<td width="50%">
|
||||
<textarea name="conf" id="conf" rows="10" style="width: 600px;" maxlength="1000"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table id="btxt" width="700" border="0" style="display:table;">
|
||||
<tr>
|
||||
<td width="10%"><input type="button" id="apply1" class="cbi-button cbi-button-apply" value="<%:Upload Conf File%>" onclick="return uploadc(this)" /></td>
|
||||
|
||||
<td width="10%"><div align="right"><strong><%:Instance Name : %></strong></div></td>
|
||||
<td width="12%"><input type="text" name="iname" id="iname" class="cbi-input-text" style="width: 150px;" maxlength="100" value="SardisTel"></input></td>
|
||||
<td width="10%"><div align="right"><strong><%:Start on Boot : %></strong></div></td>
|
||||
<td width="8%">
|
||||
<input type="checkbox" id="boot" checked />
|
||||
</td>
|
||||
<td width="50%"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
@@ -0,0 +1,228 @@
|
||||
<%#
|
||||
Copyright 2016-2017 Dan Luedtke <mail@danrl.com>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%
|
||||
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
|
||||
function bytes_to_str(bytes) {
|
||||
bytes = parseFloat(bytes);
|
||||
if (bytes < 1) { return "0 B"; }
|
||||
var sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'];
|
||||
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
|
||||
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
|
||||
};
|
||||
|
||||
function timestamp_to_str(timestamp) {
|
||||
if (timestamp < 1) {
|
||||
return '<%:Never%>';
|
||||
}
|
||||
var now = new Date();
|
||||
var seconds = (now.getTime() / 1000) - timestamp;
|
||||
var ago = "";
|
||||
if (seconds < 60) {
|
||||
ago = parseInt(seconds) + '<%:s ago%>';
|
||||
} else if (seconds < 3600) {
|
||||
ago = parseInt(seconds / 60) + '<%:m ago%>';
|
||||
} else if (seconds < 86401) {
|
||||
ago = parseInt(seconds / 3600) + '<%:h ago%>';
|
||||
} else {
|
||||
ago = '<%:over a day ago%>';
|
||||
}
|
||||
var t = new Date(timestamp * 1000);
|
||||
return t.toUTCString() + ' (' + ago + ')';
|
||||
}
|
||||
|
||||
|
||||
XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "vpn", "wirestatus")%>', null,
|
||||
function(x, data) {
|
||||
both = {};
|
||||
bothbp={};
|
||||
iii = 1;
|
||||
for (var key in data) {
|
||||
if (!data.hasOwnProperty(key)) { continue; }
|
||||
var ifname = key;
|
||||
var iface = data[key];
|
||||
|
||||
var s = "";
|
||||
if (iface.public_key == '(none)') {
|
||||
s += '<em><%:Interface does not have a public key!%></em>';
|
||||
} else {
|
||||
s += String.format(
|
||||
'<strong><%:Public Key%>: </strong>%s',
|
||||
iface.public_key
|
||||
);
|
||||
}
|
||||
if (iface.listen_port > 0) {
|
||||
s += String.format(
|
||||
'<br /><strong><%:Listen Port%>: </strong>%s',
|
||||
iface.listen_port
|
||||
);
|
||||
}
|
||||
if (iface.fwmark != 'off') {
|
||||
s += String.format(
|
||||
'<br /><strong><%:Firewall Mark%>: </strong>%s',
|
||||
iface.fwmark
|
||||
);
|
||||
}
|
||||
if ( iii == 1 )
|
||||
{
|
||||
document.getElementById("iinfo").innerHTML = s;
|
||||
document.getElementById("leg").innerHTML = ifname;
|
||||
}
|
||||
else
|
||||
{
|
||||
document.getElementById("iinfo1").innerHTML = s;
|
||||
document.getElementById("leg1").innerHTML = ifname;
|
||||
}
|
||||
for (var i = 0, ilen = iface.peers.length; i < ilen; i++) {
|
||||
var peer = iface.peers[i];
|
||||
var s = String.format(
|
||||
'<strong><%:Public Key%>: </strong>%s',
|
||||
peer.public_key
|
||||
);
|
||||
if (peer.endpoint != '(none)') {
|
||||
s += String.format(
|
||||
'<br /><strong><%:Endpoint%>: </strong>%s',
|
||||
peer.endpoint
|
||||
);
|
||||
}
|
||||
if (peer.allowed_ips.length > 0) {
|
||||
s += '<br /><strong><%:Allowed IPs%>:</strong>';
|
||||
for (var k = 0, klen = peer.allowed_ips.length; k < klen; k++) {
|
||||
s += '<br /> • ' + peer.allowed_ips[k];
|
||||
}
|
||||
}
|
||||
if (peer.persistent_keepalive != 'off') {
|
||||
s += String.format(
|
||||
'<br /><strong><%:Persistent Keepalive%>: </strong>%ss',
|
||||
peer.persistent_keepalive
|
||||
);
|
||||
}
|
||||
var icon = '<img src="<%=resource%>/icons/wireguard_disabled.png" />';
|
||||
var now = new Date();
|
||||
if (((now.getTime() / 1000) - peer.latest_handshake) < 140) {
|
||||
icon = '<img src="<%=resource%>/icons/wireguard.png" />';
|
||||
}
|
||||
s += String.format(
|
||||
'<br /><strong><%:Latest Handshake%>: </strong>%s',
|
||||
timestamp_to_str(peer.latest_handshake)
|
||||
);
|
||||
s += String.format(
|
||||
'<br /><strong><%:Data Received%>: </strong>%s' +
|
||||
'<br /><strong><%:Data Transmitted%>: </strong>%s',
|
||||
bytes_to_str(peer.transfer_rx),
|
||||
bytes_to_str(peer.transfer_tx)
|
||||
);
|
||||
if ( iii == 1 )
|
||||
{
|
||||
document.getElementById("config").innerHTML = icon;
|
||||
document.getElementById("info").innerHTML = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
document.getElementById("config1").innerHTML = icon;
|
||||
document.getElementById("info1").innerHTML = s;
|
||||
}
|
||||
}
|
||||
iii = iii + 1;
|
||||
}
|
||||
});
|
||||
//]]></script>
|
||||
|
||||
<h2><%:WireGuard Status%></h2>
|
||||
|
||||
<fieldset class="cbi-section">
|
||||
|
||||
<div>
|
||||
<table width="900" border="0">
|
||||
<tr>
|
||||
<td width="50px" style="vertical-align:center;font-size : 25px">
|
||||
<div><%:Interface %></div>
|
||||
</td>
|
||||
<td width="100px" id="leg" style="width:100px; text-align:left; padding:3px;font-size : 25px"> </td>
|
||||
<td width="650px"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<table width="900" border="0">
|
||||
<tr>
|
||||
<td width="20px"> </td>
|
||||
<td width="150px" style="vertical-align:center;font-size : 20px">
|
||||
<div><%:Configuration%></div>
|
||||
</td>
|
||||
<td width="100px" id="config" style="width:16px; text-align:center; padding:3px"> </td>
|
||||
<td width="50px"> </td>
|
||||
<td width="580px">
|
||||
<div id="info" style="vertical-align:middle; padding: 3px">
|
||||
<em><%:Collecting data...%></em>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td style="vertical-align:center;font-size : 20px">
|
||||
<div><%:Peer%></div>
|
||||
</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
<td>
|
||||
<div id="iinfo" style="vertical-align:middle; padding: 3px">
|
||||
<em><%:Collecting data...%></em>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table width="900" border="0" id="second1">
|
||||
<tr>
|
||||
<td width="50px" style="vertical-align:center;font-size : 25px">
|
||||
<div><%:Interface %></div>
|
||||
</td>
|
||||
<td width="100px" id="leg1" style="width:100px; text-align:left; padding:3px;font-size : 25px"> </td>
|
||||
<td width="650px"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<table width="900" border="0" id="second">
|
||||
<tr>
|
||||
<td width="20px"> </td>
|
||||
<td width="150px" style="vertical-align:center;font-size : 20px">
|
||||
<div><%:Configuration%></div>
|
||||
</td>
|
||||
<td width="100px" id="config1" style="width:16px; text-align:center; padding:3px"> </td>
|
||||
<td width="50px"> </td>
|
||||
<td width="580px">
|
||||
<div id="info1" style="vertical-align:middle; padding: 3px">
|
||||
<em><%:Collecting data...%></em>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td style="vertical-align:center;font-size : 20px">
|
||||
<div><%:Peer%></div>
|
||||
</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
<td>
|
||||
<div id="iinfo1" style="vertical-align:middle; padding: 3px">
|
||||
<em><%:Collecting data...%></em>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--
|
||||
<table id="cmdtxt" width="700" border="0" style="display:table;">
|
||||
<tr>
|
||||
<td width="100%">
|
||||
<textarea readonly="readonly" name="attxt" id="attxt" rows="6" style="width: 600px;" maxlength="160"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table> -->
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
|
||||
134
ipk-source/luci-app-go-wireguard/root/usr/lib/wireguard/conf.sh
Executable file
134
ipk-source/luci-app-go-wireguard/root/usr/lib/wireguard/conf.sh
Executable file
@@ -0,0 +1,134 @@
|
||||
#!/bin/sh
|
||||
|
||||
log() {
|
||||
modlog "Wireguard Conf" "$@"
|
||||
}
|
||||
|
||||
name=$1
|
||||
file=$2
|
||||
auto=$3
|
||||
if [ -z $auto ]; then
|
||||
auto="0"
|
||||
fi
|
||||
|
||||
extract() {
|
||||
line=$1
|
||||
PD=$(echo "$line" | grep "#")
|
||||
if [ ! -z "$PD" ]; then
|
||||
return
|
||||
fi
|
||||
PRK=$(echo "$line" | grep "PrivateKey" | tr " " ",")
|
||||
if [ ! -z "$PRK" ]; then
|
||||
PrivateKey=$(echo $PRK | cut -d, -f3)
|
||||
fi
|
||||
PRK=$(echo "$line" | grep "PublicKey" | tr " " ",")
|
||||
if [ ! -z "$PRK" ]; then
|
||||
PublicKey=$(echo $PRK | cut -d, -f3)
|
||||
fi
|
||||
PRK=$(echo "$line" | grep "PresharedKey" | tr " " ",")
|
||||
if [ ! -z "$PRK" ]; then
|
||||
PreSharedKey=$(echo $PRK | cut -d, -f3)
|
||||
fi
|
||||
INTER=$(echo "$line" | grep "WGinterface" | tr " " ",")
|
||||
if [ ! -z "$INTER" ]; then
|
||||
wginter=$(echo $INTER | cut -d, -f3)
|
||||
if [ "$wginter" -gt 1 ]; then
|
||||
wginter="1"
|
||||
fi
|
||||
fi
|
||||
PRK=$(echo "$line" | grep "Address" | tr " " "#")
|
||||
if [ ! -z "$PRK" ]; then
|
||||
if [ -z $Address ]; then
|
||||
Address=$(echo $PRK | cut -d# -f3)
|
||||
else
|
||||
Address=$Address","$(echo $PRK | cut -d# -f3)
|
||||
fi
|
||||
fi
|
||||
PRK=$(echo "$line" | grep "dns" | tr " " "#")
|
||||
if [ ! -z "$PRK" ]; then
|
||||
dns=$(echo $PRK | cut -d# -f3)
|
||||
fi
|
||||
PRK=$(echo "$line" | grep "DNS" | tr " " "#")
|
||||
if [ ! -z "$PRK" ]; then
|
||||
dns=$(echo $PRK | cut -d# -f3)
|
||||
fi
|
||||
PRK=$(echo "$line" | grep "ListenPort" | tr " " ",")
|
||||
if [ ! -z "$PRK" ]; then
|
||||
listenport=$(echo $PRK | cut -d, -f3)
|
||||
fi
|
||||
PRK=$(echo "$line" | grep "AllowedIPs" | tr " " "#")
|
||||
if [ ! -z "$PRK" ]; then
|
||||
if [ -z $allowedips ]; then
|
||||
allowedips=$(echo $PRK | cut -d# -f3)
|
||||
else
|
||||
allowedips=$allowedips","$(echo $PRK | cut -d# -f3)
|
||||
fi
|
||||
fi
|
||||
PRK=$(echo "$line" | grep "Endpoint" | tr " " ",")
|
||||
if [ ! -z "$PRK" ]; then
|
||||
endpoint=$(echo $PRK | cut -d, -f3)
|
||||
fi
|
||||
MTU=$(echo "$line" | grep "MTU" | tr " " ",")
|
||||
if [ ! -z "$MTU" ]; then
|
||||
mtu=$(echo $MTU | cut -d, -f3)
|
||||
fi
|
||||
}
|
||||
|
||||
listenport="51280"
|
||||
dns=""
|
||||
sed -i -e "s!PrivateKey= !PrivateKey=!g" $file
|
||||
sed -i -e "s!PrivateKey=!PrivateKey = !g" $file
|
||||
sed -i -e "s!PublicKey= !PublicKey=!g" $file
|
||||
sed -i -e "s!PublicKey=!PublicKey = !g" $file
|
||||
sed -i -e "s!PresharedKey= !PresharedKey=!g" $file
|
||||
sed -i -e "s!PresharedKey=!PresharedKey = !g" $file
|
||||
sed -i -e "s!Address= !Address=!g" $file
|
||||
sed -i -e "s!Address=!Address = !g" $file
|
||||
sed -i -e "s!WGinterface=!WGinterface = !g" $file
|
||||
sed -i -e "s!WGinterface= !WGinterface = !g" $file
|
||||
sed -i -e "s!dns= !dns=!g" $file
|
||||
sed -i -e "s!dns=!dns = !g" $file
|
||||
sed -i -e "s!DNS= !DNS=!g" $file
|
||||
sed -i -e "s!DNS=!DNS = !g" $file
|
||||
sed -i -e "s!ListenPort= !ListenPort=!g" $file
|
||||
sed -i -e "s!ListenPort=!ListenPort = !g" $file
|
||||
sed -i -e "s!AllowedIPs= !AllowedIPs=!g" $file
|
||||
sed -i -e "s!AllowedIPs=!AllowedIPs = !g" $file
|
||||
sed -i -e "s!Endpoint= !Endpoint=!g" $file
|
||||
sed -i -e "s!Endpoint=!Endpoint = !g" $file
|
||||
sed -i -e "s!MTU= !MTU=!g" $file
|
||||
sed -i -e "s!MTU=!MTU = !g" $file
|
||||
|
||||
while IFS= read -r linex
|
||||
do
|
||||
extract "$linex"
|
||||
done < $file
|
||||
extract "$linex"
|
||||
PRK=$(echo "$endpoint" | tr ":" ",")
|
||||
endpoint=$(echo $PRK | cut -d, -f1)
|
||||
sport=$(echo $PRK | cut -d, -f2)
|
||||
if [ -z "$wginter" ]; then
|
||||
wginter="0"
|
||||
fi
|
||||
uci delete wireguard.$name
|
||||
uci set wireguard.$name=wireguard
|
||||
uci set wireguard.$name.auto=$auto
|
||||
uci set wireguard.$name.client="1"
|
||||
uci set wireguard.$name.active="0"
|
||||
uci set wireguard.$name.privatekey="$PrivateKey"
|
||||
uci set wireguard.$name.presharedkey="$PreSharedKey"
|
||||
uci set wireguard.$name.port="$listenport"
|
||||
uci set wireguard.$name.addresses="$Address"
|
||||
uci set wireguard.$name.dns="$dns"
|
||||
uci set wireguard.$name.wginter="$wginter"
|
||||
uci set wireguard.$name.publickey="$PublicKey"
|
||||
uci set wireguard.$name.endpoint_host="$endpoint"
|
||||
uci set wireguard.$name.ips="$allowedips"
|
||||
uci set wireguard.$name.name="$name"
|
||||
uci set wireguard.$name.sport="$sport"
|
||||
uci set wireguard.$name.mtu="$mtu"
|
||||
uci set wireguard.$name.persistent_keepalive='25'
|
||||
uci commit wireguard
|
||||
|
||||
rm -f $file
|
||||
|
||||
81
ipk-source/luci-app-go-wireguard/root/usr/lib/wireguard/create.sh
Executable file
81
ipk-source/luci-app-go-wireguard/root/usr/lib/wireguard/create.sh
Executable file
@@ -0,0 +1,81 @@
|
||||
#!/bin/sh
|
||||
. /lib/functions.sh
|
||||
|
||||
log() {
|
||||
logger -t "Wireguard Conf" "$@"
|
||||
}
|
||||
|
||||
WG=$(cat /tmp/wginst)
|
||||
|
||||
do_create() {
|
||||
local config=$1
|
||||
|
||||
config_get name $config name
|
||||
if [ -z $name ]; then
|
||||
name=$config
|
||||
fi
|
||||
|
||||
echo "----Start Conf File for "$name" ----" >> ${PKI_DIR}/package/wg.conf
|
||||
echo "[Interface]" >> ${PKI_DIR}/package/wg.conf
|
||||
config_get privatekey $config privatekey
|
||||
echo "PrivateKey = "$privatekey >> ${PKI_DIR}/package/wg.conf
|
||||
config_get address $config address
|
||||
echo "Address = "$address >> ${PKI_DIR}/package/wg.conf
|
||||
config_get endpoint_port $config endpoint_port
|
||||
if [ ! -z $endpoint_port ]; then
|
||||
echo "ListenPort = "$endpoint_port >> ${PKI_DIR}/package/wg.conf
|
||||
fi
|
||||
config_get dns $config dns
|
||||
if [ ! -z $dns ]; then
|
||||
echo "DNS = "$dns >> ${PKI_DIR}/package/wg.conf
|
||||
fi
|
||||
config_get mtu $config mtu
|
||||
if [ ! -z $mtu ]; then
|
||||
echo "MTU = "$mtu >> ${PKI_DIR}/package/wg.conf
|
||||
fi
|
||||
config_get wginter $config wginter
|
||||
if [ -z"$wginter"]; then
|
||||
wginter=0
|
||||
fi
|
||||
#echo "PrivateKey = "$wginter >> ${PKI_DIR}/package/wg.conf
|
||||
echo " " >> ${PKI_DIR}/package/wg.conf
|
||||
echo "[Peer]" >> ${PKI_DIR}/package/wg.conf
|
||||
PUB=$(uci get wireguard."$WG".publickey)
|
||||
echo "PublicKey = "$PUB >> ${PKI_DIR}/package/wg.conf
|
||||
USE=$(uci get wireguard."$WG".usepre)
|
||||
if [ $USE = "1" ]; then
|
||||
PRE=$(uci get wireguard."$WG".presharedkey)
|
||||
echo "PresharedKey = "$PRE >> ${PKI_DIR}/package/wg.conf
|
||||
fi
|
||||
HOST=$(uci get wireguard."$WG".endpoint_host)
|
||||
PORT=$(uci get wireguard."$WG".port)
|
||||
if [ ! -z $PORT ]; then
|
||||
HOST=$HOST":"$PORT
|
||||
fi
|
||||
echo "Endpoint = "$HOST >> ${PKI_DIR}/package/wg.conf
|
||||
config_get allowed_ips $config allowed_ips
|
||||
echo "AllowedIPs = "$allowed_ips >> ${PKI_DIR}/package/wg.conf
|
||||
echo "----EndConf File for "$name" ----" >> ${PKI_DIR}/package/wg.conf
|
||||
echo " " >> ${PKI_DIR}/package/wg.conf
|
||||
}
|
||||
|
||||
#PKI_DIR="/tmp/wireguard"
|
||||
PKI_DIR="/www"
|
||||
#rm -rfv "$PKI_DIR"
|
||||
#mkdir -p ${PKI_DIR}
|
||||
#chmod -R 0777 ${PKI_DIR}
|
||||
cd ${PKI_DIR}
|
||||
mkdir -p package
|
||||
cd ..
|
||||
chmod -R 0777 ${PKI_DIR}/package
|
||||
#rm -rfv "/www/package"
|
||||
#ln -s ${PKI_DIR}/package /www/package
|
||||
|
||||
|
||||
rm -f ${PKI_DIR}/package/wg.conf
|
||||
config_load wireguard
|
||||
config_foreach do_create custom$WG
|
||||
|
||||
cd ${PKI_DIR}/package
|
||||
|
||||
tar -czf wgconf.tar.gz wg.conf
|
||||
68
ipk-source/luci-app-go-wireguard/root/usr/lib/wireguard/keygen.sh
Executable file
68
ipk-source/luci-app-go-wireguard/root/usr/lib/wireguard/keygen.sh
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/bin/sh
|
||||
. /lib/functions.sh
|
||||
|
||||
log() {
|
||||
modlog "Wireguard KeyGen" "$@"
|
||||
}
|
||||
|
||||
WG=$1
|
||||
|
||||
ww=$(echo "$WG" | grep "https")
|
||||
if [ ! -z "$ww" ]; then
|
||||
exit 0
|
||||
fi
|
||||
echo "$WG" > /tmp/wginst
|
||||
|
||||
sleep 5
|
||||
|
||||
EXST=$(uci get wireguard."$WG")
|
||||
if [ -z $EXST ]; then
|
||||
uci set wireguard."$WG"="wireguard"
|
||||
uci commit wireguard
|
||||
fi
|
||||
|
||||
PRIV=$(uci get wireguard."$WG".privatekey)
|
||||
if [ -z $PRIV ]; then
|
||||
umask u=rw,g=,o=
|
||||
wg genkey | tee /tmp/wgserver.key | wg pubkey > /tmp/wgclient.pub
|
||||
wg genpsk > /tmp/wg.psk
|
||||
|
||||
WG_KEY="$(cat /tmp/wgserver.key)" # private key
|
||||
WG_PSK="$(cat /tmp/wg.psk)" # shared key
|
||||
WG_PUB="$(cat /tmp/wgclient.pub)" # public key to be used on other end
|
||||
rm -f /tmp/wgserver.key
|
||||
rm -f /tmp/wg.psk
|
||||
rm -f /tmp/wgclient.pub
|
||||
uci set wireguard."$WG".privatekey=$WG_KEY
|
||||
uci set wireguard."$WG".publickey=$WG_PUB
|
||||
uci set wireguard."$WG".presharedkey=$WG_PSK
|
||||
uci commit wireguard
|
||||
fi
|
||||
|
||||
do_custom() {
|
||||
local config=$1
|
||||
|
||||
config_get privatekey $config privatekey
|
||||
if [ -z "$privatekey" ]; then
|
||||
umask u=rw,g=,o=
|
||||
wg genkey | tee /tmp/wgserver.key | wg pubkey > /tmp/wgclient.pub
|
||||
wg genpsk > /tmp/wg.psk
|
||||
|
||||
WG_KEY="$(cat /tmp/wgserver.key)" # private key
|
||||
WG_PSK="$(cat /tmp/wg.psk)" # shared key
|
||||
WG_PUB="$(cat /tmp/wgclient.pub)" # public key to be used on other end
|
||||
rm -f /tmp/wgserver.key
|
||||
rm -f /tmp/wg.psk
|
||||
rm -f /tmp/wgclient.pub
|
||||
log "$WG_KEY"
|
||||
uci set wireguard."$config".privatekey=$WG_KEY
|
||||
uci set wireguard."$config".publickey=$WG_PUB
|
||||
uci set wireguard."$config".presharedkey=$WG_PSK
|
||||
uci set wireguard."$config".persistent_keepalive='25'
|
||||
uci set wireguard."$config".route_allowed_ips='1'
|
||||
fi
|
||||
}
|
||||
|
||||
config_load wireguard
|
||||
config_foreach do_custom custom$WG
|
||||
uci commit wireguard
|
||||
328
ipk-source/luci-app-go-wireguard/root/usr/lib/wireguard/startvpn.sh
Executable file
328
ipk-source/luci-app-go-wireguard/root/usr/lib/wireguard/startvpn.sh
Executable file
@@ -0,0 +1,328 @@
|
||||
#!/bin/sh
|
||||
. /lib/functions.sh
|
||||
|
||||
log() {
|
||||
logger -t "Wireguard Start" "$@"
|
||||
}
|
||||
|
||||
WG=$1
|
||||
|
||||
chk_zone() {
|
||||
local config=$1
|
||||
|
||||
config_get src $config src
|
||||
config_get dest $config dest
|
||||
if [ $src = "lan" -a $dest = "wan" ]; then
|
||||
uci set firewall."$config".dest="wg"
|
||||
uci commit firewall
|
||||
fi
|
||||
}
|
||||
|
||||
do_dns() {
|
||||
cdns=$1
|
||||
local ifce=$2
|
||||
ldns=$(uci -q get network.wg$ifce.dns)
|
||||
ex=$(echo "$ldns" | grep "$cdns")
|
||||
if [ -z $ex ]; then
|
||||
log "Add DNS $cdns to WG$ifce"
|
||||
uci add_list network.wg$ifce.dns="$cdns"
|
||||
uci commit network
|
||||
/etc/init.d/network reload
|
||||
fi
|
||||
}
|
||||
|
||||
do_port() {
|
||||
PORT=$1
|
||||
udp=$2
|
||||
# look for rule for this port
|
||||
INB="inbound"$PORT$udp
|
||||
RULE=$(uci -q get firewall.$INB)
|
||||
if [ -z $RULE ]; then
|
||||
uci set firewall.$INB=rule
|
||||
uci set firewall.$INB.name=$INB
|
||||
uci set firewall.$INB.target=ACCEPT
|
||||
uci set firewall.$INB.src=*
|
||||
uci set firewall.$INB.proto=$udp
|
||||
uci set firewall.$INB.dest_port=$PORT
|
||||
uci commit firewall
|
||||
/etc/init.d/firewall reload
|
||||
fi
|
||||
}
|
||||
|
||||
do_delete() {
|
||||
local config=$1
|
||||
|
||||
uci delete network.$1
|
||||
}
|
||||
|
||||
create_speer() {
|
||||
local config=$1
|
||||
|
||||
uci set network.$config="wireguard_wg1"
|
||||
|
||||
config_get persistent_keepalive $config persistent_keepalive
|
||||
uci set network.$config.persistent_keepalive="$persistent_keepalive"
|
||||
config_get route_allowed_ips $config route_allowed_ips
|
||||
uci set network.$config.route_allowed_ips="$route_allowed_ips"
|
||||
config_get publickey $config publickey
|
||||
uci set network.$config.public_key="$publickey"
|
||||
usepre=$(uci -q get wireguard.$WG.usepre)
|
||||
log "$usepre"
|
||||
if [ $usepre = "1" ]; then
|
||||
presharedkey=$(uci -q get wireguard.$WG.presharedkey)
|
||||
log "$presharedkey"
|
||||
uci set network.$config.preshared_key="$presharedkey"
|
||||
fi
|
||||
config_get allowed_ips $config allowed_ips
|
||||
allowed_ips=$allowed_ips","
|
||||
ips=$(echo $allowed_ips | cut -d, -f1)
|
||||
i=1
|
||||
while [ ! -z $ips ]
|
||||
do
|
||||
uci add_list network.$config.allowed_ips="$ips"
|
||||
i=$((i+1))
|
||||
ips=$(echo $allowed_ips | cut -d, -f$i)
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
create_cpeer() {
|
||||
local config=$1
|
||||
local ifce=$2
|
||||
|
||||
uci set network.$config="wireguard_wg$ifce"
|
||||
|
||||
publickey=$(uci -q get wireguard."$config".publickey)
|
||||
uci set network.$config.public_key="$publickey"
|
||||
presharedkey=$(uci -q get wireguard."$WG".presharedkey)
|
||||
if [ ! -z $presharedkey ]; then
|
||||
uci set network.$config.preshared_key="$presharedkey"
|
||||
fi
|
||||
persistent_keepalive=$(uci -q get wireguard."$config".persistent_keepalive)
|
||||
if [ -z $persistent_keepalive ]; then
|
||||
persistent_keepalive=25
|
||||
fi
|
||||
uci set network.$config.persistent_keepalive="$persistent_keepalive"
|
||||
route_allowed_ips=1
|
||||
uci set network.$config.route_allowed_ips="$route_allowed_ips"
|
||||
|
||||
if [ $UDP = 1 ]; then
|
||||
endpoint_host="127.0.0.1"
|
||||
uci set network.$config.endpoint_host="$endpoint_host"
|
||||
sport=$(uci -q get wireguard."$config".port)
|
||||
if [ -z $sport ]; then
|
||||
sport="54321"
|
||||
fi
|
||||
uci set network.$config.endpoint_port="$sport"
|
||||
else
|
||||
endpoint_host=$(uci -q get wireguard."$config".endpoint_host)
|
||||
uci set network.$config.endpoint_host="$endpoint_host"
|
||||
sport=$(uci -q get wireguard."$config".sport)
|
||||
if [ -z $sport ]; then
|
||||
sport="51280"
|
||||
fi
|
||||
uci set network.$config.endpoint_port="$sport"
|
||||
fi
|
||||
|
||||
ips=$(uci -q get wireguard."$config".ips)","
|
||||
cips=$(echo $ips | cut -d, -f1)
|
||||
i=1
|
||||
while [ ! -z $cips ]
|
||||
do
|
||||
uci add_list network.$config.allowed_ips="$cips"
|
||||
i=$((i+1))
|
||||
cips=$(echo $ips | cut -d, -f$i)
|
||||
done
|
||||
}
|
||||
|
||||
handle_server() {
|
||||
config_foreach do_delete wireguard_wg1
|
||||
|
||||
uci delete network.wg1
|
||||
uci set network.wg1="interface"
|
||||
uci set network.wg1.proto="wireguard"
|
||||
|
||||
auto=$(uci -q get wireguard."$WG".auto)
|
||||
if [ -z $auto ]; then
|
||||
auto="0"
|
||||
fi
|
||||
uci set network.wg1.auto="$auto"
|
||||
|
||||
port=$(uci -q get wireguard."$WG".port)
|
||||
if [ -z $port ]; then
|
||||
port="51280"
|
||||
fi
|
||||
uci set network.wg1.listen_port="$port"
|
||||
do_port $port udp
|
||||
|
||||
privatekey=$(uci -q get wireguard."$WG".privatekey)
|
||||
uci set network.wg1.private_key="$privatekey"
|
||||
|
||||
ips=$(uci -q get wireguard."$WG".addresses)","
|
||||
cips=$(echo $ips | cut -d, -f1)
|
||||
i=1
|
||||
while [ ! -z $cips ]
|
||||
do
|
||||
uci add_list network.wg1.addresses="$cips"
|
||||
i=$((i+1))
|
||||
cips=$(echo $ips | cut -d, -f"$i")
|
||||
if [ -z $cips ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
config_load wireguard
|
||||
config_foreach create_speer custom$WG
|
||||
|
||||
uci commit network
|
||||
}
|
||||
|
||||
handle_client() {
|
||||
ifce=$1
|
||||
config_foreach do_delete wireguard_wg$ifce
|
||||
|
||||
uci delete network.wg$ifce
|
||||
uci set network.wg$ifce="interface"
|
||||
uci set network.wg$ifce.proto="wireguard"
|
||||
uci set network.wg$ifce.metric="1"
|
||||
|
||||
auto=$(uci -q get wireguard."$WG".auto)
|
||||
if [ -z $auto ]; then
|
||||
auto="0"
|
||||
fi
|
||||
uci set network.wg$ifce.auto="$auto"
|
||||
mtu=$(uci -q get wireguard."$WG".mtu)
|
||||
if [ ! -z $mtu ]; then
|
||||
uci set network.wg$ifce.mtu="$mtu"
|
||||
fi
|
||||
dns=$(uci -q get wireguard."$WG".dns)
|
||||
if [ ! -z $dns ]; then
|
||||
do_dns $dns $ifce
|
||||
fi
|
||||
port=$(uci -q get wireguard."$WG".port)
|
||||
if [ -z $port ]; then
|
||||
port="51280"
|
||||
fi
|
||||
uci set network.wg$ifce.listen_port="$port"
|
||||
do_port $port udp
|
||||
|
||||
privatekey=$(uci -q get wireguard."$WG".privatekey)
|
||||
uci set network.wg$ifce.private_key="$privatekey"
|
||||
|
||||
ips=$(uci -q get wireguard."$WG".addresses)","
|
||||
cips=$(echo $ips | cut -d, -f1)
|
||||
i=1
|
||||
while [ ! -z "$cips" ]
|
||||
do
|
||||
uci add_list network.wg$ifce.addresses="$cips"
|
||||
i=$((i+1))
|
||||
cips=$(echo "$ips" | cut -d, -f"$i")
|
||||
if [ -z "$cips" ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
uci add_list network.wg$ifce.addresses="::/0"
|
||||
|
||||
create_cpeer $WG $ifce
|
||||
|
||||
uci commit network
|
||||
}
|
||||
|
||||
udp_server() {
|
||||
local config=$1
|
||||
udpport=$(uci -q get wireguard."$WG".udpport)
|
||||
if [ -z $udpport ]; then
|
||||
udpport="54321"
|
||||
fi
|
||||
port=$(uci -q get wireguard."$WG".port)
|
||||
if [ -z $port ]; then
|
||||
port="54321"
|
||||
fi
|
||||
do_port $udpport tcp
|
||||
udptunnel -s -v "0.0.0.0:"$udpport "127.0.0.1:"$port &
|
||||
#log "udptunnel -s -v 0.0.0.0:$udpport 127.0.0.1:$port"
|
||||
}
|
||||
|
||||
udp_client() {
|
||||
local config=$1
|
||||
port=$(uci -q get wireguard."$WG".port)
|
||||
if [ -z $port ]; then
|
||||
port="54321"
|
||||
fi
|
||||
endpoint_host=$(uci -q get wireguard.$WG.endpoint_host)
|
||||
sport=$(uci -q get wireguard.$WG.sport)
|
||||
if [ -z $sport ]; then
|
||||
sport="51280"
|
||||
fi
|
||||
|
||||
udptunnel "127.0.0.1:"$port $endpoint_host":"$sport &
|
||||
#log "udptunnel 127.0.0.1:$port $endpoint_host:$sport"
|
||||
}
|
||||
|
||||
forward=$(uci -q get wireguard."$WG".forward)
|
||||
if [ "$forward" != "0" ]; then
|
||||
config_load firewall
|
||||
config_foreach chk_zone forwarding
|
||||
else
|
||||
uci set firewall.wgwforward=forwarding
|
||||
uci set firewall.wgwforward.dest="wan"
|
||||
uci set firewall.wgwforward.src="wg"
|
||||
|
||||
uci set firewall.wwgforward=forwarding
|
||||
uci set firewall.wwgforward.dest="wg"
|
||||
uci set firewall.wwgforward.src="wan"
|
||||
|
||||
uci set firewall.lwgforward=forwarding
|
||||
uci set firewall.lwgforward.dest="wg"
|
||||
uci set firewall.lwgforward.src="lan"
|
||||
|
||||
uci set firewall.wglforward=forwarding
|
||||
uci set firewall.wglforward.dest="lan"
|
||||
uci set firewall.wglforward.src="wg"
|
||||
uci commit firewall
|
||||
fi
|
||||
/etc/init.d/firewall restart
|
||||
|
||||
config_load network
|
||||
SERVE=$(uci -q get wireguard."$WG".client)
|
||||
if [ $SERVE = "0" ]; then
|
||||
running=$(uci -q get wireguard.settings.server)
|
||||
if [ $running = 1 ]; then
|
||||
exit 0
|
||||
fi
|
||||
UDP=$(uci -q get wireguard."$WG".udptunnel)
|
||||
if [ $UDP = 1 ]; then
|
||||
udp_server $WG
|
||||
fi
|
||||
handle_server
|
||||
uci commit network
|
||||
ifup wg1
|
||||
sleep 2
|
||||
uci set wireguard.settings.server="1"
|
||||
else
|
||||
running=$(uci -q get wireguard.settings.client)
|
||||
log "Client running $running"
|
||||
|
||||
INTER=$(uci -q get wireguard."$WG".wginter)
|
||||
if [ -z "$INTER" ]; then
|
||||
INTER=0
|
||||
fi
|
||||
UDP=$(uci -q get wireguard."$WG".udptunnel)
|
||||
if [ $UDP = 1 ]; then
|
||||
udp_client $WG
|
||||
fi
|
||||
handle_client $INTER
|
||||
uci commit network
|
||||
log "Start Interface"
|
||||
ifup wg$INTER
|
||||
sleep 2
|
||||
uci set wireguard.settings.client="1"
|
||||
if [ -e /usr/lib/wireguard/wiremwan3.sh ]; then
|
||||
/usr/lib/wireguard/wiremwan3.sh start
|
||||
fi
|
||||
fi
|
||||
|
||||
uci set wireguard."$WG".active="1"
|
||||
uci commit wireguard
|
||||
service firewall reload
|
||||
|
||||
75
ipk-source/luci-app-go-wireguard/root/usr/lib/wireguard/stopvpn.sh
Executable file
75
ipk-source/luci-app-go-wireguard/root/usr/lib/wireguard/stopvpn.sh
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/bin/sh
|
||||
. /lib/functions.sh
|
||||
|
||||
log() {
|
||||
logger -t "Wireguard Stop" "$@"
|
||||
}
|
||||
|
||||
chk_zone() {
|
||||
local config=$1
|
||||
|
||||
config_get src $config src
|
||||
config_get dest $config dest
|
||||
if [ $src = "lan" -a $dest = "wg" ]; then
|
||||
uci set firewall."$config".dest="wan"
|
||||
uci commit firewall
|
||||
fi
|
||||
}
|
||||
|
||||
WG=$1
|
||||
|
||||
forward=$(uci -q get wireguard."$WG".forward)
|
||||
if [ "$forward" != "0" ]; then
|
||||
config_load firewall
|
||||
config_foreach chk_zone forwarding
|
||||
else
|
||||
uci delete firewall.wgwforward
|
||||
uci delete firewall.wwgforward
|
||||
uci delete firewall.lwgforward
|
||||
uci delete firewall.wglforward
|
||||
uci commit firewall
|
||||
fi
|
||||
/etc/init.d/firewall restart
|
||||
|
||||
SERVE=$(uci get wireguard."$WG".client)
|
||||
if [ $SERVE = "0" ]; then
|
||||
ifdown wg1
|
||||
uci set wireguard.settings.server="0"
|
||||
uci delete network.wg1
|
||||
uci set network.wg1=interface
|
||||
uci set network.wg1.proto="wireguard"
|
||||
uci set network.wg1.auto="0"
|
||||
uci set network.wg1.private_key=""
|
||||
uci set network.wg1.listen_port=""
|
||||
uci add_list network.wg1.addresses=""
|
||||
uci commit network
|
||||
else
|
||||
INTER=$(uci -q get wireguard."$WG".wginter)
|
||||
if [ -z "$INTER" ]; then
|
||||
INTER=0
|
||||
fi
|
||||
ifdown wg$INTER
|
||||
uci set wireguard.settings.client="0"
|
||||
uci delete network.wg$INTER
|
||||
uci set network.wg$INTER=interface
|
||||
uci set network.wg$INTER.proto="wireguard"
|
||||
uci set network.wg$INTER.auto="0"
|
||||
uci set network.wg$INTER.private_key=""
|
||||
uci set network.wg$INTER.listen_port=""
|
||||
uci add_list network.wg$INTER.addresses=""
|
||||
uci commit network
|
||||
if [ -e /usr/lib/wireguard/wiremwan3.sh ]; then
|
||||
/usr/lib/wireguard/wiremwan3.sh stop
|
||||
fi
|
||||
ifup wan
|
||||
fi
|
||||
UDP=$(uci get wireguard."$WG".udptunnel)
|
||||
if [ $UDP = 1 ]; then
|
||||
PID=$(ps |grep "udptunnel" | grep -v grep |head -n 1 | awk '{print $1}')
|
||||
kill -9 $PID
|
||||
fi
|
||||
|
||||
uci set wireguard."$WG".active="0"
|
||||
uci commit wireguard
|
||||
|
||||
/etc/init.d/wireguard stop
|
||||
19
ipk-source/luci-app-go-wireguard/root/usr/lib/wireguard/text.sh
Executable file
19
ipk-source/luci-app-go-wireguard/root/usr/lib/wireguard/text.sh
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
. /lib/functions.sh
|
||||
|
||||
log() {
|
||||
logger -t "Wireguard TextConf" "$@"
|
||||
}
|
||||
|
||||
conf1=$1
|
||||
conf=$(echo $conf1)
|
||||
conf=$(echo "$conf" | tr "?" "~")
|
||||
|
||||
boot=$(echo "$conf" | cut -d~ -f1)
|
||||
iname=$(echo "$conf" | cut -d~ -f2)
|
||||
conf=$(echo "$conf1" | tr "?" "~")
|
||||
confile=$(echo "$conf" | cut -d~ -f3)
|
||||
|
||||
echo "$confile" > /tmp/confile
|
||||
|
||||
/usr/lib/wireguard/conf.sh $iname /tmp/confile $boot
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user