Compare commits

...

269 commits

Author SHA1 Message Date
Daniel Golle
f32df8f473 luci-0.10: correct spelling on luci startup page 2013-02-26 20:47:10 +00:00
Jo-Philipp Wich
d9f43242df luci-0.10: merge r8886 2012-07-18 11:25:37 +00:00
Manuel Munz
2d7ca41abf luci-0.10: merge r8882 2012-07-09 09:53:23 +00:00
Manuel Munz
f2d09101e0 luci-0.10: Merge r8880 2012-07-09 06:25:54 +00:00
Manuel Munz
e06384a87f luci-0.10: Merge r8878 2012-07-09 06:09:38 +00:00
Manuel Munz
b0bb1bd227 luci-0.10: Merge r8876 2012-07-09 05:54:32 +00:00
Manuel Munz
75641af9bc luci-0.10: merge r8874 2012-07-09 05:50:22 +00:00
Jo-Philipp Wich
79e8ea479e contrib/package: remove erroneous roman2 i18n entry 2012-07-05 17:03:48 +00:00
Jo-Philipp Wich
2fc7e33a39 luci-0.10: merge r8794 2012-06-27 14:12:42 +00:00
Jo-Philipp Wich
cc1007d471 luci-0.10: merge r8792 2012-06-27 13:53:46 +00:00
Jo-Philipp Wich
3dff5debf2 luci-0.10: merge r8704 2012-06-26 17:23:25 +00:00
Manuel Munz
d999b68b00 luci-0.10: merge r8775 2012-06-23 09:10:06 +00:00
Manuel Munz
870fb6989f luci-0.10: Merge r8706 2012-06-18 11:14:12 +00:00
Manuel Munz
fd96871acd luci-0.10: Fix typo in profile for Franken 2012-05-03 13:20:50 +00:00
Manuel Munz
56fbd550ab luci-0.10: Merge r8669 2012-05-03 13:13:00 +00:00
Manuel Munz
73c9f6ebe9 luci-0.10: Merge r8555 2012-04-11 17:31:33 +00:00
Manuel Munz
06b466bdab luci-0.10: Merge r8512 2012-04-04 15:41:31 +00:00
Manuel Munz
ea0ec551e2 luci-0.10: olsr-services: Merge r7908 and r7926 2012-03-06 18:13:02 +00:00
Manuel Munz
7998c11592 luci-0.10: Merge r7907, r7927, r7966, r8222 2012-03-06 18:10:12 +00:00
Manuel Munz
ccfb59e20a luci-0.10: Merge r8322 2012-02-24 21:09:49 +00:00
Manuel Munz
ad612f71ec luci-0.10: Merge r8319 2012-02-21 17:03:03 +00:00
Manuel Munz
76d3cfe7e8 luci-0.10: Merge r8317 2012-02-21 16:53:15 +00:00
Manuel Munz
159f1b12db luci-0.10: Merge r8315 2012-02-21 09:42:28 +00:00
Jo-Philipp Wich
66ecb8d42e luci-0.10: merge r8220 2012-02-06 21:28:06 +00:00
Jo-Philipp Wich
4491773c61 luci-0.10: po: sync base translation 2012-01-24 21:03:26 +00:00
Jo-Philipp Wich
c1dbd33cfb luci-0.10: merge r8190 2012-01-24 21:01:16 +00:00
Jo-Philipp Wich
76e602284b luci-0.10: merge r8171 2012-01-12 12:19:13 +00:00
Jo-Philipp Wich
579975840f luci-0.10: merge r8151 2012-01-06 16:30:29 +00:00
Jo-Philipp Wich
0b6238c7f2 luci-0.10: merge r8144 2012-01-01 17:21:42 +00:00
Jo-Philipp Wich
a36434e0eb luci-0.10: merge r8142 2012-01-01 15:53:21 +00:00
Jo-Philipp Wich
47acd1bc4b luci-0.10: merge r8140 2012-01-01 15:41:44 +00:00
Jo-Philipp Wich
6de2016817 luci-0.10: merge r8137 2012-01-01 14:47:19 +00:00
Jo-Philipp Wich
8475315bac luci-0.10: merge r8135 2011-12-26 16:16:00 +00:00
Daniel Golle
52ded00a64 backport r8132 to luci-0.10 branch
modules/admin-full: fix crypto depends for ad-hoc and static wds modes (#271)
2011-12-21 23:10:59 +00:00
Jo-Philipp Wich
81aee352c0 po: sync trunc translations 2011-12-20 19:48:10 +00:00
Jo-Philipp Wich
d1710f7e0c luci-0.10: merge r8127 and r8128 2011-12-20 19:05:17 +00:00
Jo-Philipp Wich
2f6a862dc0 luci-0.10: merge r8125 2011-12-20 18:33:17 +00:00
Jo-Philipp Wich
71e73497ba luci-0.10: merge r8104 2011-12-16 06:06:26 +00:00
Jo-Philipp Wich
3cbb9b3796 luci-0.10: merge r8102 2011-12-16 05:53:11 +00:00
Jo-Philipp Wich
fe08392b7e luci-0.10: merge r8100 2011-12-16 02:11:08 +00:00
Jo-Philipp Wich
9847037963 luci-0.10: merge r8096, r8097 and r8098 2011-12-16 01:43:17 +00:00
Jo-Philipp Wich
41469346de luci-0.10: merge r8091 2011-12-14 15:03:35 +00:00
Jo-Philipp Wich
71dd8be453 luci-0.10: merge r8089 2011-12-13 15:58:08 +00:00
Jo-Philipp Wich
3055cf902d luci-0.10: merge r8087 2011-12-13 14:08:37 +00:00
Jo-Philipp Wich
5534152403 luci-0.10: merge r8084 2011-12-12 14:36:52 +00:00
Jo-Philipp Wich
86268bd4e6 luci-0.10: merge r8082 2011-12-12 14:17:35 +00:00
Jo-Philipp Wich
95157f0fd2 luci-0.10: merge r8074 2011-12-09 18:08:01 +00:00
Jo-Philipp Wich
0c58154c44 luci-0.10: merge r8072 2011-12-08 16:55:52 +00:00
Jo-Philipp Wich
459dfa8fa4 luci-0.10: merge r8070 2011-12-08 03:38:00 +00:00
Jo-Philipp Wich
cd19ee1ea6 luci-0.10: merge luci-pbx-voicemail source 2011-12-08 00:54:47 +00:00
Jo-Philipp Wich
f249d28885 luci-0.10: merge package definitions for luci-app-pbx and voicemail 2011-12-07 21:39:04 +00:00
Jo-Philipp Wich
38de51453f luci-0.10: merge luci-pbx translations 2011-12-07 21:31:05 +00:00
Jo-Philipp Wich
96a7817515 luci-0.10: merge luci-pbx source 2011-12-07 21:28:39 +00:00
Jo-Philipp Wich
63b1f034f7 luci-0.10: merge r8018 2011-12-06 11:10:08 +00:00
Jo-Philipp Wich
ac68e2aff1 luci-0.10: merge r8040 2011-12-06 11:08:12 +00:00
Jo-Philipp Wich
57370fe158 luci-0.10: merge r8053 2011-12-06 11:04:35 +00:00
Jo-Philipp Wich
5e3c4fbeac luci-0.10: merge r8046-r8051 2011-12-05 19:44:20 +00:00
Jo-Philipp Wich
07ad0dfc37 luci-0.10: merge r8045 2011-12-05 16:40:25 +00:00
Jo-Philipp Wich
f8e33488a5 luci-0.10: merge r8042 2011-12-03 14:15:02 +00:00
Jo-Philipp Wich
2f377b807f luci-0.10: merge r8034 2011-12-01 16:22:09 +00:00
Jo-Philipp Wich
a3b65997af luci-0.10: merge r7968 2011-11-20 18:21:58 +00:00
Manuel Munz
c5e4ff18b1 luci-0.10: Merge r7966 2011-11-18 17:08:03 +00:00
Jo-Philipp Wich
894d192836 luci-0Ã.10: merge r7963 2011-11-15 15:48:09 +00:00
Jo-Philipp Wich
28218e66ae luci-0Ã.10: merge r7961 2011-11-15 15:46:28 +00:00
Jo-Philipp Wich
c78825f5e6 luci-0.10: merge r7934 - r7959 2011-11-14 19:14:16 +00:00
Jo-Philipp Wich
410ee753fd luci-0.10: merge r7932 2011-11-13 22:01:19 +00:00
Jo-Philipp Wich
0ef5fe9621 luci-0.10: merge r7930 2011-11-13 21:03:50 +00:00
Jo-Philipp Wich
d883578e1e luci-0.10: merge r7924 2011-11-12 14:32:48 +00:00
Jo-Philipp Wich
4c15e9d73f luci-0.10: merge r7922 2011-11-12 11:31:03 +00:00
Jo-Philipp Wich
fdf0bc74e1 luci-0.10: merge r7919 2011-11-10 22:46:59 +00:00
Manuel Munz
ca767deb68 luci-0.10: Merge r7917 2011-11-10 13:45:04 +00:00
Manuel Munz
a048a52f84 luci-0.10: Merge rr7915 2011-11-10 12:58:10 +00:00
Manuel Munz
d2732442a0 luci-0.10: Merge r7913 2011-11-10 12:26:52 +00:00
Manuel Munz
8c97c5116f luci-0.10: Merge r7911 2011-11-10 11:41:44 +00:00
Jo-Philipp Wich
ae633a407e luci-0.10: merge r7909 2011-11-10 11:24:48 +00:00
Jo-Philipp Wich
7e74d8062f luci-0.10: merge r7905 2011-11-09 12:40:59 +00:00
Jo-Philipp Wich
426d1b6de4 luci-0.10: merge r7903 2011-11-09 11:22:59 +00:00
Jo-Philipp Wich
549477e099 luci-0.10: merge r7901 2011-11-08 23:13:13 +00:00
Jo-Philipp Wich
a5637fe149 luci-0.10: merge r7899 2011-11-08 22:35:53 +00:00
Jo-Philipp Wich
5e70d90eb6 luci-0.10: merge r7897 2011-11-08 14:06:49 +00:00
Manuel Munz
5883b736f2 luci-0.10: Merge r7895 2011-11-08 09:36:09 +00:00
Jo-Philipp Wich
9886d1a792 luci-0.10: merge r7891 2011-11-07 06:31:43 +00:00
Manuel Munz
e7d32b47e8 luci-0.10: Merge r7886 2011-11-06 17:16:06 +00:00
Jo-Philipp Wich
51dc9425b0 luci-0.10: merge r7881 2011-11-05 18:37:51 +00:00
Jo-Philipp Wich
eecff0e7aa luci-0.10: merge r7876 2011-11-03 19:47:06 +00:00
Manuel Munz
438ef2df25 luci-0.10: Merge r7874 2011-11-03 11:09:50 +00:00
Jo-Philipp Wich
271faba4db luci-0.10: merge r7872 2011-11-02 19:13:50 +00:00
Jo-Philipp Wich
1f96239c94 luci-0.10: merge r7870 2011-11-02 19:00:46 +00:00
Manuel Munz
6285f95975 luci-0.10: Merge r7868 2011-11-02 13:38:15 +00:00
Manuel Munz
7d121d1573 luci-0.10: Merge r7866 2011-11-02 10:35:03 +00:00
Manuel Munz
bcfa820625 luci-0.10: Merge latest changes to meshwizard 2011-11-02 09:20:16 +00:00
Manuel Munz
9c7ee0afc5 luci-0.10: Merge r7863 2011-11-02 08:47:44 +00:00
Jo-Philipp Wich
f60d31425e luci-0.10: merge r7860 2011-10-31 18:25:43 +00:00
Jo-Philipp Wich
98df0adb27 luci-0.10: merge r7858 2011-10-31 04:06:07 +00:00
Jo-Philipp Wich
206146b65f luci-0.10: merge r7851 2011-10-30 15:01:48 +00:00
Jo-Philipp Wich
0dd60c237b luci-0.10: merge r7849 2011-10-30 03:02:41 +00:00
Manuel Munz
adce1af3f9 luci-0.10: Merge r7846 2011-10-29 20:34:43 +00:00
Jo-Philipp Wich
d2367c3405 luci-0.10: merge r7844 2011-10-28 22:36:47 +00:00
Jo-Philipp Wich
2dc3077c5e luci-0.10: merge r7813 - r7842 2011-10-28 21:44:32 +00:00
Jo-Philipp Wich
bdf643403b luci-0.10: merge r7811 2011-10-28 19:21:12 +00:00
Jo-Philipp Wich
eda5b4becd luci-0.10: sync with trunk, drop broken and unfinished applications 2011-10-28 15:15:27 +00:00
Manuel Munz
94f2ebc329 luci-0.10: Merge r7739 2011-10-16 14:17:11 +00:00
Jo-Philipp Wich
af64410662 luci-0.10: merge r7721 2011-10-14 22:28:44 +00:00
Manuel Munz
0b7ff75dca luci-0.10: fix suffix for aachen 2011-10-02 21:04:56 +00:00
Manuel Munz
e19a3a91d5 luci-0.10: Merge r7535 2011-09-23 16:11:53 +00:00
Manuel Munz
f3b64b4eda luci-0.10: Merge r7521 2011-09-22 13:56:02 +00:00
Manuel Munz
9dd3750372 luci-0.10: Merge r7519 2011-09-22 13:12:15 +00:00
Manuel Munz
4bce06b29f luci-0.10: Merge r7498 2011-09-14 12:39:51 +00:00
Manuel Munz
69cb53a192 luci-0.10: Merge r7496 2011-09-14 12:36:11 +00:00
Manuel Munz
3f904eb841 luci-0.10: Merge r7494 2011-09-14 12:26:48 +00:00
Manuel Munz
52376387a8 luci-0.10: Merge r7468-r7481 2011-09-08 15:55:27 +00:00
Jo-Philipp Wich
be335c1d9c luci-0.10: merge r7456 2011-09-04 10:15:24 +00:00
Jo-Philipp Wich
7b169fd22d luci-0.10: merge r7454 2011-09-04 00:10:29 +00:00
Jo-Philipp Wich
dc0ca02dfc luci-0.10: merge r7452 2011-09-03 18:42:41 +00:00
Jo-Philipp Wich
3a9ee287cd luci-0.10: merge r7388 - r7450 2011-09-03 18:27:23 +00:00
Jo-Philipp Wich
5312e2919e luci-0.10: merge r7386 2011-09-01 16:07:57 +00:00
Manuel Munz
f70dee6125 luci-0.10: Merge r7384 2011-08-28 16:19:08 +00:00
Manuel Munz
779a64f62e luci-0.10: Merge r7382 2011-08-28 16:14:16 +00:00
Manuel Munz
3d7925ff51 luci-0.10: Merge r7379 2011-08-28 13:44:23 +00:00
Manuel Munz
68428f3913 luci-0.10: merge r7370 2011-08-24 10:52:53 +00:00
Jo-Philipp Wich
1fe5639832 luci-0.10: merge r7347 - r7354 2011-08-12 10:33:40 +00:00
Manuel Munz
7c058daf01 luci-0.10: Merge r7345 2011-08-05 17:55:36 +00:00
Jo-Philipp Wich
bfbda1b14d luci-0.10: merge r7341 2011-07-31 12:38:04 +00:00
Jo-Philipp Wich
2a8e9f2a63 luci-0.10: prevent faults when no rdate info exists (#284) 2011-07-30 20:11:52 +00:00
Jo-Philipp Wich
5cf7c51590 luci-0.10: merge r7338 2011-07-30 20:03:38 +00:00
Jo-Philipp Wich
6c92060639 luci-0.10: merge r7336 2011-07-30 19:43:15 +00:00
Jo-Philipp Wich
cd0b0fbedf luci-0.10: merge r7334 2011-07-22 14:50:26 +00:00
Jo-Philipp Wich
072f01704d luci-0Ã.10: merge r7332 2011-07-22 14:00:14 +00:00
Jo-Philipp Wich
6af2781783 luci-0.10: merge r7330 2011-07-22 13:56:42 +00:00
Jo-Philipp Wich
4b4454a3b3 luci-0.10: merge r7328 2011-07-21 15:33:26 +00:00
Jo-Philipp Wich
cb45e870f8 luci-0.10: merge r7308 - r7326 2011-07-21 10:40:57 +00:00
Jo-Philipp Wich
bb91ef614a luci-0.10: merge r7301 - r7306 2011-07-18 15:04:16 +00:00
Jo-Philipp Wich
18f89e9291 luci-0.10: merge r7299 2011-07-18 14:53:10 +00:00
Jo-Philipp Wich
e049665fe2 luci-0.10: merge r7297 2011-07-17 09:05:10 +00:00
Jo-Philipp Wich
5848874d1a luci-0.10: merge r7295 2011-07-17 08:29:30 +00:00
Jo-Philipp Wich
0e9548cc77 luci-0.10: merge r7293 2011-07-17 05:47:26 +00:00
Jo-Philipp Wich
dcb366bc6f luci-0.10: merge r7270 - r7290 2011-07-12 20:47:31 +00:00
Jo-Philipp Wich
a66f8c395d luci-0.10: merge r7249 - r7265 2011-07-12 20:46:24 +00:00
Jo-Philipp Wich
f1958c0b84 luci-0.10: merge r7268 2011-07-11 13:12:02 +00:00
Jo-Philipp Wich
deb6905314 luci-0.10: merge r7266 2011-07-11 12:17:46 +00:00
Jo-Philipp Wich
c4d1e086a6 luci-0.10: merge r7247 2011-06-27 01:27:17 +00:00
Manuel Munz
fab8366b3f luci-0.10: Merge r7242 2011-06-25 23:52:12 +00:00
Jo-Philipp Wich
582dee7343 luci-0.10: merge r7240 2011-06-25 23:29:42 +00:00
Jo-Philipp Wich
df81f885c3 luci-0.10: merge r7238 2011-06-25 23:17:54 +00:00
Jo-Philipp Wich
a802cedd2e luci-0.10: merge r7236 2011-06-25 22:57:53 +00:00
Jo-Philipp Wich
2e8c061be0 luci-0.10: merge r7234 2011-06-25 22:44:10 +00:00
Jo-Philipp Wich
4e3e0a2a02 luci-0.10: merge r7232 2011-06-25 22:14:32 +00:00
Jo-Philipp Wich
880a3059c1 luci-0.10: merge r7229 and r7230 2011-06-25 21:55:46 +00:00
Jo-Philipp Wich
f3753fa7b5 luci-0.10: merge r7206 - r7227 2011-06-25 20:51:30 +00:00
Jo-Philipp Wich
03860604e2 luci-0.10: merge r7192 - r7204 2011-06-22 22:26:09 +00:00
Jo-Philipp Wich
c12ca96deb luci-0.10: merge r7188, r7189 and r7190 2011-06-20 19:40:17 +00:00
Jo-Philipp Wich
b0a1756886 luci-0.10: merge r7172 - r7186 2011-06-19 22:10:57 +00:00
Jo-Philipp Wich
40180a32e2 luci-0.10: merge r7170 2011-06-17 14:20:54 +00:00
Jo-Philipp Wich
c8324500a4 luci-0.10: merge r7168 2011-06-17 12:36:38 +00:00
Jo-Philipp Wich
d1fc1dbada luci-0.10: merge r7161, r7162, r7163, r7164, r7165 and r7166 2011-06-17 11:00:38 +00:00
Jo-Philipp Wich
89f596ec88 luci-0.10: merge r7159 2011-06-17 00:41:24 +00:00
Jo-Philipp Wich
73b0b60efc luci-0.10: merge r7157 2011-06-16 23:02:20 +00:00
Jo-Philipp Wich
652cb7ae70 luci-0.10: merge r7155 2011-06-15 23:15:38 +00:00
Jo-Philipp Wich
20f7c6a394 luci-0.10: merge r7148, r7149, r7150, r7151, r7152 and r7153 2011-06-15 11:50:19 +00:00
Jo-Philipp Wich
44aefa7fe1 luci-0.10: merge r7146 2011-06-13 23:09:39 +00:00
Jo-Philipp Wich
bfcd22f5ef luci-0.10: merge r7144 2011-06-13 21:58:34 +00:00
Jo-Philipp Wich
5cfe1607be luci-0.10: merge r7137, r7138, r7139, r7140, r7141 and r7142 2011-06-13 20:58:47 +00:00
Jo-Philipp Wich
8c642a1cf7 luci-0.10: merge r7133, r7134 and r7135 2011-06-11 13:59:48 +00:00
Jo-Philipp Wich
ac2a51220f luci-0.10: merge r7127, r7128, r7129, r7130 and r7131 2011-06-11 00:09:32 +00:00
Jo-Philipp Wich
2114042e81 luci-0.10: sync translations to trunk 2011-06-10 23:27:48 +00:00
Jo-Philipp Wich
b23b669ffb luci-0.10: merge r7113, r7114, r7115, r7116 and r7117 2011-06-10 23:17:39 +00:00
Manuel Munz
9857d8d55d luci-0.10: Merge r7111 2011-06-01 11:58:09 +00:00
Jo-Philipp Wich
3901c82a7f luci-0.10: merge r7088 2011-05-21 16:30:07 +00:00
Jo-Philipp Wich
15c1b59cf3 luci-0.10: merge r7086 2011-05-20 11:57:16 +00:00
Jo-Philipp Wich
c183fb87d4 luci-0.10: merge r7084 2011-05-20 11:49:47 +00:00
Jo-Philipp Wich
02a06a7434 luci-0.10: merge r7082 2011-05-19 23:58:45 +00:00
Jo-Philipp Wich
0582b82277 luci-0.10: merge r7080 2011-05-19 23:52:24 +00:00
Jo-Philipp Wich
1ed7b97641 luci-0.10: merge r7078 2011-05-19 12:23:02 +00:00
Manuel Munz
c0d27033dc luci-0.10: Merge r6847 - now for real 2011-05-18 11:07:17 +00:00
Manuel Munz
749e94b749 luci-0.10: Merge r6847 2011-05-18 11:05:28 +00:00
Manuel Munz
a7ecc68c6a luci-0.10: merge r7072 2011-05-17 23:24:28 +00:00
Manuel Munz
7f83c1be5a luci-0.10: Merge r7070 2011-05-17 23:08:21 +00:00
Manuel Munz
623b7d3688 luci-0.10: Merge r7068 2011-05-17 17:02:07 +00:00
Jo-Philipp Wich
b4f7f9a50a luci-0.10: merge r7065 and r7066 2011-05-16 11:53:04 +00:00
Jo-Philipp Wich
6919ec4d51 luci-0.10: merge r7048-r7057 2011-05-16 09:08:41 +00:00
Manuel Munz
cfb8357d55 luci-0.10: Merge r7062 2011-05-14 13:00:00 +00:00
Manuel Munz
3b7ed80105 luci-0.10: Merge r7060 2011-05-14 10:26:51 +00:00
Manuel Munz
81614596bf luci-0.10: Merge r7058 2011-05-14 02:46:05 +00:00
Manuel Munz
450b4a8d24 luci-0.10: Update norwegian translations 2011-05-11 08:04:58 +00:00
Jo-Philipp Wich
9c00964f51 luci-0.10: merge r7044 2011-05-10 00:09:21 +00:00
Jo-Philipp Wich
19d57e4ac8 luci-0.10: restore i18n-po2lua.pl 2011-05-09 23:52:34 +00:00
Jo-Philipp Wich
68bdf4efe2 luci-0.10: merge r7041 2011-05-09 23:48:29 +00:00
Jo-Philipp Wich
46c1f2d523 luci-0.10: merge r7039 2011-05-09 23:12:10 +00:00
Jo-Philipp Wich
cac737f54d luci-0.10: merge trunk 2011-05-09 23:04:26 +00:00
Manuel Munz
d8a20fb2cb luci-0.10: Backport r7035 2011-05-09 00:45:23 +00:00
Manuel Munz
d302710444 luci-0.10: Merge r7032 2011-05-08 21:28:00 +00:00
Manuel Munz
ab5eada15b luci-0.10: Merge r7007 2011-04-29 16:54:07 +00:00
Manuel Munz
7aa0ff6e90 luci-0.10: Merge r6997 (#225) 2011-04-22 14:03:46 +00:00
Manuel Munz
ea2717f744 luci-0.10: Merge r6995 2011-04-22 10:17:54 +00:00
Manuel Munz
2eaf5fdd10 luci-0.10: Merge r6993 2011-04-21 14:22:09 +00:00
Manuel Munz
8618eb8207 luci-0.10: Merge r6990 2011-04-18 16:41:43 +00:00
Jo-Philipp Wich
6bc13b31f5 luci-0.10: merge r6988 2011-04-17 11:39:52 +00:00
Manuel Munz
1982f945fa luci-0.10: Merge r6986 2011-04-13 19:31:01 +00:00
Manuel Munz
f27b174f60 luci-0.10: Merge r6981 2011-04-04 12:06:01 +00:00
Manuel Munz
3490606f2a luci-0.10: Merge r6979 2011-04-04 11:53:51 +00:00
Jo-Philipp Wich
62b8fe1515 luci-0.10: merge r6976 and r6977 2011-03-30 11:44:14 +00:00
Jo-Philipp Wich
89812afda3 luci-0.10: merge r6943 2011-03-11 17:59:29 +00:00
Manuel Munz
71e4e2047e luci-0.10: Merge r6937 2011-03-03 21:05:45 +00:00
Manuel Munz
83174b9a3f luci-0.10: Merge r6935 2011-02-28 12:51:17 +00:00
Manuel Munz
a56c61619f luci-0.10: Merge r6933 2011-02-28 12:39:49 +00:00
Manuel Munz
97ba429c29 luci-0.10: Revert last change 2011-02-23 23:35:32 +00:00
Manuel Munz
88fca98794 luci-0.10: Merge r6925 2011-02-23 23:17:10 +00:00
Manuel Munz
3457334d32 luci-0.10: Merge r6916 2011-02-19 11:19:25 +00:00
Manuel Munz
14c841ac0c luci-0.10: Merge r6909 2011-02-15 21:06:27 +00:00
Manuel Munz
1b57036f5d luci-0.10: Merge r6906 2011-02-15 20:42:19 +00:00
Manuel Munz
21ff313dd0 luci-0.10: Merge r6903 2011-02-14 18:07:18 +00:00
Manuel Munz
18da9d5533 luci-0.10: Merge r6900 2011-02-14 16:21:05 +00:00
Manuel Munz
0eee4e2a3e luci-0.10: Merge r6897 2011-02-14 12:26:47 +00:00
Manuel Munz
c8711c2bbf luci-0.10: Merge r6895 2011-02-14 01:28:35 +00:00
Manuel Munz
e0c0131505 luci:0.10: Merge r6883, r6884, r6889-r6891 2011-02-13 22:06:41 +00:00
Manuel Munz
a6f83e195d luci-0.10: Merge r6887 2011-02-12 19:41:38 +00:00
Manuel Munz
18074ab09c luci-0.10: merge r6877 2011-02-12 17:09:16 +00:00
Jo-Philipp Wich
39c2331d23 luci-0.10: merge r6821 and r6822 (#199) 2011-02-12 16:33:05 +00:00
Manuel Munz
0b37d5908f luci-0.10: Merge r6874 2011-02-12 13:55:33 +00:00
Manuel Munz
ee1f5eb6b1 luci-0.10: Merge r6872 2011-02-12 11:15:11 +00:00
Manuel Munz
cebf7d7c99 luci-0.10: Merge r6870 2011-02-11 23:48:20 +00:00
Manuel Munz
23bec2a413 luci-0.10: merge r6868 2011-02-11 21:48:43 +00:00
Manuel Munz
ab31537983 luci-0.10: Merge r6866 2011-02-11 21:44:50 +00:00
Manuel Munz
1da3070a3d luci-0.10: Merge 6862 2011-02-11 21:16:44 +00:00
Manuel Munz
a8c7157392 luci-0.10: Merge r6863 2011-02-11 21:15:33 +00:00
Manuel Munz
edb5da3448 luci-0.10: Merge r6860 2011-02-11 19:07:14 +00:00
Manuel Munz
1a76d58baa luci-0.10: Merge r6858 2011-02-11 18:56:01 +00:00
Manuel Munz
d1bb3b8592 luci-0.10: Merge r6856 2011-02-11 18:52:44 +00:00
Manuel Munz
2e17e1254b luci-0.10: Merge r6854 2011-02-11 18:50:30 +00:00
Manuel Munz
9796ac0572 luci-0.10: Merge r6850 2011-02-10 15:02:09 +00:00
Manuel Munz
480b5ff1bb luci-0.10: Merge r6847 2011-02-09 20:17:55 +00:00
Manuel Munz
eb17b22200 luci-0.10: Merge r 6840 2011-02-03 15:19:19 +00:00
Jo-Philipp Wich
f44d481aac luci-0.10: merge r6838 2011-02-02 23:48:37 +00:00
Manuel Munz
5b3fcceee5 luci-0.10: Merge r6836 2011-02-02 10:57:08 +00:00
Jo-Philipp Wich
461adc7e1f luci-0.10: merge r6834 2011-01-30 16:12:25 +00:00
Jo-Philipp Wich
d6bdac40d4 luci-0.10: merge r6832 2011-01-30 01:30:54 +00:00
Jo-Philipp Wich
d3f8fbb5bd luci-0.10: merge r6825-r6830 2011-01-30 01:11:01 +00:00
Jo-Philipp Wich
25e1a5fd86 luci-0.10: merge r6823 2011-01-29 18:06:08 +00:00
Manuel Munz
8386ffd50a luci-0.10: Merge r6819 2011-01-29 14:22:29 +00:00
Manuel Munz
c55d80e056 luci-0.10: Backport r6816 2011-01-29 13:03:11 +00:00
Jo-Philipp Wich
79d5eca464 luci-0.10: merge r6814 2011-01-29 03:56:55 +00:00
Jo-Philipp Wich
bdf7a18dcd luci-0.10: merge r6812 2011-01-29 03:40:37 +00:00
Jo-Philipp Wich
19884465f1 luci-0.10: merge r6808 and r6809 2011-01-29 03:35:17 +00:00
Manuel Munz
dfef0f4fa4 luci-0.10: Merge 6805 2011-01-29 01:22:27 +00:00
Manuel Munz
d2e35b8e4e luci-0.10: Merge 6804 2011-01-28 23:33:21 +00:00
Manuel Munz
ee54d4de77 luci-0.10: Merge r6802 2011-01-28 23:01:30 +00:00
Manuel Munz
8a1088dc5f luci-0.10: Another part of the merge was missing 2011-01-27 14:28:11 +00:00
Manuel Munz
767a413e96 luci-0.10: One part of the merge was missing 2011-01-27 14:25:28 +00:00
Manuel Munz
22dbcceecf luci-0.10: Merge r6797 and r6798 2011-01-27 14:23:43 +00:00
Jo-Philipp Wich
2d6f584b19 luci-0.10: merge r6795 2011-01-26 19:13:24 +00:00
Jo-Philipp Wich
524c2de327 luci-0.10: merge r6791, r6792 and r6793 2011-01-26 16:25:15 +00:00
Jo-Philipp Wich
b563a74360 luci-0.10: merge r6789 2011-01-25 12:52:35 +00:00
Jo-Philipp Wich
e558edee0b luci-0.10: merge r6786 and r6787 (#188) 2011-01-24 07:40:39 +00:00
Jo-Philipp Wich
658a2a69bd luci-0.10: merge r6759-r6784 2011-01-23 18:38:22 +00:00
Jo-Philipp Wich
8383f6b979 luci-0.10: merge r6757 2011-01-19 21:37:44 +00:00
Jo-Philipp Wich
29b6de2d38 luci-0.10: merge r6755 2011-01-19 18:42:51 +00:00
Jo-Philipp Wich
9bc9eae960 luci-0.10: partly revert r6749 2011-01-18 20:54:24 +00:00
Jo-Philipp Wich
21660222d9 luci-0.10: merge r6750 2011-01-18 20:01:44 +00:00
Jo-Philipp Wich
8349acf449 luci-0.10: merge r6746, r6747 and r6748 2011-01-18 19:15:46 +00:00
Jo-Philipp Wich
dbe1c54a45 luci-0.10: merge r6724-r6744 2011-01-16 23:45:51 +00:00
Jo-Philipp Wich
55240d05ac luci-0.10: merge r6709-r6717 2011-01-13 22:40:27 +00:00
Jo-Philipp Wich
865c8f3c07 luci-0.10: merge r6706 2011-01-11 13:22:51 +00:00
Jo-Philipp Wich
a2e15947ad luci-0.10: merge r6704 2011-01-10 23:28:01 +00:00
Jo-Philipp Wich
8423ad783b luci-0.10: merge r6702 2011-01-10 23:09:17 +00:00
Jo-Philipp Wich
b58cd2ba20 luci-0.10: merge r6700 2011-01-10 18:42:28 +00:00
Jo-Philipp Wich
43a7436644 luci-0.10: merge r6698 2011-01-10 15:50:24 +00:00
Jo-Philipp Wich
eaa05f9f29 luci-0.10: merge r6695 and r6696 2011-01-10 00:44:43 +00:00
Jo-Philipp Wich
4370e52a97 luci-0.10: prepare feed Makefile 2011-01-10 00:26:02 +00:00
Jo-Philipp Wich
60e2d067fa Start LuCI 0.10.x branch 2011-01-10 00:25:17 +00:00
338 changed files with 21251 additions and 30741 deletions

View file

@ -1,6 +0,0 @@
#!/bin/sh
[ -n "${IPKG_INSTROOT}" ] || {
( . /etc/uci-defaults/luci-asterisk ) && rm -f /etc/uci-defaults/luci-asterisk
/etc/init.d/asterisk enabled || /etc/init.d/asterisk enable
exit 0
}

View file

@ -1,759 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Asterisk PBX interface library
Copyright 2009 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
module("luci.asterisk", package.seeall)
require("luci.asterisk.cc_idd")
local _io = require("io")
local uci = require("luci.model.uci").cursor()
local sys = require("luci.sys")
local util = require("luci.util")
AST_BIN = "/usr/sbin/asterisk"
AST_FLAGS = "-r -x"
--- LuCI Asterisk - Resync uci context
function uci_resync()
uci = luci.model.uci.cursor()
end
--- LuCI Asterisk io interface
-- Handles low level io.
-- @type module
io = luci.util.class()
--- Execute command and return output
-- @param command String containing the command to execute
-- @return String containing the command output
function io.exec(command)
local fh = _io.popen( "%s %s %q" %{ AST_BIN, AST_FLAGS, command }, "r" )
assert(fh, "Failed to invoke asterisk")
local buffer = fh:read("*a")
fh:close()
return buffer
end
--- Execute command and invoke given callback for each readed line
-- @param command String containing the command to execute
-- @param callback Function to call back for each line
-- @return Always true
function io.execl(command, callback)
local ln
local fh = _io.popen( "%s %s %q" %{ AST_BIN, AST_FLAGS, command }, "r" )
assert(fh, "Failed to invoke asterisk")
repeat
ln = fh:read("*l")
callback(ln)
until not ln
fh:close()
return true
end
--- Execute command and return an iterator that returns one line per invokation
-- @param command String containing the command to execute
-- @return Iterator function
function io.execi(command)
local fh = _io.popen( "%s %s %q" %{ AST_BIN, AST_FLAGS, command }, "r" )
assert(fh, "Failed to invoke asterisk")
return function()
local ln = fh:read("*l")
if not ln then fh:close() end
return ln
end
end
--- LuCI Asterisk - core status
core = luci.util.class()
--- Retrive version string.
-- @return String containing the reported asterisk version
function core.version(self)
local version = io.exec("core show version")
return version:gsub(" *\n", "")
end
--- LuCI Asterisk - SIP information.
-- @type module
sip = luci.util.class()
--- Get a list of known SIP peers
-- @return Table containing each SIP peer
function sip.peers(self)
local head = false
local peers = { }
for line in io.execi("sip show peers") do
if not head then
head = true
elseif not line:match(" sip peers ") then
local online, delay, id, uid
local name, host, dyn, nat, acl, port, status =
line:match("(.-) +(.-) +([D ]) ([N ]) (.) (%d+) +(.+)")
if host == '(Unspecified)' then host = nil end
if port == '0' then port = nil else port = tonumber(port) end
dyn = ( dyn == 'D' and true or false )
nat = ( nat == 'N' and true or false )
acl = ( acl ~= ' ' and true or false )
online, delay = status:match("(OK) %((%d+) ms%)")
if online == 'OK' then
online = true
delay = tonumber(delay)
elseif status ~= 'Unmonitored' then
online = false
delay = 0
else
online = nil
delay = 0
end
id, uid = name:match("(.+)/(.+)")
if not ( id and uid ) then
id = name .. "..."
uid = nil
end
peers[#peers+1] = {
online = online,
delay = delay,
name = id,
user = uid,
dynamic = dyn,
nat = nat,
acl = acl,
host = host,
port = port
}
end
end
return peers
end
--- Get informations of given SIP peer
-- @param peer String containing the name of the SIP peer
function sip.peer(peer)
local info = { }
local keys = { }
for line in io.execi("sip show peer " .. peer) do
if #line > 0 then
local key, val = line:match("(.-) *: +(.*)")
if key and val then
key = key:gsub("^ +",""):gsub(" +$", "")
val = val:gsub("^ +",""):gsub(" +$", "")
if key == "* Name" then
key = "Name"
elseif key == "Addr->IP" then
info.address, info.port = val:match("(.+) Port (.+)")
info.port = tonumber(info.port)
elseif key == "Status" then
info.online, info.delay = val:match("(OK) %((%d+) ms%)")
if info.online == 'OK' then
info.online = true
info.delay = tonumber(info.delay)
elseif status ~= 'Unmonitored' then
info.online = false
info.delay = 0
else
info.online = nil
info.delay = 0
end
end
if val == 'Yes' or val == 'yes' or val == '<Set>' then
val = true
elseif val == 'No' or val == 'no' then
val = false
elseif val == '<Not set>' or val == '(none)' then
val = nil
end
keys[#keys+1] = key
info[key] = val
end
end
end
return info, keys
end
--- LuCI Asterisk - Internal helpers
-- @type module
tools = luci.util.class()
--- Convert given value to a list of tokens. Split by white space.
-- @param val String or table value
-- @return Table containing tokens
function tools.parse_list(v)
local tokens = { }
v = type(v) == "table" and v or { v }
for _, v in ipairs(v) do
if type(v) == "string" then
for v in v:gmatch("(%S+)") do
tokens[#tokens+1] = v
end
end
end
return tokens
end
--- Convert given list to a collection of hyperlinks
-- @param list Table of tokens
-- @param url String pattern or callback function to construct urls (optional)
-- @param sep String containing the seperator (optional, default is ", ")
-- @return String containing the html fragment
function tools.hyperlinks(list, url, sep)
local html
local function mkurl(p, t)
if type(p) == "string" then
return p:format(t)
elseif type(p) == "function" then
return p(t)
else
return '#'
end
end
list = list or { }
url = url or "%s"
sep = sep or ", "
for _, token in ipairs(list) do
html = ( html and html .. sep or '' ) ..
'<a href="%s">%s</a>' %{ mkurl(url, token), token }
end
return html or ''
end
--- LuCI Asterisk - International Direct Dialing Prefixes
-- @type module
idd = luci.util.class()
--- Lookup the country name for the given IDD code.
-- @param country String containing IDD code
-- @return String containing the country name
function idd.country(c)
for _, v in ipairs(cc_idd.CC_IDD) do
if type(v[3]) == "table" then
for _, v2 in ipairs(v[3]) do
if v2 == tostring(c) then
return v[1]
end
end
elseif v[3] == tostring(c) then
return v[1]
end
end
end
--- Lookup the country code for the given IDD code.
-- @param country String containing IDD code
-- @return Table containing the country code(s)
function idd.cc(c)
for _, v in ipairs(cc_idd.CC_IDD) do
if type(v[3]) == "table" then
for _, v2 in ipairs(v[3]) do
if v2 == tostring(c) then
return type(v[2]) == "table"
and v[2] or { v[2] }
end
end
elseif v[3] == tostring(c) then
return type(v[2]) == "table"
and v[2] or { v[2] }
end
end
end
--- Lookup the IDD code(s) for the given country.
-- @param idd String containing the country name
-- @return Table containing the IDD code(s)
function idd.idd(c)
for _, v in ipairs(cc_idd.CC_IDD) do
if v[1]:lower():match(c:lower()) then
return type(v[3]) == "table"
and v[3] or { v[3] }
end
end
end
--- Populate given CBI field with IDD codes.
-- @param field CBI option object
-- @return (nothing)
function idd.cbifill(o)
for i, v in ipairs(cc_idd.CC_IDD) do
o:value("_%i" % i, util.pcdata(v[1]))
end
o.formvalue = function(...)
local val = luci.cbi.Value.formvalue(...)
if val:sub(1,1) == "_" then
val = tonumber((val:gsub("^_", "")))
if val then
return type(cc_idd.CC_IDD[val][3]) == "table"
and cc_idd.CC_IDD[val][3] or { cc_idd.CC_IDD[val][3] }
end
end
return val
end
o.cfgvalue = function(...)
local val = luci.cbi.Value.cfgvalue(...)
if val then
val = tools.parse_list(val)
for i, v in ipairs(cc_idd.CC_IDD) do
if type(v[3]) == "table" then
if v[3][1] == val[1] then
return "_%i" % i
end
else
if v[3] == val[1] then
return "_%i" % i
end
end
end
end
return val
end
end
--- LuCI Asterisk - Country Code Prefixes
-- @type module
cc = luci.util.class()
--- Lookup the country name for the given CC code.
-- @param country String containing CC code
-- @return String containing the country name
function cc.country(c)
for _, v in ipairs(cc_idd.CC_IDD) do
if type(v[2]) == "table" then
for _, v2 in ipairs(v[2]) do
if v2 == tostring(c) then
return v[1]
end
end
elseif v[2] == tostring(c) then
return v[1]
end
end
end
--- Lookup the international dialing code for the given CC code.
-- @param cc String containing CC code
-- @return String containing IDD code
function cc.idd(c)
for _, v in ipairs(cc_idd.CC_IDD) do
if type(v[2]) == "table" then
for _, v2 in ipairs(v[2]) do
if v2 == tostring(c) then
return type(v[3]) == "table"
and v[3] or { v[3] }
end
end
elseif v[2] == tostring(c) then
return type(v[3]) == "table"
and v[3] or { v[3] }
end
end
end
--- Lookup the CC code(s) for the given country.
-- @param country String containing the country name
-- @return Table containing the CC code(s)
function cc.cc(c)
for _, v in ipairs(cc_idd.CC_IDD) do
if v[1]:lower():match(c:lower()) then
return type(v[2]) == "table"
and v[2] or { v[2] }
end
end
end
--- Populate given CBI field with CC codes.
-- @param field CBI option object
-- @return (nothing)
function cc.cbifill(o)
for i, v in ipairs(cc_idd.CC_IDD) do
o:value("_%i" % i, util.pcdata(v[1]))
end
o.formvalue = function(...)
local val = luci.cbi.Value.formvalue(...)
if val:sub(1,1) == "_" then
val = tonumber((val:gsub("^_", "")))
if val then
return type(cc_idd.CC_IDD[val][2]) == "table"
and cc_idd.CC_IDD[val][2] or { cc_idd.CC_IDD[val][2] }
end
end
return val
end
o.cfgvalue = function(...)
local val = luci.cbi.Value.cfgvalue(...)
if val then
val = tools.parse_list(val)
for i, v in ipairs(cc_idd.CC_IDD) do
if type(v[2]) == "table" then
if v[2][1] == val[1] then
return "_%i" % i
end
else
if v[2] == val[1] then
return "_%i" % i
end
end
end
end
return val
end
end
--- LuCI Asterisk - Dialzone
-- @type module
dialzone = luci.util.class()
--- Parse a dialzone section
-- @param zone Table containing the zone info
-- @return Table with parsed information
function dialzone.parse(z)
if z['.name'] then
return {
trunks = tools.parse_list(z.uses),
name = z['.name'],
description = z.description or z['.name'],
addprefix = z.addprefix,
matches = tools.parse_list(z.match),
intlmatches = tools.parse_list(z.international),
countrycode = z.countrycode,
localzone = z.localzone,
localprefix = z.localprefix
}
end
end
--- Get a list of known dial zones
-- @return Associative table of zones and table of zone names
function dialzone.zones()
local zones = { }
local znames = { }
uci:foreach("asterisk", "dialzone",
function(z)
zones[z['.name']] = dialzone.parse(z)
znames[#znames+1] = z['.name']
end)
return zones, znames
end
--- Get a specific dial zone
-- @param name Name of the dial zone
-- @return Table containing zone information
function dialzone.zone(n)
local zone
uci:foreach("asterisk", "dialzone",
function(z)
if z['.name'] == n then
zone = dialzone.parse(z)
end
end)
return zone
end
--- Find uci section hash for given zone number
-- @param idx Zone number
-- @return String containing the uci hash pointing to the section
function dialzone.ucisection(i)
local hash
local index = 1
i = tonumber(i)
uci:foreach("asterisk", "dialzone",
function(z)
if not hash and index == i then
hash = z['.name']
end
index = index + 1
end)
return hash
end
--- LuCI Asterisk - Voicemailbox
-- @type module
voicemail = luci.util.class()
--- Parse a voicemail section
-- @param zone Table containing the mailbox info
-- @return Table with parsed information
function voicemail.parse(z)
if z.number and #z.number > 0 then
local v = {
id = '%s@%s' %{ z.number, z.context or 'default' },
number = z.number,
context = z.context or 'default',
name = z.name or z['.name'] or 'OpenWrt',
zone = z.zone or 'homeloc',
password = z.password or '0000',
email = z.email or '',
page = z.page or '',
dialplans = { }
}
uci:foreach("asterisk", "dialplanvoice",
function(s)
if s.dialplan and #s.dialplan > 0 and
s.voicebox == v.number
then
v.dialplans[#v.dialplans+1] = s.dialplan
end
end)
return v
end
end
--- Get a list of known voicemail boxes
-- @return Associative table of boxes and table of box numbers
function voicemail.boxes()
local vboxes = { }
local vnames = { }
uci:foreach("asterisk", "voicemail",
function(z)
local v = voicemail.parse(z)
if v then
local n = '%s@%s' %{ v.number, v.context }
vboxes[n] = v
vnames[#vnames+1] = n
end
end)
return vboxes, vnames
end
--- Get a specific voicemailbox
-- @param number Number of the voicemailbox
-- @return Table containing mailbox information
function voicemail.box(n)
local box
n = n:gsub("@.+$","")
uci:foreach("asterisk", "voicemail",
function(z)
if z.number == tostring(n) then
box = voicemail.parse(z)
end
end)
return box
end
--- Find all voicemailboxes within the given dialplan
-- @param plan Dialplan name or table
-- @return Associative table containing extensions mapped to mailbox info
function voicemail.in_dialplan(p)
local plan = type(p) == "string" and p or p.name
local boxes = { }
uci:foreach("asterisk", "dialplanvoice",
function(s)
if s.extension and #s.extension > 0 and s.dialplan == plan then
local box = voicemail.box(s.voicebox)
if box then
boxes[s.extension] = box
end
end
end)
return boxes
end
--- Remove voicemailbox and associated extensions from config
-- @param box Voicemailbox number or table
-- @param ctx UCI context to use (optional)
-- @return Boolean indicating success
function voicemail.remove(v, ctx)
ctx = ctx or uci
local box = type(v) == "string" and v or v.number
local ok1 = ctx:delete_all("asterisk", "voicemail", {number=box})
local ok2 = ctx:delete_all("asterisk", "dialplanvoice", {voicebox=box})
return ( ok1 or ok2 ) and true or false
end
--- LuCI Asterisk - MeetMe Conferences
-- @type module
meetme = luci.util.class()
--- Parse a meetme section
-- @param room Table containing the room info
-- @return Table with parsed information
function meetme.parse(r)
if r.room and #r.room > 0 then
local v = {
room = r.room,
pin = r.pin or '',
adminpin = r.adminpin or '',
description = r._description or '',
dialplans = { }
}
uci:foreach("asterisk", "dialplanmeetme",
function(s)
if s.dialplan and #s.dialplan > 0 and s.room == v.room then
v.dialplans[#v.dialplans+1] = s.dialplan
end
end)
return v
end
end
--- Get a list of known meetme rooms
-- @return Associative table of rooms and table of room numbers
function meetme.rooms()
local mrooms = { }
local mnames = { }
uci:foreach("asterisk", "meetme",
function(r)
local v = meetme.parse(r)
if v then
mrooms[v.room] = v
mnames[#mnames+1] = v.room
end
end)
return mrooms, mnames
end
--- Get a specific meetme room
-- @param number Number of the room
-- @return Table containing room information
function meetme.room(n)
local room
uci:foreach("asterisk", "meetme",
function(r)
if r.room == tostring(n) then
room = meetme.parse(r)
end
end)
return room
end
--- Find all meetme rooms within the given dialplan
-- @param plan Dialplan name or table
-- @return Associative table containing extensions mapped to room info
function meetme.in_dialplan(p)
local plan = type(p) == "string" and p or p.name
local rooms = { }
uci:foreach("asterisk", "dialplanmeetme",
function(s)
if s.extension and #s.extension > 0 and s.dialplan == plan then
local room = meetme.room(s.room)
if room then
rooms[s.extension] = room
end
end
end)
return rooms
end
--- Remove meetme room and associated extensions from config
-- @param room Voicemailbox number or table
-- @param ctx UCI context to use (optional)
-- @return Boolean indicating success
function meetme.remove(v, ctx)
ctx = ctx or uci
local room = type(v) == "string" and v or v.number
local ok1 = ctx:delete_all("asterisk", "meetme", {room=room})
local ok2 = ctx:delete_all("asterisk", "dialplanmeetme", {room=room})
return ( ok1 or ok2 ) and true or false
end
--- LuCI Asterisk - Dialplan
-- @type module
dialplan = luci.util.class()
--- Parse a dialplan section
-- @param plan Table containing the plan info
-- @return Table with parsed information
function dialplan.parse(z)
if z['.name'] then
local plan = {
zones = { },
name = z['.name'],
description = z.description or z['.name']
}
-- dialzones
for _, name in ipairs(tools.parse_list(z.include)) do
local zone = dialzone.zone(name)
if zone then
plan.zones[#plan.zones+1] = zone
end
end
-- voicemailboxes
plan.voicemailboxes = voicemail.in_dialplan(plan)
-- meetme conferences
plan.meetmerooms = meetme.in_dialplan(plan)
return plan
end
end
--- Get a list of known dial plans
-- @return Associative table of plans and table of plan names
function dialplan.plans()
local plans = { }
local pnames = { }
uci:foreach("asterisk", "dialplan",
function(p)
plans[p['.name']] = dialplan.parse(p)
pnames[#pnames+1] = p['.name']
end)
return plans, pnames
end
--- Get a specific dial plan
-- @param name Name of the dial plan
-- @return Table containing plan information
function dialplan.plan(n)
local plan
uci:foreach("asterisk", "dialplan",
function(p)
if p['.name'] == n then
plan = dialplan.parse(p)
end
end)
return plan
end

View file

@ -1,254 +0,0 @@
--[[
LuCI - Asterisk - International Direct Dialing Prefixes and Country Codes
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
]]--
module "luci.asterisk.cc_idd"
CC_IDD = {
-- Country, CC, IDD
{ "Afghanistan", "93", "00" },
{ "Albania", "355", "00" },
{ "Algeria", "213", "00" },
{ "American Samoa", "684", "00" },
{ "Andorra", "376", "00" },
{ "Angola", "244", "00" },
{ "Anguilla", "264", "011" },
{ "Antarctica", "672", "" },
{ "Antigua", "268", "011" },
{ "Argentina", "54", "00" },
{ "Armenia", "374", "00" },
{ "Aruba", "297", "00" },
{ "Ascension Island", "247", "00" },
{ "Australia", "61", "0011" },
{ "Austria", "43", "00" },
{ "Azberbaijan", "994", "00" },
{ "Bahamas", "242", "011" },
{ "Bahrain", "973", "00" },
{ "Bangladesh", "880", "00" },
{ "Barbados", "246", "011" },
{ "Barbuda", "268", "011" },
{ "Belarus", "375", "810" },
{ "Belgium", "32", "00" },
{ "Belize", "501", "00" },
{ "Benin", "229", "00" },
{ "Bermuda", "441", "011" },
{ "Bhutan", "975", "00" },
{ "Bolivia", "591", "00" },
{ "Bosnia", "387", "00" },
{ "Botswana", "267", "00" },
{ "Brazil", "55", "00" },
{ "British Virgin Islands", "284", "011" },
{ "Brunei", "673", "00" },
{ "Bulgaria", "359", "00" },
{ "Burkina Faso", "226", "00" },
{ "Burma (Myanmar)", "95", "00" },
{ "Burundi", "257", "00" },
{ "Cambodia", "855", "001" },
{ "Cameroon", "237", "00" },
{ "Canada", "1", "011" },
{ "Cape Verde Islands", "238", "0" },
{ "Cayman Islands", "345", "011" },
{ "Central African Rep.", "236", "00" },
{ "Chad", "235", "15" },
{ "Chile", "56", "00" },
{ "China", "86", "00" },
{ "Christmas Island", "61", "0011" },
{ "Cocos Islands", "61", "0011" },
{ "Colombia", "57", "00" },
{ "Comoros", "269", "00" },
{ "Congo", "242", "00" },
{ "Congo, Dem. Rep. of", "243", "00" },
{ "Cook Islands", "682", "00" },
{ "Costa Rica", "506", "00" },
{ "Croatia", "385", "00" },
{ "Cuba", "53", "119" },
{ "Cyprus", "357", "00" },
{ "Czech Republic", "420", "00" },
{ "Denmark", "45", "00" },
{ "Diego Garcia", "246", "00" },
{ "Djibouti", "253", "00" },
{ "Dominica", "767", "011" },
{ "Dominican Rep.", "809", "011" },
{ "Ecuador", "593", "00" },
{ "Egypt", "20", "00" },
{ "El Salvador", "503", "00" },
{ "Equatorial Guinea", "240", "00" },
{ "Eritrea", "291", "00" },
{ "Estonia", "372", "00" },
{ "Ethiopia", "251", "00" },
{ "Faeroe Islands", "298", "00" },
{ "Falkland Islands", "500", "00" },
{ "Fiji Islands", "679", "00" },
{ "Finland", "358", "00" },
{ "France", "33", "00" },
{ "French Antilles", "596", "00" },
{ "French Guiana", "594", "00" },
{ "French Polynesia", "689", "00" },
{ "Gabon", "241", "00" },
{ "Gambia", "220", "00" },
{ "Georgia", "995", "810" },
{ "Germany", "49", "00" },
{ "Ghana", "233", "00" },
{ "Gibraltar", "350", "00" },
{ "Greece", "30", "00" },
{ "Greenland", "299", "00" },
{ "Grenada", "473", "011" },
{ "Guadeloupe", "590", "00" },
{ "Guam", "671", "011" },
{ "Guantanamo Bay", "5399", "00" },
{ "Guatemala", "502", "00" },
{ "Guinea", "224", "00" },
{ "Guinea Bissau", "245", "00" },
{ "Guyana", "592", "001" },
{ "Haiti", "509", "00" },
{ "Honduras", "504", "00" },
{ "Hong Kong", "852", "001" },
{ "Hungary", "36", "00" },
{ "Iceland", "354", "00" },
{ "India", "91", "00" },
{ "Indonesia", "62", { "001", "008" } },
{ "Iran", "98", "00" },
{ "Iraq", "964", "00" },
{ "Ireland", "353", "00" },
{ "Israel", "972", "00" },
{ "Italy", "39", "00" },
{ "Ivory Coast", "225", "00" },
{ "Jamaica", "876", "011" },
{ "Japan", "81", "001" },
{ "Jordan", "962", "00" },
{ "Kazakhstan", "7", "810" },
{ "Kenya", "254", "000" },
{ "Kiribati", "686", "00" },
{ "Korea, North", "850", "00" },
{ "Korea, South", "82", "001" },
{ "Kuwait", "965", "00" },
{ "Kyrgyzstan", "996", "00" },
{ "Laos", "856", "00" },
{ "Latvia", "371", "00" },
{ "Lebanon", "961", "00" },
{ "Lesotho", "266", "00" },
{ "Liberia", "231", "00" },
{ "Libya", "218", "00" },
{ "Liechtenstein", "423", "00" },
{ "Lithuania", "370", "00" },
{ "Luxembourg", "352", "00" },
{ "Macau", "853", "00" },
{ "Macedonia", "389", "00" },
{ "Madagascar", "261", "00" },
{ "Malawi", "265", "00" },
{ "Malaysia", "60", "00" },
{ "Maldives", "960", "00" },
{ "Mali", "223", "00" },
{ "Malta", "356", "00" },
{ "Mariana Islands", "670", "011" },
{ "Marshall Islands", "692", "011" },
{ "Martinique", "596", "00" },
{ "Mauritania", "222", "00" },
{ "Mauritius", "230", "00" },
{ "Mayotte Islands", "269", "00" },
{ "Mexico", "52", "00" },
{ "Micronesia", "691", "011" },
{ "Midway Island", "808", "011" },
{ "Moldova", "373", "00" },
{ "Monaco", "377", "00" },
{ "Mongolia", "976", "001" },
{ "Montserrat", "664", "011" },
{ "Morocco", "212", "00" },
{ "Mozambique", "258", "00" },
{ "Myanmar (Burma)", "95", "00" },
{ "Namibia", "264", "00" },
{ "Nauru", "674", "00" },
{ "Nepal", "977", "00" },
{ "Netherlands", "31", "00" },
{ "Netherlands Antilles", "599", "00" },
{ "Nevis", "869", "011" },
{ "New Caledonia", "687", "00" },
{ "New Zealand", "64", "00" },
{ "Nicaragua", "505", "00" },
{ "Niger", "227", "00" },
{ "Nigeria", "234", "009" },
{ "Niue", "683", "00" },
{ "Norfolk Island", "672", "00" },
{ "Norway", "47", "00" },
{ "Oman", "968", "00" },
{ "Pakistan", "92", "00" },
{ "Palau", "680", "011" },
{ "Palestine", "970", "00" },
{ "Panama", "507", "00" },
{ "Papua New Guinea", "675", "05" },
{ "Paraguay", "595", "002" },
{ "Peru", "51", "00" },
{ "Philippines", "63", "00" },
{ "Poland", "48", "00" },
{ "Portugal", "351", "00" },
{ "Puerto Rico", { "787", "939" }, "011" },
{ "Qatar", "974", "00" },
{ "Reunion Island", "262", "00" },
{ "Romania", "40", "00" },
{ "Russia", "7", "810" },
{ "Rwanda", "250", "00" },
{ "St. Helena", "290", "00" },
{ "St. Kitts", "869", "011" },
{ "St. Lucia", "758", "011" },
{ "St. Perre & Miquelon", "508", "00" },
{ "St. Vincent", "784", "011" },
{ "San Marino", "378", "00" },
{ "Sao Tome & Principe", "239", "00" },
{ "Saudi Arabia", "966", "00" },
{ "Senegal", "221", "00" },
{ "Serbia", "381", "99" },
{ "Seychelles", "248", "00" },
{ "Sierra Leone", "232", "00" },
{ "Singapore", "65", "001" },
{ "Slovakia", "421", "00" },
{ "Slovenia", "386", "00" },
{ "Solomon Islands", "677", "00" },
{ "Somalia", "252", "00" },
{ "South Africa", "27", "09" },
{ "Spain", "34", "00" },
{ "Sri Lanka", "94", "00" },
{ "Sudan", "249", "00" },
{ "Suriname", "597", "00" },
{ "Swaziland", "268", "00" },
{ "Sweden", "46", "00" },
{ "Switzerland", "41", "00" },
{ "Syria", "963", "00" },
{ "Taiwan", "886", "002" },
{ "Tajikistan", "992", "810" },
{ "Tanzania", "255", "00" },
{ "Thailand", "66", "001" },
{ "Togo", "228", "00" },
{ "Tonga", "676", "00" },
{ "Trinidad & Tobago", "868", "011" },
{ "Tunisia", "216", "00" },
{ "Turkey", "90", "00" },
{ "Turkmenistan", "993", "810" },
{ "Turks & Caicos", "649", "011" },
{ "Tuvalu", "688", "00" },
{ "Uganda", "256", "000" },
{ "Ukraine", "380", "810" },
{ "United Arab Emirates", "971", "00" },
{ "United Kingdom", "44", "00" },
{ "Uruguay", "598", "00" },
{ "USA", "1", "011" },
{ "US Virgin Islands", "340", "011" },
{ "Uzbekistan", "998", "810" },
{ "Vanuatu", "678", "00" },
{ "Vatican City", "39", "00" },
{ "Venezuela", "58", "00" },
{ "Vietnam", "84", "00" },
{ "Wake Island", "808", "00" },
{ "Wallis & Futuna", "681", "19" },
{ "Western Samoa", "685", "00" },
{ "Yemen", "967", "00" },
{ "Yugoslavia", "381", "99" },
{ "Zambia", "260", "00" },
{ "Zimbabwe", "263", "00" }
}

View file

@ -1,205 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
module("luci.controller.asterisk", package.seeall)
function index()
entry({"admin", "services", "asterisk"}, cbi("asterisk"), "Asterisk", 80).i18n = "asterisk"
entry({"admin", "services", "asterisk", "voice"}, cbi("asterisk-voice"), "Voice Functions", 1)
entry({"admin", "services", "asterisk", "meetme"}, cbi("asterisk-meetme"), "Meetme Conferences", 2)
entry({"admin", "services", "asterisk", "iax-conns"}, cbi("asterisk-iax-connections"), "IAX Connections", 3)
entry({"admin", "services", "asterisk", "sip-conns"}, cbi("asterisk-sip-connections"), "SIP Connections", 4)
entry({"admin", "services", "asterisk", "dialplans"}, cbi("asterisk-dialplans"), "Dial Plans", 5)
entry({"admin", "services", "asterisk", "mod"}, cbi("asterisk-mod-app"), "Modules", 4)
entry({"admin", "services", "asterisk", "mod", "app"}, cbi("asterisk-mod-app"), "Applications", 1)
entry({"admin", "services", "asterisk", "mod", "cdr"}, cbi("asterisk-mod-cdr"), "Call Detail Records", 2)
entry({"admin", "services", "asterisk", "mod", "chan"}, cbi("asterisk-mod-chan"), "Channels", 3)
entry({"admin", "services", "asterisk", "mod", "codec"}, cbi("asterisk-mod-codec"), "Codecs", 4)
entry({"admin", "services", "asterisk", "mod", "format"}, cbi("asterisk-mod-format"), "Format", 5)
entry({"admin", "services", "asterisk", "mod", "func"}, cbi("asterisk-mod-func"), "Functions", 6)
entry({"admin", "services", "asterisk", "mod", "pbx"}, cbi("asterisk-mod-pbx"), "PBX", 7)
entry({"admin", "services", "asterisk", "mod", "res"}, cbi("asterisk-mod-res"), "Resources", 8)
entry({"admin", "services", "asterisk", "mod", "res", "feature"},
cbi("asterisk-mod-res-feature"), "Feature Module Configuration", 9 )
entry({"admin", "asterisk"}, cbi("asterisk/main"), "Asterisk", 99).i18n = "asterisk"
entry({"admin", "asterisk", "phones"}, cbi("asterisk/phones"), "Phones", 1)
entry({"admin", "asterisk", "phones", "sip"}, cbi("asterisk/phone_sip"), nil, 1).leaf = true
--entry({"admin", "asterisk", "phones", "exten"}, cbi("asterisk/phone_exten"), "Extensions", 2).leaf = true
entry({"admin", "asterisk", "trunks"}, cbi("asterisk/trunks"), "Trunks", 2)
entry({"admin", "asterisk", "trunks", "sip"}, cbi("asterisk/trunk_sip"), nil, 1).leaf = true
entry({"admin", "asterisk", "voicemail"}, cbi("asterisk/voicemail"), "Voicemail", 3)
entry({"admin", "asterisk", "voicemail", "mailboxes"}, cbi("asterisk/voicemail"), "Mailboxes", 1)
entry({"admin", "asterisk", "voicemail", "settings"}, cbi("asterisk/voicemail_settings"), "Settings", 2)
entry({"admin", "asterisk", "meetme"}, cbi("asterisk/meetme"), "MeetMe", 4)
entry({"admin", "asterisk", "meetme", "rooms"}, cbi("asterisk/meetme"), "Rooms", 1)
entry({"admin", "asterisk", "meetme", "settings"}, cbi("asterisk/meetme_settings"), "Settings", 2)
entry({"admin", "asterisk", "dialplans"}, call("handle_dialplan"), "Call Routing", 5)
entry({"admin", "asterisk", "dialplans", "out"}, cbi("asterisk/dialplan_out"), nil, 1).leaf = true
entry({"admin", "asterisk", "dialplans", "zones"}, call("handle_dialzones"), "Dial Zones", 2).leaf = true
end
function handle_dialplan()
local uci = luci.model.uci.cursor()
local ast = require "luci.asterisk"
local err = false
for k, v in pairs(luci.http.formvaluetable("delzone")) do
local plan = ast.dialplan.plan(k)
if #v > 0 and plan then
local newinc = { }
for _, z in ipairs(plan.zones) do
if z.name ~= v then
newinc[#newinc+1] = z.name
end
end
uci:delete("asterisk", plan.name, "include")
if #newinc > 0 then
uci:set("asterisk", plan.name, "include", newinc)
end
end
end
for k, v in pairs(luci.http.formvaluetable("addzone")) do
local plan = ast.dialplan.plan(k)
local zone = ast.dialzone.zone(v)
if #v > 0 and plan and zone then
local newinc = { zone.name }
for _, z in ipairs(plan.zones) do
newinc[#newinc+1] = z.name
end
uci:delete("asterisk", plan.name, "include")
if #newinc > 0 then
uci:set("asterisk", plan.name, "include", newinc)
end
end
end
for k, v in pairs(luci.http.formvaluetable("delvbox")) do
local plan = ast.dialplan.plan(k)
if #v > 0 and plan then
uci:delete_all("asterisk", "dialplanvoice",
{ extension=v, dialplan=plan.name })
end
end
for k, v in pairs(luci.http.formvaluetable("addvbox")) do
local plan = ast.dialplan.plan(k)
local vbox = ast.voicemail.box(v)
if plan and vbox then
local vext = luci.http.formvalue("addvboxext.%s" % plan.name)
vext = ( vext and #vext > 0 ) and vext or vbox.number
uci:section("asterisk", "dialplanvoice", nil, {
dialplan = plan.name,
extension = vext,
voicebox = vbox.number,
voicecontext = vbox.context
})
end
end
for k, v in pairs(luci.http.formvaluetable("delmeetme")) do
local plan = ast.dialplan.plan(k)
if #v > 0 and plan then
uci:delete_all("asterisk", "dialplanmeetme",
{ extension=v, dialplan=plan.name })
end
end
for k, v in pairs(luci.http.formvaluetable("addmeetme")) do
local plan = ast.dialplan.plan(k)
local meetme = ast.meetme.room(v)
if plan and meetme then
local mext = luci.http.formvalue("addmeetmeext.%s" % plan.name)
mext = ( mext and #mext > 0 ) and mext or meetme.room
uci:section("asterisk", "dialplanmeetme", nil, {
dialplan = plan.name,
extension = mext,
room = meetme.room
})
end
end
local aname = luci.http.formvalue("addplan")
if aname and #aname > 0 then
if aname:match("^[a-zA-Z0-9_]+$") then
uci:section("asterisk", "dialplan", aname, { })
else
err = true
end
end
local dname = luci.http.formvalue("delplan")
if dname and #dname > 0 then
if uci:get("asterisk", dname) == "dialplan" then
uci:delete("asterisk", dname)
uci:delete_all("asterisk", "dialplanvoice", { dialplan=dname })
uci:delete_all("asterisk", "dialplanmeetme", { dialplan=dname })
end
end
uci:save("asterisk")
ast.uci_resync()
luci.template.render("asterisk/dialplans", { create_error = err })
end
function handle_dialzones()
local ast = require "luci.asterisk"
local uci = luci.model.uci.cursor()
local err = false
if luci.http.formvalue("newzone") then
local name = luci.http.formvalue("newzone_name")
if name and name:match("^[a-zA-Z0-9_]+$") then
uci:section("asterisk", "dialzone", name, {
uses = ast.tools.parse_list(luci.http.formvalue("newzone_uses") or {}),
match = ast.tools.parse_list(luci.http.formvalue("newzone_match") or {})
})
uci:save("asterisk")
else
err = true
end
end
if luci.http.formvalue("delzone") then
local name = luci.http.formvalue("delzone")
if uci:get("asterisk", name) == "dialzone" then
uci:delete("asterisk", name)
uci:save("asterisk")
end
end
luci.template.render("asterisk/dialzones", { create_error = err })
end

View file

@ -1,102 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
dialplan = cbimap:section(TypedSection, "dialplan", "Section dialplan", "")
dialplan.addremove = true
dialplan.dynamic = true
include = dialplan:option(MultiValue, "include", "Include zones and plans", "")
cbimap.uci:foreach( "asterisk", "dialplan", function(s) include:value(s['.name']) end )
cbimap.uci:foreach( "asterisk", "dialzone", function(s) include:value(s['.name']) end )
dialplanexten = cbimap:section(TypedSection, "dialplanexten", "Dialplan Extension", "")
dialplanexten.anonymous = true
dialplanexten.addremove = true
dialplanexten.dynamic = true
dialplangeneral = cbimap:section(TypedSection, "dialplangeneral", "Dialplan General Options", "")
dialplangeneral.anonymous = true
dialplangeneral.addremove = true
allowtransfer = dialplangeneral:option(Flag, "allowtransfer", "Allow transfer", "")
allowtransfer.rmempty = true
canreinvite = dialplangeneral:option(ListValue, "canreinvite", "Reinvite/redirect media connections", "")
canreinvite:value("yes", "Yes")
canreinvite:value("nonat", "Yes when not behind NAT")
canreinvite:value("update", "Use UPDATE rather than INVITE for path redirection")
canreinvite:value("no", "No")
canreinvite.rmempty = true
clearglobalvars = dialplangeneral:option(Flag, "clearglobalvars", "Clear global vars", "")
clearglobalvars.rmempty = true
dialplangoto = cbimap:section(TypedSection, "dialplangoto", "Dialplan Goto", "")
dialplangoto.anonymous = true
dialplangoto.addremove = true
dialplangoto.dynamic = true
dialplanmeetme = cbimap:section(TypedSection, "dialplanmeetme", "Dialplan Conference", "")
dialplanmeetme.anonymous = true
dialplanmeetme.addremove = true
dialplanmeetme.dynamic = true
dialplansaytime = cbimap:section(TypedSection, "dialplansaytime", "Dialplan Time", "")
dialplansaytime.anonymous = true
dialplansaytime.addremove = true
dialplansaytime.dynamic = true
dialplanvoice = cbimap:section(TypedSection, "dialplanvoice", "Dialplan Voicemail", "")
dialplanvoice.anonymous = true
dialplanvoice.addremove = true
dialplanvoice.dynamic = true
dialzone = cbimap:section(TypedSection, "dialzone", "Dial Zones for Dialplan", "")
dialzone.addremove = true
dialzone.template = "cbi/tblsection"
addprefix = dialzone:option(Value, "addprefix", "Prefix to add matching dialplans", "")
addprefix.rmempty = true
--international = dialzone:option(DynamicList, "international", "Match International prefix", "")
international = dialzone:option(Value, "international", "Match International prefix", "")
international.rmempty = true
localprefix = dialzone:option(Value, "localprefix", "Prefix (0) to add/remove to/from intl. numbers", "")
localprefix.rmempty = true
localzone = dialzone:option(Value, "localzone", "Dialzone for intl. numbers matched as local", "")
localzone.titleref = luci.dispatcher.build_url( "admin", "services", "asterisk", "dialplans" )
cbimap.uci:foreach( "asterisk", "dialplan", function(s) localzone:value(s['.name']) end )
cbimap.uci:foreach( "asterisk", "dialzone", function(s) localzone:value(s['.name']) end )
match = dialzone:option(Value, "match", "Match plan", "")
match.rmempty = true
uses = dialzone:option(ListValue, "uses", "Connection to use", "")
uses.titleref = luci.dispatcher.build_url( "admin", "services", "asterisk", "sip-conns" )
cbimap.uci:foreach( "asterisk", "sip", function(s) uses:value('SIP/'..s['.name']) end )
cbimap.uci:foreach( "asterisk", "iax", function(s) uses:value('IAX/'..s['.name']) end )
return cbimap

View file

@ -1,60 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
iax = cbimap:section(TypedSection, "iax", "IAX Connection", "")
iax.addremove = true
alwaysinternational = iax:option(Flag, "alwaysinternational", "Always Dial International", "")
alwaysinternational.optional = true
context = iax:option(ListValue, "context", "Context to use", "")
context.titleref = luci.dispatcher.build_url( "admin", "services", "asterisk", "dialplans" )
cbimap.uci:foreach( "asterisk", "dialplan", function(s) context:value(s['.name']) end )
cbimap.uci:foreach( "asterisk", "dialzone", function(s) context:value(s['.name']) end )
countrycode = iax:option(Value, "countrycode", "Country Code for connection", "")
countrycode.optional = true
extension = iax:option(Value, "extension", "Add as Extension", "")
extension.optional = true
host = iax:option(Value, "host", "Host name (or blank)", "")
host.optional = true
internationalprefix = iax:option(Value, "internationalprefix", "International Dial Prefix", "")
internationalprefix.optional = true
prefix = iax:option(Value, "prefix", "Dial Prefix (for external line)", "")
prefix.optional = true
secret = iax:option(Value, "secret", "Secret", "")
secret.optional = true
timeout = iax:option(Value, "timeout", "Dial Timeout (sec)", "")
timeout.optional = true
type = iax:option(ListValue, "type", "Option type", "")
type:value("friend", "Friend (outbound/inbound)")
type:value("user", "User (inbound - authenticate by \"from\")")
type:value("peer", "Peer (outbound - match by host)")
type.optional = true
username = iax:option(Value, "username", "User name", "")
username.optional = true
return cbimap

View file

@ -1,33 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
meetmegeneral = cbimap:section(TypedSection, "meetmegeneral", "Meetme Conference General Options", "")
audiobuffers = meetmegeneral:option(Value, "audiobuffers", "Number of 20ms audio buffers to be used", "")
meetme = cbimap:section(TypedSection, "meetme", "Meetme Conference", "")
meetme.addremove = true
adminpin = meetme:option(Value, "adminpin", "Admin PIN", "")
adminpin.password = true
pin = meetme:option(Value, "pin", "Meeting PIN", "")
pin.password = true
return cbimap

View file

@ -1,391 +0,0 @@
cbimap = Map("asterisk", "asterisk", "")
module = cbimap:section(TypedSection, "module", "Modules", "")
module.anonymous = true
app_alarmreceiver = module:option(ListValue, "app_alarmreceiver", "Alarm Receiver Application", "")
app_alarmreceiver:value("yes", "Load")
app_alarmreceiver:value("no", "Do Not Load")
app_alarmreceiver:value("auto", "Load as Required")
app_alarmreceiver.rmempty = true
app_authenticate = module:option(ListValue, "app_authenticate", "Authentication Application", "")
app_authenticate:value("yes", "Load")
app_authenticate:value("no", "Do Not Load")
app_authenticate:value("auto", "Load as Required")
app_authenticate.rmempty = true
app_cdr = module:option(ListValue, "app_cdr", "Make sure asterisk doesnt save CDR", "")
app_cdr:value("yes", "Load")
app_cdr:value("no", "Do Not Load")
app_cdr:value("auto", "Load as Required")
app_cdr.rmempty = true
app_chanisavail = module:option(ListValue, "app_chanisavail", "Check if channel is available", "")
app_chanisavail:value("yes", "Load")
app_chanisavail:value("no", "Do Not Load")
app_chanisavail:value("auto", "Load as Required")
app_chanisavail.rmempty = true
app_chanspy = module:option(ListValue, "app_chanspy", "Listen in on any channel", "")
app_chanspy:value("yes", "Load")
app_chanspy:value("no", "Do Not Load")
app_chanspy:value("auto", "Load as Required")
app_chanspy.rmempty = true
app_controlplayback = module:option(ListValue, "app_controlplayback", "Control Playback Application", "")
app_controlplayback:value("yes", "Load")
app_controlplayback:value("no", "Do Not Load")
app_controlplayback:value("auto", "Load as Required")
app_controlplayback.rmempty = true
app_cut = module:option(ListValue, "app_cut", "Cuts up variables", "")
app_cut:value("yes", "Load")
app_cut:value("no", "Do Not Load")
app_cut:value("auto", "Load as Required")
app_cut.rmempty = true
app_db = module:option(ListValue, "app_db", "Database access functions", "")
app_db:value("yes", "Load")
app_db:value("no", "Do Not Load")
app_db:value("auto", "Load as Required")
app_db.rmempty = true
app_dial = module:option(ListValue, "app_dial", "Dialing Application", "")
app_dial:value("yes", "Load")
app_dial:value("no", "Do Not Load")
app_dial:value("auto", "Load as Required")
app_dial.rmempty = true
app_dictate = module:option(ListValue, "app_dictate", "Virtual Dictation Machine Application", "")
app_dictate:value("yes", "Load")
app_dictate:value("no", "Do Not Load")
app_dictate:value("auto", "Load as Required")
app_dictate.rmempty = true
app_directed_pickup = module:option(ListValue, "app_directed_pickup", "Directed Call Pickup Support", "")
app_directed_pickup:value("yes", "Load")
app_directed_pickup:value("no", "Do Not Load")
app_directed_pickup:value("auto", "Load as Required")
app_directed_pickup.rmempty = true
app_directory = module:option(ListValue, "app_directory", "Extension Directory", "")
app_directory:value("yes", "Load")
app_directory:value("no", "Do Not Load")
app_directory:value("auto", "Load as Required")
app_directory.rmempty = true
app_disa = module:option(ListValue, "app_disa", "DISA (Direct Inward System Access) Application", "")
app_disa:value("yes", "Load")
app_disa:value("no", "Do Not Load")
app_disa:value("auto", "Load as Required")
app_disa.rmempty = true
app_dumpchan = module:option(ListValue, "app_dumpchan", "Dump channel variables Application", "")
app_dumpchan:value("yes", "Load")
app_dumpchan:value("no", "Do Not Load")
app_dumpchan:value("auto", "Load as Required")
app_dumpchan.rmempty = true
app_echo = module:option(ListValue, "app_echo", "Simple Echo Application", "")
app_echo:value("yes", "Load")
app_echo:value("no", "Do Not Load")
app_echo:value("auto", "Load as Required")
app_echo.rmempty = true
app_enumlookup = module:option(ListValue, "app_enumlookup", "ENUM Lookup", "")
app_enumlookup:value("yes", "Load")
app_enumlookup:value("no", "Do Not Load")
app_enumlookup:value("auto", "Load as Required")
app_enumlookup.rmempty = true
app_eval = module:option(ListValue, "app_eval", "Reevaluates strings", "")
app_eval:value("yes", "Load")
app_eval:value("no", "Do Not Load")
app_eval:value("auto", "Load as Required")
app_eval.rmempty = true
app_exec = module:option(ListValue, "app_exec", "Executes applications", "")
app_exec:value("yes", "Load")
app_exec:value("no", "Do Not Load")
app_exec:value("auto", "Load as Required")
app_exec.rmempty = true
app_externalivr = module:option(ListValue, "app_externalivr", "External IVR application interface", "")
app_externalivr:value("yes", "Load")
app_externalivr:value("no", "Do Not Load")
app_externalivr:value("auto", "Load as Required")
app_externalivr.rmempty = true
app_forkcdr = module:option(ListValue, "app_forkcdr", "Fork The CDR into 2 seperate entities", "")
app_forkcdr:value("yes", "Load")
app_forkcdr:value("no", "Do Not Load")
app_forkcdr:value("auto", "Load as Required")
app_forkcdr.rmempty = true
app_getcpeid = module:option(ListValue, "app_getcpeid", "Get ADSI CPE ID", "")
app_getcpeid:value("yes", "Load")
app_getcpeid:value("no", "Do Not Load")
app_getcpeid:value("auto", "Load as Required")
app_getcpeid.rmempty = true
app_groupcount = module:option(ListValue, "app_groupcount", "Group Management Routines", "")
app_groupcount:value("yes", "Load")
app_groupcount:value("no", "Do Not Load")
app_groupcount:value("auto", "Load as Required")
app_groupcount.rmempty = true
app_ices = module:option(ListValue, "app_ices", "Encode and Stream via icecast and ices", "")
app_ices:value("yes", "Load")
app_ices:value("no", "Do Not Load")
app_ices:value("auto", "Load as Required")
app_ices.rmempty = true
app_image = module:option(ListValue, "app_image", "Image Transmission Application", "")
app_image:value("yes", "Load")
app_image:value("no", "Do Not Load")
app_image:value("auto", "Load as Required")
app_image.rmempty = true
app_lookupblacklist = module:option(ListValue, "app_lookupblacklist", "Look up Caller*ID name/number from black", "")
app_lookupblacklist:value("yes", "Load")
app_lookupblacklist:value("no", "Do Not Load")
app_lookupblacklist:value("auto", "Load as Required")
app_lookupblacklist.rmempty = true
app_lookupcidname = module:option(ListValue, "app_lookupcidname", "Look up CallerID Name from local databas", "")
app_lookupcidname:value("yes", "Load")
app_lookupcidname:value("no", "Do Not Load")
app_lookupcidname:value("auto", "Load as Required")
app_lookupcidname.rmempty = true
app_macro = module:option(ListValue, "app_macro", "Extension Macros", "")
app_macro:value("yes", "Load")
app_macro:value("no", "Do Not Load")
app_macro:value("auto", "Load as Required")
app_macro.rmempty = true
app_math = module:option(ListValue, "app_math", "A simple math Application", "")
app_math:value("yes", "Load")
app_math:value("no", "Do Not Load")
app_math:value("auto", "Load as Required")
app_math.rmempty = true
app_md5 = module:option(ListValue, "app_md5", "MD5 checksum Application", "")
app_md5:value("yes", "Load")
app_md5:value("no", "Do Not Load")
app_md5:value("auto", "Load as Required")
app_md5.rmempty = true
app_milliwatt = module:option(ListValue, "app_milliwatt", "Digital Milliwatt (mu-law) Test Application", "")
app_milliwatt:value("yes", "Load")
app_milliwatt:value("no", "Do Not Load")
app_milliwatt:value("auto", "Load as Required")
app_milliwatt.rmempty = true
app_mixmonitor = module:option(ListValue, "app_mixmonitor", "Record a call and mix the audio during the recording", "")
app_mixmonitor:value("yes", "Load")
app_mixmonitor:value("no", "Do Not Load")
app_mixmonitor:value("auto", "Load as Required")
app_mixmonitor.rmempty = true
app_parkandannounce = module:option(ListValue, "app_parkandannounce", "Call Parking and Announce Application", "")
app_parkandannounce:value("yes", "Load")
app_parkandannounce:value("no", "Do Not Load")
app_parkandannounce:value("auto", "Load as Required")
app_parkandannounce.rmempty = true
app_playback = module:option(ListValue, "app_playback", "Trivial Playback Application", "")
app_playback:value("yes", "Load")
app_playback:value("no", "Do Not Load")
app_playback:value("auto", "Load as Required")
app_playback.rmempty = true
app_privacy = module:option(ListValue, "app_privacy", "Require phone number to be entered", "")
app_privacy:value("yes", "Load")
app_privacy:value("no", "Do Not Load")
app_privacy:value("auto", "Load as Required")
app_privacy.rmempty = true
app_queue = module:option(ListValue, "app_queue", "True Call Queueing", "")
app_queue:value("yes", "Load")
app_queue:value("no", "Do Not Load")
app_queue:value("auto", "Load as Required")
app_queue.rmempty = true
app_random = module:option(ListValue, "app_random", "Random goto", "")
app_random:value("yes", "Load")
app_random:value("no", "Do Not Load")
app_random:value("auto", "Load as Required")
app_random.rmempty = true
app_read = module:option(ListValue, "app_read", "Read Variable Application", "")
app_read:value("yes", "Load")
app_read:value("no", "Do Not Load")
app_read:value("auto", "Load as Required")
app_read.rmempty = true
app_readfile = module:option(ListValue, "app_readfile", "Read in a file", "")
app_readfile:value("yes", "Load")
app_readfile:value("no", "Do Not Load")
app_readfile:value("auto", "Load as Required")
app_readfile.rmempty = true
app_realtime = module:option(ListValue, "app_realtime", "Realtime Data Lookup/Rewrite", "")
app_realtime:value("yes", "Load")
app_realtime:value("no", "Do Not Load")
app_realtime:value("auto", "Load as Required")
app_realtime.rmempty = true
app_record = module:option(ListValue, "app_record", "Trivial Record Application", "")
app_record:value("yes", "Load")
app_record:value("no", "Do Not Load")
app_record:value("auto", "Load as Required")
app_record.rmempty = true
app_sayunixtime = module:option(ListValue, "app_sayunixtime", "Say time", "")
app_sayunixtime:value("yes", "Load")
app_sayunixtime:value("no", "Do Not Load")
app_sayunixtime:value("auto", "Load as Required")
app_sayunixtime.rmempty = true
app_senddtmf = module:option(ListValue, "app_senddtmf", "Send DTMF digits Application", "")
app_senddtmf:value("yes", "Load")
app_senddtmf:value("no", "Do Not Load")
app_senddtmf:value("auto", "Load as Required")
app_senddtmf.rmempty = true
app_sendtext = module:option(ListValue, "app_sendtext", "Send Text Applications", "")
app_sendtext:value("yes", "Load")
app_sendtext:value("no", "Do Not Load")
app_sendtext:value("auto", "Load as Required")
app_sendtext.rmempty = true
app_setcallerid = module:option(ListValue, "app_setcallerid", "Set CallerID Application", "")
app_setcallerid:value("yes", "Load")
app_setcallerid:value("no", "Do Not Load")
app_setcallerid:value("auto", "Load as Required")
app_setcallerid.rmempty = true
app_setcdruserfield = module:option(ListValue, "app_setcdruserfield", "CDR user field apps", "")
app_setcdruserfield:value("yes", "Load")
app_setcdruserfield:value("no", "Do Not Load")
app_setcdruserfield:value("auto", "Load as Required")
app_setcdruserfield.rmempty = true
app_setcidname = module:option(ListValue, "app_setcidname", "load => .so ; Set CallerID Name", "")
app_setcidname:value("yes", "Load")
app_setcidname:value("no", "Do Not Load")
app_setcidname:value("auto", "Load as Required")
app_setcidname.rmempty = true
app_setcidnum = module:option(ListValue, "app_setcidnum", "load => .so ; Set CallerID Number", "")
app_setcidnum:value("yes", "Load")
app_setcidnum:value("no", "Do Not Load")
app_setcidnum:value("auto", "Load as Required")
app_setcidnum.rmempty = true
app_setrdnis = module:option(ListValue, "app_setrdnis", "Set RDNIS Number", "")
app_setrdnis:value("yes", "Load")
app_setrdnis:value("no", "Do Not Load")
app_setrdnis:value("auto", "Load as Required")
app_setrdnis.rmempty = true
app_settransfercapability = module:option(ListValue, "app_settransfercapability", "Set ISDN Transfer Capability", "")
app_settransfercapability:value("yes", "Load")
app_settransfercapability:value("no", "Do Not Load")
app_settransfercapability:value("auto", "Load as Required")
app_settransfercapability.rmempty = true
app_sms = module:option(ListValue, "app_sms", "SMS/PSTN handler", "")
app_sms:value("yes", "Load")
app_sms:value("no", "Do Not Load")
app_sms:value("auto", "Load as Required")
app_sms.rmempty = true
app_softhangup = module:option(ListValue, "app_softhangup", "Hangs up the requested channel", "")
app_softhangup:value("yes", "Load")
app_softhangup:value("no", "Do Not Load")
app_softhangup:value("auto", "Load as Required")
app_softhangup.rmempty = true
app_stack = module:option(ListValue, "app_stack", "Stack Routines", "")
app_stack:value("yes", "Load")
app_stack:value("no", "Do Not Load")
app_stack:value("auto", "Load as Required")
app_stack.rmempty = true
app_system = module:option(ListValue, "app_system", "Generic System() application", "")
app_system:value("yes", "Load")
app_system:value("no", "Do Not Load")
app_system:value("auto", "Load as Required")
app_system.rmempty = true
app_talkdetect = module:option(ListValue, "app_talkdetect", "Playback with Talk Detection", "")
app_talkdetect:value("yes", "Load")
app_talkdetect:value("no", "Do Not Load")
app_talkdetect:value("auto", "Load as Required")
app_talkdetect.rmempty = true
app_test = module:option(ListValue, "app_test", "Interface Test Application", "")
app_test:value("yes", "Load")
app_test:value("no", "Do Not Load")
app_test:value("auto", "Load as Required")
app_test.rmempty = true
app_transfer = module:option(ListValue, "app_transfer", "Transfer", "")
app_transfer:value("yes", "Load")
app_transfer:value("no", "Do Not Load")
app_transfer:value("auto", "Load as Required")
app_transfer.rmempty = true
app_txtcidname = module:option(ListValue, "app_txtcidname", "TXTCIDName", "")
app_txtcidname:value("yes", "Load")
app_txtcidname:value("no", "Do Not Load")
app_txtcidname:value("auto", "Load as Required")
app_txtcidname.rmempty = true
app_url = module:option(ListValue, "app_url", "Send URL Applications", "")
app_url:value("yes", "Load")
app_url:value("no", "Do Not Load")
app_url:value("auto", "Load as Required")
app_url.rmempty = true
app_userevent = module:option(ListValue, "app_userevent", "Custom User Event Application", "")
app_userevent:value("yes", "Load")
app_userevent:value("no", "Do Not Load")
app_userevent:value("auto", "Load as Required")
app_userevent.rmempty = true
app_verbose = module:option(ListValue, "app_verbose", "Send verbose output", "")
app_verbose:value("yes", "Load")
app_verbose:value("no", "Do Not Load")
app_verbose:value("auto", "Load as Required")
app_verbose.rmempty = true
app_voicemail = module:option(ListValue, "app_voicemail", "Voicemail", "")
app_voicemail:value("yes", "Load")
app_voicemail:value("no", "Do Not Load")
app_voicemail:value("auto", "Load as Required")
app_voicemail.rmempty = true
app_waitforring = module:option(ListValue, "app_waitforring", "Waits until first ring after time", "")
app_waitforring:value("yes", "Load")
app_waitforring:value("no", "Do Not Load")
app_waitforring:value("auto", "Load as Required")
app_waitforring.rmempty = true
app_waitforsilence = module:option(ListValue, "app_waitforsilence", "Wait For Silence Application", "")
app_waitforsilence:value("yes", "Load")
app_waitforsilence:value("no", "Do Not Load")
app_waitforsilence:value("auto", "Load as Required")
app_waitforsilence.rmempty = true
app_while = module:option(ListValue, "app_while", "While Loops and Conditional Execution", "")
app_while:value("yes", "Load")
app_while:value("no", "Do Not Load")
app_while:value("auto", "Load as Required")
app_while.rmempty = true
return cbimap

View file

@ -1,58 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
module = cbimap:section(TypedSection, "module", "Modules", "")
module.anonymous = true
cdr_csv = module:option(ListValue, "cdr_csv", "Comma Separated Values CDR Backend", "")
cdr_csv:value("yes", "Load")
cdr_csv:value("no", "Do Not Load")
cdr_csv:value("auto", "Load as Required")
cdr_csv.rmempty = true
cdr_custom = module:option(ListValue, "cdr_custom", "Customizable Comma Separated Values CDR Backend", "")
cdr_custom:value("yes", "Load")
cdr_custom:value("no", "Do Not Load")
cdr_custom:value("auto", "Load as Required")
cdr_custom.rmempty = true
cdr_manager = module:option(ListValue, "cdr_manager", "Asterisk Call Manager CDR Backend", "")
cdr_manager:value("yes", "Load")
cdr_manager:value("no", "Do Not Load")
cdr_manager:value("auto", "Load as Required")
cdr_manager.rmempty = true
cdr_mysql = module:option(ListValue, "cdr_mysql", "MySQL CDR Backend", "")
cdr_mysql:value("yes", "Load")
cdr_mysql:value("no", "Do Not Load")
cdr_mysql:value("auto", "Load as Required")
cdr_mysql.rmempty = true
cdr_pgsql = module:option(ListValue, "cdr_pgsql", "PostgreSQL CDR Backend", "")
cdr_pgsql:value("yes", "Load")
cdr_pgsql:value("no", "Do Not Load")
cdr_pgsql:value("auto", "Load as Required")
cdr_pgsql.rmempty = true
cdr_sqlite = module:option(ListValue, "cdr_sqlite", "SQLite CDR Backend", "")
cdr_sqlite:value("yes", "Load")
cdr_sqlite:value("no", "Do Not Load")
cdr_sqlite:value("auto", "Load as Required")
cdr_sqlite.rmempty = true
return cbimap

View file

@ -1,56 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
module = cbimap:section(TypedSection, "module", "Modules", "")
module.anonymous = true
chan_agent = module:option(ListValue, "chan_agent", "Agent Proxy Channel", "")
chan_agent:value("yes", "Load")
chan_agent:value("no", "Do Not Load")
chan_agent:value("auto", "Load as Required")
chan_agent.rmempty = true
chan_alsa = module:option(ListValue, "chan_alsa", "Channel driver for GTalk", "")
chan_alsa:value("yes", "Load")
chan_alsa:value("no", "Do Not Load")
chan_alsa:value("auto", "Load as Required")
chan_alsa.rmempty = true
chan_gtalk = module:option(ListValue, "chan_gtalk", "Channel driver for GTalk", "")
chan_gtalk:value("yes", "Load")
chan_gtalk:value("no", "Do Not Load")
chan_gtalk:value("auto", "Load as Required")
chan_gtalk.rmempty = true
chan_iax2 = module:option(Flag, "chan_iax2", "Option chan_iax2", "")
chan_iax2.rmempty = true
chan_local = module:option(ListValue, "chan_local", "Local Proxy Channel", "")
chan_local:value("yes", "Load")
chan_local:value("no", "Do Not Load")
chan_local:value("auto", "Load as Required")
chan_local.rmempty = true
chan_sip = module:option(ListValue, "chan_sip", "Session Initiation Protocol (SIP)", "")
chan_sip:value("yes", "Load")
chan_sip:value("no", "Do Not Load")
chan_sip:value("auto", "Load as Required")
chan_sip.rmempty = true
return cbimap

View file

@ -1,64 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
module = cbimap:section(TypedSection, "module", "Modules", "")
module.anonymous = true
codec_a_mu = module:option(ListValue, "codec_a_mu", "A-law and Mulaw direct Coder/Decoder", "")
codec_a_mu:value("yes", "Load")
codec_a_mu:value("no", "Do Not Load")
codec_a_mu:value("auto", "Load as Required")
codec_a_mu.rmempty = true
codec_adpcm = module:option(ListValue, "codec_adpcm", "Adaptive Differential PCM Coder/Decoder", "")
codec_adpcm:value("yes", "Load")
codec_adpcm:value("no", "Do Not Load")
codec_adpcm:value("auto", "Load as Required")
codec_adpcm.rmempty = true
codec_alaw = module:option(ListValue, "codec_alaw", "A-law Coder/Decoder", "")
codec_alaw:value("yes", "Load")
codec_alaw:value("no", "Do Not Load")
codec_alaw:value("auto", "Load as Required")
codec_alaw.rmempty = true
codec_g726 = module:option(ListValue, "codec_g726", "ITU G.726-32kbps G726 Transcoder", "")
codec_g726:value("yes", "Load")
codec_g726:value("no", "Do Not Load")
codec_g726:value("auto", "Load as Required")
codec_g726.rmempty = true
codec_gsm = module:option(ListValue, "codec_gsm", "GSM/PCM16 (signed linear) Codec Translation", "")
codec_gsm:value("yes", "Load")
codec_gsm:value("no", "Do Not Load")
codec_gsm:value("auto", "Load as Required")
codec_gsm.rmempty = true
codec_speex = module:option(ListValue, "codec_speex", "Speex/PCM16 (signed linear) Codec Translator", "")
codec_speex:value("yes", "Load")
codec_speex:value("no", "Do Not Load")
codec_speex:value("auto", "Load as Required")
codec_speex.rmempty = true
codec_ulaw = module:option(ListValue, "codec_ulaw", "Mu-law Coder/Decoder", "")
codec_ulaw:value("yes", "Load")
codec_ulaw:value("no", "Do Not Load")
codec_ulaw:value("auto", "Load as Required")
codec_ulaw.rmempty = true
return cbimap

View file

@ -1,100 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
module = cbimap:section(TypedSection, "module", "Modules", "")
module.anonymous = true
format_au = module:option(ListValue, "format_au", "Sun Microsystems AU format (signed linear)", "")
format_au:value("yes", "Load")
format_au:value("no", "Do Not Load")
format_au:value("auto", "Load as Required")
format_au.rmempty = true
format_g723 = module:option(ListValue, "format_g723", "G.723.1 Simple Timestamp File Format", "")
format_g723:value("yes", "Load")
format_g723:value("no", "Do Not Load")
format_g723:value("auto", "Load as Required")
format_g723.rmempty = true
format_g726 = module:option(ListValue, "format_g726", "Raw G.726 (16/24/32/40kbps) data", "")
format_g726:value("yes", "Load")
format_g726:value("no", "Do Not Load")
format_g726:value("auto", "Load as Required")
format_g726.rmempty = true
format_g729 = module:option(ListValue, "format_g729", "Raw G729 data", "")
format_g729:value("yes", "Load")
format_g729:value("no", "Do Not Load")
format_g729:value("auto", "Load as Required")
format_g729.rmempty = true
format_gsm = module:option(ListValue, "format_gsm", "Raw GSM data", "")
format_gsm:value("yes", "Load")
format_gsm:value("no", "Do Not Load")
format_gsm:value("auto", "Load as Required")
format_gsm.rmempty = true
format_h263 = module:option(ListValue, "format_h263", "Raw h263 data", "")
format_h263:value("yes", "Load")
format_h263:value("no", "Do Not Load")
format_h263:value("auto", "Load as Required")
format_h263.rmempty = true
format_jpeg = module:option(ListValue, "format_jpeg", "JPEG (Joint Picture Experts Group) Image", "")
format_jpeg:value("yes", "Load")
format_jpeg:value("no", "Do Not Load")
format_jpeg:value("auto", "Load as Required")
format_jpeg.rmempty = true
format_pcm = module:option(ListValue, "format_pcm", "Raw uLaw 8khz Audio support (PCM)", "")
format_pcm:value("yes", "Load")
format_pcm:value("no", "Do Not Load")
format_pcm:value("auto", "Load as Required")
format_pcm.rmempty = true
format_pcm_alaw = module:option(ListValue, "format_pcm_alaw", "load => .so ; Raw aLaw 8khz PCM Audio support", "")
format_pcm_alaw:value("yes", "Load")
format_pcm_alaw:value("no", "Do Not Load")
format_pcm_alaw:value("auto", "Load as Required")
format_pcm_alaw.rmempty = true
format_sln = module:option(ListValue, "format_sln", "Raw Signed Linear Audio support (SLN)", "")
format_sln:value("yes", "Load")
format_sln:value("no", "Do Not Load")
format_sln:value("auto", "Load as Required")
format_sln.rmempty = true
format_vox = module:option(ListValue, "format_vox", "Dialogic VOX (ADPCM) File Format", "")
format_vox:value("yes", "Load")
format_vox:value("no", "Do Not Load")
format_vox:value("auto", "Load as Required")
format_vox.rmempty = true
format_wav = module:option(ListValue, "format_wav", "Microsoft WAV format (8000hz Signed Line", "")
format_wav:value("yes", "Load")
format_wav:value("no", "Do Not Load")
format_wav:value("auto", "Load as Required")
format_wav.rmempty = true
format_wav_gsm = module:option(ListValue, "format_wav_gsm", "Microsoft WAV format (Proprietary GSM)", "")
format_wav_gsm:value("yes", "Load")
format_wav_gsm:value("no", "Do Not Load")
format_wav_gsm:value("auto", "Load as Required")
format_wav_gsm.rmempty = true
return cbimap

View file

@ -1,40 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
module = cbimap:section(TypedSection, "module", "Modules", "")
module.anonymous = true
func_callerid = module:option(ListValue, "func_callerid", "Caller ID related dialplan functions", "")
func_callerid:value("yes", "Load")
func_callerid:value("no", "Do Not Load")
func_callerid:value("auto", "Load as Required")
func_callerid.rmempty = true
func_enum = module:option(ListValue, "func_enum", "ENUM Functions", "")
func_enum:value("yes", "Load")
func_enum:value("no", "Do Not Load")
func_enum:value("auto", "Load as Required")
func_enum.rmempty = true
func_uri = module:option(ListValue, "func_uri", "URI encoding / decoding functions", "")
func_uri:value("yes", "Load")
func_uri:value("no", "Do Not Load")
func_uri:value("auto", "Load as Required")
func_uri.rmempty = true
return cbimap

View file

@ -1,64 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
module = cbimap:section(TypedSection, "module", "Modules", "")
module.anonymous = true
pbx_ael = module:option(ListValue, "pbx_ael", "Asterisk Extension Language Compiler", "")
pbx_ael:value("yes", "Load")
pbx_ael:value("no", "Do Not Load")
pbx_ael:value("auto", "Load as Required")
pbx_ael.rmempty = true
pbx_config = module:option(ListValue, "pbx_config", "Text Extension Configuration", "")
pbx_config:value("yes", "Load")
pbx_config:value("no", "Do Not Load")
pbx_config:value("auto", "Load as Required")
pbx_config.rmempty = true
pbx_functions = module:option(ListValue, "pbx_functions", "load => .so ; Builtin dialplan functions", "")
pbx_functions:value("yes", "Load")
pbx_functions:value("no", "Do Not Load")
pbx_functions:value("auto", "Load as Required")
pbx_functions.rmempty = true
pbx_loopback = module:option(ListValue, "pbx_loopback", "Loopback Switch", "")
pbx_loopback:value("yes", "Load")
pbx_loopback:value("no", "Do Not Load")
pbx_loopback:value("auto", "Load as Required")
pbx_loopback.rmempty = true
pbx_realtime = module:option(ListValue, "pbx_realtime", "Realtime Switch", "")
pbx_realtime:value("yes", "Load")
pbx_realtime:value("no", "Do Not Load")
pbx_realtime:value("auto", "Load as Required")
pbx_realtime.rmempty = true
pbx_spool = module:option(ListValue, "pbx_spool", "Outgoing Spool Support", "")
pbx_spool:value("yes", "Load")
pbx_spool:value("no", "Do Not Load")
pbx_spool:value("auto", "Load as Required")
pbx_spool.rmempty = true
pbx_wilcalu = module:option(ListValue, "pbx_wilcalu", "Wil Cal U (Auto Dialer)", "")
pbx_wilcalu:value("yes", "Load")
pbx_wilcalu:value("no", "Do Not Load")
pbx_wilcalu:value("auto", "Load as Required")
pbx_wilcalu.rmempty = true
return cbimap

View file

@ -1,111 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
featuremap = cbimap:section(TypedSection, "featuremap", "Feature Key maps", "")
featuremap.anonymous = true
featuremap.addremove = true
atxfer = featuremap:option(Value, "atxfer", "Attended transfer key", "")
atxfer.rmempty = true
blindxfer = featuremap:option(Value, "blindxfer", "Blind transfer key", "")
blindxfer.rmempty = true
disconnect = featuremap:option(Value, "disconnect", "Key to Disconnect call", "")
disconnect.rmempty = true
parkcall = featuremap:option(Value, "parkcall", "Key to Park call", "")
parkcall.rmempty = true
featurepark = cbimap:section(TypedSection, "featurepark", "Parking Feature", "")
featurepark.anonymous = true
parkenabled = featurepark:option(Flag, "parkenabled", "Enable Parking", "")
adsipark = featurepark:option(Flag, "adsipark", "ADSI Park", "")
adsipark.rmempty = true
adsipark:depends({ parkenabled = "1" })
atxfernoanswertimeout = featurepark:option(Value, "atxfernoanswertimeout", "Attended transfer timeout (sec)", "")
atxfernoanswertimeout.rmempty = true
atxfernoanswertimeout:depends({ parkenabled = "1" })
automon = featurepark:option(Value, "automon", "One touch record key", "")
automon.rmempty = true
automon:depends({ parkenabled = "1" })
context = featurepark:option(Value, "context", "Name of call context for parking", "")
context.rmempty = true
context:depends({ parkenabled = "1" })
courtesytone = featurepark:option(Value, "courtesytone", "Sound file to play to parked caller", "")
courtesytone.rmempty = true
courtesytone:depends({ parkenabled = "1" })
featuredigittimeout = featurepark:option(Value, "featuredigittimeout", "Max time (ms) between digits for feature activation", "")
featuredigittimeout.rmempty = true
featuredigittimeout:depends({ parkenabled = "1" })
findslot = featurepark:option(ListValue, "findslot", "Method to Find Parking slot", "")
findslot:value("first", "First available slot")
findslot:value("next", "Next free parking space")
findslot.rmempty = true
findslot:depends({ parkenabled = "1" })
parkedmusicclass = featurepark:option(ListValue, "parkedmusicclass", "Music on Hold class for the parked channel", "")
parkedmusicclass.titleref = luci.dispatcher.build_url( "admin", "services", "asterisk" )
parkedmusicclass:depends({ parkenabled = "1" })
cbimap.uci:foreach( "asterisk", "moh", function(s) parkedmusicclass:value(s['.name']) end )
parkedplay = featurepark:option(ListValue, "parkedplay", "Play courtesy tone to", "")
parkedplay:value("caller", "Caller")
parkedplay:value("parked", "Parked user")
parkedplay:value("both", "Both")
parkedplay.rmempty = true
parkedplay:depends({ parkenabled = "1" })
parkext = featurepark:option(Value, "parkext", "Extension to dial to park", "")
parkext.rmempty = true
parkext:depends({ parkenabled = "1" })
parkingtime = featurepark:option(Value, "parkingtime", "Parking time (secs)", "")
parkingtime.rmempty = true
parkingtime:depends({ parkenabled = "1" })
parkpos = featurepark:option(Value, "parkpos", "Range of extensions for call parking", "")
parkpos.rmempty = true
parkpos:depends({ parkenabled = "1" })
pickupexten = featurepark:option(Value, "pickupexten", "Pickup extension", "")
pickupexten.rmempty = true
pickupexten:depends({ parkenabled = "1" })
transferdigittimeout = featurepark:option(Value, "transferdigittimeout", "Seconds to wait bewteen digits when transferring", "")
transferdigittimeout.rmempty = true
transferdigittimeout:depends({ parkenabled = "1" })
xferfailsound = featurepark:option(Value, "xferfailsound", "sound when attended transfer is complete", "")
xferfailsound.rmempty = true
xferfailsound:depends({ parkenabled = "1" })
xfersound = featurepark:option(Value, "xfersound", "Sound when attended transfer fails", "")
xfersound.rmempty = true
xfersound:depends({ parkenabled = "1" })
return cbimap

View file

@ -1,88 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
module = cbimap:section(TypedSection, "module", "Modules", "")
module.anonymous = true
res_config_mysql = module:option(ListValue, "res_config_mysql", "MySQL Config Resource", "")
res_config_mysql:value("yes", "Load")
res_config_mysql:value("no", "Do Not Load")
res_config_mysql:value("auto", "Load as Required")
res_config_mysql.rmempty = true
res_config_odbc = module:option(ListValue, "res_config_odbc", "ODBC Config Resource", "")
res_config_odbc:value("yes", "Load")
res_config_odbc:value("no", "Do Not Load")
res_config_odbc:value("auto", "Load as Required")
res_config_odbc.rmempty = true
res_config_pgsql = module:option(ListValue, "res_config_pgsql", "PGSQL Module", "")
res_config_pgsql:value("yes", "Load")
res_config_pgsql:value("no", "Do Not Load")
res_config_pgsql:value("auto", "Load as Required")
res_config_pgsql.rmempty = true
res_crypto = module:option(ListValue, "res_crypto", "Cryptographic Digital Signatures", "")
res_crypto:value("yes", "Load")
res_crypto:value("no", "Do Not Load")
res_crypto:value("auto", "Load as Required")
res_crypto.rmempty = true
res_features = module:option(ListValue, "res_features", "Call Parking Resource", "")
res_features:value("yes", "Load")
res_features:value("no", "Do Not Load")
res_features:value("auto", "Load as Required")
res_features.rmempty = true
res_indications = module:option(ListValue, "res_indications", "Indications Configuration", "")
res_indications:value("yes", "Load")
res_indications:value("no", "Do Not Load")
res_indications:value("auto", "Load as Required")
res_indications.rmempty = true
res_monitor = module:option(ListValue, "res_monitor", "Call Monitoring Resource", "")
res_monitor:value("yes", "Load")
res_monitor:value("no", "Do Not Load")
res_monitor:value("auto", "Load as Required")
res_monitor.rmempty = true
res_musiconhold = module:option(ListValue, "res_musiconhold", "Music On Hold Resource", "")
res_musiconhold:value("yes", "Load")
res_musiconhold:value("no", "Do Not Load")
res_musiconhold:value("auto", "Load as Required")
res_musiconhold.rmempty = true
res_odbc = module:option(ListValue, "res_odbc", "ODBC Resource", "")
res_odbc:value("yes", "Load")
res_odbc:value("no", "Do Not Load")
res_odbc:value("auto", "Load as Required")
res_odbc.rmempty = true
res_smdi = module:option(ListValue, "res_smdi", "SMDI Module", "")
res_smdi:value("yes", "Load")
res_smdi:value("no", "Do Not Load")
res_smdi:value("auto", "Load as Required")
res_smdi.rmempty = true
res_snmp = module:option(ListValue, "res_snmp", "SNMP Module", "")
res_snmp:value("yes", "Load")
res_snmp:value("no", "Do Not Load")
res_snmp:value("auto", "Load as Required")
res_snmp.rmempty = true
return cbimap

View file

@ -1,109 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
sip = cbimap:section(TypedSection, "sip", "SIP Connection", "")
sip.addremove = true
alwaysinternational = sip:option(Flag, "alwaysinternational", "Always Dial International", "")
alwaysinternational.optional = true
canreinvite = sip:option(ListValue, "canreinvite", "Reinvite/redirect media connections", "")
canreinvite:value("yes", "Yes")
canreinvite:value("nonat", "Yes when not behind NAT")
canreinvite:value("update", "Use UPDATE rather than INVITE for path redirection")
canreinvite:value("no", "No")
canreinvite.optional = true
context = sip:option(ListValue, "context", "Context to use", "")
context.titleref = luci.dispatcher.build_url( "admin", "services", "asterisk", "dialplans" )
cbimap.uci:foreach( "asterisk", "dialplan", function(s) context:value(s['.name']) end )
cbimap.uci:foreach( "asterisk", "dialzone", function(s) context:value(s['.name']) end )
countrycode = sip:option(Value, "countrycode", "Country Code for connection", "")
countrycode.optional = true
dtmfmode = sip:option(ListValue, "dtmfmode", "DTMF mode", "")
dtmfmode:value("info", "Use RFC2833 or INFO for the BudgeTone")
dtmfmode:value("rfc2833", "Use RFC2833 for the BudgeTone")
dtmfmode:value("inband", "Use Inband (only with ulaw/alaw)")
dtmfmode.optional = true
extension = sip:option(Value, "extension", "Add as Extension", "")
extension.optional = true
fromdomain = sip:option(Value, "fromdomain", "Primary domain identity for From: headers", "")
fromdomain.optional = true
fromuser = sip:option(Value, "fromuser", "From user (required by many SIP providers)", "")
fromuser.optional = true
host = sip:option(Value, "host", "Host name (or blank)", "")
host.optional = true
incoming = sip:option(DynamicList, "incoming", "Ring on incoming dialplan contexts", "")
incoming.optional = true
insecure = sip:option(ListValue, "insecure", "Allow Insecure for", "")
insecure:value("port", "Allow mismatched port number")
insecure:value("invite", "Do not require auth of incoming INVITE")
insecure:value("port,invite", "Allow mismatched port and Do not require auth of incoming INVITE")
insecure.optional = true
internationalprefix = sip:option(Value, "internationalprefix", "International Dial Prefix", "")
internationalprefix.optional = true
mailbox = sip:option(Value, "mailbox", "Mailbox for MWI", "")
mailbox.optional = true
nat = sip:option(Flag, "nat", "NAT between phone and Asterisk", "")
nat.optional = true
pedantic = sip:option(Flag, "pedantic", "Check tags in headers", "")
pedantic.optional = true
port = sip:option(Value, "port", "SIP Port", "")
port.optional = true
prefix = sip:option(Value, "prefix", "Dial Prefix (for external line)", "")
prefix.optional = true
qualify = sip:option(Value, "qualify", "Reply Timeout (ms) for down connection", "")
qualify.optional = true
register = sip:option(Flag, "register", "Register connection", "")
register.optional = true
secret = sip:option(Value, "secret", "Secret", "")
secret.optional = true
selfmailbox = sip:option(Flag, "selfmailbox", "Dial own extension for mailbox", "")
selfmailbox.optional = true
timeout = sip:option(Value, "timeout", "Dial Timeout (sec)", "")
timeout.optional = true
type = sip:option(ListValue, "type", "Client Type", "")
type:value("friend", "Friend (outbound/inbound)")
type:value("user", "User (inbound - authenticate by \"from\")")
type:value("peer", "Peer (outbound - match by host)")
type.optional = true
username = sip:option(Value, "username", "Username", "")
username.optional = true
return cbimap

View file

@ -1,52 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
voicegeneral = cbimap:section(TypedSection, "voicegeneral", "Voicemail general options", "")
serveremail = voicegeneral:option(Value, "serveremail", "From Email address of server", "")
voicemail = cbimap:section(TypedSection, "voicemail", "Voice Mail boxes", "")
voicemail.addremove = true
attach = voicemail:option(Flag, "attach", "Email contains attachment", "")
attach.rmempty = true
email = voicemail:option(Value, "email", "Email", "")
email.rmempty = true
name = voicemail:option(Value, "name", "Display Name", "")
name.rmempty = true
password = voicemail:option(Value, "password", "Password", "")
password.rmempty = true
zone = voicemail:option(ListValue, "zone", "Voice Zone", "")
cbimap.uci:foreach( "asterisk", "voicezone", function(s) zone:value(s['.name']) end )
voicezone = cbimap:section(TypedSection, "voicezone", "Voice Zone settings", "")
voicezone.addremove = true
message = voicezone:option(Value, "message", "Message Format", "")
message.rmempty = true
zone = voicezone:option(Value, "zone", "Time Zone", "")
zone.rmempty = true
return cbimap

View file

@ -1,162 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "asterisk", "")
asterisk = cbimap:section(TypedSection, "asterisk", "Asterisk General Options", "")
asterisk.anonymous = true
agidir = asterisk:option(Value, "agidir", "AGI directory", "")
agidir.rmempty = true
cache_record_files = asterisk:option(Flag, "cache_record_files", "Cache recorded sound files during recording", "")
cache_record_files.rmempty = true
debug = asterisk:option(Value, "debug", "Debug Level", "")
debug.rmempty = true
dontwarn = asterisk:option(Flag, "dontwarn", "Disable some warnings", "")
dontwarn.rmempty = true
dumpcore = asterisk:option(Flag, "dumpcore", "Dump core on crash", "")
dumpcore.rmempty = true
highpriority = asterisk:option(Flag, "highpriority", "High Priority", "")
highpriority.rmempty = true
initcrypto = asterisk:option(Flag, "initcrypto", "Initialise Crypto", "")
initcrypto.rmempty = true
internal_timing = asterisk:option(Flag, "internal_timing", "Use Internal Timing", "")
internal_timing.rmempty = true
logdir = asterisk:option(Value, "logdir", "Log directory", "")
logdir.rmempty = true
maxcalls = asterisk:option(Value, "maxcalls", "Maximum number of calls allowed", "")
maxcalls.rmempty = true
maxload = asterisk:option(Value, "maxload", "Maximum load to stop accepting new calls", "")
maxload.rmempty = true
nocolor = asterisk:option(Flag, "nocolor", "Disable console colors", "")
nocolor.rmempty = true
record_cache_dir = asterisk:option(Value, "record_cache_dir", "Sound files Cache directory", "")
record_cache_dir.rmempty = true
record_cache_dir:depends({ ["cache_record_files"] = "true" })
rungroup = asterisk:option(Flag, "rungroup", "The Group to run as", "")
rungroup.rmempty = true
runuser = asterisk:option(Flag, "runuser", "The User to run as", "")
runuser.rmempty = true
spooldir = asterisk:option(Value, "spooldir", "Voicemail Spool directory", "")
spooldir.rmempty = true
systemname = asterisk:option(Value, "systemname", "Prefix UniquID with system name", "")
systemname.rmempty = true
transcode_via_sln = asterisk:option(Flag, "transcode_via_sln", "Build transcode paths via SLINEAR, not directly", "")
transcode_via_sln.rmempty = true
transmit_silence_during_record = asterisk:option(Flag, "transmit_silence_during_record", "Transmit SLINEAR silence while recording a channel", "")
transmit_silence_during_record.rmempty = true
verbose = asterisk:option(Value, "verbose", "Verbose Level", "")
verbose.rmempty = true
zone = asterisk:option(Value, "zone", "Time Zone", "")
zone.rmempty = true
hardwarereboot = cbimap:section(TypedSection, "hardwarereboot", "Reload Hardware Config", "")
method = hardwarereboot:option(ListValue, "method", "Reboot Method", "")
method:value("web", "Web URL (wget)")
method:value("system", "program to run")
method.rmempty = true
param = hardwarereboot:option(Value, "param", "Parameter", "")
param.rmempty = true
iaxgeneral = cbimap:section(TypedSection, "iaxgeneral", "IAX General Options", "")
iaxgeneral.anonymous = true
iaxgeneral.addremove = true
allow = iaxgeneral:option(MultiValue, "allow", "Allow Codecs", "")
allow:value("alaw", "alaw")
allow:value("gsm", "gsm")
allow:value("g726", "g726")
allow.rmempty = true
canreinvite = iaxgeneral:option(ListValue, "canreinvite", "Reinvite/redirect media connections", "")
canreinvite:value("yes", "Yes")
canreinvite:value("nonat", "Yes when not behind NAT")
canreinvite:value("update", "Use UPDATE rather than INVITE for path redirection")
canreinvite:value("no", "No")
canreinvite.rmempty = true
static = iaxgeneral:option(Flag, "static", "Static", "")
static.rmempty = true
writeprotect = iaxgeneral:option(Flag, "writeprotect", "Write Protect", "")
writeprotect.rmempty = true
sipgeneral = cbimap:section(TypedSection, "sipgeneral", "Section sipgeneral", "")
sipgeneral.anonymous = true
sipgeneral.addremove = true
allow = sipgeneral:option(MultiValue, "allow", "Allow codecs", "")
allow:value("ulaw", "ulaw")
allow:value("alaw", "alaw")
allow:value("gsm", "gsm")
allow:value("g726", "g726")
allow.rmempty = true
port = sipgeneral:option(Value, "port", "SIP Port", "")
port.rmempty = true
realm = sipgeneral:option(Value, "realm", "SIP realm", "")
realm.rmempty = true
moh = cbimap:section(TypedSection, "moh", "Music On Hold", "")
application = moh:option(Value, "application", "Application", "")
application.rmempty = true
application:depends({ ["asterisk.moh.mode"] = "custom" })
directory = moh:option(Value, "directory", "Directory of Music", "")
directory.rmempty = true
mode = moh:option(ListValue, "mode", "Option mode", "")
mode:value("system", "program to run")
mode:value("files", "Read files from directory")
mode:value("quietmp3", "Quite MP3")
mode:value("mp3", "Loud MP3")
mode:value("mp3nb", "unbuffered MP3")
mode:value("quietmp3nb", "Quiet Unbuffered MP3")
mode:value("custom", "Run a custom application")
mode.rmempty = true
random = moh:option(Flag, "random", "Random Play", "")
random.rmempty = true
return cbimap

View file

@ -1,137 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local ast = require("luci.asterisk")
local function find_outgoing_contexts(uci)
local c = { }
local h = { }
-- uci:foreach("asterisk", "dialplan",
-- function(s)
-- if not h[s['.name']] then
-- c[#c+1] = { s['.name'], "Dialplan: %s" % s['.name'] }
-- h[s['.name']] = true
-- end
-- end)
uci:foreach("asterisk", "dialzone",
function(s)
if not h[s['.name']] then
c[#c+1] = { s['.name'], "Dialzone: %s" % s['.name'] }
h[s['.name']] = true
end
end)
return c
end
local function find_incoming_contexts(uci)
local c = { }
local h = { }
uci:foreach("asterisk", "sip",
function(s)
if s.context and not h[s.context] and
uci:get_bool("asterisk", s['.name'], "provider")
then
c[#c+1] = { s.context, "Incoming: %s" % s['.name'] or s.context }
h[s.context] = true
end
end)
return c
end
local function find_trunks(uci)
local t = { }
uci:foreach("asterisk", "sip",
function(s)
if uci:get_bool("asterisk", s['.name'], "provider") then
t[#t+1] = {
"SIP/%s" % s['.name'],
"SIP: %s" % s['.name']
}
end
end)
uci:foreach("asterisk", "iax",
function(s)
t[#t+1] = {
"IAX/%s" % s['.name'],
"IAX: %s" % s.extension or s['.name']
}
end)
return t
end
--[[
dialzone {name} - Outgoing zone.
uses - Outgoing line to use: TYPE/Name
match (list) - Number to match
countrycode - The effective country code of this dialzone
international (list) - International prefix to match
localzone - dialzone for local numbers
addprefix - Prexix required to dial out.
localprefix - Prefix for a local call
]]
--
-- SIP dialzone configuration
--
if arg[1] then
cbimap = Map("asterisk", "Edit Dialplan Entry")
entry = cbimap:section(NamedSection, arg[1])
back = entry:option(DummyValue, "_overview", "Back to dialplan overview")
back.value = ""
back.titleref = luci.dispatcher.build_url("admin", "asterisk", "dialplans")
desc = entry:option(Value, "description", "Description")
function desc.cfgvalue(self, s, ...)
return Value.cfgvalue(self, s, ...) or s
end
match = entry:option(DynamicList, "match", "Number matches")
intl = entry:option(DynamicList, "international", "Intl. prefix matches (optional)")
trunk = entry:option(MultiValue, "uses", "Used trunk")
for _, v in ipairs(find_trunks(cbimap.uci)) do
trunk:value(unpack(v))
end
aprefix = entry:option(Value, "addprefix", "Add prefix to dial out (optional)")
--ast.idd.cbifill(aprefix)
ccode = entry:option(Value, "countrycode", "Effective countrycode (optional)")
ast.cc.cbifill(ccode)
lzone = entry:option(ListValue, "localzone", "Dialzone for local numbers")
lzone:value("", "no special treatment of local numbers")
for _, v in ipairs(find_outgoing_contexts(cbimap.uci)) do
lzone:value(unpack(v))
end
lprefix = entry:option(Value, "localprefix", "Prefix for local calls (optional)")
return cbimap
end

View file

@ -1,115 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local ast = require("luci.asterisk")
cbimap = Map("asterisk", "Registered Trunks")
cbimap.pageaction = false
local sip_peers = { }
cbimap.uci:foreach("asterisk", "sip",
function(s)
if s.type == "peer" then
s.name = s['.name']
s.info = ast.sip.peer(s.name)
sip_peers[s.name] = s
end
end)
sip_table = cbimap:section(TypedSection, "sip", "SIP Trunks")
sip_table.template = "cbi/tblsection"
sip_table.extedit = luci.dispatcher.build_url("admin", "asterisk", "trunks", "sip", "%s")
sip_table.addremove = true
sip_table.sectionhead = "Extension"
function sip_table.filter(self, s)
return s and (
cbimap.uci:get("asterisk", s, "type") == nil or
cbimap.uci:get_bool("asterisk", s, "provider")
)
end
function sip_table.create(self, section)
if TypedSection.create(self, section) then
created = section
else
self.invalid_cts = true
end
end
function sip_table.parse(self, ...)
TypedSection.parse(self, ...)
if created then
cbimap.uci:tset("asterisk", created, {
type = "friend",
qualify = "yes",
provider = "yes"
})
cbimap.uci:save("asterisk")
luci.http.redirect(luci.dispatcher.build_url(
"admin", "asterisk", "trunks", "sip", created
))
end
end
user = sip_table:option(DummyValue, "username", "Username")
host = sip_table:option(DummyValue, "host", "Hostname")
function host.cfgvalue(self, s)
if sip_peers[s] and sip_peers[s].info.address then
return "%s:%i" %{ sip_peers[s].info.address, sip_peers[s].info.port }
else
return "n/a"
end
end
context = sip_table:option(DummyValue, "context", "Dialplan")
context.href = luci.dispatcher.build_url("admin", "asterisk", "dialplan")
function context.cfgvalue(...)
return AbstractValue.cfgvalue(...) or "(default)"
end
online = sip_table:option(DummyValue, "online", "Registered")
function online.cfgvalue(self, s)
if sip_peers[s] and sip_peers[s].info.online == nil then
return "n/a"
else
return sip_peers[s] and sip_peers[s].info.online
and "yes" or "no (%s)" %{
sip_peers[s] and sip_peers[s].info.Status:lower() or "unknown"
}
end
end
delay = sip_table:option(DummyValue, "delay", "Delay")
function delay.cfgvalue(self, s)
if sip_peers[s] and sip_peers[s].info.online then
return "%i ms" % sip_peers[s].info.delay
else
return "n/a"
end
end
info = sip_table:option(Button, "_info", "Info")
function info.write(self, s)
luci.http.redirect(luci.dispatcher.build_url(
"admin", "asterisk", "trunks", "sip", s, "info"
))
end
return cbimap

View file

@ -1,135 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id: trunks.lua 4025 2009-01-11 23:37:21Z jow $
]]--
local ast = require("luci.asterisk")
local uci = require("luci.model.uci").cursor()
--[[
Dialzone overview table
]]
if not arg[1] then
zonemap = Map("asterisk", "Dial Zones", [[
Dial zones hold patterns of dialed numbers to match.
Each zone has one or more trunks assigned. If the first trunk is
congested, Asterisk will try to use the next available connection.
If all trunks fail, then the following zones in the parent dialplan
are tried.
]])
local zones, znames = ast.dialzone.zones()
zonetbl = zonemap:section(Table, zones, "Zone Overview")
zonetbl.sectionhead = "Zone"
zonetbl.addremove = true
zonetbl.anonymous = false
zonetbl.extedit = luci.dispatcher.build_url(
"admin", "asterisk", "dialplans", "zones", "%s"
)
function zonetbl.cfgsections(self)
return znames
end
function zonetbl.parse(self)
for k, v in pairs(self.map:formvaluetable(
luci.cbi.REMOVE_PREFIX .. self.config
) or {}) do
if k:sub(-2) == ".x" then k = k:sub(1, #k - 2) end
uci:delete("asterisk", k)
uci:save("asterisk")
self.data[k] = nil
for i = 1,#znames do
if znames[i] == k then
table.remove(znames, i)
break
end
end
end
Table.parse(self)
end
zonetbl:option(DummyValue, "description", "Description")
zonetbl:option(DummyValue, "addprefix")
match = zonetbl:option(DummyValue, "matches")
function match.cfgvalue(self, s)
return table.concat(zones[s].matches, ", ")
end
trunks = zonetbl:option(DummyValue, "trunk")
trunks.template = "asterisk/cbi/cell"
function trunks.cfgvalue(self, s)
return ast.tools.hyperlinks(zones[s].trunks)
end
return zonemap
--[[
Zone edit form
]]
else
zoneedit = Map("asterisk", "Edit Dialzone")
entry = zoneedit:section(NamedSection, arg[1])
entry.title = "Zone %q" % arg[1];
back = entry:option(DummyValue, "_overview", "Back to dialzone overview")
back.value = ""
back.titleref = luci.dispatcher.build_url(
"admin", "asterisk", "dialplans", "zones"
)
desc = entry:option(Value, "description", "Description")
function desc.cfgvalue(self, s, ...)
return Value.cfgvalue(self, s, ...) or s
end
trunks = entry:option(MultiValue, "uses", "Used trunks")
trunks.widget = "checkbox"
uci:foreach("asterisk", "sip",
function(s)
if s.provider == "yes" then
trunks:value(
"SIP/%s" % s['.name'],
"SIP/%s (%s)" %{ s['.name'], s.host or 'n/a' }
)
end
end)
match = entry:option(DynamicList, "match", "Number matches")
intl = entry:option(DynamicList, "international", "Intl. prefix matches (optional)")
aprefix = entry:option(Value, "addprefix", "Add prefix to dial out (optional)")
ccode = entry:option(Value, "countrycode", "Effective countrycode (optional)")
lzone = entry:option(ListValue, "localzone", "Dialzone for local numbers")
lzone:value("", "no special treatment of local numbers")
for _, z in ipairs(ast.dialzone.zones()) do
lzone:value(z.name, "%q (%s)" %{ z.name, z.description })
end
--for _, v in ipairs(find_outgoing_contexts(zoneedit.uci)) do
-- lzone:value(unpack(v))
--end
lprefix = entry:option(Value, "localprefix", "Prefix for local calls (optional)")
return zoneedit
end

View file

@ -1,49 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2009 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local ast = require "luci.asterisk"
cbimap = Map("asterisk", "MeetMe - Rooms")
meetme = cbimap:section(TypedSection, "meetme", "MeetMe Rooms")
meetme.addremove = true
meetme.anonymous = true
meetme.template = "cbi/tblsection"
meetme:option(Value, "_description", "Description", "Short room description")
room = meetme:option(Value, "room", "Room Number", "Unique room identifier")
function room.write(self, s, val)
if val and #val > 0 then
local old = self:cfgvalue(s)
self.map.uci:foreach("asterisk", "dialplanmeetme",
function(v)
if v.room == old then
self.map:set(v['.name'], "room", val)
end
end)
Value.write(self, s, val)
end
end
meetme:option(Value, "pin", "PIN", "PIN required to access")
meetme:option(Value, "adminpin", "Admin PIN", "PIN required for administration")
function meetme.remove(self, s)
return ast.meetme.remove(self.map:get(s, "room"), self.map.uci)
end
return cbimap

View file

@ -1,28 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2009 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
cbimap = Map("asterisk", "MeetMe - Common Settings",
"Common settings for MeetMe phone conferences.")
meetme = cbimap:section(TypedSection, "meetmegeneral", "General MeetMe Options")
meetme.addremove = false
meetme.anonymous = true
audiobuffers = meetme:option(ListValue, "audiobuffers",
"Number of 20ms audio buffers to use for conferences")
for i = 2, 32 do audiobuffers:value(i) end
return cbimap

View file

@ -1,157 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local ast = require("luci.asterisk")
local function find_outgoing_contexts(uci)
local c = { }
local h = { }
uci:foreach("asterisk", "dialplan",
function(s)
if not h[s['.name']] then
c[#c+1] = { s['.name'], "Dialplan: %s" % s['.name'] }
h[s['.name']] = true
end
end)
return c
end
local function find_incoming_contexts(uci)
local c = { }
local h = { }
uci:foreach("asterisk", "sip",
function(s)
if s.context and not h[s.context] and
uci:get_bool("asterisk", s['.name'], "provider")
then
c[#c+1] = { s.context, "Incoming: %s" % s['.name'] or s.context }
h[s.context] = true
end
end)
return c
end
--
-- SIP phone info
--
if arg[2] == "info" then
form = SimpleForm("asterisk", "SIP Phone Information")
form.reset = false
form.submit = "Back to overview"
local info, keys = ast.sip.peer(arg[1])
local data = { }
for _, key in ipairs(keys) do
data[#data+1] = {
key = key,
val = type(info[key]) == "boolean"
and ( info[key] and "yes" or "no" )
or ( info[key] == nil or #info[key] == 0 )
and "(none)"
or tostring(info[key])
}
end
itbl = form:section(Table, data, "SIP Phone %q" % arg[1])
itbl:option(DummyValue, "key", "Key")
itbl:option(DummyValue, "val", "Value")
function itbl.parse(...)
luci.http.redirect(
luci.dispatcher.build_url("admin", "asterisk", "phones")
)
end
return form
--
-- SIP phone configuration
--
elseif arg[1] then
cbimap = Map("asterisk", "Edit SIP Client")
peer = cbimap:section(NamedSection, arg[1])
peer.hidden = {
type = "friend",
qualify = "yes",
host = "dynamic",
nat = "no",
canreinvite = "no"
}
back = peer:option(DummyValue, "_overview", "Back to phone overview")
back.value = ""
back.titleref = luci.dispatcher.build_url("admin", "asterisk", "phones")
active = peer:option(Flag, "disable", "Account enabled")
active.enabled = "yes"
active.disabled = "no"
function active.cfgvalue(...)
return AbstractValue.cfgvalue(...) or "yes"
end
exten = peer:option(Value, "extension", "Extension Number")
cbimap.uci:foreach("asterisk", "dialplanexten",
function(s)
exten:value(
s.extension,
"%s (via %s/%s)" %{ s.extension, s.type:upper(), s.target }
)
end)
display = peer:option(Value, "callerid", "Display Name")
username = peer:option(Value, "username", "Authorization ID")
password = peer:option(Value, "secret", "Authorization Password")
password.password = true
regtimeout = peer:option(Value, "registertimeout", "Registration Time Value")
function regtimeout.cfgvalue(...)
return AbstractValue.cfgvalue(...) or "60"
end
sipport = peer:option(Value, "port", "SIP Port")
function sipport.cfgvalue(...)
return AbstractValue.cfgvalue(...) or "5060"
end
linekey = peer:option(ListValue, "_linekey", "Linekey Mode (broken)")
linekey:value("", "Off")
linekey:value("trunk", "Trunk Appearance")
linekey:value("call", "Call Appearance")
dialplan = peer:option(ListValue, "context", "Assign Dialplan")
dialplan.titleref = luci.dispatcher.build_url("admin", "asterisk", "dialplans")
for _, v in ipairs(find_outgoing_contexts(cbimap.uci)) do
dialplan:value(unpack(v))
end
incoming = peer:option(StaticList, "incoming", "Receive incoming calls from")
for _, v in ipairs(find_incoming_contexts(cbimap.uci)) do
incoming:value(unpack(v))
end
--function incoming.cfgvalue(...)
--error(table.concat(MultiValue.cfgvalue(...),"."))
--end
return cbimap
end

View file

@ -1,116 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local ast = require("luci.asterisk")
cbimap = Map("asterisk", "Registered Phones")
cbimap.pageaction = false
local sip_peers = { }
cbimap.uci:foreach("asterisk", "sip",
function(s)
if s.type ~= "peer" then
s.name = s['.name']
s.info = ast.sip.peer(s.name)
sip_peers[s.name] = s
end
end)
sip_table = cbimap:section(TypedSection, "sip", "SIP Phones")
sip_table.template = "cbi/tblsection"
sip_table.extedit = luci.dispatcher.build_url("admin", "asterisk", "phones", "sip", "%s")
sip_table.addremove = true
function sip_table.filter(self, s)
return s and not cbimap.uci:get_bool("asterisk", s, "provider")
end
function sip_table.create(self, section)
if TypedSection.create(self, section) then
created = section
cbimap.uci:tset("asterisk", section, {
type = "friend",
qualify = "yes",
provider = "no",
host = "dynamic",
nat = "no",
canreinvite = "no",
extension = section:match("^%d+$") and section or "",
username = section:match("^%d+$") and section or ""
})
else
self.invalid_cts = true
end
end
function sip_table.parse(self, ...)
TypedSection.parse(self, ...)
if created then
cbimap.uci:save("asterisk")
luci.http.redirect(luci.dispatcher.build_url(
"admin", "asterisk", "phones", "sip", created
))
end
end
user = sip_table:option(DummyValue, "username", "Username")
function user.cfgvalue(self, s)
return sip_peers[s] and sip_peers[s].callerid or
AbstractValue.cfgvalue(self, s)
end
host = sip_table:option(DummyValue, "host", "Hostname")
function host.cfgvalue(self, s)
if sip_peers[s] and sip_peers[s].info.address then
return "%s:%i" %{ sip_peers[s].info.address, sip_peers[s].info.port }
else
return "n/a"
end
end
context = sip_table:option(DummyValue, "context", "Dialplan")
context.href = luci.dispatcher.build_url("admin", "asterisk", "dialplan")
online = sip_table:option(DummyValue, "online", "Registered")
function online.cfgvalue(self, s)
if sip_peers[s] and sip_peers[s].info.online == nil then
return "n/a"
else
return sip_peers[s] and sip_peers[s].info.online
and "yes" or "no (%s)" % {
sip_peers[s] and sip_peers[s].info.Status:lower() or "unknown"
}
end
end
delay = sip_table:option(DummyValue, "delay", "Delay")
function delay.cfgvalue(self, s)
if sip_peers[s] and sip_peers[s].info.online then
return "%i ms" % sip_peers[s].info.delay
else
return "n/a"
end
end
info = sip_table:option(Button, "_info", "Info")
function info.write(self, s)
luci.http.redirect(luci.dispatcher.build_url(
"admin", "asterisk", "phones", "sip", s, "info"
))
end
return cbimap

View file

@ -1,98 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local ast = require("luci.asterisk")
--
-- SIP trunk info
--
if arg[2] == "info" then
form = SimpleForm("asterisk", "SIP Trunk Information")
form.reset = false
form.submit = "Back to overview"
local info, keys = ast.sip.peer(arg[1])
local data = { }
for _, key in ipairs(keys) do
data[#data+1] = {
key = key,
val = type(info[key]) == "boolean"
and ( info[key] and "yes" or "no" )
or ( info[key] == nil or #info[key] == 0 )
and "(none)"
or tostring(info[key])
}
end
itbl = form:section(Table, data, "SIP Trunk %q" % arg[1])
itbl:option(DummyValue, "key", "Key")
itbl:option(DummyValue, "val", "Value")
function itbl.parse(...)
luci.http.redirect(
luci.dispatcher.build_url("admin", "asterisk", "trunks")
)
end
return form
--
-- SIP trunk config
--
elseif arg[1] then
cbimap = Map("asterisk", "Edit SIP Trunk")
peer = cbimap:section(NamedSection, arg[1])
peer.hidden = {
type = "peer",
qualify = "yes",
}
back = peer:option(DummyValue, "_overview", "Back to trunk overview")
back.value = ""
back.titleref = luci.dispatcher.build_url("admin", "asterisk", "trunks")
sipdomain = peer:option(Value, "host", "SIP Domain")
sipport = peer:option(Value, "port", "SIP Port")
function sipport.cfgvalue(...)
return AbstractValue.cfgvalue(...) or "5060"
end
username = peer:option(Value, "username", "Authorization ID")
password = peer:option(Value, "secret", "Authorization Password")
password.password = true
outboundproxy = peer:option(Value, "outboundproxy", "Outbound Proxy")
outboundport = peer:option(Value, "outboundproxyport", "Outbound Proxy Port")
register = peer:option(Flag, "register", "Register with peer")
register.enabled = "yes"
register.disabled = "no"
regext = peer:option(Value, "registerextension", "Extension to register (optional)")
regext:depends({register="1"})
didval = peer:option(ListValue, "_did", "Number of assigned DID numbers")
didval:value("", "(none)")
for i=1,24 do didval:value(i) end
dialplan = peer:option(ListValue, "context", "Dialplan Context")
dialplan:value(arg[1] .. "_inbound", "(default)")
cbimap.uci:foreach("asterisk", "dialplan",
function(s) dialplan:value(s['.name']) end)
return cbimap
end

View file

@ -1,106 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local ast = require("luci.asterisk")
cbimap = Map("asterisk", "Trunks")
cbimap.pageaction = false
local sip_peers = { }
cbimap.uci:foreach("asterisk", "sip",
function(s)
if s.type == "peer" then
s.name = s['.name']
s.info = ast.sip.peer(s.name)
sip_peers[s.name] = s
end
end)
sip_table = cbimap:section(TypedSection, "sip", "SIP Trunks")
sip_table.template = "cbi/tblsection"
sip_table.extedit = luci.dispatcher.build_url("admin", "asterisk", "trunks", "sip", "%s")
sip_table.addremove = true
sip_table.sectionhead = "Extension"
function sip_table.filter(self, s)
return s and (
cbimap.uci:get("asterisk", s, "type") == nil or
cbimap.uci:get_bool("asterisk", s, "provider")
)
end
function sip_table.create(self, section)
if TypedSection.create(self, section) then
created = section
else
self.invalid_cts = true
end
end
function sip_table.parse(self, ...)
TypedSection.parse(self, ...)
if created then
cbimap.uci:tset("asterisk", created, {
type = "friend",
qualify = "yes",
provider = "yes"
})
cbimap.uci:save("asterisk")
luci.http.redirect(luci.dispatcher.build_url(
"admin", "asterisk", "trunks", "sip", created
))
end
end
user = sip_table:option(DummyValue, "username", "Username")
context = sip_table:option(DummyValue, "context", "Dialplan")
context.href = luci.dispatcher.build_url("admin", "asterisk", "dialplan")
function context.cfgvalue(...)
return AbstractValue.cfgvalue(...) or "(default)"
end
online = sip_table:option(DummyValue, "online", "Registered")
function online.cfgvalue(self, s)
if sip_peers[s] and sip_peers[s].info.online == nil then
return "n/a"
else
return sip_peers[s] and sip_peers[s].info.online
and "yes" or "no (%s)" %{
sip_peers[s] and sip_peers[s].info.Status:lower() or "unknown"
}
end
end
delay = sip_table:option(DummyValue, "delay", "Delay")
function delay.cfgvalue(self, s)
if sip_peers[s] and sip_peers[s].info.online then
return "%i ms" % sip_peers[s].info.delay
else
return "n/a"
end
end
info = sip_table:option(Button, "_info", "Info")
function info.write(self, s)
luci.http.redirect(luci.dispatcher.build_url(
"admin", "asterisk", "trunks", "sip", s, "info"
))
end
return cbimap

View file

@ -1,59 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2009 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local ast = require "luci.asterisk"
cbimap = Map("asterisk", "Voicemail - Mailboxes")
voicemail = cbimap:section(TypedSection, "voicemail", "Voicemail Boxes")
voicemail.addremove = true
voicemail.anonymous = true
voicemail.template = "cbi/tblsection"
context = voicemail:option(ListValue, "context", "Context")
context:value("default")
number = voicemail:option(Value, "number",
"Mailbox Number", "Unique mailbox identifier")
function number.write(self, s, val)
if val and #val > 0 then
local old = self:cfgvalue(s)
self.map.uci:foreach("asterisk", "dialplanvoice",
function(v)
if v.voicebox == old then
self.map:set(v['.name'], "voicebox", val)
end
end)
Value.write(self, s, val)
end
end
voicemail:option(Value, "name", "Ownername", "Human readable display name")
voicemail:option(Value, "password", "Password", "Access protection")
voicemail:option(Value, "email", "eMail", "Where to send voice messages")
voicemail:option(Value, "page", "Pager", "Pager number")
zone = voicemail:option(ListValue, "zone", "Timezone", "Used time format")
zone.titleref = luci.dispatcher.build_url("admin/asterisk/voicemail/settings")
cbimap.uci:foreach("asterisk", "voicezone",
function(s) zone:value(s['.name']) end)
function voicemail.remove(self, s)
return ast.voicemail.remove(self.map:get(s, "number"), self.map.uci)
end
return cbimap

View file

@ -1,62 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2009 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
require "luci.sys.zoneinfo"
cbimap = Map("asterisk", "Voicemail - Common Settings")
voicegeneral = cbimap:section(TypedSection, "voicegeneral",
"General Voicemail Options", "Common settings for all mailboxes are " ..
"defined here. Most of them are optional. The storage format should " ..
"never be changed once set.")
voicegeneral.anonymous = true
voicegeneral.addremove = false
format = voicegeneral:option(MultiValue, "Used storage formats")
format.widget = "checkbox"
format:value("wav49")
format:value("gsm")
format:value("wav")
voicegeneral:option(Flag, "sendvoicemail", "Enable sending of emails")
voicegeneral:option(Flag, "attach", "Attach voice messages to emails")
voicegeneral:option(Value, "serveremail", "Used email sender address")
voicegeneral:option(Value, "emaildateformat", "Date format used in emails").optional = true
voicegeneral:option(Value, "maxlogins", "Max. failed login attempts").optional = true
voicegeneral:option(Value, "maxmsg", "Max. allowed messages per mailbox").optional = true
voicegeneral:option(Value, "minmessage", "Min. number of seconds for voicemail").optional = true
voicegeneral:option(Value, "maxmessage", "Max. number of seconds for voicemail").optional = true
voicegeneral:option(Value, "maxsilence", "Seconds of silence until stop recording").optional = true
voicegeneral:option(Value, "maxgreet", "Max. number of seconds for greetings").optional = true
voicegeneral:option(Value, "skipms", "Milliseconds to skip for rew./ff.").optional = true
voicegeneral:option(Value, "silencethreshold", "Threshold to detect silence").optional = true
voicezone = cbimap:section(TypedSection, "voicezone", "Time Zones",
"Time zones define how dates and times are expressen when used in " ..
"an voice mails. Refer to the asterisk manual for placeholder values.")
voicezone.addremove = true
voicezone.sectionhead = "Name"
voicezone.template = "cbi/tblsection"
tz = voicezone:option(ListValue, "zone", "Location")
for _, z in ipairs(luci.sys.zoneinfo.TZ) do tz:value(z[1]) end
voicezone:option(Value, "message", "Date Format")
return cbimap

View file

@ -1,22 +0,0 @@
<%#
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id: dvalue.htm 3367 2008-09-19 10:42:02Z Cyrus $
-%>
<%+cbi/valueheader%>
<% if self.href then %><a href="<%=self.href%>"><% end -%>
<%=self:cfgvalue(section)%>
<%- if self.href then %></a><%end%>
&#160;
<input type="hidden" id="<%=cbid%>" value="<%=luci.util.pcdata(self:cfgvalue(section))%>" />
<%+cbi/valuefooter%>

View file

@ -1,254 +0,0 @@
<%#
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
-%>
<%+header%>
<%
local uci = luci.model.uci.cursor_state()
local ast = require "luci.asterisk"
function digit_pattern(s,t)
return "<code style='padding: 2px; border:1px solid #CCCCCC; background-color: #FFFFFF'%s>%s</code>"
%{ t and " title='" .. t .. "'" or "", s }
end
function rowstyle(i)
return "cbi-rowstyle-%i" %{
( i % 2 ) == 0 and 2 or 1
}
end
function format_matches(z)
local html = { }
if type(z) ~= "table" then
z = { matches = { z } }
end
if z.localprefix then
for _, m in ipairs(z.matches) do
html[#html+1] =
digit_pattern(z.localprefix, "local prefix") .. " " ..
digit_pattern(m)
end
end
if z.intlmatches and #z.intlmatches > 0 then
for _, i in ipairs(z.intlmatches) do
for _, m in ipairs(z.matches) do
html[#html+1] = "%s %s" %{
digit_pattern("(%s)" % i, "intl. prefix"),
digit_pattern(m)
}
end
end
else
for _, m in ipairs(z.matches) do
html[#html+1] = digit_pattern(m)
end
end
return table.concat(html, "; ")
end
%>
<form method="post" action="<%=luci.dispatcher.build_url("admin", "asterisk", "dialplans")%>" enctype="multipart/form-data">
<div>
<script type="text/javascript" src="/luci-static/resources/cbi.js"></script>
<input type="hidden" name="cbi.submit" value="1" />
<input type="submit" value="Save" class="hidden" />
</div>
<div class="cbi-map" id="cbi-asterisk">
<h2><a id="content" name="content">Outgoing Call Routing</a></h2>
<div class="cbi-map-descr">
Here you can manage your dial plans which are used to route outgoing calls from your local extensions.<br /><br />
Related tasks:<br />
<a href="<%=luci.dispatcher.build_url('admin/asterisk/dialplans/zones')%>" class="cbi-title-ref">Manage dialzones</a> |
<a href="<%=luci.dispatcher.build_url('admin/asterisk/voicemail/mailboxes')%>" class="cbi-title-ref">Manage voicemail boxes</a> |
<a href="<%=luci.dispatcher.build_url('admin/asterisk/meetme/rooms')%>" class="cbi-title-ref">Manage meetme rooms</a>
</div>
<!-- tblsection -->
<fieldset class="cbi-section" id="cbi-asterisk-sip">
<!--<legend>Dialplans</legend>-->
<div class="cbi-section-descr"></div>
<% for i, plan in pairs(ast.dialplan.plans()) do %>
<div class="cbi-section-node">
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th style="text-align: left; padding: 3px" class="cbi-section-table-cell">
<big>Dialplan <em><%=plan.name%></em></big>
</th>
<td>
<a href="<%=luci.dispatcher.build_url('admin', 'asterisk', 'dialplans')%>?delplan=<%=plan.name%>">
<img style="border:none" alt="Remove this dialplan" title="Remove this dialplan" src="/luci-static/resources/cbi/remove.gif" />
</a>
</td>
</tr>
<!-- dialzones -->
<% local zones_used = { }; local row = 0 %>
<% for i, zone in ipairs(plan.zones) do zones_used[zone.name] = true %>
<tr class="cbi-section-table-row <%=rowstyle(row)%>">
<td style="text-align: left; padding: 3px" class="cbi-section-table-cell">
<strong>&#x2514; Dialzone <em><%=zone.name%></em></strong> (<%=zone.description%>)
<p style="padding-left: 1em; margin-bottom:0">
Lines:
<%=ast.tools.hyperlinks(
zone.trunks, function(v)
return luci.dispatcher.build_url("admin", "asterisk", "trunks", "%s") % v:lower()
end
)%><br />
Matches:
<%=format_matches(zone)%>
</p>
</td>
<td style="width:5%" class="cbi-value-field">
<a href="<%=luci.dispatcher.build_url('admin/asterisk/dialplans/out', zone.name)%>">
<img style="border:none" alt="Edit dialzone" title="Edit dialzone" src="/luci-static/resources/cbi/edit.gif" />
</a>
<a href="<%=luci.dispatcher.build_url('admin/asterisk/dialplans')%>?delzone.<%=plan.name%>=<%=zone.name%>">
<img style="border:none" alt="Remove from this dialplan" title="Remove from this dialplan" src="/luci-static/resources/cbi/remove.gif" />
</a>
</td>
</tr>
<% row = row + 1; end %>
<!-- /dialzones -->
<!-- voicemail -->
<% local boxes_used = { } %>
<% for ext, box in luci.util.kspairs(plan.voicemailboxes) do boxes_used[box.id] = true %>
<tr class="cbi-section-table-row <%=rowstyle(row)%>">
<td style="text-align: left; padding: 3px" class="cbi-section-table-cell">
<strong>&#x2514; Voicemailbox <em><%=box.id%></em></strong> (<%=box.name%>)
<p style="padding-left: 1em; margin-bottom:0">
Owner: <%=box.name%> |
eMail: <%=#box.email > 0 and box.email or 'n/a'%> |
Pager: <%=#box.page > 0 and box.page or 'n/a'%><br />
Matches: <%=format_matches(ext)%>
</p>
</td>
<td style="width:5%" class="cbi-value-field">
<a href="<%=luci.dispatcher.build_url('admin/asterisk/voicemail/mailboxes')%>">
<img style="border:none" alt="Manage mailboxes ..." title="Manage mailboxes ..." src="/luci-static/resources/cbi/edit.gif" />
</a>
<a href="<%=luci.dispatcher.build_url('admin/asterisk/dialplans')%>?delvbox.<%=plan.name%>=<%=ext%>">
<img style="border:none" alt="Remove from this dialplan" title="Remove from this dialplan" src="/luci-static/resources/cbi/remove.gif" />
</a>
</td>
</tr>
<% row = row + 1; end %>
<!-- /voicemail -->
<!-- meetme -->
<% local rooms_used = { } %>
<% for ext, room in luci.util.kspairs(plan.meetmerooms) do rooms_used[room.room] = true %>
<tr class="cbi-section-table-row <%=rowstyle(row)%>">
<td style="text-align: left; padding: 3px" class="cbi-section-table-cell">
<strong>&#x2514; MeetMe Room <em><%=room.room%></em></strong>
<% if room.description and #room.description > 0 then %> (<%=room.description%>)<% end %>
<p style="padding-left: 1em; margin-bottom:0">
Matches: <%=format_matches(ext)%>
</p>
</td>
<td style="width:5%" class="cbi-value-field">
<a href="<%=luci.dispatcher.build_url('admin/asterisk/meetme/rooms')%>">
<img style="border:none" alt="Manage conferences ..." title="Manage conferences ..." src="/luci-static/resources/cbi/edit.gif" />
</a>
<a href="<%=luci.dispatcher.build_url('admin/asterisk/dialplans')%>?delmeetme.<%=plan.name%>=<%=ext%>">
<img style="border:none" alt="Remove from this dialplan" title="Remove from this dialplan" src="/luci-static/resources/cbi/remove.gif" />
</a>
</td>
</tr>
<% row = row + 1; end %>
<!-- /meetme -->
<tr class="cbi-section-table-row">
<td style="text-align: left; padding: 3px" class="cbi-section-table-cell" colspan="2">
<hr style="margin-bottom:0.5em; border-width:0 0 1px 0" />
Add Dialzone:<br />
<select style="width:30%" name="addzone.<%=plan.name%>">
<option value="">-- please select --</option>
<% for _, zone in luci.util.kspairs(ast.dialzone.zones()) do %>
<% if not zones_used[zone.name] then %>
<option value="<%=zone.name%>"><%=zone.name%> (<%=zone.description%>)</option>
<% end %>
<% end %>
</select>
<br /><br />
Add Voicemailbox:<br />
<select style="width:20%" name="addvbox.<%=plan.name%>" onchange="this.form['addvboxext.<%=plan.name%>'].value=this.options[this.selectedIndex].value.split('@')[0]">
<option value="">-- please select --</option>
<% for ext, box in luci.util.kspairs(ast.voicemail.boxes()) do %>
<% if not boxes_used[box.id] then %>
<option value="<%=box.id%>"><%=box.id%> (<%=box.name%>)</option>
<% end %>
<% end %>
</select>
as extension
<input type="text" style="width:5%" name="addvboxext.<%=plan.name%>" />
<br /><br />
Add MeetMe Conference:<br />
<select style="width:20%" name="addmeetme.<%=plan.name%>" onchange="this.form['addmeetmeext.<%=plan.name%>'].value=this.options[this.selectedIndex].value">
<option value="">-- please select --</option>
<% for ext, room in luci.util.kspairs(ast.meetme.rooms()) do %>
<%# if not rooms_used[room.room] then %>
<option value="<%=room.room%>">
<%=room.room%>
<% if room.description and #room.description > 0 then %>(<%=room.description%>)<% end %>
</option>
<%# end %>
<% end %>
</select>
as extension
<input type="text" style="width:5%" name="addmeetmeext.<%=plan.name%>" />
<br /><br />
<input type="submit" class="cbi-button cbi-button-add" value="Add item &raquo;" title="Add item ..."/>
</td>
</tr>
</table>
<div class="cbi-section-create cbi-tblsection-create"></div>
</div>
<br />
<% end %>
<div class="cbi-section-node">
<div class="cbi-section-create cbi-tblsection-create" style="padding: 3px">
<h3>Create a new dialplan</h3>
The name is required and must be unique. It may only contain the characters A-Z, a-z, 0-9 and _ .<br />
<%- if create_error then %>
<br /><span style="color:red">Invalid name given!</span><br />
<% end -%>
<br />
<input type="text" class="cbi-section-create-name" name="addplan" style="width:200px" />
<input type="submit" class="cbi-button cbi-button-add" value="Add dialplan" title="Add dialplan"/>
</div>
</div>
</fieldset>
</div>
</form>
<div class="clear"></div>
<%+footer%>

View file

@ -1,174 +0,0 @@
<%#
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
-%>
<%+header%>
<%
local uci = luci.model.uci.cursor_state()
local ast = require("luci.asterisk")
function digit_pattern(s)
return "<code style='padding: 2px; border:1px solid #CCCCCC; background-color: #FFFFFF'>%s</code>" % s
end
function rowstyle(i)
return "cbi-rowstyle-%i" %{
( i % 2 ) == 0 and 2 or 1
}
end
local function find_trunks()
local t = { }
uci:foreach("asterisk", "sip",
function(s)
if uci:get_bool("asterisk", s['.name'], "provider") then
t[#t+1] = {
"SIP/%s" % s['.name'],
"SIP: %s" % s['.name']
}
end
end)
uci:foreach("asterisk", "iax",
function(s)
t[#t+1] = {
"IAX/%s" % s['.name'],
"IAX: %s" % s.extension or s['.name']
}
end)
return t
end
%>
<form method="post" action="<%=luci.dispatcher.build_url("admin", "asterisk", "dialplans", "zones")%>" enctype="multipart/form-data">
<div>
<script type="text/javascript" src="/luci-static/resources/cbi.js"></script>
<input type="hidden" name="cbi.submit" value="1" />
<input type="submit" value="Save" class="hidden" />
</div>
<div class="cbi-map" id="cbi-asterisk">
<h2><a id="content" name="content">Dial Zone Management</a></h2>
<div class="cbi-map-descr">
<a href="<%=luci.dispatcher.build_url("admin/asterisk/dialplans")%>" class="cbi-title-ref">Back to dialplan overview</a><br /><br />
Here you can manage your dial zones. The zones are used to route outgoing calls to the destination.
Each zone groups multiple trunks and number matches to represent a logical destination. Zones can
also be used to enforce certain dial restrictions on selected extensions.
</div>
<!-- tblsection -->
<fieldset class="cbi-section" id="cbi-asterisk-sip">
<div class="cbi-section-node">
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th style="text-align: left; padding: 3px" class="cbi-section-table-cell" colspan="6">
<h3>Dialzone Overview</h3>
</th>
</tr>
<tr class="cbi-section-table-descr">
<th style="width: 5%; text-align:right" class="cbi-section-table-cell">Name</th>
<th style="width: 5%; text-align:right" class="cbi-section-table-cell">Prepend</th>
<th style="width: 20%; text-align:left" class="cbi-section-table-cell">- Match</th>
<th style="text-align:left" class="cbi-section-table-cell">Trunk</th>
<th style="width: 35%; text-align:left" class="cbi-section-table-cell">Description</th>
<th style="width: 4%; text-align:left" class="cbi-section-table-cell"></th>
</tr>
<% for i, rule in pairs(ast.dialzone.zones()) do %>
<tr class="cbi-section-table-row <%=rowstyle(i)%>">
<td style="text-align:right" class="cbi-value-field">
<%=rule.name%>
</td>
<td style="text-align:right" class="cbi-value-field">
<% for _ in ipairs(rule.matches) do %>
<%=rule.addprefix and digit_pattern(rule.addprefix)%>&#160;<br />
<% end %>
</td>
<td style="text-align:left" class="cbi-value-field">
<% for _, m in ipairs(rule.matches) do %>
<%=rule.localprefix and "%s " % digit_pattern(rule.localprefix)%>
<%=digit_pattern(m)%><br />
<% end %>
</td>
<td style="text-align:left" class="cbi-value-field">
<%=ast.tools.hyperlinks(
rule.trunks, function(v)
return luci.dispatcher.build_url("admin", "asterisk", "trunks", "%s") % v:lower()
end
)%>
</td>
<td style="text-align:left" class="cbi-value-field">
<%=rule.description or rule.name%>
</td>
<td style="text-align:left" class="cbi-value-field">
<a href="<%=luci.dispatcher.build_url('admin', 'asterisk', 'dialplans', 'out', rule.name)%>">
<img style="border:none" alt="Edit entry" title="Edit entry" src="/luci-static/resources/cbi/edit.gif" />
</a>
<a href="<%=luci.dispatcher.build_url('admin', 'asterisk', 'dialplans', 'zones')%>?delzone=<%=rule.name%>">
<img style="border:none" alt="Delete entry" title="Delete entry" src="/luci-static/resources/cbi/remove.gif" />
</a>
</td>
</tr>
<% end %>
</table>
<div class="cbi-section-create cbi-tblsection-create"></div>
</div>
<br />
<div class="cbi-section-node">
<div class="cbi-section-create cbi-tblsection-create" style="padding: 3px">
<h3>Create a new dialzone</h3>
The name is required and must be unique. It may only contain the characters A-Z, a-z, 0-9 and _ .<br />
You can specifiy multiple number matches by separating them with spaces.<br />
<%- if create_error then %>
<br /><span style="color:red">Invalid name given!</span><br />
<% end -%>
<table>
<tr>
<td style="padding:3px">
<label for="create1">1) Name</label><br />
<input type="text" class="cbi-section-create-name" id="create1" name="newzone_name" style="width:200px" />
<br /><br />
<label for="create2">2) Number Match</label><br />
<input type="text" class="cbi-section-create-name" id="create2" name="newzone_match" style="width:200px" />
</td>
<td style="padding:3px">
<label for="create3">3) Trunks</label><br />
<select class="cbi-input-select" multiple="multiple" id="create3" name="newzone_uses" size="4" style="width:200px">
<% for i, t in ipairs(find_trunks()) do %>
<option value="<%=t[1]%>"><%=t[2]%></option>
<% end %>
</select>
</td>
</tr>
</table>
<br />
<input type="submit" class="cbi-button cbi-button-add" name="newzone" value="Add entry" title="Add entry"/>
</div>
</div>
</fieldset>
</div>
</form>
<div class="clear"></div>
<%+footer%>

View file

@ -1,231 +0,0 @@
config 'asterisk'
option 'verbose' 3
option 'debug' 3
option 'zone' 'Australia/Perth'
config 'hardware' 'reboot'
option 'method' 'web'
option 'param' 'http://ata.lan/admin/reboot'
config 'feature' 'park'
option 'parkenabled' 'yes'
option 'parkext' '700'
option 'parkpos' '701-720'
option 'context' 'parkedcalls'
option 'parkingtime' '45'
option 'courtesytone' 'beep'
option 'parkedplay' 'caller'
option 'adsipark' 'yes'
option 'findslot' 'first'
option 'parkedmusicclass' 'default'
option 'transferdigittimeout' '3'
option 'xfersound' 'beep'
option 'xferfailsound' 'beeperr'
option 'pickupexten' '"*8"'
option 'featuredigittimeout' '500'
option 'atxfernoanswertimeout' '15'
config 'feature' 'map'
option 'blindxfer' '#1'
option 'disconnect' '*0'
option 'automon' '*1'
option 'atxfer' '#2'
option 'parkcall' '#30'
config 'sipgeneral'
option 'realm' 'sip.mydomain.net'
option 'allow' 'alaw'
option 'extension' '102'
config 'module'
option 'res_config_mysql' 'no'
option 'res_crypto' 'auto'
option 'chan_iax2' 'yes'
config 'sip' 'PAP2T'
option 'type' 'friend'
option 'extension' '101'
option 'username' 'PAP2T'
option 'secret' 'mypass'
option 'port' '5061'
option 'host' ''
option 'dtmfmode' 'rfc2833'
option 'insecure' 'very'
option 'context' 'internal'
option 'mailbox' '1001@default'
option 'nat' 'no'
option 'canreinvite' 'nonat'
option 'selfmailbox' 'yes'
option 'incoming' 'provider_inbound'
config 'sip' 'PAP2T2'
option 'type' 'friend'
option 'extension' '101'
option 'username' 'PAP2T2'
option 'secret' 'mysecret'
option 'port' '5060'
option 'host' ''
option 'dtmfmode' 'rfc2833'
option 'insecure' 'very'
option 'context' 'internal'
option 'mailbox' '1001@default'
option 'nat' 'no'
option 'canreinvite' 'nonat'
option 'selfmailbox' 'yes'
option 'incoming' 'provider_inbound'
config 'sip' 'providerphone'
option 'provider' 'yes'
option 'type' 'friend'
option 'timeout' '55'
option 'internationalprefix' '0011'
option 'alwaysinternational' 'no'
option 'countrycode' '63'
option 'register' 'yes'
option 'host' '200.200.200.200'
option 'username' '0899999999'
option 'fromuser' '0899999999'
option 'secret' 'mysecret'
option 'fromdomain' 'providerphone.provider.net.au'
option 'context' 'provider_inbound'
option 'canreinvite' 'no'
option 'nat' 'yes'
option 'qualify' 'yes'
option 'insecure' 'very'
option 'pedantic' 'no'
option 'qualify' '1000'
config 'iaxgeneral'
option 'static' 'yes'
option 'writeprotect' 'no'
option 'canreinvite' 'no'
option 'allow' 'ulaw,gsm'
config 'iax' 'nell'
option 'type' 'friend'
option 'extension' '108'
option 'host' ''
option 'username' 'nell'
option 'secret' 'mypass'
option 'context' 'internal'
config 'iax' 'iax_vista'
option 'extension' '106'
option 'type' 'friend'
option 'host' ''
option 'username' 'vista'
option 'secret' 'mysecret'
option 'context' 'internal'
config 'iax' 'sam'
option 'type' 'friend'
option 'extension' '103'
option 'host' ''
option 'username' 'sam'
option 'secret' 'mysecret'
option 'context' 'internal'
config 'voicegeneral'
option 'serveremail' 'voice@sip.mydomain.net'
config 'voicemail'
option 'number' '1001'
option 'context' 'default'
option 'password' '0000'
option 'name' 'Family'
option 'email' 'us@mydomain.net'
option 'zone' 'wa'
option 'attach' 'no'
config 'voicezone' 'wa'
option 'zone' 'Australia/Perth'
option 'message' 'Q IMp'
config 'voicezone' 'military'
option 'zone' 'Zulu'
option 'message' '"vm-received" q "digits/at" H N "hours" "phonetic/z_p"'
config 'incominggeneral'
option 'allowtransfer' 'no'
option 'timeout' '20'
option 'answerfirst' 'no'
option 'mailbox' '1001@default'
config 'dialplangeneral'
option 'static' 'yes'
option 'writeprotect' 'no'
option 'canreinvite' 'no'
option 'clearglobalvars' 'no'
option 'allowtransfer' 'no'
config 'dialplan' 'internal'
option 'include' 'localcall interstate smartnumber emergency extensions'
config 'dialplanvoice'
option 'dialplan' 'internal'
option 'extension' '1001'
option 'voicecontext' 'default'
option 'voicebox' '1001'
config 'dialplansaytime'
option 'dialplan' 'internal'
option 'extension' '108'
config 'dialplanmeetme'
option 'dialplan' 'internal'
option 'extension' '109'
option 'room' '101'
config 'dialplanmeetme'
option 'dialplan' 'internal'
option 'extension' '1009'
option 'room' ''
config 'dialplan' 'localinternational'
option 'include' 'mobile interstate'
config 'dialzone' 'interstate'
option 'uses' 'SIP/providerphone'
option 'match' '0[235-8]NXXXXXXX'
option 'localprefix' '0'
config 'dialzone' 'mobile'
option 'uses' 'SIP/providerphone'
option 'match' '04XXXXXXXX'
option 'localprefix' '0'
config 'dialzone' 'smartnumber'
option 'uses' 'SIP/providerphone'
option 'match' '1[835]00.'
option 'match' '13ZXXX'
config 'dialzone' 'emergency'
option 'uses' 'SIP/providerphone'
option 'match' '000'
option 'match' '112'
config 'dialzone' 'localcall'
option 'uses' 'SIP/providerphone'
option 'match' 'NXXXXXXX'
option 'addprefix' '08'
option 'localprefix' '0'
config 'dialzone' 'international'
option 'uses' 'SIP/providerphone'
option 'international' '0011,+'
option 'localzone' 'localinternational'
option 'localprefix' '0'
option 'addprefix' ''
config 'meetmegeneral'
option 'audiobuffers' '32'
config 'meetme'
option 'room' '101'
option 'pin' ''
option 'adminpin' ''
config 'moh' 'default'
option 'mode' 'files'
option 'directory' '/opt/moh'
option 'random' 'no'

View file

@ -1,11 +0,0 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@asterisk[-1]
add ucitrack asterisk
set ucitrack.@asterisk[-1].init=asterisk
commit ucitrack
EOF
rm -f /tmp/luci-indexcache
exit 0

View file

@ -1,4 +0,0 @@
PO = coovachilli
include ../../build/config.mk
include ../../build/module.mk

View file

@ -1,27 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
module("luci.controller.coovachilli", package.seeall)
function index()
local cc
cc = entry( { "admin", "services", "coovachilli" }, cbi("coovachilli"), _("CoovaChilli"), 90)
cc.i18n = "coovachilli"
cc.subindex = true
entry( { "admin", "services", "coovachilli", "network" }, cbi("coovachilli_network"), _("Network Configuration"), 10)
entry( { "admin", "services", "coovachilli", "radius" }, cbi("coovachilli_radius"), _("RADIUS configuration"), 20)
entry( { "admin", "services", "coovachilli", "auth" }, cbi("coovachilli_auth"), _("UAM and MAC Authentication"), 30)
end

View file

@ -1,31 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
m = Map("coovachilli")
-- general
s = m:section(TypedSection, "general")
s.anonymous = true
s:option( Flag, "debug" )
s:option( Value, "interval" )
s:option( Value, "pidfile" ).optional = true
s:option( Value, "statedir" ).optional = true
s:option( Value, "cmdsock" ).optional = true
s:option( Value, "logfacility" ).optional = true
return m

View file

@ -1,76 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
m = Map("coovachilli")
-- uam config
s1 = m:section(TypedSection, "uam")
s1.anonymous = true
s1:option( Value, "uamserver" )
s1:option( Value, "uamsecret" ).password = true
s1:option( Flag, "uamanydns" )
s1:option( Flag, "nouamsuccess" )
s1:option( Flag, "nouamwispr" )
s1:option( Flag, "chillixml" )
s1:option( Flag, "uamanyip" ).optional = true
s1:option( Flag, "dnsparanoia" ).optional = true
s1:option( Flag, "usestatusfile" ).optional = true
s1:option( Value, "uamhomepage" ).optional = true
s1:option( Value, "uamlisten" ).optional = true
s1:option( Value, "uamport" ).optional = true
s1:option( Value, "uamiport" ).optional = true
s1:option( DynamicList, "uamdomain" ).optional = true
s1:option( Value, "uamlogoutip" ).optional = true
s1:option( DynamicList, "uamallowed" ).optional = true
s1:option( Value, "uamui" ).optional = true
s1:option( Value, "wisprlogin" ).optional = true
s1:option( Value, "defsessiontimeout" ).optional = true
s1:option( Value, "defidletimeout" ).optional = true
s1:option( Value, "definteriminterval" ).optional = true
s1:option( Value, "ssid" ).optional = true
s1:option( Value, "vlan" ).optional = true
s1:option( Value, "nasip" ).optional = true
s1:option( Value, "nasmac" ).optional = true
s1:option( Value, "wwwdir" ).optional = true
s1:option( Value, "wwwbin" ).optional = true
s1:option( Value, "localusers" ).optional = true
s1:option( Value, "postauthproxy" ).optional = true
s1:option( Value, "postauthproxyport" ).optional = true
s1:option( Value, "locationname" ).optional = true
-- mac authentication
s2 = m:section(TypedSection, "macauth")
s2.anonymous = true
s2:option( Flag, "macauth" )
s2:option( Flag, "macallowlocal" )
s2:option( DynamicList, "macallowed" )
pw = s2:option( Value, "macpasswd" )
pw.optional = true
pw.password = true
s2:option( Value, "macsuffix" ).optional = true
return m

View file

@ -1,67 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
require("luci.sys")
require("luci.ip")
m = Map("coovachilli")
-- tun
s1 = m:section(TypedSection, "tun")
s1.anonymous = true
s1:option( Flag, "usetap" )
s1:option( Value, "tundev" ).optional = true
s1:option( Value, "txqlen" ).optional = true
net = s1:option( Value, "net" )
for _, route in ipairs(luci.sys.net.routes()) do
if route.device ~= "lo" and route.dest:prefix() < 32 then
net:value( route.dest:string() )
end
end
s1:option( Value, "dynip" ).optional = true
s1:option( Value, "statip" ).optional = true
s1:option( Value, "dns1" ).optional = true
s1:option( Value, "dns2" ).optional = true
s1:option( Value, "domain" ).optional = true
s1:option( Value, "ipup" ).optional = true
s1:option( Value, "ipdown" ).optional = true
s1:option( Value, "conup" ).optional = true
s1:option( Value, "condown" ).optional = true
-- dhcp config
s2 = m:section(TypedSection, "dhcp")
s2.anonymous = true
dif = s2:option( Value, "dhcpif" )
for _, nif in ipairs(luci.sys.net.devices()) do
if nif ~= "lo" then dif:value(nif) end
end
s2:option( Value, "dhcpmac" ).optional = true
s2:option( Value, "lease" ).optional = true
s2:option( Value, "dhcpstart" ).optional = true
s2:option( Value, "dhcpend" ).optional = true
s2:option( Flag, "eapolenable" )
return m

View file

@ -1,67 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
m = Map("coovachilli")
-- radius server
s1 = m:section(TypedSection, "radius")
s1.anonymous = true
s1:option( Value, "radiusserver1" )
s1:option( Value, "radiusserver2" )
s1:option( Value, "radiussecret" ).password = true
s1:option( Value, "radiuslisten" ).optional = true
s1:option( Value, "radiusauthport" ).optional = true
s1:option( Value, "radiusacctport" ).optional = true
s1:option( Value, "radiusnasid" ).optional = true
s1:option( Value, "radiusnasip" ).optional = true
s1:option( Value, "radiuscalled" ).optional = true
s1:option( Value, "radiuslocationid" ).optional = true
s1:option( Value, "radiuslocationname" ).optional = true
s1:option( Value, "radiusnasporttype" ).optional = true
s1:option( Flag, "radiusoriginalurl" )
s1:option( Value, "adminuser" ).optional = true
rs = s1:option( Value, "adminpassword" )
rs.optional = true
rs.password = true
s1:option( Flag, "swapoctets" )
s1:option( Flag, "openidauth" )
s1:option( Flag, "wpaguests" )
s1:option( Flag, "acctupdate" )
s1:option( Value, "coaport" ).optional = true
s1:option( Flag, "coanoipcheck" )
-- radius proxy
s2 = m:section(TypedSection, "proxy")
s2.anonymous = true
s2:option( Value, "proxylisten" ).optional = true
s2:option( Value, "proxyport" ).optional = true
s2:option( Value, "proxyclient" ).optional = true
ps = s2:option( Value, "proxysecret" )
ps.optional = true
ps.password = true
return m

View file

@ -1,243 +0,0 @@
##############################################################################
#
# Sample CoovaChilli configuration file
#
##############################################################################
# General settings
config general
# Enable this flag to include debug information.
option debug 0
# Re-read configuration file at this interval. Will also cause new domain
# name lookups to be performed. Value is given in seconds.
option interval 3600
# File to store information about the process id of the program.
# The program must have write access to this file/directory.
option pidfile /var/run/chilli.pid
# Directory to use for nonvolatile storage.
# The program must have write access to this directory.
# This tag is currently ignored
#option statedir ./
# TUN parameters
config tun
# IP network address of external packet data network
# Used to allocate dynamic IP addresses and set up routing.
# Normally you do not need to uncomment this tag.
option net 192.168.182.0/24
# Dynamic IP address pool
# Used to allocate dynamic IP addresses to clients.
# If not set it defaults to the net tag.
# Do not uncomment this tag unless you are an experienced user!
#option dynip 192.168.182.0/24
# Static IP address pool
# Used to allocate static IP addresses to clients.
# Do not uncomment this tag unless you are an experienced user!
#option statip 192.168.182.0/24
# Primary DNS server.
# Will be suggested to the client.
# If omitted the system default will be used.
# Normally you do not need to uncomment this tag.
#option dns1 172.16.0.5
# Secondary DNS server.
# Will be suggested to the client.
# If omitted the system default will be used.
# Normally you do not need to uncomment this tag.
#option dns2 172.16.0.6
# Domain name
# Will be suggested to the client.
# Normally you do not need to uncomment this tag.
option domain key.chillispot.org
# Script executed after network interface has been brought up.
# Executed with the following parameters: <devicename> <ip address> <mask>
# Normally you do not need to uncomment this tag.
#option ipup /etc/chilli.ipup
# Script executed after network interface has been taken down.
# Executed with the following parameters: <devicename> <ip address> <mask>
# Normally you do not need to uncomment this tag.
#option ipdown /etc/chilli.ipdown
# Script executed after a user has been authenticated.
# Executed with the following parameters: <devicename> <ip address>
# <mask> <user ip address> <user mac address> <filter ID>
# Normally you do not need to uncomment this tag.
#option conup /etc/chilli.conup
# Script executed after a user has disconnected.
# Executed with the following parameters: <devicename> <ip address>
# <mask> <user ip address> <user mac address> <filter ID>
# Normally you do not need to uncomment this tag.
#option condown /etc/chilli.condown
# DHCP Parameters
config dhcp
# Ethernet interface to listen to.
# This is the network interface which is connected to the access points.
# In a typical configuration this tag should be set to eth1.
option dhcpif eth1
# Use specified MAC address.
# An address in the range 00:00:5E:00:02:00 - 00:00:5E:FF:FF:FF falls
# within the IANA range of addresses and is not allocated for other
# purposes.
# Normally you do not need to uncomment this tag.
#option dhcpmac 00:00:5E:00:02:00
# Time before DHCP lease expires
# Normally you do not need to uncomment this tag.
#option lease 600
# Radius parameters
config radius
# IP address to listen to
# Normally you do not need to uncomment this tag.
#option radiuslisten 127.0.0.1
# IP address of radius server 1
# For most installations you need to modify this tag.
option radiusserver1 rad01.chillispot.org
# IP address of radius server 2
# If you have only one radius server you should set radiusserver2 to the
# same value as radiusserver1.
# For most installations you need to modify this tag.
option radiusserver2 rad02.chillispot.org
# Radius authentication port
# The UDP port number to use for radius authentication requests.
# The same port number is used for both radiusserver1 and radiusserver2.
# Normally you do not need to uncomment this tag.
#option radiusauthport 1812
# Radius accounting port
# The UDP port number to use for radius accounting requests.
# The same port number is used for both radiusserver1 and radiusserver2.
# Normally you do not need to uncomment this tag.
#option radiusacctport 1813
# Radius shared secret for both servers
# For all installations you should modify this tag.
#option radiussecret testing123
# Radius NAS-Identifier
# Normally you do not need to uncomment this tag.
#option radiusnasid nas01
# Radius NAS-IP-Address
# Normally you do not need to uncomment this tag.
#option radiusnasip 127.0.0.1
# Radius Called-Station-ID
# Normally you do not need to uncomment this tag.
#option radiuscalled 00133300
# WISPr Location ID. Should be in the format: isocc=<ISO_Country_Code>,
# cc=<E.164_Country_Code>,ac=<E.164_Area_Code>,network=<ssid/ZONE>
# Normally you do not need to uncomment this tag.
#option radiuslocationid isocc=us,cc=1,ac=408,network=ACMEWISP_NewarkAirport
# WISPr Location Name. Should be in the format:
# <HOTSPOT_OPERATOR_NAME>,<LOCATION>
# Normally you do not need to uncomment this tag.
#option radiuslocationname ACMEWISP,Gate_14_Terminal_C_of_Newark_Airport
# Radius proxy parameters
config proxy
# IP address to listen to
# Normally you do not need to uncomment this tag.
#option proxylisten 10.0.0.1
# UDP port to listen to.
# If not specified a port will be selected by the system
# Normally you do not need to uncomment this tag.
#option proxyport 1645
# Client(s) from which we accept radius requests
# Normally you do not need to uncomment this tag.
#option proxyclient 10.0.0.1/24
# Radius proxy shared secret for all clients
# If not specified defaults to radiussecret
# Normally you do not need to uncomment this tag.
#option proxysecret testing123
# Universal access method (UAM) parameters
config uam
# URL of web server handling authentication.
option uamserver https://radius.chillispot.org/hotspotlogin
# URL of welcome homepage.
# Unauthenticated users will be redirected to this URL. If not specified
# users will be redirected to the uamserver instead.
# Normally you do not need to uncomment this tag.
#option uamhomepage http://192.168.182.1/welcome.html
# Shared between chilli and authentication web server
#option uamsecret ht2eb8ej6s4et3rg1ulp
# IP address to listen to for authentication requests
# Do not uncomment this tag unless you are an experienced user!
#option uamlisten 192.168.182.1
# TCP port to listen to for authentication requests
# Do not uncomment this tag unless you are an experienced user!
#option uamport 3990
# Comma separated list of domain names, IP addresses or network segments
# the client can access without first authenticating.
# It is possible to specify this tag multiple times.
# Normally you do not need to uncomment this tag.
#list uamallowed www.chillispot.org
#list uamallowed 10.11.12.0/24
# If this flag is given unauthenticated users are allowed to use
# any DNS server.
# Normally you do not need to uncomment this tag.
#uamanydns
# MAC authentication
config macauth
# If this flag is given users will be authenticated only on their MAC
# address.
# Normally you do not need to enable this flag.
option macauth 0
# List of MAC addresses.
# The MAC addresses specified in this list will be authenticated only on
# their MAC address.
# This tag is ignored if the macauth tag is given.
# It is possible to specify this tag multiple times.
# Normally you do not need to uncomment this tag.
#list macallowed 00-0A-5E-AC-BE-51
#list macallowed 00-30-1B-3C-32-E9
# Password to use for MAC authentication.
# Normally you do not need to uncomment this tag.
#option macpasswd password
# Suffix to add to MAC address in order to form the username.
# Normally you do not need to uncomment this tag.
#option macsuffix suffix

View file

@ -129,7 +129,7 @@ msrc = s:taboption("advanced", DynamicList, "masq_src",
translate("Restrict Masquerading to given source subnets"))
msrc.optional = true
msrc.datatype = "neg_network_ip4addr"
msrc.datatype = "neg(network)"
msrc.placeholder = "0.0.0.0/0"
msrc:depends("family", "")
msrc:depends("family", "ipv4")
@ -138,7 +138,7 @@ mdest = s:taboption("advanced", DynamicList, "masq_dest",
translate("Restrict Masquerading to given destination subnets"))
mdest.optional = true
mdest.datatype = "neg_network_ip4addr"
mdest.datatype = "neg(network)"
mdest.placeholder = "0.0.0.0/0"
mdest:depends("family", "")
mdest:depends("family", "ipv4")

View file

@ -1,90 +1,153 @@
<%+header%>
<%#
LuCI - Lua Configuration Interface
Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
-%>
<%
local fs = require "luci.fs"
local utl = require "luci.util"
-- check if nameservice plugin is enabled and where to find the services file
local last_update
local i = 1
local rawdata
local services_file_empty
local has_services = false
local uci = require "luci.model.uci".cursor()
uci:foreach("olsrd", "LoadPlugin", function(s)
if s.library == "olsrd_nameservice.so.0.3" then
if s.services_file and fs.access(s.services_file) then
has_services = true
services_file = s.services_file
rawdata = fs.readfile(s.services_file)
else
if fs.access("/var/run/services_olsr") then
has_services = true
services_file = "/var/run/services_olsr"
rawdata = fs.readfile("/var/run/services_olsr")
end
end
if rawdata and #rawdata == 0 then
services_file_empty = true
end
end
end)
if not has_services or services_file_empty then
%>
<%+header%>
<br />
<%:No services can be shown, because olsrd is not running or the olsrd-nameservice Plugin is not loaded.%>
<%+footer%>
<%
return
end
function fetch_services()
local rawdata = fs.readfile(services_file)
if #rawdata == 0 then
return nil
end
local data = {}
local tables = utl.split(utl.trim(rawdata), "\n", nil, true)
-- remove the first 3 lines
table.remove(tables,1)
table.remove(tables,1)
table.remove(tables,1)
-- remove first 3 lines
for i = 1,3 do
table.remove(tables,1)
end
-- store last line in last_update and remove it, then remove another empty line at the end
last_update=table.remove(tables)
table.remove(tables)
for i, tbl in ipairs(tables) do
local lines = utl.split(tbl, "\n", nil, true)
end
return tables
end
local services = fetch_services()
if luci.http.formvalue("status") == "1" then
local rv = {}
for k, line in ipairs(services) do
local field = utl.split(line, "[#|]", split, true)
local url, proto, descr, origin = pcdata(field[1]), pcdata(field[2]), utl.trim(pcdata(field[3])), pcdata(field[4])
rv[#rv+1] = {
url = url,
proto = proto,
origin = origin,
descr = descr,
}
end
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
return
end
%>
<% if has_services then %>
<div class="cbi-map">
<h2><a id="content" name="content"><%:Services%></a></h2>
<div class="cbi-map-descr"/>
<div class="cbi-section">
<div class="cbi-section-node">
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Url%></th>
<th class="cbi-section-table-cell"><%:Source%></th>
</tr>
<%+header%>
<% table=fetch_services()
local i = 1
for k, line in ipairs(table) do
local field = {}
-- split line at # and |, 1=url, 2=proto, 3=description, 4=source
local field = utl.split(line, "[#|]", split, true)
local url,descr,origin = pcdata(field[1]),pcdata(field[3]),pcdata(field[4])
%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%>">
<td class="cbi-section-table-cell"><a href="<%=url%>"><%=descr%></a></td>
<td class="cbi-section-table-cell"><%=origin%></td>
</tr>
<% if i == 1 then i = 0 elseif i == 0 then i = 1 end %>
<%end%>
</table>
</div>
</div>
</div>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
XHR.poll(10 , '<%=REQUEST_URI%>', { status: 1 },
function(x, info)
{
var tbody = document.getElementById('olsr_services');
if (tbody)
{
var s = '';
for (var idx = 0; idx < info.length; idx++)
{
var service = info[idx];
s += String.format(
'<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+'">' +
'<td class="cbi-section-table-cell"><a href="%s">%s</a></td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell"><a href="http://%s/cgi-bin-status.html">%s</a></td>' +
'</tr>',
service.url, service.descr, service.proto, service.origin, service.origin || '?'
);
}
tbody.innerHTML = s;
}
}
);
//]]></script>
<h2><a id="content" name="content"><%:Services%></a></h2>
<fieldset class="cbi-section">
<legend><%:Internal services%></legend>
<table class="cbi-section-table">
<thead>
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Url%></th>
<th class="cbi-section-table-cell"><%:Protocol%></th>
<th class="cbi-section-table-cell"><%:Source%></th>
</tr>
</thead>
<tbody id="olsr_services">
<%
for k, line in ipairs(services) do
local field = {}
-- split line at # and |, 1=url, 2=proto, 3=description, 4=source
local field = utl.split(line, "[#|]", split, true)
local url, proto, descr, origin = pcdata(field[1]), pcdata(field[2]), utl.trim(pcdata(field[3])), pcdata(field[4])
%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%>">
<td class="cbi-section-table-cell"><a href="<%=url%>"><%=descr%></a></td>
<td class="cbi-section-table-cell"><%=proto%></td>
<td class="cbi-section-table-cell"><a href="http://<%=origin%>/cgi-bin-status.html"><%=origin%></a></td>
</tr>
<% i = ((i % 2) + 1)
end %>
</tbody>
</table>
<br />
<%=last_update%>
<%else%>
<%:No services can be shown, because olsrd is not running or the olsrd-nameservice Plugin is not loaded.%>
<%end%>
</fieldset>
<%+footer%>

View file

@ -91,7 +91,21 @@ function index()
)
end
function action_neigh()
local function compare_links(a, b)
local c = tonumber(a.Cost)
local d = tonumber(b.Cost)
if not c or c == 0 then
return false
end
if not d or d == 0 then
return true
end
return c < d
end
function action_neigh(json)
local data = fetch_txtinfo("links")
if not data or not data.Links then
@ -99,22 +113,7 @@ function action_neigh()
return nil
end
local function compare(a, b)
local c = tonumber(a.Cost)
local d = tonumber(b.Cost)
if not c or c == 0 then
return false
end
if not d or d == 0 then
return true
end
return c < d
end
table.sort(data.Links, compare)
table.sort(data.Links, compare_links)
luci.template.render("status-olsr/neighbors", {links=data.Links})
end

View file

@ -2,6 +2,7 @@
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -12,33 +13,44 @@ You may obtain a copy of the License at
$Id$
]]--
mh = Map("olsrd", translate("OLSR - HNA-Announcements"))
local uci = require "luci.model.uci".cursor()
local ipv = uci:get_first("olsrd", "olsrd", "IpVersion", "4")
mh = Map("olsrd", translate("OLSR - HNA-Announcements"), translate("Hosts in a OLSR routed network can announce connecitivity " ..
"to external networks using HNA messages."))
hna4 = mh:section(TypedSection, "Hna4", translate("Hna4"), translate("Both values must use the dotted decimal notation."))
hna4.addremove = true
hna4.anonymous = true
hna4.template = "cbi/tblsection"
if ipv == "6and4" or ipv == "4" then
hna4 = mh:section(TypedSection, "Hna4", translate("Hna4"), translate("Both values must use the dotted decimal notation."))
hna4.addremove = true
hna4.anonymous = true
hna4.template = "cbi/tblsection"
net4 = hna4:option(Value, "netaddr", translate("Network address"))
net4.datatype = "ip4addr"
net4.placeholder = "15.15.0.0"
msk4 = hna4:option(Value, "netmask", translate("Netmask"))
msk4.datatype = "ip4addr"
msk4.placeholder = "255.255.255.0"
net4 = hna4:option(Value, "netaddr", translate("Network address"))
net4.datatype = "ip4addr"
net4.placeholder = "10.11.12.13"
net4.default = "10.11.12.13"
msk4 = hna4:option(Value, "netmask", translate("Netmask"))
msk4.datatype = "ip4addr"
msk4.placeholder = "255.255.255.255"
msk4.default = "255.255.255.255"
end
hna6 = mh:section(TypedSection, "Hna6", translate("Hna6"), translate("IPv6 network must be given in full notation, " ..
"prefix must be in CIDR notation."))
hna6.addremove = true
hna6.anonymous = true
hna6.template = "cbi/tblsection"
net6 = hna6:option(Value, "netaddr", translate("Network address"))
net6.datatype = "ip6addr"
net6.placeholder = "fec0:2200:106:0:0:0:0:0"
msk6 = hna6:option(Value, "prefix", translate("Prefix"))
msk6.datatype = "range(0,128)"
msk6.placeholder = "48"
if ipv == "6and4" or ipv == "6" then
hna6 = mh:section(TypedSection, "Hna6", translate("Hna6"), translate("IPv6 network must be given in full notation, " ..
"prefix must be in CIDR notation."))
hna6.addremove = true
hna6.anonymous = true
hna6.template = "cbi/tblsection"
net6 = hna6:option(Value, "netaddr", translate("Network address"))
net6.datatype = "ip6addr"
net6.placeholder = "fec0:2200:106:0:0:0:0:0"
net6.default = "fec0:2200:106:0:0:0:0:0"
msk6 = hna6:option(Value, "prefix", translate("Prefix"))
msk6.datatype = "range(0,128)"
msk6.placeholder = "128"
msk6.default = "128"
end
return mh

View file

@ -0,0 +1,28 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
]]--
module("luci.tools.olsr", package.seeall)
function etx_color(etx)
local color = "#bb3333"
if etx == 0 then
color = "#bb3333"
elseif etx < 4 then
color = "#00cc00"
elseif etx < 10 then
color = "#ffcb05"
elseif etx < 100 then
color = "#ff6600"
end
return color
end

View file

@ -2,6 +2,7 @@
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -12,26 +13,36 @@ You may obtain a copy of the License at
$Id$
-%>
<%
local i = 1
%>
<%+header%>
<h2><a id="content" name="content"><%:Active host net announcements%></a></h2>
<p><%:Overview of currently active OLSR host net announcements%></p>
<br />
<table class="smalltext" cellspacing="0" cellpadding="6">
<tr>
<th><%:Announced network%></th>
<th><%:OLSR gateway%></th>
</tr>
<% for k, route in ipairs(routes) do %>
<tr>
<td><%=route.Destination%></td>
<td>
<a href="http://<%=route.Gateway%>/cgi-bin-status.html"><%=route.Gateway%></a>
<% if route.Hostname then %>
/ <a href="http://<%=route.Hostname%>/cgi-bin-status.html"><%=route.Hostname%></a>
<% end %>
</td>
</tr>
<% end %>
</table>
<br />
<fieldset class="cbi-section">
<legend><%:Overview of currently active OLSR host net announcements%></legend>
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Announced network%></th>
<th class="cbi-section-table-cell"><%:OLSR gateway%></th>
</tr>
<% for k, route in ipairs(routes) do %>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%>">
<td class="cbi-section-table-cell"><%=route.Destination%></td>
<td class="cbi-section-table-cell">
<a href="http://<%=route.Gateway%>/cgi-bin-status.html"><%=route.Gateway%></a>
<% if route.Hostname then %>
/ <a href="http://<%=route.Hostname%>/cgi-bin-status.html"><%=route.Hostname%></a>
<% end %>
</td>
</tr>
<% i = ((i % 2) + 1)
end %>
</table>
</fieldset>
<%+footer%>

View file

@ -2,7 +2,7 @@
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Copyright 2010 Manuel Munz <freifunk at somakoma dot de>
Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -13,33 +13,42 @@ You may obtain a copy of the License at
$Id: mid.htm 5448 2009-10-31 15:54:11Z jow $
-%>
<%
local i = 1
%>
<%+header%>
<h2><a id="content" name="content"><%:Interfaces%></a></h2>
<p><%:Overview of interfaces where OLSR is running%></p>
<br />
<table class="smalltext" cellspacing="0" cellpadding="6">
<tr>
<th><%:Interface%></th>
<th><%:State%></th>
<th><%:MTU%></th>
<th><%:WLAN%></th>
<th><%:Source address%></th>
<th><%:Netmask%></th>
<th><%:Broadcast address%></th>
</tr>
<% for k, i in ipairs(iface) do %>
<tr>
<td><%=i.Name%></td>
<td><%=i.State%></td>
<td><%=i.MTU%></td>
<td><%=i.WLAN%></td>
<td><%=i["Src-Adress"]%></td>
<td><%=i.Mask%></td>
<td><%=i["Dst-Adress"]%></td>
</tr>
<% end %>
<fieldset class="cbi-section">
<legend><%:Overview of interfaces where OLSR is running%></legend>
</table>
<br />
<table class="cbi-section-table">
<tr>
<th class="cbi-section-table-cell"><%:Interface%></th>
<th class="cbi-section-table-cell"><%:State%></th>
<th class="cbi-section-table-cell"><%:MTU%></th>
<th class="cbi-section-table-cell"><%:WLAN%></th>
<th class="cbi-section-table-cell"><%:Source address%></th>
<th class="cbi-section-table-cell"><%:Netmask%></th>
<th class="cbi-section-table-cell"><%:Broadcast address%></th>
</tr>
<% for k, iface in ipairs(iface) do %>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%>">
<td class="cbi-section-table-cell"><%=iface.Name%></td>
<td class="cbi-section-table-cell"><%=iface.State%></td>
<td class="cbi-section-table-cell"><%=iface.MTU%></td>
<td class="cbi-section-table-cell"><%=iface.WLAN%></td>
<td class="cbi-section-table-cell"><%=iface["Src-Adress"]%></td>
<td class="cbi-section-table-cell"><%=iface.Mask%></td>
<td class="cbi-section-table-cell"><%=iface["Dst-Adress"]%></td>
</tr>
<% i = ((i % 2) + 1)
end %>
</table>
</fieldset>
<%+footer%>

View file

@ -2,6 +2,7 @@
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -12,21 +13,30 @@ You may obtain a copy of the License at
$Id$
-%>
<%
local i = 1
%>
<%+header%>
<h2><a id="content" name="content"><%:Active MID announcements%></a></h2>
<p><%:Overview of known multiple interface announcements%></p>
<br />
<table class="smalltext" cellspacing="0" cellpadding="6">
<tr>
<th><%:OLSR node%></th>
<th><%:Secondary OLSR interfaces%></th>
</tr>
<% for k, mid in ipairs(mids) do %>
<tr>
<td><a href="http://<%=mid["IP address"]%>"><%=mid["IP address"]%></a></td>
<td><%=mid.Aliases%></td>
</tr>
<% end %>
</table>
<br />
<fieldset class="cbi-section">
<legend><%:Overview of known multiple interface announcements%></legend>
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:OLSR node%></th>
<th class="cbi-section-table-cell" ><%:Secondary OLSR interfaces%></th>
</tr>
<% for k, mid in ipairs(mids) do %>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%>">
<td class="cbi-section-table-cell"><a href="http://<%=mid["IP address"]%>/cgi-bin-status.html"><%=mid["IP address"]%></a></td>
<td class="cbi-section-table-cell"><%=mid.Aliases%></td>
</tr>
<% i = ((i % 2) + 1)
end %>
</table>
</fieldset>
<%+footer%>

View file

@ -2,6 +2,7 @@
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -9,58 +10,143 @@ You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id: index.htm 6619 2010-12-05 15:02:44Z soma $
-%>
<%+header%>
<h2><a id="content" name="content"><%:OLSR connections%></a></h2>
<p><%:Overview of currently established OLSR connections%></p>
<br />
<table class="smalltext" cellspacing="0" cellpadding="6">
<tr>
<th><%:Neighbour IP%></th>
<th><%:Hostname%></th>
<th><%:Local interface IP%></th>
<th><%:Device%></th>
<th>LQ</th>
<th>NLQ</th>
<th>ETX</th>
</tr>
<% for k, link in ipairs(links) do
local color = "#bb3333"
link.Cost = tonumber(link.Cost) or 0
if link.Cost == 0 then
color = "#bb3333"
elseif link.Cost < 4 then
color = "#00cc00"
elseif link.Cost < 10 then
color = "#ffcb05"
elseif link.Cost < 100 then
color = "#ff6600"
end
<%
local olsrtools = require "luci.tools.olsr"
local i = 1
defaultgw_color = ""
if link.defaultgw == 1 then
defaultgw_color = "#ffff99"
if luci.http.formvalue("status") == "1" then
local rv = {}
for k, link in ipairs(links) do
link.Cost = tonumber(link.Cost) or 0
local color = olsrtools.etx_color(link.Cost)
defaultgw_color = ""
if link.defaultgw == 1 then
defaultgw_color = "#ffff99"
end
rv[#rv+1] = {
rip = link["Remote IP"],
hn = link["Hostname"],
lip = link["Local IP"],
dev = link["Local Device"],
lq = link.LQ,
nlq = link.NLQ,
cost = string.format("%.3f", link.Cost),
color = color,
dfgcolor = defaultgw_color
}
end
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
return
end
%>
<tr>
<td style="background-color:<%=defaultgw_color%>"><a href="http://<%=link["Remote IP"]%>/cgi-bin-status.html"><%=link["Remote IP"]%></a></td>
<td style="background-color:<%=defaultgw_color%>"><a href="http://<%=link["Hostname"]%>/cgi-bin-status.html"><%=link["Hostname"]%></a></td>
<td style="background-color:<%=defaultgw_color%>"><%=link["Local IP"]%></td>
<td style="background-color:<%=defaultgw_color%>"><%=link["Local Device"]%></td>
<td style="background-color:<%=defaultgw_color%>"><%=link.LQ%></td>
<td style="background-color:<%=defaultgw_color%>"><%=link.NLQ%></td>
<td style="background-color:<%=color%>"><%=string.format("%.3f", link.Cost)%></td>
</tr>
<% end %>
</table>
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
XHR.poll(10 , '<%=REQUEST_URI%>', { status: 1 },
function(x, info)
{
var nt = document.getElementById('olsr_neigh_table');
if (nt)
{
var s = '';
for (var idx = 0; idx < info.length; idx++)
{
var neigh = info[idx];
s += String.format(
'<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+'">' +
'<td class="cbi-section-table-cell" style="background-color:%s"><a href="http://%s/cgi-bin-status.html">%s</a></td>',
neigh.dfgcolor, neigh.rip, neigh.rip
);
if (neigh.hn) {
s += String.format(
'<td class="cbi-section-table-cell" style="background-color:%s"><a href="http://%s/cgi-bin-status.html">%s</a></td>',
neigh.dfgcolor, neigh.hn, neigh.hn
);
}
else {
s += String.format(
'<td class="cbi-section-table-cell" style="background-color:%s">?</td>',
neigh.dfgcolor
);
}
s += String.format(
'<td class="cbi-section-table-cell" style="background-color:%s">%s</td>' +
'<td class="cbi-section-table-cell" style="background-color:%s">%s</td>' +
'<td class="cbi-section-table-cell" style="background-color:%s">%s</td>' +
'<td class="cbi-section-table-cell" style="background-color:%s">%s</td>' +
'<td class="cbi-section-table-cell" style="background-color:%s">%s</td>' +
'</tr>',
neigh.dfgcolor, neigh.lip, neigh.dfgcolor, neigh.dev, neigh.dfgcolor, neigh.lq, neigh.dfgcolor, neigh.nlq, neigh.color, neigh.cost || '?'
);
}
nt.innerHTML = s;
}
}
);
//]]></script>
<h2><a id="content" name="content"><%:OLSR connections%></a></h2>
<fieldset class="cbi-section">
<legend><%:Overview of currently established OLSR connections%></legend>
<table class="cbi-section-table">
<thead>
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Neighbour IP%></th>
<th class="cbi-section-table-cell"><%:Hostname%></th>
<th class="cbi-section-table-cell"><%:Local interface IP%></th>
<th class="cbi-section-table-cell"><%:Device%></th>
<th class="cbi-section-table-cell">LQ</th>
<th class="cbi-section-table-cell">NLQ</th>
<th class="cbi-section-table-cell">ETX</th>
</tr>
</thead>
<tbody id="olsr_neigh_table">
<% local i = 1
for k, link in ipairs(links) do
link.Cost = tonumber(link.Cost) or 0
color = olsrtools.etx_color(link.Cost)
defaultgw_color = ""
if link.defaultgw == 1 then
defaultgw_color = "#ffff99"
end
%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%>">
<td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link["Remote IP"]%>/cgi-bin-status.html"><%=link["Remote IP"]%></a></td>
<td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link["Hostname"]%>/cgi-bin-status.html"><%=link["Hostname"]%></a></td>
<td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><%=link["Local IP"]%></td>
<td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><%=link["Local Device"]%></td>
<td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><%=link.LQ%></td>
<td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><%=link.NLQ%></td>
<td class="cbi-section-table-cell" style="background-color:<%=color%>"><%=string.format("%.3f", link.Cost)%></td>
</tr>
<%
i = ((i % 2) + 1)
end %>
</tbody>
</table>
<br />
<h3><%:Legend%>:</h3>
<ul>
<li><strong>LQ: </strong><%:Success rate of packages received from the neighbour%></li>
<li><strong>NLQ: </strong><%:Success rate of packages sent to the neighbour%></li>
<li><strong>ETX: </strong><%:Expected retransmission count%></li>
<li><strong>LQ: </strong><%:Success rate of packages received from the neighbour%></li>
<li><strong>NLQ: </strong><%:Success rate of packages sent to the neighbour%></li>
<li><strong>ETX: </strong><%:Expected retransmission count%></li>
</ul>
</fieldset>
<%+footer%>

View file

@ -2,7 +2,7 @@
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Copyright 2010 Manuel Munz <freifunk at somakoma dot de>
Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -69,6 +69,23 @@ local nr_hna = #data.HNA
local meshfactor = string.format("%.2f", nr_topo / nr_nodes)
if luci.http.formvalue("status") == "1" then
rv = {
nr_neighbors = nr_neigbors,
neighbors = neighbors,
interfaces = interfaces,
nr_ifaces = nr_ifaces,
nr_links = nr_links,
nr_topo = nr_topo,
nr_nodes = nr_nodes,
meshfactor = meshfactor
}
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
return
end
local ipv = luci.model.uci.cursor():get_first("olsrd", "olsrd", "IpVersion", "4")
function write_conf(conf, file)
@ -104,64 +121,172 @@ end
%>
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
XHR.poll(30, '<%=REQUEST_URI%>', { status: 1 },
function(x, info)
{
var e;
if (e = document.getElementById('nr_neighbors'))
e.innerHTML = info.nr_neighbors;
if (e = document.getElementById('neighbors'))
e.innerHTML = info.neighbors;
if (e = document.getElementById('nr_ifaces'))
e.innerHTML = info.nr_ifaces;
if (e = document.getElementById('interfaces'))
e.innerHTML = info.interfaces;
if (e = document.getElementById('nr_links'))
e.innerHTML = info.nr_links;
if (e = document.getElementById('nr_topo'))
e.innerHTML = info.nr_topo;
if (e = document.getElementById('nr_nodes'))
e.innerHTML = info.nr_nodes;
if (e = document.getElementById('meshfactor'))
e.innerHTML = info.meshfactor;
}
);
//]]></script>
<h2><a id="content" name="content">OLSR <%:Overview%></a></h2>
<div class="cbi-map">
<div class="cbi-section-node">
<div class="cbi-value"><label class="cbi-value-title"><%:Interfaces%></label>
<div class="cbi-value">
<div style="width: 15em; float:left;">
<label class="cbi-value-title"><%:Interfaces%></label>
</div>
<div class="cbi-value-field">
<div style="width: 6em; float:left;">
<a href="<%=luci.dispatcher.build_url("freifunk", "olsr", "interfaces")%>"><%=nr_ifaces%></a>
<a href="<%=luci.dispatcher.build_url("freifunk", "olsr", "interfaces")%>">
<span id="nr_ifaces">
<%=nr_ifaces%>
<span>
</a>
</div>
<div style="padding-left: 6em;">
<%=interfaces%>
<div style="padding-left: 21em;">
<span id="interfaces">
<%=interfaces%>
</span>
</div>
</div>
<br/>
</div>
<div class="cbi-value"><label class="cbi-value-title"><%:Neighbors%></label>
<div class="cbi-value">
<div style="width: 15em; float:left;">
<%:Neighbors%>
</div>
<div class="cbi-value-field">
<div style="width: 6em; float:left;">
<a href="<%=luci.dispatcher.build_url("freifunk", "olsr", "neighbors")%>"><%=nr_neigh%></a>
<a href="<%=luci.dispatcher.build_url("freifunk", "olsr", "neighbors")%>">
<span id="nr_neigh">
<%=nr_neigh%>
</span>
</a>
</div>
<div style="padding-left: 6em;">
<%=neighbors%>
<div style="padding-left: 21em;">
<span id="neighbors">
<%=neighbors%>
</span>
</div>
</div>
<br/>
</div>
<div class="cbi-value"><label class="cbi-value-title"><%:Nodes%></label>
<div class="cbi-value-field"><a href="<%=luci.dispatcher.build_url("freifunk", "olsr", "topology")%>"><%=nr_nodes%></a>
<div class="cbi-value">
<div style="width: 15em; float:left;">
<%:Nodes%>
</div>
<div class="cbi-value-field">
<div style="width: 6em; float:left;">
<a href="<%=luci.dispatcher.build_url("freifunk", "olsr", "topology")%>">
<span id="nr_nodes">
<%=nr_nodes%>
</span>
</a>
</div>
</div>
<br/>
</div>
<div class="cbi-value"><label class="cbi-value-title"><%:HNA%></label>
<div class="cbi-value-field"><a href="<%=luci.dispatcher.build_url("freifunk", "olsr", "hna")%>"><%=nr_hna%></a>
<div class="cbi-value">
<div style="width: 15em; float:left;">
<%:HNA%>
</div>
<div class="cbi-value-field">
<div style="width: 6em; float:left;">
<a href="<%=luci.dispatcher.build_url("freifunk", "olsr", "hna")%>">
<span id="nr_hna">
<%=nr_hna%>
</span>
</a>
</div>
</div>
<br/>
</div>
<div class="cbi-value"><label class="cbi-value-title"><%:Links total%></label>
<div class="cbi-value-field"><a href="<%=luci.dispatcher.build_url("freifunk", "olsr", "topology")%>"><%=nr_topo%></a>
<div class="cbi-value">
<div style="width: 15em; float:left;">
<%:Links total%>
</div>
<div class="cbi-value-field">
<div style="width: 6em; float:left;">
<a href="<%=luci.dispatcher.build_url("freifunk", "olsr", "topology")%>">
<span id="nr_topo">
<%=nr_topo%>
</span>
</a>
</div>
</div>
<br/>
</div>
<div class="cbi-value"><label class="cbi-value-title"><%:Links per node (average)%></label>
<div class="cbi-value-field"><%=meshfactor%>
<div class="cbi-value">
<div style="width: 15em; float:left;">
<%:Links per node (average)%>
</div>
<div class="cbi-value-field">
<div style="width: 6em; float:left;">
<span id="meshfactor">
<%=meshfactor%>
</span>
</div>
</div>
<br/>
</div>
</div>
</div>
<br/>
<h2><a id="content" name="content">OLSR <%:Configuration%></a></h2>
<div class="cbi-map">
<div class="cbi-section-node">
<div class="cbi-value"><label class="cbi-value-title"><%:Version%></label>
<div class="cbi-value-field"><%=ver.version%> (built <%=ver.date%> on <%=ver.host%>)
<div class="cbi-value">
<div style="width: 15em; float:left;">
<%:Version%>
</div>
<div class="cbi-value-field">
<%=ver.version%> (built <%=ver.date%> on <%=ver.host%>)
</div>
<br/>
</div>
<div class="cbi-value"><label class="cbi-value-title"><%:Download Config%></label>
<div class="cbi-value">
<div style="width: 15em; float:left;">
<%:Download Config%>
</div>
<div class="cbi-value-field">
<a href="<%=REQUEST_URI%>?openwrt">OpenWrt</a>,
<% if ipv == "6and4" then %>
@ -171,6 +296,7 @@ end
<a href="<%=REQUEST_URI%>?conf">OLSRD</a>
<% end %>
</div>
<br/>
</div>
</div>
</div>

View file

@ -2,55 +2,129 @@
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
-%>
<%+header%>
<h2><a id="content" name="content"><%:Known OLSR routes%></a></h2>
<p><%:Overview of currently known routes to other OLSR nodes%></p>
<br />
<table class="smalltext" cellspacing="0" cellpadding="6">
<tr>
<th><%:Announced network%></th>
<th><%:OLSR gateway%></th>
<th><%:Interface%></th>
<th><%:Metric%></th>
<th>ETX</th>
</tr>
<% for k, route in ipairs(routes) do
local color = "#bb3333"
route.ETX = tonumber(route.ETX)
if route.ETX == 0 then
color = "#bb3333"
elseif route.ETX < 4 then
color = "#00cc00"
elseif route.ETX < 10 then
color = "#ffcb05"
elseif route.ETX < 100 then
color = "#ff6600"
<%
local olsrtools = require "luci.tools.olsr"
local i = 1
if luci.http.formvalue("status") == "1" then
local rv = {}
for k, route in ipairs(routes) do
rv[#rv+1] = {
hostname = route.Hostname,
dest = route.Destination,
gw = route["Gateway IP"],
interface = route.Interface,
metric = route.Metric,
etx = tonumber(route.ETX),
color = olsrtools.etx_color(tonumber(route.ETX)),
}
end
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
return
end
%>
<tr>
<td><%=route.Destination%></td>
<td>
<a href="http://<%=route["Gateway IP"]%>/cgi-bin-status.html"><%=route["Gateway IP"]%></a>
<% if route.Hostname then %>
/ <a href="http://<%=route.Hostname%>/cgi-bin-status.html"><%=route.Hostname%></a>
<% end %>
</td>
<td><%=route.Interface%></td>
<td><%=route.Metric%></td>
<td style="background-color:<%=color%>"><%=string.format("%.3f", tonumber(route.ETX) or 0)%></td>
</tr>
<% end %>
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 },
function(x, info)
{
var rt = document.getElementById('olsrd_routes');
if (rt)
{
var s = '';
for (var idx = 0; idx < info.length; idx++)
{
var route = info[idx];
s += String.format(
'<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+'">' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">' +
'<a href="http://%s/cgi-bin-status.html">%s</a>',
route.dest, route.gw, route.gw
)
if (route.hostname)
{
s += String.format(
' / <a href="http://%s/cgi-bin-status.html">%s</a>',
route.hostname, route.hostname || '?'
);
}
s += String.format(
'</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell" style="background-color:%s">%s</td>' +
'</tr>',
route.interface, route.metric, route.color, route.etx || '?'
);
}
}
rt.innerHTML = s;
}
);
//]]></script>
<h2><a id="content" name="content"><%:Known OLSR routes%></a></h2>
<fieldset class="cbi-section">
<legend><%:Overview of currently known routes to other OLSR nodes%></legend>
<table class="cbi-section-table">
<thead>
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Announced network%></th>
<th class="cbi-section-table-cell"><%:OLSR gateway%></th>
<th class="cbi-section-table-cell"><%:Interface%></th>
<th class="cbi-section-table-cell"><%:Metric%></th>
<th class="cbi-section-table-cell">ETX</th>
</tr>
</thead>
<tbody id="olsrd_routes">
<% for k, route in ipairs(routes) do
color = olsrtools.etx_color(tonumber(route.ETX))
%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%>">
<td class="cbi-section-table-cell"><%=route.Destination%></td>
<td class="cbi-section-table-cell">
<a href="http://<%=route["Gateway IP"]%>/cgi-bin-status.html"><%=route["Gateway IP"]%></a>
<% if route.Hostname then %>
/ <a href="http://<%=route.Hostname%>/cgi-bin-status.html"><%=route.Hostname%></a>
<% end %>
</td>
<td class="cbi-section-table-cell"><%=route.Interface%></td>
<td class="cbi-section-table-cell"><%=route.Metric%></td>
<td class="cbi-section-table-cell" style="background-color:<%=color%>"><%=string.format("%.3f", tonumber(route.ETX) or 0)%></td>
</tr>
<%
i = ((i % 2) + 1)
end %>
</tbody>
</table>
<br />
</fieldset>
<%+footer%>

View file

@ -2,7 +2,7 @@
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Copyright 2010 Manuel Munz <freifunk at somakoma dot de>
Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -12,6 +12,7 @@ You may obtain a copy of the License at
-%>
<%
local i = 1
require("luci.model.uci")
local uci = luci.model.uci.cursor_state()
@ -23,39 +24,48 @@ end)
<%+header%>
<h2><a id="content" name="content"><%:SmartGW announcements%></a></h2>
<% if has_smartgw then %>
<p><%:Overview of smart gateways in this network%></p>
<br />
<table class="smalltext" cellspacing="0" cellpadding="6">
<tr>
<th><%:Gateway%></th>
<th><%:Status%></th>
<th><%:ETX%></th>
<th><%:Hops%></th>
<th><%:Uplink%></th>
<th><%:Downlink%></th>
<th><%:IPv4%></th>
<th><%:IPv6%></th>
<th><%:Prefix%></th>
</tr>
<% for k, gw in ipairs(gws) do %>
<tr>
<td><a href="http://<%=gw["Gateway IP"]%>/cgi-bin-status.html"><%=gw["Gateway IP"]%></a></td>
<td><%=gw.Status%></td>
<td><%=gw.ETX%></td>
<td><%=gw.Hopcnt%></td>
<td><%=gw.Uplink%></td>
<td><%=gw.Downlnk%></td>
<td><%=gw.IPv4%></td>
<td><%=gw.IPv6%></td>
<td><%=gw.Prefix%></td>
</tr>
<% end %>
</table>
<br />
<% if has_smartgw then %>
<fieldset class="cbi-section">
<legend><%:Overview of smart gateways in this network%></legend>
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Gateway%></th>
<th class="cbi-section-table-cell"><%:Status%></th>
<th class="cbi-section-table-cell"><%:ETX%></th>
<th class="cbi-section-table-cell"><%:Hops%></th>
<th class="cbi-section-table-cell"><%:Uplink%></th>
<th class="cbi-section-table-cell"><%:Downlink%></th>
<th class="cbi-section-table-cell"><%:IPv4%></th>
<th class="cbi-section-table-cell"><%:IPv6%></th>
<th class="cbi-section-table-cell"><%:Prefix%></th>
</tr>
<% for k, gw in ipairs(gws) do %>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%>">
<td class="cbi-section-table-cell"><a href="http://<%=gw["Gateway IP"]%>/cgi-bin-status.html"><%=gw["Gateway IP"]%></a></td>
<td class="cbi-section-table-cell"><%=gw.Status%></td>
<td class="cbi-section-table-cell"><%=gw.ETX%></td>
<td class="cbi-section-table-cell"><%=gw.Hopcnt%></td>
<td class="cbi-section-table-cell"><%=gw.Uplink%></td>
<td class="cbi-section-table-cell"><%=gw.Downlnk%></td>
<td class="cbi-section-table-cell"><%=gw.IPv4%></td>
<td class="cbi-section-table-cell"><%=gw.IPv6%></td>
<td class="cbi-section-table-cell"><%=gw.Prefix%></td>
</tr>
<% i = ((i % 2) + 1)
end %>
</table>
</fieldset>
<% else %>
<%:SmartGateway is not configured on this system.%>
<%:SmartGateway is not configured on this system.%>
<% end %>
<%+footer%>

View file

@ -2,6 +2,7 @@
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -12,28 +13,41 @@ You may obtain a copy of the License at
$Id$
-%>
<%
local i = 1
local olsrtools = require "luci.tools.olsr"
%>
<%+header%>
<h2><a id="content" name="content"><%:Active OLSR nodes%></a></h2>
<p><%:Overview of currently known OLSR nodes%></p>
<br />
<table class="smalltext" cellspacing="0" cellpadding="6">
<tr>
<th><%:OLSR node%></th>
<th><%:Last hop%></th>
<th>LQ</th>
<th>ILQ</th>
<th>ETX</th>
</tr>
<% for k, route in ipairs(routes) do
%>
<tr>
<td><a href="http://<%=route["Dest. IP"]%>"><%=route["Dest. IP"]%></a></td>
<td><a href="http://<%=route["Last hop IP"]%>"><%=route["Last hop IP"]%></a></td>
<td><%=route.LQ%></td>
<td><%=route.NLQ%></td>
<td><%=string.format("%.3f", tonumber(route.Cost) or 0)%></td>
</tr>
<% end %>
</table>
<br />
<fieldset class="cbi-section">
<legend><%:Overview of currently known OLSR nodes%></legend>
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:OLSR node%></th>
<th class="cbi-section-table-cell"><%:Last hop%></th>
<th class="cbi-section-table-cell"><%:LQ%></th>
<th class="cbi-section-table-cell"><%:NLQ%></th>
<th class="cbi-section-table-cell"><%:ETX%></th>
</tr>
<% for k, route in ipairs(routes) do
local cost = string.format("%.3f", tonumber(route.Cost) or 0)
local color = olsrtools.etx_color(tonumber(cost))
%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%>">
<td class="cbi-section-table-cell"><a href="http://<%=route["Dest. IP"]%>/cgi-bin-status.html"><%=route["Dest. IP"]%></a></td>
<td class="cbi-section-table-cell"><a href="http://<%=route["Last hop IP"]%>/cgi-bin-status.html"><%=route["Last hop IP"]%></a></td>
<td class="cbi-section-table-cell"><%=route.LQ%></td>
<td class="cbi-section-table-cell"><%=route.NLQ%></td>
<td class="cbi-section-table-cell" style="background-color:<%=color%>"><%=cost%></td>
</tr>
<% i = ((i % 2) + 1)
end %>
</table>
</fieldset>
<%+footer%>

View file

@ -70,7 +70,7 @@ function s.create(self, name)
end
s:option( Flag, "enable", translate("Enabled") )
s:option( Flag, "enabled", translate("Enabled") )
local active = s:option( DummyValue, "_active", translate("Started") )
function active.cfgvalue(self, section)

View file

@ -63,7 +63,6 @@ config openvpn_recipe client_tun
option persist_tun "1"
option verb "3"
option reneg_sec "0"
option explicit_exit_notify "1"
option float "1"
option management "127.0.0.1 31194"
@ -104,6 +103,5 @@ config openvpn_recipe client_tap_bridge
option persist_key "1"
option verb "3"
option reneg_sec "0"
option explicit_exit_notify "1"
option float "1"
option management "127.0.0.1 31194"

View file

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View file

@ -1,4 +1,4 @@
PO = asterisk
PO = pbx-voicemail
include ../../build/config.mk
include ../../build/module.mk

View file

@ -0,0 +1,24 @@
--[[
Copyright 2011 Iordan Iordanov <iiordanov (AT) gmail.com>
This file is part of luci-pbx-voicemail.
luci-pbx-voicemail is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
luci-pbx-voicemail is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with luci-pbx-voicemail. If not, see <http://www.gnu.org/licenses/>.
]]--
module("luci.controller.pbx-voicemail", package.seeall)
function index()
entry({"admin", "services", "pbx", "pbx-voicemail"}, cbi("pbx-voicemail"), "Voicemail", 5)
end

View file

@ -0,0 +1,150 @@
--[[
Copyright 2011 Iordan Iordanov <iiordanov (AT) gmail.com>
This file is part of luci-pbx-voicemail.
luci-pbx-voicemail is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
luci-pbx-voicemail is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with luci-pbx-voicemail. If not, see <http://www.gnu.org/licenses/>.
]]--
if nixio.fs.access("/etc/init.d/asterisk") then
server = "asterisk"
elseif nixio.fs.access("/etc/init.d/freeswitch") then
server = "freeswitch"
else
server = ""
end
modulename = "pbx-voicemail"
vmlogfile = "/tmp/last_sent_voicemail.log"
m = Map (modulename, translate("Voicemail Setup"),
translate("Here you can configure a global voicemail for this PBX. Since this system is \
intended to run on embedded systems like routers, there is no local storage of voicemail - \
it must be sent out by email. Therefore you need to configure an outgoing mail (SMTP) server \
(for example your ISP's, Google's, or Yahoo's SMTP server), and provide a list of \
addresses that receive recorded voicemail."))
-- Recreate the config, and restart services after changes are commited to the configuration.
function m.on_after_commit(self)
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null")
end
----------------------------------------------------------------------------------------------------
s = m:section(NamedSection, "global_voicemail", "voicemail", translate("Global Voicemail Setup"),
translate("When you enable voicemail, you will have the opportunity to specify \
email addresses that receive recorded voicemail. You must also set up an SMTP server below."))
s.anonymous = true
enable = s:option(ListValue, "enabled", translate("Enable Voicemail"))
enable:value("yes", translate("Yes"))
enable:value("no", translate("No"))
enable.default = "no"
emails = s:option(DynamicList, "global_email_addresses",
translate("Email Addresses that Receive Voicemail"))
emails:depends("enabled", "yes")
savepath = s:option(Value, "global_save_path", translate("Local Storage Directory"),
translate("You can also retain copies of voicemail messages on the device running \
your PBX. The path specified here will be created if it doesn't exist. \
Beware of limited space on embedded devices like routers, and enable this \
option only if you know what you are doing."))
savepath.optional = true
if nixio.fs.access("/etc/pbx-voicemail/greeting.WAV") then
m1 = s:option(DummyValue, "_m1")
m1:depends("enabled", "yes")
m1.default = "NOTE: Found a voicemail greeting. To check or change your voicemail greeting, dial *789 \
and the system will play your current message. You have 5 seconds to hangup, otherwise a \
new recording will begin and your old message will be overwritten. Hang up or press # to \
stop recording. When you press #, the system will play back the new recording."
else
m1 = s:option(DummyValue, "_m1")
m1:depends("enabled", "yes")
m1.default = "WARNING: Could not find voicemail greeting. Callers will hear only a beep before \
recording starts. To record a greeting, dial *789 and record a greeting after the beep. \
Hang up or press # to stop recording. When # is pressed the system will play back the \
recording."
end
----------------------------------------------------------------------------------------------------
s = m:section(NamedSection, "voicemail_smtp", "voicemail", translate("Outgoing mail (SMTP) Server"),
translate("In order for this PBX to send emails containing voicemail recordings, you need to \
set up an SMTP server here. Your ISP usually provides an SMTP server for that purpose. \
You can also set up a third party SMTP server such as the one provided by Google or Yahoo."))
s.anonymous = true
serv = s:option(Value, "smtp_server", translate("SMTP Server Hostname or IP Address"))
serv.datatype = "host"
port = s:option(Value, "smtp_port", translate("SMTP Port Number"))
port.datatype = "port"
port.default = "25"
tls = s:option(ListValue, "smtp_tls", translate("Secure Connection Using TLS"))
tls:value("on", translate("Yes"))
tls:value("off", translate("No"))
tls.default = "on"
auth = s:option(ListValue, "smtp_auth", translate("SMTP Server Authentication"))
auth:value("on", translate("Yes"))
auth:value("off", translate("No"))
auth.default = "off"
user = s:option(Value, "smtp_user", translate("SMTP User Name"))
user:depends("smtp_auth", "on")
pwd = s:option(Value, "smtp_password", translate("SMTP Password"),
translate("Your real SMTP password is not shown for your protection. It will be changed \
only when you change the value in this box."))
pwd.password = true
pwd:depends("smtp_auth", "on")
-- We skip reading off the saved value and return nothing.
function pwd.cfgvalue(self, section)
return "Password Not Displayed"
end
-- We check the entered value against the saved one, and only write if the entered value is
-- something other than the empty string, and it differes from the saved value.
function pwd.write(self, section, value)
local orig_pwd = m:get(section, self.option)
if value == "Password Not Displayed" then value = "" end
if value and #value > 0 and orig_pwd ~= value then
Value.write(self, section, value)
end
end
----------------------------------------------------------------------------------------------------
s = m:section(NamedSection, "voicemail_log", "voicemail", translate("Last Sent Voicemail Log"))
s.anonymous = true
s:option (DummyValue, "vmlog")
sts = s:option(DummyValue, "_sts")
sts.template = "cbi/tvalue"
sts.rows = 5
function sts.cfgvalue(self, section)
log = nixio.fs.readfile(vmlogfile)
if log == nil or log == "" then
log = "No errors or messages reported."
end
return log
end
return m

View file

@ -0,0 +1,6 @@
config 'voicemail' 'global_voicemail'
config 'voicemail' 'voicemail_smtp'
config 'voicemail' 'voicemail_log'

View file

@ -0,0 +1,2 @@
user |USER|
password |PASSWORD|

View file

@ -0,0 +1,2 @@
account default : defaultacct

View file

@ -0,0 +1,5 @@
account defaultacct
host |HOST|
port |PORT|
from voicemail@pbx

View file

@ -0,0 +1,5 @@
defaults
auth |AUTH|
tls_certcheck off
tls |TLS|

View file

@ -0,0 +1,114 @@
#!/bin/sh
#
# Copyright 2011 Iordan Iordanov <iiordanov (AT) gmail.com>
#
# This file is part of luci-pbx-voicemail.
#
# luci-pbx-voicemail is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# luci-pbx-voicemail is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with luci-pbx-voicemail. If not, see <http://www.gnu.org/licenses/>.
#
#
# Thanks to http://www.zedwood.com for providing an excellent example of how to
# properly assemble an email message with a uuencoded attachment.
#
LOGFILE=/tmp/last_sent_voicemail.log
# Redirect standard error and standard output to a log file.
rm -f "$LOGFILE"
exec 1>"$LOGFILE"
exec 2>&1
# Appends its second argument to a file named in the first argument.
append_to_file ()
{
echo "$2">>$1;
}
# Grab the attachment name, which should be sent as the first argument, and
# exit with a warning if there is no voicemail to send.
ATTACHMENT="$1"
[ ! -f "$ATTACHMENT" ] && echo "WARNING: Found no voicemail recording to send." && exit
# Grab the callerID which should have been sent as an argument.
CALLERID="$2"
[ -z "$CALLERID" ] && CALLERID="An unknown caller"
# Determine addresses we would like to send the voicemail to and exit if none are found.
TO="`uci -q get pbx-voicemail.global_voicemail.global_email_addresses | tr ' ' ','`"
[ -z "$TO" ] && echo "WARNING: Found no addresses to send voicemail to." && exit
# See whether we should retain a copy of the voicemail.
SAVEPATH="`uci -q get pbx-voicemail.global_voicemail.global_save_path`"
DATE="`date +%Y-%m-%d`"
TIME="`date +%H:%M:%S`"
FROM="voicemail@pbx"
REPLY="do-not-reply@pbx"
SUBJECT="Voicemail from $CALLERID, $DATE, $TIME"
MSGBODY="$CALLERID has left voicemail for you on $DATE at $TIME."
MIMETYPE="audio/wav"
TMP1="/tmp/tmpemail1.$$";
TMP2="/tmp/tmpemail2.$$";
BOUNDARY="`date +%s | md5sum | awk '{print $1}'`"
FILENAME="voicemail-$DATE-$TIME.WAV"
# Clean up just in case.
rm -f $TMP1 $TMP2
append_to_file $TMP1 "From: $FROM"
append_to_file $TMP1 "To: $TO"
append_to_file $TMP1 "Reply-To: $REPLY"
append_to_file $TMP1 "Subject: $SUBJECT"
append_to_file $TMP1 "Content-Type: multipart/mixed; boundary=\""$BOUNDARY"\""
append_to_file $TMP1 ""
append_to_file $TMP1 "This is a MIME formatted message. If you see this text it means that your"
append_to_file $TMP1 "email software does not support MIME formatted messages."
append_to_file $TMP1 ""
append_to_file $TMP1 "--$BOUNDARY"
append_to_file $TMP1 "Content-Type: text/plain; charset=ISO-8859-1; format=flowed"
append_to_file $TMP1 "Content-Transfer-Encoding: 7bit"
append_to_file $TMP1 "Content-Disposition: inline"
append_to_file $TMP1 ""
append_to_file $TMP1 "$MSGBODY"
append_to_file $TMP1 ""
append_to_file $TMP1 ""
append_to_file $TMP1 "--$BOUNDARY"
append_to_file $TMP1 "Content-Type: $MIMETYPE; name=\"$FILENAME\""
append_to_file $TMP1 "Content-Transfer-Encoding: base64"
append_to_file $TMP1 "Content-Disposition: attachment; filename=\"$FILENAME\";"
append_to_file $TMP1 ""
append_to_file $TMP2 ""
append_to_file $TMP2 ""
append_to_file $TMP2 "--$BOUNDARY--"
append_to_file $TMP2 ""
append_to_file $TMP2 ""
# Cat everything together and pass to msmtprc to send out.
( cat $TMP1
cat "$ATTACHMENT" | uuencode --base64 /dev/stdout | sed -e '1,1d' -e '$d'
cat $TMP2 ) | msmtp -t -C /etc/pbx-msmtprc
# Clean up email temp files.
rm -f $TMP1 $TMP2
# Either delete or move the attachment based on the SAVEPATH variable.
if [ -z "$SAVEPATH" ]
then
rm -f "$ATTACHMENT"
else
mkdir -p "$SAVEPATH"
mv --backup=t "$ATTACHMENT" "$SAVEPATH/$FILENAME"
fi

View file

@ -0,0 +1,7 @@
This file pertains to the sounds files included in root/etc/pbx-asterisk/sounds
Recorded by:
Allison Smith (http://www.theivrvoice.com)
Financial Contributions by:
Digium, Inc. (http://www.digium.com)

View file

@ -0,0 +1,312 @@
This file pertains to the sounds files included in root/etc/pbx-asterisk/sounds
LICENSE FOR VOICE PROMPT FILES
------------------------------
The voice prompt files distributed herewith are Copyright (C) 2003-2008
Allison Smith, and provided under terms of the following License. For
more information, or to purchase custom voice prompt files, please
visit:
http://www.digium.com/ivr or http://www.theasteriskvoice.com
LICENSE
-------
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS
CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS
PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE
WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS
PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND
AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS
LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU
THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH
TERMS AND CONDITIONS.
1. Definitions.
a. "Collective Work" means a work, such as a periodical issue,
anthology or encyclopedia, in which the Work in its entirety in
unmodified form, along with one or more other contributions,
constituting separate and independent works in themselves, are
assembled into a collective whole. A work that constitutes a
Collective Work will not be considered a Derivative Work (as defined
below) for the purposes of this License.
b. "Creative Commons Compatible License" means a license that is
listed at http://creativecommons.org/compatiblelicenses that has been
approved by Creative Commons as being essentially equivalent to this
License, including, at a minimum, because that license: (i) contains
terms that have the same purpose, meaning and effect as the License
Elements of this License; and, (ii) explicitly permits the relicensing
of derivatives of works made available under that license under this
License or either a Creative Commons unported license or a Creative
Commons jurisdiction license with the same License Elements as this
License.
c. "Derivative Work" means a work based upon the Work or upon the Work
and other pre-existing works, such as a translation, musical
arrangement, dramatization, fictionalization, motion picture version,
sound recording, art reproduction, abridgment, condensation, or any
other form in which the Work may be recast, transformed, or adapted,
except that a work that constitutes a Collective Work will not be
considered a Derivative Work for the purpose of this License. For the
avoidance of doubt, where the Work is a musical composition or sound
recording, the synchronization of the Work in timed-relation with a
moving image ("synching") will be considered a Derivative Work for the
purpose of this License.
d. "License Elements" means the following high-level license
attributes as selected by Licensor and indicated in the title of this
License: Attribution, ShareAlike.
e. "Licensor" means the individual, individuals, entity or entities
that offers the Work under the terms of this License.
f. "Original Author" means the individual, individuals, entity or
entities who created the Work.
g. "Work" means the copyrighted voice prompt files recorded by Allison
Smith for Asterisk and distributed with this License.
h. "You" means an individual or entity exercising rights under this
License who has not previously violated the terms of this License with
respect to the Work, or who has received express permission from the
Licensor to exercise rights under this License despite a previous
violation.
2. Fair Use Rights.
Nothing in this license is intended to reduce, limit, or restrict any
rights arising from fair use, first sale or other limitations on the
exclusive rights of the copyright owner under copyright law or other
applicable laws.
3. License Grant.
Subject to the terms and conditions of this License, Licensor hereby
grants You a worldwide, royalty-free, non-exclusive, perpetual (for
the duration of the applicable copyright) license to exercise the
rights in the Work as stated below:
a. to reproduce the Work, to incorporate the Work into one or more
Collective Works, and to reproduce the Work as incorporated in the
Collective Works;
b. to create and reproduce Derivative Works provided that any such
Derivative Work, including any translation in any medium, takes
reasonable steps to clearly label, demarcate or otherwise identify
that changes were made to the original Work. For example, a
translation could be marked "The original work was translated from
English to Spanish," or a modification could indicate "The original
work has been modified.";
c. to distribute copies or phonorecords of, display publicly, perform
publicly, and perform publicly by means of a digital audio
transmission the Work including as incorporated in Collective Works;
d. to distribute copies or phonorecords of, display publicly, perform
publicly, and perform publicly by means of a digital audio
transmission Derivative Works.
e. For the avoidance of doubt, where the Work is a musical
composition:
i. Performance Royalties Under Blanket Licenses. Licensor waives the
exclusive right to collect, whether individually or, in the event
that Licensor is a member of a performance rights society
(e.g. ASCAP, BMI, SESAC), via that society, royalties for the public
performance or public digital performance e.g. webcast) of the Work.
ii.Mechanical Rights and Statutory Royalties. Licensor waives the
exclusive right to collect, whether individually or via a music
rights agency or designated agent (e.g. Harry Fox Agency), royalties
for any phonorecord You create from the Work ("cover version") and
distribute, subject to the compulsory license created by 17 USC
Section 115 of the US Copyright Act (or the equivalent in other
jurisdictions).
f. Webcasting Rights and Statutory Royalties. For the avoidance of
doubt, where the Work is a sound recording, Licensor waives the
exclusive right to collect, whether individually or via a
performance-rights society (e.g. SoundExchange), royalties for the
public digital performance (e.g. webcast) of the Work, subject to the
compulsory license created by 17 USC Section 114 of the US Copyright
Act (or the equivalent in other jurisdictions).
The above rights may be exercised in all media and formats whether now
known or hereafter devised. The above rights include the right to make
such modifications as are technically necessary to exercise the rights
in other media and formats. All rights not expressly granted by
Licensor are hereby reserved.
4. Restrictions.
The license granted in Section 3 above is expressly made subject to
and limited by the following restrictions:
a. You may distribute, publicly display, publicly perform, or publicly
digitally perform the Work only under the terms of this License, and
You must include a copy of, or the Uniform Resource Identifier for,
this License with every copy or phonorecord of the Work You
distribute, publicly display, publicly perform, or publicly digitally
perform. You may not offer or impose any terms on the Work that
restrict the terms of this License or the ability of a recipient of
the Work to exercise of the rights granted to that recipient under the
terms of the License. You may not sublicense the Work. You must keep
intact all notices that refer to this License and to the disclaimer of
warranties. When You distribute, publicly display, publicly perform,
or publicly digitally perform the Work, You may not impose any
technological measures on the Work that restrict the ability of a
recipient of the Work from You to exercise of the rights granted to
that recipient under the terms of the License. This Section 4(a)
applies to the Work as incorporated in a Collective Work, but this
does not require the Collective Work apart from the Work itself to be
made subject to the terms of this License. If You create a Collective
Work, upon notice from any Licensor You must, to the extent
practicable, remove from the Collective Work any credit as required by
Section 4(c), as requested. If You create a Derivative Work, upon
notice from any Licensor You must, to the extent practicable, remove
from the Derivative Work any credit as required by Section 4(c), as
requested.
b. You may distribute, publicly display, publicly perform, or publicly
digitally perform a Derivative Work only under: (i) the terms of this
License; (ii) a later version of this License with the same License
Elements as this License; (iii) either the Creative Commons (Unported)
license or a Creative Commons jurisdiction license (either this or a
later license version) that contains the same License Elements as this
License (e.g. Attribution-ShareAlike 3.0 (Unported)); (iv) a Creative
Commons Compatible License. If you license the Derivative Work under
one of the licenses mentioned in (iv), you must comply with the terms
of that license. If you license the Derivative Work under the terms of
any of the licenses mentioned in (i), (ii) or (iii) (the "Applicable
License"), you must comply with the terms of the Applicable License
generally and with the following provisions: (I) You must include a
copy of, or the Uniform Resource Identifier for, the Applicable
License with every copy or phonorecord of each Derivative Work You
distribute, publicly display, publicly perform, or publicly digitally
perform; (II) You may not offer or impose any terms on the Derivative
Works that restrict the terms of the Applicable License or the ability
of a recipient of the Work to exercise the rights granted to that
recipient under the terms of the Applicable License; (III) You must
keep intact all notices that refer to the Applicable License and to
the disclaimer of warranties; and, (IV) when You distribute, publicly
display, publicly perform, or publicly digitally perform the Work, You
may not impose any technological measures on the Derivative Work that
restrict the ability of a recipient of the Derivative Work from You to
exercise the rights granted to that recipient under the terms of the
Applicable License. This Section 4(b) applies to the Derivative Work
as incorporated in a Collective Work, but this does not require the
Collective Work apart from the Derivative Work itself to be made
subject to the terms of the Applicable License.
c. If You distribute, publicly display, publicly perform, or publicly
digitally perform the Work (as defined in Section 1 above) or any
Derivative Works (as defined in Section 1 above) or Collective Works
(as defined in Section 1 above), You must, unless a request has been
made pursuant to Section 4(a), keep intact all copyright notices for
the Work and provide, reasonable to the medium or means You are
utilizing: (i) the name of the Original Author (or pseudonym, if
applicable) if supplied, and/or (ii) if the Original Author and/or
Licensor designate another party or parties (e.g. a sponsor institute,
publishing entity, journal) for attribution ("Attribution Parties") in
Licensor's copyright notice, terms of service or by other reasonable
means, the name of such party or parties; the title of the Work if
supplied; to the extent reasonably practicable, the Uniform Resource
Identifier, if any, that Licensor specifies to be associated with the
Work, unless such URI does not refer to the copyright notice or
licensing information for the Work; and, consistent with Section 3(b)
in the case of a Derivative Work, a credit identifying the use of the
Work in the Derivative Work (e.g., "French translation of the Work by
Original Author," or "Screenplay based on original Work by Original
Author"). The credit required by this Section 4(c) may be implemented
in any reasonable manner; provided, however, that in the case of a
Derivative Work or Collective Work, at a minimum such credit will
appear, if a credit for all contributing authors of the Derivative
Work or Collective Work appears, then as part of these credits and in
a manner at least as prominent as the credits for the other
contributing authors. For the avoidance of doubt, You may only use the
credit required by this Section for the purpose of attribution in the
manner set out above and, by exercising Your rights under this
License, You may not implicitly or explicitly assert or imply any
connection with, sponsorship or endorsement by the Original Author,
Licensor and/or Attribution Parties, as appropriate, of You or Your
use of the Work, without the separate, express prior written
permission of the Original Author, Licensor and/or Attribution
Parties.
5. Representations, Warranties and Disclaimer.
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING,
LICENSOR OFFERS THE WORK AS-IS AND ONLY TO THE EXTENT OF ANY RIGHTS
HELD IN THE LICENSED WORK BY THE LICENSOR. THE LICENSOR MAKES NO
REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK,
EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT
LIMITATION, WARRANTIES OF TITLE, MARKETABILITY, MERCHANTIBILITY,
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF
ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW
THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY
TO YOU.
6. Limitation on Liability.
EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL
LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT
OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. Termination.
a. This License and the rights granted hereunder will terminate
automatically upon any breach by You of the terms of this
License. Individuals or entities who have received Derivative Works or
Collective Works from You under this License, however, will not have
their licenses terminated provided such individuals or entities remain
in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8
will survive any termination of this License.
b. Subject to the above terms and conditions, the license granted here
is perpetual (for the duration of the applicable copyright in the
Work). Notwithstanding the above, Licensor reserves the right to
release the Work under different license terms or to stop distributing
the Work at any time; provided, however that any such election will
not serve to withdraw this License (or any other license that has
been, or is required to be, granted under the terms of this License),
and this License will continue in full force and effect unless
terminated as stated above.
8. Miscellaneous.
a. Each time You distribute or publicly digitally perform the Work (as
defined in Section 1 above) or a Collective Work (as defined in
Section 1 above), the Licensor offers to the recipient a license to
the Work on the same terms and conditions as the license granted to
You under this License.
b. Each time You distribute or publicly digitally perform a Derivative
Work, Licensor offers to the recipient a license to the original Work
on the same terms and conditions as the license granted to You under
this License.
c. If any provision of this License is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of
the remainder of the terms of this License, and without further action
by the parties to this agreement, such provision shall be reformed to
the minimum extent necessary to make such provision valid and
enforceable.
d. No term or provision of this License shall be deemed waived and no
breach consented to unless such waiver or consent shall be in writing
and signed by the party to be charged with such waiver or consent.
e. This License constitutes the entire agreement between the parties
with respect to the Work licensed here. There are no understandings,
agreements or representations with respect to the Work not specified
here. Licensor shall not be bound by any additional provisions that
may appear in any communication from You. This License may not be
modified without the mutual written agreement of the Licensor and You.

View file

@ -20,10 +20,10 @@
module("luci.controller.pbx", package.seeall)
function index()
entry({"admin", "services", "pbx"}, cbi("pbx"), "PBX", 80)
entry({"admin", "services", "pbx", "pbx-google"}, cbi("pbx-google"), "Google Accounts", 1)
entry({"admin", "services", "pbx", "pbx-voip"}, cbi("pbx-voip"), "SIP Accounts", 2)
entry({"admin", "services", "pbx", "pbx-users"}, cbi("pbx-users"), "User Accounts", 3)
entry({"admin", "services", "pbx", "pbx-calls"}, cbi("pbx-calls"), "Call Routing", 4)
entry({"admin", "services", "pbx", "pbs-advanced"}, cbi("pbx-advanced"), "Advanced Settings", 5)
entry({"admin", "services", "pbx"}, cbi("pbx"), "PBX", 80)
entry({"admin", "services", "pbx", "pbx-google"}, cbi("pbx-google"), "Google Accounts", 1)
entry({"admin", "services", "pbx", "pbx-voip"}, cbi("pbx-voip"), "SIP Accounts", 2)
entry({"admin", "services", "pbx", "pbx-users"}, cbi("pbx-users"), "User Accounts", 3)
entry({"admin", "services", "pbx", "pbx-calls"}, cbi("pbx-calls"), "Call Routing", 4)
entry({"admin", "services", "pbx", "pbx-advanced"}, cbi("pbx-advanced"), "Advanced Settings", 6)
end

View file

@ -33,194 +33,194 @@ defaultrtpend = 19900
-- Returns all the network related settings, including a constructed RTP range
function get_network_info()
externhost = m.uci:get(modulename, "advanced", "externhost")
ipaddr = m.uci:get("network", "lan", "ipaddr")
bindport = m.uci:get(modulename, "advanced", "bindport")
rtpstart = m.uci:get(modulename, "advanced", "rtpstart")
rtpend = m.uci:get(modulename, "advanced", "rtpend")
externhost = m.uci:get(modulename, "advanced", "externhost")
ipaddr = m.uci:get("network", "lan", "ipaddr")
bindport = m.uci:get(modulename, "advanced", "bindport")
rtpstart = m.uci:get(modulename, "advanced", "rtpstart")
rtpend = m.uci:get(modulename, "advanced", "rtpend")
if bindport == nil then bindport = defaultbindport end
if rtpstart == nil then rtpstart = defaultrtpstart end
if rtpend == nil then rtpend = defaultrtpend end
if bindport == nil then bindport = defaultbindport end
if rtpstart == nil then rtpstart = defaultrtpstart end
if rtpend == nil then rtpend = defaultrtpend end
if rtpstart == nil or rtpend == nil then
rtprange = nil
else
rtprange = rtpstart .. "-" .. rtpend
end
if rtpstart == nil or rtpend == nil then
rtprange = nil
else
rtprange = rtpstart .. "-" .. rtpend
end
return bindport, rtprange, ipaddr, externhost
return bindport, rtprange, ipaddr, externhost
end
-- If not present, insert empty rules in the given config & section named PBX-SIP and PBX-RTP
function insert_empty_sip_rtp_rules(config, section)
-- Add rules named PBX-SIP and PBX-RTP if not existing
found_sip_rule = false
found_rtp_rule = false
m.uci:foreach(config, section,
function(s1)
if s1._name == 'PBX-SIP' then
found_sip_rule = true
elseif s1._name == 'PBX-RTP' then
found_rtp_rule = true
end
end)
-- Add rules named PBX-SIP and PBX-RTP if not existing
found_sip_rule = false
found_rtp_rule = false
m.uci:foreach(config, section,
function(s1)
if s1._name == 'PBX-SIP' then
found_sip_rule = true
elseif s1._name == 'PBX-RTP' then
found_rtp_rule = true
end
end)
if found_sip_rule ~= true then
newrule=m.uci:add(config, section)
m.uci:set(config, newrule, '_name', 'PBX-SIP')
end
if found_rtp_rule ~= true then
newrule=m.uci:add(config, section)
m.uci:set(config, newrule, '_name', 'PBX-RTP')
end
if found_sip_rule ~= true then
newrule=m.uci:add(config, section)
m.uci:set(config, newrule, '_name', 'PBX-SIP')
end
if found_rtp_rule ~= true then
newrule=m.uci:add(config, section)
m.uci:set(config, newrule, '_name', 'PBX-RTP')
end
end
-- Delete rules in the given config & section named PBX-SIP and PBX-RTP
function delete_sip_rtp_rules(config, section)
-- Remove rules named PBX-SIP and PBX-RTP
commit = false
m.uci:foreach(config, section,
function(s1)
if s1._name == 'PBX-SIP' or s1._name == 'PBX-RTP' then
m.uci:delete(config, s1['.name'])
commit = true
end
end)
-- Remove rules named PBX-SIP and PBX-RTP
commit = false
m.uci:foreach(config, section,
function(s1)
if s1._name == 'PBX-SIP' or s1._name == 'PBX-RTP' then
m.uci:delete(config, s1['.name'])
commit = true
end
end)
-- If something changed, then we commit the config.
if commit == true then m.uci:commit(config) end
-- If something changed, then we commit the config.
if commit == true then m.uci:commit(config) end
end
-- Deletes QoS rules associated with this PBX.
function delete_qos_rules()
delete_sip_rtp_rules ("qos", "classify")
delete_sip_rtp_rules ("qos", "classify")
end
function insert_qos_rules()
-- Insert empty PBX-SIP and PBX-RTP rules if not present.
insert_empty_sip_rtp_rules ("qos", "classify")
-- Insert empty PBX-SIP and PBX-RTP rules if not present.
insert_empty_sip_rtp_rules ("qos", "classify")
-- Get the network information
bindport, rtprange, ipaddr, externhost = get_network_info()
-- Get the network information
bindport, rtprange, ipaddr, externhost = get_network_info()
-- Iterate through the QoS rules, and if there is no other rule with the same port
-- range at the express service level, insert this rule.
commit = false
m.uci:foreach("qos", "classify",
function(s1)
if s1._name == 'PBX-SIP' then
if s1.ports ~= bindport or s1.target ~= "Express" or s1.proto ~= "udp" then
m.uci:set("qos", s1['.name'], "ports", bindport)
m.uci:set("qos", s1['.name'], "proto", "udp")
m.uci:set("qos", s1['.name'], "target", "Express")
commit = true
end
elseif s1._name == 'PBX-RTP' then
if s1.ports ~= rtprange or s1.target ~= "Express" or s1.proto ~= "udp" then
m.uci:set("qos", s1['.name'], "ports", rtprange)
m.uci:set("qos", s1['.name'], "proto", "udp")
m.uci:set("qos", s1['.name'], "target", "Express")
commit = true
end
end
end)
-- Iterate through the QoS rules, and if there is no other rule with the same port
-- range at the priority service level, insert this rule.
commit = false
m.uci:foreach("qos", "classify",
function(s1)
if s1._name == 'PBX-SIP' then
if s1.ports ~= bindport or s1.target ~= "Priority" or s1.proto ~= "udp" then
m.uci:set("qos", s1['.name'], "ports", bindport)
m.uci:set("qos", s1['.name'], "proto", "udp")
m.uci:set("qos", s1['.name'], "target", "Priority")
commit = true
end
elseif s1._name == 'PBX-RTP' then
if s1.ports ~= rtprange or s1.target ~= "Priority" or s1.proto ~= "udp" then
m.uci:set("qos", s1['.name'], "ports", rtprange)
m.uci:set("qos", s1['.name'], "proto", "udp")
m.uci:set("qos", s1['.name'], "target", "Priority")
commit = true
end
end
end)
-- If something changed, then we commit the qos config.
if commit == true then m.uci:commit("qos") end
-- If something changed, then we commit the qos config.
if commit == true then m.uci:commit("qos") end
end
-- This function is a (so far) unsuccessful attempt to manipulate the firewall rules from here
-- Need to do more testing and eventually move to this mode.
function maintain_firewall_rules()
-- Get the network information
bindport, rtprange, ipaddr, externhost = get_network_info()
-- Get the network information
bindport, rtprange, ipaddr, externhost = get_network_info()
commit = false
-- Only if externhost is set, do we control firewall rules.
if externhost ~= nil and bindport ~= nil and rtprange ~= nil then
-- Insert empty PBX-SIP and PBX-RTP rules if not present.
insert_empty_sip_rtp_rules ("firewall", "rule")
commit = false
-- Only if externhost is set, do we control firewall rules.
if externhost ~= nil and bindport ~= nil and rtprange ~= nil then
-- Insert empty PBX-SIP and PBX-RTP rules if not present.
insert_empty_sip_rtp_rules ("firewall", "rule")
-- Iterate through the firewall rules, and if the dest_port and dest_ip setting of the\
-- SIP and RTP rule do not match what we want configured, set all the entries in the rule\
-- appropriately.
m.uci:foreach("firewall", "rule",
function(s1)
if s1._name == 'PBX-SIP' then
if s1.dest_port ~= bindport then
m.uci:set("firewall", s1['.name'], "dest_port", bindport)
m.uci:set("firewall", s1['.name'], "src", "wan")
m.uci:set("firewall", s1['.name'], "proto", "udp")
m.uci:set("firewall", s1['.name'], "target", "ACCEPT")
commit = true
end
elseif s1._name == 'PBX-RTP' then
if s1.dest_port ~= rtprange then
m.uci:set("firewall", s1['.name'], "dest_port", rtprange)
m.uci:set("firewall", s1['.name'], "src", "wan")
m.uci:set("firewall", s1['.name'], "proto", "udp")
m.uci:set("firewall", s1['.name'], "target", "ACCEPT")
commit = true
end
end
end)
else
-- We delete the firewall rules if one or more of the necessary parameters are not set.
sip_rule_name=nil
rtp_rule_name=nil
-- Iterate through the firewall rules, and if the dest_port and dest_ip setting of the\
-- SIP and RTP rule do not match what we want configured, set all the entries in the rule\
-- appropriately.
m.uci:foreach("firewall", "rule",
function(s1)
if s1._name == 'PBX-SIP' then
if s1.dest_port ~= bindport then
m.uci:set("firewall", s1['.name'], "dest_port", bindport)
m.uci:set("firewall", s1['.name'], "src", "wan")
m.uci:set("firewall", s1['.name'], "proto", "udp")
m.uci:set("firewall", s1['.name'], "target", "ACCEPT")
commit = true
end
elseif s1._name == 'PBX-RTP' then
if s1.dest_port ~= rtprange then
m.uci:set("firewall", s1['.name'], "dest_port", rtprange)
m.uci:set("firewall", s1['.name'], "src", "wan")
m.uci:set("firewall", s1['.name'], "proto", "udp")
m.uci:set("firewall", s1['.name'], "target", "ACCEPT")
commit = true
end
end
end)
else
-- We delete the firewall rules if one or more of the necessary parameters are not set.
sip_rule_name=nil
rtp_rule_name=nil
-- First discover the configuration names of the rules.
m.uci:foreach("firewall", "rule",
function(s1)
if s1._name == 'PBX-SIP' then
sip_rule_name = s1['.name']
elseif s1._name == 'PBX-RTP' then
rtp_rule_name = s1['.name']
end
end)
-- First discover the configuration names of the rules.
m.uci:foreach("firewall", "rule",
function(s1)
if s1._name == 'PBX-SIP' then
sip_rule_name = s1['.name']
elseif s1._name == 'PBX-RTP' then
rtp_rule_name = s1['.name']
end
end)
-- Then, using the names, actually delete the rules.
if sip_rule_name ~= nil then
m.uci:delete("firewall", sip_rule_name)
commit = true
end
if rtp_rule_name ~= nil then
m.uci:delete("firewall", rtp_rule_name)
commit = true
end
end
-- Then, using the names, actually delete the rules.
if sip_rule_name ~= nil then
m.uci:delete("firewall", sip_rule_name)
commit = true
end
if rtp_rule_name ~= nil then
m.uci:delete("firewall", rtp_rule_name)
commit = true
end
end
-- If something changed, then we commit the firewall config.
if commit == true then m.uci:commit("firewall") end
-- If something changed, then we commit the firewall config.
if commit == true then m.uci:commit("firewall") end
end
m = Map (modulename, translate("Advanced Settings"),
translate("This section contains settings which do not need to be changed under\
normal circumstances. In addition, here you can configure your system\
for use with remote SIP devices, and resolve call quality issues by enabling\
the insertion of QoS rules."))
translate("This section contains settings that do not need to be changed under \
normal circumstances. In addition, here you can configure your system \
for use with remote SIP devices, and resolve call quality issues by enabling \
the insertion of QoS rules."))
-- Recreate the voip server config, and restart necessary services after changes are commited
-- to the advanced configuration. The firewall must restart because of "Remote Usage".
function m.on_after_commit(self)
-- Make sure firewall rules are in place
maintain_firewall_rules()
-- Make sure firewall rules are in place
maintain_firewall_rules()
-- If insertion of QoS rules is enabled
if m.uci:get(modulename, "advanced", "qos_enabled") == "yes" then
insert_qos_rules()
else
delete_qos_rules()
end
-- If insertion of QoS rules is enabled
if m.uci:get(modulename, "advanced", "qos_enabled") == "yes" then
insert_qos_rules()
else
delete_qos_rules()
end
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/firewall restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/firewall restart 1\>/dev/null 2\>/dev/null")
end
-----------------------------------------------------------------------------
@ -229,46 +229,53 @@ s.anonymous = true
s:tab("general", translate("General Settings"))
s:tab("remote_usage", translate("Remote Usage"),
translatef("You can use your SIP devices/softphones with this system from a remote location\
as well, as long as your Internet Service Provider gives you a public IP.\
You will be able to call other local users for free (e.g. other Analog Telephone Adapters (ATAs))\
and use your VoIP providers to make calls as if you were at local to the PBX.\
After configuring this tab, go back to where users are configured and see the new\
Server and Port setting you need to configure the SIP devices with. Please note that by default\
%s uses UDP port range %d to %d for RTP traffic (which carries voice), in case you need to configure\
NAT or QoS on another device.", appname, defaultrtpstart, defaultrtpend))
translatef("You can use your SIP devices/softphones with this system from a remote location \
as well, as long as your Internet Service Provider gives you a public IP. \
You will be able to call other local users for free (e.g. other Analog Telephone Adapters (ATAs)) \
and use your VoIP providers to make calls as if you were local to the PBX. \
After configuring this tab, go back to where users are configured and see the new \
Server and Port setting you need to configure the remote SIP devices with. Please note that if this \
PBX is not running on your router/gateway, you will need to configure port forwarding (NAT) on your \
router/gateway. Please forward the ports below (SIP port and RTP range) to the IP address of the \
device running this PBX."))
s:tab("qos", translate("QoS Settings"),
translate("If you experience jittery or high latency audio during heavy downloads, you may want to enable QoS.\
QoS prioritizes traffic to and from your network for specified ports and IP addresses, resulting in\
better latency and throughput for sound in our case. If enabled below, a QoS rule for this service will\
be configured by the PBX automatically, but you must visit the QoS configuration page (Network->QoS) to\
configure other critical QoS settings like Download and Upload speed."))
translate("If you experience jittery or high latency audio during heavy downloads, you may want \
to enable QoS. QoS prioritizes traffic to and from your network for specified ports and IP \
addresses, resulting in better latency and throughput for sound in our case. If enabled below, \
a QoS rule for this service will be configured by the PBX automatically, but you must visit the \
QoS configuration page (Network->QoS) to configure other critical QoS settings like Download \
and Upload speed."))
ringtime = s:taboption("general", Value, "ringtime", translate("Number of Seconds to Ring"),
translate("Set the number of seconds to ring users upon incoming calls before hanging up \
or going to voicemail, if the voicemail is installed and enabled."))
ringtime.default = 30
ua = s:taboption("general", Value, "useragent", translate("User Agent String"),
translate("This is the name that the VoIP server will use to identify itself when\
registering to VoIP (SIP) providers. Some providers require this to a specific\
string matching a hardware SIP device."))
translate("This is the name that the VoIP server will use to identify itself when \
registering to VoIP (SIP) providers. Some providers require this to a specific \
string matching a hardware SIP device."))
ua.default = appname
h = s:taboption("remote_usage", Value, "externhost", translate("Domain Name/Dynamic Domain Name"),
translate("You should either have registered a domain name and have a static IP\
address, or have configured Dynamic DNS on this router. Enter a\
domain name which resolves to your external IP address."))
h = s:taboption("remote_usage", Value, "externhost", translate("Domain/IP Address/Dynamic Domain"),
translate("You can enter your domain name, external IP address, or dynamic domain name here \
Please keep in mind that if your IP address is dynamic and it changes your configuration \
will become invalid. Hence, it's recommended to set up Dynamic DNS in this case."))
h.datatype = "hostname"
p = s:taboption("remote_usage", Value, "bindport", translate("External SIP Port"),
translate("Pick a random port number between 6500 and 9500 for the service to listen on.\
Do not pick the standard 5060, because it is often subject to brute-force attacks.\
When finished, (1) click \"Save and Apply\", and (2) click the \"Restart VoIP Service\"\
button above. Finally, (3) look in the \"SIP Device/Softphone Accounts\" section for\
updated Server and Port settings for your SIP Devices/Softphones."))
translate("Pick a random port number between 6500 and 9500 for the service to listen on. \
Do not pick the standard 5060, because it is often subject to brute-force attacks. \
When finished, (1) click \"Save and Apply\", and (2) click the \"Restart VoIP Service\" \
button above. Finally, (3) look in the \"SIP Device/Softphone Accounts\" section for \
updated Server and Port settings for your SIP Devices/Softphones."))
p.datatype = "port"
p = s:taboption("remote_usage", Value, "rtpstart", translate("RTP Port Range Start"),
translate("RTP traffic carries actual voice packets. This is the start of the port range\
which will be used for setting up RTP communication. It's usually OK to leave this\
at the default value."))
translate("RTP traffic carries actual voice packets. This is the start of the port range \
that will be used for setting up RTP communication. It's usually OK to leave this \
at the default value."))
p.datatype = "port"
p.default = defaultrtpstart

View file

@ -25,277 +25,271 @@ else
server = ""
end
modulename = "pbx-calls"
voipmodulename = "pbx-voip"
googlemodulename = "pbx-google"
usersmodulename = "pbx-users"
modulename = "pbx-calls"
voipmodulename = "pbx-voip"
googlemodulename = "pbx-google"
usersmodulename = "pbx-users"
allvalidaccounts = {}
nallvalidaccounts = 0
validoutaccounts = {}
nvalidoutaccounts = 0
validinaccounts = {}
nvalidinaccounts = 0
allvalidusers = {}
nallvalidusers = 0
validoutusers = {}
nvalidoutusers = 0
-- This function builds and returns a table with all the entries in a given "module" and "section".
function get_existing_entries(module, section)
i = 1
existing_entries = {}
m.uci:foreach(module, section,
function(s1)
existing_entries[i] = s1
i = i + 1
end)
return existing_entries
end
-- This function is used to build and return a table where the name field for
-- every element in a table entries are the indexes to the table (used to check
-- validity of user input.
function get_valid_names(entries)
validnames={}
for index,value in ipairs(entries) do
validnames[entries[index].name] = true
end
return validnames
end
-- This function is used to build and return a table where the defaultuser field for
-- every element in a table entries are the indexes to the table (used to check
-- validity of user input.
function get_valid_defaultusers(entries)
validnames={}
for index,value in ipairs(entries) do
validnames[entries[index].defaultuser] = true
end
return validnames
end
-- Checks whether the entered extension is valid syntactically.
function is_valid_extension(exten)
return (exten:match("[#*+0-9NXZ]+$") ~= nil)
end
m = Map (modulename, translate("Call Routing"),
translate("This is where you indicate which Google/SIP accounts are used to call what \
country/area codes, which users can use which SIP/Google accounts, how incoming\
calls are routed, what numbers can get into this PBX with a password, and what\
numbers are blacklisted."))
translate("This is where you indicate which Google/SIP accounts are used to call what \
country/area codes, which users can use what SIP/Google accounts, how incoming \
calls are routed, what numbers can get into this PBX with a password, and what \
numbers are blacklisted."))
-- Recreate the config, and restart services after changes are commited to the configuration.
function m.on_after_commit(self)
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null")
end
-- Add Google accounts to all valid accounts, and accounts valid for incoming and outgoing calls.
m.uci:foreach(googlemodulename, "gtalk_jabber",
function(s1)
-- Add this provider to list of valid accounts.
if s1.username ~= nil and s1.name ~= nil then
allvalidaccounts[s1.name] = s1.username
nallvalidaccounts = nallvalidaccounts + 1
if s1.make_outgoing_calls == "yes" then
-- Add provider to the associative array of valid outgoing accounts.
validoutaccounts[s1.name] = s1.username
nvalidoutaccounts = nvalidoutaccounts + 1
end
if s1.register == "yes" then
-- Add provider to the associative array of valid outgoing accounts.
validinaccounts[s1.name] = s1.username
nvalidinaccounts = nvalidinaccounts + 1
end
end
end)
-- Add SIP accounts to all valid accounts, and accounts valid for incoming and outgoing calls.
m.uci:foreach(voipmodulename, "voip_provider",
function(s1)
-- Add this provider to list of valid accounts.
if s1.defaultuser ~= nil and s1.host ~= nil and s1.name ~= nil then
allvalidaccounts[s1.name] = s1.defaultuser .. "@" .. s1.host
nallvalidaccounts = nallvalidaccounts + 1
if s1.make_outgoing_calls == "yes" then
-- Add provider to the associative array of valid outgoing accounts.
validoutaccounts[s1.name] = s1.defaultuser .. "@" .. s1.host
nvalidoutaccounts = nvalidoutaccounts + 1
end
if s1.register == "yes" then
-- Add provider to the associative array of valid outgoing accounts.
validinaccounts[s1.name] = s1.defaultuser .. "@" .. s1.host
nvalidinaccounts = nvalidinaccounts + 1
end
end
end)
-- Add Local User accounts to all valid users, and users allowed to make outgoing calls.
m.uci:foreach(usersmodulename, "local_user",
function(s1)
-- Add user to list of all valid users.
if s1.defaultuser ~= nil then
allvalidusers[s1.defaultuser] = true
nallvalidusers = nallvalidusers + 1
if s1.can_call == "yes" then
validoutusers[s1.defaultuser] = true
nvalidoutusers = nvalidoutusers + 1
end
end
end)
----------------------------------------------------------------------------------------------------
-- If there are no accounts configured, or no accounts enabled for outgoing calls, display a warning.
-- Otherwise, display the usual help text within the section.
if nallvalidaccounts == 0 then
text = translate("NOTE: There are no Google or SIP provider accounts configured.")
elseif nvalidoutaccounts == 0 then
text = translate("NOTE: There are no Google or SIP provider accounts enabled for outgoing calls.")
else
text = translate("If you have more than one account that can make outgoing calls, you \
should enter a list of phone numbers and/or prefixes in the following fields for each \
provider listed. Invalid prefixes are removed silently, and only 0-9, X, Z, N, #, *, \
and + are valid characters. The letter X matches 0-9, Z matches 1-9, and N matches 2-9. \
For example to make calls to Germany through a provider, you can enter 49. To make calls \
to North America, you can enter 1NXXNXXXXXX. If one of your providers can make \"local\" \
calls to an area code like New York's 646, you can enter 646NXXXXXX for that \
provider. You should leave one account with an empty list to make calls with \
it by default, if no other provider's prefixes match. The system will automatically \
replace an empty list with a message that the provider dials all numbers not matched by another \
provider's prefixes. Be as specific as possible (i.e. 1NXXNXXXXXX is better than 1). Please note \
all international dial codes are discarded (e.g. 00, 011, 010, 0011). Entries can be made in a \
space-separated list, and/or one per line by hitting enter after every one.")
end
s = m:section(NamedSection, "outgoing_calls", "call_routing", translate("Outgoing Calls"), text)
s.anonymous = true
for k,v in pairs(validoutaccounts) do
patterns = s:option(DynamicList, k, v)
-- If the saved field is empty, we return a string
-- telling the user that this account would dial any exten.
function patterns.cfgvalue(self, section)
value = self.map:get(section, self.option)
if value == nil then
return {translate("Dials numbers unmatched elsewhere")}
else
return value
end
end
-- Write only valid extensions into the config file.
function patterns.write(self, section, value)
newvalue = {}
nindex = 1
for index, field in ipairs(value) do
val = luci.util.trim(value[index])
if is_valid_extension(val) == true then
newvalue[nindex] = val
nindex = nindex + 1
end
end
DynamicList.write(self, section, newvalue)
end
end
----------------------------------------------------------------------------------------------------
s = m:section(NamedSection, "outgoing_calls", "call_routing", translate("Outgoing Calls"),
translate("If you have more than one account which can make outgoing calls, you\
should enter a list of phone numbers and prefixes in the following fields for each\
provider listed. Invalid prefixes are removed silently, and only 0-9, X, Z, N, #, *,\
and + are valid characters. The letter X matches 0-9, Z matches 1-9, and N matches 2-9.\
For example to make calls to Germany through a provider, you can enter 49. To make calls\
to North America, you can enter 1NXXNXXXXXX. If one of your providers can make \"local\"\
calls to an area code like New York's 646, you can enter 646NXXXXXX for that\
provider. You should leave one account with an empty list to make calls with\
it by default, if no other provider's prefixes match. The system will automatically\
replace an empty list with a message that the provider dials all numbers. Be as specific as\
possible (i.e. 1NXXNXXXXXX is better than 1). Please note all international dial codes\
are discarded (e.g. 00, 011, 010, 0011). Entries can be made in a\
space-separated list, and/or one per line by hitting enter after every one."))
-- If there are no accounts configured, or no accounts enabled for incoming calls, display a warning.
-- Otherwise, display the usual help text within the section.
if nallvalidaccounts == 0 then
text = translate("NOTE: There are no Google or SIP provider accounts configured.")
elseif nvalidinaccounts == 0 then
text = translate("NOTE: There are no Google or SIP provider accounts enabled for incoming calls.")
else
text = translate("For each provider enabled for incoming calls, here you can restrict which users to\
ring on incoming calls. If the list is empty, the system will indicate that all users \
enabled for incoming calls will ring. Invalid usernames will be rejected \
silently. Also, entering a username here overrides the user's setting to not receive \
incoming calls. This way, you can make certain users ring only for specific providers. \
Entries can be made in a space-separated list, and/or one per line by hitting enter after \
every one.")
end
s = m:section(NamedSection, "incoming_calls", "call_routing", translate("Incoming Calls"), text)
s.anonymous = true
m.uci:foreach(googlemodulename, "gtalk_jabber",
function(s1)
if s1.username ~= nil and s1.name ~= nil and
s1.make_outgoing_calls == "yes" then
patt = s:option(DynamicList, s1.name, s1.username)
for k,v in pairs(validinaccounts) do
users = s:option(DynamicList, k, v)
-- If the saved field is empty, we return a string
-- telling the user that this account would dial any exten.
function patt.cfgvalue(self, section)
value = self.map:get(section, self.option)
-- If the saved field is empty, we return a string
-- telling the user that this account would dial any exten.
function users.cfgvalue(self, section)
value = self.map:get(section, self.option)
if value == nil then
return {"Dials any number"}
else
return value
end
end
if value == nil then
return {translate("Rings users enabled for incoming calls")}
else
return value
end
end
-- Write only valid extensions into the config file.
function patt.write(self, section, value)
newvalue = {}
nindex = 1
for index, field in ipairs(value) do
if is_valid_extension(value[index]) == true then
newvalue[nindex] = value[index]
nindex = nindex + 1
end
end
DynamicList.write(self, section, newvalue)
end
end
end)
-- Write only valid user names.
function users.write(self, section, value)
newvalue = {}
nindex = 1
for index, field in ipairs(value) do
trimuser = luci.util.trim(value[index])
if allvalidusers[trimuser] == true then
newvalue[nindex] = trimuser
nindex = nindex + 1
end
end
DynamicList.write(self, section, newvalue)
end
end
m.uci:foreach(voipmodulename, "voip_provider",
function(s1)
if s1.defaultuser ~= nil and s1.host ~= nil and
s1.name ~= nil and s1.make_outgoing_calls == "yes" then
patt = s:option(DynamicList, s1.name, s1.defaultuser .. "@" .. s1.host)
-- If the saved field is empty, we return a string
-- telling the user that this account would dial any exten.
function patt.cfgvalue(self, section)
value = self.map:get(section, self.option)
if value == nil then
return {"Dials any number"}
else
return value
end
end
-- Write only valid extensions into the config file.
function patt.write(self, section, value)
newvalue = {}
nindex = 1
for index, field in ipairs(value) do
if is_valid_extension(value[index]) == true then
newvalue[nindex] = value[index]
nindex = nindex + 1
end
end
DynamicList.write(self, section, newvalue)
end
end
end)
----------------------------------------------------------------------------------------------------
s = m:section(NamedSection, "incoming_calls", "call_routing", translate("Incoming Calls"),
translate("For each provider that receives calls, here you can restrict which users to ring\
on incoming calls. If the list is empty, the system will indicate that all users\
which are enabled for incoming calls will ring. Invalid usernames will be rejected\
silently. Also, entering a username here overrides the user's setting to not receive\
incoming calls, so this way, you can make users ring only for select providers.\
Entries can be made in a space-separated list, and/or one per\
line by hitting enter after every one."))
s.anonymous = true
m.uci:foreach(googlemodulename, "gtalk_jabber",
function(s1)
if s1.username ~= nil and s1.register == "yes" then
field_name=string.gsub(s1.username, "%W", "_")
gtalkaccts = s:option(DynamicList, field_name, s1.username)
-- If the saved field is empty, we return a string
-- telling the user that this account would dial any exten.
function gtalkaccts.cfgvalue(self, section)
value = self.map:get(section, self.option)
if value == nil then
return {"Rings all users"}
else
return value
end
end
-- Write only valid user names.
function gtalkaccts.write(self, section, value)
users=get_valid_defaultusers(get_existing_entries(usersmodulename, "local_user"))
newvalue = {}
nindex = 1
for index, field in ipairs(value) do
if users[value[index]] == true then
newvalue[nindex] = value[index]
nindex = nindex + 1
end
end
DynamicList.write(self, section, newvalue)
end
end
end)
-- If there are no user accounts configured, no user accounts enabled for outgoing calls,
-- display a warning. Otherwise, display the usual help text within the section.
if nallvalidusers == 0 then
text = translate("NOTE: There are no local user accounts configured.")
elseif nvalidoutusers == 0 then
text = translate("NOTE: There are no local user accounts enabled for outgoing calls.")
else
text = translate("For each user enabled for outgoing calls you can restrict what providers the user \
can use for outgoing calls. By default all users can use all providers. To show up in the list \
below the user should be allowed to make outgoing calls in the \"User Accounts\" page. Enter VoIP \
providers in the format username@some.host.name, as listed in \"Outgoing Calls\" above. It's \
easiest to copy and paste the providers from above. Invalid entries, including providers not \
enabled for outgoing calls, will be rejected silently. Entries can be made in a space-separated \
list, and/or one per line by hitting enter after every one.")
end
m.uci:foreach(voipmodulename, "voip_provider",
function(s1)
if s1.defaultuser ~= nil and s1.host ~= nil and s1.register == "yes" then
field_name=string.gsub(s1.defaultuser .. "_" .. s1.host, "%W", "_")
voipaccts = s:option(DynamicList, field_name, s1.defaultuser .. "@" .. s1.host)
-- If the saved field is empty, we return a string
-- telling the user that this account would dial any exten.
function voipaccts.cfgvalue(self, section)
value = self.map:get(section, self.option)
if value == nil then
return {"Rings all users"}
else
return value
end
end
-- Write only valid user names.
function voipaccts.write(self, section, value)
users=get_valid_defaultusers(get_existing_entries(usersmodulename, "local_user"))
newvalue = {}
nindex = 1
for index, field in ipairs(value) do
if users[value[index]] == true then
newvalue[nindex] = value[index]
nindex = nindex + 1
end
end
DynamicList.write(self, section, newvalue)
end
end
end)
----------------------------------------------------------------------------------------------------
s = m:section(NamedSection, "providers_user_can_use", "call_routing",
translate("Providers Used for Outgoing Calls"),
translate("If you would like, you could restrict which providers users are allowed to use for outgoing\
calls. By default all users can use all providers. To show up in the list below the user should\
be allowed to make outgoing calls in the \"User Accounts\" page. Enter VoIP providers in the format\
username@some.host.name, as listed in \"Outgoing Calls\" above. It's easiest to copy and paste\
the providers from above. Invalid entries will be rejected silently. Also, any entries automatically\
change to this PBX's internal naming scheme, with \"_\" replacing all non-alphanumeric characters.\
Entries can be made in a space-separated list, and/or one per line by hitting enter after every\
one."))
translate("Providers Used for Outgoing Calls"), text)
s.anonymous = true
m.uci:foreach(usersmodulename, "local_user",
function(s1)
if s1.defaultuser ~= nil and s1.can_call == "yes" then
providers = s:option(DynamicList, s1.defaultuser, s1.defaultuser)
for k,v in pairs(validoutusers) do
providers = s:option(DynamicList, k, k)
-- If the saved field is empty, we return a string
-- telling the user that this account would dial any exten.
function providers.cfgvalue(self, section)
value = self.map:get(section, self.option)
-- If the saved field is empty, we return a string
-- telling the user that this account would dial any exten.
function providers.cfgvalue(self, section)
value = self.map:get(section, self.option)
if value == nil then
return {"Uses all provider accounts"}
else
return value
end
end
if value == nil then
return {translate("Uses providers enabled for outgoing calls")}
else
newvalue = {}
-- Convert internal names to user@host values.
for i,v in ipairs(value) do
newvalue[i] = validoutaccounts[v]
end
return newvalue
end
end
-- Cook the new values prior to entering them into the config file.
-- Also, enter them only if they are valid.
function providers.write(self, section, value)
validvoip=get_valid_names(get_existing_entries(voipmodulename, "voip_provider"))
validgoog=get_valid_names(get_existing_entries(googlemodulename, "gtalk_jabber"))
cookedvalue = {}
cindex = 1
for index, field in ipairs(value) do
cooked = string.gsub(value[index], "%W", "_")
if validvoip[cooked] == true or validgoog[cooked] == true then
cookedvalue[cindex] = string.gsub(value[index], "%W", "_")
cindex = cindex + 1
end
end
DynamicList.write(self, section, cookedvalue)
end
end
end)
-- Cook the new values prior to entering them into the config file.
-- Also, enter them only if they are valid.
function providers.write(self, section, value)
cookedvalue = {}
cindex = 1
for index, field in ipairs(value) do
cooked = string.gsub(luci.util.trim(value[index]), "%W", "_")
if validoutaccounts[cooked] ~= nil then
cookedvalue[cindex] = cooked
cindex = cindex + 1
end
end
DynamicList.write(self, section, cookedvalue)
end
end
----------------------------------------------------------------------------------------------------
s = m:section(TypedSection, "callthrough_numbers", translate("Call-through Numbers"),
translate("Designate numbers which will be allowed to call through this system and which user's\
privileges it will have."))
translate("Designate numbers that are allowed to call through this system and which user's \
privileges it will have."))
s.anonymous = true
s.addremove = true
@ -308,19 +302,20 @@ p:value("no", translate("No"))
p.default = "yes"
user = s:option(Value, "defaultuser", translate("User Name"),
translate("The number(s) specified above will be able to dial outwith this user's providers.\
Invalid usernames are dropped silently, please verify that the entry was accepted."))
translate("The number(s) specified above will be able to dial out with this user's providers. \
Invalid usernames, including users not enabled for outgoing calls, are dropped silently. \
Please verify that the entry was accepted."))
function user.write(self, section, value)
users=get_valid_defaultusers(get_existing_entries(usersmodulename, "local_user"))
if users[value] == true then
Value.write(self, section, value)
trimuser = luci.util.trim(value)
if allvalidusers[trimuser] == true then
Value.write(self, section, trimuser)
end
end
pwd = s:option(Value, "pin", translate("PIN"),
translate("Your PIN disappears when saved for your protection. It will be changed\
only when you enter a value different from the saved one. Leaving the PIN\
empty is possible, but please beware of the security implications."))
translate("Your PIN disappears when saved for your protection. It will be changed \
only when you enter a value different from the saved one. Leaving the PIN \
empty is possible, but please beware of the security implications."))
pwd.password = true
pwd.rmempty = false
@ -340,19 +335,18 @@ end
----------------------------------------------------------------------------------------------------
s = m:section(NamedSection, "blacklisting", "call_routing", translate("Blacklisted Numbers"),
translate("Enter phone numbers that you want to decline calls from automatically.\
You should probably omit the country code and any leading\
zeroes, but please experiment to make sure you are blocking numbers from your\
desired area successfully."))
translate("Enter phone numbers that you want to decline calls from automatically. \
You should probably omit the country code and any leading zeroes, but please \
experiment to make sure you are blocking numbers from your desired area successfully."))
s.anonymous = true
b = s:option(DynamicList, "blacklist1", translate("Dynamic List of Blacklisted Numbers"),
translate("Specify numbers individually here. Press enter to add more numbers."))
translate("Specify numbers individually here. Press enter to add more numbers."))
b.cast = "string"
b.datatype = "uinteger"
b = s:option(Value, "blacklist2", translate("Space-Separated List of Blacklisted Numbers"),
translate("Copy-paste large lists of numbers here."))
translate("Copy-paste large lists of numbers here."))
b.template = "cbi/tvalue"
b.rows = 3

View file

@ -31,24 +31,26 @@ defaultstatus = "dnd"
defaultstatusmessage = "PBX online, may lose messages"
m = Map (modulename, translate("Google Accounts"),
translate("This is where you set up your Google (Talk and Voice) Accounts, in order to start\
using them for dialing and receiving calls (voice chat and real phone calls). Click \"Add\"\
to add as many accounts as you wish."))
translate("This is where you set up your Google (Talk and Voice) Accounts, in order to start \
using them for dialing and receiving calls (voice chat and real phone calls). Please \
make at least one voice call using the Google Talk plugin installable through the \
GMail interface, and then log out from your account everywhere. Click \"Add\" \
to add as many accounts as you wish."))
-- Recreate the config, and restart services after changes are commited to the configuration.
function m.on_after_commit(self)
-- Create a field "name" for each account which identifies the account in the backend.
-- Create a field "name" for each account that identifies the account in the backend.
commit = false
m.uci:foreach(modulename, "gtalk_jabber",
function(s1)
if s1.username ~= nil then
name=string.gsub(s1.username, "%W", "_")
if s1.name ~= name then
m.uci:set(modulename, s1['.name'], "name", name)
commit = true
end
end
end)
function(s1)
if s1.username ~= nil then
name=string.gsub(s1.username, "%W", "_")
if s1.name ~= name then
m.uci:set(modulename, s1['.name'], "name", name)
commit = true
end
end
end)
if commit == true then m.uci:commit(modulename) end
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
@ -63,9 +65,9 @@ s.addremove = true
s:option(Value, "username", translate("Email"))
pwd = s:option(Value, "secret", translate("Password"),
translate("When your password is saved, it disappears from this field and is not displayed\
for your protection. The previously saved password will be changed only when you\
enter a value different from the saved one."))
translate("When your password is saved, it disappears from this field and is not displayed \
for your protection. The previously saved password will be changed only when you \
enter a value different from the saved one."))
pwd.password = true
pwd.rmempty = false
@ -85,35 +87,35 @@ end
p = s:option(ListValue, "register",
translate("Enable Incoming Calls (See Status, Message below)"),
translate("When somebody starts voice chat with your GTalk account or calls the GVoice,\
number (if you have Google Voice), the call will be forwarded to any users\
that are online (registered using a SIP device or softphone) and permitted to\
receive the call. If you have Google Voice, you must go to your GVoice settings and\
forward calls to Google chat in order to actually receive calls made to your\
GVoice number. If you have trouble receiving calls from GVoice, experiment\
with the Call Screening option in your GVoice Settings. Finally, make sure no other\
client is online with this account (browser in gmail, mobile/desktop Google Talk\
App) as it may interfere."))
translate("Enable Incoming Calls (set Status below)"),
translate("When somebody starts voice chat with your GTalk account or calls the GVoice, \
number (if you have Google Voice), the call will be forwarded to any users \
that are online (registered using a SIP device or softphone) and permitted to \
receive the call. If you have Google Voice, you must go to your GVoice settings and \
forward calls to Google chat in order to actually receive calls made to your \
GVoice number. If you have trouble receiving calls from GVoice, experiment \
with the Call Screening option in your GVoice Settings. Finally, make sure no other \
client is online with this account (browser in gmail, mobile/desktop Google Talk \
App) as it may interfere."))
p:value("yes", translate("Yes"))
p:value("no", translate("No"))
p.default = "yes"
p = s:option(ListValue, "make_outgoing_calls", translate("Enable Outgoing Calls"),
translate("Use this account to make outgoing calls as configured in the \"Call Routing\" section."))
translate("Use this account to make outgoing calls as configured in the \"Call Routing\" section."))
p:value("yes", translate("Yes"))
p:value("no", translate("No"))
p.default = "yes"
st = s:option(ListValue, "status", translate("Account Status"))
st = s:option(ListValue, "status", translate("Google Talk Status"))
st:depends("register", "yes")
st:value("dnd", translate("Do Not Disturb"))
st:value("away", translate("Away"))
st:value("available", translate("Available"))
st.default = defaultstatus
stm = s:option(Value, "statusmessage", translate("Account Status Message"),
translate("Avoid using anything but alpha-numeric characters, space, comma, and period."))
stm = s:option(Value, "statusmessage", translate("Google Talk Status Message"),
translate("Avoid using anything but alpha-numeric characters, space, comma, and period."))
stm:depends("register", "yes")
stm.default = defaultstatusmessage

View file

@ -29,34 +29,19 @@ modulename = "pbx-users"
modulenamecalls = "pbx-calls"
modulenameadvanced = "pbx-advanced"
m = Map (modulename, translate("User Accounts"),
translate("Here you must configure at least one SIP account, which you\
will use to register with this service. Use this account either in an analog telephony\
adapter (ATA), or in a SIP softphone like CSipSimple, Linphone, or Sipdroid on your\
Android smartphone, or X-lite or Ekiga on your computer. By default, all SIP accounts\
will ring simultaneously if a call is made to one of your VoIP provider accounts or GV\
numbers."))
translate("Here you must configure at least one SIP account, that you \
will use to register with this service. Use this account either in an Analog Telephony \
Adapter (ATA), or in a SIP software like CSipSimple, Linphone, or Sipdroid on your \
smartphone, or Ekiga, Linphone, or X-Lite on your computer. By default, all SIP accounts \
will ring simultaneously if a call is made to one of your VoIP provider accounts or GV \
numbers."))
-- Recreate the config, and restart services after changes are commited to the configuration.
function m.on_after_commit(self)
--allusers = ""
--ringusers = ""
--
---- Create two lists of users - one of all users and one of users enabled for incoming calls.
--m.uci:foreach(modulename, "local_user",
-- function(s1)
-- allusers = allusers .. " " .. s1.defaultuser
-- if s1.ring == "yes" then
-- ringusers = ringusers .. " " .. s1.defaultuser
-- end
-- end)
--
--m.uci:set (modulenamecalls, "valid_users", "allusers", allusers)
--m.uci:set (modulenamecalls, "valid_users", "ringusers", ringusers)
--m.uci:commit (modulenamecalls)
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null")
end
externhost = m.uci:get(modulenameadvanced, "advanced", "externhost")
@ -77,8 +62,8 @@ if bindport ~= nil then
end
s:option(DummyValue, "ipaddr", translate("Server Setting for Local SIP Devices"),
translate("Enter this IP (or IP:port) in the Server/Registrar setting of SIP devices you will\
use ONLY locally and never from a remote location.")).default = ipaddr
translate("Enter this IP (or IP:port) in the Server/Registrar setting of SIP devices you will \
use ONLY locally and never from a remote location.")).default = ipaddr
if externhost ~= nil then
if bindport ~= nil then
@ -86,20 +71,20 @@ if externhost ~= nil then
externhost = externhost .. ":" .. bindport
end
s:option(DummyValue, "externhost", translate("Server Setting for Remote SIP Devices"),
translate("Enter this hostname (or hostname:port) in the Server/Registrar setting of SIP\
devices you will use from a remote location (they will work locally too).")
).default = externhost
translate("Enter this hostname (or hostname:port) in the Server/Registrar setting of SIP \
devices you will use from a remote location (they will work locally too).")
).default = externhost
end
if bindport ~= nil then
s:option(DummyValue, "bindport", translate("Port Setting for SIP Devices"),
translatef("If setting Server/Registrar to %s or %s does not work for you, try setting\
it to %s or %s and entering this port number in a separate field which specifies the\
Server/Registrar port number. Beware that some devices have a confusing\
setting which sets the port where SIP requests originate from on the SIP\
device itself (bind port). The port specified on this page is NOT this bind port\
but the this service listens on.",
ipaddr, externhost, just_ipaddr, just_externhost)).default = bindport
s:option(DummyValue, "bindport", translate("Port Setting for SIP Devices"),
translatef("If setting Server/Registrar to %s or %s does not work for you, try setting \
it to %s or %s and entering this port number in a separate field that specifies the \
Server/Registrar port number. Beware that some devices have a confusing \
setting that sets the port where SIP requests originate from on the SIP \
device itself (the bind port). The port specified on this page is NOT this bind port \
but the port this service listens on.",
ipaddr, externhost, just_ipaddr, just_externhost)).default = bindport
end
-----------------------------------------------------------------------------
@ -108,16 +93,16 @@ s.anonymous = true
s.addremove = true
s:option(Value, "fullname", translate("Full Name"),
translate("You can specify a real name to show up in the Caller ID here."))
translate("You can specify a real name to show up in the Caller ID here."))
du = s:option(Value, "defaultuser", translate("User Name"),
translate("Use (four to five digit) numeric user name if you are connecting normal telephones\
with ATAs to this system (so they can dial user names)."))
translate("Use (four to five digit) numeric user name if you are connecting normal telephones \
with ATAs to this system (so they can dial user names)."))
du.datatype = "uciname"
pwd = s:option(Value, "secret", translate("Password"),
translate("Your password disappears when saved for your protection. It will be changed\
only when you enter a value different from the saved one."))
translate("Your password disappears when saved for your protection. It will be changed \
only when you enter a value different from the saved one."))
pwd.password = true
pwd.rmempty = false

View file

@ -28,25 +28,25 @@ end
modulename = "pbx-voip"
m = Map (modulename, translate("SIP Accounts"),
translate("This is where you set up your SIP (VoIP) accounts ts like Sipgate, SipSorcery,\
the popular Betamax providers, and any other providers with SIP settings in order to start \
using them for dialing and receiving calls (SIP uri and real phone calls). Click \"Add\" to\
add as many accounts as you wish."))
translate("This is where you set up your SIP (VoIP) accounts ts like Sipgate, SipSorcery, \
the popular Betamax providers, and any other providers with SIP settings in order to start \
using them for dialing and receiving calls (SIP uri and real phone calls). Click \"Add\" to \
add as many accounts as you wish."))
-- Recreate the config, and restart services after changes are commited to the configuration.
function m.on_after_commit(self)
commit = false
-- Create a field "name" for each account which identifies the account in the backend.
-- Create a field "name" for each account that identifies the account in the backend.
m.uci:foreach(modulename, "voip_provider",
function(s1)
if s1.defaultuser ~= nil and s1.host ~= nil then
name=string.gsub(s1.defaultuser.."_"..s1.host, "%W", "_")
if s1.name ~= name then
m.uci:set(modulename, s1['.name'], "name", name)
commit = true
end
end
end)
function(s1)
if s1.defaultuser ~= nil and s1.host ~= nil then
name=string.gsub(s1.defaultuser.."_"..s1.host, "%W", "_")
if s1.name ~= name then
m.uci:set(modulename, s1['.name'], "name", name)
commit = true
end
end
end)
if commit == true then m.uci:commit(modulename) end
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
@ -60,9 +60,9 @@ s.addremove = true
s:option(Value, "defaultuser", translate("User Name"))
pwd = s:option(Value, "secret", translate("Password"),
translate("When your password is saved, it disappears from this field and is not displayed\
for your protection. The previously saved password will be changed only when you\
enter a value different from the saved one."))
translate("When your password is saved, it disappears from this field and is not displayed \
for your protection. The previously saved password will be changed only when you \
enter a value different from the saved one."))
@ -87,21 +87,21 @@ h = s:option(Value, "host", translate("SIP Server/Registrar"))
h.datatype = "host"
p = s:option(ListValue, "register", translate("Enable Incoming Calls (Register via SIP)"),
translate("This option should be set to \"Yes\" if you have a DID \(real telephone number\)\
associated with this SIP account or want to receive SIP uri calls through this\
provider."))
translate("This option should be set to \"Yes\" if you have a DID \(real telephone number\) \
associated with this SIP account or want to receive SIP uri calls through this \
provider."))
p:value("yes", translate("Yes"))
p:value("no", translate("No"))
p.default = "yes"
p = s:option(ListValue, "make_outgoing_calls", translate("Enable Outgoing Calls"),
translate("Use this account to make outgoing calls."))
translate("Use this account to make outgoing calls."))
p:value("yes", translate("Yes"))
p:value("no", translate("No"))
p.default = "yes"
from = s:option(Value, "fromdomain",
translate("SIP Realm (needed by some providers)"))
translate("SIP Realm (needed by some providers)"))
from.optional = true
from.datatype = "host"

View file

@ -17,6 +17,9 @@
along with luci-pbx. If not, see <http://www.gnu.org/licenses/>.
]]--
modulename = "pbx"
if nixio.fs.access("/etc/init.d/asterisk") then
server = "asterisk"
elseif nixio.fs.access("/etc/init.d/freeswitch") then
@ -25,70 +28,63 @@ else
server = ""
end
modulename = "pbx"
function mysplit(inputstr, sep)
if sep == nil then
sep = "%s"
end
t={} ; i=1
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
t[i] = str
i = i + 1
end
return t
-- Returns formatted output of string containing only the words at the indices
-- specified in the table "indices".
function format_indices(string, indices)
if indices == nil then
return "Error: No indices to format specified.\n"
end
-- Split input into separate lines.
lines = luci.util.split(luci.util.trim(string), "\n")
-- Split lines into separate words.
splitlines = {}
for lpos,line in ipairs(lines) do
splitlines[lpos] = luci.util.split(luci.util.trim(line), "%s+", nil, true)
end
-- For each split line, if the word at all indices specified
-- to be formatted are not null, add the formatted line to the
-- gathered output.
output = ""
for lpos,splitline in ipairs(splitlines) do
loutput = ""
for ipos,index in ipairs(indices) do
if splitline[index] ~= nil then
loutput = loutput .. string.format("%-40s", splitline[index])
else
loutput = nil
break
end
end
if loutput ~= nil then
output = output .. loutput .. "\n"
end
end
return output
end
function format_two_indices(string, ind1, ind2)
lines=mysplit(string, "\n")
words={}
for index,value in ipairs(lines) do
words[index]=mysplit(value)
end
output = ""
for index,value in ipairs(words) do
if value[ind1] ~= nil and value[ind2] ~= nil then
output = output .. string.format("%-40s \t %-20s\n", value[ind1], value[ind2])
end
end
return output
end
function format_one_index(string, ind1)
lines=mysplit(string, "\n")
words={}
for index,value in ipairs(lines) do
words[index]=mysplit(value)
end
output = ""
for index,value in ipairs(words) do
if value[ind1] ~= nil then
output = output .. string.format("%-40s\n", value[ind1])
end
end
return output
end
m = Map (modulename, translate("PBX Main Page"),
translate("This configuration page allows you to configure a phone system (PBX) service which\
permits making phone calls with, and sharing multiple Google and SIP (like Sipgate,\
SipSorcery, and Betamax) accounts among many SIP devices. Note that Google\
accounts, SIP accounts, and local user accounts are configured in the\
\"Google Accounts\", \"SIP Accounts\", and \"User Accounts\" sub-sections.\
You must configure at least one local SIP account\
on this PBX, to make and receive calls with your Google/SIP accounts.\
Configuring multiple users will allow you to make free calls between users, and share the configured\
Google and SIP accounts. If you have more than one Google and SIP accounts set up,\
you should probably configure how calls to and from them are routed in the \"Call Routing\" page.\
If you're interested in using your own PBX from anywhere in the world,\
then visit the \"Remote Usage\" section in the \"Advanced Settings\" page."))
translate("This configuration page allows you to configure a phone system (PBX) service which \
permits making phone calls through multiple Google and SIP (like Sipgate, \
SipSorcery, and Betamax) accounts and sharing them among many SIP devices. \
Note that Google accounts, SIP accounts, and local user accounts are configured in the \
\"Google Accounts\", \"SIP Accounts\", and \"User Accounts\" sub-sections. \
You must add at least one User Account to this PBX, and then configure a SIP device or \
softphone to use the account, in order to make and receive calls with your Google/SIP \
accounts. Configuring multiple users will allow you to make free calls between all users, \
and share the configured Google and SIP accounts. If you have more than one Google and SIP \
accounts set up, you should probably configure how calls to and from them are routed in \
the \"Call Routing\" page. If you're interested in using your own PBX from anywhere in the \
world, then visit the \"Remote Usage\" section in the \"Advanced Settings\" page."))
----------------------------------------------------------------------------------------------------
s = m:section(NamedSection, "connection_status", "main", translate("Service Control and Connection Status"))
-----------------------------------------------------------------------------------------
s = m:section(NamedSection, "connection_status", "main",
translate("PBX Service Status"))
s.anonymous = true
s:option (DummyValue, "status", translate("Service Status"))
@ -100,12 +96,15 @@ sts.rows = 20
function sts.cfgvalue(self, section)
if server == "asterisk" then
reg = luci.sys.exec("asterisk -rx 'sip show registry' | sed 's/peer-//'")
jab = luci.sys.exec("asterisk -rx 'jabber show connections' | grep onnected")
regs = luci.sys.exec("asterisk -rx 'sip show registry' | sed 's/peer-//'")
jabs = luci.sys.exec("asterisk -rx 'jabber show connections' | grep onnected")
usrs = luci.sys.exec("asterisk -rx 'sip show users'")
chan = luci.sys.exec("asterisk -rx 'core show channels'")
return format_two_indices(reg, 1, 5) .. format_two_indices(jab, 2, 4) .. "\n"
.. format_one_index(usrs,1) .. "\n" .. chan
return format_indices(regs, {1, 5}) ..
format_indices(jabs, {2, 4}) .. "\n" ..
format_indices(usrs, {1} ) .. "\n" .. chan
elseif server == "freeswitch" then
return "Freeswitch is not supported yet.\n"
else

View file

@ -1 +1,5 @@
config 'settings' 'advanced'
option 'useragent' 'PBX'
option 'ringtime' '30'
option 'rtpstart' '19850'
option 'rtpend' '19900'

795
applications/luci-pbx/root/etc/init.d/pbx-asterisk Normal file → Executable file

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,11 @@
[directories]
astetcdir => /etc/asterisk
astmoddir => /usr/lib/asterisk/modules
astvarlibdir => /var/lib/asterisk
astvarlibdir => /usr/lib/asterisk
astdbdir => /usr/lib/asterisk
astkeydir => /var/lib/asterisk
astdatadir => /usr/share/asterisk
astagidir => /usr/share/asterisk/agi-bin
astkeydir => /usr/lib/asterisk
astdatadir => /usr/lib/asterisk
astagidir => /usr/lib/asterisk/agi-bin
astspooldir => /var/spool/asterisk
astrundir => /var/run/asterisk
astlogdir => /var/log/asterisk

View file

@ -4,25 +4,19 @@ writeprotect = yes
clearglobalvars = no
[globals]
RINGTIME => |RINGTIME|
[default]
[context-user-hangup]
[context-user-hangup-call-context]
exten => s,1,Hangup()
exten => _X.,1,Hangup()
[context-catch-all]
exten => _[!-~].,1,Dial(SIP/${EXTEN},60,r)
[default-incoming-call-context]
exten => s,1,NoOp(${CALLERID})
exten => s,n,Set(SOURCECONTEXT=default-incoming-call-context)
exten => s,n,Set(SOURCEEXTEN=s)
exten => s,n,Goto(blacklist-call-context,s,1)
exten => s,n(doneblacklist),NoOp()
exten => s,n,Goto(disa-check-call-context,s,1)
exten => s,n(donedisacheck),Dial(|LOCALUSERS|,60,r)
#include extensions_default.conf
#include extensions_voicemail.conf
#include extensions_incoming.conf
#include extensions_incoming_gtalk.conf
#include extensions_blacklist.conf

View file

@ -0,0 +1,9 @@
[default-incoming-call-context]
exten => s,1,NoOp(${CALLERID})
exten => s,n,Set(SOURCECONTEXT=default-incoming-call-context)
exten => s,n,Set(SOURCEEXTEN=s)
exten => s,n,Goto(blacklist-call-context,s,1)
exten => s,n(doneblacklist),NoOp()
exten => s,n,Goto(disa-check-call-context,s,1)
exten => s,n(donedisacheck),Dial(|LOCALUSERS|,${RINGTIME},r)
exten => s,n,Goto(context-voicemail,s,1)

View file

@ -0,0 +1 @@
exten => |DEFAULTUSER|,1,Goto(default-incoming-call-context,s,1)

View file

@ -1,4 +1,6 @@
exten => |NUMBER|,1,Noop()
exten => |NUMBER|,n,Set(TIMEOUT(digit)=7)
exten => |NUMBER|,n,Set(TIMEOUT(response)=21)
exten => |NUMBER|,n,Authenticate(|PIN|)
exten => |NUMBER|,n,DISA(no-password,context-user-|DEFAULTUSER|)

View file

@ -8,4 +8,6 @@ same => n,Set(SOURCEEXTEN=|USERNAME|)
same => n,Goto(blacklist-call-context,s,1)
same => n(doneblacklist),NoOp()
same => n,Goto(disa-check-call-context,s,1)
same => n(donedisacheck),Dial(|LOCALUSERS|,60,D(:w11111111))
same => n(donedisacheck),Dial(|LOCALUSERS|,${RINGTIME},D(:w11111111))
same => n,Goto(context-voicemail,s,1)

View file

@ -6,4 +6,5 @@ exten => s,n,Set(SOURCEEXTEN=s)
exten => s,n,Goto(blacklist-call-context,s,1)
exten => s,n(doneblacklist),NoOp()
exten => s,n,Goto(disa-check-call-context,s,1)
exten => s,n(donedisacheck),Dial(|LOCALUSERS|,60,r)
exten => s,n(donedisacheck),Dial(|LOCALUSERS|,${RINGTIME},r)
exten => s,n,Goto(context-voicemail,s,1)

View file

@ -1 +1 @@
exten => |DEFAULTUSER|,1,Dial(SIP/|DEFAULTUSER|,60,r)
exten => |DEFAULTUSER|,1,Dial(SIP/|DEFAULTUSER|,${RINGTIME},r)

View file

@ -1 +1,2 @@
include => context-voicemail-record-greeting
include => context-catch-all

View file

@ -0,0 +1,4 @@
[context-voicemail-record-greeting]
[context-voicemail]
exten => s,1,Hangup()

View file

@ -0,0 +1,15 @@
[context-voicemail-record-greeting]
exten => *789,1,Wait(2)
exten => *789,n,Playback(/etc/pbx-voicemail/greeting)
exten => *789,n,Wait(5)
exten => *789,n,Record(/etc/pbx-voicemail/greeting:WAV,20,90,k)
exten => *789,n,Wait(2)
exten => *789,n,Playback(/etc/pbx-voicemail/greeting)
[context-voicemail]
exten => s,1,Wait(2)
exten => s,2,Playback(/etc/pbx-voicemail/greeting)
exten => s,3,Wait(2)
exten => s,n,Record(/tmp/voicemail%d:WAV,20,180,k)
exten => h,1,System(/etc/pbx-voicemail/pbx-send-voicemail '${RECORDED_FILE}.WAV' '${CALLERID(all)}' &)

View file

@ -1,2 +0,0 @@
iptables -I INPUT 3 -p udp -s 0/0 -d 0/0 --dport |SIPPORT| -j ACCEPT
iptables -I INPUT 3 -p udp -s 0/0 -d 0/0 --dport |RTPRANGE| -j ACCEPT

View file

@ -18,14 +18,17 @@ load => codec_gsm.so ; GSM/PCM16 (signed linear) Codec Translat - Requires N/A
load => codec_ulaw.so ; Mu-law Coder/Decoder - Requires N/A
load => format_gsm.so ; Raw GSM data - Requires N/A
load => format_pcm.so ; Raw uLaw 8khz Audio support (PCM) - Requires N/A
load => format_wav_gsm.so
load => app_dial.so ; Dialing Application - Requires res_features.so, res_musiconhold.so
load => app_parkandannounce.so ; Call Parking and Announce Application - Requires res_features.so
load => app_playback.so ; Sound File Playback Application - Requires N/A
load => app_record.so ; Sound File Record Application - Requires N/A
load => app_system.so ; Execute a system command - Requires N/A
load => app_disa.so ; Direct Inward System Access
load => app_authenticate.so ; Authenticate via pin
load => app_senddtmf.so ; Ability to send DTMF tones on the line.
load => func_cut.so ; To manipulate strings
load => func_timeout.so ; Used for DISA timeouts
[global]
chan_modem.so=no

View file

@ -191,6 +191,10 @@ function ipt_delete_all(args, comp, off)
end
end
-- Convert mac to uci-compatible section name
function convert_mac_to_secname(mac)
return string.gsub(mac, ":", "")
end
-- Add a lease to state and invoke add_rule
function add_lease(mac, arp, no_uci)
@ -208,7 +212,7 @@ function add_lease(mac, arp, no_uci)
-- Add lease if there is an ip addr
if ipaddr then
if not no_uci then
uci:section("luci_splash", "lease", nil, {
uci:section("luci_splash", "lease", convert_mac_to_secname(mac), {
mac = mac,
ipaddr = ipaddr,
start = os.time()
@ -241,7 +245,7 @@ end
-- Add a whitelist entry
function add_whitelist(mac)
uci:section("luci_splash", "whitelist", nil, { mac = mac })
uci:section("luci_splash", "whitelist", convert_mac_to_secname(mac), { mac = mac })
uci:save("luci_splash")
uci:commit("luci_splash")
add_whitelist_rule(mac)
@ -250,7 +254,7 @@ end
-- Add a blacklist entry
function add_blacklist(mac)
uci:section("luci_splash", "blacklist", nil, { mac = mac })
uci:section("luci_splash", "blacklist", convert_mac_to_secname(mac), { mac = mac })
uci:save("luci_splash")
uci:commit("luci_splash")
add_blacklist_rule(mac)
@ -343,7 +347,7 @@ function sync()
remove_lease_rule(v.mac, v.ipaddr)
else
-- Rewrite state
uci:section("luci_splash", "lease", nil, {
uci:section("luci_splash", "lease", convert_mac_to_secname(v.mac), {
mac = v.mac,
ipaddr = v.ipaddr,
start = v.start

View file

@ -66,7 +66,7 @@ function index()
}
-- create toplevel menu nodes
local st = entry({"admin", "statistics"}, call("statistics_index"), _("Statistics"), 80)
local st = entry({"admin", "statistics"}, template("admin_statistics/index"), _("Statistics"), 80)
st.i18n = "statistics"
st.index = true
@ -97,7 +97,7 @@ function index()
end
-- output views
local page = entry( { "admin", "statistics", "graph" }, call("statistics_index"), _("Graphs"), 80)
local page = entry( { "admin", "statistics", "graph" }, template("admin_statistics/index"), _("Graphs"), 80)
page.i18n = "statistics"
page.setuser = "nobody"
page.setgroup = "nogroup"

View file

@ -309,6 +309,12 @@ plugins = {
{ "Irqs" }
},
iwinfo = {
{ },
{ "IgnoreSelected" },
{ "Interfaces" }
},
load = {
{ },
{ },

View file

@ -25,7 +25,7 @@ s:tab("filter", translate("Filtering and ACLs"))
s:tab("limits", translate("Server limits"))
o = s:taboption("general", Flag, "enable", translate("Enable Tinyproxy server"))
o = s:taboption("general", Flag, "enabled", translate("Enable Tinyproxy server"))
o.rmempty = false
function o.write(self, section, value)

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