mirror of
https://github.com/asterisk/asterisk.git
synced 2026-03-02 03:31:09 +00:00
Compare commits
3870 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fa9cd9521 | ||
|
|
c6363dc1d7 | ||
|
|
0bd9a22495 | ||
|
|
63046de1cb | ||
|
|
e132aba5c9 | ||
|
|
4196243583 | ||
|
|
9ce061aa3f | ||
|
|
168ed954eb | ||
|
|
0d1660a369 | ||
|
|
ebb8253d2f | ||
|
|
11f81ad761 | ||
|
|
ad8786f355 | ||
|
|
17fd431b31 | ||
|
|
45c9175c77 | ||
|
|
8355d829bb | ||
|
|
b14b81d8b4 | ||
|
|
e875a17b48 | ||
|
|
7f9f2f6543 | ||
|
|
b2cfc35315 | ||
|
|
31c57904fd | ||
|
|
0ead801f25 | ||
|
|
009b812d76 | ||
|
|
a0d4959fc5 | ||
|
|
11c11d27bc | ||
|
|
6b36952664 | ||
|
|
afdd1c5512 | ||
|
|
ac303de4aa | ||
|
|
508b3ba688 | ||
|
|
75b0c4445a | ||
|
|
2f5ced421e | ||
|
|
d09714e12b | ||
|
|
52171d4c26 | ||
|
|
8bd93a96ac | ||
|
|
5a80b57ccf | ||
|
|
b2fb3d501c | ||
|
|
6cf8ee01a6 | ||
|
|
153119a7bc | ||
|
|
9b8ba163f2 | ||
|
|
bfac0241be | ||
|
|
09f5f15a72 | ||
|
|
84957104b2 | ||
|
|
312008513e | ||
|
|
08630905fa | ||
|
|
83ef83a5f8 | ||
|
|
2595998b8f | ||
|
|
7fe4d52579 | ||
|
|
39d4e1253b | ||
|
|
f7eada3cff | ||
|
|
405ff91e92 | ||
|
|
ce07ed72c0 | ||
|
|
150fc177cd | ||
|
|
c73ad9e6f9 | ||
|
|
cf638de6ad | ||
|
|
40ea953811 | ||
|
|
8061ba32c3 | ||
|
|
120e4bc237 | ||
|
|
4fc7030156 | ||
|
|
34d2254f70 | ||
|
|
b47ed67c84 | ||
|
|
e6f049f9bf | ||
|
|
7491dba549 | ||
|
|
3e7d040f3f | ||
|
|
c78761cc7c | ||
|
|
6b6eb7977b | ||
|
|
a795d02a30 | ||
|
|
2faf30d730 | ||
|
|
c2a39b5c64 | ||
|
|
ffc2c34f15 | ||
|
|
57cb8c168c | ||
|
|
f1274662f4 | ||
|
|
9f6e57f90a | ||
|
|
8ff6d5cabf | ||
|
|
298718ebaa | ||
|
|
171872003b | ||
|
|
5fe5bf08b2 | ||
|
|
cf238fa10d | ||
|
|
7e3d58e030 | ||
|
|
508b530e39 | ||
|
|
5e168ffd67 | ||
|
|
9e05fb4f39 | ||
|
|
a2c28355e0 | ||
|
|
0e4c9f9765 | ||
|
|
4d504015d4 | ||
|
|
3e2bd82411 | ||
|
|
2877470389 | ||
|
|
4a15544b22 | ||
|
|
9400e87db0 | ||
|
|
200ca9631d | ||
|
|
4f1e96c0b6 | ||
|
|
eac2ef9374 | ||
|
|
dd70231e97 | ||
|
|
02bb0b5e22 | ||
|
|
f14775e845 | ||
|
|
ee90d54c2e | ||
|
|
f4c2a167ed | ||
|
|
0ad6773b76 | ||
|
|
320be7fff9 | ||
|
|
0c2abdf74e | ||
|
|
0b3cfb26b4 | ||
|
|
cbc30c9163 | ||
|
|
71a395e3e3 | ||
|
|
b2073cb75f | ||
|
|
df905cf5a2 | ||
|
|
cf45c660cc | ||
|
|
2995096956 | ||
|
|
a6e8158ddc | ||
|
|
68206d0890 | ||
|
|
6dbcb94c01 | ||
|
|
91f9740856 | ||
|
|
083cf7af1d | ||
|
|
984142aebe | ||
|
|
29f7161c9b | ||
|
|
6618cec0d7 | ||
|
|
ebe377fc5c | ||
|
|
268eedc2f3 | ||
|
|
eadb02a84f | ||
|
|
c98832d092 | ||
|
|
888c329e65 | ||
|
|
548ce34d97 | ||
|
|
2e4b4764fb | ||
|
|
bf1069b3ae | ||
|
|
f717cd2719 | ||
|
|
cda604fabe | ||
|
|
6125965ff5 | ||
|
|
a6cea6892b | ||
|
|
1031a3c36d | ||
|
|
89d62574ef | ||
|
|
262e9c3003 | ||
|
|
43e32456ca | ||
|
|
fcb8ab5da6 | ||
|
|
0f5dbaf7ec | ||
|
|
8e267ac60a | ||
|
|
794d0b2c68 | ||
|
|
8c97879e99 | ||
|
|
47f2779b9d | ||
|
|
c77e7ed452 | ||
|
|
a9fd6fca9e | ||
|
|
57b353cebf | ||
|
|
07c87b82ff | ||
|
|
f1c3d761aa | ||
|
|
34f9e85a11 | ||
|
|
56cf655835 | ||
|
|
4d1e5adfdc | ||
|
|
3d263c243a | ||
|
|
334e508e66 | ||
|
|
28eedd8e44 | ||
|
|
e0aaf08b3b | ||
|
|
e16718bb2e | ||
|
|
1e70fa09cd | ||
|
|
a2f752ec6c | ||
|
|
3ad71d439c | ||
|
|
d667d39367 | ||
|
|
c96d5eabad | ||
|
|
941ba1c5be | ||
|
|
17045b502f | ||
|
|
916f6b627a | ||
|
|
e56c7ba459 | ||
|
|
34bc1ac241 | ||
|
|
4920426fbd | ||
|
|
e5f2fef425 | ||
|
|
4faec1b262 | ||
|
|
efc4fdf079 | ||
|
|
8b6aa2741c | ||
|
|
90fea452ac | ||
|
|
8451fd7f7d | ||
|
|
ed8a15efce | ||
|
|
6bee09440d | ||
|
|
d54b330a2e | ||
|
|
621b5be6cd | ||
|
|
687846975e | ||
|
|
315e0c3054 | ||
|
|
4f4009663c | ||
|
|
48f1386fff | ||
|
|
8f0e43be23 | ||
|
|
4b165caef4 | ||
|
|
4a14b7c071 | ||
|
|
e12e134ef9 | ||
|
|
7b319eb03a | ||
|
|
98d05f22ac | ||
|
|
7ba20c5024 | ||
|
|
2e6d346313 | ||
|
|
8aaa9e194e | ||
|
|
60a9627192 | ||
|
|
28a319be01 | ||
|
|
f066af663f | ||
|
|
1e2baaf12e | ||
|
|
f56ba6a441 | ||
|
|
2ea44416b2 | ||
|
|
78f6f43d19 | ||
|
|
42b84afa40 | ||
|
|
be446083ab | ||
|
|
61538bec92 | ||
|
|
4402a86f93 | ||
|
|
4ead78e851 | ||
|
|
d056623e60 | ||
|
|
a281bef2b3 | ||
|
|
4b30e9ee37 | ||
|
|
2b1a8d34d9 | ||
|
|
bc70235479 | ||
|
|
857bf5486b | ||
|
|
4d6e2801d1 | ||
|
|
f4a80f1609 | ||
|
|
26d298f693 | ||
|
|
926270782f | ||
|
|
fd7f18421d | ||
|
|
ee53dc7286 | ||
|
|
d565dc3225 | ||
|
|
fe07794bba | ||
|
|
4aa9d15438 | ||
|
|
83e1402d8a | ||
|
|
f1c93a8ff3 | ||
|
|
a004c5ca9e | ||
|
|
d6efd17100 | ||
|
|
3aeb519068 | ||
|
|
eb767e674f | ||
|
|
b4af00a20f | ||
|
|
39e574a8bd | ||
|
|
04c06471e6 | ||
|
|
687b01f298 | ||
|
|
8e59e3e38c | ||
|
|
1dec1dfb9c | ||
|
|
292059c9cb | ||
|
|
63b6e2a2a1 | ||
|
|
9420fee71d | ||
|
|
ece9341019 | ||
|
|
e608ffdaa9 | ||
|
|
684ffcce61 | ||
|
|
a346745899 | ||
|
|
5ef097f5d7 | ||
|
|
d35a82a5b6 | ||
|
|
b2ab9ffaec | ||
|
|
2e88a61fa3 | ||
|
|
9e1d3683fa | ||
|
|
528d2dcff5 | ||
|
|
40969e6b29 | ||
|
|
59814ed3e5 | ||
|
|
8f2106c5e3 | ||
|
|
37a80ea3bc | ||
|
|
a46350e315 | ||
|
|
e1a6d33ed0 | ||
|
|
4979d7fbb1 | ||
|
|
bdcbd76e13 | ||
|
|
081e28667e | ||
|
|
1ef98ac6de | ||
|
|
b90f6b40d9 | ||
|
|
2bb388ebc8 | ||
|
|
1714f299c9 | ||
|
|
5571294b91 | ||
|
|
3696407c67 | ||
|
|
76b18e2d6e | ||
|
|
d9d599a84d | ||
|
|
36d08dc8f0 | ||
|
|
3035547927 | ||
|
|
517413928f | ||
|
|
b3ee85ee4a | ||
|
|
540a2571ca | ||
|
|
53840ccffc | ||
|
|
61d87e19f1 | ||
|
|
63a98a2bed | ||
|
|
4542f92842 | ||
|
|
fa023ceccf | ||
|
|
6c5bf0d542 | ||
|
|
a3b4b4459c | ||
|
|
58b1b7f825 | ||
|
|
4f5f53706d | ||
|
|
a87fb09763 | ||
|
|
fb3de07e39 | ||
|
|
02bb7498b0 | ||
|
|
8c9f25ece1 | ||
|
|
6356638b6a | ||
|
|
659eb8bd36 | ||
|
|
2ef418765c | ||
|
|
33cffbd344 | ||
|
|
5d877f53ed | ||
|
|
334bd9f57d | ||
|
|
a6fb9eef88 | ||
|
|
d9d070e30b | ||
|
|
73f50db89e | ||
|
|
d1b6552ef7 | ||
|
|
8b079c4bf2 | ||
|
|
22db312ca1 | ||
|
|
fbc3e2e3ce | ||
|
|
d2d967d775 | ||
|
|
c69bb18184 | ||
|
|
dc5042762f | ||
|
|
efcc597742 | ||
|
|
b0a516034f | ||
|
|
2880956743 | ||
|
|
56dd7681f8 | ||
|
|
a6d0cc6c02 | ||
|
|
9c92ca2d27 | ||
|
|
f8526ef3ba | ||
|
|
96624911f0 | ||
|
|
5967d8f2bc | ||
|
|
dcd5da730a | ||
|
|
3c54495507 | ||
|
|
f9eedef7ee | ||
|
|
de117b689e | ||
|
|
5799a6a60c | ||
|
|
a97e1f873f | ||
|
|
74239cb26c | ||
|
|
fa7a75c886 | ||
|
|
4a187156b2 | ||
|
|
f45b8fcc70 | ||
|
|
1db571cb37 | ||
|
|
8289500dd5 | ||
|
|
ec9f642dc3 | ||
|
|
f2a2787b42 | ||
|
|
da0fb57df3 | ||
|
|
10378ed083 | ||
|
|
b0b9c0928b | ||
|
|
9386b25b51 | ||
|
|
9a81d7270e | ||
|
|
29062def81 | ||
|
|
ad851c87b5 | ||
|
|
b67759975d | ||
|
|
f4adada2e8 | ||
|
|
a4671a3d88 | ||
|
|
379d3a133c | ||
|
|
dd8d225b4e | ||
|
|
78693d31e9 | ||
|
|
49d18cef95 | ||
|
|
cc8996361c | ||
|
|
8060744e05 | ||
|
|
799ff464f2 | ||
|
|
b107f9c1c9 | ||
|
|
0e39f602ea | ||
|
|
a391baf1be | ||
|
|
3384173257 | ||
|
|
51ea5a2797 | ||
|
|
1298f6585d | ||
|
|
2ebc21f175 | ||
|
|
6c6ec855a7 | ||
|
|
10bbbf2c14 | ||
|
|
fcf810801f | ||
|
|
665cf4fb64 | ||
|
|
6f60468d3d | ||
|
|
00f2912aaa | ||
|
|
b32ffb8190 | ||
|
|
4ceafc96b1 | ||
|
|
bed2bda4f4 | ||
|
|
a97bf16d2d | ||
|
|
8a987daf3b | ||
|
|
8d135aa5ae | ||
|
|
0a4530cead | ||
|
|
ad1ee839cc | ||
|
|
1b53088a4b | ||
|
|
a5b4c8881e | ||
|
|
2583e00e03 | ||
|
|
7e3f8ee419 | ||
|
|
b035299213 | ||
|
|
4020387145 | ||
|
|
3e7c0ce67f | ||
|
|
0caa4033c9 | ||
|
|
cd65e922b2 | ||
|
|
90f22a990d | ||
|
|
0b74a19625 | ||
|
|
429432f5ff | ||
|
|
46f97f76a5 | ||
|
|
ec3b5c9b5b | ||
|
|
a160a8c9d5 | ||
|
|
65d6be272d | ||
|
|
1e75116e74 | ||
|
|
187942d00a | ||
|
|
418ff58e61 | ||
|
|
bb6333e01f | ||
|
|
df6c1f8b39 | ||
|
|
2b9417e2e5 | ||
|
|
f53fe9761c | ||
|
|
902661dd8e | ||
|
|
646dc459fa | ||
|
|
3d48bc2f61 | ||
|
|
28109dedf5 | ||
|
|
10781d30d2 | ||
|
|
c0c9a1a5f0 | ||
|
|
13e54102fd | ||
|
|
f4470352ff | ||
|
|
77ad568144 | ||
|
|
1b05a4639d | ||
|
|
e73c4e4a44 | ||
|
|
60c2988f53 | ||
|
|
35dd204d76 | ||
|
|
8eb984caec | ||
|
|
9801c6c63f | ||
|
|
1b754ff59d | ||
|
|
713ddd2172 | ||
|
|
d3cb67a4cd | ||
|
|
1f02d433b3 | ||
|
|
dbf6ad2ecd | ||
|
|
c6938534bd | ||
|
|
ac659af3ea | ||
|
|
bdabdcbf1e | ||
|
|
457d6f2822 | ||
|
|
0d23dbb490 | ||
|
|
3cd77bab28 | ||
|
|
a39d05855e | ||
|
|
66d0e5756f | ||
|
|
591eb8fac1 | ||
|
|
0ae97da489 | ||
|
|
014a0a178b | ||
|
|
5e8f6247fb | ||
|
|
de1c7219ea | ||
|
|
7352e07e12 | ||
|
|
bfe333ed67 | ||
|
|
ec25eab17f | ||
|
|
e212b875fc | ||
|
|
92f1ec6be4 | ||
|
|
4443cc2107 | ||
|
|
d612a5ce42 | ||
|
|
808ecc893a | ||
|
|
1e9087357b | ||
|
|
124c88fba3 | ||
|
|
ef3f4d29c9 | ||
|
|
67478da442 | ||
|
|
67c451783b | ||
|
|
517e58c5df | ||
|
|
b86dbdb22c | ||
|
|
807bbf3461 | ||
|
|
8b1cdad2f5 | ||
|
|
ce25d82aa7 | ||
|
|
d354512eca | ||
|
|
f0131ed0f2 | ||
|
|
a4111e1f93 | ||
|
|
f7098a28be | ||
|
|
fdffdc9364 | ||
|
|
d91f0dadc9 | ||
|
|
291309df4a | ||
|
|
eb08e2600f | ||
|
|
0faa51794d | ||
|
|
5f5017defd | ||
|
|
737023e9d4 | ||
|
|
e98d85bf09 | ||
|
|
6adefd13c1 | ||
|
|
5c37031b1c | ||
|
|
141a82674e | ||
|
|
2423b41fd9 | ||
|
|
f85277c7b3 | ||
|
|
d60b955324 | ||
|
|
663636b515 | ||
|
|
8bccbf9afb | ||
|
|
1d10b782b4 | ||
|
|
3cd48f9a41 | ||
|
|
d50ef1d333 | ||
|
|
fbcd14b30b | ||
|
|
09ca3690b5 | ||
|
|
6db145dd07 | ||
|
|
0ff4ffd27f | ||
|
|
ba5a68e731 | ||
|
|
df358f42e0 | ||
|
|
0e518edee4 | ||
|
|
dea58d2e88 | ||
|
|
97efb246b3 | ||
|
|
17a3454b92 | ||
|
|
3680bb43cd | ||
|
|
b0180d6665 | ||
|
|
f9be91101f | ||
|
|
e16c9c9ecd | ||
|
|
57c86cec8e | ||
|
|
d600998f7e | ||
|
|
a75365ea8e | ||
|
|
8b34f224e7 | ||
|
|
97d664a128 | ||
|
|
04bcd2ff23 | ||
|
|
3f9482f7bc | ||
|
|
ebf15d6151 | ||
|
|
38f5196684 | ||
|
|
31457d7be1 | ||
|
|
a196c598b6 | ||
|
|
ca88a7476f | ||
|
|
eda8998156 | ||
|
|
b1b4db95c2 | ||
|
|
01e406626e | ||
|
|
89da44223d | ||
|
|
ddf2648326 | ||
|
|
4c2148bea5 | ||
|
|
66bf105bbc | ||
|
|
1700f24dd3 | ||
|
|
aa2e435d82 | ||
|
|
2fc5fed79e | ||
|
|
efd42d2d5c | ||
|
|
2ff6a84a16 | ||
|
|
01c0938ddf | ||
|
|
fda8fa2367 | ||
|
|
998ef5948c | ||
|
|
cbc39f7d71 | ||
|
|
802a44a15b | ||
|
|
efbb88225c | ||
|
|
30d264ebda | ||
|
|
bf4ca23372 | ||
|
|
9ecfd9f33e | ||
|
|
255ce93616 | ||
|
|
4ffa6c246f | ||
|
|
a9db074776 | ||
|
|
7b10240bc3 | ||
|
|
9812bcc03c | ||
|
|
fb6e840213 | ||
|
|
2a896e5d3c | ||
|
|
ab67420c37 | ||
|
|
07a6cd4592 | ||
|
|
762cd4621d | ||
|
|
a23534c4e2 | ||
|
|
1597114535 | ||
|
|
aea667c7c8 | ||
|
|
e0f335a4eb | ||
|
|
78531a0f32 | ||
|
|
a2297d6776 | ||
|
|
ef889d6672 | ||
|
|
291ce3e839 | ||
|
|
42806dc1ac | ||
|
|
45a157ec0e | ||
|
|
49389bd690 | ||
|
|
a638a19ea2 | ||
|
|
199ec4356a | ||
|
|
5dad6f4319 | ||
|
|
27e4a2ee57 | ||
|
|
d7fb7e9ed7 | ||
|
|
528cf89739 | ||
|
|
b96abb803c | ||
|
|
574d3785ab | ||
|
|
d1be79cce2 | ||
|
|
9d8c71ee86 | ||
|
|
877f1f64c2 | ||
|
|
a9f5393bfe | ||
|
|
038cd054ae | ||
|
|
e228c88d2a | ||
|
|
4824ee8b20 | ||
|
|
0da1f7593d | ||
|
|
8fae88d368 | ||
|
|
5c32080a0c | ||
|
|
610d52b054 | ||
|
|
0aa4c95a89 | ||
|
|
d2385517ac | ||
|
|
3fc2609468 | ||
|
|
0eec8c8318 | ||
|
|
bdc00dae0e | ||
|
|
a1442538b5 | ||
|
|
ce68497243 | ||
|
|
9a387e5a7a | ||
|
|
c4aa1dadbd | ||
|
|
556f27ecf1 | ||
|
|
ef2cd744cf | ||
|
|
f5b1c6c27e | ||
|
|
5f93d06cf8 | ||
|
|
952a5e6dd9 | ||
|
|
238b9d24c6 | ||
|
|
7457c51bc2 | ||
|
|
a4437b1362 | ||
|
|
45b91a90e1 | ||
|
|
3cb1d7843b | ||
|
|
4d6b943ea4 | ||
|
|
d8aff59a9e | ||
|
|
e9dbd238c8 | ||
|
|
89447a99ec | ||
|
|
e499028440 | ||
|
|
2f82498995 | ||
|
|
71df4d92da | ||
|
|
ac1e884328 | ||
|
|
e31d4ee777 | ||
|
|
cc30079edd | ||
|
|
b76252d68e | ||
|
|
ce868ed5f5 | ||
|
|
8283811633 | ||
|
|
00f227a684 | ||
|
|
a6e748e491 | ||
|
|
8a12240f73 | ||
|
|
815318b12f | ||
|
|
5e0b84633e | ||
|
|
aa2a8ed77c | ||
|
|
9e96cb612b | ||
|
|
f54c287c73 | ||
|
|
14e1fe4795 | ||
|
|
81df8343d3 | ||
|
|
388ca07547 | ||
|
|
b3fdacf9cc | ||
|
|
cb896da998 | ||
|
|
879c401544 | ||
|
|
c6025e41c6 | ||
|
|
52647db120 | ||
|
|
5adfdcba1e | ||
|
|
550e8e56ba | ||
|
|
8d457d07c4 | ||
|
|
b3333ebc2e | ||
|
|
3454b5927f | ||
|
|
54e81f5ca0 | ||
|
|
c1e14143fa | ||
|
|
97904aee06 | ||
|
|
24e902d2a4 | ||
|
|
0da197d593 | ||
|
|
6b2e3f29f9 | ||
|
|
64b9a563f2 | ||
|
|
a703e927b1 | ||
|
|
8d0d386970 | ||
|
|
dc542971df | ||
|
|
8fb1ddeb5d | ||
|
|
e94fa076cb | ||
|
|
f83715ce9c | ||
|
|
b0970b9e33 | ||
|
|
f4b60a5c65 | ||
|
|
e7908a50e8 | ||
|
|
789c4f4587 | ||
|
|
19be63c4c3 | ||
|
|
04a9441769 | ||
|
|
a2da1f08bd | ||
|
|
eb57ea95d6 | ||
|
|
1e2db0e885 | ||
|
|
d77ae42896 | ||
|
|
2a2d65541b | ||
|
|
fd7577eed2 | ||
|
|
93818c761b | ||
|
|
bc72d7584a | ||
|
|
b813a5f3fa | ||
|
|
d952c7ed71 | ||
|
|
07166e63a3 | ||
|
|
9888487f9c | ||
|
|
3c7ab1ca5e | ||
|
|
08a8632ac7 | ||
|
|
4b2877834e | ||
|
|
344ec00439 | ||
|
|
082f628401 | ||
|
|
3cf360ae44 | ||
|
|
0c39d6de8e | ||
|
|
53262335c8 | ||
|
|
380b9a40a3 | ||
|
|
f6109b7b94 | ||
|
|
1db964ad95 | ||
|
|
416079db61 | ||
|
|
49ca05642a | ||
|
|
7d88098555 | ||
|
|
82db278716 | ||
|
|
cfb711bf57 | ||
|
|
471df8f512 | ||
|
|
9f1562a599 | ||
|
|
e2fe8ef485 | ||
|
|
4a19a2644f | ||
|
|
066a53df8a | ||
|
|
2a108b9b06 | ||
|
|
6749f1b8b5 | ||
|
|
8ff9c0d1b9 | ||
|
|
b48987922c | ||
|
|
5259155e52 | ||
|
|
2f753040ef | ||
|
|
bd7ca6bb69 | ||
|
|
0f88c702df | ||
|
|
28e5320ab4 | ||
|
|
47f8883942 | ||
|
|
4c133e47da | ||
|
|
0cf6b2ba31 | ||
|
|
7fffa6e20a | ||
|
|
ccdd86775f | ||
|
|
91d2e58d1b | ||
|
|
1327846518 | ||
|
|
11b1e81197 | ||
|
|
616780b64e | ||
|
|
90a497c3b8 | ||
|
|
de1d9a90dd | ||
|
|
516cd1ba8d | ||
|
|
c7541bd672 | ||
|
|
c3c13114fb | ||
|
|
2863202bed | ||
|
|
cab4557006 | ||
|
|
f1be7d7ffc | ||
|
|
c22fdb7232 | ||
|
|
bd1c5ac3cf | ||
|
|
fa814abe05 | ||
|
|
03cd30b746 | ||
|
|
7ede296efd | ||
|
|
264fead207 | ||
|
|
e5ad308a2b | ||
|
|
f31a210cb2 | ||
|
|
b27c9f26fe | ||
|
|
0ffa958fc4 | ||
|
|
e8483c021b | ||
|
|
5596c6a5da | ||
|
|
0a6f41cdf2 | ||
|
|
4219bdc2b4 | ||
|
|
fa9c265ce7 | ||
|
|
6d447004ea | ||
|
|
091c6c36b9 | ||
|
|
1f34a1dab4 | ||
|
|
ba55e8ae64 | ||
|
|
461596d9b1 | ||
|
|
0e3fc6a4fe | ||
|
|
6a589d5630 | ||
|
|
b8c18d6176 | ||
|
|
4210fd6ad9 | ||
|
|
1ddd0afe36 | ||
|
|
230d4b38a3 | ||
|
|
1afd98d916 | ||
|
|
60707a4172 | ||
|
|
f2dcfca9c4 | ||
|
|
d8436708c0 | ||
|
|
de3528f0be | ||
|
|
d0ab0358aa | ||
|
|
4f9f6df42c | ||
|
|
ed20af4517 | ||
|
|
3ca96a1317 | ||
|
|
3bcff2d2f9 | ||
|
|
3e85e4b82c | ||
|
|
299b26ae4a | ||
|
|
bbbbcaf73f | ||
|
|
37e789fd79 | ||
|
|
27f3c530ed | ||
|
|
534e44c599 | ||
|
|
1587fd6b84 | ||
|
|
ce51451ca6 | ||
|
|
3385ecc112 | ||
|
|
5d589eb866 | ||
|
|
039aad9ff4 | ||
|
|
a0b8879af4 | ||
|
|
e1c9ebc5b9 | ||
|
|
02ffc0eec8 | ||
|
|
a560227ccb | ||
|
|
87a7a3aaff | ||
|
|
6723ea3afb | ||
|
|
3ff53cd50b | ||
|
|
94f18868f1 | ||
|
|
e85d440f88 | ||
|
|
6910fd79f2 | ||
|
|
c14b405974 | ||
|
|
0125ed120f | ||
|
|
be2d39a1a5 | ||
|
|
cbe0264949 | ||
|
|
96e2c3a3aa | ||
|
|
7216081447 | ||
|
|
7acee329e1 | ||
|
|
916566ac11 | ||
|
|
785eaf01b3 | ||
|
|
ccbc7a6835 | ||
|
|
6193bc31b8 | ||
|
|
698820f4e3 | ||
|
|
34e40a3a59 | ||
|
|
a21e295c96 | ||
|
|
082d7ee4b8 | ||
|
|
bdd9753f1e | ||
|
|
0df4b4eb64 | ||
|
|
2ee29be0e8 | ||
|
|
172a45d603 | ||
|
|
27d0ebc686 | ||
|
|
be02813c26 | ||
|
|
85a15b4fc9 | ||
|
|
c16542c1d0 | ||
|
|
1de05fb7da | ||
|
|
a2e82071c5 | ||
|
|
cfba600eab | ||
|
|
99f901f065 | ||
|
|
f074b92823 | ||
|
|
07f349766c | ||
|
|
892b06e282 | ||
|
|
f3522b6c01 | ||
|
|
437f625786 | ||
|
|
8b364485a0 | ||
|
|
345dff63e9 | ||
|
|
76913125d8 | ||
|
|
f195e423f4 | ||
|
|
5abc3ecb56 | ||
|
|
87787b05ae | ||
|
|
4f2b8f8e9a | ||
|
|
c8170cf360 | ||
|
|
358ff9f7d6 | ||
|
|
e094bf07dc | ||
|
|
05e338ce75 | ||
|
|
fbe6024753 | ||
|
|
4d3f4f719a | ||
|
|
b240128ed4 | ||
|
|
70b3ab34a8 | ||
|
|
27e3cd9ca8 | ||
|
|
13a45232fa | ||
|
|
c4bfcdeec5 | ||
|
|
cfcc58d96e | ||
|
|
096feeeddd | ||
|
|
2de01f7b7e | ||
|
|
0369242c4c | ||
|
|
a70d444333 | ||
|
|
79a00a33f9 | ||
|
|
c542576190 | ||
|
|
725c352e94 | ||
|
|
64e1166e6f | ||
|
|
57b6515d82 | ||
|
|
e786eae3cd | ||
|
|
a322c6f411 | ||
|
|
943133953e | ||
|
|
f6717c92b2 | ||
|
|
9b0b4bf041 | ||
|
|
183fb08ee6 | ||
|
|
760bc42049 | ||
|
|
3329f8154e | ||
|
|
b4f6d91eda | ||
|
|
0f93207cda | ||
|
|
43866cf0d9 | ||
|
|
deb02a000f | ||
|
|
baef4818d2 | ||
|
|
bf70a01da6 | ||
|
|
5733f64bdd | ||
|
|
a57ad69b53 | ||
|
|
7b52e19b6d | ||
|
|
728e55e697 | ||
|
|
71f41a06dc | ||
|
|
e90022767d | ||
|
|
a395d75a91 | ||
|
|
42837cde4c | ||
|
|
1394a78bd6 | ||
|
|
e4d4c93bd8 | ||
|
|
00f3bf560b | ||
|
|
5bd8cf6cde | ||
|
|
9e789de703 | ||
|
|
d1ad2a695d | ||
|
|
d0c1882cf7 | ||
|
|
0abd9ec096 | ||
|
|
25afd9876c | ||
|
|
eb718e597d | ||
|
|
1bfdd45fca | ||
|
|
d189993f15 | ||
|
|
6f5eb3b8fa | ||
|
|
4eedf0cd2e | ||
|
|
630ca201d6 | ||
|
|
bf17aa1eca | ||
|
|
5ed7dc3590 | ||
|
|
0fc1ef8c9d | ||
|
|
d89ed4ab5f | ||
|
|
0905b587cf | ||
|
|
35ffb12ae8 | ||
|
|
4dba976a7f | ||
|
|
d3499da6fd | ||
|
|
a1531e0ae3 | ||
|
|
7f234dbc4e | ||
|
|
1a3ec0536c | ||
|
|
832da92bdc | ||
|
|
e85731555d | ||
|
|
7ab67c9fba | ||
|
|
0afbb8bcbf | ||
|
|
bb75fcc4db | ||
|
|
0bb8d95674 | ||
|
|
405d0be9fe | ||
|
|
b5ad8c24be | ||
|
|
e252af2152 | ||
|
|
a59c1d2ac4 | ||
|
|
e49aae74d0 | ||
|
|
c87d1f6309 | ||
|
|
a23fa08274 | ||
|
|
24a5704798 | ||
|
|
d3397cd37d | ||
|
|
f8594ac304 | ||
|
|
ed42d3074d | ||
|
|
eb80683222 | ||
|
|
5808760bf4 | ||
|
|
404485711e | ||
|
|
daf76979ca | ||
|
|
73f91fcc44 | ||
|
|
8a4967294f | ||
|
|
dc60239686 | ||
|
|
b600cf2232 | ||
|
|
d9be9eb5a8 | ||
|
|
449bef5a36 | ||
|
|
b53507021e | ||
|
|
463444b391 | ||
|
|
a1cf0fbd43 | ||
|
|
2f2122875a | ||
|
|
569b95352a | ||
|
|
ab7cd94b60 | ||
|
|
57217916f1 | ||
|
|
de4188df06 | ||
|
|
f10148d3e3 | ||
|
|
b1e841edab | ||
|
|
68070c82d0 | ||
|
|
823f4559c9 | ||
|
|
f202a8dbb3 | ||
|
|
09c3679e2d | ||
|
|
6b8ecfa35f | ||
|
|
3abd26bfdf | ||
|
|
03b1d1ea8c | ||
|
|
b1d55878a7 | ||
|
|
d5c614397a | ||
|
|
eac29e9814 | ||
|
|
bba1faf910 | ||
|
|
78117423fa | ||
|
|
5de01235b6 | ||
|
|
e167cc89f8 | ||
|
|
05d3d9c25f | ||
|
|
957782627c | ||
|
|
6e9d4faf61 | ||
|
|
0a4a5483ae | ||
|
|
bab6f6bdf2 | ||
|
|
fa0ca01ffe | ||
|
|
044ad2e2e7 | ||
|
|
9cd917c42a | ||
|
|
1b9251ad14 | ||
|
|
2f1c9c690f | ||
|
|
0c6b76f7c2 | ||
|
|
2a9d43407b | ||
|
|
8ed49644a6 | ||
|
|
872685d088 | ||
|
|
4d32c46126 | ||
|
|
4290558ec0 | ||
|
|
9b08305eae | ||
|
|
f78179c374 | ||
|
|
e42c11905e | ||
|
|
3fdbac912a | ||
|
|
3ba284094e | ||
|
|
634521b59b | ||
|
|
423fd40090 | ||
|
|
058f20179b | ||
|
|
dd293ed6fe | ||
|
|
3c7300d145 | ||
|
|
fb3f2062fa | ||
|
|
9e0e3799bf | ||
|
|
f107562f75 | ||
|
|
602d616726 | ||
|
|
611da9b699 | ||
|
|
34ed331f82 | ||
|
|
7ca6f85a41 | ||
|
|
069d045513 | ||
|
|
7c97de2611 | ||
|
|
11ee0b6a41 | ||
|
|
a40e6c115f | ||
|
|
4113c814c7 | ||
|
|
8426e454de | ||
|
|
c5e44cc3cb | ||
|
|
c793ab62ff | ||
|
|
decd0771ee | ||
|
|
68dd66c46d | ||
|
|
568ba9c398 | ||
|
|
e3d12a2ab2 | ||
|
|
c4a633a87b | ||
|
|
b5780eda44 | ||
|
|
65fc87b245 | ||
|
|
12b3b6c86e | ||
|
|
8ebfe337a7 | ||
|
|
28076a9c68 | ||
|
|
851fce9568 | ||
|
|
91a7960ad5 | ||
|
|
216fd6e249 | ||
|
|
18844270c3 | ||
|
|
fd9b6d13e6 | ||
|
|
5fa70e63a0 | ||
|
|
432bb121f3 | ||
|
|
52549b25cd | ||
|
|
fba5172e8a | ||
|
|
155d84a979 | ||
|
|
a7d2842beb | ||
|
|
70c530630a | ||
|
|
a722b0462e | ||
|
|
f63d46097d | ||
|
|
75d4369dfc | ||
|
|
3697f7dbcc | ||
|
|
9de6aed36b | ||
|
|
2e5873cb5d | ||
|
|
d2f22c57fe | ||
|
|
b1d9a040d4 | ||
|
|
fb8ebe6365 | ||
|
|
201849fb42 | ||
|
|
8e2e53c987 | ||
|
|
bd7418b625 | ||
|
|
3cf3edb14f | ||
|
|
3e2806114b | ||
|
|
2f911dfba6 | ||
|
|
64439e0692 | ||
|
|
b94f5ca495 | ||
|
|
1f1c915fea | ||
|
|
7be9c6e469 | ||
|
|
60ad539878 | ||
|
|
9b32ff1eeb | ||
|
|
074f8d9378 | ||
|
|
4b5f53d6a0 | ||
|
|
34208f76a5 | ||
|
|
e7bd1ce7b9 | ||
|
|
a8d8221357 | ||
|
|
ee4a248e6b | ||
|
|
4d0dd2775a | ||
|
|
eb6b35b75f | ||
|
|
9a478cb855 | ||
|
|
457528ae86 | ||
|
|
733c167528 | ||
|
|
f97df161f4 | ||
|
|
5bb0c3786d | ||
|
|
6195ae7453 | ||
|
|
779140b94c | ||
|
|
196112076c | ||
|
|
30910d48bc | ||
|
|
408ead2dda | ||
|
|
baa46147a5 | ||
|
|
3d0e3d3c0f | ||
|
|
560068617a | ||
|
|
ef0128ec41 | ||
|
|
5fec7176e0 | ||
|
|
a11c4965b7 | ||
|
|
b283a02a7d | ||
|
|
09c41b415d | ||
|
|
9b6bd35ed3 | ||
|
|
eb9adf42d6 | ||
|
|
6f0a7f7a15 | ||
|
|
614d878b04 | ||
|
|
a9da004305 | ||
|
|
88eede5218 | ||
|
|
9127ab071b | ||
|
|
05110e85d3 | ||
|
|
ca75adf9cb | ||
|
|
54dcc9bf56 | ||
|
|
ca7fc00ad5 | ||
|
|
df2394af02 | ||
|
|
c3af8944af | ||
|
|
b140eef0aa | ||
|
|
88bcbb2368 | ||
|
|
d9ed36059c | ||
|
|
1af31f2c64 | ||
|
|
b76935b95c | ||
|
|
03fbf171a7 | ||
|
|
3db853b428 | ||
|
|
a30ae193db | ||
|
|
a466fdbc40 | ||
|
|
2fb8ad79c2 | ||
|
|
9ab74af94f | ||
|
|
c9f168ed0f | ||
|
|
dbea1448bd | ||
|
|
e6de64a5a9 | ||
|
|
fe4b2401bd | ||
|
|
d37b6dd459 | ||
|
|
0a059f8ce1 | ||
|
|
80c9620612 | ||
|
|
2f421a55da | ||
|
|
42ad569376 | ||
|
|
bdbed69984 | ||
|
|
1d473f25dd | ||
|
|
b0972b8d1f | ||
|
|
f6f67727c6 | ||
|
|
8ef1f1ea2e | ||
|
|
df93792f9c | ||
|
|
08ac005489 | ||
|
|
27bb1601d3 | ||
|
|
da49f53b66 | ||
|
|
e9f2a805b9 | ||
|
|
74fdefdf1e | ||
|
|
68248b91f0 | ||
|
|
6729301b4d | ||
|
|
5e36feac27 | ||
|
|
7a363d3d17 | ||
|
|
2187465cae | ||
|
|
0f6db9f939 | ||
|
|
a03db324dd | ||
|
|
3f9c34f415 | ||
|
|
024f486810 | ||
|
|
f5c18f62a1 | ||
|
|
8801247d76 | ||
|
|
45ee2978cd | ||
|
|
f5de717d6e | ||
|
|
5546e32355 | ||
|
|
2f4a0dc3f5 | ||
|
|
652e085d0f | ||
|
|
8b2b0278c9 | ||
|
|
e66aef0c05 | ||
|
|
9cb185e126 | ||
|
|
2bd13db091 | ||
|
|
551e3ad719 | ||
|
|
df4ea0cec4 | ||
|
|
3ccf8627e0 | ||
|
|
aa63104784 | ||
|
|
2efcb2e331 | ||
|
|
76fe489c86 | ||
|
|
ec3f9d5041 | ||
|
|
7b0160ee51 | ||
|
|
b0991ab170 | ||
|
|
8c4cacbd58 | ||
|
|
502e74e5db | ||
|
|
b168dcdddf | ||
|
|
585afa7e8e | ||
|
|
737e9b2458 | ||
|
|
2ee28d0ccf | ||
|
|
bbe5ff18c2 | ||
|
|
ef4d9eb5b7 | ||
|
|
491e5d941c | ||
|
|
b72227e845 | ||
|
|
70167380a3 | ||
|
|
347f32ab97 | ||
|
|
3b3a042cef | ||
|
|
a054fec8ef | ||
|
|
bc9e475d6e | ||
|
|
18fef6deb1 | ||
|
|
133120aa38 | ||
|
|
e32c8f1ebe | ||
|
|
19d5ae6e8d | ||
|
|
3932d756d4 | ||
|
|
f75a3079e0 | ||
|
|
d11177774a | ||
|
|
e5629ea138 | ||
|
|
4f72a1da77 | ||
|
|
095b971fc6 | ||
|
|
2d78f0d53c | ||
|
|
4a4e1e348d | ||
|
|
702b8a96b0 | ||
|
|
dd4aba8022 | ||
|
|
e3c58c8ebe | ||
|
|
fdf586e416 | ||
|
|
88aec64bce | ||
|
|
db8da3c376 | ||
|
|
7538cee13b | ||
|
|
be9d4b4333 | ||
|
|
b3b931fab9 | ||
|
|
8fa9d75365 | ||
|
|
1f4eadaf6a | ||
|
|
ada1e768c4 | ||
|
|
7255d8797c | ||
|
|
46303772e5 | ||
|
|
d0e532a070 | ||
|
|
6c9b510d5d | ||
|
|
dc7ceb7fd8 | ||
|
|
d88a461764 | ||
|
|
db8da85266 | ||
|
|
bc80b3130d | ||
|
|
001623fa0a | ||
|
|
c53e76528d | ||
|
|
ee664e6ccd | ||
|
|
427be16475 | ||
|
|
5b9cab6c13 | ||
|
|
f70b57352b | ||
|
|
bec994b037 | ||
|
|
3cf5ea7383 | ||
|
|
d208532e6e | ||
|
|
800ad7f727 | ||
|
|
fd70e7920e | ||
|
|
d030752f72 | ||
|
|
319011b0e3 | ||
|
|
9e3a90e249 | ||
|
|
439e5eeeb4 | ||
|
|
1b23fce2bd | ||
|
|
a3355d9fe2 | ||
|
|
c359ec8f5c | ||
|
|
31b39fe85e | ||
|
|
c51934cd70 | ||
|
|
481a59e92e | ||
|
|
1bc96b7aab | ||
|
|
bad7cc9c14 | ||
|
|
c96b39a960 | ||
|
|
758f246390 | ||
|
|
b1a658f57e | ||
|
|
8800bd6b1f | ||
|
|
a53d260d5f | ||
|
|
3ef099dede | ||
|
|
1794aac9e1 | ||
|
|
de57be6bbd | ||
|
|
a23c43cefa | ||
|
|
727abcdec7 | ||
|
|
c96046b6c2 | ||
|
|
f105351643 | ||
|
|
5ae7b48700 | ||
|
|
8c2bc79b77 | ||
|
|
d3fd49f2cf | ||
|
|
68c45465c8 | ||
|
|
ad49896f6b | ||
|
|
8995f5d810 | ||
|
|
22de310e04 | ||
|
|
9bd9958722 | ||
|
|
dff7c80952 | ||
|
|
a14ba4f1b5 | ||
|
|
994c0a5573 | ||
|
|
a9b5a6cbb0 | ||
|
|
8699103fa1 | ||
|
|
469c7d6de9 | ||
|
|
9c42fa75a4 | ||
|
|
0f2e75a257 | ||
|
|
e115566669 | ||
|
|
65d5921dde | ||
|
|
e325aa312f | ||
|
|
7b7dbfb855 | ||
|
|
cc36c3d475 | ||
|
|
a550016fd6 | ||
|
|
df9b7608a9 | ||
|
|
b9d81ae6ad | ||
|
|
32ecea7b8c | ||
|
|
746d2e7f67 | ||
|
|
27578642b8 | ||
|
|
63b280e97c | ||
|
|
0062fe9588 | ||
|
|
103bb4a334 | ||
|
|
aa2795cc46 | ||
|
|
269507ad59 | ||
|
|
ca0c646539 | ||
|
|
8cc1ffe2ab | ||
|
|
dc7e5f5f03 | ||
|
|
799b876aa0 | ||
|
|
8f5498177e | ||
|
|
8f9ace9228 | ||
|
|
5a9ab574de | ||
|
|
ea2b6241fd | ||
|
|
ea70485e7b | ||
|
|
37ae3cd701 | ||
|
|
b6beb440cd | ||
|
|
bc86e5de2a | ||
|
|
2587e6faa4 | ||
|
|
ce82bfa75a | ||
|
|
31e427d775 | ||
|
|
a435f135b5 | ||
|
|
36b87b3b33 | ||
|
|
8164972e34 | ||
|
|
49257bafbc | ||
|
|
9286f2c6d3 | ||
|
|
fdcf41cef0 | ||
|
|
66fae27e3a | ||
|
|
c66bf9a326 | ||
|
|
8968d50976 | ||
|
|
b0f9569b5c | ||
|
|
514acf8dfc | ||
|
|
89561c6a29 | ||
|
|
c47538a24b | ||
|
|
5ee4f3048c | ||
|
|
0f5ed60d51 | ||
|
|
5ef2ef8a1d | ||
|
|
d34639a601 | ||
|
|
bf2ec2d6d0 | ||
|
|
f30d55fbf6 | ||
|
|
8136198e53 | ||
|
|
fa9a8d158a | ||
|
|
cc698e15cf | ||
|
|
4926908616 | ||
|
|
a2cc6b01be | ||
|
|
63074875d6 | ||
|
|
04887bcc3e | ||
|
|
5b53760717 | ||
|
|
ff2ba012d2 | ||
|
|
e446f4ca81 | ||
|
|
4d1706d05f | ||
|
|
4f5ddbc374 | ||
|
|
96117402b1 | ||
|
|
2cd1eb39b1 | ||
|
|
03cb980dc2 | ||
|
|
b820fd0075 | ||
|
|
cf57ba2310 | ||
|
|
fc7593e594 | ||
|
|
54780434a6 | ||
|
|
ec14976ac3 | ||
|
|
fdb8ffe20d | ||
|
|
f7a7158f3f | ||
|
|
b4a2ee6104 | ||
|
|
728cceca7e | ||
|
|
7baf86bc8b | ||
|
|
9432a1c19f | ||
|
|
1b5d2d4667 | ||
|
|
682913a1f3 | ||
|
|
82b3a5f417 | ||
|
|
8f9e2b6633 | ||
|
|
8161efd26a | ||
|
|
1799dd3641 | ||
|
|
1147ed1e8c | ||
|
|
0f966565af | ||
|
|
2cc7d3e8db | ||
|
|
67b3ab9ee5 | ||
|
|
7dee677799 | ||
|
|
9dbb2ef08c | ||
|
|
0e1e513d5a | ||
|
|
588801931f | ||
|
|
e3ad88c784 | ||
|
|
af69f68359 | ||
|
|
3377298b06 | ||
|
|
15b86b3afb | ||
|
|
776497fb6b | ||
|
|
9082b027ef | ||
|
|
bbce72c316 | ||
|
|
d7ba067af6 | ||
|
|
1798abd909 | ||
|
|
4b5f7f0ef6 | ||
|
|
5273e43919 | ||
|
|
316bffd061 | ||
|
|
ba264f8158 | ||
|
|
cf24f7ff7e | ||
|
|
5e29d3a518 | ||
|
|
25ca4c854c | ||
|
|
50449d5c87 | ||
|
|
740243552f | ||
|
|
9f14461cb7 | ||
|
|
194fe2a4a5 | ||
|
|
e300367ad8 | ||
|
|
15b2f1f635 | ||
|
|
47133fda31 | ||
|
|
a0486afb83 | ||
|
|
ad67680ed3 | ||
|
|
93da37619a | ||
|
|
0284bc4b99 | ||
|
|
7f1117a71f | ||
|
|
0004e8a4be | ||
|
|
41c995dd18 | ||
|
|
89dbeddcfc | ||
|
|
6195dd35e0 | ||
|
|
e1b72cf020 | ||
|
|
b1462cd593 | ||
|
|
868fec3692 | ||
|
|
a105455487 | ||
|
|
0882f61a8e | ||
|
|
eff9477388 | ||
|
|
fc6a82fcb8 | ||
|
|
2bc871a62e | ||
|
|
61ce929656 | ||
|
|
67e1c59427 | ||
|
|
3f6896acd3 | ||
|
|
17aeeda774 | ||
|
|
143b73ee7b | ||
|
|
260fcde6e2 | ||
|
|
ce55c480e9 | ||
|
|
5738da5225 | ||
|
|
457f4caf6f | ||
|
|
34347418e3 | ||
|
|
5d9aa86efa | ||
|
|
ff5851c685 | ||
|
|
7976579ef6 | ||
|
|
36f888e06e | ||
|
|
a73524874c | ||
|
|
1c445d44c5 | ||
|
|
a54a0e5ecb | ||
|
|
e0ab451084 | ||
|
|
2310261cbe | ||
|
|
99876da380 | ||
|
|
76a22457ce | ||
|
|
e36ed02083 | ||
|
|
1f506e55d0 | ||
|
|
a80bce7e58 | ||
|
|
4b56cf02f0 | ||
|
|
668f8161ab | ||
|
|
d117f2258f | ||
|
|
1a81758f1c | ||
|
|
655bce9e1f | ||
|
|
9242c5c05e | ||
|
|
adc4fbe921 | ||
|
|
95ef751780 | ||
|
|
e2dd1cc3da | ||
|
|
2dfb2d723f | ||
|
|
1feaac6a54 | ||
|
|
4fc75f6559 | ||
|
|
e37c73ef97 | ||
|
|
3c50e18f46 | ||
|
|
ed443d08cf | ||
|
|
3794c9bfef | ||
|
|
1081dc05c2 | ||
|
|
72ca19339d | ||
|
|
83c46fb83e | ||
|
|
b8190d0e92 | ||
|
|
103034acf2 | ||
|
|
2742f2ca72 | ||
|
|
f222665d1d | ||
|
|
70007e6095 | ||
|
|
694c1c0c9c | ||
|
|
d146b72e53 | ||
|
|
4d1137ded4 | ||
|
|
2293ad0b1f | ||
|
|
f59f077d27 | ||
|
|
28c55ae8e3 | ||
|
|
7254cca9f3 | ||
|
|
50b637d1f9 | ||
|
|
023939d65f | ||
|
|
83a8b6745f | ||
|
|
baeb134536 | ||
|
|
c1b3b1d5b1 | ||
|
|
beae1fb946 | ||
|
|
6b0805633b | ||
|
|
c9d3a81c3a | ||
|
|
dbb7b83ecc | ||
|
|
ed01d3b366 | ||
|
|
88fa72f892 | ||
|
|
1aba1bbca4 | ||
|
|
10c25aa6d9 | ||
|
|
34e400fe2b | ||
|
|
a7818fb1be | ||
|
|
e753e1a460 | ||
|
|
fb80a4a397 | ||
|
|
964565519c | ||
|
|
960c01e4c6 | ||
|
|
87e3b8b2ad | ||
|
|
230eb50e96 | ||
|
|
1bc23d416c | ||
|
|
4b84c43811 | ||
|
|
22243ee9ae | ||
|
|
2d8c703fa0 | ||
|
|
6ead43beb1 | ||
|
|
62eef7c695 | ||
|
|
f2e0152108 | ||
|
|
25b07915d6 | ||
|
|
811f5cff35 | ||
|
|
c00550f3ae | ||
|
|
8ef3b1544b | ||
|
|
3e3642433b | ||
|
|
aff78a98cf | ||
|
|
d2a4408930 | ||
|
|
9740f51d00 | ||
|
|
812b527dd8 | ||
|
|
297e62b8be | ||
|
|
3189e70baa | ||
|
|
dca37d634e | ||
|
|
29718a5001 | ||
|
|
0ce20fea8a | ||
|
|
46b24e8a27 | ||
|
|
66b96f417c | ||
|
|
b974395573 | ||
|
|
1057e70da0 | ||
|
|
1d7c058f08 | ||
|
|
36911830dd | ||
|
|
2fbee61fff | ||
|
|
76adf66390 | ||
|
|
c94e23b2f6 | ||
|
|
28f4e820f7 | ||
|
|
6f9829fa5e | ||
|
|
6d280193d6 | ||
|
|
bb8d1dbb3a | ||
|
|
f1d0d949dc | ||
|
|
efc8c74b9a | ||
|
|
5f2dc3fe14 | ||
|
|
05a87a441c | ||
|
|
9c5c609de2 | ||
|
|
ab3c603b1c | ||
|
|
be1efdbf89 | ||
|
|
960f681dec | ||
|
|
995468ea0a | ||
|
|
ecbd983648 | ||
|
|
2bda857bf7 | ||
|
|
6f3dd86f22 | ||
|
|
cc1da2eb5b | ||
|
|
cc9ffa5ac1 | ||
|
|
9cc62f6461 | ||
|
|
6ac10272bc | ||
|
|
19a080ddd7 | ||
|
|
fdec9012eb | ||
|
|
67c11acbbf | ||
|
|
a5ad1269ef | ||
|
|
958668f001 | ||
|
|
5acaa777b8 | ||
|
|
9bb1b64d48 | ||
|
|
cf0659f7af | ||
|
|
e158ab2fe9 | ||
|
|
5098302f2f | ||
|
|
e8ed258aa4 | ||
|
|
b4a674e0ac | ||
|
|
d4c439c61d | ||
|
|
9c683b7423 | ||
|
|
ca2069a246 | ||
|
|
07a40f5141 | ||
|
|
3b3674807b | ||
|
|
bbaf536f6a | ||
|
|
b50ecc25b2 | ||
|
|
f2ccbc81d9 | ||
|
|
5537e1ad17 | ||
|
|
0e89f839e1 | ||
|
|
131a8c8f53 | ||
|
|
603511ea6f | ||
|
|
ded7dae112 | ||
|
|
8c05e4677e | ||
|
|
73b389da6c | ||
|
|
09eeb42315 | ||
|
|
e05b6242a5 | ||
|
|
c3c38eeeaf | ||
|
|
6cdbd6903c | ||
|
|
503dbb3d8a | ||
|
|
35ca4404f0 | ||
|
|
ee0532702a | ||
|
|
44de97d496 | ||
|
|
9d1e203b3d | ||
|
|
cb59df7bed | ||
|
|
70d5cd0210 | ||
|
|
3c134b6549 | ||
|
|
511816a56d | ||
|
|
3ad6ed3e92 | ||
|
|
9144ad4883 | ||
|
|
00c2c1b70e | ||
|
|
307168cc0f | ||
|
|
58a42e51e2 | ||
|
|
5b34d11ce9 | ||
|
|
1dbc8e3f0e | ||
|
|
3d775d9286 | ||
|
|
faaef0fbe3 | ||
|
|
ff7f09ecc7 | ||
|
|
0a457907fe | ||
|
|
73b62ab0f6 | ||
|
|
0122a3ea08 | ||
|
|
c432265ab7 | ||
|
|
b773853b03 | ||
|
|
3d16691c9e | ||
|
|
770796275d | ||
|
|
a717d81cea | ||
|
|
ec6644c146 | ||
|
|
93fd179b4c | ||
|
|
a3803a3c93 | ||
|
|
489656458f | ||
|
|
30e9661919 | ||
|
|
3e48f862a7 | ||
|
|
722f92e834 | ||
|
|
d106797a26 | ||
|
|
6f9df58afe | ||
|
|
66498eee0b | ||
|
|
1f21ca187a | ||
|
|
c7df3b4b22 | ||
|
|
da010f1600 | ||
|
|
709e526ad9 | ||
|
|
cd788e2ab9 | ||
|
|
01f39a3e51 | ||
|
|
1622c57f07 | ||
|
|
a46999cf0d | ||
|
|
b34020d5a6 | ||
|
|
4f51ef7ab7 | ||
|
|
ec8a80b070 | ||
|
|
5192a1a054 | ||
|
|
7e79c52808 | ||
|
|
314877e155 | ||
|
|
da8f6a9acf | ||
|
|
e5059cb891 | ||
|
|
ebba5fd9af | ||
|
|
e6b464ed23 | ||
|
|
33faf463a0 | ||
|
|
ceb572a280 | ||
|
|
8ace87616e | ||
|
|
ffe885b21f | ||
|
|
b18913b338 | ||
|
|
fd9d8ca43b | ||
|
|
882411586a | ||
|
|
90a331f7a5 | ||
|
|
478474bcb1 | ||
|
|
19064660d2 | ||
|
|
0fe6d16e89 | ||
|
|
7ca96ea7e5 | ||
|
|
5f71712b8b | ||
|
|
6cbc92b760 | ||
|
|
286d0656e2 | ||
|
|
f34b684e0e | ||
|
|
f9226cd9cd | ||
|
|
7596de9ac8 | ||
|
|
5385ca0a0e | ||
|
|
f4b55b802c | ||
|
|
0d048dee56 | ||
|
|
6726488e48 | ||
|
|
3b64c4830f | ||
|
|
add7cf7ded | ||
|
|
6b55f06a23 | ||
|
|
2b5a352840 | ||
|
|
2a3fc7b8ea | ||
|
|
1511750650 | ||
|
|
cce37f8d32 | ||
|
|
69f5623a03 | ||
|
|
7567113e71 | ||
|
|
9c13bd8884 | ||
|
|
30a7162bd9 | ||
|
|
f85d0713cf | ||
|
|
64c9e859e0 | ||
|
|
ed360fcf57 | ||
|
|
c924d1a322 | ||
|
|
ce44c6ec41 | ||
|
|
459fda5e44 | ||
|
|
435e55958f | ||
|
|
0eca3cf384 | ||
|
|
b9604cde6c | ||
|
|
470f226d9d | ||
|
|
8a411edf9f | ||
|
|
243a3df832 | ||
|
|
90778ada6d | ||
|
|
7bf0c1bc45 | ||
|
|
f9aef7098f | ||
|
|
ba078042ba | ||
|
|
3534419f14 | ||
|
|
025ae183eb | ||
|
|
6534f4d668 | ||
|
|
0d9adb7294 | ||
|
|
d851db3cee | ||
|
|
a640df56e6 | ||
|
|
17563e2929 | ||
|
|
12bcd39583 | ||
|
|
e30e0c5135 | ||
|
|
d3f9887589 | ||
|
|
ca493a14e1 | ||
|
|
250c1d2068 | ||
|
|
65c3fe8b33 | ||
|
|
fe9255a816 | ||
|
|
0f3f7eee9a | ||
|
|
22411494aa | ||
|
|
fcf07fce61 | ||
|
|
87e84064d2 | ||
|
|
0134d2cc85 | ||
|
|
c984a64f3e | ||
|
|
f864caba2f | ||
|
|
0709926b82 | ||
|
|
8f86c8409d | ||
|
|
ef89a2709a | ||
|
|
c96b093a58 | ||
|
|
b54d2b2c38 | ||
|
|
50edb67fc4 | ||
|
|
776a66f5db | ||
|
|
8a7f4bcd7a | ||
|
|
8e0f9147b2 | ||
|
|
a84bb950fa | ||
|
|
e9ea9975de | ||
|
|
7a8ec5bea4 | ||
|
|
98533cbccc | ||
|
|
36a13f931a | ||
|
|
295ce9fc8d | ||
|
|
e7f819bed1 | ||
|
|
34e415222e | ||
|
|
d8a6763be4 | ||
|
|
2d232c4c57 | ||
|
|
1487d749fe | ||
|
|
74de37e81e | ||
|
|
ec6d3b535a | ||
|
|
698b0b090b | ||
|
|
a3d9d7b58b | ||
|
|
de51a91db3 | ||
|
|
97dd838cda | ||
|
|
02287658f7 | ||
|
|
083d9c8039 | ||
|
|
5ebb0b8c15 | ||
|
|
64d509a931 | ||
|
|
9cb2272494 | ||
|
|
d3f45d14b3 | ||
|
|
7ed519ba84 | ||
|
|
c512310934 | ||
|
|
e15b5a83d5 | ||
|
|
fec02c20a9 | ||
|
|
63702b9a78 | ||
|
|
a8fb88516a | ||
|
|
694cacc93d | ||
|
|
d2019972f7 | ||
|
|
f2ee5d3a80 | ||
|
|
43d7359221 | ||
|
|
ae07b8ee83 | ||
|
|
fcf76b36aa | ||
|
|
639438836b | ||
|
|
cbd5a0e6bb | ||
|
|
9cb145c44c | ||
|
|
4d7386fc5f | ||
|
|
8f591d1b71 | ||
|
|
e9c65d0c08 | ||
|
|
1b2dc7ef75 | ||
|
|
0f2bcccaba | ||
|
|
6cde9d87a3 | ||
|
|
61ff225f1d | ||
|
|
50edc08001 | ||
|
|
0b2a9dc297 | ||
|
|
f7b250f963 | ||
|
|
78641613c7 | ||
|
|
42034844dc | ||
|
|
d45addcc7a | ||
|
|
df9089d3f8 | ||
|
|
6938bb6109 | ||
|
|
5a2c606d94 | ||
|
|
a3d396b11b | ||
|
|
a1ffc320e4 | ||
|
|
512583709a | ||
|
|
13bca43aa8 | ||
|
|
d0037ea2fd | ||
|
|
6b09ce4336 | ||
|
|
584936aa9b | ||
|
|
672e3e49fb | ||
|
|
1d8f780f45 | ||
|
|
d3bcf405c2 | ||
|
|
426bf55df2 | ||
|
|
1bbf0d2cf6 | ||
|
|
8cfed866d3 | ||
|
|
852422f4ab | ||
|
|
528c513602 | ||
|
|
1cf4ea2eb3 | ||
|
|
70dfab8be0 | ||
|
|
f897350521 | ||
|
|
b5da1073b0 | ||
|
|
dc383a7ee7 | ||
|
|
09e0fc2074 | ||
|
|
940a5deb2e | ||
|
|
aacc5e108b | ||
|
|
1cf0d5ad9d | ||
|
|
9f726fce46 | ||
|
|
d051e2da43 | ||
|
|
94279f00c1 | ||
|
|
ef1f39d29e | ||
|
|
9c7ffa265e | ||
|
|
9cc3adbdd9 | ||
|
|
d42f7886ab | ||
|
|
e2b0f32c18 | ||
|
|
52f13283ea | ||
|
|
7d2624dd3c | ||
|
|
7ae1d61120 | ||
|
|
39c9375eef | ||
|
|
cdb1b1dba3 | ||
|
|
3d61f5f20e | ||
|
|
59859d8cc2 | ||
|
|
b285cd40b2 | ||
|
|
3415434e04 | ||
|
|
36a8fb3e4d | ||
|
|
a925c1b306 | ||
|
|
7f6b9ccb5b | ||
|
|
3cedced29a | ||
|
|
1d53342b18 | ||
|
|
1e87c2aa48 | ||
|
|
fbc5be2426 | ||
|
|
4b02c78aaa | ||
|
|
71e80e5f62 | ||
|
|
8b5bbe4673 | ||
|
|
c89cbd916d | ||
|
|
3c70509e9b | ||
|
|
e1112c64c9 | ||
|
|
8dec8d3632 | ||
|
|
722babe8d1 | ||
|
|
3e9c337946 | ||
|
|
2c0d0d836c | ||
|
|
dbbf64fdd4 | ||
|
|
1ccab64d86 | ||
|
|
4b234476bb | ||
|
|
6ce8fc0b15 | ||
|
|
9fca20acc1 | ||
|
|
eeb2ca5b26 | ||
|
|
4b4c55e328 | ||
|
|
3ee43dd572 | ||
|
|
a222dbe8c7 | ||
|
|
2ff5d7de53 | ||
|
|
c6aaaf438e | ||
|
|
fb0af47761 | ||
|
|
211afe3a4b | ||
|
|
ea1c68b666 | ||
|
|
82bf2663e3 | ||
|
|
638684636c | ||
|
|
3ec7218ffb | ||
|
|
96c7fb890e | ||
|
|
efd7427f33 | ||
|
|
b43c1f054b | ||
|
|
f8b04c4bb6 | ||
|
|
bb8b00dad8 | ||
|
|
8279f0eac5 | ||
|
|
61d1fd9a0e | ||
|
|
4f72330f5c | ||
|
|
3b6c8b3f77 | ||
|
|
a05ef35ca8 | ||
|
|
359430871f | ||
|
|
747a18f65d | ||
|
|
598d7963e5 | ||
|
|
484484ce89 | ||
|
|
6e15f28d6a | ||
|
|
b5d452b1c7 | ||
|
|
b46d67e301 | ||
|
|
3107d6d03b | ||
|
|
67af82457e | ||
|
|
2a16a0a30c | ||
|
|
b19cb95257 | ||
|
|
dc41c40eba | ||
|
|
71eafcf3da | ||
|
|
7555e69cdc | ||
|
|
284a5b3465 | ||
|
|
25d74e0334 | ||
|
|
c1c704c042 | ||
|
|
3f5277d57b | ||
|
|
98b59da9ad | ||
|
|
a8bbe997d2 | ||
|
|
893ed27f5b | ||
|
|
97c5b2b7d7 | ||
|
|
730ca5f9b1 | ||
|
|
7c35f68e29 | ||
|
|
79668f0624 | ||
|
|
4ba3ced42f | ||
|
|
21d31939d1 | ||
|
|
68e767078f | ||
|
|
ff9621e279 | ||
|
|
de20d2a179 | ||
|
|
6fb5ebfedb | ||
|
|
7132570353 | ||
|
|
92f6d077fd | ||
|
|
1498cc552f | ||
|
|
32bde5b009 | ||
|
|
af6016cfd0 | ||
|
|
f3d440a16f | ||
|
|
47b6495e9b | ||
|
|
7192fbfae7 | ||
|
|
be59053650 | ||
|
|
c36ec4f9d7 | ||
|
|
5191a04055 | ||
|
|
9ef542b3cb | ||
|
|
2414aeb4dd | ||
|
|
cd8bc46a15 | ||
|
|
b79b6aba5d | ||
|
|
fa308aa83b | ||
|
|
b90a103e22 | ||
|
|
0ddcb1f666 | ||
|
|
785ac43c84 | ||
|
|
7075b58ee1 | ||
|
|
a386f01a7c | ||
|
|
ce9e964c5f | ||
|
|
2524d2c413 | ||
|
|
687b0ebe6e | ||
|
|
8c232e1dbb | ||
|
|
bc2a510fb7 | ||
|
|
130c64e5d9 | ||
|
|
264bfb7121 | ||
|
|
d3b2cb19e4 | ||
|
|
e7ecf6accb | ||
|
|
4c06525432 | ||
|
|
bf5d593e71 | ||
|
|
29b7818ebf | ||
|
|
ce88c6dd08 | ||
|
|
1b05e77127 | ||
|
|
726d3cba43 | ||
|
|
b690dc13aa | ||
|
|
b0d28cedf7 | ||
|
|
b3f94c4c00 | ||
|
|
0753ca66ab | ||
|
|
e02fae664a | ||
|
|
2a75bbb711 | ||
|
|
9223055df1 | ||
|
|
4b0d26c93d | ||
|
|
0e90480d6b | ||
|
|
c30ff0935d | ||
|
|
200ae67551 | ||
|
|
89c55fe46c | ||
|
|
f997f9f139 | ||
|
|
0852f5a930 | ||
|
|
9e83daa3bb | ||
|
|
ea92b714f2 | ||
|
|
aa2bdcc078 | ||
|
|
7989800674 | ||
|
|
9d8952f3a8 | ||
|
|
51f004494a | ||
|
|
044aa4fa60 | ||
|
|
17e2416f68 | ||
|
|
8750f1c05f | ||
|
|
afab3c4151 | ||
|
|
3a2f0750cb | ||
|
|
4efa995ae1 | ||
|
|
f1330f7efd | ||
|
|
1e8ea5eece | ||
|
|
12a8e15227 | ||
|
|
a082f8d8c7 | ||
|
|
39c60235f8 | ||
|
|
f12928f700 | ||
|
|
8812409528 | ||
|
|
6406e07a79 | ||
|
|
6741234ec9 | ||
|
|
c0ef6a5d1b | ||
|
|
18b3da6bab | ||
|
|
fac46c078a | ||
|
|
21832436ec | ||
|
|
6c6bd28308 | ||
|
|
d298a73aab | ||
|
|
f82797006f | ||
|
|
6f0d8022d1 | ||
|
|
3edb8bfc21 | ||
|
|
f986561b62 | ||
|
|
d971478d75 | ||
|
|
b1718d715e | ||
|
|
674d81ce27 | ||
|
|
0d5dcf7358 | ||
|
|
653b86fa48 | ||
|
|
3461b2f5bb | ||
|
|
f2b52d46d0 | ||
|
|
d9359f8249 | ||
|
|
146469ab19 | ||
|
|
fa4ed416c7 | ||
|
|
7f2e23bb50 | ||
|
|
d97cc460b0 | ||
|
|
2bc6301e39 | ||
|
|
c07a37b91d | ||
|
|
94f3b5751a | ||
|
|
e42e998f76 | ||
|
|
5bf9b86aa4 | ||
|
|
1b37f94737 | ||
|
|
82a2a8b7eb | ||
|
|
359160d8a1 | ||
|
|
a1d8701369 | ||
|
|
b4ea3725da | ||
|
|
595049117c | ||
|
|
a51ca42b18 | ||
|
|
fa7454688b | ||
|
|
657056b114 | ||
|
|
16d9e65b32 | ||
|
|
9e21bc74ac | ||
|
|
0a103544e4 | ||
|
|
80904fddcf | ||
|
|
550785ba29 | ||
|
|
1f691912e1 | ||
|
|
bff0a94507 | ||
|
|
806bb3c63f | ||
|
|
534e78b372 | ||
|
|
4653b4bb79 | ||
|
|
e67f8a50f9 | ||
|
|
d260293f62 | ||
|
|
22b56f13cc | ||
|
|
6d799e9ff8 | ||
|
|
e141e7311c | ||
|
|
96e3d08787 | ||
|
|
b82aa22442 | ||
|
|
9d5fe279b6 | ||
|
|
231dbeea61 | ||
|
|
40ec19961c | ||
|
|
4cd13f4ebf | ||
|
|
5fafcdd73c | ||
|
|
7409bc052d | ||
|
|
8f73da1f79 | ||
|
|
4de0a2e30e | ||
|
|
32a11a2b20 | ||
|
|
a9d042db2c | ||
|
|
4160dfa6e1 | ||
|
|
b32c690175 | ||
|
|
064d7ffdb2 | ||
|
|
6a73e70663 | ||
|
|
5f68a5f70d | ||
|
|
ade75fecae | ||
|
|
43d758e630 | ||
|
|
0f111e2d3a | ||
|
|
a232d8e060 | ||
|
|
cf854246fa | ||
|
|
548d6bb6c0 | ||
|
|
6a0bc27b35 | ||
|
|
a303a83b92 | ||
|
|
e8c21dfe67 | ||
|
|
3439c08170 | ||
|
|
133748f004 | ||
|
|
35f3f86df4 | ||
|
|
462cfbe8ae | ||
|
|
38198d8cb3 | ||
|
|
500ebad7aa | ||
|
|
6de8d14b29 | ||
|
|
853ead07d4 | ||
|
|
8bfe5e86b4 | ||
|
|
ff976ce055 | ||
|
|
96abbad91d | ||
|
|
6023b736d9 | ||
|
|
066212158e | ||
|
|
2a9044d607 | ||
|
|
23eaf5c442 | ||
|
|
39a358ef56 | ||
|
|
f62061aa78 | ||
|
|
406e4283fd | ||
|
|
1f33e8b807 | ||
|
|
a23c89dd75 | ||
|
|
d1cb6a3aa9 | ||
|
|
d53b0d0643 | ||
|
|
a06b48ccc6 | ||
|
|
c278f09897 | ||
|
|
e08247218e | ||
|
|
84cbebcf17 | ||
|
|
d03dbf91a6 | ||
|
|
90594b5fc8 | ||
|
|
de6910a6b6 | ||
|
|
ce8778c01b | ||
|
|
6724dd1597 | ||
|
|
79500cdb9f | ||
|
|
0b8234edb4 | ||
|
|
b2a648b4da | ||
|
|
48496a930c | ||
|
|
43e312bd62 | ||
|
|
fb96473eb0 | ||
|
|
89c76a80f2 | ||
|
|
f285c61830 | ||
|
|
cc894e6100 | ||
|
|
e2ecedfa70 | ||
|
|
a1c6ac945d | ||
|
|
509e9a4d4e | ||
|
|
c28a51899f | ||
|
|
9028579d84 | ||
|
|
2cbef73a27 | ||
|
|
dbe3dea363 | ||
|
|
df987c2086 | ||
|
|
2655e5c7b9 | ||
|
|
52be37dd37 | ||
|
|
8a6dc0d0b4 | ||
|
|
7907a37002 | ||
|
|
4b26ec2372 | ||
|
|
2a31c91136 | ||
|
|
f49d75994e | ||
|
|
864fe70e35 | ||
|
|
98391c1324 | ||
|
|
e83acf8658 | ||
|
|
bac2215fb6 | ||
|
|
7cdb6d36f4 | ||
|
|
2671e3d9bb | ||
|
|
29571cfcb1 | ||
|
|
260072954e | ||
|
|
077975cba7 | ||
|
|
e1df8c9082 | ||
|
|
02f99cb631 | ||
|
|
ae4adad5c4 | ||
|
|
cf4825233d | ||
|
|
82e18770bc | ||
|
|
0dd66bd2e9 | ||
|
|
8baa1ed52e | ||
|
|
ba3b53d64a | ||
|
|
02858c574c | ||
|
|
1e4b334321 | ||
|
|
9a7374faf0 | ||
|
|
3f69c1b62d | ||
|
|
4bef006566 | ||
|
|
860f35a7ab | ||
|
|
9bd6034f9b | ||
|
|
694058ccb1 | ||
|
|
78602e0966 | ||
|
|
1a225306f8 | ||
|
|
2c9585e9f6 | ||
|
|
bc06fe3b51 | ||
|
|
5bb289262e | ||
|
|
8c339b9d63 | ||
|
|
904027f25f | ||
|
|
0068b8c823 | ||
|
|
d3ab1d50b5 | ||
|
|
9c2f131b66 | ||
|
|
1e3c163233 | ||
|
|
28d980de3d | ||
|
|
e2dddf3532 | ||
|
|
12934e17e6 | ||
|
|
87f28fa6dd | ||
|
|
83344af1c2 | ||
|
|
c7f703c476 | ||
|
|
48748b8f9a | ||
|
|
c33c9283f1 | ||
|
|
0cadef62c1 | ||
|
|
fc7311e94c | ||
|
|
068fd1d839 | ||
|
|
81cf763a97 | ||
|
|
2ad3e1428d | ||
|
|
9286665be5 | ||
|
|
c7f175309d | ||
|
|
917f50e737 | ||
|
|
15ba1fe530 | ||
|
|
ccf510188f | ||
|
|
eb97ef73fa | ||
|
|
8dbbc0e72b | ||
|
|
695422d698 | ||
|
|
c0eb1e6bfe | ||
|
|
32e131862d | ||
|
|
1c838758c3 | ||
|
|
f5c3a23a75 | ||
|
|
cf036062c4 | ||
|
|
c5deb0a325 | ||
|
|
aa4f316c14 | ||
|
|
b53e81786a | ||
|
|
80f23eb97d | ||
|
|
e7f46a4251 | ||
|
|
39f0e4b207 | ||
|
|
1b3e733e1c | ||
|
|
78e57f29bc | ||
|
|
1d02548e4a | ||
|
|
2078c0d1bf | ||
|
|
662e7238ef | ||
|
|
8face6c67c | ||
|
|
f2bb840936 | ||
|
|
01d62f822d | ||
|
|
0efa5c562a | ||
|
|
785da17231 | ||
|
|
a9b3a77cda | ||
|
|
e60848a65f | ||
|
|
1455d0211b | ||
|
|
1499f1e480 | ||
|
|
dbe6828978 | ||
|
|
4fa609e2be | ||
|
|
8d80f9c624 | ||
|
|
e26d9ae75e | ||
|
|
92aba71fb5 | ||
|
|
4393076c6c | ||
|
|
6a6814379f | ||
|
|
c23ffc045d | ||
|
|
8abe6ccb64 | ||
|
|
4718c784af | ||
|
|
616e31f795 | ||
|
|
dd96991005 | ||
|
|
fa0c31b864 | ||
|
|
a7154d73fe | ||
|
|
de08da1003 | ||
|
|
c6fb650a62 | ||
|
|
821643f30b | ||
|
|
3d40b1c03f | ||
|
|
e993855421 | ||
|
|
8a8b2d0684 | ||
|
|
94fe1c8b26 | ||
|
|
5f23eba1b0 | ||
|
|
036cb819d6 | ||
|
|
94da5ac1e8 | ||
|
|
e2db31c94b | ||
|
|
de6d4f266e | ||
|
|
69c84b4c28 | ||
|
|
c44e6130cc | ||
|
|
81b1cb9caa | ||
|
|
3f0a3cc6c0 | ||
|
|
cf41cc2ec2 | ||
|
|
b3ab1cbe73 | ||
|
|
1c60de9c6b | ||
|
|
929f24602e | ||
|
|
508cb3d34a | ||
|
|
a4cc03ffd9 | ||
|
|
74aea6680a | ||
|
|
35a1ef8198 | ||
|
|
3b4935ad97 | ||
|
|
7f2fdcc2bf | ||
|
|
8fb24677a4 | ||
|
|
337d7f6884 | ||
|
|
54478c3a0a | ||
|
|
00fff0dbc1 | ||
|
|
e46d9edc98 | ||
|
|
e88fdae17d | ||
|
|
b3d1d22317 | ||
|
|
3817133d4f | ||
|
|
dade45942c | ||
|
|
057f297bfd | ||
|
|
40bd0e0ec1 | ||
|
|
51bac49a91 | ||
|
|
9e980fde5f | ||
|
|
d181abbab8 | ||
|
|
b1488a63ef | ||
|
|
b9d9f86770 | ||
|
|
9c1844a927 | ||
|
|
4f9f4c44d1 | ||
|
|
4a558d611b | ||
|
|
226ec5bd25 | ||
|
|
3340239733 | ||
|
|
c5dcbb9901 | ||
|
|
8c83933000 | ||
|
|
8298664e1c | ||
|
|
0f4379d111 | ||
|
|
4231743209 | ||
|
|
64bd104b64 | ||
|
|
93567dffb6 | ||
|
|
dcbd70fc54 | ||
|
|
2786bc27be | ||
|
|
3db5846f8f | ||
|
|
424b4be5c6 | ||
|
|
aa03b29d77 | ||
|
|
d4af3ee3b6 | ||
|
|
7a39517c94 | ||
|
|
c060d39cca | ||
|
|
a39f993cd4 | ||
|
|
9e1bae7bad | ||
|
|
d319206566 | ||
|
|
5273ddbbdd | ||
|
|
8a731e502d | ||
|
|
b103bfdb8b | ||
|
|
0c6adc08fc | ||
|
|
e08cce6b6b | ||
|
|
92f261cf3b | ||
|
|
171865492f | ||
|
|
ee342cc3b8 | ||
|
|
5520872def | ||
|
|
00f8683fc0 | ||
|
|
cf6a85ba65 | ||
|
|
adb41a5685 | ||
|
|
8fa4149a37 | ||
|
|
fcfd867c25 | ||
|
|
b9bd0c6fe1 | ||
|
|
50fe0ee0b3 | ||
|
|
5d6c0a66b4 | ||
|
|
f582495d75 | ||
|
|
071ea96fbd | ||
|
|
248350a9a5 | ||
|
|
b0649afc37 | ||
|
|
b7e53c695f | ||
|
|
3a5f932648 | ||
|
|
673814eac5 | ||
|
|
f102ce6f26 | ||
|
|
c26e3b15ac | ||
|
|
6b5c11548e | ||
|
|
1e3bd03b92 | ||
|
|
f6d7d4d020 | ||
|
|
2eaddaca67 | ||
|
|
06d2506544 | ||
|
|
9e3c926730 | ||
|
|
275f0ed037 | ||
|
|
da6648f3c9 | ||
|
|
9b960f3555 | ||
|
|
ed72e0e169 | ||
|
|
389d089ecc | ||
|
|
459d19823e | ||
|
|
68d2aa2491 | ||
|
|
91f3a18d33 | ||
|
|
718d215046 | ||
|
|
4042e0f832 | ||
|
|
365bacfea6 | ||
|
|
3ccb9c1c31 | ||
|
|
3135a5e01f | ||
|
|
168242c841 | ||
|
|
f020200c2c | ||
|
|
c54405c270 | ||
|
|
9c116b4d4d | ||
|
|
be056ad723 | ||
|
|
1a0797e6bd | ||
|
|
02196c2c68 | ||
|
|
6ae49b9ccd | ||
|
|
548860bce0 | ||
|
|
e8622a660a | ||
|
|
564c1c8fa7 | ||
|
|
6b6ff098eb | ||
|
|
3f0477868a | ||
|
|
5bd726380c | ||
|
|
2e3400f899 | ||
|
|
81fd2f29de | ||
|
|
571c8be2de | ||
|
|
861ed9a339 | ||
|
|
0cd9e10d2d | ||
|
|
5a0ef67644 | ||
|
|
2d8a1765eb | ||
|
|
d06dcc74b4 | ||
|
|
d3c388db9c | ||
|
|
5fc7f417da | ||
|
|
ce44ad5019 | ||
|
|
d9de4806b0 | ||
|
|
6f21ad6d86 | ||
|
|
12186e981c | ||
|
|
d86261dc2b | ||
|
|
0448f34aff | ||
|
|
22b3dd8c17 | ||
|
|
3470e79f83 | ||
|
|
772b6b66b1 | ||
|
|
3eef7bf9ab | ||
|
|
452b07a6c2 | ||
|
|
efc9862836 | ||
|
|
73f26fd3b9 | ||
|
|
ee480fecae | ||
|
|
b4141f7e91 | ||
|
|
d1641a7cd0 | ||
|
|
b0fe498112 | ||
|
|
e7d8b197f3 | ||
|
|
f0774e7a6c | ||
|
|
9697652c0a | ||
|
|
c3b8ab76a5 | ||
|
|
19b7e41fda | ||
|
|
d4b69a2f24 | ||
|
|
d0a7e585d7 | ||
|
|
152eeec7a7 | ||
|
|
9be31cd944 | ||
|
|
58c1a92bc4 | ||
|
|
148edfcf26 | ||
|
|
b7bd21bc0a | ||
|
|
e9186caa33 | ||
|
|
8abff30849 | ||
|
|
5dc45a0046 | ||
|
|
91ef46755f | ||
|
|
a8d8f70335 | ||
|
|
ecc015889c | ||
|
|
3827fbc302 | ||
|
|
5bc570d449 | ||
|
|
f1676593d0 | ||
|
|
ddf7bc57d3 | ||
|
|
d2b596f108 | ||
|
|
d3bf33f9aa | ||
|
|
ef6973087b | ||
|
|
0ae915c0f6 | ||
|
|
f96c0762ff | ||
|
|
9e996ceef8 | ||
|
|
83c63206c1 | ||
|
|
fd0c9f6c2d | ||
|
|
a2418cd15d | ||
|
|
40b77a4661 | ||
|
|
60d1f9cf45 | ||
|
|
a41fc6bbf9 | ||
|
|
fb3d6a049f | ||
|
|
8b557dfd30 | ||
|
|
843ae2cc2c | ||
|
|
6fb9ea4ea5 | ||
|
|
1a603dd365 | ||
|
|
25ebd8de49 | ||
|
|
41d9f563a8 | ||
|
|
1540cd05a9 | ||
|
|
c3b80c117f | ||
|
|
5dd1310ac6 | ||
|
|
2f69b332d8 | ||
|
|
23cfe10d94 | ||
|
|
72e21db66a | ||
|
|
b3af980c46 | ||
|
|
a5e6cf5003 | ||
|
|
64e4031fb7 | ||
|
|
a91dc75020 | ||
|
|
7a714fa8c3 | ||
|
|
2b30f6aa04 | ||
|
|
1451a407ac | ||
|
|
0f2bdc6d0a | ||
|
|
2fe1bc2e71 | ||
|
|
368377375d | ||
|
|
64d595c1c0 | ||
|
|
cb161e634c | ||
|
|
3e6c5132de | ||
|
|
e8a355e872 | ||
|
|
eab0dfc66b | ||
|
|
d94279554c | ||
|
|
9270beada5 | ||
|
|
37f1885152 | ||
|
|
7e38be5470 | ||
|
|
09573266da | ||
|
|
fac7eaffa9 | ||
|
|
26411c1021 | ||
|
|
da34cf8fd6 | ||
|
|
bbbf123fcf | ||
|
|
3d776a2da2 | ||
|
|
6b45687df2 | ||
|
|
af19291e01 | ||
|
|
1740f71793 | ||
|
|
4518e7d1f0 | ||
|
|
1525d7f901 | ||
|
|
8f276e00c5 | ||
|
|
3171dea6ef | ||
|
|
5b13ea0278 | ||
|
|
08c7c4be31 | ||
|
|
b3e9086d5d | ||
|
|
dec9f318a8 | ||
|
|
e6e73e7c94 | ||
|
|
b497faff84 | ||
|
|
3526997670 | ||
|
|
f42b2aaeef | ||
|
|
8a4d7dd913 | ||
|
|
9b97ea8983 | ||
|
|
4468124abd | ||
|
|
e1f471f89c | ||
|
|
9ccfcb3d24 | ||
|
|
efc61fe709 | ||
|
|
7d74bcd7bc | ||
|
|
37f33c4346 | ||
|
|
d4fe6cf255 | ||
|
|
6a7ddeb222 | ||
|
|
d6d3585c03 | ||
|
|
e45e601c35 | ||
|
|
f367a8bd33 | ||
|
|
343b784d6c | ||
|
|
66d2f2de66 | ||
|
|
8b7dd0193e | ||
|
|
ca1504db04 | ||
|
|
3cfe7e6e25 | ||
|
|
55beaa4d47 | ||
|
|
541568fbb6 | ||
|
|
171b29fd4c | ||
|
|
2154f62f51 | ||
|
|
73b98c7500 | ||
|
|
250e28aaf4 | ||
|
|
143b3de606 | ||
|
|
e0544c3eb5 | ||
|
|
d547cbee4e | ||
|
|
aa68c67537 | ||
|
|
1d08a35f18 | ||
|
|
967871d4b8 | ||
|
|
d4c9f37994 | ||
|
|
bfb27d0836 | ||
|
|
dc17a4c1c8 | ||
|
|
e6e02ac002 | ||
|
|
6d32c64100 | ||
|
|
50a4441a6f | ||
|
|
d31be07a25 | ||
|
|
669e957291 | ||
|
|
8bcee712e0 | ||
|
|
e09ed4f612 | ||
|
|
54ae8fcd9e | ||
|
|
502e18c0d0 | ||
|
|
cd0e1c9780 | ||
|
|
a16e5d577c | ||
|
|
626d85b1bd | ||
|
|
1ceb43f77f | ||
|
|
69bef6678a | ||
|
|
e30e685ee1 | ||
|
|
bb2bb1d083 | ||
|
|
3d4c7fd9dd | ||
|
|
02121840c1 | ||
|
|
6da153e69c | ||
|
|
e406f72564 | ||
|
|
538dec2390 | ||
|
|
dae1a4e6df | ||
|
|
e3b0a66805 | ||
|
|
6f9da41a6c | ||
|
|
2850b4962f | ||
|
|
265d0a060c | ||
|
|
6f6ff1a673 | ||
|
|
ae77308b3f | ||
|
|
ada8ccbb14 | ||
|
|
e7626bb3ce | ||
|
|
f6c230ebcb | ||
|
|
64c02a2174 | ||
|
|
5f0e314fe5 | ||
|
|
9d244cb4ce | ||
|
|
fe98390fe0 | ||
|
|
d886e2a557 | ||
|
|
acf41ac2df | ||
|
|
c71d9d53ff | ||
|
|
08b0a2e4e2 | ||
|
|
dbb09a65fe | ||
|
|
484e1fae4e | ||
|
|
4195115d60 | ||
|
|
d21c6b7c13 | ||
|
|
270c8e3746 | ||
|
|
38ea72559b | ||
|
|
9d2c55e62a | ||
|
|
6955b7cda1 | ||
|
|
3a3722eb90 | ||
|
|
078022fa64 | ||
|
|
f7b3b78414 | ||
|
|
a2303e3d0f | ||
|
|
5865f43a79 | ||
|
|
027d5bbf30 | ||
|
|
f6e02bc306 | ||
|
|
5904fc0ed0 | ||
|
|
ec06e092ff | ||
|
|
ccb2b96262 | ||
|
|
9175d0a1ee | ||
|
|
d3850ae0e7 | ||
|
|
795767ee49 | ||
|
|
b0f482d9b3 | ||
|
|
d48b05d8ab | ||
|
|
9f110a3b81 | ||
|
|
f4cafc5041 | ||
|
|
f305473af5 | ||
|
|
a8e01c95f8 | ||
|
|
81339d3c3c | ||
|
|
6cd4d3c008 | ||
|
|
2705394aeb | ||
|
|
47b3c0ec82 | ||
|
|
fe46a4c9d3 | ||
|
|
994d37c441 | ||
|
|
f391225968 | ||
|
|
f518e71f76 | ||
|
|
f70f05ca35 | ||
|
|
952faabb04 | ||
|
|
b5ec8ef1d9 | ||
|
|
98166ff081 | ||
|
|
019d707dc2 | ||
|
|
d7df92d71b | ||
|
|
89aadcec48 | ||
|
|
2768a55b02 | ||
|
|
d387ca7779 | ||
|
|
fa45f2e6ba | ||
|
|
e255fe1685 | ||
|
|
1e95c3a4ac | ||
|
|
7ec16a6af7 | ||
|
|
0c5ee9486b | ||
|
|
4d5b31e943 | ||
|
|
8284ea8b46 | ||
|
|
ec8d4cfdcc | ||
|
|
840e27bd41 | ||
|
|
0827fe8bc1 | ||
|
|
da93b54687 | ||
|
|
0519fde656 | ||
|
|
71dd98a22e | ||
|
|
0de223a1ee | ||
|
|
251e70953e | ||
|
|
3d994d0b6c | ||
|
|
6e445e39a1 | ||
|
|
c420eb06ea | ||
|
|
4ce283ff18 | ||
|
|
cd5bbf0f35 | ||
|
|
5d32badfee | ||
|
|
a1d9de0613 | ||
|
|
bc7b8ef41e | ||
|
|
a40f00bee9 | ||
|
|
4d0e046a06 | ||
|
|
e425ba6c0e | ||
|
|
77003fea94 | ||
|
|
b5bcecce5d | ||
|
|
c6569f5177 | ||
|
|
37ff334508 | ||
|
|
765bc4a66c | ||
|
|
67d2608db9 | ||
|
|
9e7084c024 | ||
|
|
8cd853a1c8 | ||
|
|
dd5a2c44a5 | ||
|
|
a1fe10de33 | ||
|
|
7d4e0b32e1 | ||
|
|
85bf34eb5e | ||
|
|
d9d8746b06 | ||
|
|
adb1122f72 | ||
|
|
ada63fbb4f | ||
|
|
c5efc24b53 | ||
|
|
ff6e7df51a | ||
|
|
a6b382fa40 | ||
|
|
8ea87da749 | ||
|
|
46c8f9282e | ||
|
|
df3bb5d4ef | ||
|
|
524c10a4c5 | ||
|
|
82d87fe9cc | ||
|
|
5e25770a83 | ||
|
|
de28fa60cf | ||
|
|
1692747009 | ||
|
|
bc69cfe5a4 | ||
|
|
c0d8f10a42 | ||
|
|
20760f83da | ||
|
|
13b7b73b08 | ||
|
|
d5b54e4b7f | ||
|
|
084ce330ff | ||
|
|
f59f259586 | ||
|
|
a32f02162b | ||
|
|
aada3ee156 | ||
|
|
2bf8b38383 | ||
|
|
a10a120c99 | ||
|
|
274ce67572 | ||
|
|
6615fcee6e | ||
|
|
c8a93d08eb | ||
|
|
1682b2ced8 | ||
|
|
4966cfa119 | ||
|
|
f537e2e0ec | ||
|
|
7198e00097 | ||
|
|
1b19a2b1de | ||
|
|
ea4aeb0c67 | ||
|
|
55637d3de5 | ||
|
|
0f007abd86 | ||
|
|
4e1fa1bbb9 | ||
|
|
d86015f6b7 | ||
|
|
ceb8d1ccb8 | ||
|
|
daf8899e5c | ||
|
|
dd96bea16c | ||
|
|
9efec3dff4 | ||
|
|
285d3a4497 | ||
|
|
1343c2638c | ||
|
|
07e971e7c2 | ||
|
|
f5a68e9839 | ||
|
|
9cb95aad26 | ||
|
|
a5e6d130fd | ||
|
|
d79518ec0e | ||
|
|
357e60ffdc | ||
|
|
f7f5b56b0a | ||
|
|
e4b8d32001 | ||
|
|
3892a7162a | ||
|
|
03e8e4a18e | ||
|
|
3b49a87972 | ||
|
|
b016beaeb1 | ||
|
|
b239d0de27 | ||
|
|
c0dde4ac5b | ||
|
|
cacfd42960 | ||
|
|
8cd100de39 | ||
|
|
16ae57d222 | ||
|
|
9e68716e0e | ||
|
|
d3e0c54f7d | ||
|
|
80f05b38b0 | ||
|
|
694d3435e1 | ||
|
|
7db0e60486 | ||
|
|
19ef8e56ef | ||
|
|
740e8469da | ||
|
|
3bbf429ac0 | ||
|
|
b9643771af | ||
|
|
b64094d528 | ||
|
|
a97186b2f1 | ||
|
|
50ecdfc27e | ||
|
|
a2126b635f | ||
|
|
229f4abf93 | ||
|
|
4fe5b6f516 | ||
|
|
0bf4bf3f54 | ||
|
|
7bf42218fe | ||
|
|
f1c0d4683b | ||
|
|
f02ca8f2e9 | ||
|
|
a2c9772f3c | ||
|
|
df0c9bee94 | ||
|
|
f6c0dd8c4d | ||
|
|
55e664cb00 | ||
|
|
78b6e77a95 | ||
|
|
d3369ceb9b | ||
|
|
7d1dd00794 | ||
|
|
eca42807c3 | ||
|
|
78be0c2b5c | ||
|
|
4b08d2b86c | ||
|
|
cb4fccfd5d | ||
|
|
249eef49d6 | ||
|
|
372bb483c5 | ||
|
|
41cafc5042 | ||
|
|
b455108961 | ||
|
|
43ad5e5129 | ||
|
|
0399d007f3 | ||
|
|
d48612ee3d | ||
|
|
b14e6b526b | ||
|
|
55512a7328 | ||
|
|
8d4b8f164c | ||
|
|
02fa2dab28 | ||
|
|
c6d3583e08 | ||
|
|
9eb75e0e3e | ||
|
|
c514e681e7 | ||
|
|
be64ea63b1 | ||
|
|
153c3c3f99 | ||
|
|
45f21ff66b | ||
|
|
83e9734908 | ||
|
|
9a49c07cf3 | ||
|
|
273e1b07d6 | ||
|
|
403f27e5b9 | ||
|
|
cfe24ba7e9 | ||
|
|
b54c5c7561 | ||
|
|
29d2a6d9d2 | ||
|
|
c545cd3cf7 | ||
|
|
a83662beda | ||
|
|
7c59caf852 | ||
|
|
27787e21ec | ||
|
|
27294b83d2 | ||
|
|
a2ee614628 | ||
|
|
dc3d7eb38c | ||
|
|
b0500e1945 | ||
|
|
320a52e5f5 | ||
|
|
f2e2b29c3c | ||
|
|
4ac2cab962 | ||
|
|
6dfc67d078 | ||
|
|
7af5d948da | ||
|
|
0644267b41 | ||
|
|
90f6d836ee | ||
|
|
233591ddc5 | ||
|
|
a2894c1114 | ||
|
|
4e13099add | ||
|
|
d77b1791d8 | ||
|
|
79ecd05a02 | ||
|
|
6be8c6b6bf | ||
|
|
d6f33f273d | ||
|
|
26fdbec56f | ||
|
|
02222bc6c1 | ||
|
|
c3174c0319 | ||
|
|
c165196f71 | ||
|
|
a4c9fa34d9 | ||
|
|
d28bc810a3 | ||
|
|
d6ba77a74b | ||
|
|
b745ba8380 | ||
|
|
00b83639fd | ||
|
|
c1c5fcd426 | ||
|
|
56f915e783 | ||
|
|
c511b967ed | ||
|
|
faeb2e28f2 | ||
|
|
fd4bc1398d | ||
|
|
86278dfb1f | ||
|
|
3bd044c236 | ||
|
|
5a894711eb | ||
|
|
4828759ab8 | ||
|
|
3672619e13 | ||
|
|
78ef0d0ebe | ||
|
|
884381d54d | ||
|
|
08079c6863 | ||
|
|
ac19ba51bd | ||
|
|
c874416036 | ||
|
|
69d2a4917c | ||
|
|
76b99bb025 | ||
|
|
14dd5077a9 | ||
|
|
441be8c4d7 | ||
|
|
979dc97f36 | ||
|
|
479a67e629 | ||
|
|
1e19f72077 | ||
|
|
541a3eb0b1 | ||
|
|
328897248a | ||
|
|
059b57438b | ||
|
|
ebae0a11be | ||
|
|
7b8a61c9a7 | ||
|
|
8785c02365 | ||
|
|
d488a8c522 | ||
|
|
d4c55fbdb5 | ||
|
|
6e8a074912 | ||
|
|
fb1c18e6fd | ||
|
|
c80158ce30 | ||
|
|
687a0e76b5 | ||
|
|
e42d5a20fd | ||
|
|
ef1632a591 | ||
|
|
bb0fba0974 | ||
|
|
9c12f6b550 | ||
|
|
9f1fc03a58 | ||
|
|
d104c1d73d | ||
|
|
28ade8e879 | ||
|
|
4974960882 | ||
|
|
c0f4fbf6ad | ||
|
|
6d2e62cda0 | ||
|
|
204f6c2f0c | ||
|
|
52c2755347 | ||
|
|
884c178142 | ||
|
|
f12366ffc7 | ||
|
|
6d3f2dbae3 | ||
|
|
7893c6b188 | ||
|
|
d855c2855a | ||
|
|
193f6631be | ||
|
|
03373895c2 | ||
|
|
43fdbc4b63 | ||
|
|
c22a72fc65 | ||
|
|
a44c2e4636 | ||
|
|
b12730866a | ||
|
|
0faa3c1baf | ||
|
|
79a5692764 | ||
|
|
2fbf9c9e16 | ||
|
|
f14004abfd | ||
|
|
3ee27a8a89 | ||
|
|
01882fa17e | ||
|
|
c6d42e9779 | ||
|
|
77a6aa9327 | ||
|
|
c3882de991 | ||
|
|
e46cb9d09a | ||
|
|
e5732d1743 | ||
|
|
00f701aa87 | ||
|
|
771c1e867f | ||
|
|
a257ce71d1 | ||
|
|
01f66003a4 | ||
|
|
578b394236 | ||
|
|
e46cefeb4b | ||
|
|
aaf83cc86f | ||
|
|
1434714b58 | ||
|
|
44e6a8619e | ||
|
|
e89a2bcd5c | ||
|
|
822d556924 | ||
|
|
194998be61 | ||
|
|
0857d4255d | ||
|
|
174af33085 | ||
|
|
4f944c0e3d | ||
|
|
eeceb89d31 | ||
|
|
5c19df841a | ||
|
|
6c1f176438 | ||
|
|
1d7e348b8f | ||
|
|
dcb9b8f9a2 | ||
|
|
2d9561427e | ||
|
|
f148fe7e4f | ||
|
|
2dd53c0bba | ||
|
|
384072d44c | ||
|
|
730d7655c7 | ||
|
|
d6cfcc994d | ||
|
|
8d4afb9c19 | ||
|
|
4c1686f194 | ||
|
|
5a25985a00 | ||
|
|
1f628fe5f9 | ||
|
|
6b8998b8ec | ||
|
|
bc46ece67f | ||
|
|
438ed9e5f8 | ||
|
|
46059b0714 | ||
|
|
ddb5ae08e8 | ||
|
|
2421bea611 | ||
|
|
7d8d7837b4 | ||
|
|
aa7997427a | ||
|
|
f3b5e16672 | ||
|
|
783fddaede | ||
|
|
3f2e9d2e0d | ||
|
|
436f02d38a | ||
|
|
4b1baccb2e | ||
|
|
51895a907e | ||
|
|
a869aae156 | ||
|
|
2cedb10fa7 | ||
|
|
202f44e45a | ||
|
|
7c7806d768 | ||
|
|
b79a237186 | ||
|
|
e280cb5f96 | ||
|
|
63373352e5 | ||
|
|
eb22964898 | ||
|
|
913a5331b7 | ||
|
|
f50b20df7a | ||
|
|
eefb17607c | ||
|
|
b938de4ea7 | ||
|
|
312760c381 | ||
|
|
55d8ae6caa | ||
|
|
704f806df6 | ||
|
|
789a8be699 | ||
|
|
326456653b | ||
|
|
52095246a6 | ||
|
|
e492a6ef88 | ||
|
|
d3bdd36e46 | ||
|
|
f148cc891b | ||
|
|
2eda7699de | ||
|
|
04ca3568cb | ||
|
|
fa073b7330 | ||
|
|
1ab3f636cc | ||
|
|
caffbd564d | ||
|
|
a66020eda9 | ||
|
|
91e3e209bf | ||
|
|
8d5c7dd566 | ||
|
|
f3a4294a11 | ||
|
|
9140063401 | ||
|
|
5f5e75de6e | ||
|
|
e71e9b07a8 | ||
|
|
5ff7c338f2 | ||
|
|
36795a34a2 | ||
|
|
341c78552d | ||
|
|
c3d0f7e463 | ||
|
|
7089f24156 | ||
|
|
fff9b4ecba | ||
|
|
e5f7fd404e | ||
|
|
79bbadc3c4 | ||
|
|
36508bc31a | ||
|
|
e4a8e3fd9e | ||
|
|
5774f469c0 | ||
|
|
9ced4a373b | ||
|
|
1fc8a6ca14 | ||
|
|
501c800c5a | ||
|
|
6fc89a80d1 | ||
|
|
4e82233874 | ||
|
|
6be62cdb7a | ||
|
|
858ad8ca64 | ||
|
|
ec3d5a0c43 | ||
|
|
738fe3d529 | ||
|
|
3e211c91a2 | ||
|
|
6aa3efe185 | ||
|
|
eb72c49bd2 | ||
|
|
37b7bccc61 | ||
|
|
a9414a6e2a | ||
|
|
ae886f5c2b | ||
|
|
28f69488c6 | ||
|
|
0e56b81f4c | ||
|
|
7264ffaabb | ||
|
|
4c17496489 | ||
|
|
c7eef6e141 | ||
|
|
c9998ac0e2 | ||
|
|
5aab786c35 | ||
|
|
1b1917f4b3 | ||
|
|
46171bc538 | ||
|
|
bca487f709 | ||
|
|
9edf987b94 | ||
|
|
8e5659a7e8 | ||
|
|
2edde8f5a4 | ||
|
|
78daafd161 | ||
|
|
c21550022e | ||
|
|
981b58ae55 | ||
|
|
5047f6f219 | ||
|
|
5b3ad85c96 | ||
|
|
933f70cf5d | ||
|
|
67fb880dfb | ||
|
|
006e49982e | ||
|
|
465a7518cc | ||
|
|
66252c0f4b | ||
|
|
d91f72fd5f | ||
|
|
e35371be2b | ||
|
|
1bb58646de | ||
|
|
4a396046fe | ||
|
|
6d59eee9e3 | ||
|
|
c032902159 | ||
|
|
f230bc9d12 | ||
|
|
62ed498468 | ||
|
|
e4c58b025f | ||
|
|
71fd88b931 | ||
|
|
4fbe072aa4 | ||
|
|
e85c9cbc45 | ||
|
|
e9f725b418 | ||
|
|
655f60e567 | ||
|
|
e4614cf487 | ||
|
|
1695ca0ce8 | ||
|
|
50af63e1d2 | ||
|
|
7fa4d658e3 | ||
|
|
fe73c5fc95 | ||
|
|
b5fb02dc70 | ||
|
|
0e2190687f | ||
|
|
886cf4f227 | ||
|
|
5dc7640d74 | ||
|
|
d2e8557038 | ||
|
|
af6128c44b | ||
|
|
b12891297f | ||
|
|
680e851452 | ||
|
|
45bdf40534 | ||
|
|
785958db53 | ||
|
|
385647af43 | ||
|
|
c82e412d32 | ||
|
|
f37a567e8c | ||
|
|
51b800f40a | ||
|
|
be647641bb | ||
|
|
5a0a0ff8dd | ||
|
|
d21648495a | ||
|
|
29802d2ff5 | ||
|
|
1d12de4da6 | ||
|
|
c5155d54c6 | ||
|
|
fac1fb13da | ||
|
|
e13c4fac01 | ||
|
|
c10477c152 | ||
|
|
9f51b3590d | ||
|
|
01fcb9779a | ||
|
|
58022ed110 | ||
|
|
5e39502200 | ||
|
|
e0369d78c9 | ||
|
|
826fe52a8a | ||
|
|
d7754393bb | ||
|
|
6ca53fde12 | ||
|
|
f778fb89a5 | ||
|
|
b7d9b6702e | ||
|
|
2711c7aed9 | ||
|
|
75fbecf831 | ||
|
|
7f886b4c53 | ||
|
|
601df24372 | ||
|
|
cd5a6fd5d8 | ||
|
|
e707a89e63 | ||
|
|
1d0858f08e | ||
|
|
f4985479d2 | ||
|
|
1fb2eaabf3 | ||
|
|
7ab4290896 | ||
|
|
895b4077d1 | ||
|
|
0484eac549 | ||
|
|
fd62e99c23 | ||
|
|
697993ef35 | ||
|
|
ebe8fb518a | ||
|
|
e217072b8b | ||
|
|
5fc9d43a99 | ||
|
|
56f1a46121 | ||
|
|
d407e8e25e | ||
|
|
184c7ab61f | ||
|
|
663e7feea2 | ||
|
|
5ea641b2d3 | ||
|
|
21b6696e8b | ||
|
|
c8edb6ab5d | ||
|
|
7a6ec6b25a | ||
|
|
34b28107e2 | ||
|
|
fbada4d85a | ||
|
|
19f4f3c36c | ||
|
|
57d8ea696c | ||
|
|
3119961e8c | ||
|
|
e2ca759d56 | ||
|
|
6b3938f2f2 | ||
|
|
43d532519f | ||
|
|
27d3190aa2 | ||
|
|
7a594ca15d | ||
|
|
70f306e8d8 | ||
|
|
b03498907b | ||
|
|
ecf50fcee8 | ||
|
|
159de43db3 | ||
|
|
4cb0fe78ba | ||
|
|
bb187d73e4 | ||
|
|
91f9ec998a | ||
|
|
a085980b22 | ||
|
|
f1ed7d40c1 | ||
|
|
6bb88bdcc0 | ||
|
|
d218619e35 | ||
|
|
4a2a281c32 | ||
|
|
b0b27ae007 | ||
|
|
5ca00863fb | ||
|
|
0b7e57f8b8 | ||
|
|
4aacf51f4d | ||
|
|
9f7b1269b7 | ||
|
|
3f1d92ad68 | ||
|
|
f561107add | ||
|
|
9fd6ce9eba | ||
|
|
27b54b8d01 | ||
|
|
3fabe90067 | ||
|
|
a948d041fe | ||
|
|
da17bb3e97 | ||
|
|
f2d573fe85 | ||
|
|
7fa873f2b2 | ||
|
|
c05524beb1 | ||
|
|
e4ef5fc7fc | ||
|
|
53fab94828 | ||
|
|
2984b40bc9 | ||
|
|
cd16a399e5 | ||
|
|
c9d68a3a2b | ||
|
|
aa45923166 | ||
|
|
4386d3b764 | ||
|
|
acb58deb48 | ||
|
|
09a80571a5 | ||
|
|
546e9d3ecc | ||
|
|
1521e09083 | ||
|
|
f4341a13d0 | ||
|
|
c6a3f83e83 | ||
|
|
529b08c3a3 | ||
|
|
fb1aeaa66c | ||
|
|
cbd33586ac | ||
|
|
37f1d9add6 | ||
|
|
94f7087311 | ||
|
|
4e6c02b6ad | ||
|
|
936baa4dfa | ||
|
|
d0e69f8c6e | ||
|
|
29aeb9d959 | ||
|
|
9023f99c52 | ||
|
|
c9472cabee | ||
|
|
5a82b043d0 | ||
|
|
c11f4d9df6 | ||
|
|
e74c5226f3 | ||
|
|
26fab30972 | ||
|
|
4285e650af | ||
|
|
cf5a44f1e3 | ||
|
|
f88d485e38 | ||
|
|
a5a9db828e | ||
|
|
3b84a3f8a4 | ||
|
|
7de3a7fcb0 | ||
|
|
6d3f4243c1 | ||
|
|
4ec902aab5 | ||
|
|
fd1ca04d76 | ||
|
|
c2ad77b27f | ||
|
|
5a4e282ae8 | ||
|
|
3201291b32 | ||
|
|
485db41457 | ||
|
|
748c909e7b | ||
|
|
1b473c2ef0 | ||
|
|
72d36d9c27 | ||
|
|
6b3f1c2e99 | ||
|
|
db2ec82162 | ||
|
|
20af2eb571 | ||
|
|
a0f9b1a2ed | ||
|
|
3bd078e428 | ||
|
|
b66f9e2579 | ||
|
|
e9cffc55a7 | ||
|
|
81fc3f26fa | ||
|
|
6a19e66d00 | ||
|
|
16b14c8945 | ||
|
|
65ed20b4f4 | ||
|
|
cbe865df7a | ||
|
|
e78cef0d9f | ||
|
|
f7f30d8c63 | ||
|
|
6fb26bad22 | ||
|
|
746c335bcd | ||
|
|
9b0526bb46 | ||
|
|
40e4cfe458 | ||
|
|
97fc11c244 | ||
|
|
2a3888bfac | ||
|
|
813531edd4 | ||
|
|
8a20115615 | ||
|
|
817fc344e7 | ||
|
|
9c9ee7c952 | ||
|
|
3b78918878 | ||
|
|
9befc69684 | ||
|
|
f5e13431a5 | ||
|
|
71c9cbb2b1 | ||
|
|
f945ae2122 | ||
|
|
e7a1bdc90c | ||
|
|
3a83b65a88 | ||
|
|
1e7da835b8 | ||
|
|
97bbd2381b | ||
|
|
733f251743 | ||
|
|
0bcf4e2787 | ||
|
|
01e8718ad5 | ||
|
|
10183deadb | ||
|
|
7540c30f54 | ||
|
|
f6d219cb18 | ||
|
|
250b80eaf7 | ||
|
|
0e46787829 | ||
|
|
74a4fde52e | ||
|
|
cd2d5400ce | ||
|
|
ff7e6bda27 | ||
|
|
842b885e3c | ||
|
|
4331bbcc1a | ||
|
|
f3e493de49 | ||
|
|
4c021fb727 | ||
|
|
a5cee9d917 | ||
|
|
da6bceb5a7 | ||
|
|
cf43ccdfde | ||
|
|
3654cba018 | ||
|
|
d562c7c228 | ||
|
|
2685819181 | ||
|
|
ada0d0504c | ||
|
|
60f13d2625 | ||
|
|
b2796a0d46 | ||
|
|
b95777507e | ||
|
|
fb101603f0 | ||
|
|
7625719654 | ||
|
|
0c23127aae | ||
|
|
b04542e11e | ||
|
|
226e31d86d | ||
|
|
3664ca0cbb | ||
|
|
9706fc6bac | ||
|
|
5d6ede1055 | ||
|
|
8a2e7f50d7 | ||
|
|
cfe1d50b1a | ||
|
|
615a463e23 | ||
|
|
fc8d3631b4 | ||
|
|
819668f839 | ||
|
|
6407936c27 | ||
|
|
fc12d8258b | ||
|
|
5b7ef7bfa3 | ||
|
|
51973e530b | ||
|
|
c680adba74 | ||
|
|
731dccfccc | ||
|
|
79c8c611db | ||
|
|
f08922f6b7 | ||
|
|
71633c9523 | ||
|
|
521e6eece4 | ||
|
|
d30a9acc68 | ||
|
|
a13bf9ab7a | ||
|
|
1cb4cc98ab | ||
|
|
eca9614457 | ||
|
|
8458723ef2 | ||
|
|
1ba2edcfb2 | ||
|
|
f24eba5c44 | ||
|
|
d52ac4259b | ||
|
|
81a770b93f | ||
|
|
047bc4bd88 | ||
|
|
11325940c8 | ||
|
|
ed04393d27 | ||
|
|
d6e3f866bc | ||
|
|
a03406e91f | ||
|
|
37d41292bb | ||
|
|
b27b9b09c6 | ||
|
|
8082927ba3 | ||
|
|
139db65acf | ||
|
|
24457fa523 | ||
|
|
acc40fafeb | ||
|
|
38c28eb6cb | ||
|
|
921ffb5dd7 | ||
|
|
bc75095a9a | ||
|
|
d82c9db4c8 | ||
|
|
3693410426 | ||
|
|
cee8ab8dc0 | ||
|
|
208f167090 | ||
|
|
4c29324050 | ||
|
|
bc973fb1d0 | ||
|
|
3e6d45aebe | ||
|
|
878db20a92 | ||
|
|
2f6b25c4fb | ||
|
|
e888d3d393 | ||
|
|
e5e82459c6 | ||
|
|
1d22c714ce | ||
|
|
a342626920 | ||
|
|
bbdb142d2e | ||
|
|
26926ffcfa | ||
|
|
a4f55d7fd7 | ||
|
|
1dbd21dc61 | ||
|
|
28e58d7df2 | ||
|
|
e7b5056769 | ||
|
|
0ceeeafa41 | ||
|
|
b531a37942 | ||
|
|
21e9421c4b | ||
|
|
166f1120c8 | ||
|
|
cd3f2c48c0 | ||
|
|
b0760f8006 | ||
|
|
f345e8a77c | ||
|
|
b4429b287a | ||
|
|
df27f744df | ||
|
|
7c2d9a9302 | ||
|
|
7a506337e6 | ||
|
|
377303a391 | ||
|
|
0ad12d0e0b | ||
|
|
978733388c | ||
|
|
4f5c46fb20 | ||
|
|
8f27350e65 | ||
|
|
8e280ab712 | ||
|
|
1d3cdc6b11 | ||
|
|
2b67a9e709 | ||
|
|
783919611b | ||
|
|
10376c0c61 | ||
|
|
7ec55a027f | ||
|
|
6642fb0688 | ||
|
|
af47f4a497 | ||
|
|
847f8207f7 | ||
|
|
2a0036e496 | ||
|
|
412cf715a7 | ||
|
|
5e8102a304 | ||
|
|
48647bfc08 | ||
|
|
40c4e1f8c4 | ||
|
|
21524d6652 | ||
|
|
ba9786d714 | ||
|
|
85accd0169 | ||
|
|
fff27f4683 | ||
|
|
e0458e4c27 | ||
|
|
75113c58ef | ||
|
|
f5fe6c81ee | ||
|
|
8ee8f1e057 | ||
|
|
11ee28639d | ||
|
|
3f16af5a44 | ||
|
|
425ab889d6 | ||
|
|
d593a70bbf | ||
|
|
7a37c73b8e | ||
|
|
bd8f307677 | ||
|
|
bbe2d4668e | ||
|
|
687b0543c8 | ||
|
|
067eae567c | ||
|
|
5aa87dbfa7 | ||
|
|
814d7db11a | ||
|
|
5e26db0a5d | ||
|
|
94c3b35271 | ||
|
|
06101a43c8 | ||
|
|
5e019a3df5 | ||
|
|
e34e97ef86 | ||
|
|
27ba5b8b62 | ||
|
|
4228090f88 | ||
|
|
51cc98e6f2 | ||
|
|
c31ecfba93 | ||
|
|
3b0d12d986 | ||
|
|
f6f32e60d5 | ||
|
|
db43c5e732 | ||
|
|
eb2ba42eaa | ||
|
|
50e9f66257 | ||
|
|
26e0fbbeb5 | ||
|
|
73c22d0d50 | ||
|
|
fa44c77c6f | ||
|
|
3051f1edd9 | ||
|
|
7b517e7131 | ||
|
|
5a5b4b41c0 | ||
|
|
1a3cd8e6ad | ||
|
|
fda8b94bdf | ||
|
|
5806a08168 | ||
|
|
f83d5e5be8 | ||
|
|
01a79e3adc | ||
|
|
b7e5181f8e | ||
|
|
7fe77f16a7 | ||
|
|
8b257ef3b6 | ||
|
|
f3b8441cc7 | ||
|
|
8162607c58 | ||
|
|
fe7038fb2d | ||
|
|
fba6a02260 | ||
|
|
163898dae7 | ||
|
|
f0d069772c | ||
|
|
47da76ae48 | ||
|
|
d77613aaba | ||
|
|
475fc3de54 | ||
|
|
b7dcee9370 | ||
|
|
6abb9f6415 | ||
|
|
b32daa0ed7 | ||
|
|
835c162442 | ||
|
|
4981335c1d | ||
|
|
d7216653df | ||
|
|
0e451c786e | ||
|
|
07dfb3d5f2 | ||
|
|
f7e921313e | ||
|
|
9ba4867e64 | ||
|
|
278d8a7319 | ||
|
|
e4c20dbe87 | ||
|
|
c58934fd46 | ||
|
|
be6da9b8ea | ||
|
|
2aba17e440 | ||
|
|
711d99a23c | ||
|
|
80e0c565cd | ||
|
|
36028564f8 | ||
|
|
209a6d00f3 | ||
|
|
5526000ece | ||
|
|
7babc7c8cd | ||
|
|
67623b0801 | ||
|
|
d73839b733 | ||
|
|
c6179991b8 | ||
|
|
29ac09a2aa | ||
|
|
59488458b0 | ||
|
|
f6764f4722 | ||
|
|
493cba1f80 | ||
|
|
05b1559275 | ||
|
|
6eeee2496b | ||
|
|
b9d6efa20e | ||
|
|
20e1b92862 | ||
|
|
a54678d7fa | ||
|
|
0a9130bb4b | ||
|
|
6e3fdcffa6 | ||
|
|
3cf4974cfe | ||
|
|
ba1639e1f7 | ||
|
|
791c0bf970 | ||
|
|
5987504e82 | ||
|
|
4602d19afd | ||
|
|
829e4e749f | ||
|
|
0f453631c4 | ||
|
|
cdbc2f2b9e | ||
|
|
562fc888b5 | ||
|
|
b0506b3e4b | ||
|
|
c75324a1a4 | ||
|
|
b3543499f0 | ||
|
|
ddf2e8a342 | ||
|
|
67aa337ee7 | ||
|
|
6eb85b943b | ||
|
|
75e98ab6d1 | ||
|
|
8feb0d8bb6 | ||
|
|
e6472033b1 | ||
|
|
82082c0a35 | ||
|
|
c4225d255e | ||
|
|
a71b49f405 | ||
|
|
89e0dd94a2 | ||
|
|
f5652e5d4e | ||
|
|
1302c48d8e | ||
|
|
7d1c585587 | ||
|
|
d19769f687 | ||
|
|
c6ff40e6aa | ||
|
|
08979fc8ff | ||
|
|
907980f17d | ||
|
|
0e09ca68a5 | ||
|
|
df565c2ccb | ||
|
|
82b01cca71 | ||
|
|
9cb7619730 | ||
|
|
beaab96cdf | ||
|
|
5d3958b794 | ||
|
|
0dee7f521b | ||
|
|
833d11aeb2 | ||
|
|
a03e42860f | ||
|
|
dea29b88c5 | ||
|
|
4a90412468 | ||
|
|
53eabdf513 | ||
|
|
f2245eff85 | ||
|
|
732c8b2a00 | ||
|
|
2e449cd972 | ||
|
|
a1486ff1b1 | ||
|
|
f01788bff9 | ||
|
|
dffda7e8c7 | ||
|
|
d2c9cc6e2b | ||
|
|
f37357f371 | ||
|
|
5d4c51eeb9 | ||
|
|
e16a3e6f74 | ||
|
|
edf612581f | ||
|
|
d855fee050 | ||
|
|
154334a414 | ||
|
|
40fe8aa533 | ||
|
|
7ba7ec9c97 | ||
|
|
df085816fc | ||
|
|
0cfae29887 | ||
|
|
c4da749362 | ||
|
|
dbe00ec2d2 | ||
|
|
41129c57bd | ||
|
|
3fddf10c3e | ||
|
|
4fef1b32cd | ||
|
|
21dd479a6b | ||
|
|
e6c2b58b2b | ||
|
|
ca5ebe78cd | ||
|
|
8d2dcf3a32 | ||
|
|
523d20a573 | ||
|
|
aae534130b | ||
|
|
7b6912fd28 | ||
|
|
665e5bfee1 | ||
|
|
1cdcc857d9 | ||
|
|
2cf87c7c50 | ||
|
|
ac16b57304 | ||
|
|
979de9323a | ||
|
|
a02b54bfb8 | ||
|
|
dd2c3a3d48 | ||
|
|
7cabdde1ce | ||
|
|
c3098625ea | ||
|
|
bbcac3aa85 | ||
|
|
f6b058e8ae | ||
|
|
256093b5da | ||
|
|
13dbf301c6 | ||
|
|
5654b1b886 | ||
|
|
f94a62d64e | ||
|
|
aa39431646 | ||
|
|
a6cc0b233e | ||
|
|
2cfa5ed899 | ||
|
|
4ffdfcbec7 | ||
|
|
c75fdd13cf | ||
|
|
93cd3c18e7 | ||
|
|
ae23339452 | ||
|
|
8b8de46573 | ||
|
|
091c4e1a85 | ||
|
|
10a7938b6e | ||
|
|
15b1b0b0f1 | ||
|
|
39094852db | ||
|
|
926b8041a1 | ||
|
|
70daa486aa | ||
|
|
abde9eef28 | ||
|
|
b430999a96 | ||
|
|
3e10ac9f6e | ||
|
|
45eb2c1c9d | ||
|
|
b0bb0ed079 | ||
|
|
f8a6b5e31d | ||
|
|
1bfcc8d8d0 | ||
|
|
ec6cca344b | ||
|
|
c7c91a93f2 | ||
|
|
14009dbfa1 | ||
|
|
9d5e3ee8b9 | ||
|
|
af6aeefada | ||
|
|
3bcda42140 | ||
|
|
e24848eeaa | ||
|
|
ea57a86564 | ||
|
|
fa4e465fd4 | ||
|
|
fa9c225dd3 | ||
|
|
6301ef6baf | ||
|
|
863104131d | ||
|
|
43604eb770 | ||
|
|
be1d78a3ea | ||
|
|
2758349cae | ||
|
|
7f844be5e0 | ||
|
|
6978d58552 | ||
|
|
4bd768a43e | ||
|
|
a0afd5f8fb | ||
|
|
259d29a58d | ||
|
|
b49fd4ab95 | ||
|
|
501d2cdc17 | ||
|
|
16c2861fa8 | ||
|
|
b6a6c83b78 | ||
|
|
451970b3fb | ||
|
|
9cc2aa39d0 | ||
|
|
4952835d93 | ||
|
|
09e1c34d99 | ||
|
|
2f771c677e | ||
|
|
3e8183de43 | ||
|
|
d6b38a8b3b | ||
|
|
c88abff66a | ||
|
|
60ed66900b | ||
|
|
cd3a6739a4 | ||
|
|
fd6cc08ac8 | ||
|
|
736bb7c6dc | ||
|
|
c0aac70a7b | ||
|
|
451e3aa6dd | ||
|
|
5c18d407c5 | ||
|
|
1680ccf66c | ||
|
|
85cb2844aa | ||
|
|
67eafb9b74 | ||
|
|
c42b5f915d | ||
|
|
201246ea7f | ||
|
|
f8755643cd | ||
|
|
77b48c0aed | ||
|
|
864fc0cfce | ||
|
|
c2e4a6646d | ||
|
|
511730407d | ||
|
|
c35b05dd30 | ||
|
|
9f8cab83a3 | ||
|
|
c235acc4ea | ||
|
|
346d8d1b23 | ||
|
|
fbc8fd227c | ||
|
|
9c6f9b78de | ||
|
|
7edc592778 | ||
|
|
f3475fad8c | ||
|
|
a4e97626d3 | ||
|
|
56790e3021 | ||
|
|
0a7548d4ec | ||
|
|
eeb1a0aad4 | ||
|
|
b7585a7578 | ||
|
|
2d5b51e3b0 | ||
|
|
9b67525144 | ||
|
|
cb87c27bfd | ||
|
|
817eaa46c7 | ||
|
|
611c0b41f5 | ||
|
|
6b4c9fca59 | ||
|
|
6b466cfcf4 | ||
|
|
9df7ee5653 | ||
|
|
a54c71d4c3 | ||
|
|
33d20ff5ea | ||
|
|
3ebbb69e65 | ||
|
|
5349624ae4 | ||
|
|
861deb56f3 | ||
|
|
7f1005e793 | ||
|
|
7bc99b0135 | ||
|
|
a8420172ba | ||
|
|
b5073a2e44 | ||
|
|
2b32a1bbb7 | ||
|
|
9baba73625 | ||
|
|
e6918cb42e | ||
|
|
a987ef1163 | ||
|
|
0e170f8f81 | ||
|
|
503f3be1d2 | ||
|
|
d93216742c | ||
|
|
a7d793678e | ||
|
|
082813a0fa | ||
|
|
13d3fd287b | ||
|
|
7674dff43d | ||
|
|
6a72f56ee2 | ||
|
|
2f35e7462e | ||
|
|
488cdb8ef7 | ||
|
|
235fb19b74 | ||
|
|
33fbc73fc5 | ||
|
|
0f0bc1fdb2 | ||
|
|
65761373bd | ||
|
|
e44df9eaa2 | ||
|
|
d73281e230 | ||
|
|
f4c5c7a8f1 | ||
|
|
ca8a788993 | ||
|
|
e6fcca503b | ||
|
|
bf81946eb0 | ||
|
|
07baf77b6c | ||
|
|
08db8f131e | ||
|
|
a8225de175 | ||
|
|
10772f4512 | ||
|
|
e4153aab01 | ||
|
|
9dbe69a7a4 | ||
|
|
7d2025db5f | ||
|
|
56fea820dc | ||
|
|
d2e7f73adc | ||
|
|
e1503e9af7 | ||
|
|
d391e86036 | ||
|
|
666b208093 | ||
|
|
0f7e77fb23 | ||
|
|
8e9f4405bf | ||
|
|
43b082cf5c | ||
|
|
3df489bff6 | ||
|
|
a98ed49b0c | ||
|
|
697c33c81d | ||
|
|
54d3735b7b | ||
|
|
eb180d0bb5 | ||
|
|
429d086d2c | ||
|
|
eaa0379d5b | ||
|
|
e2c23ff3db | ||
|
|
63d49a667e | ||
|
|
445bf6c4f1 | ||
|
|
dd86d6d6d4 | ||
|
|
68ebc88679 | ||
|
|
12ab2fcadf | ||
|
|
425b690ef2 | ||
|
|
1d49a6b34f | ||
|
|
8a8e98da61 | ||
|
|
5cc201a9cf | ||
|
|
83016e1bce | ||
|
|
f02b64d258 | ||
|
|
d0d50a4ad7 | ||
|
|
d5251a8505 | ||
|
|
81cf114576 | ||
|
|
bd4eb86616 | ||
|
|
176799c7f6 | ||
|
|
e856df69d0 | ||
|
|
4d3a223232 | ||
|
|
371a3d4185 | ||
|
|
18a59c1f0a | ||
|
|
dfd7cff867 | ||
|
|
ad80c6308b | ||
|
|
b11c63b0c2 | ||
|
|
4b77904dbe | ||
|
|
72ee4c5781 | ||
|
|
2c64ccad0f | ||
|
|
0954f713fc | ||
|
|
e8ae988b72 | ||
|
|
ca908e767c | ||
|
|
060dda2022 | ||
|
|
61e446f04b | ||
|
|
7640e83360 | ||
|
|
d1b666fc56 | ||
|
|
2d86a6955c | ||
|
|
d9848d6c49 | ||
|
|
4ebaef0e1c | ||
|
|
66a57e51e3 | ||
|
|
67fad0eab1 | ||
|
|
1ecb57b142 | ||
|
|
0ce1ae2a36 | ||
|
|
c1e327a713 | ||
|
|
32b4c314f9 | ||
|
|
d50ea0e9d4 | ||
|
|
f2c4538f61 | ||
|
|
a8723ad68f | ||
|
|
fa50831650 | ||
|
|
ce58e5862d | ||
|
|
3f86070028 | ||
|
|
b9ae36c893 | ||
|
|
708c892f57 | ||
|
|
d76da9c8e8 | ||
|
|
3a8580e982 | ||
|
|
36ce5024df | ||
|
|
4ac7db7746 | ||
|
|
c7ea3e9425 | ||
|
|
7a67a8faa3 | ||
|
|
17769619c2 | ||
|
|
877a281b74 | ||
|
|
48130719cb | ||
|
|
cf3b725fe9 | ||
|
|
9ea88c1825 | ||
|
|
1c156b82d1 | ||
|
|
55d89cfea0 | ||
|
|
06fde4bfaf | ||
|
|
52a7b81e24 | ||
|
|
2bd936105e | ||
|
|
d2f186de49 | ||
|
|
f7714db80b | ||
|
|
8ce222478d | ||
|
|
1bd973bfce | ||
|
|
ddcc8fad13 | ||
|
|
93b3bd7ea2 | ||
|
|
b413c00ad1 | ||
|
|
e403f86b4b | ||
|
|
c78714436e | ||
|
|
23dce94f2d | ||
|
|
6315850d11 | ||
|
|
8dd7713d21 | ||
|
|
0592345e63 | ||
|
|
c1fd6c1e4c | ||
|
|
ca85e1d7a6 | ||
|
|
f15b12873f | ||
|
|
bb6e95e35c | ||
|
|
63ff352808 | ||
|
|
60c5f7a1fb | ||
|
|
070c998a16 | ||
|
|
21203386be | ||
|
|
30f0113f45 | ||
|
|
20393ecf10 | ||
|
|
dbf5bc4527 | ||
|
|
32c3738fb8 | ||
|
|
5da3961f68 | ||
|
|
e5ce9c9c14 | ||
|
|
99469b77d2 | ||
|
|
b075be1caa | ||
|
|
367be1fc7e | ||
|
|
94ca29c410 | ||
|
|
2039beaffa | ||
|
|
aeb89d9744 | ||
|
|
ef91635ecc | ||
|
|
9b5c611ead | ||
|
|
e358921d34 | ||
|
|
9fb0063933 | ||
|
|
f84214231f | ||
|
|
32131f4c53 | ||
|
|
60410e4b5d | ||
|
|
db7b74182d | ||
|
|
d73253bdb4 | ||
|
|
51f77ae844 | ||
|
|
d9f5eb8b8c | ||
|
|
3d1d4221aa | ||
|
|
12a42fbf3a | ||
|
|
d5ccd47ad0 | ||
|
|
88d965b9cc | ||
|
|
a01d8d593f | ||
|
|
a07436624d | ||
|
|
a4581f56be | ||
|
|
a36ec02c7b | ||
|
|
7e8b1a0389 | ||
|
|
7f0078a8cc | ||
|
|
d4cce257b2 | ||
|
|
55dc769bc3 | ||
|
|
9bc09cd23c | ||
|
|
f25f75d16a | ||
|
|
8fb1eb8ee7 | ||
|
|
a849677253 | ||
|
|
3deb2d074a | ||
|
|
0aed2ff99f | ||
|
|
7bcf9080c5 | ||
|
|
77a1b3573d | ||
|
|
4fc8108a2b | ||
|
|
c6df9fae0e | ||
|
|
ea59b1b791 | ||
|
|
b1551be44b | ||
|
|
8104433a4c | ||
|
|
ab426a3ec7 | ||
|
|
bbfe082812 | ||
|
|
e488544457 | ||
|
|
622848130b | ||
|
|
c895d9cc41 | ||
|
|
d9d6da8edf | ||
|
|
b24318dafb | ||
|
|
69eaf7375d | ||
|
|
fb5cc266e2 | ||
|
|
775de47268 | ||
|
|
5a486c4015 | ||
|
|
1650f8e882 | ||
|
|
735a7f709a | ||
|
|
8d811b503f | ||
|
|
a3eb43a6bf | ||
|
|
3990f9c86d | ||
|
|
ddfb2af298 | ||
|
|
e42d61fac6 | ||
|
|
bdecee176e | ||
|
|
14650e5c4f | ||
|
|
f05df8140b | ||
|
|
0b6f6e81e0 | ||
|
|
96fb2cc31a | ||
|
|
d4a901a5bd | ||
|
|
8cd708fbeb | ||
|
|
1681e18ce8 | ||
|
|
b26b0e9529 | ||
|
|
201b40c520 | ||
|
|
105b71e710 | ||
|
|
b4050e5159 | ||
|
|
ba82790739 | ||
|
|
5ebc524d35 | ||
|
|
c0acada4b5 | ||
|
|
dd8905bf88 | ||
|
|
8c020ca8fe | ||
|
|
49728b8c7c | ||
|
|
71ca1d1630 | ||
|
|
eca3fe39be | ||
|
|
a68a0d526d | ||
|
|
0ee3f68ba2 | ||
|
|
8df5fb20b9 | ||
|
|
f8ea53ff6d | ||
|
|
5e1eef326c | ||
|
|
e2b7ef8902 | ||
|
|
c1e73a2736 | ||
|
|
2f79ff2ad7 | ||
|
|
e86dd9ef2e | ||
|
|
861a2d021d | ||
|
|
c756b2d07c | ||
|
|
99e1f111e6 | ||
|
|
7370ed011e | ||
|
|
995231efc7 | ||
|
|
5bbb08f041 | ||
|
|
39055ab5d7 | ||
|
|
c89f206a7a | ||
|
|
5994799c1e | ||
|
|
d233fd5d12 | ||
|
|
67751c3992 | ||
|
|
54c89ccea9 | ||
|
|
c159dbafae | ||
|
|
9bcb56b600 | ||
|
|
cdd947a98b | ||
|
|
fe77fd8bb3 | ||
|
|
dcb600ff3b | ||
|
|
80555f6587 | ||
|
|
bab0cfd263 | ||
|
|
8c63834523 | ||
|
|
13f34c3518 | ||
|
|
3eb85f722f | ||
|
|
ee40af15ad | ||
|
|
ceab2dfcf9 | ||
|
|
7336b021e8 | ||
|
|
afd122b895 | ||
|
|
747f8e9238 | ||
|
|
123613853b | ||
|
|
9086941a86 | ||
|
|
4a8dc28b52 | ||
|
|
ed6b4c821e | ||
|
|
ede7bca2a7 | ||
|
|
738689ea86 | ||
|
|
faa9890ff2 | ||
|
|
e055bb6e86 | ||
|
|
b824677a2a | ||
|
|
11fefdc37c | ||
|
|
f18ffcb4b7 | ||
|
|
919b935980 | ||
|
|
5b44727583 | ||
|
|
44ec0d02a2 | ||
|
|
a734901dee | ||
|
|
c75c3e8bc2 | ||
|
|
2a2f2c2c04 | ||
|
|
b3abeb59d3 | ||
|
|
75a75233da | ||
|
|
d5930d1fe8 | ||
|
|
04cde57a77 | ||
|
|
218fdfa3e5 | ||
|
|
0f77c05d85 | ||
|
|
ce47c7f2c7 | ||
|
|
fc8c05165a | ||
|
|
62099ea6b9 | ||
|
|
c918ef0f40 | ||
|
|
b1f7ca718e | ||
|
|
c0a63a9c86 | ||
|
|
61cf4e2668 | ||
|
|
b78dc9e0f6 | ||
|
|
afdafc85ce | ||
|
|
34c34980c6 | ||
|
|
a4cb6c34d3 | ||
|
|
7e81dc97e5 | ||
|
|
7417052303 | ||
|
|
7d19251487 | ||
|
|
f683340aa5 | ||
|
|
bc1141dfff | ||
|
|
f62f33ce93 | ||
|
|
4b75f411fc | ||
|
|
aec202cbdb | ||
|
|
edcd34976e | ||
|
|
3214cf6ba9 | ||
|
|
3f06397045 | ||
|
|
51a5499532 | ||
|
|
5f53621223 | ||
|
|
4a792f6c7c | ||
|
|
60811d944f | ||
|
|
493945c224 | ||
|
|
bc740c86fd | ||
|
|
21b5e17de5 | ||
|
|
6c1cfa8b83 | ||
|
|
3957344c83 | ||
|
|
2ac5d0b1aa | ||
|
|
42b068e43e | ||
|
|
239b43d953 | ||
|
|
31fcc5dbed | ||
|
|
c36135eebf | ||
|
|
0cbb5dd731 | ||
|
|
cf4fe25d62 | ||
|
|
f3140658b4 | ||
|
|
4494a6d2f4 | ||
|
|
09634dde46 | ||
|
|
31c31a718c | ||
|
|
f2784d97fd | ||
|
|
c27ef7f85c | ||
|
|
eb97d576eb | ||
|
|
54e1f06913 | ||
|
|
0051d20a04 | ||
|
|
473cbda85c | ||
|
|
a0e2c58919 | ||
|
|
eac24165f7 | ||
|
|
3a8facf06d | ||
|
|
42a1f82af3 | ||
|
|
5da86a5290 | ||
|
|
364f873573 | ||
|
|
54df359acc | ||
|
|
1983a179c9 | ||
|
|
aefb1f6b06 | ||
|
|
277e550a07 | ||
|
|
e2a5bf3445 | ||
|
|
2ff8edf07b | ||
|
|
55b33a9ef9 | ||
|
|
0327bf310f | ||
|
|
036770fe92 | ||
|
|
0235e1fe05 | ||
|
|
a07f2c930b | ||
|
|
39b383b353 | ||
|
|
e13bb52a79 | ||
|
|
12135c8167 | ||
|
|
dbd257811b | ||
|
|
5e2ede7f54 | ||
|
|
c555c6fbcf | ||
|
|
6b543c1ef5 | ||
|
|
a23604f544 | ||
|
|
31587bd336 | ||
|
|
a891fe8cbb | ||
|
|
a779a730c4 | ||
|
|
433fac9bce | ||
|
|
cb5561655e | ||
|
|
f9e75aa6ea | ||
|
|
a25ff9cea5 | ||
|
|
2c794ba3d2 | ||
|
|
888125eae4 | ||
|
|
e2fa665ed5 | ||
|
|
71355b3fe0 | ||
|
|
a6d5b550cb | ||
|
|
0fb559c35c | ||
|
|
44407ad3da | ||
|
|
7c6bbd795c | ||
|
|
ebf777ad20 | ||
|
|
b430086163 | ||
|
|
aa7fcf7317 | ||
|
|
5cab624871 | ||
|
|
4e37f3fa57 | ||
|
|
e83b9fb7af | ||
|
|
707be9ed74 | ||
|
|
49cafd3409 | ||
|
|
bbf7c462ce | ||
|
|
f346211ccb | ||
|
|
acf94e8ac5 | ||
|
|
1738b4476a | ||
|
|
60cd4168d1 | ||
|
|
7c83e67367 | ||
|
|
37bcb5098b | ||
|
|
0cb5cada89 | ||
|
|
c62ffabb2f | ||
|
|
7c23eba5ed | ||
|
|
78870f9224 | ||
|
|
e2a8ee869e | ||
|
|
723b819bec | ||
|
|
b8458e4358 | ||
|
|
2d677ce27e | ||
|
|
7c5f022f3f | ||
|
|
6c9f2f25bf | ||
|
|
97a72ecf96 | ||
|
|
66d9d817b5 | ||
|
|
905845347c | ||
|
|
d9a7d03d8d | ||
|
|
dd539444bb | ||
|
|
7e5ebff4c4 | ||
|
|
4c681bb67e | ||
|
|
14f24a6e0f | ||
|
|
20e29b0fad | ||
|
|
b9ca901fdc | ||
|
|
8ebed3afd6 | ||
|
|
48c30eaca2 | ||
|
|
677e22cd2c | ||
|
|
188030b4d9 | ||
|
|
3dd98b5a1e | ||
|
|
842317f825 | ||
|
|
0bffff6a4d | ||
|
|
132d84be6c | ||
|
|
fb7bdf8ae0 | ||
|
|
d6cb5495fa | ||
|
|
a60e43e291 | ||
|
|
2f65e18d23 | ||
|
|
579ad5672c | ||
|
|
cfc4be0207 | ||
|
|
d33151577c | ||
|
|
17a5e70931 | ||
|
|
716dee69c3 | ||
|
|
cf6d4b2f3c | ||
|
|
648671db85 | ||
|
|
55a9a171a3 | ||
|
|
3a0a095d15 | ||
|
|
ad0aa8091a | ||
|
|
3de1dabd91 | ||
|
|
30920d7525 | ||
|
|
58666d1759 | ||
|
|
a71a6a44d3 | ||
|
|
28c41d85c6 | ||
|
|
741485a034 | ||
|
|
7d241111b0 | ||
|
|
13f9da9128 | ||
|
|
d1062a4a95 | ||
|
|
ef8bf8f364 | ||
|
|
557986760c | ||
|
|
c0f55c67aa | ||
|
|
0c0a2993e4 | ||
|
|
801db5a7ba | ||
|
|
4f93bc2bbf | ||
|
|
959a650313 | ||
|
|
01cad24629 | ||
|
|
b6db14fcb6 | ||
|
|
a6bd9c9717 | ||
|
|
eda650079d | ||
|
|
9d810e14fe | ||
|
|
73bec54be0 | ||
|
|
28c458b15b | ||
|
|
b178be4766 | ||
|
|
5f97dfdf34 | ||
|
|
be5a2dee08 | ||
|
|
ffb7afe7b5 | ||
|
|
b8e298f1fa | ||
|
|
bbff5356cc | ||
|
|
525037c4c2 | ||
|
|
5f80ce7975 | ||
|
|
832e39f98f | ||
|
|
ef47e8b675 | ||
|
|
a2828462c0 | ||
|
|
5d75c05877 | ||
|
|
b74e32754f | ||
|
|
9eb053a847 | ||
|
|
89e58f12a8 | ||
|
|
cc1ca5d154 | ||
|
|
a28c19e326 | ||
|
|
1e56a9a9cf | ||
|
|
58e773dfe1 | ||
|
|
cb8c335ca7 | ||
|
|
4e599dad0a | ||
|
|
ab2f06bb7b | ||
|
|
207a1254cb | ||
|
|
ac767e11a8 | ||
|
|
9cd6b539ab | ||
|
|
84becc0972 | ||
|
|
0d803132c1 | ||
|
|
75260d742a | ||
|
|
054b91de6e | ||
|
|
e4cbcd6411 | ||
|
|
1faca4015c | ||
|
|
61de43ea32 | ||
|
|
fcba224b14 | ||
|
|
7157261be4 | ||
|
|
22318b627d | ||
|
|
40780b1559 | ||
|
|
b8d62891e7 | ||
|
|
5e4e1adcb5 | ||
|
|
87255f840f | ||
|
|
d3417cad56 | ||
|
|
0b9685cc3b | ||
|
|
e165a9d027 | ||
|
|
4ea6a05122 | ||
|
|
67826ab9b8 | ||
|
|
4e8bcf1af1 | ||
|
|
ce46416cb3 | ||
|
|
fa5bb58d49 | ||
|
|
83b4945e05 | ||
|
|
b545125d11 | ||
|
|
dc57c56065 | ||
|
|
81b7115939 | ||
|
|
e47ab6be7a | ||
|
|
760f0507e4 | ||
|
|
dbc092f362 | ||
|
|
0fc22e9d3d | ||
|
|
9efbfe2213 |
30
BUGS
Executable file → Normal file
30
BUGS
Executable file → Normal file
@@ -1,11 +1,23 @@
|
||||
* EVERYTHING MARKED WITH "XXX" IN THE SOURCE REPRESENTS A BUG! Sometimes
|
||||
these bugs are in asterisk, and sometimes they relate to the products
|
||||
that asterisk uses.
|
||||
Asterisk 1.0-RC-1 Known Major Bugs
|
||||
==================================
|
||||
* Some people still have issues with H.323
|
||||
* QuickNet driver still not entirely stable
|
||||
|
||||
* The translator API may introduce warble in the case of going in both
|
||||
directions, but I haven't verified that. The trouble should only enter
|
||||
in the case of mismatched frame lengths.
|
||||
Asterisk Bug Tracking Information
|
||||
=================================
|
||||
|
||||
* In general Asterisk is a very new program, and there are liable to be
|
||||
many bugs yet to be discovered, so if you think you've found one, please
|
||||
be sure to report it.
|
||||
To learn about and report Asterisk bugs or make feature
|
||||
requests, please visit the official Asterisk Bug Tracker
|
||||
at:
|
||||
|
||||
http://bugs.digium.com
|
||||
|
||||
For more information on using the bug tracker, or to
|
||||
learn how you can contribute by acting as a bug marshal
|
||||
please see:
|
||||
|
||||
http://www.digium.com/bugtracker.html
|
||||
|
||||
Thank you!
|
||||
|
||||
Mark
|
||||
|
||||
36
CHANGES
36
CHANGES
@@ -1,36 +0,0 @@
|
||||
* Asterisk 0.1.3
|
||||
-- Update VoFR for latest sangoma code
|
||||
-- Update QuickNet Driver
|
||||
-- Add text message handling
|
||||
-- Fix transfers to use "default" if not in current context
|
||||
-- Add call parking
|
||||
-- Improve format/content negotiation
|
||||
-- Added support for multiple languages
|
||||
-- Bug fixes, as always...
|
||||
* Asterisk 0.1.2
|
||||
-- Updated README file with a "Getting Started" section
|
||||
-- Added sample sounds and configuration files.
|
||||
-- Added LPC10 very low bandwidth (low quality) compression
|
||||
-- Enhanced translation selection mechanism.
|
||||
-- Enhanced IAX jitter buffer, improved reliability
|
||||
-- Support echo cancelation on PhoneJack
|
||||
-- Updated PhoneJack driver to std. Telephony interface
|
||||
-- Added app_echo for evaluating VoIP latency
|
||||
-- Added app_system to execute arbitrary programs
|
||||
-- Updated sample configuration files
|
||||
-- Added OSS channel driver (full duplex only)
|
||||
-- Added IAX implementation
|
||||
-- Fixed some deadlocks.
|
||||
-- A whole bunch of bug fixes
|
||||
* Asterisk 0.1.1
|
||||
-- Revised translator, fixed some general race conditions throughout *
|
||||
-- Made dialer somewhat more aware of incompatible voice channels
|
||||
-- Added Voice Modem driver and A/Open Modem Driver stub
|
||||
-- Added MP3 decoder channel
|
||||
-- Added Microsoft WAV49 support
|
||||
-- Revised License -- Pure GPL, nothing else
|
||||
-- Modified Copyright statement since code is still currently owned by author
|
||||
-- Added RAW GSM headerless data format
|
||||
-- Innumerable bug fixes
|
||||
* Asterisk 0.1.0
|
||||
-- Initial Release
|
||||
71
CREDITS
Executable file → Normal file
71
CREDITS
Executable file → Normal file
@@ -1,10 +1,71 @@
|
||||
|
||||
=== DEVELOPMENT SUPPORT ===
|
||||
I'd like to thank the following companies for helping fund development of
|
||||
Asterisk:
|
||||
|
||||
Pilosoft, Inc. - for supporting ADSI development in Asterisk
|
||||
|
||||
Asterlink, Inc. - for supporting broad Asterisk development
|
||||
|
||||
GFS - for supporting ALSA development
|
||||
|
||||
Telesthetic - for supporting SIP development
|
||||
|
||||
Christos Ricudis - for substantial code contributions
|
||||
|
||||
Paul Bagyenda, Digital Solutions - for initial Voicetronix driver development
|
||||
|
||||
=== WISHLIST CONTRIBUTERS ===
|
||||
Jeremy McNamara - SpeeX support
|
||||
Nick Seraphin - RDNIS support
|
||||
Gary - Phonejack ADSI (in progress)
|
||||
Wasim - Hangup detect
|
||||
|
||||
=== HARDWARE DONORS ===
|
||||
|
||||
* Special thanks to Adtran, Inc, for their donation of an Adtran Atlas,
|
||||
and TSU 120e to the project. (http://www.adtran.com)
|
||||
|
||||
* Thanks to QuickNet Technologies for their donation of an Internet
|
||||
PhoneJack card to the project. (http://www.quicknet.net)
|
||||
PhoneJack and Linejack card to the project. (http://www.quicknet.net)
|
||||
|
||||
=== MISCELLANEOUS PATCHES ===
|
||||
Anthony Minessale - Countless big and small fixes, and relentless forward push
|
||||
anthmct@yahoo.com http://www.asterlink.com
|
||||
James Golovich - Innumerable contributions
|
||||
You can find him and asterisk-perl at http://asterisk.gnuinter.net
|
||||
Andre Bierwirth - Extension hints and status
|
||||
Oliver Daudey - ISDN4Linux fixes
|
||||
Pauline Middelink - ISDN4Linux patches and some general patches.
|
||||
She can be found at http://www.polyware.nl/~middelink/En/
|
||||
Jean-Denis Girard - Various contributions from the South Pacific Islands
|
||||
jd-girard@esoft.pf http://www.esoft.pf
|
||||
William Jordan / Vonage - MySQL enhancmenets to Voicemail
|
||||
wjordan@vonage.com
|
||||
Jac Kersing - Various fixes
|
||||
Steven Critchfield - Seek and Trunc functions for playback and recording
|
||||
critch@basesys.com
|
||||
Jefferson Noxon - app_lookupcidname, app_db, and various other contributions
|
||||
Klaus-Peter Junghanns - in-band DTMF on SIP and MGCP
|
||||
Ross Finlayson - Dynamic RTP payload support
|
||||
Mahmut Fettahlioglu - Audio recording, music-on-hold changes, alaw file
|
||||
format, and various fixes. Can be contacted at mahmut@oa.com.au
|
||||
James Dennis - Cisco SIP compatibility patches to work with SIP service
|
||||
providers. Can be contacted at asterisk@jdennis.net
|
||||
Tilghman Lesher - - Route lookup code; ast_localtime(), ast_say_date_with_format();
|
||||
GotoIfTime, Random, SayUnixTime, HasNewVoicemail, and Cut applications,
|
||||
along with various other patches. http://asterisk.drunkcoder.com/
|
||||
Jayson Vantuyl - Manager protocol changes, various other bugs.
|
||||
jvantuyl@computingedge.net
|
||||
Thorsten Lockert - OpenBSD, FreeBSD ports, making MacOS X port run on 10.3,
|
||||
dialplan include verification, route lookup on OpenBSD, various other
|
||||
bugs. tholo@sigmasoft.com
|
||||
Brian West - ODBC support and Bug Marshaling
|
||||
William Waites - syslog support, SIP NAT traversal for SIP-UA. ww@styx.org
|
||||
Rich Murphey - Porting to FreeBSD, NetBSD, OpenBSD, and Darwin.
|
||||
rich@whiteoaklabs.com http://whiteoaklabs.com
|
||||
|
||||
=== OTHER CONTRIBUTIONS ===
|
||||
John Todd - Monkey sounds and associated teletorture prompt
|
||||
|
||||
=== HOLD MUSIC ===
|
||||
Music provided by www.opsound.org
|
||||
|
||||
=== OTHER SOURCE CODE IN ASTERISK ===
|
||||
|
||||
|
||||
653
ChangeLog
Normal file
653
ChangeLog
Normal file
@@ -0,0 +1,653 @@
|
||||
NOTE: Corrections or additions to the ChangeLog may be submitted to
|
||||
http://bugs.digium.com. Documentation and formatting fixes are not
|
||||
not listed here. A complete listing of changes is available through
|
||||
the Asterisk-commits mailing list hosted at http://lists.digium.com.
|
||||
|
||||
Asterisk 1.0.12
|
||||
|
||||
-- chan_skinny
|
||||
-- An exploitable buffer overflow in this channel driver was fixed.
|
||||
|
||||
Asterisk 1.0.11.1
|
||||
|
||||
-- chan_iax2
|
||||
-- A bug in the vulnerability fix in the last release could cause Asterisk
|
||||
to improperly reject incoming video frames and result in deadlocks.
|
||||
|
||||
Asterisk 1.0.11
|
||||
|
||||
-- chan_iax2
|
||||
-- A security vulnerability that could lead to denial of service attacks
|
||||
and Asterisk process crashes was fixed in this release.Asterisk 1.0.11
|
||||
|
||||
Asterisk 1.0.10
|
||||
|
||||
-- chan_local
|
||||
-- In releases 1.0.8 and 1.0.9, the Local channels that are created would
|
||||
not be masqueraded into the new channel type. This has now been fixed.
|
||||
-- chan_sip
|
||||
-- The 'insecure' options have been changed to support matching peersby IP
|
||||
only, not requiring authentication on incoming invites, or both. Before,
|
||||
to not require authentication on incoming invites also required matching
|
||||
peers based on IP only.
|
||||
-- chan_zap
|
||||
-- Before, call waiting could occur during the initial ringing on the line.
|
||||
This has now been fixed.
|
||||
-- app_disa
|
||||
-- We will now not set the accountcode if one is not supplied.
|
||||
-- app_meetme
|
||||
-- If the first caller into a conference hangs up while being prompted for
|
||||
the conference pin number, the conference will no longer be held open.
|
||||
-- app_userevent
|
||||
-- Events created with this application were indicated as a "call" event
|
||||
instead of a "user" event. This made the "user" event permissions
|
||||
not work correctly.
|
||||
-- app_voicemail
|
||||
-- When using the externpass option for voicemail, the password will be
|
||||
immediately updated in memory as well, instead of having to wait for
|
||||
the next time the configuration is reloaded.
|
||||
-- app_zapras
|
||||
-- We now ensure buffer policy is restored after RAS is done with a channel.
|
||||
This could cause audio problems on the channel after zapras is done
|
||||
with it.
|
||||
-- res_agi
|
||||
-- We now unmask the SIGHUP signal before executing an AGI script. This
|
||||
fixes problems where some AGI scripts would continue running long after
|
||||
the call is over.
|
||||
-- extensions
|
||||
-- A potential crash has been fixed when calling LEN() to get the length of
|
||||
a string that was 80 characters or larger.
|
||||
-- general
|
||||
-- Added man pages for astgenkey, autosupport, and safe_asterisk
|
||||
|
||||
Asterisk 1.0.9
|
||||
|
||||
-- fix bug in callerid matching in the dialplan that was introduced in 1.0.8
|
||||
|
||||
Asterisk 1.0.8
|
||||
|
||||
-- chan_zap
|
||||
-- Asterisk will now also look in the regular context for the fax extension
|
||||
while executing a macro. Previously, for this to work, the fax extension
|
||||
would have to be included in the macro definition.
|
||||
-- On some systems, ALERTING will be sent after PROCEEDING, so code has been
|
||||
added to account for this case.
|
||||
-- If no extension is specified on an overlap call, the 's' extension will
|
||||
be used.
|
||||
-- chan_sip
|
||||
-- We no longer send a "to" tag on "100 Trying" messages, as it is
|
||||
inappropriate to do so.
|
||||
-- We now respond correctly to an invite for T.38 with a "488 Not acceptable
|
||||
here"
|
||||
-- We now discard saved tags on 401/407 responses in case the provider we're
|
||||
talking to tries to pull a dirty trick on us and change it.
|
||||
-- rtptimeout options will now be correctly set on a peer basis rather than
|
||||
only global
|
||||
-- chan_mgcp
|
||||
-- Fixed setting of accountcode
|
||||
-- Fixed where *67 to block callerid only worked for first call
|
||||
-- chan_agent
|
||||
-- We now will not pass audio until the agent has acked the call if the
|
||||
configuration
|
||||
is set up for the agent to do so.
|
||||
-- chan_alsa
|
||||
-- Fixed problems with the unloading of this module
|
||||
-- res_agi
|
||||
-- A fix has been added to prevent calls from being hung up when more than
|
||||
one call is executing an AGI script calling the GET DATA command.
|
||||
-- AGI scripts will now continue to run even if a file was not found with
|
||||
the GET DATA command.
|
||||
-- When calling SAY NUMBER with a number like 09, we will now say "nine"
|
||||
instead of "zero"
|
||||
-- app_dial
|
||||
-- There was a problem where text frames would not be forwarded before the
|
||||
channel has been answered.
|
||||
-- app_disa
|
||||
-- Fixed the timeout used when no password is set
|
||||
-- app_queue
|
||||
-- Distinctive ring has been fixed to work for queue members
|
||||
-- rtp
|
||||
-- Fixed a logic error when setting the "rtpchecksums" option
|
||||
-- say.c
|
||||
-- A problem has been fixed with saying the date in Spanish.
|
||||
-- Makefile
|
||||
-- A line was missing for the autosupport script that caused "make rpm" to
|
||||
fail
|
||||
-- format_wav_gsm
|
||||
-- Fixed a problem with wav formatting that prevented files from being
|
||||
played in some media players
|
||||
-- pbx_spool
|
||||
-- Fixed if the last line of text in a file for the call spool did not
|
||||
contain a new line, it would not be processed
|
||||
-- logger
|
||||
-- Fixed the logger so that color escape sequences wouldn't be sent to the
|
||||
logs
|
||||
-- format_sln
|
||||
-- A lot of changes were made to correctly handle signed linear format on
|
||||
big endian machines
|
||||
-- asterisk.conf
|
||||
-- fix 'highpriority' option for asterisk.conf
|
||||
|
||||
Asterisk 1.0.7
|
||||
|
||||
-- chan_sip
|
||||
-- The fix for some codec availibility issues in 1.0.6 caused music on hold
|
||||
problems, but has now been fixed.
|
||||
-- chan_skinny
|
||||
-- A check has been added to avoid a crash.
|
||||
-- chan_iax2
|
||||
-- A feature has been added to CVS head to have the option of sending
|
||||
timestamps with trunk frames. It is not supported in 1.0, but a change
|
||||
has been made so that it will at least not choke if sent trunk
|
||||
timestamps.
|
||||
-- app_voicemail
|
||||
-- Some checks have been added to avoid a crash.
|
||||
-- speex
|
||||
-- The path /usr/include/speex has been added for a place to look for the
|
||||
speex header.
|
||||
|
||||
Asterisk 1.0.6
|
||||
|
||||
-- chan_iax2:
|
||||
-- Fixed a bug dealing with a division by zero that could cause a crash
|
||||
-- chan_sip:
|
||||
-- Behavior was changed so that when a registration fails due to DNS
|
||||
resolution issues, a retry will be attempted in 20 seconds.
|
||||
-- Peer settings were not reset to null values when reloading the
|
||||
configuration file. Behavior has been changed so that these values are
|
||||
now cleared.
|
||||
-- 'restrictcid' now properly works on MySQL peers.
|
||||
-- Only use the default callerid if it has been specified.
|
||||
-- Asterisk was not sending the same From: line in SIP messages during
|
||||
certain times. Fixed to make sure it stays the same. This makes some
|
||||
providers happier, to a working state.
|
||||
-- Certain circumstances involving a blank callerid caused asterisk to
|
||||
segmentation fault.
|
||||
-- There was a problem incorrectly matching codec availablity when global
|
||||
preferences were different from that of the user. To fix this,
|
||||
processing of SDP data has been moved to after determining who the call
|
||||
is coming from.
|
||||
-- Asterisk would run out of RTP ports while waiting for SUBSCRIBE's to
|
||||
expire even though an RTP port isn't needed in this case. This has been
|
||||
fixed by releasing the ports early.
|
||||
-- chan_zap:
|
||||
-- During a certain scenario when using flash and '#' transfers you would
|
||||
hear the other person and the music they were hearing. This has been
|
||||
fixed.
|
||||
-- A fix for a compilation issue with gcc4 was added.
|
||||
-- chan_modem_bestdata:
|
||||
-- A fix for a compilation issue with gcc4 was added.
|
||||
-- format_g729:
|
||||
-- Treat a 10-byte read as an end of file indication instead of an error.
|
||||
Some G729 encoders like to put 10-bytes at the end to indicate this.
|
||||
-- res_features:
|
||||
-- During certain situations when parking a call, both endpoints would get
|
||||
musiconhold. This has been fixed so the individual who parked the call
|
||||
will hear the digits and not musiconhold.
|
||||
-- app_dial:
|
||||
-- DIALEDPEERNUMBER is now being set, so if you attempted to use it in the
|
||||
past and failed, it should work now.
|
||||
-- A callerid change caused many headaches, this has been reversed to the
|
||||
original 1.0 behavior.
|
||||
-- A crash caused with the combination of the 'g' option and # transfer was
|
||||
fixed.
|
||||
-- app_voicemail:
|
||||
-- If two people hit the voicemail system at the same time, and were leaving
|
||||
a message the second message was overwriting the first. This has been
|
||||
fixed so that each one is distinct and will not overwrite eachother.
|
||||
-- cdr_tds:
|
||||
-- If the server you were using was going down, it had the potential to
|
||||
bring your asterisk server down with it. Extra stuff has been added so
|
||||
as to bring in more error/connection checking.
|
||||
-- cdr_pgsql:
|
||||
-- This will now attempt to reconnect after a connection problem.
|
||||
-- IAXY firmware:
|
||||
-- This has been updated to version 23. It includes a fix for lost
|
||||
registrations.
|
||||
-- internals
|
||||
-- Behavior was changed for 'show codec <number>' to make it more intuitive.
|
||||
-- DNS failures and asterisk do not get along too well, this is not totally
|
||||
the case anymore.
|
||||
-- Asterisk will now handle DNS failures at startup more gracefully, and
|
||||
won't crash and burn
|
||||
-- Choosing to append to a wave file would render the outputted wave file
|
||||
corrupt. Appending now works again.
|
||||
-- If you failed to define certain keys, asterisk had the potential to crash
|
||||
when seeing if you had used them.
|
||||
-- Attempting to use such things as ${EXTEN:-1} gave a wrong return value.
|
||||
However, this was never a documented feature...
|
||||
|
||||
Asterisk 1.0.5
|
||||
|
||||
-- chan_zap
|
||||
-- fix a callerid bug introduced in 1.0.4
|
||||
-- app_queue
|
||||
-- fix some penalty behavior
|
||||
|
||||
Asterisk 1.0.4
|
||||
|
||||
-- general
|
||||
-- fix memory leak evident with extensive use of variables
|
||||
-- update IAXy firmware to version 22
|
||||
-- enable some special write protection
|
||||
-- enable outbound DTMF
|
||||
-- fix seg fault with incorrect usage of SetVar
|
||||
-- other minor fixes including typos and doc updates
|
||||
-- chan_sip
|
||||
-- fix codecs to not be case sensitive
|
||||
-- Re-use auth credentials
|
||||
-- fix MWI when using type=friend
|
||||
-- fix global NAT option
|
||||
-- chan_agent / chan_local
|
||||
-- fix incorrect use count
|
||||
-- chan_zap
|
||||
-- Allow CID rings to be configured in zapata.conf
|
||||
-- no more patching needed for UK CID
|
||||
-- app_macro
|
||||
-- allow Macros to exit with '*' or '#' like regular extension processing
|
||||
-- app_voicemail
|
||||
-- don't allow '#' as a password
|
||||
-- add option to save voicemail before going to the operator
|
||||
-- fix global operator=yes
|
||||
-- app_read
|
||||
-- return 0 instead of -1 if user enters nothing
|
||||
-- res_agi
|
||||
-- don't exit AGI when file not found to stream
|
||||
-- send script parameter when using FastAGI
|
||||
|
||||
Asterisk 1.0.3
|
||||
|
||||
-- chan_zap
|
||||
-- fix seg fault when doing *0 to flash a trunk
|
||||
-- rtp
|
||||
-- seg fault fix
|
||||
-- chan_sip
|
||||
-- fix to prevent seg fault when attempting a transfer
|
||||
-- fix bug with supervised transfers
|
||||
-- fix codec preferences
|
||||
-- chan_h323
|
||||
-- fix compilation problem
|
||||
-- chan_iax2
|
||||
-- avoid a deadlock related to a static config of a BUNCH of peers
|
||||
-- cdr_pgsql
|
||||
-- fix memory leak when reading config
|
||||
-- Numerous other minor bug fixes
|
||||
|
||||
Asterisk 1.0.2
|
||||
|
||||
-- Major bugfix release
|
||||
|
||||
Asterisk 1.0.1
|
||||
|
||||
-- Added AGI over TCP support
|
||||
-- Add ability to purge callers from queue if no agents are logged in
|
||||
-- Fix inband PRI indication detection
|
||||
-- Fix for MGCP - always request digits if no RTP stream
|
||||
-- Fixed seg fault for ast_control_streamfile
|
||||
-- Make pick-up extension configurable via features.conf
|
||||
-- Numerous other bug fixes
|
||||
|
||||
Asterisk 1.0.0
|
||||
-- Use Q.931 standard cause codes for asterisk cause codes
|
||||
-- Bug fixes from the bug tracker
|
||||
Asterisk 1.0-RC2
|
||||
-- Additional CDR backends
|
||||
-- Allow muted to reconnect
|
||||
-- Call parking improvements (including SIP parking support)
|
||||
-- Added licensed hold music from opsound.org
|
||||
-- GR-303 and Zap improvements
|
||||
-- More bug fixes from the bug tracker
|
||||
-- Improved FreeBSD/OpenBSD/MacOS X support
|
||||
Asterisk 1.0-RC1
|
||||
-- Innumerable bug fixes and features from the bug tracker
|
||||
-- Added Open Settlement Protocol (OSP) support
|
||||
-- Added Non-facility Associated Signalling (NFAS) Support
|
||||
-- Added alarm Monitoring support
|
||||
-- Added new MeetMe options
|
||||
-- Added GR-303 Support
|
||||
-- Added trunk groups
|
||||
-- ADPCM Standardization
|
||||
-- Numerous bug fixes
|
||||
-- Add IAX2 Firmware Support
|
||||
-- Add G.726 support
|
||||
-- Add ices/icecast support
|
||||
-- Numerous bug fixes
|
||||
Asterisk 0.7.2
|
||||
-- Countless small bug fixes from bug tracker
|
||||
-- DSP Fixes
|
||||
-- Fix unloading of Zaptel
|
||||
-- Pass Caller*ID/ANI properly on call forwarding
|
||||
-- Add indication for Italy
|
||||
Asterisk 0.7.1
|
||||
-- Fixed timed include context's and GotoIfTime
|
||||
-- Fixed chan_h323 it now gets remote ip properly instead of 127.0.0.1
|
||||
Asterisk 0.7.0
|
||||
-- Removed MP3 format and codec
|
||||
-- Can now load and unload SIP,IAX,IAX2,H323 channels without core
|
||||
-- Fixed various compiler warnings and clean up source tree
|
||||
-- Preliminary AES Support
|
||||
-- Fix SIP REINVITE
|
||||
-- Outbound SIP registration behind NAT using externip
|
||||
-- More CLI documentation and clean up
|
||||
-- Pin numbers on MeeMe
|
||||
-- Dynamic MeetMe conferences are more consistent with static conferences
|
||||
-- Added channel variables ${HANGUPCAUSE}, ${SIPDOMAIN}, ${TIMESTAMP}, ${ACCONTCODE}
|
||||
-- ODBC support for logging CDRs
|
||||
-- Indications for Norway and New Zeland
|
||||
-- Major redesign of app_voicemail
|
||||
-- Syslog support
|
||||
-- Reload logfiles with CLI command 'logger reload' and rotate logs with "logger rotate'
|
||||
-- Configurable DEBUG, NOTICE, WARNING, ERROR and ast_verbose messages now appear on remote console
|
||||
-- Properly reaping any zombie processes
|
||||
-- Added applications SayUnixTime, SetCDRUserField, HasNewVoicemail, ZapScan, Random, ResetCDR, NoCDR
|
||||
-- Make PRI Hangup Cause available to the dialplan
|
||||
-- Verify included contexts in extensions.conf
|
||||
-- Add DESTDIR support for building RPMs and packages
|
||||
-- Do route lookups on OpenBSD
|
||||
-- Add support for building on FreeBSD and OS X
|
||||
-- Add support for PostgreSQL in Voicemail
|
||||
-- Translate SIP hangup cause to PRI hangup cause where needed
|
||||
-- Better support for MOH in IAX2
|
||||
-- Fix SIP problem where channels were not removed on BYE
|
||||
-- Display codecs by name
|
||||
-- Remove MySQL and put PGSql instead for licensing reasons
|
||||
-- Better capability matching in SIP
|
||||
-- Full IBR4 compliance for chan_zap
|
||||
-- More flexible CDR handling
|
||||
-- Distinguish between BUSY and FAILURE on outbound calls
|
||||
-- Add initial support for SCCP via chan_skinny
|
||||
-- Better support for Future Group B signaling
|
||||
Asterisk 0.5.0
|
||||
-- Retain IAX2 and SIP registrations past shutdown/crash and restart
|
||||
-- True data mode bridging when possible
|
||||
-- H.323 build improvements
|
||||
-- Agent Callback-login support
|
||||
-- RFC2833 Improvements
|
||||
-- Add thread debugging
|
||||
-- Add optional pedantic SIP checking for Pingtel
|
||||
-- Allow extension names, include context, switch to use global vars.
|
||||
-- Allow variables in extensions.conf to reference previously defined ones
|
||||
-- Merge voicemail enhancements (app_voicemail2)
|
||||
-- Add multiple queueing strategies
|
||||
-- Merge support for 'T'
|
||||
-- Allow pending agent calling (Agent/:1)
|
||||
-- Add groupings to agents.conf
|
||||
-- Add video support to IAX2
|
||||
-- Zaptel optimize playback
|
||||
-- Add video support to SIP
|
||||
-- Make RTP ports configurable
|
||||
-- Add RDNIS support to SIP and IAX2
|
||||
-- Add transfer app (implement in SIP and IAX2)
|
||||
-- Make voicemail segmentable by context (app_voicemail2)
|
||||
-- Major restructuring of voicemail (app_voicemail2)
|
||||
-- Add initial ENUM support
|
||||
-- Add malloc debugging support
|
||||
-- Add preliminary Voicetronix support
|
||||
-- Add iLBC codec
|
||||
Asterisk 0.4.0
|
||||
-- Merge and edit Nick's FXO dial support
|
||||
-- Reengineer SIP registration (outbound)
|
||||
-- Support call pickup on SIP and compatibly with ZAP
|
||||
-- Support 302 Redirect on SIP
|
||||
-- Management interface improvements
|
||||
-- Add "hint" support
|
||||
-- Improve call forwarding using new "Local" channel driver.
|
||||
-- Add "Local" channel
|
||||
-- Substantial SIP enhancements including retransmissions
|
||||
-- Enforce case sensitivity on extension/context names
|
||||
-- Add monitor support (Thanks, Mahmut)
|
||||
-- Add experimental "trunk" option to IAX2 for high density VoIP
|
||||
-- Add experimental "debug channel" command
|
||||
-- Add 'C' flag to dial command to reset call detail record (handy for calling cards)
|
||||
-- Add NAT and dynamic support to MGCP
|
||||
-- Allow selection of in-band, out-of-band, or INFO based DTMF
|
||||
-- Add contributed "*80" support to blacklist numbers (Thanks James!)
|
||||
-- Add "NAT" option to sip user, peer, friend
|
||||
-- Add experimental "IAX2" protocol
|
||||
-- Change special variable "EXTEN-n" to "EXTEN:n" to follow Bash syntax
|
||||
-- Add "Enhanced" AGI with audio pass-through (voice recognition anyone?)
|
||||
-- Choose best priority from codec from allow/disallow
|
||||
-- Reject SIP calls to self
|
||||
-- Allow SIP registration to provide an alternative contact
|
||||
-- Make HOLD on SIP make use of asterisk MOH
|
||||
-- Add supervised transfer (tested with Pingtel only)
|
||||
-- Allow maxexpirey and defaultexpirey to be runtime configurable for SIP
|
||||
-- Preliminary codec 13 support (RFC3389)
|
||||
-- Add app_authenticate for general purpose authentication
|
||||
-- Optimize RTP and smoother
|
||||
-- Create special variable "EXTEN-n" where it is extension stripped by n MSD
|
||||
-- Fix uninitialized frame pointer in channel.c
|
||||
-- Add global variables support under [globals] of extensions.conf
|
||||
-- Add macro support (show application Macro)
|
||||
-- Allow [123-5] etc in extensions
|
||||
-- Allow format of App(arg1,arg2,...) instead of just App,arg1|arg2 in dialplan
|
||||
-- Add message waiting indicator to SIP
|
||||
-- Fix double free bug in channel.c
|
||||
Asterisk 0.3.0
|
||||
-- Add fastfoward, rewind, seek, and truncate functions to streams
|
||||
-- Support registration
|
||||
-- Add G729 format
|
||||
-- Permit applications to return a digit indicating new extension
|
||||
-- Change "SHUTDOWN" to "STOP" in commands
|
||||
-- SIP "Hold" fixes and VXML URI support
|
||||
-- New chan_zap with 160 sample chunk size
|
||||
-- Add DTMF, MF, and Fax tone detector to dsp routines
|
||||
-- Allow overlap dialing (inbound) on PRI
|
||||
-- Enable tone detection with PRI
|
||||
-- Add special information tone detection
|
||||
-- Add Asterisk DB support
|
||||
-- Add pulse dialing
|
||||
-- Re-record all system prompts
|
||||
-- Change "timelen" to samples for better accuracy
|
||||
-- Move to editline, eliminating readline dependency
|
||||
-- Add peer "poke" support to SIP and IAX
|
||||
-- Add experimental call progress detection
|
||||
-- Add SIP authentication (digest)
|
||||
-- Add RDNIS
|
||||
-- Reroute faxes to "fax" extension
|
||||
-- Create ISDN/modem group concept
|
||||
-- Centralize indication
|
||||
-- Add initial MGCP support
|
||||
-- SIP debugging cleanup
|
||||
-- SIP reload
|
||||
-- SIP commands (show channels, etc)
|
||||
-- Add optional busy detection
|
||||
-- Add Visual Message Waiting Indicator (MDMF and SDMF)
|
||||
-- Add ambiguous extension matching
|
||||
-- Add *69
|
||||
-- Major SIP enhancements from SIPit
|
||||
-- Rewrite of ZAP CLASS features using subchannels
|
||||
-- Enhanced call parking
|
||||
-- Add extended outgoing spool support (pbx_spool)
|
||||
Asterisk 0.2.0
|
||||
-- Outbound origination API
|
||||
-- Call management improvements
|
||||
-- Add Do Not Disturb (*78, *79)
|
||||
-- Add agents
|
||||
-- Document variables
|
||||
-- Add transfer capability on the console
|
||||
-- Add SpeeX codec translator
|
||||
-- Add call queues
|
||||
-- Add setcallerid functionality (AGI, application)
|
||||
-- Add special variables ${CALLERID}, ${EXTEN}, ${CONTEXT}, ${PRIORITY}
|
||||
-- Don't echo cancel on pure TDM connections by default
|
||||
-- Implement Async GOTO
|
||||
-- Differentiate softhangups
|
||||
-- Add date/time
|
||||
Asterisk 0.1.12
|
||||
-- Fix for Big Endian machines
|
||||
-- MySQL CDR Engine
|
||||
-- Various SIP fixes and enhancements
|
||||
-- Add "zapateller application and arbitrary tone pairs
|
||||
-- Don't always start at "s"
|
||||
-- Separate linear mode for pseudo and real
|
||||
-- Add initial RTP and SIP support (no jitter buffer yet, unknown stability)
|
||||
-- Add 'h' extension, executed on hangup
|
||||
-- Add duration timer to message info
|
||||
-- Add web based voicemail checking ("make webvmail")
|
||||
-- Add ast_queue_frame function and eliminate frame pipes in most drivers
|
||||
-- Centralize host access (and possibly future ACL's)
|
||||
-- Add Caller*ID on PhoneJack (Thanks Nathan)
|
||||
-- Add "safe_asterisk" wrapper script to auto-restart Asterisk
|
||||
-- Indicate ringback on chan_phone
|
||||
-- Add answer confirmation (press '#' to confirm answer)
|
||||
-- Add distinctive ring support (e.g. Dial,Zap/4r2)
|
||||
-- Add ANSI/vt100 color support
|
||||
-- Make parking configurable through parking.conf
|
||||
-- Fix the empty voicemail problem
|
||||
-- Add Music On Hold
|
||||
-- Add ADSI Compiler (app_adsiprog)
|
||||
-- Extensive DISA re-work to improve tone generation
|
||||
-- Reset all idle channels every 10 minutes on a PRI
|
||||
-- Reset channels which are hungup with "channel in use"
|
||||
-- Implement VNAK support in chan_iax
|
||||
-- Fix chan_oss to support proper hangups and autoanswer
|
||||
-- Make shutdown properly hangup channels
|
||||
-- Add idling capability to chan_zap for idle-net
|
||||
-- Add "MeetMe" conferencing app (app_meetme)
|
||||
-- Add timing information to include
|
||||
Asterisk 0.1.11
|
||||
-- Add ISDN RAS capability
|
||||
-- Add stutter dialtone to Chan Zap
|
||||
-- Add "#include" capability to config files.
|
||||
-- Add call-forward variable to Chan Zap (*72, *73)
|
||||
-- Optimize IAX flow when transfer isn't possible
|
||||
-- Allow transmission of ANI over IAX
|
||||
Asterisk 0.1.10
|
||||
-- Make ast_readstring parameter be the max # of digits, not the max size with \0
|
||||
-- Make up any missing messages on the fly
|
||||
-- Add support for specific DTMF interruption to saying numbers
|
||||
-- Add new "u" and "b" options to condense busy/unavail handling
|
||||
-- Add support for RSA authentication on IAX calls
|
||||
-- Add support for ADSI compatible CPE
|
||||
-- Outgoing call queue
|
||||
-- Remote dialplan fixes for Quicknet
|
||||
-- Added AGI commands supporting TDD functions (RECEIVE CHAR & TDD MODE)
|
||||
-- Added TDD support (send/receive text in chan_zap)
|
||||
-- Fix all strncpy references
|
||||
-- Implement CSV CDR backend
|
||||
-- Implement Call Detail Records
|
||||
Asterisk 0.1.9
|
||||
-- Implement IAX quelching
|
||||
-- Allow Caller*ID to be overridden and suggested
|
||||
-- Configure defaults to use IAXTEL
|
||||
-- Allow remote dialplan polling via IAX
|
||||
-- Eliminate ast_longest_extension
|
||||
-- Implement dialplan request/reply
|
||||
-- Let peers have allow/disallow for codecs
|
||||
-- Change allow/deny to permit/deny in IAX
|
||||
-- Allow dialplan entries to match Caller*ID as well
|
||||
-- Added AGI (Asterisk Gateway Interface) scripting interface (app_agi)
|
||||
-- Added chan_zap for zapata telephony kernel interface, removed chan_tor
|
||||
-- Add convenience functions
|
||||
-- Fix race condition in channel hangup
|
||||
-- Fix memory leaks in both asterisk and iax frame allocations
|
||||
-- Add "iax show stats" command and -DTRACE_FRAMES (for frame tracing)
|
||||
-- Add DISA application (Thanks to Jim Dixon)
|
||||
-- Add IAX transfer support
|
||||
-- Add URL and HTML transmission
|
||||
-- Add application for sending images
|
||||
-- Add RedHat RPM spec file and build capability
|
||||
-- Fix GSM WAV file format bug
|
||||
-- Move ignorepat to main dialplan
|
||||
-- Add ability to specificy TOS bits in IAX
|
||||
-- Allow username:password in IAX strings
|
||||
-- Updates to PhoneJack interface
|
||||
-- Allow "servermail" in voicemail.conf to override e-mail in "from" line
|
||||
-- Add 'skip' option to app_playback
|
||||
-- Reject IAX calls on unknown extensions
|
||||
-- Fix version stuff
|
||||
Asterisk 0.1.8
|
||||
-- Keep track of version information
|
||||
-- Add -f to cause Asterisk not to fork
|
||||
-- Keep important information in voicemail .txt file
|
||||
-- Adtran Voice over Frame Relay updates
|
||||
-- Implement option setting/querying of channel drivers
|
||||
-- IAX performance improvements and protocol fixes
|
||||
-- Substantial enhancement of console channel driver
|
||||
-- Add IAX registration. Now IAX can dynamically register
|
||||
-- Add flash-hook transfer on tormenta channels
|
||||
-- Added Three Way Calling on tormenta channels
|
||||
-- Start on concept of zombie channel
|
||||
-- Add Call Waiting CallerID
|
||||
-- Keep track of who registeres contexts, includes, and extensions
|
||||
-- Added Call Waiting(tm), *67, *70, and *82 codes
|
||||
-- Move parked calls into "parkedcalls" context by default
|
||||
-- Allow dialplan to be displayed
|
||||
-- Allow "=>" instead of just "=" to make instantiation clearer
|
||||
-- Asterisk forks if called with no arguments
|
||||
-- Add remote control by running asterisk -vvvc
|
||||
-- Adjust verboseness with "set verbose" now
|
||||
-- No longer requires libaudiofile
|
||||
-- Install beep
|
||||
-- Make PBX Config module reload extensions on SIGHUP
|
||||
-- Allow modules to be reloaded when SIGHUP is received
|
||||
-- Variables now contain line numbers
|
||||
-- Make dialer send in band signalling
|
||||
-- Add record application
|
||||
-- Added PRI signalling to Tormenta driver
|
||||
-- Allow use of BYEXTENSION in "Goto"
|
||||
-- Allow adjustment of gains on tormenta channels
|
||||
-- Added raw PCM file format support
|
||||
-- Add U-law translator
|
||||
-- Fix DTMF handling in bridge code
|
||||
-- Fix access control with IAX
|
||||
* Asterisk 0.1.7
|
||||
-- Update configuration files and add some missing sounds
|
||||
-- Added ability to include one context in another
|
||||
-- Rewrite of PBX switching
|
||||
-- Major mods to dialler application
|
||||
-- Added Caller*ID spill reception
|
||||
-- Added Dialogic VOX file format support
|
||||
-- Added ADPCM Codec
|
||||
-- Add Tormenta driver (RBS signalling)
|
||||
-- Add Caller*ID spill creation
|
||||
-- Rewrite of translation layer entirely
|
||||
-- Add ability to run PBX without additional thread
|
||||
* Asterisk 0.1.6
|
||||
-- Make app_dial handle a lack of translators smoothly
|
||||
-- Add ISDN4Linux support -- dtmf is weird...
|
||||
-- Minor bug fixes
|
||||
* Asterisk 0.1.5
|
||||
-- Fix a small mistake in IAX
|
||||
-- Fix the QuickNet driver to work with newer cards
|
||||
* Asterisk 0.1.4
|
||||
-- Update VoFR some more
|
||||
-- Fix the QuickNet driver to work with LineJack
|
||||
-- Add ability to pass images for IAX.
|
||||
* Asterisk 0.1.3
|
||||
-- Update VoFR for latest sangoma code
|
||||
-- Update QuickNet Driver
|
||||
-- Add text message handling
|
||||
-- Fix transfers to use "default" if not in current context
|
||||
-- Add call parking
|
||||
-- Improve format/content negotiation
|
||||
-- Added support for multiple languages
|
||||
-- Bug fixes, as always...
|
||||
* Asterisk 0.1.2
|
||||
-- Updated README file with a "Getting Started" section
|
||||
-- Added sample sounds and configuration files.
|
||||
-- Added LPC10 very low bandwidth (low quality) compression
|
||||
-- Enhanced translation selection mechanism.
|
||||
-- Enhanced IAX jitter buffer, improved reliability
|
||||
-- Support echo cancelation on PhoneJack
|
||||
-- Updated PhoneJack driver to std. Telephony interface
|
||||
-- Added app_echo for evaluating VoIP latency
|
||||
-- Added app_system to execute arbitrary programs
|
||||
-- Updated sample configuration files
|
||||
-- Added OSS channel driver (full duplex only)
|
||||
-- Added IAX implementation
|
||||
-- Fixed some deadlocks.
|
||||
-- A whole bunch of bug fixes
|
||||
* Asterisk 0.1.1
|
||||
-- Revised translator, fixed some general race conditions throughout *
|
||||
-- Made dialer somewhat more aware of incompatible voice channels
|
||||
-- Added Voice Modem driver and A/Open Modem Driver stub
|
||||
-- Added MP3 decoder channel
|
||||
-- Added Microsoft WAV49 support
|
||||
-- Revised License -- Pure GPL, nothing else
|
||||
-- Modified Copyright statement since code is still currently owned by author
|
||||
-- Added RAW GSM headerless data format
|
||||
-- Innumerable bug fixes
|
||||
* Asterisk 0.1.0
|
||||
-- Initial Release
|
||||
70
HARDWARE
Normal file
70
HARDWARE
Normal file
@@ -0,0 +1,70 @@
|
||||
A PBX is only really useful if you can get calls into it. Of course, you
|
||||
can use Asterisk with VoIP calls (SIP, H.323, IAX), but you can also talk
|
||||
to the real PSTN through various cards.
|
||||
|
||||
Supported Hardware is divided into two general groups: Zaptel devices and
|
||||
non-zaptel devices. The Zaptel compatible hardware supports pseudo-TDM
|
||||
conferencing and all call features through chan_zap, whereas non-zaptel
|
||||
compatible hardware may have different features.
|
||||
|
||||
Zaptel compatible hardware
|
||||
==========================
|
||||
|
||||
-- Digium (Primary author of Asterisk)
|
||||
http://www.digium.com, http://store.yahoo.com/asteriskpbx
|
||||
|
||||
* Wildcard X100P - Single FXO interface connects to Loopstart phone
|
||||
line
|
||||
|
||||
* Wildcard T400P (obsolete) - Quad T1 interface connects to four T1/PRI
|
||||
interfaces. Supports RBS and PRI voice and PPP, FR, and HDLC data.
|
||||
|
||||
* Wildcard E400P (obsolete)- Quad E1 interface connects to four E1/PRI
|
||||
(or PRA) interfaces. Supports PRA/PRI, EuroISDN voice and data.
|
||||
|
||||
* Wildcard T100P - Single T1 interface connects to a single T1/PRI
|
||||
interface. Supports RBS and PRI voice and PPP, FR, and HDLC data.
|
||||
|
||||
* Wildcard E100P - Single E1 interface connects to a single E1/PRI (or PRA)
|
||||
interface. Supports PRA/PRI, EuroISDN voice and PPP, FR, HDLC data.
|
||||
|
||||
* Wildcard S100U - Single FXS interface connects to a standard analog
|
||||
telephone.
|
||||
|
||||
* Wildcard TDM400P - Quad Modular FXS interface connects to standard
|
||||
analog telephones.
|
||||
|
||||
* Wildcard TE410P - Quad T1/E1 switchable interface. Supports PRI and
|
||||
RBS signalling, as well as PPP, FR, and HDLC data modes.
|
||||
|
||||
Non-zaptel compatible hardware
|
||||
==============================
|
||||
|
||||
-- QuickNet, Inc.
|
||||
http://www.quicknet.net
|
||||
|
||||
* Internet PhoneJack - Single FXS interface. Supports Linux telephony
|
||||
interface. DSP compression built-in.
|
||||
|
||||
* Internet LineJack - Single FXS or FXO interface. Supports Linux
|
||||
telephony interface.
|
||||
|
||||
|
||||
Miscellaneous other interfaces
|
||||
==============================
|
||||
|
||||
-- ISDN4Linux
|
||||
http://www.isdn4linux.de/
|
||||
|
||||
* Any ISDN terminal adapter supported by isdn4linux should provide
|
||||
connectivity.
|
||||
|
||||
-- ALSA
|
||||
http://www.alsa-project.org
|
||||
|
||||
* Any ALSA compatible full-duplex sound card
|
||||
|
||||
-- OSS
|
||||
http://www.opensound.com
|
||||
|
||||
* Any OSS compatible full-duplex sound card
|
||||
583
Makefile
Executable file → Normal file
583
Makefile
Executable file → Normal file
@@ -11,24 +11,228 @@
|
||||
# the GNU General Public License
|
||||
#
|
||||
|
||||
|
||||
.EXPORT_ALL_VARIABLES:
|
||||
|
||||
MODULES_DIR=/usr/lib/asterisk/modules
|
||||
# Create OPTIONS variable
|
||||
OPTIONS=
|
||||
|
||||
OSARCH=$(shell uname -s)
|
||||
|
||||
ifeq (${OSARCH},Linux)
|
||||
PROC=$(shell uname -m)
|
||||
ifeq ($(PROC),x86_64)
|
||||
# You must have GCC 3.4 to use k8, otherwise use athlon
|
||||
PROC=k8
|
||||
#PROC=athlon
|
||||
OPTIONS+=-m64
|
||||
endif
|
||||
ifeq ($(PROC),sparc64)
|
||||
#The problem with sparc is the best stuff is in newer versions of gcc (post 3.0) only.
|
||||
#This works for even old (2.96) versions of gcc and provides a small boost either way.
|
||||
#A ultrasparc cpu is really v9 but the stock debian stable 3.0 gcc doesn't support it.
|
||||
#So we go lowest common available by gcc and go a step down, still a step up from
|
||||
#the default as we now have a better instruction set to work with. - Belgarath
|
||||
PROC=ultrasparc
|
||||
OPTIONS+=$(shell if $(CC) -mtune=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mtune=$(PROC)"; fi)
|
||||
OPTIONS+=$(shell if $(CC) -mcpu=v8 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mcpu=v8"; fi)
|
||||
OPTIONS+=-fomit-frame-pointer
|
||||
endif
|
||||
|
||||
MPG123TARG=linux
|
||||
endif
|
||||
|
||||
ifeq ($(findstring BSD,${OSARCH}),BSD)
|
||||
PROC=$(shell uname -m)
|
||||
endif
|
||||
|
||||
# Pentium Pro Optimize
|
||||
#PROC=i686
|
||||
# Pentium Optimize
|
||||
PROC=i586
|
||||
|
||||
# Pentium & VIA processors optimize
|
||||
#PROC=i586
|
||||
|
||||
#PROC=k6
|
||||
#PROC=ppc
|
||||
|
||||
PWD=$(shell pwd)
|
||||
|
||||
######### More GSM codec optimization
|
||||
######### Uncomment to enable MMXTM optimizations for x86 architecture CPU's
|
||||
######### which support MMX instructions. This should be newer pentiums,
|
||||
######### ppro's, etc, as well as the AMD K6 and K7.
|
||||
#K6OPT = -DK6OPT
|
||||
|
||||
#Tell gcc to optimize the asterisk's code
|
||||
OPTIMIZE+=-O6
|
||||
|
||||
#Include debug symbols in the executables (-g) and profiling info (-pg)
|
||||
DEBUG=-g #-pg
|
||||
|
||||
# If you are running a radio application, define RADIO_RELAX so that the DTMF
|
||||
# will be received more reliably
|
||||
#OPTIONS += -DRADIO_RELAX
|
||||
|
||||
# If you don't have a lot of memory (e.g. embedded Asterisk), uncomment the
|
||||
# following to reduce the size of certain static buffers
|
||||
#OPTIONS += -DLOW_MEMORY
|
||||
|
||||
# Optional debugging parameters
|
||||
DEBUG_THREADS = #-DDEBUG_THREADS #-DDO_CRASH
|
||||
|
||||
# Uncomment next one to enable ast_frame tracing (for debugging)
|
||||
TRACE_FRAMES = #-DTRACE_FRAMES
|
||||
|
||||
# Uncomment next one to enable malloc debugging
|
||||
# You can view malloc debugging with:
|
||||
# *CLI> show memory allocations [filename]
|
||||
# *CLI> show memory summary [filename]
|
||||
#
|
||||
MALLOC_DEBUG = #-include $(PWD)/include/asterisk/astmm.h
|
||||
|
||||
# Where to install asterisk after compiling
|
||||
# Default -> leave empty
|
||||
INSTALL_PREFIX=
|
||||
|
||||
# Staging directory
|
||||
# Files are copied here temporarily during the install process
|
||||
# For example, make DESTDIR=/tmp/asterisk woud put things in
|
||||
# /tmp/asterisk/etc/asterisk
|
||||
DESTDIR=
|
||||
|
||||
# Original busydetect routine
|
||||
BUSYDETECT = #-DBUSYDETECT
|
||||
|
||||
# Improved busydetect routine, comment the previous one if you use this one
|
||||
BUSYDETECT+= -DBUSYDETECT_MARTIN
|
||||
# Detect the busy signal looking only at tone lengths
|
||||
# For example if you have 3 beeps 100ms tone, 100ms silence separated by 500 ms of silence
|
||||
BUSYDETECT+= #-DBUSYDETECT_TONEONLY
|
||||
# Inforce the detection of busy singal (get rid of false hangups)
|
||||
# Don't use together with -DBUSYDETECT_TONEONLY
|
||||
BUSYDETECT+= #-DBUSYDETECT_COMPARE_TONE_AND_SILENCE
|
||||
|
||||
ASTLIBDIR=$(INSTALL_PREFIX)/usr/lib/asterisk
|
||||
ASTVARLIBDIR=$(INSTALL_PREFIX)/var/lib/asterisk
|
||||
ASTETCDIR=$(INSTALL_PREFIX)/etc/asterisk
|
||||
ASTSPOOLDIR=$(INSTALL_PREFIX)/var/spool/asterisk
|
||||
ASTLOGDIR=$(INSTALL_PREFIX)/var/log/asterisk
|
||||
ASTHEADERDIR=$(INSTALL_PREFIX)/usr/include/asterisk
|
||||
ASTCONFPATH=$(ASTETCDIR)/asterisk.conf
|
||||
ASTBINDIR=$(INSTALL_PREFIX)/usr/bin
|
||||
ASTSBINDIR=$(INSTALL_PREFIX)/usr/sbin
|
||||
ASTVARRUNDIR=$(INSTALL_PREFIX)/var/run
|
||||
ASTMANDIR=$(INSTALL_PREFIX)/usr/share/man
|
||||
|
||||
MODULES_DIR=$(ASTLIBDIR)/modules
|
||||
AGI_DIR=$(ASTVARLIBDIR)/agi-bin
|
||||
|
||||
INCLUDE=-Iinclude -I../include
|
||||
CFLAGS=-pipe -Wall -Werror -Wmissing-prototypes -Wmissing-declarations -O6 $(DEBUG) $(INCLUDE) -D_REENTRANT
|
||||
CFLAGS=-pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations $(DEBUG) $(INCLUDE) -D_REENTRANT -D_GNU_SOURCE #-DMAKE_VALGRIND_HAPPY
|
||||
CFLAGS+=$(OPTIMIZE)
|
||||
|
||||
ifneq ($(PROC),ultrasparc)
|
||||
CFLAGS+=$(shell if $(CC) -march=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=$(PROC)"; fi)
|
||||
CFLAGS+=$(shell [ ! -f /usr/include/linux/if_wanpipe.h ] && echo " -DOLD_SANGOMA_API")
|
||||
SUBDIRS=channels pbx apps codecs formats
|
||||
LIBS=-ldl -lpthread -lreadline #-lefence
|
||||
OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o translate.o file.o say.o pbx.o cli.o md5.o asterisk.o
|
||||
endif
|
||||
|
||||
CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi)
|
||||
CFLAGS+=$(shell if [ -f /usr/include/osp/osp.h ]; then echo "-DOSP_SUPPORT -I/usr/include/osp" ; fi)
|
||||
|
||||
ifeq (${OSARCH},FreeBSD)
|
||||
OSVERSION=$(shell make -V OSVERSION -f /usr/share/mk/bsd.port.subdir.mk)
|
||||
CFLAGS+=$(shell if test ${OSVERSION} -lt 500016 ; then echo "-D_THREAD_SAFE"; fi)
|
||||
LIBS+=$(shell if test ${OSVERSION} -lt 502102 ; then echo "-lc_r"; else echo "-pthread"; fi)
|
||||
INCLUDE+=-I/usr/local/include
|
||||
CFLAGS+=$(shell if [ -d /usr/local/include/spandsp ]; then echo "-I/usr/local/include/spandsp"; fi)
|
||||
MPG123TARG=freebsd
|
||||
endif # FreeBSD
|
||||
|
||||
ifeq (${OSARCH},NetBSD)
|
||||
CFLAGS+=-pthread
|
||||
INCLUDE+=-I/usr/local/include -I/usr/pkg/include
|
||||
MPG123TARG=netbsd
|
||||
endif
|
||||
|
||||
ifeq (${OSARCH},OpenBSD)
|
||||
CFLAGS+=-pthread
|
||||
endif
|
||||
|
||||
#Uncomment this to use the older DSP routines
|
||||
#CFLAGS+=-DOLD_DSP_ROUTINES
|
||||
|
||||
CFLAGS+=$(shell if [ -f /usr/include/linux/zaptel.h ]; then echo "-DZAPTEL_OPTIMIZATIONS"; fi)
|
||||
CFLAGS+=$(shell if [ -f /usr/local/include/zaptel.h ]; then echo "-DZAPTEL_OPTIMIZATIONS"; fi)
|
||||
|
||||
LIBEDIT=editline/libedit.a
|
||||
|
||||
ASTERISKVERSION=$(shell if [ -f .version ]; then cat .version; else if [ -d CVS ]; then if [ -f CVS/Tag ] ; then echo "CVS-`sed 's/^T//g' CVS/Tag`-`date +"%D-%T"`"; else echo "CVS-HEAD-`date +"%D-%T"`"; fi; fi; fi)
|
||||
HTTPDIR=$(shell if [ -d /var/www ]; then echo "/var/www"; else echo "/home/httpd"; fi)
|
||||
RPMVERSION=$(shell if [ -f .version ]; then sed 's/[-\/:]/_/g' .version; else echo "unknown" ; fi)
|
||||
CFLAGS+=-DASTERISK_VERSION=\"$(ASTERISKVERSION)\"
|
||||
CFLAGS+=-DINSTALL_PREFIX=\"$(INSTALL_PREFIX)\"
|
||||
CFLAGS+=-DASTETCDIR=\"$(ASTETCDIR)\"
|
||||
CFLAGS+=-DASTLIBDIR=\"$(ASTLIBDIR)\"
|
||||
CFLAGS+=-DASTVARLIBDIR=\"$(ASTVARLIBDIR)\"
|
||||
CFLAGS+=-DASTVARRUNDIR=\"$(ASTVARRUNDIR)\"
|
||||
CFLAGS+=-DASTSPOOLDIR=\"$(ASTSPOOLDIR)\"
|
||||
CFLAGS+=-DASTLOGDIR=\"$(ASTLOGDIR)\"
|
||||
CFLAGS+=-DASTCONFPATH=\"$(ASTCONFPATH)\"
|
||||
CFLAGS+=-DASTMODDIR=\"$(MODULES_DIR)\"
|
||||
CFLAGS+=-DASTAGIDIR=\"$(AGI_DIR)\"
|
||||
|
||||
CFLAGS+= $(DEBUG_THREADS)
|
||||
CFLAGS+= $(TRACE_FRAMES)
|
||||
CFLAGS+= $(MALLOC_DEBUG)
|
||||
CFLAGS+= $(BUSYDETECT)
|
||||
CFLAGS+= $(OPTIONS)
|
||||
CFLAGS+=# -fomit-frame-pointer
|
||||
SUBDIRS=res channels pbx apps codecs formats agi cdr astman stdtime
|
||||
ifeq (${OSARCH},Linux)
|
||||
LIBS=-ldl -lpthread
|
||||
endif
|
||||
LIBS+=-lncurses -lm
|
||||
ifeq (${OSARCH},Linux)
|
||||
LIBS+=-lresolv #-lnjamd
|
||||
endif
|
||||
ifeq (${OSARCH},Darwin)
|
||||
LIBS+=-lresolv
|
||||
endif
|
||||
ifeq (${OSARCH},FreeBSD)
|
||||
LIBS+=-lcrypto
|
||||
endif
|
||||
ifeq (${OSARCH},NetBSD)
|
||||
LIBS+=-lpthread -lcrypto -lm -L/usr/local/lib -L/usr/pkg/lib -lncurses
|
||||
endif
|
||||
ifeq (${OSARCH},OpenBSD)
|
||||
LIBS=-lcrypto -lpthread -lm -lncurses
|
||||
endif
|
||||
LIBS+=-lssl
|
||||
OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o \
|
||||
translate.o file.o say.o pbx.o cli.o md5.o term.o \
|
||||
ulaw.o alaw.o callerid.o fskmodem.o image.o app.o \
|
||||
cdr.o tdd.o acl.o rtp.o manager.o asterisk.o ast_expr.o \
|
||||
dsp.o chanvars.o indications.o autoservice.o db.o privacy.o \
|
||||
astmm.o enum.o srv.o dns.o aescrypt.o aestab.o aeskey.o \
|
||||
utils.o
|
||||
ifeq (${OSARCH},Darwin)
|
||||
ASTLINK=-Wl,-dynamic
|
||||
SOLINK=-dynamic -bundle -undefined suppress -force_flat_namespace
|
||||
OBJS+= poll.o
|
||||
CFLAGS+=-DPOLLCOMPAT
|
||||
else
|
||||
ASTLINK=-Wl,-E
|
||||
SOLINK=-shared -Xlinker -x
|
||||
endif
|
||||
|
||||
ifeq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/sys/poll.h),)
|
||||
OBJS+= poll.o
|
||||
CFLAGS+=-DPOLLCOMPAT
|
||||
endif
|
||||
|
||||
ifeq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/dlfcn.h),)
|
||||
OBJS+= dhfcn.o
|
||||
CFLAGS+=-DDLFCNCOMPAT
|
||||
endif
|
||||
|
||||
CC=gcc
|
||||
INSTALL=install
|
||||
|
||||
@@ -38,68 +242,347 @@ _all: all
|
||||
@echo " + cannot be run before being installed by +"
|
||||
@echo " + running: +"
|
||||
@echo " + +"
|
||||
@echo " + make install +"
|
||||
@echo " + +"
|
||||
@echo " + $(MAKE) install +"
|
||||
@echo " +-------------------------------------------+"
|
||||
|
||||
all: asterisk subdirs
|
||||
all: depend asterisk subdirs
|
||||
|
||||
asterisk: $(OBJS)
|
||||
gcc -o asterisk -rdynamic $(OBJS) $(LIBS)
|
||||
editline/config.h:
|
||||
cd editline && unset CFLAGS LIBS && ./configure ; \
|
||||
|
||||
editline/libedit.a: FORCE
|
||||
cd editline && unset CFLAGS LIBS && test -f config.h || ./configure
|
||||
$(MAKE) -C editline libedit.a
|
||||
|
||||
db1-ast/libdb1.a: FORCE
|
||||
@if [ -d db1-ast ]; then \
|
||||
$(MAKE) -C db1-ast libdb1.a ; \
|
||||
else \
|
||||
echo "You need to do a cvs update -d not just cvs update"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
ifneq ($(wildcard .depend),)
|
||||
include .depend
|
||||
endif
|
||||
|
||||
.PHONY: _version
|
||||
|
||||
_version:
|
||||
if [ -d CVS ] && ! [ -f .version ]; then echo $(ASTERISKVERSION) > .version; fi
|
||||
|
||||
.version: _version
|
||||
|
||||
.y.c:
|
||||
bison $< --name-prefix=ast_yy -o $@
|
||||
|
||||
ast_expr.o: ast_expr.c
|
||||
|
||||
cli.o: cli.c build.h
|
||||
|
||||
asterisk.o: asterisk.c build.h
|
||||
|
||||
manpage: asterisk.8.gz
|
||||
|
||||
asterisk.8.gz: asterisk.sgml
|
||||
rm -f asterisk.8
|
||||
docbook2man asterisk.sgml
|
||||
mv ./*.8 asterisk.8
|
||||
gzip asterisk.8
|
||||
|
||||
ifneq ($(strip $(ASTERISKVERSION)),)
|
||||
build.h: .version
|
||||
./make_build_h
|
||||
else
|
||||
build.h:
|
||||
./make_build_h
|
||||
endif
|
||||
|
||||
stdtime/libtime.a: FORCE
|
||||
@if [ -d stdtime ]; then \
|
||||
$(MAKE) -C stdtime libtime.a ; \
|
||||
else \
|
||||
echo "You need to do a cvs update -d not just cvs update"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
asterisk: editline/libedit.a db1-ast/libdb1.a stdtime/libtime.a $(OBJS)
|
||||
$(CC) $(DEBUG) -o asterisk $(ASTLINK) $(OBJS) $(LIBEDIT) db1-ast/libdb1.a stdtime/libtime.a $(LIBS)
|
||||
|
||||
muted: muted.o
|
||||
$(CC) -o muted muted.o
|
||||
|
||||
subdirs:
|
||||
for x in $(SUBDIRS); do $(MAKE) -C $$x || exit 1 ; done
|
||||
|
||||
clean:
|
||||
for x in $(SUBDIRS); do $(MAKE) -C $$x clean || exit 1 ; done
|
||||
rm -f *.o *.so asterisk
|
||||
rm -f *.o *.so asterisk .depend
|
||||
rm -f build.h
|
||||
rm -f ast_expr.c
|
||||
@if [ -e editline/Makefile ]; then $(MAKE) -C editline distclean ; fi
|
||||
@if [ -d mpg123-0.59r ]; then $(MAKE) -C mpg123-0.59r clean; fi
|
||||
$(MAKE) -C db1-ast clean
|
||||
$(MAKE) -C stdtime clean
|
||||
|
||||
datafiles: all
|
||||
mkdir -p /var/lib/asterisk/sounds/digits
|
||||
for x in sounds/digits/*; do \
|
||||
install $$x /var/lib/asterisk/sounds/digits ; \
|
||||
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/digits
|
||||
for x in sounds/digits/*.gsm; do \
|
||||
if grep -q "^%`basename $$x`%" sounds.txt; then \
|
||||
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/digits ; \
|
||||
else \
|
||||
echo "No description for $$x"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
done
|
||||
for x in sounds/vm-* sounds/transfer* ; do \
|
||||
install $$x /var/lib/asterisk/sounds ; \
|
||||
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/letters
|
||||
for x in sounds/letters/*.gsm; do \
|
||||
if grep -q "^%`basename $$x`%" sounds.txt; then \
|
||||
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/letters ; \
|
||||
else \
|
||||
echo "No description for $$x"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
done
|
||||
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/phonetic
|
||||
for x in sounds/phonetic/*.gsm; do \
|
||||
if grep -q "^%`basename $$x`%" sounds.txt; then \
|
||||
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/phonetic ; \
|
||||
else \
|
||||
echo "No description for $$x"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
done
|
||||
for x in sounds/vm-* sounds/transfer* sounds/pbx-* sounds/ss-* sounds/beep* sounds/dir-* sounds/conf-* sounds/agent-* sounds/invalid* sounds/tt-* sounds/auth-* sounds/privacy-* sounds/queue-* sounds/hello-*; do \
|
||||
if grep -q "^%`basename $$x`%" sounds.txt; then \
|
||||
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds ; \
|
||||
else \
|
||||
echo "No description for $$x"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
done
|
||||
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/mohmp3
|
||||
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/images
|
||||
for x in images/*.jpg; do \
|
||||
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/images ; \
|
||||
done
|
||||
mkdir -p $(DESTDIR)$(AGI_DIR)
|
||||
|
||||
install: all
|
||||
mkdir -p $(MODULES_DIR)
|
||||
update:
|
||||
@if [ -d CVS ]; then \
|
||||
echo "Updating from CVS..." ; \
|
||||
cvs -q -z3 update -Pd; \
|
||||
rm -f .version; \
|
||||
else \
|
||||
echo "Not CVS"; \
|
||||
fi
|
||||
|
||||
bininstall: all
|
||||
mkdir -p $(DESTDIR)$(MODULES_DIR)
|
||||
mkdir -p $(DESTDIR)$(ASTSBINDIR)
|
||||
mkdir -p $(DESTDIR)$(ASTETCDIR)
|
||||
mkdir -p $(DESTDIR)$(ASTBINDIR)
|
||||
mkdir -p $(DESTDIR)$(ASTSBINDIR)
|
||||
mkdir -p $(DESTDIR)$(ASTVARRUNDIR)
|
||||
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail
|
||||
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/tmp
|
||||
install -m 755 asterisk $(DESTDIR)$(ASTSBINDIR)/
|
||||
install -m 755 contrib/scripts/astgenkey $(DESTDIR)$(ASTSBINDIR)/
|
||||
install -m 755 contrib/scripts/autosupport $(DESTDIR)$(ASTSBINDIR)/
|
||||
if [ ! -f $(DESTDIR)$(ASTSBINDIR)/safe_asterisk ]; then \
|
||||
install -m 755 contrib/scripts/safe_asterisk $(DESTDIR)$(ASTSBINDIR)/ ;\
|
||||
fi
|
||||
for x in $(SUBDIRS); do $(MAKE) -C $$x install || exit 1 ; done
|
||||
install -d /usr/include/asterisk
|
||||
install include/asterisk/*.h /usr/include/asterisk
|
||||
rm -f /var/lib/asterisk/sounds/vm
|
||||
mkdir -p /var/spool/asterisk/vm
|
||||
rm -f /usr/lib/asterisk/modules/chan_ixj.so
|
||||
mkdir -p /var/lib/asterisk/sounds
|
||||
( cd /var/lib/asterisk/sounds ; ln -s ../../../spool/asterisk/vm . )
|
||||
install -d $(DESTDIR)$(ASTHEADERDIR)
|
||||
install -m 644 include/asterisk/*.h $(DESTDIR)$(ASTHEADERDIR)
|
||||
rm -f $(DESTDIR)$(ASTVARLIBDIR)/sounds/vm
|
||||
rm -f $(DESTDIR)$(ASTVARLIBDIR)/sounds/voicemail
|
||||
if [ ! -h $(DESTDIR)$(ASTSPOOLDIR)/vm ] && [ -d $(DESTDIR)$(ASTSPOOLDIR)/vm ]; then \
|
||||
mv $(DESTDIR)$(ASTSPOOLDIR)/vm $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default; \
|
||||
else \
|
||||
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default; \
|
||||
rm -f $(DESTDIR)$(ASTSPOOLDIR)/vm; \
|
||||
fi
|
||||
ln -s $(ASTSPOOLDIR)/voicemail/default $(DESTDIR)$(ASTSPOOLDIR)/vm
|
||||
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds
|
||||
mkdir -p $(DESTDIR)$(ASTLOGDIR)/cdr-csv
|
||||
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/keys
|
||||
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/firmware
|
||||
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/firmware/iax
|
||||
mkdir -p $(DESTDIR)$(ASTMANDIR)/man8
|
||||
install -m 644 keys/iaxtel.pub $(DESTDIR)$(ASTVARLIBDIR)/keys
|
||||
install -m 644 keys/freeworlddialup.pub $(DESTDIR)$(ASTVARLIBDIR)/keys
|
||||
install -m 644 asterisk.8.gz $(DESTDIR)$(ASTMANDIR)/man8
|
||||
install -m 644 contrib/scripts/astgenkey.8 $(DESTDIR)$(ASTMANDIR)/man8
|
||||
install -m 644 contrib/scripts/autosupport.8 $(DESTDIR)$(ASTMANDIR)/man8
|
||||
install -m 644 contrib/scripts/safe_asterisk.8 $(DESTDIR)$(ASTMANDIR)/man8
|
||||
if [ -d contrib/firmware/iax ]; then \
|
||||
install -m 644 contrib/firmware/iax/iaxy.bin $(DESTDIR)$(ASTVARLIBDIR)/firmware/iax/iaxy.bin; \
|
||||
else \
|
||||
echo "You need to do cvs update -d not just cvs update" ; \
|
||||
fi
|
||||
( cd $(DESTDIR)$(ASTVARLIBDIR)/sounds ; ln -s $(ASTSPOOLDIR)/vm . )
|
||||
( cd $(DESTDIR)$(ASTVARLIBDIR)/sounds ; ln -s $(ASTSPOOLDIR)/voicemail . )
|
||||
if [ -f mpg123-0.59r/mpg123 ]; then $(MAKE) -C mpg123-0.59r install; fi
|
||||
@echo " +---- Asterisk Installation Complete -------+"
|
||||
@echo " + +"
|
||||
@echo " + YOU MUST READ THE SECURITY DOCUMENT +"
|
||||
@echo " + +"
|
||||
@echo " + Asterisk has successfully been installed. +"
|
||||
@echo " + If you would like to install the sample +"
|
||||
@echo " + configuration files (overwriting any +"
|
||||
@echo " + existing config files), run: +"
|
||||
@echo " + +"
|
||||
@echo " + make samples +"
|
||||
@echo " + $(MAKE) samples +"
|
||||
@echo " + +"
|
||||
@echo " +----------------- or ---------------------+"
|
||||
@echo " + +"
|
||||
@echo " + You can go ahead and install the asterisk +"
|
||||
@echo " + program documentation now or later run: +"
|
||||
@echo " + +"
|
||||
@echo " + $(MAKE) progdocs +"
|
||||
@echo " + +"
|
||||
@echo " + **Note** This requires that you have +"
|
||||
@echo " + doxygen installed on your local system +"
|
||||
@echo " +-------------------------------------------+"
|
||||
@echo " + +"
|
||||
@echo " + ** NOTE FOR DOWNGRADING FROM CVS HEAD ** +"
|
||||
@echo " + +"
|
||||
@echo " + If you are downgrading from CVS HEAD to +"
|
||||
@echo " + a stable release, remember to delete +"
|
||||
@echo " + everything from your asterisk modules +"
|
||||
@echo " + directory (/usr/lib/asterisk/modules/) +"
|
||||
@echo " + and the asterisk header directory +"
|
||||
@echo " + (/usr/include/asterisk/) +"
|
||||
@echo " + before doing a '$(MAKE) install'. +"
|
||||
@echo " + +"
|
||||
@echo " +-------------------------------------------+"
|
||||
|
||||
|
||||
install: all datafiles bininstall
|
||||
|
||||
upgrade: all bininstall
|
||||
|
||||
adsi: all
|
||||
mkdir -p $(DESTDIR)$(ASTETCDIR)
|
||||
for x in configs/*.adsi; do \
|
||||
if ! [ -f $(DESTDIR)$(ASTETCDIRX)/$$x ]; then \
|
||||
install -m 644 $$x $(DESTDIR)$(ASTETCDIR)/`basename $$x` ; \
|
||||
fi ; \
|
||||
done
|
||||
|
||||
samples: all datafiles adsi
|
||||
mkdir -p $(DESTDIR)$(ASTETCDIR)
|
||||
for x in configs/*.sample; do \
|
||||
if [ -f $(DESTDIR)$(ASTETCDIR)/`basename $$x .sample` ]; then \
|
||||
mv -f $(DESTDIR)$(ASTETCDIR)/`basename $$x .sample` $(DESTDIR)$(ASTETCDIR)/`basename $$x .sample`.old ; \
|
||||
fi ; \
|
||||
install -m 644 $$x $(DESTDIR)$(ASTETCDIR)/`basename $$x .sample` ;\
|
||||
done
|
||||
echo "[directories]" > $(DESTDIR)$(ASTETCDIR)/asterisk.conf
|
||||
echo "astetcdir => $(ASTETCDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
|
||||
echo "astmoddir => $(MODULES_DIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
|
||||
echo "astvarlibdir => $(ASTVARLIBDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
|
||||
echo "astagidir => $(AGI_DIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
|
||||
echo "astspooldir => $(ASTSPOOLDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
|
||||
echo "astrundir => $(ASTVARRUNDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
|
||||
echo "astlogdir => $(ASTLOGDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
|
||||
for x in sounds/demo-*; do \
|
||||
if grep -q "^%`basename $$x`%" sounds.txt; then \
|
||||
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds ; \
|
||||
else \
|
||||
echo "No description for $$x"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
done
|
||||
for x in sounds/*.mp3; do \
|
||||
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/mohmp3 ; \
|
||||
done
|
||||
rm -f $(DESTDIR)$(ASTVARLIBDIR)/mohmp3/sample-hold.mp3
|
||||
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/INBOX
|
||||
:> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/unavail.gsm
|
||||
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isunavail; do \
|
||||
cat $(DESTDIR)$(ASTVARLIBDIR)/sounds/$$x.gsm >> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/unavail.gsm ; \
|
||||
done
|
||||
:> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/busy.gsm
|
||||
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isonphone; do \
|
||||
cat $(DESTDIR)$(ASTVARLIBDIR)/sounds/$$x.gsm >> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/busy.gsm ; \
|
||||
done
|
||||
|
||||
webvmail:
|
||||
@[ -d $(DESTDIR)$(HTTPDIR) ] || ( echo "No HTTP directory" && exit 1 )
|
||||
@[ -d $(DESTDIR)$(HTTPDIR)/html ] || ( echo "No http directory" && exit 1 )
|
||||
@[ -d $(DESTDIR)$(HTTPDIR)/cgi-bin ] || ( echo "No cgi-bin directory" && exit 1 )
|
||||
install -m 4755 -o root -g root contrib/scripts/vmail.cgi $(DESTDIR)$(HTTPDIR)/cgi-bin/vmail.cgi
|
||||
mkdir -p $(DESTDIR)$(HTTPDIR)/html/_asterisk
|
||||
for x in images/*.gif; do \
|
||||
install -m 644 $$x $(DESTDIR)$(HTTPDIR)/html/_asterisk/; \
|
||||
done
|
||||
@echo " +--------- Asterisk Web Voicemail ----------+"
|
||||
@echo " + +"
|
||||
@echo " + Asterisk Web Voicemail is installed in +"
|
||||
@echo " + your cgi-bin directory. IT USES A SETUID +"
|
||||
@echo " + ROOT PERL SCRIPT, SO IF YOU DON'T LIKE +"
|
||||
@echo " + THAT, UNINSTALL IT! +"
|
||||
@echo " + +"
|
||||
@echo " +-------------------------------------------+"
|
||||
|
||||
samples: all datafiles
|
||||
mkdir -p /etc/asterisk
|
||||
for x in configs/*.sample; do \
|
||||
if [ -f /etc/asterisk/`basename $$x .sample` ]; then \
|
||||
mv -f /etc/asterisk/`basename $$x .sample` /etc/asterisk/`basename $$x .sample`.old ; \
|
||||
fi ; \
|
||||
install $$x /etc/asterisk/`basename $$x .sample` ;\
|
||||
done
|
||||
for x in sounds/demo-*; do \
|
||||
install $$x /var/lib/asterisk/sounds; \
|
||||
done
|
||||
mkdir -p /var/spool/asterisk/vm/1234/INBOX
|
||||
:> /var/lib/asterisk/sounds/vm/1234/unavail.gsm
|
||||
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isunavail; do \
|
||||
cat /var/lib/asterisk/sounds/$$x.gsm >> /var/lib/asterisk/sounds/vm/1234/unavail.gsm ; \
|
||||
done
|
||||
:> /var/lib/asterisk/sounds/vm/1234/busy.gsm
|
||||
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isonphone; do \
|
||||
cat /var/lib/asterisk/sounds/$$x.gsm >> /var/lib/asterisk/sounds/vm/1234/busy.gsm ; \
|
||||
done
|
||||
mailbox:
|
||||
./contrib/scripts/addmailbox
|
||||
|
||||
rpm: __rpm
|
||||
|
||||
__rpm: _version
|
||||
rm -rf /tmp/asterisk ; \
|
||||
mkdir -p /tmp/asterisk/redhat/RPMS/i386 ; \
|
||||
$(MAKE) DESTDIR=/tmp/asterisk install ; \
|
||||
$(MAKE) DESTDIR=/tmp/asterisk samples ; \
|
||||
mkdir -p /tmp/asterisk/etc/rc.d/init.d ; \
|
||||
cp -f redhat/asterisk /tmp/asterisk/etc/rc.d/init.d/ ; \
|
||||
sed "s/^Version:.*/Version: $(RPMVERSION)/g" redhat/asterisk.spec > asterisk.spec ; \
|
||||
rpmbuild --rcfile /usr/lib/rpm/rpmrc:redhat/rpmrc -bb asterisk.spec
|
||||
|
||||
progdocs:
|
||||
doxygen contrib/asterisk-ng-doxygen
|
||||
|
||||
mpg123:
|
||||
@wget -V >/dev/null || (echo "You need wget" ; false )
|
||||
[ -f mpg123-0.59r.tar.gz ] || wget http://www.mpg123.de/mpg123/mpg123-0.59r.tar.gz
|
||||
[ -d mpg123-0.59r ] || tar xfz mpg123-0.59r.tar.gz
|
||||
$(MAKE) -C mpg123-0.59r $(MPG123TARG)
|
||||
|
||||
config:
|
||||
if [ -d /etc/rc.d/init.d ]; then \
|
||||
install -m 755 contrib/init.d/rc.redhat.asterisk /etc/rc.d/init.d/asterisk; \
|
||||
/sbin/chkconfig --add asterisk; \
|
||||
elif [ -d /etc/init.d ]; then \
|
||||
install -m 755 init.asterisk /etc/init.d/asterisk; \
|
||||
fi
|
||||
|
||||
dont-optimize:
|
||||
$(MAKE) OPTIMIZE= K6OPT= install
|
||||
|
||||
valgrind: dont-optimize
|
||||
|
||||
depend: .depend
|
||||
for x in $(SUBDIRS); do $(MAKE) -C $$x depend || exit 1 ; done
|
||||
|
||||
.depend:
|
||||
@if ! which mpg123 &>/dev/null ; then \
|
||||
echo "*** You don't have mpg123 installed. You're going to need ***";\
|
||||
echo "*** it if you want MusicOnHold ***";\
|
||||
elif ! mpg123 --longhelp 2>&1 | grep .59r &>/dev/null ; then \
|
||||
echo "*************************************************************";\
|
||||
echo "*** You have the WRONG version of mpg123... you need .59r ***";\
|
||||
echo "*** Use 'make mpg123' to get the right verison ***";\
|
||||
echo "*************************************************************";\
|
||||
fi
|
||||
./mkdep ${CFLAGS} `ls *.c`
|
||||
|
||||
FORCE:
|
||||
|
||||
%_env:
|
||||
$(MAKE) -C $(shell echo $@ | sed "s/_env//g") env
|
||||
|
||||
env:
|
||||
env
|
||||
|
||||
182
README
Executable file → Normal file
182
README
Executable file → Normal file
@@ -1,44 +1,72 @@
|
||||
The Asterisk Open Source PBX
|
||||
by Mark Spencer <markster@linux-support.net>
|
||||
Copyright (C) 1999, Mark Spencer
|
||||
by Mark Spencer <markster@digium.com>
|
||||
Copyright (C) 2001-2004 Digium
|
||||
================================================================
|
||||
* SECURITY
|
||||
It is imperative that you read and fully understand the contents of
|
||||
the SECURITY file before you attempt to configure an Asterisk server.
|
||||
|
||||
* WHAT IS ASTERISK
|
||||
Asterisk is an Open Source PBX and telephony toolkit. It is, in a
|
||||
sense, middleware between Internet and telephony channels on the bottom,
|
||||
and Internet and telephony applications at the top. For more information
|
||||
on the project itself, please visit the Asterisk home page at:
|
||||
|
||||
http://www.asteriskpbx.com
|
||||
http://www.asterisk.org
|
||||
|
||||
In addition you'll find lot's of information compiled by the Asterisk
|
||||
community on this Wiki:
|
||||
|
||||
http://www.voip-info.org/wiki-Asterisk
|
||||
|
||||
* LICENSING
|
||||
Asterisk is distributed under GNU General Public License. The GPL also
|
||||
must apply to all loadable modules as well, except as defined below.
|
||||
|
||||
Digium, Inc. (formerly Linux Support Services) retains copyright to all
|
||||
of the core Asterisk system, and therefore can grant, at its sole discretion,
|
||||
the ability for companies, individuals, or organizations to create proprietary
|
||||
or Open Source (but non-GPL'd) modules which may be dynamically linked at
|
||||
runtime with the portions of Asterisk which fall under our copyright
|
||||
umbrella, or are distributed under more flexible licenses than GPL.
|
||||
|
||||
|
||||
If you wish to use our code in other GPL programs, don't worry -- there
|
||||
is no requirement that you provide the same exemption in your GPL'd
|
||||
products (although if you've written a module for Asterisk we would
|
||||
strongly encourage you to make the same exemption that we do).
|
||||
|
||||
Specific permission is also granted to OpenSSL and OpenH323 to link to
|
||||
Asterisk.
|
||||
|
||||
If you have any questions, whatsoever, regarding our licensing policy,
|
||||
please contact us.
|
||||
|
||||
Modules that are GPL-licensed and not available under Digium's
|
||||
licensing scheme are added to the Asterisk-addons CVS module.
|
||||
|
||||
* REQUIRED COMPONENTS
|
||||
|
||||
== Linux ==
|
||||
Currently, the Asterisk Open Source PBX is only known to run on the
|
||||
Linux OS, although it may be portable to other UNIX-like operating systems
|
||||
as well.
|
||||
|
||||
== libaudiofile ==
|
||||
|
||||
If you want to use format_wav module, then you need a very recent
|
||||
version of libaudiofile (at least version 0.2.0, or you can apply the
|
||||
included patch. RPMS for the patched libaudiofile are available at:
|
||||
ftp://ftp.asteriskpbx.com/pub/asterisk/support
|
||||
(like FreeBSD) as well.
|
||||
|
||||
|
||||
* GETTING STARTED
|
||||
|
||||
First, be sure you've installed the required libaudiofile upgrade if
|
||||
you want to use the non-GSM WAV format. Next, be sure you've got
|
||||
supported hardware. To use Asterisk right now, you will need one of
|
||||
the following:
|
||||
First, be sure you've got supported hardware (but note that you don't need ANY hardware, not even a soundcard) to install and run Asterisk. Supported are:
|
||||
|
||||
* Adtran Atlas 800 Plus
|
||||
* QuickNet Internet PhoneJack
|
||||
* All Wildcard (tm) products from Digium (www.digium.com)
|
||||
* QuickNet Internet PhoneJack and LineJack (http://www.quicknet.net)
|
||||
* Full Duplex Sound Card supported by Linux
|
||||
* Adtran Atlas 800 Plus
|
||||
* ISDN4Linux compatible ISDN card
|
||||
* Tormenta Dual T1 card (www.bsdtelephony.com.mx)
|
||||
|
||||
Assuming you have one of these (most likely the third) you're ready to
|
||||
proceed:
|
||||
Hint: CAPI compatible ISDN cards can be run using the add-on channel chan_capi.
|
||||
|
||||
So let's proceed:
|
||||
|
||||
1) Run "make"
|
||||
2) Run "make install"
|
||||
@@ -48,19 +76,16 @@ the sample PBX, with demonstration extensions, etc. If so, run:
|
||||
|
||||
"make samples"
|
||||
|
||||
Doing so will overwrite any existing config files you have.
|
||||
Doing so will overwrite any existing config files you have. If you are lacking a soundcard you won't be able to use the DIAL command on the console, though.
|
||||
|
||||
Finally, you can launch Asterisk with:
|
||||
|
||||
./asterisk -vvvc
|
||||
|
||||
If you get an error about unresolved symbols, install the updated
|
||||
libaudiofile (available at ftp://ftp.asteriskpbx.com/pub/asterisk/support
|
||||
|
||||
You'll see a bunch of verbose messages fly by your screen as Asterisk
|
||||
initializes (that's the "very very verbose" mode). When it's ready, if
|
||||
you specified the "c" then you'll get a command line console, that looks
|
||||
like this:
|
||||
like this:
|
||||
|
||||
*CLI>
|
||||
|
||||
@@ -75,7 +100,114 @@ won't work right (not yet).
|
||||
Feel free to look over the configuration files in /etc/asterisk, where
|
||||
you'll find a lot of information about what you can do with Asterisk.
|
||||
|
||||
* ABOUT CONFIGURATION FILES
|
||||
|
||||
All Asterisk configuration files share a common format. Comments are
|
||||
delimited by ';' (since '#' of course, being a DTMF digit, may occur in
|
||||
many places). A configuration file is divided into sections whose names
|
||||
appear in []'s. Each section typically contains two types of statements,
|
||||
those of the form 'variable = value', and those of the form 'object =>
|
||||
parameters'. Internally the use of '=' and '=>' is exactly the same, so
|
||||
they're used only to help make the configuration file easier to
|
||||
understand, and do not affect how it is actually parsed.
|
||||
|
||||
Entries of the form 'variable=value' set the value of some parameter in
|
||||
asterisk. For example, in tormenta.conf, one might specify:
|
||||
|
||||
switchtype=national
|
||||
|
||||
In order to indicate to Asterisk that the switch they are connecting to is
|
||||
of the type "national". In general, the parameter will apply to
|
||||
instantiations which occur below its specification. For example, if the
|
||||
configuration file read:
|
||||
|
||||
switchtype = national
|
||||
channel => 1-4
|
||||
channel => 10-12
|
||||
switchtype = dms100
|
||||
channel => 25-47
|
||||
|
||||
Then, the "national" switchtype would be applied to channels one through
|
||||
four and channels 10 through 12, whereas the "dms100" switchtype would
|
||||
apply to channels 25 through 47.
|
||||
|
||||
The "object => parameters" instantiates an object with the given
|
||||
parameters. For example, the line "channel => 25-47" creates objects for
|
||||
the channels 25 through 47 of the tormenta card, obtaining the settings
|
||||
from the variables specified above.
|
||||
|
||||
* SPECIAL NOTE ON TIME
|
||||
|
||||
Those using SIP phones should be aware the Asterisk is sensitive to
|
||||
large jumps in time. Manually changing the system time using date(1)
|
||||
(or other similar commands) may cause SIP registrations and other
|
||||
internal processes to fail. If your system cannot keep accurate time
|
||||
by itself use NTP (http://www.ntp.org/) to keep the system clock
|
||||
synchronized to "real time". NTP is designed to keep the system clock
|
||||
synchronized by speeding up or slowing down the system clock until it
|
||||
is synchronized to "real time" rather than by jumping the time and
|
||||
causing discontinuities. Most Linux distributions include precompiled
|
||||
versions of NTP. Beware of some time synchronization methods that get
|
||||
the correct real time periodically and then manually set the system
|
||||
clock.
|
||||
|
||||
Apparent time changes due to daylight savings time are just that,
|
||||
apparent. The use of daylight savings time in a Linux system is
|
||||
purely a user interface issue and does not affect the operation of the
|
||||
Linux kernel or Asterisk. The system clock on Linux kernels operates
|
||||
on UTC. UTC does not use daylight savings time.
|
||||
|
||||
Also note that this issue is separate from the clocking of TDM
|
||||
channels, and is known to at least affect SIP registrations.
|
||||
|
||||
* FILE DESCRIPTORS
|
||||
|
||||
Depending on the size of your system and your configuration,
|
||||
Asterisk can consume a large number of file descriptors. In UNIX,
|
||||
file descriptors are used for more than just files on disk. File
|
||||
descriptors are also used for handling network communication
|
||||
(e.g. SIP, IAX2, or H.323 calls) and hardware access (e.g. analog and
|
||||
digital trunk hardware). Asterisk accesses many on-disk files for
|
||||
everything from configuration information to voicemail storage.
|
||||
|
||||
Most systems limit the number of file descriptors that Asterisk can
|
||||
have open at one time. This can limit the number of simultaneous
|
||||
calls that your system can handle. For example, if the limit is set
|
||||
at 1024 (a common default value) Asterisk can handle approxiately 150
|
||||
SIP calls simultaneously. To change the number of file descriptors
|
||||
follow the instructions for your system below:
|
||||
|
||||
== PAM-based Linux System ==
|
||||
|
||||
If your system uses PAM (Pluggable Authentication Modules) edit
|
||||
/etc/security/limits.conf. Add these lines to the bottom of the file:
|
||||
|
||||
root soft nofile 4096
|
||||
root hard nofile 8196
|
||||
asterisk soft nofile 4096
|
||||
asterisk hard nofile 8196
|
||||
|
||||
(adjust the numbers to taste). You may need to reboot the system for
|
||||
these changes to take effect.
|
||||
|
||||
== Generic UNIX System ==
|
||||
|
||||
If there are no instructions specifically adapted to your system
|
||||
above you can try adding the command "ulimit -n 8192" to the script
|
||||
that starts Asterisk.
|
||||
|
||||
|
||||
* MORE INFORMATION
|
||||
|
||||
See the doc directory for more documentation.
|
||||
|
||||
Finally, you may wish to visit the web site and join the mailing list if
|
||||
you're interested in getting more information.
|
||||
|
||||
Mark
|
||||
http://www.asterisk.org/index.php?menu=support
|
||||
|
||||
Welcome to the growing worldwide community of Asterisk users!
|
||||
|
||||
Mark Spencer
|
||||
|
||||
|
||||
|
||||
22
README.opsound
Normal file
22
README.opsound
Normal file
@@ -0,0 +1,22 @@
|
||||
About Hold Music
|
||||
================
|
||||
These files were obtained from http://opsound.org, where the authors placed them
|
||||
under the Creative Commons Attribution-Share Alike 2.5 license, a copy of which
|
||||
may be found at http://creativecommons.org.
|
||||
|
||||
Credits
|
||||
================
|
||||
macroform-cold_day - Paul Shuler (Macroform)
|
||||
paulshuler@gmail.com - http://macroform.bandcamp.com/
|
||||
|
||||
macroform-robot_dity - Paul Shuler (Macroform)
|
||||
paulshuler@gmail.com - http://macroform.bandcamp.com/
|
||||
|
||||
macroform-the_simplicity - Paul Shuler (Macroform)
|
||||
paulshuler@gmail.com - http://macroform.bandcamp.com/
|
||||
|
||||
manolo_camp-morning_coffee - Manolo Camp
|
||||
beatbastard@gmx.net - http://ccmixter.org/people/ManoloCamp
|
||||
|
||||
reno_project-system - Reno Project
|
||||
renoproject@hotmail.com - http://www.jamendo.com/en/album/23661
|
||||
41
SECURITY
Normal file
41
SECURITY
Normal file
@@ -0,0 +1,41 @@
|
||||
==== Security Notes with Asterisk ====
|
||||
|
||||
PLEASE READ THE FOLLOWING IMPORTANT SECURITY RELATED INFORMATION.
|
||||
IMPROPER CONFIGURATION OF ASTERISK COULD ALLOW UNAUTHORIZED USE OF YOUR
|
||||
FACILITIES, POTENTIALLY INCURRING SUBSTANTIAL CHARGES.
|
||||
|
||||
First and foremost remember this:
|
||||
|
||||
USE THE EXTENSION CONTEXTS TO ISOLATE OUTGOING OR TOLL SERVICES FROM ANY
|
||||
INCOMING CONNECTIONS.
|
||||
|
||||
You should consider that if any channel, incoming line, etc can enter an
|
||||
extension context that it has the capability of accessing any extension
|
||||
within that context.
|
||||
|
||||
Therefore, you should NOT allow access to outgoing or toll services in
|
||||
contexts that are accessible (especially without a password) from incoming
|
||||
channels, be they IAX channels, FX or other trunks, or even untrusted
|
||||
stations within you network. In particular, never ever put outgoing toll
|
||||
services in the "default" context. To make things easier, you can include
|
||||
the "default" context within other private contexts by using:
|
||||
|
||||
include => default
|
||||
|
||||
in the appropriate section. A well designed PBX might look like this:
|
||||
|
||||
[longdistance]
|
||||
exten => _91NXXNXXXXXX,1,Dial(Zap/g2/${EXTEN:1})
|
||||
include => local
|
||||
|
||||
[local]
|
||||
exten => _9NXXNXXX,1,Dial(Zap/g2/${EXTEN:1})
|
||||
include => default
|
||||
|
||||
[default]
|
||||
exten => 6123,Dial(Zap/1)
|
||||
|
||||
|
||||
DON'T FORGET TO TAKE THE DEMO CONTEXT OUT OF YOUR DEFAULT CONTEXT. There
|
||||
isn't really a security reason, it just will keep people from wanting to
|
||||
play with your asterisk setup remotely.
|
||||
409
acl.c
Normal file
409
acl.c
Normal file
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Various sorts of access control
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <asterisk/acl.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/ioctl.h>
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
|
||||
#include <fcntl.h>
|
||||
#include <net/route.h>
|
||||
|
||||
AST_MUTEX_DEFINE_STATIC(routeseq_lock);
|
||||
#endif
|
||||
|
||||
|
||||
struct ast_ha {
|
||||
/* Host access rule */
|
||||
struct in_addr netaddr;
|
||||
struct in_addr netmask;
|
||||
int sense;
|
||||
struct ast_ha *next;
|
||||
};
|
||||
|
||||
/* Default IP - if not otherwise set, don't breathe garbage */
|
||||
static struct in_addr __ourip = { 0x00000000 };
|
||||
|
||||
struct my_ifreq {
|
||||
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "eth0", "ppp0", etc. */
|
||||
struct sockaddr_in ifru_addr;
|
||||
};
|
||||
|
||||
/* Free HA structure */
|
||||
void ast_free_ha(struct ast_ha *ha)
|
||||
{
|
||||
struct ast_ha *hal;
|
||||
while(ha) {
|
||||
hal = ha;
|
||||
ha = ha->next;
|
||||
free(hal);
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy HA structure */
|
||||
static void ast_copy_ha(struct ast_ha *from, struct ast_ha *to)
|
||||
{
|
||||
memcpy(&to->netaddr, &from->netaddr, sizeof(from->netaddr));
|
||||
memcpy(&to->netmask, &from->netmask, sizeof(from->netmask));
|
||||
to->sense = from->sense;
|
||||
}
|
||||
|
||||
/* Create duplicate of ha structure */
|
||||
static struct ast_ha *ast_duplicate_ha(struct ast_ha *original)
|
||||
{
|
||||
struct ast_ha *new_ha = malloc(sizeof(struct ast_ha));
|
||||
|
||||
/* Copy from original to new object */
|
||||
ast_copy_ha(original, new_ha);
|
||||
|
||||
return(new_ha);
|
||||
|
||||
}
|
||||
|
||||
/* Create duplicate HA link list */
|
||||
/* Used in chan_sip2 templates */
|
||||
struct ast_ha *ast_duplicate_ha_list(struct ast_ha *original)
|
||||
{
|
||||
struct ast_ha *start=original;
|
||||
struct ast_ha *ret = NULL;
|
||||
struct ast_ha *link,*prev=NULL;
|
||||
|
||||
while(start) {
|
||||
link = ast_duplicate_ha(start); /* Create copy of this object */
|
||||
if (prev)
|
||||
prev->next = link; /* Link previous to this object */
|
||||
|
||||
if (!ret)
|
||||
ret = link; /* Save starting point */
|
||||
|
||||
start = start->next; /* Go to next object */
|
||||
prev = link; /* Save pointer to this object */
|
||||
}
|
||||
return (ret); /* Return start of list */
|
||||
}
|
||||
|
||||
struct ast_ha *ast_append_ha(char *sense, char *stuff, struct ast_ha *path)
|
||||
{
|
||||
struct ast_ha *ha = malloc(sizeof(struct ast_ha));
|
||||
char *nm="255.255.255.255";
|
||||
char tmp[256] = "";
|
||||
struct ast_ha *prev = NULL;
|
||||
struct ast_ha *ret;
|
||||
int x,z;
|
||||
unsigned int y;
|
||||
ret = path;
|
||||
while(path) {
|
||||
prev = path;
|
||||
path = path->next;
|
||||
}
|
||||
if (ha) {
|
||||
strncpy(tmp, stuff, sizeof(tmp) - 1);
|
||||
nm = strchr(tmp, '/');
|
||||
if (!nm)
|
||||
nm = "255.255.255.255";
|
||||
else {
|
||||
*nm = '\0';
|
||||
nm++;
|
||||
}
|
||||
if (!strchr(nm, '.')) {
|
||||
if ((sscanf(nm, "%i", &x) == 1) && (x >= 0) && (x <= 32)) {
|
||||
y = 0;
|
||||
for (z=0;z<x;z++) {
|
||||
y >>= 1;
|
||||
y |= 0x80000000;
|
||||
}
|
||||
ha->netmask.s_addr = htonl(y);
|
||||
}
|
||||
} else if (!inet_aton(nm, &ha->netmask)) {
|
||||
ast_log(LOG_WARNING, "%s not a valid netmask\n", nm);
|
||||
free(ha);
|
||||
return path;
|
||||
}
|
||||
if (!inet_aton(tmp, &ha->netaddr)) {
|
||||
ast_log(LOG_WARNING, "%s not a valid IP\n", tmp);
|
||||
free(ha);
|
||||
return path;
|
||||
}
|
||||
ha->netaddr.s_addr &= ha->netmask.s_addr;
|
||||
if (!strncasecmp(sense, "p", 1)) {
|
||||
ha->sense = AST_SENSE_ALLOW;
|
||||
} else {
|
||||
ha->sense = AST_SENSE_DENY;
|
||||
}
|
||||
ha->next = NULL;
|
||||
if (prev)
|
||||
prev->next = ha;
|
||||
else
|
||||
ret = ha;
|
||||
}
|
||||
ast_log(LOG_DEBUG, "%s/%s appended to acl for peer\n",stuff, nm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin)
|
||||
{
|
||||
/* Start optimistic */
|
||||
int res = AST_SENSE_ALLOW;
|
||||
while(ha) {
|
||||
char iabuf[INET_ADDRSTRLEN];
|
||||
char iabuf2[INET_ADDRSTRLEN];
|
||||
/* DEBUG */
|
||||
ast_log(LOG_DEBUG,
|
||||
"##### Testing %s with %s\n",
|
||||
ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr),
|
||||
ast_inet_ntoa(iabuf2, sizeof(iabuf2), ha->netaddr));
|
||||
/* For each rule, if this address and the netmask = the net address
|
||||
apply the current rule */
|
||||
if ((sin->sin_addr.s_addr & ha->netmask.s_addr) == (ha->netaddr.s_addr))
|
||||
res = ha->sense;
|
||||
ha = ha->next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int ast_get_ip(struct sockaddr_in *sin, char *value)
|
||||
{
|
||||
struct hostent *hp;
|
||||
struct ast_hostent ahp;
|
||||
hp = ast_gethostbyname(value, &ahp);
|
||||
if (hp) {
|
||||
memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* iface is the interface (e.g. eth0); address is the return value */
|
||||
int ast_lookup_iface(char *iface, struct in_addr *address) {
|
||||
int mysock, res = 0;
|
||||
struct my_ifreq ifreq;
|
||||
|
||||
memset(&ifreq, 0, sizeof(ifreq));
|
||||
strncpy(ifreq.ifrn_name,iface,sizeof(ifreq.ifrn_name) - 1);
|
||||
|
||||
mysock = socket(PF_INET,SOCK_DGRAM,IPPROTO_IP);
|
||||
res = ioctl(mysock,SIOCGIFADDR,&ifreq);
|
||||
|
||||
close(mysock);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno));
|
||||
memcpy((char *)address,(char *)&__ourip,sizeof(__ourip));
|
||||
return -1;
|
||||
} else {
|
||||
memcpy((char *)address,(char *)&ifreq.ifru_addr.sin_addr,sizeof(ifreq.ifru_addr.sin_addr));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int ast_ouraddrfor(struct in_addr *them, struct in_addr *us)
|
||||
{
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr *sa;
|
||||
struct {
|
||||
struct rt_msghdr m_rtm;
|
||||
char m_space[512];
|
||||
} m_rtmsg;
|
||||
char iabuf[INET_ADDRSTRLEN];
|
||||
char *cp, *p;
|
||||
int i, l, s, seq, flags;
|
||||
pid_t pid = getpid();
|
||||
static int routeseq; /* Protected by "routeseq_lock" mutex */
|
||||
|
||||
p = ast_strdupa(ast_inet_ntoa(iabuf, sizeof(iabuf), *them));
|
||||
memset(us, 0, sizeof(struct in_addr));
|
||||
|
||||
memset(&m_rtmsg, 0, sizeof(m_rtmsg));
|
||||
m_rtmsg.m_rtm.rtm_type = RTM_GET;
|
||||
m_rtmsg.m_rtm.rtm_version = RTM_VERSION;
|
||||
ast_mutex_lock(&routeseq_lock);
|
||||
seq = ++routeseq;
|
||||
ast_mutex_unlock(&routeseq_lock);
|
||||
m_rtmsg.m_rtm.rtm_seq = seq;
|
||||
m_rtmsg.m_rtm.rtm_addrs = RTA_DST | RTA_IFA;
|
||||
m_rtmsg.m_rtm.rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);
|
||||
sin = (struct sockaddr_in *)m_rtmsg.m_space;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(struct sockaddr_in);
|
||||
sin->sin_addr = *them;
|
||||
|
||||
if ((s = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC)) < 0) {
|
||||
ast_log(LOG_ERROR, "Error opening routing socket\n");
|
||||
return -1;
|
||||
}
|
||||
flags = fcntl(s, F_GETFL);
|
||||
fcntl(s, F_SETFL, flags | O_NONBLOCK);
|
||||
if (write(s, (char *)&m_rtmsg, m_rtmsg.m_rtm.rtm_msglen) < 0) {
|
||||
ast_log(LOG_ERROR, "Error writing to routing socket: %s\n", strerror(errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
do {
|
||||
l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
|
||||
} while (l > 0 && (m_rtmsg.m_rtm.rtm_seq != seq || m_rtmsg.m_rtm.rtm_pid != pid));
|
||||
if (l < 0) {
|
||||
if (errno != EAGAIN)
|
||||
ast_log(LOG_ERROR, "Error reading from routing socket\n");
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
close(s);
|
||||
|
||||
if (m_rtmsg.m_rtm.rtm_version != RTM_VERSION) {
|
||||
ast_log(LOG_ERROR, "Unsupported route socket protocol version\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (m_rtmsg.m_rtm.rtm_msglen != l)
|
||||
ast_log(LOG_WARNING, "Message length mismatch, in packet %d, returned %d\n",
|
||||
m_rtmsg.m_rtm.rtm_msglen, l);
|
||||
|
||||
if (m_rtmsg.m_rtm.rtm_errno) {
|
||||
ast_log(LOG_ERROR, "RTM_GET got %s (%d)\n",
|
||||
strerror(m_rtmsg.m_rtm.rtm_errno), m_rtmsg.m_rtm.rtm_errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cp = (char *)m_rtmsg.m_space;
|
||||
if (m_rtmsg.m_rtm.rtm_addrs)
|
||||
for (i = 1; i; i <<= 1)
|
||||
if (m_rtmsg.m_rtm.rtm_addrs & i) {
|
||||
sa = (struct sockaddr *)cp;
|
||||
if (i == RTA_IFA && sa->sa_family == AF_INET) {
|
||||
sin = (struct sockaddr_in *)sa;
|
||||
*us = sin->sin_addr;
|
||||
ast_log(LOG_DEBUG, "Found route to %s, output from our address %s.\n", p, ast_inet_ntoa(iabuf, sizeof(iabuf), *us));
|
||||
return 0;
|
||||
}
|
||||
cp += sa->sa_len > 0 ?
|
||||
(1 + ((sa->sa_len - 1) | (sizeof(long) - 1))) :
|
||||
sizeof(long);
|
||||
}
|
||||
|
||||
ast_log(LOG_DEBUG, "No route found for address %s!\n", p);
|
||||
return -1;
|
||||
#else
|
||||
FILE *PROC;
|
||||
unsigned int remote_ip;
|
||||
int res = 1;
|
||||
char line[256];
|
||||
remote_ip = them->s_addr;
|
||||
|
||||
PROC = fopen("/proc/net/route","r");
|
||||
if (!PROC) {
|
||||
bzero(us,sizeof(struct in_addr));
|
||||
return -1;
|
||||
}
|
||||
/* First line contains headers */
|
||||
fgets(line,sizeof(line),PROC);
|
||||
|
||||
while (!feof(PROC)) {
|
||||
char iface[256];
|
||||
unsigned int dest, gateway, mask;
|
||||
int i,fieldnum;
|
||||
char *fields[40];
|
||||
|
||||
fgets(line,sizeof(line),PROC);
|
||||
|
||||
fieldnum = 0;
|
||||
for (i=0;i<sizeof(line);i++) {
|
||||
char *offset;
|
||||
|
||||
fields[fieldnum++] = line + i;
|
||||
offset = strchr(line + i,'\t');
|
||||
if (offset == NULL) {
|
||||
/* Exit loop */
|
||||
break;
|
||||
} else if (fieldnum >= 9) {
|
||||
/* Short-circuit: can't break at 8, since the end of field 7 is figured when fieldnum=8 */
|
||||
break;
|
||||
} else {
|
||||
*offset = '\0';
|
||||
i = offset - line;
|
||||
}
|
||||
}
|
||||
if (fieldnum >= 8) {
|
||||
|
||||
sscanf(fields[0],"%s",iface);
|
||||
sscanf(fields[1],"%x",&dest);
|
||||
sscanf(fields[2],"%x",&gateway);
|
||||
sscanf(fields[7],"%x",&mask);
|
||||
#if 0
|
||||
{ char iabuf[INET_ADDRSTRLEN];
|
||||
printf("Addr: %s %08x Dest: %08x Mask: %08x\n", ast_inet_ntoa(iabuf, sizeof(iabuf), *them), remote_ip, dest, mask); }
|
||||
#endif
|
||||
/* Looks simple, but here is the magic */
|
||||
if (((remote_ip & mask) ^ dest) == 0) {
|
||||
res = ast_lookup_iface(iface,us);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(PROC);
|
||||
if (res == 1) {
|
||||
ast_log(LOG_WARNING, "Yikes! No default route?!!\n");
|
||||
bzero(us,sizeof(struct in_addr));
|
||||
return -2;
|
||||
} else if (res) {
|
||||
/* We've already warned in subroutine */
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ast_find_ourip(struct in_addr *ourip, struct sockaddr_in bindaddr)
|
||||
{
|
||||
char ourhost[MAXHOSTNAMELEN]="";
|
||||
struct ast_hostent ahp;
|
||||
struct hostent *hp;
|
||||
struct in_addr saddr;
|
||||
|
||||
/* just use the bind address if it is nonzero */
|
||||
if (ntohl(bindaddr.sin_addr.s_addr)) {
|
||||
memcpy(ourip, &bindaddr.sin_addr, sizeof(*ourip));
|
||||
return 0;
|
||||
}
|
||||
/* try to use our hostname */
|
||||
if (gethostname(ourhost, sizeof(ourhost)-1)) {
|
||||
ast_log(LOG_WARNING, "Unable to get hostname\n");
|
||||
} else {
|
||||
hp = ast_gethostbyname(ourhost, &ahp);
|
||||
if (hp) {
|
||||
memcpy(ourip, hp->h_addr, sizeof(*ourip));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* A.ROOT-SERVERS.NET. */
|
||||
if (inet_aton("198.41.0.4", &saddr) && !ast_ouraddrfor(&saddr, ourip))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
311
aescrypt.c
Normal file
311
aescrypt.c
Normal file
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
|
||||
All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
|
||||
2. distributions in binary form include the above copyright
|
||||
notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other associated materials;
|
||||
|
||||
3. the copyright holder's name is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
ALTERNATIVELY, provided that this notice is retained in full, this product
|
||||
may be distributed under the terms of the GNU General Public License (GPL),
|
||||
in which case the provisions of the GPL apply INSTEAD OF those given above.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 26/08/2003
|
||||
|
||||
This file contains the code for implementing encryption and decryption
|
||||
for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It
|
||||
can optionally be replaced by code written in assembler using NASM. For
|
||||
further details see the file aesopt.h
|
||||
*/
|
||||
|
||||
#include "aesopt.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
|
||||
#define so(y,x,c) word_out(y, c, s(x,c))
|
||||
|
||||
#if defined(ARRAYS)
|
||||
#define locals(y,x) x[4],y[4]
|
||||
#else
|
||||
#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
|
||||
#endif
|
||||
|
||||
#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
|
||||
s(y,2) = s(x,2); s(y,3) = s(x,3);
|
||||
#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
|
||||
#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
|
||||
#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
|
||||
|
||||
#if defined(ENCRYPTION) && !defined(AES_ASM)
|
||||
|
||||
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||
Pentium optimiation with small code but this is poor for decryption
|
||||
so we need to control this with the following VC++ pragmas
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma optimize( "s", on )
|
||||
#endif
|
||||
|
||||
/* Given the column (c) of the output state variable, the following
|
||||
macros give the input state variables which are needed in its
|
||||
computation for each row (r) of the state. All the alternative
|
||||
macros give the same end values but expand into different ways
|
||||
of calculating these values. In particular the complex macro
|
||||
used for dynamically variable block sizes is designed to expand
|
||||
to a compile time constant whenever possible but will expand to
|
||||
conditional clauses on some branches (I am grateful to Frank
|
||||
Yellin for this construction)
|
||||
*/
|
||||
|
||||
#define fwd_var(x,r,c)\
|
||||
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
|
||||
: r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
|
||||
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
|
||||
: ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
|
||||
|
||||
#if defined(FT4_SET)
|
||||
#undef dec_fmvars
|
||||
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
|
||||
#elif defined(FT1_SET)
|
||||
#undef dec_fmvars
|
||||
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
|
||||
#else
|
||||
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))
|
||||
#endif
|
||||
|
||||
#if defined(FL4_SET)
|
||||
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
|
||||
#elif defined(FL1_SET)
|
||||
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
|
||||
#else
|
||||
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
|
||||
#endif
|
||||
|
||||
aes_rval aes_encrypt(const void *in_blk, void *out_blk, const aes_encrypt_ctx cx[1])
|
||||
{ aes_32t locals(b0, b1);
|
||||
const aes_32t *kp = cx->ks;
|
||||
#ifdef dec_fmvars
|
||||
dec_fmvars; /* declare variables for fwd_mcol() if needed */
|
||||
#endif
|
||||
|
||||
aes_32t nr = (kp[45] ^ kp[52] ^ kp[53] ? kp[52] : 14);
|
||||
|
||||
#ifdef AES_ERR_CHK
|
||||
if( (nr != 10 || !(kp[0] | kp[3] | kp[4]))
|
||||
&& (nr != 12 || !(kp[0] | kp[5] | kp[6]))
|
||||
&& (nr != 14 || !(kp[0] | kp[7] | kp[8])) )
|
||||
return aes_error;
|
||||
#endif
|
||||
|
||||
state_in(b0, in_blk, kp);
|
||||
|
||||
#if (ENC_UNROLL == FULL)
|
||||
|
||||
switch(nr)
|
||||
{
|
||||
case 14:
|
||||
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||
kp += 2 * N_COLS;
|
||||
case 12:
|
||||
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||
kp += 2 * N_COLS;
|
||||
case 10:
|
||||
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
|
||||
round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if (ENC_UNROLL == PARTIAL)
|
||||
{ aes_32t rnd;
|
||||
for(rnd = 0; rnd < (nr >> 1) - 1; ++rnd)
|
||||
{
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b0, b1, kp);
|
||||
}
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
#else
|
||||
{ aes_32t rnd;
|
||||
for(rnd = 0; rnd < nr - 1; ++rnd)
|
||||
{
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
l_copy(b0, b1);
|
||||
}
|
||||
#endif
|
||||
kp += N_COLS;
|
||||
round(fwd_lrnd, b0, b1, kp);
|
||||
}
|
||||
#endif
|
||||
|
||||
state_out(out_blk, b0);
|
||||
#ifdef AES_ERR_CHK
|
||||
return aes_good;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(DECRYPTION) && !defined(AES_ASM)
|
||||
|
||||
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||
Pentium optimiation with small code but this is poor for decryption
|
||||
so we need to control this with the following VC++ pragmas
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma optimize( "t", on )
|
||||
#endif
|
||||
|
||||
/* Given the column (c) of the output state variable, the following
|
||||
macros give the input state variables which are needed in its
|
||||
computation for each row (r) of the state. All the alternative
|
||||
macros give the same end values but expand into different ways
|
||||
of calculating these values. In particular the complex macro
|
||||
used for dynamically variable block sizes is designed to expand
|
||||
to a compile time constant whenever possible but will expand to
|
||||
conditional clauses on some branches (I am grateful to Frank
|
||||
Yellin for this construction)
|
||||
*/
|
||||
|
||||
#define inv_var(x,r,c)\
|
||||
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
|
||||
: r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
|
||||
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
|
||||
: ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
|
||||
|
||||
#if defined(IT4_SET)
|
||||
#undef dec_imvars
|
||||
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
|
||||
#elif defined(IT1_SET)
|
||||
#undef dec_imvars
|
||||
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
|
||||
#else
|
||||
#define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))
|
||||
#endif
|
||||
|
||||
#if defined(IL4_SET)
|
||||
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
|
||||
#elif defined(IL1_SET)
|
||||
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
|
||||
#else
|
||||
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
|
||||
#endif
|
||||
|
||||
aes_rval aes_decrypt(const void *in_blk, void *out_blk, const aes_decrypt_ctx cx[1])
|
||||
{ aes_32t locals(b0, b1);
|
||||
#ifdef dec_imvars
|
||||
dec_imvars; /* declare variables for inv_mcol() if needed */
|
||||
#endif
|
||||
|
||||
aes_32t nr = (cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] ? cx->ks[52] : 14);
|
||||
const aes_32t *kp = cx->ks + nr * N_COLS;
|
||||
|
||||
#ifdef AES_ERR_CHK
|
||||
if( (nr != 10 || !(cx->ks[0] | cx->ks[3] | cx->ks[4]))
|
||||
&& (nr != 12 || !(cx->ks[0] | cx->ks[5] | cx->ks[6]))
|
||||
&& (nr != 14 || !(cx->ks[0] | cx->ks[7] | cx->ks[8])) )
|
||||
return aes_error;
|
||||
#endif
|
||||
|
||||
state_in(b0, in_blk, kp);
|
||||
|
||||
#if (DEC_UNROLL == FULL)
|
||||
|
||||
switch(nr)
|
||||
{
|
||||
case 14:
|
||||
round(inv_rnd, b1, b0, kp - 1 * N_COLS);
|
||||
round(inv_rnd, b0, b1, kp - 2 * N_COLS);
|
||||
kp -= 2 * N_COLS;
|
||||
case 12:
|
||||
round(inv_rnd, b1, b0, kp - 1 * N_COLS);
|
||||
round(inv_rnd, b0, b1, kp - 2 * N_COLS);
|
||||
kp -= 2 * N_COLS;
|
||||
case 10:
|
||||
round(inv_rnd, b1, b0, kp - 1 * N_COLS);
|
||||
round(inv_rnd, b0, b1, kp - 2 * N_COLS);
|
||||
round(inv_rnd, b1, b0, kp - 3 * N_COLS);
|
||||
round(inv_rnd, b0, b1, kp - 4 * N_COLS);
|
||||
round(inv_rnd, b1, b0, kp - 5 * N_COLS);
|
||||
round(inv_rnd, b0, b1, kp - 6 * N_COLS);
|
||||
round(inv_rnd, b1, b0, kp - 7 * N_COLS);
|
||||
round(inv_rnd, b0, b1, kp - 8 * N_COLS);
|
||||
round(inv_rnd, b1, b0, kp - 9 * N_COLS);
|
||||
round(inv_lrnd, b0, b1, kp - 10 * N_COLS);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if (DEC_UNROLL == PARTIAL)
|
||||
{ aes_32t rnd;
|
||||
for(rnd = 0; rnd < (nr >> 1) - 1; ++rnd)
|
||||
{
|
||||
kp -= N_COLS;
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
kp -= N_COLS;
|
||||
round(inv_rnd, b0, b1, kp);
|
||||
}
|
||||
kp -= N_COLS;
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
#else
|
||||
{ aes_32t rnd;
|
||||
for(rnd = 0; rnd < nr - 1; ++rnd)
|
||||
{
|
||||
kp -= N_COLS;
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
l_copy(b0, b1);
|
||||
}
|
||||
#endif
|
||||
kp -= N_COLS;
|
||||
round(inv_lrnd, b0, b1, kp);
|
||||
}
|
||||
#endif
|
||||
|
||||
state_out(out_blk, b0);
|
||||
#ifdef AES_ERR_CHK
|
||||
return aes_good;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
463
aeskey.c
Normal file
463
aeskey.c
Normal file
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
|
||||
All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
|
||||
2. distributions in binary form include the above copyright
|
||||
notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other associated materials;
|
||||
|
||||
3. the copyright holder's name is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
ALTERNATIVELY, provided that this notice is retained in full, this product
|
||||
may be distributed under the terms of the GNU General Public License (GPL),
|
||||
in which case the provisions of the GPL apply INSTEAD OF those given above.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 26/08/2003
|
||||
|
||||
This file contains the code for implementing the key schedule for AES
|
||||
(Rijndael) for block and key sizes of 16, 24, and 32 bytes. See aesopt.h
|
||||
for further details including optimisation.
|
||||
*/
|
||||
|
||||
#include "aesopt.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Initialise the key schedule from the user supplied key. The key
|
||||
length can be specified in bytes, with legal values of 16, 24
|
||||
and 32, or in bits, with legal values of 128, 192 and 256. These
|
||||
values correspond with Nk values of 4, 6 and 8 respectively.
|
||||
|
||||
The following macros implement a single cycle in the key
|
||||
schedule generation process. The number of cycles needed
|
||||
for each cx->n_col and nk value is:
|
||||
|
||||
nk = 4 5 6 7 8
|
||||
------------------------------
|
||||
cx->n_col = 4 10 9 8 7 7
|
||||
cx->n_col = 5 14 11 10 9 9
|
||||
cx->n_col = 6 19 15 12 11 11
|
||||
cx->n_col = 7 21 19 16 13 14
|
||||
cx->n_col = 8 29 23 19 17 14
|
||||
*/
|
||||
|
||||
#define ke4(k,i) \
|
||||
{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
|
||||
k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
#define kel4(k,i) \
|
||||
{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
|
||||
k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#define ke6(k,i) \
|
||||
{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
|
||||
k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
|
||||
k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \
|
||||
}
|
||||
#define kel6(k,i) \
|
||||
{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
|
||||
k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#define ke8(k,i) \
|
||||
{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
|
||||
k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
|
||||
k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \
|
||||
k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \
|
||||
}
|
||||
#define kel8(k,i) \
|
||||
{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
|
||||
k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#if defined(ENCRYPTION_KEY_SCHEDULE)
|
||||
|
||||
#if defined(AES_128) || defined(AES_VAR)
|
||||
|
||||
aes_rval aes_encrypt_key128(const void *in_key, aes_encrypt_ctx cx[1])
|
||||
{ aes_32t ss[4];
|
||||
|
||||
cx->ks[0] = ss[0] = word_in(in_key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(in_key, 1);
|
||||
cx->ks[2] = ss[2] = word_in(in_key, 2);
|
||||
cx->ks[3] = ss[3] = word_in(in_key, 3);
|
||||
|
||||
#if ENC_UNROLL == NONE
|
||||
{ aes_32t i;
|
||||
|
||||
for(i = 0; i < ((11 * N_COLS - 1) / 4); ++i)
|
||||
ke4(cx->ks, i);
|
||||
}
|
||||
#else
|
||||
ke4(cx->ks, 0); ke4(cx->ks, 1);
|
||||
ke4(cx->ks, 2); ke4(cx->ks, 3);
|
||||
ke4(cx->ks, 4); ke4(cx->ks, 5);
|
||||
ke4(cx->ks, 6); ke4(cx->ks, 7);
|
||||
ke4(cx->ks, 8); kel4(cx->ks, 9);
|
||||
#endif
|
||||
|
||||
/* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */
|
||||
/* key and must be non-zero for 128 and 192 bits keys */
|
||||
cx->ks[53] = cx->ks[45] = 0;
|
||||
cx->ks[52] = 10;
|
||||
#ifdef AES_ERR_CHK
|
||||
return aes_good;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_192) || defined(AES_VAR)
|
||||
|
||||
aes_rval aes_encrypt_key192(const void *in_key, aes_encrypt_ctx cx[1])
|
||||
{ aes_32t ss[6];
|
||||
|
||||
cx->ks[0] = ss[0] = word_in(in_key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(in_key, 1);
|
||||
cx->ks[2] = ss[2] = word_in(in_key, 2);
|
||||
cx->ks[3] = ss[3] = word_in(in_key, 3);
|
||||
cx->ks[4] = ss[4] = word_in(in_key, 4);
|
||||
cx->ks[5] = ss[5] = word_in(in_key, 5);
|
||||
|
||||
#if ENC_UNROLL == NONE
|
||||
{ aes_32t i;
|
||||
|
||||
for(i = 0; i < (13 * N_COLS - 1) / 6; ++i)
|
||||
ke6(cx->ks, i);
|
||||
}
|
||||
#else
|
||||
ke6(cx->ks, 0); ke6(cx->ks, 1);
|
||||
ke6(cx->ks, 2); ke6(cx->ks, 3);
|
||||
ke6(cx->ks, 4); ke6(cx->ks, 5);
|
||||
ke6(cx->ks, 6); kel6(cx->ks, 7);
|
||||
#endif
|
||||
|
||||
/* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */
|
||||
/* key and must be non-zero for 128 and 192 bits keys */
|
||||
cx->ks[53] = cx->ks[45];
|
||||
cx->ks[52] = 12;
|
||||
#ifdef AES_ERR_CHK
|
||||
return aes_good;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_256) || defined(AES_VAR)
|
||||
|
||||
aes_rval aes_encrypt_key256(const void *in_key, aes_encrypt_ctx cx[1])
|
||||
{ aes_32t ss[8];
|
||||
|
||||
cx->ks[0] = ss[0] = word_in(in_key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(in_key, 1);
|
||||
cx->ks[2] = ss[2] = word_in(in_key, 2);
|
||||
cx->ks[3] = ss[3] = word_in(in_key, 3);
|
||||
cx->ks[4] = ss[4] = word_in(in_key, 4);
|
||||
cx->ks[5] = ss[5] = word_in(in_key, 5);
|
||||
cx->ks[6] = ss[6] = word_in(in_key, 6);
|
||||
cx->ks[7] = ss[7] = word_in(in_key, 7);
|
||||
|
||||
#if ENC_UNROLL == NONE
|
||||
{ aes_32t i;
|
||||
|
||||
for(i = 0; i < (15 * N_COLS - 1) / 8; ++i)
|
||||
ke8(cx->ks, i);
|
||||
}
|
||||
#else
|
||||
ke8(cx->ks, 0); ke8(cx->ks, 1);
|
||||
ke8(cx->ks, 2); ke8(cx->ks, 3);
|
||||
ke8(cx->ks, 4); ke8(cx->ks, 5);
|
||||
kel8(cx->ks, 6);
|
||||
#endif
|
||||
#ifdef AES_ERR_CHK
|
||||
return aes_good;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_VAR)
|
||||
|
||||
aes_rval aes_encrypt_key(const void *in_key, int key_len, aes_encrypt_ctx cx[1])
|
||||
{
|
||||
switch(key_len)
|
||||
{
|
||||
#ifdef AES_ERR_CHK
|
||||
case 16: case 128: return aes_encrypt_key128(in_key, cx);
|
||||
case 24: case 192: return aes_encrypt_key192(in_key, cx);
|
||||
case 32: case 256: return aes_encrypt_key256(in_key, cx);
|
||||
default: return aes_error;
|
||||
#else
|
||||
case 16: case 128: aes_encrypt_key128(in_key, cx); return;
|
||||
case 24: case 192: aes_encrypt_key192(in_key, cx); return;
|
||||
case 32: case 256: aes_encrypt_key256(in_key, cx); return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(DECRYPTION_KEY_SCHEDULE)
|
||||
|
||||
#if DEC_ROUND == NO_TABLES
|
||||
#define ff(x) (x)
|
||||
#else
|
||||
#define ff(x) inv_mcol(x)
|
||||
#ifdef dec_imvars
|
||||
#define d_vars dec_imvars
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#define kdf4(k,i) \
|
||||
{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \
|
||||
ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
|
||||
ss[4] ^= k[4*(i)]; k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \
|
||||
ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \
|
||||
}
|
||||
#define kd4(k,i) \
|
||||
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
|
||||
k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \
|
||||
k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \
|
||||
}
|
||||
#define kdl4(k,i) \
|
||||
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
|
||||
k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \
|
||||
k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \
|
||||
}
|
||||
#else
|
||||
#define kdf4(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \
|
||||
ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \
|
||||
}
|
||||
#define kd4(k,i) \
|
||||
{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
|
||||
ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \
|
||||
ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \
|
||||
ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \
|
||||
ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \
|
||||
}
|
||||
#define kdl4(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \
|
||||
ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define kdf6(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \
|
||||
ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \
|
||||
ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \
|
||||
}
|
||||
#define kd6(k,i) \
|
||||
{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
|
||||
ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \
|
||||
ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \
|
||||
ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \
|
||||
ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \
|
||||
ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \
|
||||
ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \
|
||||
}
|
||||
#define kdl6(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \
|
||||
ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \
|
||||
}
|
||||
|
||||
#define kdf8(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \
|
||||
ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \
|
||||
ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \
|
||||
ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \
|
||||
}
|
||||
#define kd8(k,i) \
|
||||
{ aes_32t g = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
|
||||
ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \
|
||||
ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \
|
||||
ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \
|
||||
ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \
|
||||
g = ls_box(ss[3],0); \
|
||||
ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \
|
||||
ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \
|
||||
ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \
|
||||
ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \
|
||||
}
|
||||
#define kdl8(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \
|
||||
ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \
|
||||
}
|
||||
|
||||
#if defined(AES_128) || defined(AES_VAR)
|
||||
|
||||
aes_rval aes_decrypt_key128(const void *in_key, aes_decrypt_ctx cx[1])
|
||||
{ aes_32t ss[5];
|
||||
#ifdef d_vars
|
||||
d_vars;
|
||||
#endif
|
||||
cx->ks[0] = ss[0] = word_in(in_key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(in_key, 1);
|
||||
cx->ks[2] = ss[2] = word_in(in_key, 2);
|
||||
cx->ks[3] = ss[3] = word_in(in_key, 3);
|
||||
|
||||
#if DEC_UNROLL == NONE
|
||||
{ aes_32t i;
|
||||
|
||||
for(i = 0; i < (11 * N_COLS - 1) / 4; ++i)
|
||||
ke4(cx->ks, i);
|
||||
#if !(DEC_ROUND == NO_TABLES)
|
||||
for(i = N_COLS; i < 10 * N_COLS; ++i)
|
||||
cx->ks[i] = inv_mcol(cx->ks[i]);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
kdf4(cx->ks, 0); kd4(cx->ks, 1);
|
||||
kd4(cx->ks, 2); kd4(cx->ks, 3);
|
||||
kd4(cx->ks, 4); kd4(cx->ks, 5);
|
||||
kd4(cx->ks, 6); kd4(cx->ks, 7);
|
||||
kd4(cx->ks, 8); kdl4(cx->ks, 9);
|
||||
#endif
|
||||
|
||||
/* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */
|
||||
/* key and must be non-zero for 128 and 192 bits keys */
|
||||
cx->ks[53] = cx->ks[45] = 0;
|
||||
cx->ks[52] = 10;
|
||||
#ifdef AES_ERR_CHK
|
||||
return aes_good;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_192) || defined(AES_VAR)
|
||||
|
||||
aes_rval aes_decrypt_key192(const void *in_key, aes_decrypt_ctx cx[1])
|
||||
{ aes_32t ss[7];
|
||||
#ifdef d_vars
|
||||
d_vars;
|
||||
#endif
|
||||
cx->ks[0] = ss[0] = word_in(in_key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(in_key, 1);
|
||||
cx->ks[2] = ss[2] = word_in(in_key, 2);
|
||||
cx->ks[3] = ss[3] = word_in(in_key, 3);
|
||||
|
||||
#if DEC_UNROLL == NONE
|
||||
cx->ks[4] = ss[4] = word_in(in_key, 4);
|
||||
cx->ks[5] = ss[5] = word_in(in_key, 5);
|
||||
{ aes_32t i;
|
||||
|
||||
for(i = 0; i < (13 * N_COLS - 1) / 6; ++i)
|
||||
ke6(cx->ks, i);
|
||||
#if !(DEC_ROUND == NO_TABLES)
|
||||
for(i = N_COLS; i < 12 * N_COLS; ++i)
|
||||
cx->ks[i] = inv_mcol(cx->ks[i]);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
cx->ks[4] = ff(ss[4] = word_in(in_key, 4));
|
||||
cx->ks[5] = ff(ss[5] = word_in(in_key, 5));
|
||||
kdf6(cx->ks, 0); kd6(cx->ks, 1);
|
||||
kd6(cx->ks, 2); kd6(cx->ks, 3);
|
||||
kd6(cx->ks, 4); kd6(cx->ks, 5);
|
||||
kd6(cx->ks, 6); kdl6(cx->ks, 7);
|
||||
#endif
|
||||
|
||||
/* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */
|
||||
/* key and must be non-zero for 128 and 192 bits keys */
|
||||
cx->ks[53] = cx->ks[45];
|
||||
cx->ks[52] = 12;
|
||||
#ifdef AES_ERR_CHK
|
||||
return aes_good;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_256) || defined(AES_VAR)
|
||||
|
||||
aes_rval aes_decrypt_key256(const void *in_key, aes_decrypt_ctx cx[1])
|
||||
{ aes_32t ss[8];
|
||||
#ifdef d_vars
|
||||
d_vars;
|
||||
#endif
|
||||
cx->ks[0] = ss[0] = word_in(in_key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(in_key, 1);
|
||||
cx->ks[2] = ss[2] = word_in(in_key, 2);
|
||||
cx->ks[3] = ss[3] = word_in(in_key, 3);
|
||||
|
||||
#if DEC_UNROLL == NONE
|
||||
cx->ks[4] = ss[4] = word_in(in_key, 4);
|
||||
cx->ks[5] = ss[5] = word_in(in_key, 5);
|
||||
cx->ks[6] = ss[6] = word_in(in_key, 6);
|
||||
cx->ks[7] = ss[7] = word_in(in_key, 7);
|
||||
{ aes_32t i;
|
||||
|
||||
for(i = 0; i < (15 * N_COLS - 1) / 8; ++i)
|
||||
ke8(cx->ks, i);
|
||||
#if !(DEC_ROUND == NO_TABLES)
|
||||
for(i = N_COLS; i < 14 * N_COLS; ++i)
|
||||
cx->ks[i] = inv_mcol(cx->ks[i]);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
cx->ks[4] = ff(ss[4] = word_in(in_key, 4));
|
||||
cx->ks[5] = ff(ss[5] = word_in(in_key, 5));
|
||||
cx->ks[6] = ff(ss[6] = word_in(in_key, 6));
|
||||
cx->ks[7] = ff(ss[7] = word_in(in_key, 7));
|
||||
kdf8(cx->ks, 0); kd8(cx->ks, 1);
|
||||
kd8(cx->ks, 2); kd8(cx->ks, 3);
|
||||
kd8(cx->ks, 4); kd8(cx->ks, 5);
|
||||
kdl8(cx->ks, 6);
|
||||
#endif
|
||||
#ifdef AES_ERR_CHK
|
||||
return aes_good;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_VAR)
|
||||
|
||||
aes_rval aes_decrypt_key(const void *in_key, int key_len, aes_decrypt_ctx cx[1])
|
||||
{
|
||||
switch(key_len)
|
||||
{
|
||||
#ifdef AES_ERR_CHK
|
||||
case 16: case 128: return aes_decrypt_key128(in_key, cx);
|
||||
case 24: case 192: return aes_decrypt_key192(in_key, cx);
|
||||
case 32: case 256: return aes_decrypt_key256(in_key, cx);
|
||||
default: return aes_error;
|
||||
#else
|
||||
case 16: case 128: aes_decrypt_key128(in_key, cx); return;
|
||||
case 24: case 192: aes_decrypt_key192(in_key, cx); return;
|
||||
case 32: case 256: aes_decrypt_key256(in_key, cx); return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
232
aestab.c
Normal file
232
aestab.c
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
|
||||
All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
|
||||
2. distributions in binary form include the above copyright
|
||||
notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other associated materials;
|
||||
|
||||
3. the copyright holder's name is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
ALTERNATIVELY, provided that this notice is retained in full, this product
|
||||
may be distributed under the terms of the GNU General Public License (GPL),
|
||||
in which case the provisions of the GPL apply INSTEAD OF those given above.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 26/08/2003
|
||||
|
||||
*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define DO_TABLES
|
||||
|
||||
#include "aesopt.h"
|
||||
|
||||
#if defined(FIXED_TABLES)
|
||||
|
||||
/* implemented in case of wrong call for fixed tables */
|
||||
|
||||
void gen_tabs(void)
|
||||
{
|
||||
}
|
||||
|
||||
#else /* dynamic table generation */
|
||||
|
||||
#if !defined(FF_TABLES)
|
||||
|
||||
/* Generate the tables for the dynamic table option
|
||||
|
||||
It will generally be sensible to use tables to compute finite
|
||||
field multiplies and inverses but where memory is scarse this
|
||||
code might sometimes be better. But it only has effect during
|
||||
initialisation so its pretty unimportant in overall terms.
|
||||
*/
|
||||
|
||||
/* return 2 ^ (n - 1) where n is the bit number of the highest bit
|
||||
set in x with x in the range 1 < x < 0x00000200. This form is
|
||||
used so that locals within fi can be bytes rather than words
|
||||
*/
|
||||
|
||||
static aes_08t hibit(const aes_32t x)
|
||||
{ aes_08t r = (aes_08t)((x >> 1) | (x >> 2));
|
||||
|
||||
r |= (r >> 2);
|
||||
r |= (r >> 4);
|
||||
return (r + 1) >> 1;
|
||||
}
|
||||
|
||||
/* return the inverse of the finite field element x */
|
||||
|
||||
static aes_08t fi(const aes_08t x)
|
||||
{ aes_08t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
|
||||
|
||||
if(x < 2) return x;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if(!n1) return v1;
|
||||
|
||||
while(n2 >= n1)
|
||||
{
|
||||
n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
|
||||
}
|
||||
|
||||
if(!n2) return v2;
|
||||
|
||||
while(n1 >= n2)
|
||||
{
|
||||
n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* The forward and inverse affine transformations used in the S-box */
|
||||
|
||||
#define fwd_affine(x) \
|
||||
(w = (aes_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(aes_08t)(w^(w>>8)))
|
||||
|
||||
#define inv_affine(x) \
|
||||
(w = (aes_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(aes_08t)(w^(w>>8)))
|
||||
|
||||
static int init = 0;
|
||||
|
||||
void gen_tabs(void)
|
||||
{ aes_32t i, w;
|
||||
|
||||
#if defined(FF_TABLES)
|
||||
|
||||
aes_08t pow[512], log[256];
|
||||
|
||||
if(init) return;
|
||||
/* log and power tables for GF(2^8) finite field with
|
||||
WPOLY as modular polynomial - the simplest primitive
|
||||
root is 0x03, used here to generate the tables
|
||||
*/
|
||||
|
||||
i = 0; w = 1;
|
||||
do
|
||||
{
|
||||
pow[i] = (aes_08t)w;
|
||||
pow[i + 255] = (aes_08t)w;
|
||||
log[w] = (aes_08t)i++;
|
||||
w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
|
||||
}
|
||||
while (w != 1);
|
||||
|
||||
#else
|
||||
if(init) return;
|
||||
#endif
|
||||
|
||||
for(i = 0, w = 1; i < RC_LENGTH; ++i)
|
||||
{
|
||||
t_set(r,c)[i] = bytes2word(w, 0, 0, 0);
|
||||
w = f2(w);
|
||||
}
|
||||
|
||||
for(i = 0; i < 256; ++i)
|
||||
{ aes_08t b;
|
||||
|
||||
b = fwd_affine(fi((aes_08t)i));
|
||||
w = bytes2word(f2(b), b, b, f3(b));
|
||||
|
||||
#ifdef SBX_SET
|
||||
t_set(s,box)[i] = b;
|
||||
#endif
|
||||
|
||||
#ifdef FT1_SET /* tables for a normal encryption round */
|
||||
t_set(f,n)[i] = w;
|
||||
#endif
|
||||
#ifdef FT4_SET
|
||||
t_set(f,n)[0][i] = w;
|
||||
t_set(f,n)[1][i] = upr(w,1);
|
||||
t_set(f,n)[2][i] = upr(w,2);
|
||||
t_set(f,n)[3][i] = upr(w,3);
|
||||
#endif
|
||||
w = bytes2word(b, 0, 0, 0);
|
||||
|
||||
#ifdef FL1_SET /* tables for last encryption round (may also */
|
||||
t_set(f,l)[i] = w; /* be used in the key schedule) */
|
||||
#endif
|
||||
#ifdef FL4_SET
|
||||
t_set(f,l)[0][i] = w;
|
||||
t_set(f,l)[1][i] = upr(w,1);
|
||||
t_set(f,l)[2][i] = upr(w,2);
|
||||
t_set(f,l)[3][i] = upr(w,3);
|
||||
#endif
|
||||
|
||||
#ifdef LS1_SET /* table for key schedule if t_set(f,l) above is */
|
||||
t_set(l,s)[i] = w; /* not of the required form */
|
||||
#endif
|
||||
#ifdef LS4_SET
|
||||
t_set(l,s)[0][i] = w;
|
||||
t_set(l,s)[1][i] = upr(w,1);
|
||||
t_set(l,s)[2][i] = upr(w,2);
|
||||
t_set(l,s)[3][i] = upr(w,3);
|
||||
#endif
|
||||
|
||||
b = fi(inv_affine((aes_08t)i));
|
||||
w = bytes2word(fe(b), f9(b), fd(b), fb(b));
|
||||
|
||||
#ifdef IM1_SET /* tables for the inverse mix column operation */
|
||||
t_set(i,m)[b] = w;
|
||||
#endif
|
||||
#ifdef IM4_SET
|
||||
t_set(i,m)[0][b] = w;
|
||||
t_set(i,m)[1][b] = upr(w,1);
|
||||
t_set(i,m)[2][b] = upr(w,2);
|
||||
t_set(i,m)[3][b] = upr(w,3);
|
||||
#endif
|
||||
|
||||
#ifdef ISB_SET
|
||||
t_set(i,box)[i] = b;
|
||||
#endif
|
||||
#ifdef IT1_SET /* tables for a normal decryption round */
|
||||
t_set(i,n)[i] = w;
|
||||
#endif
|
||||
#ifdef IT4_SET
|
||||
t_set(i,n)[0][i] = w;
|
||||
t_set(i,n)[1][i] = upr(w,1);
|
||||
t_set(i,n)[2][i] = upr(w,2);
|
||||
t_set(i,n)[3][i] = upr(w,3);
|
||||
#endif
|
||||
w = bytes2word(b, 0, 0, 0);
|
||||
#ifdef IL1_SET /* tables for last decryption round */
|
||||
t_set(i,l)[i] = w;
|
||||
#endif
|
||||
#ifdef IL4_SET
|
||||
t_set(i,l)[0][i] = w;
|
||||
t_set(i,l)[1][i] = upr(w,1);
|
||||
t_set(i,l)[2][i] = upr(w,2);
|
||||
t_set(i,l)[3][i] = upr(w,3);
|
||||
#endif
|
||||
}
|
||||
init = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
82
agi/DialAnMp3.agi
Normal file
82
agi/DialAnMp3.agi
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Simple AGI application to play mp3's selected by a user both using
|
||||
# xmms and over the phone itself.
|
||||
#
|
||||
$|=1;
|
||||
while(<STDIN>) {
|
||||
chomp;
|
||||
last unless length($_);
|
||||
if (/^agi_(\w+)\:\s+(.*)$/) {
|
||||
$AGI{$1} = $2;
|
||||
}
|
||||
}
|
||||
|
||||
print STDERR "AGI Environment Dump:\n";
|
||||
foreach $i (sort keys %AGI) {
|
||||
print STDERR " -- $i = $AGI{$i}\n";
|
||||
}
|
||||
|
||||
dbmopen(%DIGITS, "/var/lib/asterisk/mp3list", 0644) || die("Unable to open mp3list");;
|
||||
|
||||
sub checkresult {
|
||||
my ($res) = @_;
|
||||
my $retval;
|
||||
$tests++;
|
||||
chomp $res;
|
||||
if ($res =~ /^200/) {
|
||||
$res =~ /result=(-?[\w\*\#]+)/;
|
||||
return $1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#print STDERR "1. Playing beep...\n";
|
||||
#print "STREAM FILE beep \"\"\n";
|
||||
#$result = <STDIN>;
|
||||
#checkresult($result);
|
||||
|
||||
print STDERR "2. Getting song name...\n";
|
||||
print "GET DATA demo-enterkeywords\n";
|
||||
$result = <STDIN>;
|
||||
$digitstr = checkresult($result);
|
||||
if ($digitstr < 0) {
|
||||
exit(1);
|
||||
}
|
||||
$digitstr =~ s/\*/ /g;
|
||||
|
||||
print STDERR "Resulting songname is $digitstr\n";
|
||||
@searchwords = split (/\s+/, $digitstr);
|
||||
print STDERR "Searchwords: " . join(':', @searchwords) . "\n";
|
||||
|
||||
foreach $key (sort keys %DIGITS) {
|
||||
@words = split(/\s+/, $DIGITS{$key});
|
||||
$match = 1;
|
||||
foreach $search (@searchwords) {
|
||||
$match = 0 unless grep(/$search/, @words);
|
||||
}
|
||||
if ($match > 0) {
|
||||
print STDERR "File $key matches\n";
|
||||
# Play a beep
|
||||
print "STREAM FILE beep \"\"\n";
|
||||
system("xmms", $key);
|
||||
$result = <STDIN>;
|
||||
if (&checkresult($result) < 0) {
|
||||
exit 0;
|
||||
}
|
||||
print "EXEC MP3Player \"$key\"\n";
|
||||
# print "WAIT FOR DIGIT 60000\n";
|
||||
$result = <STDIN>;
|
||||
if (&checkresult($result) < 0) {
|
||||
exit 0;
|
||||
}
|
||||
print STDERR "Got here...\n";
|
||||
}
|
||||
}
|
||||
|
||||
print STDERR "4. Testing 'saynumber' of $digitstr...\n";
|
||||
print "STREAM FILE demo-nomatch\"\"\n";
|
||||
$result = <STDIN>;
|
||||
checkresult($result);
|
||||
|
||||
43
agi/Makefile
Normal file
43
agi/Makefile
Normal file
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# Asterisk -- A telephony toolkit for Linux.
|
||||
#
|
||||
# Makefile for PBX frontends (dynamically loaded)
|
||||
#
|
||||
# Copyright (C) 1999, Mark Spencer
|
||||
#
|
||||
# Mark Spencer <markster@linux-support.net>
|
||||
#
|
||||
# This program is free software, distributed under the terms of
|
||||
# the GNU General Public License
|
||||
#
|
||||
|
||||
AGIS=agi-test.agi eagi-test eagi-sphinx-test
|
||||
|
||||
CFLAGS+=
|
||||
|
||||
all: depend $(AGIS)
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(AGI_DIR)
|
||||
for x in $(AGIS); do $(INSTALL) -m 755 $$x $(DESTDIR)$(AGI_DIR) ; done
|
||||
|
||||
eagi-test: eagi-test.o
|
||||
$(CC) $(CFLAGS) -o eagi-test eagi-test.o
|
||||
|
||||
eagi-sphinx-test: eagi-sphinx-test.o
|
||||
$(CC) $(CFLAGS) -o eagi-sphinx-test eagi-sphinx-test.o
|
||||
|
||||
clean:
|
||||
rm -f *.so *.o look .depend eagi-test eagi-sphinx-test
|
||||
|
||||
%.so : %.o
|
||||
$(CC) -shared -Xlinker -x -o $@ $<
|
||||
|
||||
ifneq ($(wildcard .depend),)
|
||||
include .depend
|
||||
endif
|
||||
|
||||
depend: .depend
|
||||
|
||||
.depend:
|
||||
../mkdep $(CFLAGS) `ls *.c`
|
||||
79
agi/agi-test.agi
Normal file
79
agi/agi-test.agi
Normal file
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
|
||||
$|=1;
|
||||
|
||||
# Setup some variables
|
||||
my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;
|
||||
|
||||
while(<STDIN>) {
|
||||
chomp;
|
||||
last unless length($_);
|
||||
if (/^agi_(\w+)\:\s+(.*)$/) {
|
||||
$AGI{$1} = $2;
|
||||
}
|
||||
}
|
||||
|
||||
print STDERR "AGI Environment Dump:\n";
|
||||
foreach my $i (sort keys %AGI) {
|
||||
print STDERR " -- $i = $AGI{$i}\n";
|
||||
}
|
||||
|
||||
sub checkresult {
|
||||
my ($res) = @_;
|
||||
my $retval;
|
||||
$tests++;
|
||||
chomp $res;
|
||||
if ($res =~ /^200/) {
|
||||
$res =~ /result=(-?\d+)/;
|
||||
if (!length($1)) {
|
||||
print STDERR "FAIL ($res)\n";
|
||||
$fail++;
|
||||
} else {
|
||||
print STDERR "PASS ($1)\n";
|
||||
$pass++;
|
||||
}
|
||||
} else {
|
||||
print STDERR "FAIL (unexpected result '$res')\n";
|
||||
$fail++;
|
||||
}
|
||||
}
|
||||
|
||||
print STDERR "1. Testing 'sendfile'...";
|
||||
print "STREAM FILE beep \"\"\n";
|
||||
my $result = <STDIN>;
|
||||
&checkresult($result);
|
||||
|
||||
print STDERR "2. Testing 'sendtext'...";
|
||||
print "SEND TEXT \"hello world\"\n";
|
||||
my $result = <STDIN>;
|
||||
&checkresult($result);
|
||||
|
||||
print STDERR "3. Testing 'sendimage'...";
|
||||
print "SEND IMAGE asterisk-image\n";
|
||||
my $result = <STDIN>;
|
||||
&checkresult($result);
|
||||
|
||||
print STDERR "4. Testing 'saynumber'...";
|
||||
print "SAY NUMBER 192837465 \"\"\n";
|
||||
my $result = <STDIN>;
|
||||
&checkresult($result);
|
||||
|
||||
print STDERR "5. Testing 'waitdtmf'...";
|
||||
print "WAIT FOR DIGIT 1000\n";
|
||||
my $result = <STDIN>;
|
||||
&checkresult($result);
|
||||
|
||||
print STDERR "6. Testing 'record'...";
|
||||
print "RECORD FILE testagi gsm 1234 3000\n";
|
||||
my $result = <STDIN>;
|
||||
&checkresult($result);
|
||||
|
||||
print STDERR "6a. Testing 'record' playback...";
|
||||
print "STREAM FILE testagi \"\"\n";
|
||||
my $result = <STDIN>;
|
||||
&checkresult($result);
|
||||
|
||||
print STDERR "================== Complete ======================\n";
|
||||
print STDERR "$tests tests completed, $pass passed, $fail failed\n";
|
||||
print STDERR "==================================================\n";
|
||||
218
agi/eagi-sphinx-test.c
Normal file
218
agi/eagi-sphinx-test.c
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Extended AGI test application
|
||||
*
|
||||
* This code is released into public domain
|
||||
* without any warranty of any kind.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/select.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#define AUDIO_FILENO (STDERR_FILENO + 1)
|
||||
|
||||
#define SPHINX_HOST "192.168.1.108"
|
||||
#define SPHINX_PORT 3460
|
||||
|
||||
static int sphinx_sock = -1;
|
||||
|
||||
static int connect_sphinx(void)
|
||||
{
|
||||
struct hostent *hp;
|
||||
struct sockaddr_in sin;
|
||||
int res;
|
||||
hp = gethostbyname(SPHINX_HOST);
|
||||
if (!hp) {
|
||||
fprintf(stderr, "Unable to resolve '%s'\n", SPHINX_HOST);
|
||||
return -1;
|
||||
}
|
||||
sphinx_sock = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (sphinx_sock < 0) {
|
||||
fprintf(stderr, "Unable to allocate socket: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(SPHINX_PORT);
|
||||
memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
|
||||
if (connect(sphinx_sock, (struct sockaddr *)&sin, sizeof(sin))) {
|
||||
fprintf(stderr, "Unable to connect on socket: %s\n", strerror(errno));
|
||||
close(sphinx_sock);
|
||||
sphinx_sock = -1;
|
||||
return -1;
|
||||
}
|
||||
res = fcntl(sphinx_sock, F_GETFL);
|
||||
if ((res < 0) || (fcntl(sphinx_sock, F_SETFL, res | O_NONBLOCK) < 0)) {
|
||||
fprintf(stderr, "Unable to set flags on socket: %s\n", strerror(errno));
|
||||
close(sphinx_sock);
|
||||
sphinx_sock = -1;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_environment(void)
|
||||
{
|
||||
char buf[256];
|
||||
char *val;
|
||||
/* Read environment */
|
||||
for(;;) {
|
||||
fgets(buf, sizeof(buf), stdin);
|
||||
if (feof(stdin))
|
||||
return -1;
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
/* Check for end of environment */
|
||||
if (!strlen(buf))
|
||||
return 0;
|
||||
val = strchr(buf, ':');
|
||||
if (!val) {
|
||||
fprintf(stderr, "Invalid environment: '%s'\n", buf);
|
||||
return -1;
|
||||
}
|
||||
*val = '\0';
|
||||
val++;
|
||||
val++;
|
||||
/* Skip space */
|
||||
fprintf(stderr, "Environment: '%s' is '%s'\n", buf, val);
|
||||
|
||||
/* Load into normal environment */
|
||||
setenv(buf, val, 1);
|
||||
|
||||
}
|
||||
/* Never reached */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *wait_result(void)
|
||||
{
|
||||
fd_set fds;
|
||||
int res;
|
||||
int max;
|
||||
static char astresp[256];
|
||||
static char sphinxresp[256];
|
||||
char audiobuf[4096];
|
||||
for (;;) {
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(STDIN_FILENO, &fds);
|
||||
FD_SET(AUDIO_FILENO, &fds);
|
||||
max = AUDIO_FILENO;
|
||||
if (sphinx_sock > -1) {
|
||||
FD_SET(sphinx_sock, &fds);
|
||||
if (sphinx_sock > max)
|
||||
max = sphinx_sock;
|
||||
}
|
||||
/* Wait for *some* sort of I/O */
|
||||
res = select(max + 1, &fds, NULL, NULL, NULL);
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "Error in select: %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
if (FD_ISSET(STDIN_FILENO, &fds)) {
|
||||
fgets(astresp, sizeof(astresp), stdin);
|
||||
if (feof(stdin)) {
|
||||
fprintf(stderr, "Got hungup on apparently\n");
|
||||
return NULL;
|
||||
}
|
||||
astresp[strlen(astresp) - 1] = '\0';
|
||||
fprintf(stderr, "Ooh, got a response from Asterisk: '%s'\n", astresp);
|
||||
return astresp;
|
||||
}
|
||||
if (FD_ISSET(AUDIO_FILENO, &fds)) {
|
||||
res = read(AUDIO_FILENO, audiobuf, sizeof(audiobuf));
|
||||
if (res > 0) {
|
||||
if (sphinx_sock > -1)
|
||||
write(sphinx_sock, audiobuf, res);
|
||||
}
|
||||
}
|
||||
if ((sphinx_sock > -1) && FD_ISSET(sphinx_sock, &fds)) {
|
||||
res = read(sphinx_sock, sphinxresp, sizeof(sphinxresp));
|
||||
if (res > 0) {
|
||||
fprintf(stderr, "Oooh, Sphinx found a token: '%s'\n", sphinxresp);
|
||||
return sphinxresp;
|
||||
} else if (res == 0) {
|
||||
fprintf(stderr, "Hrm, lost sphinx, guess we're on our own\n");
|
||||
close(sphinx_sock);
|
||||
sphinx_sock = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static char *run_command(char *command)
|
||||
{
|
||||
fprintf(stdout, "%s\n", command);
|
||||
return wait_result();
|
||||
}
|
||||
|
||||
static int run_script(void)
|
||||
{
|
||||
char *res;
|
||||
res = run_command("STREAM FILE demo-enterkeywords 0123456789*#");
|
||||
if (!res) {
|
||||
fprintf(stderr, "Failed to execute command\n");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "1. Result is '%s'\n", res);
|
||||
res = run_command("STREAM FILE demo-nomatch 0123456789*#");
|
||||
if (!res) {
|
||||
fprintf(stderr, "Failed to execute command\n");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "2. Result is '%s'\n", res);
|
||||
res = run_command("SAY NUMBER 23452345 0123456789*#");
|
||||
if (!res) {
|
||||
fprintf(stderr, "Failed to execute command\n");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "3. Result is '%s'\n", res);
|
||||
res = run_command("GET DATA demo-enterkeywords");
|
||||
if (!res) {
|
||||
fprintf(stderr, "Failed to execute command\n");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "4. Result is '%s'\n", res);
|
||||
res = run_command("STREAM FILE auth-thankyou \"\"");
|
||||
if (!res) {
|
||||
fprintf(stderr, "Failed to execute command\n");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "5. Result is '%s'\n", res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *tmp;
|
||||
int ver = 0;
|
||||
int subver = 0;
|
||||
/* Setup stdin/stdout for line buffering */
|
||||
setlinebuf(stdin);
|
||||
setlinebuf(stdout);
|
||||
if (read_environment()) {
|
||||
fprintf(stderr, "Failed to read environment: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
connect_sphinx();
|
||||
tmp = getenv("agi_enhanced");
|
||||
if (tmp) {
|
||||
if (sscanf(tmp, "%d.%d", &ver, &subver) != 2)
|
||||
ver = 0;
|
||||
}
|
||||
if (ver < 1) {
|
||||
fprintf(stderr, "No enhanced AGI services available. Use EAGI, not AGI\n");
|
||||
exit(1);
|
||||
}
|
||||
if (run_script())
|
||||
return -1;
|
||||
exit(0);
|
||||
}
|
||||
161
agi/eagi-test.c
Normal file
161
agi/eagi-test.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Extended AGI test application
|
||||
*
|
||||
* This code is released into the public domain
|
||||
* with no warranty of any kind
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#define AUDIO_FILENO (STDERR_FILENO + 1)
|
||||
|
||||
static int read_environment(void)
|
||||
{
|
||||
char buf[256];
|
||||
char *val;
|
||||
/* Read environment */
|
||||
for(;;) {
|
||||
fgets(buf, sizeof(buf), stdin);
|
||||
if (feof(stdin))
|
||||
return -1;
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
/* Check for end of environment */
|
||||
if (!strlen(buf))
|
||||
return 0;
|
||||
val = strchr(buf, ':');
|
||||
if (!val) {
|
||||
fprintf(stderr, "Invalid environment: '%s'\n", buf);
|
||||
return -1;
|
||||
}
|
||||
*val = '\0';
|
||||
val++;
|
||||
val++;
|
||||
/* Skip space */
|
||||
fprintf(stderr, "Environment: '%s' is '%s'\n", buf, val);
|
||||
|
||||
/* Load into normal environment */
|
||||
setenv(buf, val, 1);
|
||||
|
||||
}
|
||||
/* Never reached */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *wait_result(void)
|
||||
{
|
||||
fd_set fds;
|
||||
int res;
|
||||
int bytes = 0;
|
||||
static char astresp[256];
|
||||
char audiobuf[4096];
|
||||
for (;;) {
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(STDIN_FILENO, &fds);
|
||||
FD_SET(AUDIO_FILENO, &fds);
|
||||
/* Wait for *some* sort of I/O */
|
||||
res = select(AUDIO_FILENO + 1, &fds, NULL, NULL, NULL);
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "Error in select: %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
if (FD_ISSET(STDIN_FILENO, &fds)) {
|
||||
fgets(astresp, sizeof(astresp), stdin);
|
||||
if (feof(stdin)) {
|
||||
fprintf(stderr, "Got hungup on apparently\n");
|
||||
return NULL;
|
||||
}
|
||||
astresp[strlen(astresp) - 1] = '\0';
|
||||
fprintf(stderr, "Ooh, got a response from Asterisk: '%s'\n", astresp);
|
||||
return astresp;
|
||||
}
|
||||
if (FD_ISSET(AUDIO_FILENO, &fds)) {
|
||||
res = read(AUDIO_FILENO, audiobuf, sizeof(audiobuf));
|
||||
if (res > 0) {
|
||||
/* XXX Process the audio with sphinx here XXX */
|
||||
#if 0
|
||||
fprintf(stderr, "Got %d/%d bytes of audio\n", res, bytes);
|
||||
#endif
|
||||
bytes += res;
|
||||
/* Prentend we detected some audio after 3 seconds */
|
||||
if (bytes > 16000 * 3) {
|
||||
return "Sample Message";
|
||||
bytes = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static char *run_command(char *command)
|
||||
{
|
||||
fprintf(stdout, "%s\n", command);
|
||||
return wait_result();
|
||||
}
|
||||
|
||||
static int run_script(void)
|
||||
{
|
||||
char *res;
|
||||
res = run_command("STREAM FILE demo-enterkeywords 0123456789*#");
|
||||
if (!res) {
|
||||
fprintf(stderr, "Failed to execute command\n");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "1. Result is '%s'\n", res);
|
||||
res = run_command("STREAM FILE demo-nomatch 0123456789*#");
|
||||
if (!res) {
|
||||
fprintf(stderr, "Failed to execute command\n");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "2. Result is '%s'\n", res);
|
||||
res = run_command("SAY NUMBER 23452345 0123456789*#");
|
||||
if (!res) {
|
||||
fprintf(stderr, "Failed to execute command\n");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "3. Result is '%s'\n", res);
|
||||
res = run_command("GET DATA demo-enterkeywords");
|
||||
if (!res) {
|
||||
fprintf(stderr, "Failed to execute command\n");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "4. Result is '%s'\n", res);
|
||||
res = run_command("STREAM FILE auth-thankyou \"\"");
|
||||
if (!res) {
|
||||
fprintf(stderr, "Failed to execute command\n");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "5. Result is '%s'\n", res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *tmp;
|
||||
int ver = 0;
|
||||
int subver = 0;
|
||||
/* Setup stdin/stdout for line buffering */
|
||||
setlinebuf(stdin);
|
||||
setlinebuf(stdout);
|
||||
if (read_environment()) {
|
||||
fprintf(stderr, "Failed to read environment: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
tmp = getenv("agi_enhanced");
|
||||
if (tmp) {
|
||||
if (sscanf(tmp, "%d.%d", &ver, &subver) != 2)
|
||||
ver = 0;
|
||||
}
|
||||
if (ver < 1) {
|
||||
fprintf(stderr, "No enhanced AGI services available. Use EAGI, not AGI\n");
|
||||
exit(1);
|
||||
}
|
||||
if (run_script())
|
||||
return -1;
|
||||
exit(0);
|
||||
}
|
||||
94
agi/fastagi-test
Normal file
94
agi/fastagi-test
Normal file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use Socket;
|
||||
use Carp;
|
||||
use IO::Handle;
|
||||
|
||||
my $port = 4573;
|
||||
|
||||
$|=1;
|
||||
|
||||
# Setup some variables
|
||||
my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;
|
||||
|
||||
sub checkresult {
|
||||
my ($res) = @_;
|
||||
my $retval;
|
||||
$tests++;
|
||||
chomp $res;
|
||||
if ($res =~ /^200/) {
|
||||
$res =~ /result=(-?\d+)/;
|
||||
if (!length($1)) {
|
||||
print STDERR "FAIL ($res)\n";
|
||||
$fail++;
|
||||
} else {
|
||||
print STDERR "PASS ($1)\n";
|
||||
$pass++;
|
||||
}
|
||||
} else {
|
||||
print STDERR "FAIL (unexpected result '$res')\n";
|
||||
$fail++;
|
||||
}
|
||||
}
|
||||
|
||||
socket(SERVER, PF_INET, SOCK_STREAM, 0);
|
||||
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, pack("l", 1));
|
||||
bind(SERVER, sockaddr_in($port, INADDR_ANY)) || die("can't bind\n");
|
||||
listen(SERVER, SOMAXCONN);
|
||||
|
||||
for(;;) {
|
||||
my $raddr = accept(CLIENT, SERVER);
|
||||
my ($s, $p) = sockaddr_in($raddr);
|
||||
CLIENT->autoflush(1);
|
||||
while(<CLIENT>) {
|
||||
chomp;
|
||||
last unless length($_);
|
||||
if (/^agi_(\w+)\:\s+(.*)$/) {
|
||||
$AGI{$1} = $2;
|
||||
}
|
||||
}
|
||||
print STDERR "AGI Environment Dump from $s:$p --\n";
|
||||
foreach my $i (sort keys %AGI) {
|
||||
print STDERR " -- $i = $AGI{$i}\n";
|
||||
}
|
||||
|
||||
print STDERR "1. Testing 'sendfile'...";
|
||||
print CLIENT "STREAM FILE beep \"\"\n";
|
||||
my $result = <CLIENT>;
|
||||
&checkresult($result);
|
||||
|
||||
print STDERR "2. Testing 'sendtext'...";
|
||||
print CLIENT "SEND TEXT \"hello world\"\n";
|
||||
my $result = <CLIENT>;
|
||||
&checkresult($result);
|
||||
|
||||
print STDERR "3. Testing 'sendimage'...";
|
||||
print CLIENT "SEND IMAGE asterisk-image\n";
|
||||
my $result = <CLIENT>;
|
||||
&checkresult($result);
|
||||
|
||||
print STDERR "4. Testing 'saynumber'...";
|
||||
print CLIENT "SAY NUMBER 192837465 \"\"\n";
|
||||
my $result = <CLIENT>;
|
||||
&checkresult($result);
|
||||
|
||||
print STDERR "5. Testing 'waitdtmf'...";
|
||||
print CLIENT "WAIT FOR DIGIT 1000\n";
|
||||
my $result = <CLIENT>;
|
||||
&checkresult($result);
|
||||
|
||||
print STDERR "6. Testing 'record'...";
|
||||
print CLIENT "RECORD FILE testagi gsm 1234 3000\n";
|
||||
my $result = <CLIENT>;
|
||||
&checkresult($result);
|
||||
|
||||
print STDERR "6a. Testing 'record' playback...";
|
||||
print CLIENT "STREAM FILE testagi \"\"\n";
|
||||
my $result = <CLIENT>;
|
||||
&checkresult($result);
|
||||
close(CLIENT);
|
||||
print STDERR "================== Complete ======================\n";
|
||||
print STDERR "$tests tests completed, $pass passed, $fail failed\n";
|
||||
print STDERR "==================================================\n";
|
||||
}
|
||||
|
||||
44
agi/numeralize
Normal file
44
agi/numeralize
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Build a database linking filenames to their numerical representations
|
||||
# using a keypad for the DialAnMp3 application
|
||||
#
|
||||
|
||||
$mp3dir="/usr/media/mpeg3";
|
||||
|
||||
dbmopen(%DIGITS, "/var/lib/asterisk/mp3list", 0644) || die("Unable to open mp3list");;
|
||||
sub process_dir {
|
||||
my ($dir) = @_;
|
||||
my $file;
|
||||
my $digits;
|
||||
my @entries;
|
||||
opendir(DIR, $dir);
|
||||
@entries = readdir(DIR);
|
||||
closedir(DIR);
|
||||
foreach $_ (@entries) {
|
||||
if (!/^\./) {
|
||||
$file = "$dir/$_";
|
||||
if (-d "$file") {
|
||||
process_dir("$file");
|
||||
} else {
|
||||
$digits = $_;
|
||||
$digits =~ s/[^ \w]+//g;
|
||||
$digits =~ s/\_/ /g;
|
||||
$digits =~ tr/[a-z]/[A-Z]/;
|
||||
$digits =~ tr/[A-C]/2/;
|
||||
$digits =~ tr/[D-F]/3/;
|
||||
$digits =~ tr/[G-I]/4/;
|
||||
$digits =~ tr/[J-L]/5/;
|
||||
$digits =~ tr/[M-O]/6/;
|
||||
$digits =~ tr/[P-S]/7/;
|
||||
$digits =~ tr/[T-V]/8/;
|
||||
$digits =~ tr/[W-Z]/9/;
|
||||
$digits =~ s/\s+/ /;
|
||||
print "File: $file, digits: $digits\n";
|
||||
$DIGITS{$file} = $digits;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process_dir($mp3dir);
|
||||
85
alaw.c
Normal file
85
alaw.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* u-Law to Signed linear conversion
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/alaw.h>
|
||||
|
||||
#define AMI_MASK 0x55
|
||||
|
||||
static inline unsigned char linear2alaw (short int linear)
|
||||
{
|
||||
int mask;
|
||||
int seg;
|
||||
int pcm_val;
|
||||
static int seg_end[8] =
|
||||
{
|
||||
0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
|
||||
};
|
||||
|
||||
pcm_val = linear;
|
||||
if (pcm_val >= 0)
|
||||
{
|
||||
/* Sign (7th) bit = 1 */
|
||||
mask = AMI_MASK | 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Sign bit = 0 */
|
||||
mask = AMI_MASK;
|
||||
pcm_val = -pcm_val;
|
||||
}
|
||||
|
||||
/* Convert the scaled magnitude to segment number. */
|
||||
for (seg = 0; seg < 8; seg++)
|
||||
{
|
||||
if (pcm_val <= seg_end[seg])
|
||||
break;
|
||||
}
|
||||
/* Combine the sign, segment, and quantization bits. */
|
||||
return ((seg << 4) | ((pcm_val >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static inline short int alaw2linear (unsigned char alaw)
|
||||
{
|
||||
int i;
|
||||
int seg;
|
||||
|
||||
alaw ^= AMI_MASK;
|
||||
i = ((alaw & 0x0F) << 4);
|
||||
seg = (((int) alaw & 0x70) >> 4);
|
||||
if (seg)
|
||||
i = (i + 0x100) << (seg - 1);
|
||||
return (short int) ((alaw & 0x80) ? i : -i);
|
||||
}
|
||||
|
||||
unsigned char __ast_lin2a[8192];
|
||||
short __ast_alaw[256];
|
||||
|
||||
void ast_alaw_init(void)
|
||||
{
|
||||
int i;
|
||||
/*
|
||||
* Set up mu-law conversion table
|
||||
*/
|
||||
for(i = 0;i < 256;i++)
|
||||
{
|
||||
__ast_alaw[i] = alaw2linear(i);
|
||||
}
|
||||
/* set up the reverse (mu-law) conversion table */
|
||||
for(i = -32768; i < 32768; i++)
|
||||
{
|
||||
__ast_lin2a[((unsigned short)i) >> 3] = linear2alaw(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
87
apps/Makefile
Executable file → Normal file
87
apps/Makefile
Executable file → Normal file
@@ -11,17 +11,94 @@
|
||||
# the GNU General Public License
|
||||
#
|
||||
|
||||
APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_intercom.so app_mp3.so app_system.so app_echo.so
|
||||
USE_MYSQL_VM_INTERFACE=0
|
||||
USE_POSTGRES_VM_INTERFACE=0
|
||||
|
||||
CFLAGS+=
|
||||
#APPS=app_dial.so app_playback.so app_directory.so app_intercom.so app_mp3.so
|
||||
APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_mp3.so\
|
||||
app_system.so app_echo.so app_record.so app_image.so app_url.so app_disa.so \
|
||||
app_qcall.so app_adsiprog.so app_getcpeid.so app_milliwatt.so \
|
||||
app_zapateller.so app_setcallerid.so app_festival.so \
|
||||
app_queue.so app_senddtmf.so app_parkandannounce.so app_striplsd.so \
|
||||
app_setcidname.so app_lookupcidname.so app_substring.so app_macro.so \
|
||||
app_authenticate.so app_softhangup.so app_lookupblacklist.so \
|
||||
app_waitforring.so app_privacy.so app_db.so app_chanisavail.so \
|
||||
app_enumlookup.so app_transfer.so app_setcidnum.so app_cdr.so \
|
||||
app_hasnewvoicemail.so app_sayunixtime.so app_cut.so app_read.so \
|
||||
app_setcdruserfield.so app_random.so app_ices.so app_eval.so \
|
||||
app_nbscat.so app_sendtext.so app_exec.so app_sms.so \
|
||||
app_groupcount.so app_txtcidname.so app_controlplayback.so \
|
||||
app_talkdetect.so app_alarmreceiver.so app_userevent.so app_verbose.so \
|
||||
app_test.so app_forkcdr.so
|
||||
|
||||
ifneq (${OSARCH},Darwin)
|
||||
APPS+=app_intercom.so
|
||||
endif
|
||||
|
||||
#APPS+=app_sql_postgres.so
|
||||
#APPS+=app_sql_odbc.so
|
||||
#APPS+=app_rpt.so
|
||||
|
||||
APPS+=$(shell if [ -f /usr/include/linux/zaptel.h ]; then echo "app_zapras.so app_meetme.so app_flash.so app_zapbarge.so app_zapscan.so" ; fi)
|
||||
APPS+=$(shell if [ -f /usr/local/include/zaptel.h ]; then echo "app_zapras.so app_meetme.so app_flash.so app_zapbarge.so app_zapscan.so" ; fi)
|
||||
APPS+=$(shell if [ -f /usr/include/osp/osp.h ]; then echo "app_osplookup.so" ; fi)
|
||||
|
||||
CFLAGS+=-fPIC
|
||||
|
||||
ifeq ($(USE_POSTGRES_VM_INTERFACE),1)
|
||||
CFLAGS+=-DUSEPOSTGRESVM
|
||||
endif
|
||||
|
||||
ifeq ($(USE_MYSQL_VM_INTERFACE),1)
|
||||
CFLAGS+=-DUSEMYSQLVM
|
||||
endif
|
||||
|
||||
all: $(APPS)
|
||||
|
||||
clean:
|
||||
rm -f *.so *.o
|
||||
rm -f *.so *.o look .depend
|
||||
|
||||
%.so : %.o
|
||||
$(CC) -shared -Xlinker -x -o $@ $<
|
||||
$(CC) $(SOLINK) -o $@ $<
|
||||
|
||||
app_rpt.so : app_rpt.o
|
||||
$(CC) $(SOLINK) -o $@ $< -ltonezone
|
||||
|
||||
install: all
|
||||
for x in $(APPS); do $(INSTALL) -m 755 $$x $(MODULES_DIR) ; done
|
||||
for x in $(APPS); do $(INSTALL) -m 755 $$x $(DESTDIR)$(MODULES_DIR) ; done
|
||||
rm -f $(DESTDIR)$(MODULES_DIR)/app_datetime.so
|
||||
|
||||
app_voicemail.so : app_voicemail.o
|
||||
ifeq ($(USE_MYSQL_VM_INTERFACE),1)
|
||||
$(CC) $(SOLINK) -o $@ $(MLFLAGS) $< -L/usr/lib/mysql -lmysqlclient -lz
|
||||
else
|
||||
ifeq ($(USE_POSTGRES_VM_INTERFACE),1)
|
||||
$(CC) $(SOLINK) -o $@ $(MLFLAGS) $< -lpq
|
||||
else
|
||||
$(CC) $(SOLINK) -o $@ $(MLFLAGS) $<
|
||||
endif
|
||||
endif
|
||||
|
||||
app_sql_postgres.o: app_sql_postgres.c
|
||||
$(CC) -pipe -I/usr/local/pgsql/include $(CFLAGS) -c -o app_sql_postgres.o app_sql_postgres.c
|
||||
|
||||
app_sql_postgres.so: app_sql_postgres.o
|
||||
$(CC) $(SOLINK) -o $@ $< -L/usr/local/pgsql/lib -lpq
|
||||
|
||||
app_sql_odbc.so: app_sql_odbc.o
|
||||
$(CC) $(SOLINK) -o $@ $< -lodbc
|
||||
|
||||
look: look.c
|
||||
$(CC) -pipe -O6 -g look.c -o look -lncurses
|
||||
|
||||
ifneq ($(wildcard .depend),)
|
||||
include .depend
|
||||
endif
|
||||
|
||||
depend: .depend
|
||||
|
||||
.depend:
|
||||
../mkdep $(CFLAGS) `ls *.c`
|
||||
|
||||
env:
|
||||
env
|
||||
|
||||
1584
apps/app_adsiprog.c
Normal file
1584
apps/app_adsiprog.c
Normal file
File diff suppressed because it is too large
Load Diff
858
apps/app_alarmreceiver.c
Normal file
858
apps/app_alarmreceiver.c
Normal file
@@ -0,0 +1,858 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Central Station Alarm receiver for Ademco Contact ID
|
||||
*
|
||||
* Copyright (C) 2004 Steve Rodgers
|
||||
*
|
||||
* Steve Rodgers <hwstar@rodgers.sdcoxmail.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*
|
||||
* *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
|
||||
*
|
||||
* Use at your own risk. Please consult the GNU GPL license document included with Asterisk details. *
|
||||
*
|
||||
* *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/ulaw.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/app.h>
|
||||
#include <asterisk/dsp.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/localtime.h>
|
||||
#include <asterisk/callerid.h>
|
||||
#include <asterisk/astdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define ALMRCV_CONFIG "alarmreceiver.conf"
|
||||
#define ADEMCO_CONTACT_ID "ADEMCO_CONTACT_ID"
|
||||
|
||||
struct event_node{
|
||||
char data[17];
|
||||
struct event_node *next;
|
||||
};
|
||||
|
||||
typedef struct event_node event_node_t;
|
||||
|
||||
static char *tdesc = "Alarm Receiver for Asterisk";
|
||||
|
||||
static char *app = "AlarmReceiver";
|
||||
|
||||
static char *synopsis = "Provide support for receving alarm reports from a burglar or fire alarm panel";
|
||||
static char *descrip =
|
||||
"Alarm receiver application for Asterisk. Only 1 signalling format is supported at this time:\n"
|
||||
"Ademco Contact ID. This application should be called whenever there is an alarm panel calling in\n"
|
||||
"to dump its events. The application will handshake with the alarm panel, and receive events,\n"
|
||||
"validate them, handshake them, and store them until the panel hangs up. Once the panel hangs up,\n"
|
||||
"the application will run the command line specified by the eventcmd setting in alarmreceiver.conf\n"
|
||||
"and pipe the events to the standard input of the application. Alarmreceiver.conf also contains settings\n"
|
||||
"for DTMF timing, and for the loudness of the acknowledgement tones.\n";
|
||||
|
||||
/* Config Variables */
|
||||
|
||||
static int fdtimeout = 2000;
|
||||
static int sdtimeout = 200;
|
||||
static int toneloudness = 4096;
|
||||
static int log_individual_events = 0;
|
||||
static char event_spool_dir[128] = {'\0'};
|
||||
static char event_app[128] = {'\0'};
|
||||
static char db_family[128] = {'\0'};
|
||||
static char time_stamp_format[128] = {"%a %b %d, %Y @ %H:%M:%S %Z"};
|
||||
|
||||
|
||||
/* Misc variables */
|
||||
|
||||
|
||||
static char event_file[14] = "/event-XXXXXX";
|
||||
|
||||
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
/*
|
||||
* Attempt to access a database variable and increment it,
|
||||
* provided that the user defined db-family in alarmreceiver.conf
|
||||
* The alarmreceiver app will write statistics to a few variables
|
||||
* in this family if it is defined. If the new key doesn't exist in the
|
||||
* family, then create it and set its value to 1.
|
||||
*/
|
||||
|
||||
static void database_increment( char *key )
|
||||
{
|
||||
int res = 0;
|
||||
unsigned v;
|
||||
char value[16];
|
||||
|
||||
|
||||
if(!strlen(db_family))
|
||||
return; /* If not defined, don't do anything */
|
||||
|
||||
res = ast_db_get(db_family, key, value, sizeof(value) - 1);
|
||||
|
||||
if(res){
|
||||
if(option_verbose >= 4)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Creating database entry %s and setting to 1\n", key);
|
||||
/* Guess we have to create it */
|
||||
res = ast_db_put(db_family, key, "1");
|
||||
return;
|
||||
}
|
||||
|
||||
sscanf(value, "%u", &v);
|
||||
v++;
|
||||
|
||||
if(option_verbose >= 4)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: New value for %s: %u\n", key, v);
|
||||
|
||||
snprintf(value, sizeof(value), "%u", v);
|
||||
|
||||
res = ast_db_put(db_family, key, value);
|
||||
|
||||
if((res)&&(option_verbose >= 4))
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: database_increment write error");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Build a MuLaw data block for a single frequency tone
|
||||
*/
|
||||
|
||||
static void make_tone_burst(unsigned char *data, float freq, float loudness, int len, int *x)
|
||||
{
|
||||
int i;
|
||||
float val;
|
||||
|
||||
for(i = 0; i < len; i++){
|
||||
val = loudness * sin((freq * 2.0 * M_PI * (*x)++)/8000.0);
|
||||
data[i] = AST_LIN2MU((int)val);
|
||||
}
|
||||
|
||||
/* wrap back around from 8000 */
|
||||
|
||||
if (*x >= 8000) *x = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a single tone burst for a specifed duration and frequency.
|
||||
* Returns 0 if successful
|
||||
*/
|
||||
|
||||
static int send_tone_burst(struct ast_channel *chan, float freq, int duration, int tldn)
|
||||
{
|
||||
int res = 0;
|
||||
int i = 0;
|
||||
int x = 0;
|
||||
struct ast_frame *f, wf;
|
||||
|
||||
struct {
|
||||
unsigned char offset[AST_FRIENDLY_OFFSET];
|
||||
unsigned char buf[640];
|
||||
} tone_block;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
|
||||
if (ast_waitfor(chan, -1) < 0){
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
f = ast_read(chan);
|
||||
if (!f){
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (f->frametype == AST_FRAME_VOICE) {
|
||||
wf.frametype = AST_FRAME_VOICE;
|
||||
wf.subclass = AST_FORMAT_ULAW;
|
||||
wf.offset = AST_FRIENDLY_OFFSET;
|
||||
wf.mallocd = 0;
|
||||
wf.data = tone_block.buf;
|
||||
wf.datalen = f->datalen;
|
||||
wf.samples = wf.datalen;
|
||||
|
||||
make_tone_burst(tone_block.buf, freq, (float) tldn, wf.datalen, &x);
|
||||
|
||||
i += wf.datalen / 8;
|
||||
if (i > duration) {
|
||||
break;
|
||||
}
|
||||
if (ast_write(chan, &wf)){
|
||||
if(option_verbose >= 4)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Failed to write frame on %s\n", chan->name);
|
||||
ast_log(LOG_WARNING, "AlarmReceiver Failed to write frame on %s\n",chan->name);
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ast_frfree(f);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the difference in milliseconds between two timeval structs
|
||||
*/
|
||||
|
||||
static int ms_diff(struct timeval *tv1, struct timeval *tv2){
|
||||
|
||||
int ms;
|
||||
|
||||
ms = (tv1->tv_sec - tv2->tv_sec) * 1000;
|
||||
ms += (tv1->tv_usec - tv2->tv_usec) / 1000;
|
||||
|
||||
return(ms);
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive a string of DTMF digits where the length of the digit string is known in advance. Do not give preferential
|
||||
* treatment to any digit value, and allow separate time out values to be specified for the first digit and all subsequent
|
||||
* digits.
|
||||
*
|
||||
* Returns 0 if all digits successfully received.
|
||||
* Returns 1 if a digit time out occurred
|
||||
* Returns -1 if the caller hung up or there was a channel error.
|
||||
*
|
||||
*/
|
||||
|
||||
static int receive_dtmf_digits(struct ast_channel *chan, char *digit_string, int length, int fdto, int sdto)
|
||||
{
|
||||
int res = 0;
|
||||
int i = 0;
|
||||
int r;
|
||||
struct ast_frame *f;
|
||||
struct timeval now, lastdigittime;
|
||||
|
||||
gettimeofday(&lastdigittime,NULL);
|
||||
for(;;){
|
||||
gettimeofday(&now,NULL);
|
||||
|
||||
/* if outa time, leave */
|
||||
if (ms_diff(&now,&lastdigittime) >
|
||||
((i > 0) ? sdto : fdto)){
|
||||
if(option_verbose >= 4)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: DTMF Digit Timeout on %s\n", chan->name);
|
||||
|
||||
ast_log(LOG_DEBUG,"AlarmReceiver: DTMF timeout on chan %s\n",chan->name);
|
||||
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((r = ast_waitfor(chan, -1) < 0)) {
|
||||
ast_log(LOG_DEBUG, "Waitfor returned %d\n", r);
|
||||
continue;
|
||||
}
|
||||
|
||||
f = ast_read(chan);
|
||||
|
||||
if (f == NULL){
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If they hung up, leave */
|
||||
if ((f->frametype == AST_FRAME_CONTROL) &&
|
||||
(f->subclass == AST_CONTROL_HANGUP)){
|
||||
ast_frfree(f);
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if not DTMF, just do it again */
|
||||
if (f->frametype != AST_FRAME_DTMF){
|
||||
ast_frfree(f);
|
||||
continue;
|
||||
}
|
||||
|
||||
digit_string[i++] = f->subclass; /* save digit */
|
||||
|
||||
ast_frfree(f);
|
||||
|
||||
/* If we have all the digits we expect, leave */
|
||||
if(i >= length)
|
||||
break;
|
||||
|
||||
gettimeofday(&lastdigittime,NULL);
|
||||
}
|
||||
|
||||
digit_string[i] = '\0'; /* Nul terminate the end of the digit string */
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the metadata to the log file
|
||||
*/
|
||||
|
||||
static int write_metadata( FILE *logfile, char *signalling_type, struct ast_channel *chan)
|
||||
{
|
||||
int res = 0;
|
||||
time_t t;
|
||||
struct tm now;
|
||||
char *cl,*cn;
|
||||
char workstring[80];
|
||||
char timestamp[80];
|
||||
|
||||
/* Extract the caller ID location */
|
||||
|
||||
strncpy(workstring, chan->callerid, sizeof(workstring) - 1);
|
||||
workstring[sizeof(workstring) - 1] = '\0';
|
||||
|
||||
ast_callerid_parse(workstring, &cn, &cl);
|
||||
if (cl)
|
||||
ast_shrink_phone_number(cl);
|
||||
|
||||
|
||||
/* Get the current time */
|
||||
|
||||
time(&t);
|
||||
ast_localtime(&t, &now, NULL);
|
||||
|
||||
/* Format the time */
|
||||
|
||||
strftime(timestamp, sizeof(timestamp), time_stamp_format, &now);
|
||||
|
||||
|
||||
res = fprintf(logfile, "\n\n[metadata]\n\n");
|
||||
|
||||
if(res >= 0)
|
||||
res = fprintf(logfile, "PROTOCOL=%s\n", signalling_type);
|
||||
|
||||
if(res >= 0)
|
||||
res = fprintf(logfile, "CALLINGFROM=%s\n", (!cl) ? "<unknown>" : cl);
|
||||
|
||||
if(res >- 0)
|
||||
res = fprintf(logfile, "CALLERNAME=%s\n", (!cn) ? "<unknown>" : cn);
|
||||
|
||||
if(res >= 0)
|
||||
res = fprintf(logfile, "TIMESTAMP=%s\n\n", timestamp);
|
||||
|
||||
if(res >= 0)
|
||||
res = fprintf(logfile, "[events]\n\n");
|
||||
|
||||
if(res < 0){
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: can't write metadata\n");
|
||||
|
||||
ast_log(LOG_DEBUG,"AlarmReceiver: can't write metadata\n");
|
||||
}
|
||||
else
|
||||
res = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a single event to the log file
|
||||
*/
|
||||
|
||||
static int write_event( FILE *logfile, event_node_t *event)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
if( fprintf(logfile, "%s\n", event->data) < 0)
|
||||
res = -1;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If we are configured to log events, do so here.
|
||||
*
|
||||
*/
|
||||
|
||||
static int log_events(struct ast_channel *chan, char *signalling_type, event_node_t *event)
|
||||
{
|
||||
|
||||
int res = 0;
|
||||
char workstring[sizeof(event_spool_dir)+sizeof(event_file)] = "";
|
||||
int fd;
|
||||
FILE *logfile;
|
||||
event_node_t *elp = event;
|
||||
|
||||
if(strlen(event_spool_dir)){
|
||||
|
||||
/* Make a template */
|
||||
|
||||
strncpy(workstring, event_spool_dir, sizeof(workstring) - 1);
|
||||
strncat(workstring, event_file, sizeof(workstring) - strlen(workstring) - 1);
|
||||
|
||||
/* Make the temporary file */
|
||||
|
||||
fd = mkstemp(workstring);
|
||||
|
||||
if(fd == -1){
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: can't make temporary file\n");
|
||||
ast_log(LOG_DEBUG,"AlarmReceiver: can't make temporary file\n");
|
||||
res = -1;
|
||||
}
|
||||
|
||||
if(!res){
|
||||
logfile = fdopen(fd, "w");
|
||||
if(logfile){
|
||||
/* Write the file */
|
||||
res = write_metadata(logfile, signalling_type, chan);
|
||||
if(!res)
|
||||
while((!res) && (elp != NULL)){
|
||||
res = write_event(logfile, elp);
|
||||
elp = elp->next;
|
||||
}
|
||||
if(!res){
|
||||
if(fflush(logfile) == EOF)
|
||||
res = -1;
|
||||
if(!res){
|
||||
if(fclose(logfile) == EOF)
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function implements the logic to receive the Ademco contact ID format.
|
||||
*
|
||||
* The function will return 0 when the caller hangs up, else a -1 if there was a problem.
|
||||
*/
|
||||
|
||||
static int receive_ademco_contact_id( struct ast_channel *chan, void *data, int fdto, int sdto, int tldn, event_node_t **ehead)
|
||||
{
|
||||
int i,j;
|
||||
int res = 0;
|
||||
int checksum;
|
||||
char event[17];
|
||||
event_node_t *enew, *elp;
|
||||
int got_some_digits = 0;
|
||||
int events_received = 0;
|
||||
int ack_retries = 0;
|
||||
|
||||
static char digit_map[15] = "0123456789*#ABC";
|
||||
static unsigned char digit_weights[15] = {10,1,2,3,4,5,6,7,8,9,11,12,13,14,15};
|
||||
|
||||
database_increment("calls-received");
|
||||
|
||||
/* Wait for first event */
|
||||
|
||||
if(option_verbose >= 4)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Waiting for first event from panel\n");
|
||||
|
||||
while(res >= 0){
|
||||
|
||||
if(got_some_digits == 0){
|
||||
|
||||
/* Send ACK tone sequence */
|
||||
|
||||
|
||||
if(option_verbose >= 4)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Sending 1400Hz 100ms burst (ACK)\n");
|
||||
|
||||
|
||||
res = send_tone_burst(chan, 1400.0, 100, tldn);
|
||||
|
||||
if(!res)
|
||||
res = ast_safe_sleep(chan, 100);
|
||||
|
||||
if(!res){
|
||||
if(option_verbose >= 4)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Sending 2300Hz 100ms burst (ACK)\n");
|
||||
|
||||
res = send_tone_burst(chan, 2300.0, 100, tldn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( res >= 0)
|
||||
res = receive_dtmf_digits(chan, event, sizeof(event) - 1, fdto, sdto);
|
||||
|
||||
if (res < 0){
|
||||
|
||||
if(events_received == 0)
|
||||
/* Hangup with no events received should be logged in the DB */
|
||||
database_increment("no-events-received");
|
||||
else{
|
||||
if(ack_retries){
|
||||
if(option_verbose >= 4)
|
||||
ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: ACK retries during this call: %d\n", ack_retries);
|
||||
|
||||
database_increment("ack-retries");
|
||||
}
|
||||
}
|
||||
if(option_verbose >= 4)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: App exiting...\n");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(res != 0){
|
||||
/* Didn't get all of the digits */
|
||||
if(option_verbose >= 2)
|
||||
ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Incomplete string: %s, trying again...\n", event);
|
||||
|
||||
if(!got_some_digits){
|
||||
got_some_digits = (strlen(event)) ? 1 : 0;
|
||||
ack_retries++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
got_some_digits = 1;
|
||||
|
||||
if(option_verbose >= 2)
|
||||
ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Received Event %s\n", event);
|
||||
ast_log(LOG_DEBUG, "AlarmReceiver: Received event: %s\n", event);
|
||||
|
||||
/* Calculate checksum */
|
||||
|
||||
for(j = 0, checksum = 0; j < 16; j++){
|
||||
for(i = 0 ; i < sizeof(digit_map) ; i++){
|
||||
if(digit_map[i] == event[j])
|
||||
break;
|
||||
}
|
||||
|
||||
if(i == 16)
|
||||
break;
|
||||
|
||||
checksum += digit_weights[i];
|
||||
}
|
||||
|
||||
if(i == 16){
|
||||
if(option_verbose >= 2)
|
||||
ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Bad DTMF character %c, trying again\n", event[j]);
|
||||
continue; /* Bad character */
|
||||
}
|
||||
|
||||
/* Checksum is mod(15) of the total */
|
||||
|
||||
checksum = checksum % 15;
|
||||
|
||||
if(checksum){
|
||||
database_increment("checksum-errors");
|
||||
if(option_verbose >= 2){
|
||||
ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Nonzero checksum\n");
|
||||
ast_log(LOG_DEBUG, "AlarmReceiver: Nonzero checksum\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the message type for correctness */
|
||||
|
||||
if(strncmp(event + 4, "18", 2)){
|
||||
if(strncmp(event + 4, "98", 2)){
|
||||
database_increment("format-errors");
|
||||
if(option_verbose >= 2)
|
||||
ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Wrong message type\n");
|
||||
ast_log(LOG_DEBUG, "AlarmReceiver: Wrong message type\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
events_received++;
|
||||
|
||||
/* Queue the Event */
|
||||
|
||||
if((enew = malloc(sizeof(event_node_t))) == NULL){
|
||||
if(option_verbose >= 1)
|
||||
ast_verbose(VERBOSE_PREFIX_1 "AlarmReceiver: Failed to allocate memory\n");
|
||||
ast_log(LOG_WARNING, "AlarmReceiver Failed to allocate memory\n");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(enew, 0, sizeof(event_node_t));
|
||||
|
||||
enew->next = NULL;
|
||||
strncpy(enew->data, event, sizeof(enew->data) - 1);
|
||||
|
||||
/*
|
||||
* Insert event onto end of list
|
||||
*/
|
||||
|
||||
if(*ehead == NULL){
|
||||
*ehead = enew;
|
||||
}
|
||||
else{
|
||||
for(elp = *ehead; elp->next != NULL; elp = elp->next)
|
||||
;
|
||||
|
||||
elp->next = enew;
|
||||
}
|
||||
|
||||
if(res > 0)
|
||||
res = 0;
|
||||
|
||||
/* Let the user have the option of logging the single event before sending the kissoff tone */
|
||||
|
||||
if((res == 0) && (log_individual_events))
|
||||
res = log_events(chan, ADEMCO_CONTACT_ID, enew);
|
||||
|
||||
/* Wait 200 msec before sending kissoff */
|
||||
|
||||
if(res == 0)
|
||||
res = ast_safe_sleep(chan, 200);
|
||||
|
||||
/* Send the kissoff tone */
|
||||
|
||||
if(res == 0)
|
||||
res = send_tone_burst(chan, 1400.0, 900, tldn);
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is the main function called by Asterisk Core whenever the App is invoked in the extension logic.
|
||||
* This function will always return 0.
|
||||
*/
|
||||
|
||||
static int alarmreceiver_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
struct localuser *u;
|
||||
event_node_t *elp, *efree;
|
||||
char signalling_type[64] = "";
|
||||
|
||||
event_node_t *event_head = NULL;
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
/* Set write and read formats to ULAW */
|
||||
|
||||
if(option_verbose >= 4)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Setting read and write formats to ULAW\n");
|
||||
|
||||
if (ast_set_write_format(chan,AST_FORMAT_ULAW)){
|
||||
ast_log(LOG_WARNING, "AlarmReceiver: Unable to set write format to Mu-law on %s\n",chan->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ast_set_read_format(chan,AST_FORMAT_ULAW)){
|
||||
ast_log(LOG_WARNING, "AlarmReceiver: Unable to set read format to Mu-law on %s\n",chan->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set default values for this invokation of the application */
|
||||
|
||||
strncpy(signalling_type, ADEMCO_CONTACT_ID, sizeof(signalling_type) - 1);
|
||||
|
||||
|
||||
/* Answer the channel if it is not already */
|
||||
|
||||
if(option_verbose >= 4)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Answering channel\n");
|
||||
|
||||
if (chan->_state != AST_STATE_UP) {
|
||||
|
||||
res = ast_answer(chan);
|
||||
|
||||
if (res) {
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for the connection to settle post-answer */
|
||||
|
||||
if(option_verbose >= 4)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Waiting for connection to stabilize\n");
|
||||
|
||||
res = ast_safe_sleep(chan, 1250);
|
||||
|
||||
/* Attempt to receive the events */
|
||||
|
||||
if(!res){
|
||||
|
||||
/* Determine the protocol to receive in advance */
|
||||
/* Note: Ademco contact is the only one supported at this time */
|
||||
/* Others may be added later */
|
||||
|
||||
if(!strcmp(signalling_type, ADEMCO_CONTACT_ID))
|
||||
receive_ademco_contact_id(chan, data, fdtimeout, sdtimeout, toneloudness, &event_head);
|
||||
else
|
||||
res = -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Events queued by receiver, write them all out here if so configured */
|
||||
|
||||
if((!res) && (log_individual_events == 0)){
|
||||
res = log_events(chan, signalling_type, event_head);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Do we exec a command line at the end?
|
||||
*/
|
||||
|
||||
if((!res) && (strlen(event_app)) && (event_head)){
|
||||
ast_log(LOG_DEBUG,"Alarmreceiver: executing: %s\n", event_app);
|
||||
ast_safe_system(event_app);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free up the data allocated in our linked list
|
||||
*/
|
||||
|
||||
for(elp = event_head; (elp != NULL);){
|
||||
efree = elp;
|
||||
elp = elp->next;
|
||||
free(efree);
|
||||
}
|
||||
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the configuration from the configuration file
|
||||
*/
|
||||
|
||||
static int load_config(void)
|
||||
{
|
||||
struct ast_config *cfg;
|
||||
char *p;
|
||||
|
||||
/* Read in the config file */
|
||||
|
||||
cfg = ast_load(ALMRCV_CONFIG);
|
||||
|
||||
if(!cfg){
|
||||
|
||||
if(option_verbose >= 4)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: No config file\n");
|
||||
}
|
||||
else{
|
||||
|
||||
|
||||
p = ast_variable_retrieve(cfg, "general", "eventcmd");
|
||||
|
||||
if(p){
|
||||
strncpy(event_app, p, sizeof(event_app) - 1);
|
||||
event_app[sizeof(event_app) - 1] = '\0';
|
||||
}
|
||||
|
||||
p = ast_variable_retrieve(cfg, "general", "loudness");
|
||||
if(p){
|
||||
toneloudness = atoi(p);
|
||||
if(toneloudness < 100)
|
||||
toneloudness = 100;
|
||||
if(toneloudness > 8192)
|
||||
toneloudness = 8192;
|
||||
}
|
||||
p = ast_variable_retrieve(cfg, "general", "fdtimeout");
|
||||
if(p){
|
||||
fdtimeout = atoi(p);
|
||||
if(fdtimeout < 1000)
|
||||
fdtimeout = 1000;
|
||||
if(fdtimeout > 10000)
|
||||
fdtimeout = 10000;
|
||||
}
|
||||
|
||||
p = ast_variable_retrieve(cfg, "general", "sdtimeout");
|
||||
if(p){
|
||||
sdtimeout = atoi(p);
|
||||
if(sdtimeout < 110)
|
||||
sdtimeout = 110;
|
||||
if(sdtimeout > 4000)
|
||||
sdtimeout = 4000;
|
||||
|
||||
}
|
||||
|
||||
p = ast_variable_retrieve(cfg, "general", "logindividualevents");
|
||||
if(p){
|
||||
log_individual_events = ast_true(p);
|
||||
|
||||
}
|
||||
|
||||
p = ast_variable_retrieve(cfg, "general", "eventspooldir");
|
||||
|
||||
if(p){
|
||||
strncpy(event_spool_dir, p, sizeof(event_spool_dir) - 1);
|
||||
event_spool_dir[sizeof(event_spool_dir) - 1] = '\0';
|
||||
}
|
||||
|
||||
p = ast_variable_retrieve(cfg, "general", "timestampformat");
|
||||
|
||||
if(p){
|
||||
strncpy(time_stamp_format, p, sizeof(time_stamp_format) - 1);
|
||||
time_stamp_format[sizeof(time_stamp_format) - 1] = '\0';
|
||||
}
|
||||
|
||||
p = ast_variable_retrieve(cfg, "general", "db-family");
|
||||
|
||||
if(p){
|
||||
strncpy(db_family, p, sizeof(db_family) - 1);
|
||||
db_family[sizeof(db_family) - 1] = '\0';
|
||||
}
|
||||
ast_destroy(cfg);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions are required to implement an Asterisk App.
|
||||
*/
|
||||
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
load_config();
|
||||
return ast_register_application(app, alarmreceiver_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
172
apps/app_authenticate.c
Normal file
172
apps/app_authenticate.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Execute arbitrary authenticate commands
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/app.h>
|
||||
#include <asterisk/astdb.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static char *tdesc = "Authentication Application";
|
||||
|
||||
static char *app = "Authenticate";
|
||||
|
||||
static char *synopsis = "Authenticate a user";
|
||||
|
||||
static char *descrip =
|
||||
" Authenticate(password[|options]): Requires a user to enter a"
|
||||
"given password in order to continue execution. If the\n"
|
||||
"password begins with the '/' character, it is interpreted as\n"
|
||||
"a file which contains a list of valid passwords (1 per line).\n"
|
||||
"an optional set of opions may be provided by concatenating any\n"
|
||||
"of the following letters:\n"
|
||||
" a - Set account code to the password that is entered\n"
|
||||
" d - Interpret path as database key, not literal file\n"
|
||||
" r - Remove database key upon successful entry (valid with 'd' only)\n"
|
||||
"\n"
|
||||
"When using a database key, the value associated with the key can be\n"
|
||||
"anything.\n"
|
||||
"Returns 0 if the user enters a valid password within three\n"
|
||||
"tries, or -1 otherwise (or on hangup).\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int auth_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
int retries;
|
||||
struct localuser *u;
|
||||
char password[256]="";
|
||||
char passwd[256];
|
||||
char *opts;
|
||||
char *prompt;
|
||||
if (!data || ast_strlen_zero(data)) {
|
||||
ast_log(LOG_WARNING, "Authenticate requires an argument(password)\n");
|
||||
return -1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
if (chan->_state != AST_STATE_UP) {
|
||||
res = ast_answer(chan);
|
||||
if (res) {
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
strncpy(password, data, sizeof(password) - 1);
|
||||
opts=strchr(password, '|');
|
||||
if (opts) {
|
||||
*opts = 0;
|
||||
opts++;
|
||||
} else
|
||||
opts = "";
|
||||
/* Start asking for password */
|
||||
prompt = "agent-pass";
|
||||
for (retries = 0; retries < 3; retries++) {
|
||||
res = ast_app_getdata(chan, prompt, passwd, sizeof(passwd) - 2, 0);
|
||||
if (res < 0)
|
||||
break;
|
||||
res = 0;
|
||||
if (password[0] == '/') {
|
||||
if (strchr(opts, 'd')) {
|
||||
char tmp[256];
|
||||
/* Compare against a database key */
|
||||
if (!ast_db_get(password + 1, passwd, tmp, sizeof(tmp))) {
|
||||
/* It's a good password */
|
||||
if (strchr(opts, 'r')) {
|
||||
ast_db_del(password + 1, passwd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Compare against a file */
|
||||
FILE *f;
|
||||
f = fopen(password, "r");
|
||||
if (f) {
|
||||
char buf[256] = "";
|
||||
while(!feof(f)) {
|
||||
fgets(buf, sizeof(buf), f);
|
||||
if (!feof(f) && !ast_strlen_zero(buf)) {
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
if (!ast_strlen_zero(buf) && !strcmp(passwd, buf))
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
if (!ast_strlen_zero(buf) && !strcmp(passwd, buf))
|
||||
break;
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Unable to open file '%s' for authentication: %s\n", password, strerror(errno));
|
||||
}
|
||||
} else {
|
||||
/* Compare against a fixed password */
|
||||
if (!strcmp(passwd, password))
|
||||
break;
|
||||
}
|
||||
prompt="auth-incorrect";
|
||||
}
|
||||
if ((retries < 3) && !res) {
|
||||
if (strchr(opts, 'a'))
|
||||
ast_cdr_setaccount(chan, passwd);
|
||||
res = ast_streamfile(chan, "auth-thankyou", chan->language);
|
||||
if (!res)
|
||||
res = ast_waitstream(chan, "");
|
||||
} else {
|
||||
if (!res)
|
||||
res = ast_streamfile(chan, "vm-goodbye", chan->language);
|
||||
if (!res)
|
||||
res = ast_waitstream(chan, "");
|
||||
res = -1;
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, auth_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
66
apps/app_cdr.c
Normal file
66
apps/app_cdr.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Applictions connected with CDR engine
|
||||
*
|
||||
* Copyright (C) 2003, Digium
|
||||
*
|
||||
* Martin Pycko <martinp@digium.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
static char *tdesc = "Make sure asterisk doesn't save CDR for a certain call";
|
||||
|
||||
static char *nocdr_descrip = "NoCDR(): makes sure there won't be any CDR written for a certain call";
|
||||
static char *nocdr_app = "NoCDR";
|
||||
static char *nocdr_synopsis = "Make sure asterisk doesn't save CDR for a certain call";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int nocdr_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
if (chan->cdr) {
|
||||
ast_cdr_free(chan->cdr);
|
||||
chan->cdr = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(nocdr_app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(nocdr_app, nocdr_exec, nocdr_synopsis, nocdr_descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
137
apps/app_chanisavail.c
Normal file
137
apps/app_chanisavail.c
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Check if Channel is Available
|
||||
*
|
||||
* Copyright (C) 2003, Digium
|
||||
*
|
||||
* Mark Spencer <markster@digium.com>
|
||||
* James Golovich <james@gnuinter.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/app.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
static char *tdesc = "Check if channel is available";
|
||||
|
||||
static char *app = "ChanIsAvail";
|
||||
|
||||
static char *synopsis = "Check if channel is available";
|
||||
|
||||
static char *descrip =
|
||||
" ChanIsAvail(Technology/resource[&Technology2/resource2...]): \n"
|
||||
"Checks is any of the requested channels are available. If none\n"
|
||||
"of the requested channels are available the new priority will be\n"
|
||||
"n+101 (unless such a priority does not exist or on error, in which\n"
|
||||
"case ChanIsAvail will return -1).\n"
|
||||
"If any of the requested channels are available, the next priority will be n+1,\n"
|
||||
"the channel variable ${AVAILCHAN} will be set to the name of the available channel\n"
|
||||
"and the ChanIsAvail app will return 0.\n"
|
||||
"${AVAILORIGCHAN} is the canonical channel name that was used to create the channel.\n"
|
||||
"${AVAILSTATUS} is the status code for the channel.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int chanavail_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=-1;
|
||||
struct localuser *u;
|
||||
char info[512], tmp[512], *peers, *tech, *number, *rest, *cur;
|
||||
struct ast_channel *tempchan;
|
||||
|
||||
if (!data) {
|
||||
ast_log(LOG_WARNING, "ChanIsAvail requires an argument (Zap/1&Zap/2)\n");
|
||||
return -1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
strncpy(info, (char *)data, sizeof(info)-1);
|
||||
peers = info;
|
||||
if (peers) {
|
||||
cur = peers;
|
||||
do {
|
||||
/* remember where to start next time */
|
||||
rest = strchr(cur, '&');
|
||||
if (rest) {
|
||||
*rest = 0;
|
||||
rest++;
|
||||
}
|
||||
tech = cur;
|
||||
number = strchr(tech, '/');
|
||||
if (!number) {
|
||||
ast_log(LOG_WARNING, "ChanIsAvail argument takes format ([technology]/[device])\n");
|
||||
return -1;
|
||||
}
|
||||
*number = '\0';
|
||||
number++;
|
||||
if ((tempchan = ast_request(tech, chan->nativeformats, number))) {
|
||||
pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name);
|
||||
/* Store the originally used channel too */
|
||||
snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
|
||||
pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", tmp);
|
||||
ast_hangup(tempchan);
|
||||
tempchan = NULL;
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
cur = rest;
|
||||
} while (cur);
|
||||
}
|
||||
|
||||
if (res < 1) {
|
||||
pbx_builtin_setvar_helper(chan, "AVAILCHAN", "");
|
||||
pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", "");
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority+=100;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, chanavail_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
138
apps/app_controlplayback.c
Normal file
138
apps/app_controlplayback.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Trivial application to control playback a sound file
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/app.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Control Playback Application";
|
||||
|
||||
static char *app = "ControlPlayback";
|
||||
|
||||
static char *synopsis = "Play a file with fast forward and rewind";
|
||||
|
||||
static char *descrip =
|
||||
"ControlPlayback(filename[|skipms[|ffchar[|rewchar[|stopchar[|pausechr]]]]]):\n"
|
||||
" Plays back a given filename (do not put extension). Options may also\n"
|
||||
" be included following a pipe symbol. You can use * and # to rewind and\n"
|
||||
" fast forward the playback specified. If 'stopchar' is added the file will\n"
|
||||
" terminate playback when 'stopchar' is pressed. Returns -1 if the channel\n"
|
||||
" was hung up, or if the file does not exist. Returns 0 otherwise.\n\n"
|
||||
" Example: exten => 1234,1,ControlPlayback(file|4000|*|#|1|0)\n\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int is_on_phonepad(char key)
|
||||
{
|
||||
return (key == 35 || key == 42 || (key >= 48 && key <= 57)) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int controlplayback_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
int skipms = 0;
|
||||
struct localuser *u;
|
||||
char tmp[256];
|
||||
char *skip = NULL, *fwd = NULL, *rev = NULL, *stop = NULL, *pause = NULL, *file = NULL;
|
||||
|
||||
if (!data || ast_strlen_zero((char *)data)) {
|
||||
ast_log(LOG_WARNING, "ControlPlayback requires an argument (filename)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(tmp, (char *)data, sizeof(tmp)-1);
|
||||
file = tmp;
|
||||
|
||||
if ((skip=strchr(tmp,'|'))) {
|
||||
*skip++ = '\0';
|
||||
fwd=strchr(skip,'|');
|
||||
if (fwd) {
|
||||
*fwd++ = '\0';
|
||||
rev = strchr(fwd,'|');
|
||||
if (rev) {
|
||||
*rev++ = '\0';
|
||||
stop = strchr(rev,'|');
|
||||
if (stop) {
|
||||
*stop++ = '\0';
|
||||
pause = strchr(stop,'|');
|
||||
if (pause) {
|
||||
*pause++ = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
skipms = skip ? atoi(skip) : 3000;
|
||||
if (!skipms)
|
||||
skipms = 3000;
|
||||
|
||||
if (!fwd || !is_on_phonepad(*fwd))
|
||||
fwd = "#";
|
||||
if (!rev || !is_on_phonepad(*rev))
|
||||
rev = "*";
|
||||
if (stop && !is_on_phonepad(*stop))
|
||||
stop = NULL;
|
||||
if (pause && !is_on_phonepad(*pause))
|
||||
pause = NULL;
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
res = ast_control_streamfile(chan, file, fwd, rev, stop, pause, skipms);
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
|
||||
/* If we stopped on one of our stop keys, return 0 */
|
||||
if(stop && strchr(stop, res))
|
||||
res = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, controlplayback_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
198
apps/app_cut.c
Normal file
198
apps/app_cut.c
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Cut application
|
||||
*
|
||||
* Copyright (c) 2003 Tilghman Lesher. All rights reserved.
|
||||
*
|
||||
* Tilghman Lesher <app_cut__v003@the-tilghman.com>
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* This code is released by the author with no restrictions on usage.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
|
||||
/* Maximum length of any variable */
|
||||
#define MAXRESULT 1024
|
||||
|
||||
static char *tdesc = "Cuts up variables";
|
||||
|
||||
static char *app_cut = "Cut";
|
||||
|
||||
static char *cut_synopsis = "Splits a variable's content using the specified delimiter";
|
||||
|
||||
static char *cut_descrip =
|
||||
"Usage: Cut(newvar=varname,delimiter,fieldspec)\n"
|
||||
" newvar - new variable created from result string\n"
|
||||
" varname - variable you want cut\n"
|
||||
" delimiter - defaults to '-'\n"
|
||||
" fieldspec - number of the field you want (1-based offset)\n"
|
||||
" may also be specified as a range (with -)\n"
|
||||
" or group of ranges and fields (with &)\n"
|
||||
" Returns 0 or -1 on hangup or error.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int cut_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
char *s, *newvar=NULL, *varname=NULL, *delimiter=NULL, *field=NULL;
|
||||
int args_okay = 0;
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
/* Check and parse arguments */
|
||||
if (data) {
|
||||
s = ast_strdupa((char *)data);
|
||||
if (s) {
|
||||
newvar = strsep(&s, "=");
|
||||
if (newvar && (newvar[0] != '\0')) {
|
||||
varname = strsep(&s, "|");
|
||||
if (varname && (varname[0] != '\0')) {
|
||||
delimiter = strsep(&s, "|");
|
||||
if (delimiter) {
|
||||
field = strsep(&s, "|");
|
||||
if (field) {
|
||||
args_okay = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_ERROR, "Out of memory\n");
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (args_okay) {
|
||||
char d, ds[2];
|
||||
char *tmp = alloca(strlen(varname) + 4);
|
||||
char varvalue[MAXRESULT], *tmp2=varvalue;
|
||||
char retstring[MAXRESULT];
|
||||
|
||||
memset(retstring, 0, MAXRESULT);
|
||||
|
||||
if (tmp) {
|
||||
snprintf(tmp, strlen(varname) + 4, "${%s}", varname);
|
||||
memset(varvalue, 0, sizeof(varvalue));
|
||||
} else {
|
||||
ast_log(LOG_ERROR, "Out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (delimiter[0])
|
||||
d = delimiter[0];
|
||||
else
|
||||
d = '-';
|
||||
|
||||
/* String form of the delimiter, for use with strsep(3) */
|
||||
snprintf(ds, sizeof(ds), "%c", d);
|
||||
|
||||
pbx_substitute_variables_helper(chan, tmp, tmp2, MAXRESULT - 1);
|
||||
|
||||
if (tmp2) {
|
||||
int curfieldnum = 1;
|
||||
while ((tmp2 != NULL) && (field != NULL)) {
|
||||
char *nextgroup = strsep(&field, "&");
|
||||
int num1 = 0, num2 = MAXRESULT;
|
||||
char trashchar;
|
||||
|
||||
if (sscanf(nextgroup, "%d-%d", &num1, &num2) == 2) {
|
||||
/* range with both start and end */
|
||||
} else if (sscanf(nextgroup, "-%d", &num2) == 1) {
|
||||
/* range with end */
|
||||
num1 = 0;
|
||||
} else if ((sscanf(nextgroup, "%d%c", &num1, &trashchar) == 2) && (trashchar == '-')) {
|
||||
/* range with start */
|
||||
num2 = MAXRESULT;
|
||||
} else if (sscanf(nextgroup, "%d", &num1) == 1) {
|
||||
/* single number */
|
||||
num2 = num1;
|
||||
} else {
|
||||
ast_log(LOG_ERROR, "Cut(): Illegal range '%s'\n", nextgroup);
|
||||
ast_log(LOG_ERROR, "Usage: %s\n", cut_synopsis);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get to start, if any */
|
||||
if (num1 > 0) {
|
||||
while ((tmp2 != (char *)NULL + 1) && (curfieldnum < num1)) {
|
||||
tmp2 = index(tmp2, d) + 1;
|
||||
curfieldnum++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Most frequent problem is the expectation of reordering fields */
|
||||
if ((num1 > 0) && (curfieldnum > num1)) {
|
||||
ast_log(LOG_WARNING, "Cut(): we're already past the field you wanted?\n");
|
||||
}
|
||||
|
||||
/* Re-null tmp2 if we added 1 to NULL */
|
||||
if (tmp2 == (char *)NULL + 1)
|
||||
tmp2 = NULL;
|
||||
|
||||
/* Output fields until we either run out of fields or num2 is reached */
|
||||
while ((tmp2 != NULL) && (curfieldnum <= num2)) {
|
||||
char *tmp3 = strsep(&tmp2, ds);
|
||||
int curlen = strlen(retstring);
|
||||
|
||||
if (strlen(retstring)) {
|
||||
snprintf(retstring + curlen, MAXRESULT - curlen, "%c%s", d, tmp3);
|
||||
} else {
|
||||
snprintf(retstring, MAXRESULT, "%s", tmp3);
|
||||
}
|
||||
|
||||
curfieldnum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pbx_builtin_setvar_helper(chan, newvar, retstring);
|
||||
}
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app_cut);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app_cut, cut_exec, cut_synopsis, cut_descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
81
apps/app_datetime.c
Normal file
81
apps/app_datetime.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Time of day - Report the time of day
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/say.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Date and Time";
|
||||
|
||||
static char *app = "DateTime";
|
||||
|
||||
static char *synopsis = "Say the date and time";
|
||||
|
||||
static char *descrip =
|
||||
" DateTime(): Says the current date and time. Returns -1 on hangup or 0\n"
|
||||
"otherwise.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int datetime_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
time_t t;
|
||||
struct localuser *u;
|
||||
LOCAL_USER_ADD(u);
|
||||
time(&t);
|
||||
if (chan->_state != AST_STATE_UP)
|
||||
res = ast_answer(chan);
|
||||
if (!res)
|
||||
res = ast_say_datetime(chan, t, "", chan->language);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, datetime_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
255
apps/app_db.c
Normal file
255
apps/app_db.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Database access functions
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
* Copyright (C) 2003, Jefferson Noxon
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
* Jefferson Noxon <jeff@debian.org>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/astdb.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Database access functions for Asterisk extension logic";
|
||||
|
||||
static char *g_descrip =
|
||||
" DBget(varname=family/key): Retrieves a value from the Asterisk\n"
|
||||
"database and stores it in the given variable. Always returns 0. If the\n"
|
||||
"requested key is not found, jumps to priority n+101 if available.\n";
|
||||
|
||||
static char *p_descrip =
|
||||
" DBput(family/key=value): Stores the given value in the Asterisk\n"
|
||||
"database. Always returns 0.\n";
|
||||
|
||||
static char *d_descrip =
|
||||
" DBdel(family/key): Deletes a key from the Asterisk database. Always\n"
|
||||
"returns 0.\n";
|
||||
|
||||
static char *dt_descrip =
|
||||
" DBdeltree(family[/keytree]): Deletes a family or keytree from the Asterisk\n"
|
||||
"database. Always returns 0.\n";
|
||||
|
||||
static char *g_app = "DBget";
|
||||
static char *p_app = "DBput";
|
||||
static char *d_app = "DBdel";
|
||||
static char *dt_app = "DBdeltree";
|
||||
|
||||
static char *g_synopsis = "Retrieve a value from the database";
|
||||
static char *p_synopsis = "Store a value in the database";
|
||||
static char *d_synopsis = "Delete a key from the database";
|
||||
static char *dt_synopsis = "Delete a family or keytree from the database";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int deltree_exec (struct ast_channel *chan, void *data)
|
||||
{
|
||||
int arglen;
|
||||
char *argv, *family, *keytree;
|
||||
|
||||
arglen = strlen (data);
|
||||
argv = alloca (arglen + 1);
|
||||
if (!argv) { /* Why would this fail? */
|
||||
ast_log (LOG_DEBUG, "Memory allocation failed\n");
|
||||
return 0;
|
||||
}
|
||||
memcpy (argv, data, arglen + 1);
|
||||
|
||||
if (strchr (argv, '/')) {
|
||||
family = strsep (&argv, "/");
|
||||
keytree = strsep (&argv, "\0");
|
||||
if (!family || !keytree) {
|
||||
ast_log (LOG_DEBUG, "Ignoring; Syntax error in argument\n");
|
||||
return 0;
|
||||
}
|
||||
if (!strlen (keytree))
|
||||
keytree = 0;
|
||||
} else {
|
||||
family = argv;
|
||||
keytree = 0;
|
||||
}
|
||||
|
||||
if (option_verbose > 2) {
|
||||
if (keytree)
|
||||
ast_verbose (VERBOSE_PREFIX_3 "DBdeltree: family=%s, keytree=%s\n", family, keytree);
|
||||
else
|
||||
ast_verbose (VERBOSE_PREFIX_3 "DBdeltree: family=%s\n", family);
|
||||
}
|
||||
|
||||
if (ast_db_deltree (family, keytree)) {
|
||||
if (option_verbose > 2)
|
||||
ast_verbose (VERBOSE_PREFIX_3 "DBdeltree: Error deleting key from database.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int del_exec (struct ast_channel *chan, void *data)
|
||||
{
|
||||
int arglen;
|
||||
char *argv, *family, *key;
|
||||
|
||||
arglen = strlen (data);
|
||||
argv = alloca (arglen + 1);
|
||||
if (!argv) { /* Why would this fail? */
|
||||
ast_log (LOG_DEBUG, "Memory allocation failed\n");
|
||||
return 0;
|
||||
}
|
||||
memcpy (argv, data, arglen + 1);
|
||||
|
||||
if (strchr (argv, '/')) {
|
||||
family = strsep (&argv, "/");
|
||||
key = strsep (&argv, "\0");
|
||||
if (!family || !key) {
|
||||
ast_log (LOG_DEBUG, "Ignoring; Syntax error in argument\n");
|
||||
return 0;
|
||||
}
|
||||
if (option_verbose > 2)
|
||||
ast_verbose (VERBOSE_PREFIX_3 "DBdel: family=%s, key=%s\n", family, key);
|
||||
if (ast_db_del (family, key)) {
|
||||
if (option_verbose > 2)
|
||||
ast_verbose (VERBOSE_PREFIX_3 "DBdel: Error deleting key from database.\n");
|
||||
}
|
||||
} else {
|
||||
ast_log (LOG_DEBUG, "Ignoring, no parameters\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int put_exec (struct ast_channel *chan, void *data)
|
||||
{
|
||||
int arglen;
|
||||
char *argv, *value, *family, *key;
|
||||
|
||||
arglen = strlen (data);
|
||||
argv = alloca (arglen + 1);
|
||||
if (!argv) { /* Why would this fail? */
|
||||
ast_log (LOG_DEBUG, "Memory allocation failed\n");
|
||||
return 0;
|
||||
}
|
||||
memcpy (argv, data, arglen + 1);
|
||||
|
||||
if (strchr (argv, '/') && strchr (argv, '=')) {
|
||||
family = strsep (&argv, "/");
|
||||
key = strsep (&argv, "=");
|
||||
value = strsep (&argv, "\0");
|
||||
if (!value || !family || !key) {
|
||||
ast_log (LOG_DEBUG, "Ignoring; Syntax error in argument\n");
|
||||
return 0;
|
||||
}
|
||||
if (option_verbose > 2)
|
||||
ast_verbose (VERBOSE_PREFIX_3 "DBput: family=%s, key=%s, value=%s\n", family, key, value);
|
||||
if (ast_db_put (family, key, value)) {
|
||||
if (option_verbose > 2)
|
||||
ast_verbose (VERBOSE_PREFIX_3 "DBput: Error writing value to database.\n");
|
||||
}
|
||||
|
||||
} else {
|
||||
ast_log (LOG_DEBUG, "Ignoring, no parameters\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_exec (struct ast_channel *chan, void *data)
|
||||
{
|
||||
int arglen;
|
||||
char *argv, *varname, *family, *key;
|
||||
char dbresult[256];
|
||||
|
||||
arglen = strlen (data);
|
||||
argv = alloca (arglen + 1);
|
||||
if (!argv) { /* Why would this fail? */
|
||||
ast_log (LOG_DEBUG, "Memory allocation failed\n");
|
||||
return 0;
|
||||
}
|
||||
memcpy (argv, data, arglen + 1);
|
||||
|
||||
if (strchr (argv, '=') && strchr (argv, '/')) {
|
||||
varname = strsep (&argv, "=");
|
||||
family = strsep (&argv, "/");
|
||||
key = strsep (&argv, "\0");
|
||||
if (!varname || !family || !key) {
|
||||
ast_log (LOG_DEBUG, "Ignoring; Syntax error in argument\n");
|
||||
return 0;
|
||||
}
|
||||
if (option_verbose > 2)
|
||||
ast_verbose (VERBOSE_PREFIX_3 "DBget: varname=%s, family=%s, key=%s\n", varname, family, key);
|
||||
if (!ast_db_get (family, key, dbresult, sizeof (dbresult) - 1)) {
|
||||
pbx_builtin_setvar_helper (chan, varname, dbresult);
|
||||
if (option_verbose > 2)
|
||||
ast_verbose (VERBOSE_PREFIX_3 "DBget: set variable %s to %s\n", varname, dbresult);
|
||||
} else {
|
||||
if (option_verbose > 2)
|
||||
ast_verbose (VERBOSE_PREFIX_3 "DBget: Value not found in database.\n");
|
||||
/* Send the call to n+101 priority, where n is the current priority */
|
||||
if (ast_exists_extension (chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority += 100;
|
||||
}
|
||||
|
||||
} else {
|
||||
ast_log (LOG_DEBUG, "Ignoring, no parameters\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unload_module (void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
retval = ast_unregister_application (dt_app);
|
||||
retval |= ast_unregister_application (d_app);
|
||||
retval |= ast_unregister_application (p_app);
|
||||
retval |= ast_unregister_application (g_app);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int load_module (void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = ast_register_application (g_app, get_exec, g_synopsis, g_descrip);
|
||||
if (!retval)
|
||||
retval = ast_register_application (p_app, put_exec, p_synopsis, p_descrip);
|
||||
if (!retval)
|
||||
retval = ast_register_application (d_app, del_exec, d_synopsis, d_descrip);
|
||||
if (!retval)
|
||||
retval = ast_register_application (dt_app, deltree_exec, dt_synopsis, dt_descrip);
|
||||
return retval;
|
||||
}
|
||||
|
||||
char *description (void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount (void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT (res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key ()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
1362
apps/app_dial.c
Executable file → Normal file
1362
apps/app_dial.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
239
apps/app_directory.c
Executable file → Normal file
239
apps/app_directory.c
Executable file → Normal file
@@ -11,6 +11,7 @@
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
@@ -18,16 +19,29 @@
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/say.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include "../asterisk.h"
|
||||
#include "../astconf.h"
|
||||
|
||||
static char *tdesc = "Extension Directory";
|
||||
static char *app = "Directory";
|
||||
|
||||
static char *synopsis = "Provide directory of voicemail extensions";
|
||||
static char *descrip =
|
||||
" Directory(vm-context[|dial-context[|options]]): Presents the user with a directory\n"
|
||||
"of extensions from which they may select by name. The list of names \n"
|
||||
"and extensions is discovered from voicemail.conf. The vm-context argument\n"
|
||||
"is required, and specifies the context of voicemail.conf to use. The\n"
|
||||
"dial-context is the context to use for dialing the users, and defaults to\n"
|
||||
"the vm-context if unspecified. The 'f' option causes the directory to match\n"
|
||||
"based on the first name in voicemail.conf instead of the last name.\n"
|
||||
"Returns 0 unless the user hangs up. It also sets up the channel on exit\n"
|
||||
"to enter the extension the user selected.\n";
|
||||
|
||||
/* For simplicity, I'm keeping the format compatible with the voicemail config,
|
||||
but i'm open to suggestions for isolating it */
|
||||
|
||||
@@ -101,7 +115,6 @@ static char *convert(char *lastname)
|
||||
case 'Z':
|
||||
tmp[lcount++] = '9';
|
||||
break;
|
||||
default:
|
||||
}
|
||||
lastname++;
|
||||
}
|
||||
@@ -110,18 +123,114 @@ static char *convert(char *lastname)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static int do_directory(struct ast_channel *chan, struct ast_config *cfg, char *context, char digit)
|
||||
/* play name of mailbox owner.
|
||||
* returns: -1 for bad or missing extension
|
||||
* '1' for selected entry from directory
|
||||
* '*' for skipped entry from directory
|
||||
*/
|
||||
static int play_mailbox_owner(struct ast_channel *chan, char *context, char *dialcontext, char *ext, char *name) {
|
||||
int res = 0;
|
||||
int loop = 3;
|
||||
char fn[256];
|
||||
char fn2[256];
|
||||
|
||||
/* Check for the VoiceMail2 greeting first */
|
||||
snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/greet",
|
||||
(char *)ast_config_AST_SPOOL_DIR, context, ext);
|
||||
|
||||
/* Otherwise, check for an old-style Voicemail greeting */
|
||||
snprintf(fn2, sizeof(fn2), "%s/vm/%s/greet",
|
||||
(char *)ast_config_AST_SPOOL_DIR, ext);
|
||||
|
||||
if (ast_fileexists(fn, NULL, chan->language) > 0) {
|
||||
res = ast_streamfile(chan, fn, chan->language);
|
||||
if (!res) {
|
||||
res = ast_waitstream(chan, AST_DIGIT_ANY);
|
||||
}
|
||||
ast_stopstream(chan);
|
||||
} else if (ast_fileexists(fn2, NULL, chan->language) > 0) {
|
||||
res = ast_streamfile(chan, fn2, chan->language);
|
||||
if (!res) {
|
||||
res = ast_waitstream(chan, AST_DIGIT_ANY);
|
||||
}
|
||||
ast_stopstream(chan);
|
||||
} else {
|
||||
res = ast_say_character_str(chan, !ast_strlen_zero(name) ? name : ext,
|
||||
AST_DIGIT_ANY, chan->language);
|
||||
}
|
||||
|
||||
while (loop) {
|
||||
if (!res) {
|
||||
res = ast_streamfile(chan, "dir-instr", chan->language);
|
||||
}
|
||||
if (!res) {
|
||||
res = ast_waitstream(chan, AST_DIGIT_ANY);
|
||||
}
|
||||
if (!res) {
|
||||
res = ast_waitfordigit(chan, 3000);
|
||||
}
|
||||
ast_stopstream(chan);
|
||||
|
||||
if (res > -1) {
|
||||
switch (res) {
|
||||
case '1':
|
||||
/* Name selected */
|
||||
loop = 0;
|
||||
if (ast_exists_extension(chan,dialcontext,ext,1,chan->callerid)) {
|
||||
strncpy(chan->exten, ext, sizeof(chan->exten)-1);
|
||||
chan->priority = 0;
|
||||
strncpy(chan->context, dialcontext, sizeof(chan->context)-1);
|
||||
} else {
|
||||
ast_log(LOG_WARNING,
|
||||
"Can't find extension '%s' in context '%s'. "
|
||||
"Did you pass the wrong context to Directory?\n",
|
||||
ext, dialcontext);
|
||||
res = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case '*':
|
||||
/* Skip to next match in list */
|
||||
loop = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Not '1', or '*', so decrement number of tries */
|
||||
res = 0;
|
||||
loop--;
|
||||
break;
|
||||
} /* end switch */
|
||||
} /* end if */
|
||||
else {
|
||||
/* User hungup, so jump out now */
|
||||
loop = 0;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
static int do_directory(struct ast_channel *chan, struct ast_config *cfg, char *context, char *dialcontext, char digit, int last)
|
||||
{
|
||||
/* Read in the first three digits.. "digit" is the first digit, already read */
|
||||
char ext[NUMDIGITS + 1];
|
||||
char name[80] = "";
|
||||
struct ast_variable *v;
|
||||
int res;
|
||||
int found=0;
|
||||
char *start, *pos, *conv;
|
||||
char fn[256];
|
||||
int lastuserchoice = 0;
|
||||
char *start, *pos, *conv,*stringp=NULL;
|
||||
|
||||
if (!context || ast_strlen_zero(context)) {
|
||||
ast_log(LOG_WARNING,
|
||||
"Directory must be called with an argument "
|
||||
"(context in which to interpret extensions)\n");
|
||||
return -1;
|
||||
}
|
||||
memset(ext, 0, sizeof(ext));
|
||||
ext[0] = digit;
|
||||
res = ast_readstring(chan, ext + 1, NUMDIGITS, 3000, 3000, "#");
|
||||
res = 0;
|
||||
if (ast_readstring(chan, ext + 1, NUMDIGITS - 1, 3000, 3000, "#") < 0) res = -1;
|
||||
if (!res) {
|
||||
/* Search for all names which start with those digits */
|
||||
v = ast_variable_browse(cfg, context);
|
||||
@@ -131,11 +240,13 @@ static int do_directory(struct ast_channel *chan, struct ast_config *cfg, char *
|
||||
/* Find a candidate extension */
|
||||
start = strdup(v->value);
|
||||
if (start) {
|
||||
strtok(start, ",");
|
||||
pos = strtok(NULL, ",");
|
||||
stringp=start;
|
||||
strsep(&stringp, ",");
|
||||
pos = strsep(&stringp, ",");
|
||||
if (pos) {
|
||||
strncpy(name, pos, sizeof(name) - 1);
|
||||
/* Grab the last name */
|
||||
if (strrchr(pos, ' '))
|
||||
if (last && strrchr(pos,' '))
|
||||
pos = strrchr(pos, ' ') + 1;
|
||||
conv = convert(pos);
|
||||
if (conv) {
|
||||
@@ -153,51 +264,46 @@ static int do_directory(struct ast_channel *chan, struct ast_config *cfg, char *
|
||||
}
|
||||
v = v->next;
|
||||
}
|
||||
|
||||
if (v) {
|
||||
/* We have a match -- play a greeting if they have it */
|
||||
snprintf(fn, sizeof(fn), "%s/vm/%s/greet", AST_SPOOL_DIR, v->name);
|
||||
if (ast_fileexists(fn, NULL, chan->language)) {
|
||||
res = ast_streamfile(chan, fn, chan->language);
|
||||
if (!res)
|
||||
res = ast_waitstream(chan, AST_DIGIT_ANY);
|
||||
ast_stopstream(chan);
|
||||
} else {
|
||||
res = ast_say_digit_str(chan, v->name, chan->language);
|
||||
}
|
||||
ahem:
|
||||
if (!res)
|
||||
res = ast_streamfile(chan, "dir-instr", chan->language);
|
||||
if (!res)
|
||||
res = ast_waitstream(chan, AST_DIGIT_ANY);
|
||||
if (!res)
|
||||
res = ast_waitfordigit(chan, 3000);
|
||||
ast_stopstream(chan);
|
||||
if (res > -1) {
|
||||
if (res == '1') {
|
||||
strncpy(chan->exten, v->name, sizeof(chan->exten));
|
||||
res = play_mailbox_owner(chan, context, dialcontext, v->name, name);
|
||||
switch (res) {
|
||||
case -1:
|
||||
/* user pressed '1' but extension does not exist, or
|
||||
* user hungup
|
||||
*/
|
||||
lastuserchoice = 0;
|
||||
break;
|
||||
case '1':
|
||||
/* user pressed '1' and extensions exists */
|
||||
lastuserchoice = res;
|
||||
strncpy(chan->context, dialcontext, sizeof(chan->context) - 1);
|
||||
strncpy(chan->exten, v->name, sizeof(chan->exten) - 1);
|
||||
chan->priority = 0;
|
||||
strncpy(chan->context, context, sizeof(chan->context));
|
||||
break;
|
||||
case '*':
|
||||
/* user pressed '*' to skip something found */
|
||||
lastuserchoice = res;
|
||||
res = 0;
|
||||
break;
|
||||
} else if (res == '*') {
|
||||
res = 0;
|
||||
v = v->next;
|
||||
} else {
|
||||
res = 0;
|
||||
goto ahem;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (found)
|
||||
res = ast_streamfile(chan, "dir-nomore", chan->language);
|
||||
else
|
||||
res = ast_streamfile(chan, "dir-nomatch", chan->language);
|
||||
if (!res)
|
||||
res = 1;
|
||||
return res;
|
||||
v = v->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (lastuserchoice != '1') {
|
||||
if (found)
|
||||
res = ast_streamfile(chan, "dir-nomore", chan->language);
|
||||
else
|
||||
res = ast_streamfile(chan, "dir-nomatch", chan->language);
|
||||
if (!res)
|
||||
res = 1;
|
||||
return res;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -207,8 +313,11 @@ static int directory_exec(struct ast_channel *chan, void *data)
|
||||
int res = 0;
|
||||
struct localuser *u;
|
||||
struct ast_config *cfg;
|
||||
int last = 1;
|
||||
char *context, *dialcontext, *dirintro, *options;
|
||||
|
||||
if (!data) {
|
||||
ast_log(LOG_WARNING, "directory requires an argument (context)\n");
|
||||
ast_log(LOG_WARNING, "directory requires an argument (context[,dialcontext])\n");
|
||||
return -1;
|
||||
}
|
||||
cfg = ast_load(DIRECTORY_CONFIG);
|
||||
@@ -218,15 +327,40 @@ static int directory_exec(struct ast_channel *chan, void *data)
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
top:
|
||||
context = ast_strdupa(data);
|
||||
dialcontext = strchr(context, '|');
|
||||
if (dialcontext) {
|
||||
*dialcontext = '\0';
|
||||
dialcontext++;
|
||||
options = strchr(dialcontext, '|');
|
||||
if (options) {
|
||||
*options = '\0';
|
||||
options++;
|
||||
if (strchr(options, 'f'))
|
||||
last = 0;
|
||||
}
|
||||
} else
|
||||
dialcontext = context;
|
||||
dirintro = ast_variable_retrieve(cfg, context, "directoryintro");
|
||||
if (!dirintro || ast_strlen_zero(dirintro))
|
||||
dirintro = ast_variable_retrieve(cfg, "general", "directoryintro");
|
||||
if (!dirintro || ast_strlen_zero(dirintro)) {
|
||||
if (last)
|
||||
dirintro = "dir-intro";
|
||||
else
|
||||
dirintro = "dir-intro-fn";
|
||||
}
|
||||
if (chan->_state != AST_STATE_UP)
|
||||
res = ast_answer(chan);
|
||||
if (!res)
|
||||
res = ast_streamfile(chan, "dir-intro", chan->language);
|
||||
res = ast_streamfile(chan, dirintro, chan->language);
|
||||
if (!res)
|
||||
res = ast_waitstream(chan, AST_DIGIT_ANY);
|
||||
ast_stopstream(chan);
|
||||
if (!res)
|
||||
res = ast_waitfordigit(chan, 5000);
|
||||
if (res > 0) {
|
||||
res = do_directory(chan, cfg, (char *)data, res);
|
||||
res = do_directory(chan, cfg, context, dialcontext, res, last);
|
||||
if (res > 0) {
|
||||
res = ast_waitstream(chan, AST_DIGIT_ANY);
|
||||
ast_stopstream(chan);
|
||||
@@ -248,7 +382,7 @@ int unload_module(void)
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, directory_exec);
|
||||
return ast_register_application(app, directory_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
@@ -262,3 +396,8 @@ int usecount(void)
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
|
||||
369
apps/app_disa.c
Normal file
369
apps/app_disa.c
Normal file
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* DISA -- Direct Inward System Access Application 6/20/2001
|
||||
*
|
||||
* Copyright (C) 2001, Linux Support Services, Inc.
|
||||
*
|
||||
* Jim Dixon <jim@lambdatel.com>
|
||||
*
|
||||
* Made only slightly more sane by Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/indications.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/ulaw.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
static char *tdesc = "DISA (Direct Inward System Access) Application";
|
||||
|
||||
static char *app = "DISA";
|
||||
|
||||
static char *synopsis = "DISA (Direct Inward System Access)";
|
||||
|
||||
static char *descrip =
|
||||
"DISA (Direct Inward System Access) -- Allows someone from outside\n"
|
||||
"the telephone switch (PBX) to obtain an \"internal\" system dialtone\n"
|
||||
"and to place calls from it as if they were placing a call from within\n"
|
||||
"the switch. A user calls a number that connects to the DISA application\n"
|
||||
"and is given dialtone. The user enters their passcode, followed by the\n"
|
||||
"pound sign (#). If the passcode is correct, the user is then given\n"
|
||||
"system dialtone on which a call may be placed. Obviously, this type\n"
|
||||
"of access has SERIOUS security implications, and GREAT care must be\n"
|
||||
"taken NOT to compromise your security.\n\n"
|
||||
"There is a possibility of accessing DISA without password. Simply\n"
|
||||
"exchange your password with no-password.\n\n"
|
||||
" Example: exten => s,1,DISA,no-password|local\n\n"
|
||||
"but be aware of using this for your security compromising.\n\n"
|
||||
"The arguments to this application (in extensions.conf) allow either\n"
|
||||
"specification of a single global password (that everyone uses), or\n"
|
||||
"individual passwords contained in a file. It also allow specification\n"
|
||||
"of the context on which the user will be dialing. If no context is\n"
|
||||
"specified, the DISA application defaults the context to \"disa\"\n"
|
||||
"presumably that a normal system will have a special context set up\n"
|
||||
"for DISA use with some or a lot of restrictions. The arguments are\n"
|
||||
"one of the following:\n\n"
|
||||
" numeric-passcode\n"
|
||||
" numeric-passcode|context\n"
|
||||
" full-pathname-of-file-that-contains-passcodes\n\n"
|
||||
"The file that contains the passcodes (if used) allows specification\n"
|
||||
"of either just a passcode (defaulting to the \"disa\" context, or\n"
|
||||
"passcode|context on each line of the file. The file may contain blank\n"
|
||||
"lines, or comments starting with \"#\" or \";\". In addition, the\n"
|
||||
"above arguments may have |new-callerid-string appended to them, to\n"
|
||||
"specify a new (different) callerid to be used for this call, for\n"
|
||||
"example: numeric-passcode|context|\"My Phone\" <(234) 123-4567> or \n"
|
||||
"full-pathname-of-passcode-file|\"My Phone\" <(234) 123-4567>. Note that\n"
|
||||
"in the case of specifying the numeric-passcode, the context must be\n"
|
||||
"specified if the callerid is specified also.\n\n"
|
||||
"If login is successful, the application parses the dialed number in\n"
|
||||
"the specified (or default) context, and returns 0 with the new extension\n"
|
||||
"context filled-in and the priority set to 1, so that the PBX may\n"
|
||||
"re-apply the routing tables to it and complete the call normally.";
|
||||
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int firstdigittimeout = 20000; /* 20 seconds first digit timeout */
|
||||
static int digittimeout = 10000; /* 10 seconds subsequent digit timeout */
|
||||
|
||||
static int ms_diff(struct timeval *tv1, struct timeval *tv2)
|
||||
{
|
||||
int ms;
|
||||
|
||||
ms = (tv1->tv_sec - tv2->tv_sec) * 1000;
|
||||
ms += (tv1->tv_usec - tv2->tv_usec) / 1000;
|
||||
return(ms);
|
||||
}
|
||||
|
||||
static void play_dialtone(struct ast_channel *chan)
|
||||
{
|
||||
const struct tone_zone_sound *ts = NULL;
|
||||
ts = ast_get_indication_tone(chan->zone, "dial");
|
||||
if (ts)
|
||||
ast_playtones_start(chan, 0, ts->data, 0);
|
||||
else
|
||||
ast_tonepair_start(chan, 350, 440, 0, 0);
|
||||
}
|
||||
|
||||
static int disa_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int i,j,k,x,did_ignore;
|
||||
struct localuser *u;
|
||||
char tmp[256],arg2[256]="",exten[AST_MAX_EXTENSION],acctcode[20]="";
|
||||
char *ourcontext,*ourcallerid;
|
||||
struct ast_frame *f;
|
||||
struct timeval lastout, now, lastdigittime;
|
||||
int res;
|
||||
time_t rstart;
|
||||
FILE *fp;
|
||||
char *stringp=NULL;
|
||||
|
||||
if (ast_set_write_format(chan,AST_FORMAT_ULAW))
|
||||
{
|
||||
ast_log(LOG_WARNING, "Unable to set write format to Mu-law on %s\n",chan->name);
|
||||
return -1;
|
||||
}
|
||||
if (ast_set_read_format(chan,AST_FORMAT_ULAW))
|
||||
{
|
||||
ast_log(LOG_WARNING, "Unable to set read format to Mu-law on %s\n",chan->name);
|
||||
return -1;
|
||||
}
|
||||
lastout.tv_sec = lastout.tv_usec = 0;
|
||||
if (!data || !strlen((char *)data)) {
|
||||
ast_log(LOG_WARNING, "disa requires an argument (passcode/passcode file)\n");
|
||||
return -1;
|
||||
}
|
||||
strncpy(tmp, (char *)data, sizeof(tmp)-1);
|
||||
stringp=tmp;
|
||||
strsep(&stringp, "|");
|
||||
ourcontext = strsep(&stringp, "|");
|
||||
/* if context specified, save 2nd arg and parse third */
|
||||
if (ourcontext) {
|
||||
strncpy(arg2,ourcontext, sizeof(arg2) - 1);
|
||||
ourcallerid = strsep(&stringp,"|");
|
||||
}
|
||||
/* if context not specified, use "disa" */
|
||||
else {
|
||||
arg2[0] = 0;
|
||||
ourcallerid = NULL;
|
||||
ourcontext = "disa";
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
if (chan->_state != AST_STATE_UP)
|
||||
{
|
||||
/* answer */
|
||||
ast_answer(chan);
|
||||
}
|
||||
i = k = x = 0; /* k is 0 for pswd entry, 1 for ext entry */
|
||||
did_ignore = 0;
|
||||
exten[0] = 0;
|
||||
acctcode[0] = 0;
|
||||
/* can we access DISA without password? */
|
||||
|
||||
ast_log(LOG_DEBUG, "Context: %s\n",ourcontext);
|
||||
|
||||
if (!strcasecmp(tmp, "no-password"))
|
||||
{;
|
||||
k |= 1; /* We have the password */
|
||||
ast_log(LOG_DEBUG, "DISA no-password login success\n");
|
||||
}
|
||||
gettimeofday(&lastdigittime,NULL);
|
||||
|
||||
play_dialtone(chan);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
gettimeofday(&now,NULL);
|
||||
/* if outa time, give em reorder */
|
||||
if (ms_diff(&now,&lastdigittime) >
|
||||
((k&2) ? digittimeout : firstdigittimeout))
|
||||
{
|
||||
ast_log(LOG_DEBUG,"DISA %s entry timeout on chan %s\n",
|
||||
((k&1) ? "extension" : "password"),chan->name);
|
||||
break;
|
||||
}
|
||||
if ((res = ast_waitfor(chan, -1) < 0)) {
|
||||
ast_log(LOG_DEBUG, "Waitfor returned %d\n", res);
|
||||
continue;
|
||||
}
|
||||
|
||||
f = ast_read(chan);
|
||||
if (f == NULL)
|
||||
{
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return -1;
|
||||
}
|
||||
if ((f->frametype == AST_FRAME_CONTROL) &&
|
||||
(f->subclass == AST_CONTROL_HANGUP))
|
||||
{
|
||||
ast_frfree(f);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return -1;
|
||||
}
|
||||
if (f->frametype == AST_FRAME_VOICE) {
|
||||
ast_frfree(f);
|
||||
continue;
|
||||
}
|
||||
/* if not DTMF, just do it again */
|
||||
if (f->frametype != AST_FRAME_DTMF)
|
||||
{
|
||||
ast_frfree(f);
|
||||
continue;
|
||||
}
|
||||
|
||||
j = f->subclass; /* save digit */
|
||||
ast_frfree(f);
|
||||
if (i == 0)
|
||||
{
|
||||
k|=2; /* We have the first digit */
|
||||
ast_playtones_stop(chan);
|
||||
}
|
||||
gettimeofday(&lastdigittime,NULL);
|
||||
/* got a DTMF tone */
|
||||
if (i < AST_MAX_EXTENSION) /* if still valid number of digits */
|
||||
{
|
||||
if (!(k&1)) /* if in password state */
|
||||
{
|
||||
if (j == '#') /* end of password */
|
||||
{
|
||||
/* see if this is an integer */
|
||||
if (sscanf(tmp,"%d",&j) < 1)
|
||||
{ /* nope, it must be a filename */
|
||||
fp = fopen(tmp,"r");
|
||||
if (!fp)
|
||||
{
|
||||
ast_log(LOG_WARNING,"DISA password file %s not found on chan %s\n",tmp,chan->name);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return -1;
|
||||
}
|
||||
tmp[0] = 0;
|
||||
while(fgets(tmp,sizeof(tmp) - 1,fp))
|
||||
{
|
||||
char *stringp=NULL,*stringp2;
|
||||
if (!tmp[0]) continue;
|
||||
if (tmp[strlen(tmp) - 1] == '\n')
|
||||
tmp[strlen(tmp) - 1] = 0;
|
||||
if (!tmp[0]) continue;
|
||||
/* skip comments */
|
||||
if (tmp[0] == '#') continue;
|
||||
if (tmp[0] == ';') continue;
|
||||
stringp=tmp;
|
||||
strsep(&stringp, "|");
|
||||
stringp2=strsep(&stringp, "|");
|
||||
if (stringp2) {
|
||||
ourcontext=stringp2;
|
||||
stringp2=strsep(&stringp, "|");
|
||||
if (stringp2) ourcallerid=stringp2;
|
||||
}
|
||||
/* password must be in valid format (numeric) */
|
||||
if (sscanf(tmp,"%d",&j) < 1) continue;
|
||||
/* if we got it */
|
||||
if (!strcmp(exten,tmp)) break;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
/* compare the two */
|
||||
if (strcmp(exten,tmp))
|
||||
{
|
||||
ast_log(LOG_WARNING,"DISA on chan %s got bad password %s\n",chan->name,exten);
|
||||
goto reorder;
|
||||
|
||||
}
|
||||
/* password good, set to dial state */
|
||||
ast_log(LOG_DEBUG,"DISA on chan %s password is good\n",chan->name);
|
||||
play_dialtone(chan);
|
||||
|
||||
k|=1; /* In number mode */
|
||||
i = 0; /* re-set buffer pointer */
|
||||
exten[sizeof(acctcode)] = 0;
|
||||
strncpy(acctcode,exten, sizeof(acctcode) - 1);
|
||||
exten[0] = 0;
|
||||
ast_log(LOG_DEBUG,"Successful DISA log-in on chan %s\n",chan->name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
exten[i++] = j; /* save digit */
|
||||
exten[i] = 0;
|
||||
if (!(k&1)) continue; /* if getting password, continue doing it */
|
||||
/* if this exists */
|
||||
|
||||
if (ast_ignore_pattern(ourcontext, exten)) {
|
||||
play_dialtone(chan);
|
||||
did_ignore = 1;
|
||||
} else
|
||||
if (did_ignore) {
|
||||
ast_playtones_stop(chan);
|
||||
did_ignore = 0;
|
||||
}
|
||||
|
||||
/* if can do some more, do it */
|
||||
if (!ast_matchmore_extension(chan,ourcontext,exten,1, chan->callerid)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((k==3) && (ast_exists_extension(chan,ourcontext,exten,1, chan->callerid)))
|
||||
{
|
||||
ast_playtones_stop(chan);
|
||||
/* We're authenticated and have a valid extension */
|
||||
if (ourcallerid && *ourcallerid)
|
||||
{
|
||||
if (chan->callerid) free(chan->callerid);
|
||||
chan->callerid = strdup(ourcallerid);
|
||||
}
|
||||
strncpy(chan->exten, exten, sizeof(chan->exten) - 1);
|
||||
strncpy(chan->context, ourcontext, sizeof(chan->context) - 1);
|
||||
if (!ast_strlen_zero(acctcode))
|
||||
strncpy(chan->accountcode, acctcode, sizeof(chan->accountcode) - 1);
|
||||
chan->priority = 0;
|
||||
ast_cdr_init(chan->cdr,chan);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return 0;
|
||||
}
|
||||
|
||||
reorder:
|
||||
|
||||
ast_indicate(chan,AST_CONTROL_CONGESTION);
|
||||
/* something is invalid, give em reorder for several seconds */
|
||||
time(&rstart);
|
||||
while(time(NULL) < rstart + 10)
|
||||
{
|
||||
if (ast_waitfor(chan, -1) < 0)
|
||||
break;
|
||||
f = ast_read(chan);
|
||||
if (!f)
|
||||
break;
|
||||
ast_frfree(f);
|
||||
}
|
||||
ast_playtones_stop(chan);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, disa_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key(void)
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
32
apps/app_echo.c
Executable file → Normal file
32
apps/app_echo.c
Executable file → Normal file
@@ -11,6 +11,7 @@
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
@@ -21,28 +22,41 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
static char *tdesc = "Simple Echo Application";
|
||||
|
||||
static char *app = "Echo";
|
||||
|
||||
static char *synopsis = "Echo audio read back to the user";
|
||||
|
||||
static char *descrip =
|
||||
" Echo(): Echo audio read from channel back to the channel. Returns 0\n"
|
||||
"if the user exits with the '#' key, or -1 if the user hangs up.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int skel_exec(struct ast_channel *chan, void *data)
|
||||
static int echo_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=-1;
|
||||
struct localuser *u;
|
||||
struct ast_frame *f;
|
||||
LOCAL_USER_ADD(u);
|
||||
ast_set_write_format(chan, ast_best_codec(chan->nativeformats));
|
||||
ast_set_read_format(chan, ast_best_codec(chan->nativeformats));
|
||||
/* Do our thing here */
|
||||
while((f = ast_read(chan))) {
|
||||
while(ast_waitfor(chan, -1) > -1) {
|
||||
f = ast_read(chan);
|
||||
if (!f)
|
||||
break;
|
||||
f->delivery.tv_sec = 0;
|
||||
f->delivery.tv_usec = 0;
|
||||
if (f->frametype == AST_FRAME_VOICE) {
|
||||
if (ast_write(chan, f))
|
||||
break;
|
||||
} else if (f->frametype == AST_FRAME_VIDEO) {
|
||||
if (ast_write(chan, f))
|
||||
break;
|
||||
} else if (f->frametype == AST_FRAME_DTMF) {
|
||||
if (f->subclass == '#') {
|
||||
res = 0;
|
||||
@@ -51,6 +65,7 @@ static int skel_exec(struct ast_channel *chan, void *data)
|
||||
if (ast_write(chan, f))
|
||||
break;
|
||||
}
|
||||
ast_frfree(f);
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
@@ -64,7 +79,7 @@ int unload_module(void)
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, skel_exec);
|
||||
return ast_register_application(app, echo_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
@@ -78,3 +93,8 @@ int usecount(void)
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
|
||||
203
apps/app_enumlookup.c
Normal file
203
apps/app_enumlookup.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Time of day - Report the time of day
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/enum.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static char *tdesc = "ENUM Lookup";
|
||||
|
||||
static char *app = "EnumLookup";
|
||||
|
||||
static char *synopsis = "Lookup number in ENUM";
|
||||
|
||||
static char *descrip =
|
||||
" EnumLookup(exten): Looks up an extension via ENUM and sets\n"
|
||||
"the variable 'ENUM'. For VoIP URIs this variable will \n"
|
||||
"look like 'TECHNOLOGY/URI' with the appropriate technology.\n"
|
||||
"Returns -1 on hangup, or 0 on completion regardless of whether the \n"
|
||||
"lookup was successful. \n"
|
||||
"Currently, the enumservices SIP, H323, IAX, IAX2 and TEL are recognized. \n"
|
||||
"A good SIP, H323, IAX or IAX2 entry will result in normal priority handling, \n"
|
||||
"whereas a good TEL entry will increase the priority by 51 (if existing).\n"
|
||||
"If the lookup was *not* successful and there exists a priority n + 101,\n"
|
||||
"then that priority will be taken next.\n" ;
|
||||
|
||||
#define ENUM_CONFIG "enum.conf"
|
||||
|
||||
static char h323driver[80] = "";
|
||||
#define H323DRIVERDEFAULT "H323"
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int enumlookup_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
char tech[80];
|
||||
char dest[80];
|
||||
char tmp[256];
|
||||
char *c,*t;
|
||||
struct localuser *u;
|
||||
if (!data || ast_strlen_zero(data)) {
|
||||
ast_log(LOG_WARNING, "EnumLookup requires an argument (extension)\n");
|
||||
res = 1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
if (!res) {
|
||||
res = ast_get_enum(chan, data, dest, sizeof(dest), tech, sizeof(tech));
|
||||
printf("ENUM got '%d'\n", res);
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
/* Parse it out */
|
||||
if (res > 0) {
|
||||
if (!strcasecmp(tech, "SIP")) {
|
||||
c = dest;
|
||||
if (!strncmp(c, "sip:", 4))
|
||||
c += 4;
|
||||
snprintf(tmp, sizeof(tmp), "SIP/%s", c);
|
||||
pbx_builtin_setvar_helper(chan, "ENUM", tmp);
|
||||
} else if (!strcasecmp(tech, "h323")) {
|
||||
c = dest;
|
||||
if (!strncmp(c, "h323:", 5))
|
||||
c += 5;
|
||||
snprintf(tmp, sizeof(tmp), "%s/%s", h323driver, c);
|
||||
/* do a s!;.*!! on the H323 URI */
|
||||
t = strchr(c,';');
|
||||
if (t)
|
||||
*t = 0;
|
||||
pbx_builtin_setvar_helper(chan, "ENUM", tmp);
|
||||
} else if (!strcasecmp(tech, "iax")) {
|
||||
c = dest;
|
||||
if (!strncmp(c, "iax:", 4))
|
||||
c += 4;
|
||||
snprintf(tmp, sizeof(tmp), "IAX/%s", c);
|
||||
pbx_builtin_setvar_helper(chan, "ENUM", tmp);
|
||||
} else if (!strcasecmp(tech, "iax2")) {
|
||||
c = dest;
|
||||
if (!strncmp(c, "iax2:", 5))
|
||||
c += 5;
|
||||
snprintf(tmp, sizeof(tmp), "IAX2/%s", c);
|
||||
pbx_builtin_setvar_helper(chan, "ENUM", tmp);
|
||||
} else if (!strcasecmp(tech, "tel")) {
|
||||
c = dest;
|
||||
if (!strncmp(c, "tel:", 4))
|
||||
c += 4;
|
||||
|
||||
if (c[0] != '+') {
|
||||
ast_log(LOG_NOTICE, "tel: uri must start with a \"+\" (got '%s')\n", c);
|
||||
res = 0;
|
||||
} else {
|
||||
/* now copy over the number, skipping all non-digits and stop at ; or NULL */
|
||||
t = tmp;
|
||||
while( *c && (*c != ';') && (t - tmp < (sizeof(tmp) - 1))) {
|
||||
if (isdigit(*c))
|
||||
*t++ = *c;
|
||||
c++;
|
||||
}
|
||||
*t = 0;
|
||||
pbx_builtin_setvar_helper(chan, "ENUM", tmp);
|
||||
ast_log(LOG_NOTICE, "tel: ENUM set to \"%s\"\n", tmp);
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 51, chan->callerid))
|
||||
chan->priority += 50;
|
||||
else
|
||||
res = 0;
|
||||
}
|
||||
} else if (!ast_strlen_zero(tech)) {
|
||||
ast_log(LOG_NOTICE, "Don't know how to handle technology '%s'\n", tech);
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
if (!res) {
|
||||
/* Look for a "busy" place */
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority += 100;
|
||||
} else if (res > 0)
|
||||
res = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
static int load_config(void)
|
||||
{
|
||||
struct ast_config *cfg;
|
||||
char *s;
|
||||
|
||||
cfg = ast_load(ENUM_CONFIG);
|
||||
if (cfg) {
|
||||
if (!(s=ast_variable_retrieve(cfg, "general", "h323driver"))) {
|
||||
strncpy(h323driver, H323DRIVERDEFAULT, sizeof(h323driver) - 1);
|
||||
} else {
|
||||
strncpy(h323driver, s, sizeof(h323driver) - 1);
|
||||
}
|
||||
ast_destroy(cfg);
|
||||
return 0;
|
||||
}
|
||||
ast_log(LOG_NOTICE, "No ENUM Config file, using defaults\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
int res;
|
||||
res = ast_register_application(app, enumlookup_exec, synopsis, descrip);
|
||||
if (res)
|
||||
return(res);
|
||||
if ((res=load_config())) {
|
||||
return(res);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int reload(void)
|
||||
{
|
||||
return(load_config());
|
||||
}
|
||||
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
|
||||
101
apps/app_eval.c
Normal file
101
apps/app_eval.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Eval application
|
||||
*
|
||||
* Copyright (c) 2004 Tilghman Lesher. All rights reserved.
|
||||
*
|
||||
* Tilghman Lesher <app_eval__v001@the-tilghman.com>
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* This code is released by the author with no restrictions on usage.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
|
||||
/* Maximum length of any variable */
|
||||
#define MAXRESULT 1024
|
||||
|
||||
static char *tdesc = "Reevaluates strings";
|
||||
|
||||
static char *app_eval = "Eval";
|
||||
|
||||
static char *eval_synopsis = "Evaluates a string";
|
||||
|
||||
static char *eval_descrip =
|
||||
"Usage: Eval(newvar=somestring)\n"
|
||||
" Normally Asterisk evaluates variables inline. But what if you want to\n"
|
||||
"store variable offsets in a database, to be evaluated later? Eval is\n"
|
||||
"the answer, by allowing a string to be evaluated twice in the dialplan,\n"
|
||||
"the first time as part of the normal dialplan, and the second using Eval.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int eval_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
char *s, *newvar=NULL, tmp[MAXRESULT];
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
/* Check and parse arguments */
|
||||
if (data) {
|
||||
s = ast_strdupa((char *)data);
|
||||
if (s) {
|
||||
newvar = strsep(&s, "=");
|
||||
if (newvar && (newvar[0] != '\0')) {
|
||||
memset(tmp, 0, MAXRESULT);
|
||||
pbx_substitute_variables_helper(chan, s, tmp, MAXRESULT - 1);
|
||||
pbx_builtin_setvar_helper(chan, newvar, tmp);
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_ERROR, "Out of memory\n");
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app_eval);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app_eval, eval_exec, eval_synopsis, eval_descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
113
apps/app_exec.c
Normal file
113
apps/app_exec.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Exec application
|
||||
*
|
||||
* Copyright (c) 2004 Tilghman Lesher. All rights reserved.
|
||||
*
|
||||
* Tilghman Lesher <app_exec__v001@the-tilghman.com>
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* This code is released by the author with no restrictions on usage.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
|
||||
/* Maximum length of any variable */
|
||||
#define MAXRESULT 1024
|
||||
|
||||
static char *tdesc = "Executes applications";
|
||||
|
||||
static char *app_exec = "Exec";
|
||||
|
||||
static char *exec_synopsis = "Exec(Appname(arguments))";
|
||||
|
||||
static char *exec_descrip =
|
||||
"Exec(appname(arguments))\n"
|
||||
" Allows an arbitrary application to be invoked even when not\n"
|
||||
"hardcoded into the dialplan. Returns whatever value the\n"
|
||||
"app returns or -2 when the app cannot be found.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int exec_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
char *s, *appname, *endargs, args[MAXRESULT];
|
||||
struct ast_app *app;
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
memset(args, 0, MAXRESULT);
|
||||
|
||||
/* Check and parse arguments */
|
||||
if (data) {
|
||||
s = ast_strdupa((char *)data);
|
||||
if (s) {
|
||||
appname = strsep(&s, "(");
|
||||
if (s) {
|
||||
endargs = strrchr(s, ')');
|
||||
if (endargs)
|
||||
*endargs = '\0';
|
||||
pbx_substitute_variables_helper(chan, s, args, MAXRESULT - 1);
|
||||
}
|
||||
if (appname) {
|
||||
app = pbx_findapp(appname);
|
||||
if (app) {
|
||||
res = pbx_exec(chan, app, args, 1);
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Could not find application (%s)\n", appname);
|
||||
res = -2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_ERROR, "Out of memory\n");
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app_exec);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app_exec, exec_exec, exec_synopsis, exec_descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
482
apps/app_festival.c
Normal file
482
apps/app_festival.c
Normal file
@@ -0,0 +1,482 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Connect to festival
|
||||
*
|
||||
* Copyright (C) 2002, Christos Ricudis
|
||||
*
|
||||
* Christos Ricudis <ricudis@itc.auth.gr>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/md5.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
#define FESTIVAL_CONFIG "festival.conf"
|
||||
|
||||
static char *tdesc = "Simple Festival Interface";
|
||||
|
||||
static char *app = "Festival";
|
||||
|
||||
static char *synopsis = "Say text to the user";
|
||||
|
||||
static char *descrip =
|
||||
" Festival(text[|intkeys]): Connect to Festival, send the argument, get back the waveform,"
|
||||
"play it to the user, allowing any given interrupt keys to immediately terminate and return\n"
|
||||
"the value, or 'any' to allow any number back (useful in dialplan)\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static char *socket_receive_file_to_buff(int fd,int *size)
|
||||
{
|
||||
/* Receive file (probably a waveform file) from socket using */
|
||||
/* Festival key stuff technique, but long winded I know, sorry */
|
||||
/* but will receive any file without closeing the stream or */
|
||||
/* using OOB data */
|
||||
static char *file_stuff_key = "ft_StUfF_key"; /* must == Festival's key */
|
||||
char *buff;
|
||||
int bufflen;
|
||||
int n,k,i;
|
||||
char c;
|
||||
|
||||
bufflen = 1024;
|
||||
buff = (char *)malloc(bufflen);
|
||||
*size=0;
|
||||
|
||||
for (k=0; file_stuff_key[k] != '\0';)
|
||||
{
|
||||
n = read(fd,&c,1);
|
||||
if (n==0) break; /* hit stream eof before end of file */
|
||||
if ((*size)+k+1 >= bufflen)
|
||||
{ /* +1 so you can add a NULL if you want */
|
||||
bufflen += bufflen/4;
|
||||
buff = (char *)realloc(buff,bufflen);
|
||||
}
|
||||
if (file_stuff_key[k] == c)
|
||||
k++;
|
||||
else if ((c == 'X') && (file_stuff_key[k+1] == '\0'))
|
||||
{ /* It looked like the key but wasn't */
|
||||
for (i=0; i < k; i++,(*size)++)
|
||||
buff[*size] = file_stuff_key[i];
|
||||
k=0;
|
||||
/* omit the stuffed 'X' */
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < k; i++,(*size)++)
|
||||
buff[*size] = file_stuff_key[i];
|
||||
k=0;
|
||||
buff[*size] = c;
|
||||
(*size)++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
static int send_waveform_to_fd(char *waveform, int length, int fd) {
|
||||
|
||||
int res;
|
||||
int x;
|
||||
#ifdef __PPC__
|
||||
char c;
|
||||
#endif
|
||||
|
||||
res = fork();
|
||||
if (res < 0)
|
||||
ast_log(LOG_WARNING, "Fork failed\n");
|
||||
if (res)
|
||||
return res;
|
||||
for (x=0;x<256;x++) {
|
||||
if (x != fd)
|
||||
close(x);
|
||||
}
|
||||
//IAS
|
||||
#ifdef __PPC__
|
||||
for( x=0; x<length; x+=2)
|
||||
{
|
||||
c = *(waveform+x+1);
|
||||
*(waveform+x+1)=*(waveform+x);
|
||||
*(waveform+x)=c;
|
||||
}
|
||||
#endif
|
||||
|
||||
write(fd,waveform,length);
|
||||
close(fd);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, int length, char *intkeys) {
|
||||
int res=0;
|
||||
int fds[2];
|
||||
int ms = -1;
|
||||
int pid = -1;
|
||||
int needed = 0;
|
||||
int owriteformat;
|
||||
struct ast_frame *f;
|
||||
struct myframe {
|
||||
struct ast_frame f;
|
||||
char offset[AST_FRIENDLY_OFFSET];
|
||||
char frdata[2048];
|
||||
} myf;
|
||||
|
||||
if (pipe(fds)) {
|
||||
ast_log(LOG_WARNING, "Unable to create pipe\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Answer if it's not already going */
|
||||
if (chan->_state != AST_STATE_UP)
|
||||
ast_answer(chan);
|
||||
ast_stopstream(chan);
|
||||
|
||||
owriteformat = chan->writeformat;
|
||||
res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
res=send_waveform_to_fd(waveform,length,fds[1]);
|
||||
if (res >= 0) {
|
||||
pid = res;
|
||||
/* Order is important -- there's almost always going to be mp3... we want to prioritize the
|
||||
user */
|
||||
for (;;) {
|
||||
ms = 1000;
|
||||
res = ast_waitfor(chan, ms);
|
||||
if (res < 1) {
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
f = ast_read(chan);
|
||||
if (!f) {
|
||||
ast_log(LOG_WARNING, "Null frame == hangup() detected\n");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
if (f->frametype == AST_FRAME_DTMF) {
|
||||
ast_log(LOG_DEBUG, "User pressed a key\n");
|
||||
if (intkeys && strchr(intkeys, f->subclass)) {
|
||||
res = f->subclass;
|
||||
ast_frfree(f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (f->frametype == AST_FRAME_VOICE) {
|
||||
/* Treat as a generator */
|
||||
needed = f->samples * 2;
|
||||
if (needed > sizeof(myf.frdata)) {
|
||||
ast_log(LOG_WARNING, "Only able to deliver %d of %d requested samples\n",
|
||||
(int)sizeof(myf.frdata) / 2, needed/2);
|
||||
needed = sizeof(myf.frdata);
|
||||
}
|
||||
res = read(fds[0], myf.frdata, needed);
|
||||
if (res > 0) {
|
||||
myf.f.frametype = AST_FRAME_VOICE;
|
||||
myf.f.subclass = AST_FORMAT_SLINEAR;
|
||||
myf.f.datalen = res;
|
||||
myf.f.samples = res / 2;
|
||||
myf.f.mallocd = 0;
|
||||
myf.f.offset = AST_FRIENDLY_OFFSET;
|
||||
myf.f.src = __PRETTY_FUNCTION__;
|
||||
myf.f.data = myf.frdata;
|
||||
if (ast_write(chan, &myf.f) < 0) {
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
if (res < needed) { // last frame
|
||||
ast_log(LOG_DEBUG, "Last frame\n");
|
||||
res=0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_DEBUG, "No more waveform\n");
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
ast_frfree(f);
|
||||
}
|
||||
}
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
// if (pid > -1)
|
||||
// kill(pid, SIGKILL);
|
||||
if (!res && owriteformat)
|
||||
ast_set_write_format(chan, owriteformat);
|
||||
return res;
|
||||
}
|
||||
|
||||
#define MAXLEN 180
|
||||
#define MAXFESTLEN 2048
|
||||
|
||||
|
||||
|
||||
|
||||
static int festival_exec(struct ast_channel *chan, void *vdata)
|
||||
{
|
||||
int usecache;
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
struct sockaddr_in serv_addr;
|
||||
struct hostent *serverhost;
|
||||
struct ast_hostent ahp;
|
||||
int fd;
|
||||
FILE *fs;
|
||||
char *host;
|
||||
char *cachedir;
|
||||
char *temp;
|
||||
char *festivalcommand;
|
||||
int port=1314;
|
||||
int n;
|
||||
char ack[4];
|
||||
char *waveform;
|
||||
int filesize;
|
||||
int wave;
|
||||
char bigstring[MAXFESTLEN];
|
||||
int i;
|
||||
struct MD5Context md5ctx;
|
||||
unsigned char MD5Res[16];
|
||||
char MD5Hex[33] = "";
|
||||
char koko[4] = "";
|
||||
char cachefile[MAXFESTLEN]="";
|
||||
int readcache=0;
|
||||
int writecache=0;
|
||||
int strln;
|
||||
int fdesc = -1;
|
||||
char buffer[16384];
|
||||
int seekpos = 0;
|
||||
char data[256] = "";
|
||||
char *intstr;
|
||||
|
||||
struct ast_config *cfg;
|
||||
cfg = ast_load(FESTIVAL_CONFIG);
|
||||
if (!cfg) {
|
||||
ast_log(LOG_WARNING, "No such configuration file %s\n", FESTIVAL_CONFIG);
|
||||
return -1;
|
||||
}
|
||||
if (!(host = ast_variable_retrieve(cfg, "general", "host"))) {
|
||||
host = "localhost";
|
||||
}
|
||||
if (!(temp = ast_variable_retrieve(cfg, "general", "port"))) {
|
||||
port = 1314;
|
||||
} else {
|
||||
port = atoi(temp);
|
||||
}
|
||||
if (!(temp = ast_variable_retrieve(cfg, "general", "usecache"))) {
|
||||
usecache=0;
|
||||
} else {
|
||||
usecache = ast_true(temp);
|
||||
}
|
||||
if (!(cachedir = ast_variable_retrieve(cfg, "general", "cachedir"))) {
|
||||
cachedir = "/tmp/";
|
||||
}
|
||||
if (!(festivalcommand = ast_variable_retrieve(cfg, "general", "festivalcommand"))) {
|
||||
festivalcommand = "(tts_textasterisk \"%s\" 'file)(quit)\n";
|
||||
}
|
||||
if (!vdata || ast_strlen_zero(vdata)) {
|
||||
ast_log(LOG_WARNING, "festival requires an argument (text)\n");
|
||||
ast_destroy(cfg);
|
||||
return -1;
|
||||
}
|
||||
strncpy(data, vdata, sizeof(data) - 1);
|
||||
if ((intstr = strchr(data, '|'))) {
|
||||
*intstr = '\0';
|
||||
intstr++;
|
||||
if (!strcasecmp(intstr, "any"))
|
||||
intstr = AST_DIGIT_ANY;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
ast_log(LOG_DEBUG, "Text passed to festival server : %s\n",(char *)data);
|
||||
/* Connect to local festival server */
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
if (fd < 0) {
|
||||
ast_log(LOG_WARNING,"festival_client: can't get socket\n");
|
||||
ast_destroy(cfg);
|
||||
return -1;
|
||||
}
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
if ((serv_addr.sin_addr.s_addr = inet_addr(host)) == -1) {
|
||||
/* its a name rather than an ipnum */
|
||||
serverhost = ast_gethostbyname(host, &ahp);
|
||||
if (serverhost == (struct hostent *)0) {
|
||||
ast_log(LOG_WARNING,"festival_client: gethostbyname failed\n");
|
||||
ast_destroy(cfg);
|
||||
return -1;
|
||||
}
|
||||
memmove(&serv_addr.sin_addr,serverhost->h_addr, serverhost->h_length);
|
||||
}
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_port = htons(port);
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) {
|
||||
ast_log(LOG_WARNING,"festival_client: connect to server failed\n");
|
||||
ast_destroy(cfg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Compute MD5 sum of string */
|
||||
MD5Init(&md5ctx);
|
||||
MD5Update(&md5ctx,(unsigned char const *)data,strlen(data));
|
||||
MD5Final(MD5Res,&md5ctx);
|
||||
MD5Hex[0] = '\0';
|
||||
|
||||
/* Convert to HEX and look if there is any matching file in the cache
|
||||
directory */
|
||||
for (i=0;i<16;i++) {
|
||||
snprintf(koko, sizeof(koko), "%X",MD5Res[i]);
|
||||
strncat(MD5Hex, koko, sizeof(MD5Hex) - strlen(MD5Hex) - 1);
|
||||
}
|
||||
readcache=0;
|
||||
writecache=0;
|
||||
if (strlen(cachedir)+strlen(MD5Hex)+1<=MAXFESTLEN && (usecache==-1)) {
|
||||
snprintf(cachefile, sizeof(cachefile), "%s/%s", cachedir, MD5Hex);
|
||||
fdesc=open(cachefile,O_RDWR);
|
||||
if (fdesc==-1) {
|
||||
fdesc=open(cachefile,O_CREAT|O_RDWR,0777);
|
||||
if (fdesc!=-1) {
|
||||
writecache=1;
|
||||
strln=strlen((char *)data);
|
||||
ast_log(LOG_DEBUG,"line length : %d\n",strln);
|
||||
write(fdesc,&strln,sizeof(int));
|
||||
write(fdesc,data,strln);
|
||||
seekpos=lseek(fdesc,0,SEEK_CUR);
|
||||
ast_log(LOG_DEBUG,"Seek position : %d\n",seekpos);
|
||||
}
|
||||
} else {
|
||||
read(fdesc,&strln,sizeof(int));
|
||||
ast_log(LOG_DEBUG,"Cache file exists, strln=%d, strlen=%d\n",strln,(int)strlen((char *)data));
|
||||
if (strlen((char *)data)==strln) {
|
||||
ast_log(LOG_DEBUG,"Size OK\n");
|
||||
read(fdesc,&bigstring,strln);
|
||||
bigstring[strln] = 0;
|
||||
if (strcmp(bigstring,data)==0) {
|
||||
readcache=1;
|
||||
} else {
|
||||
ast_log(LOG_WARNING,"Strings do not match\n");
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_WARNING,"Size mismatch\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (readcache==1) {
|
||||
close(fd);
|
||||
fd=fdesc;
|
||||
ast_log(LOG_DEBUG,"Reading from cache...\n");
|
||||
} else {
|
||||
ast_log(LOG_DEBUG,"Passing text to festival...\n");
|
||||
fs=fdopen(dup(fd),"wb");
|
||||
fprintf(fs,festivalcommand,(char *)data);
|
||||
fflush(fs);
|
||||
fclose(fs);
|
||||
}
|
||||
|
||||
/* Write to cache and then pass it down */
|
||||
if (writecache==1) {
|
||||
ast_log(LOG_DEBUG,"Writing result to cache...\n");
|
||||
while ((strln=read(fd,buffer,16384))!=0) {
|
||||
write(fdesc,buffer,strln);
|
||||
}
|
||||
close(fd);
|
||||
close(fdesc);
|
||||
fd=open(cachefile,O_RDWR);
|
||||
lseek(fd,seekpos,SEEK_SET);
|
||||
}
|
||||
|
||||
ast_log(LOG_DEBUG,"Passing data to channel...\n");
|
||||
|
||||
/* Read back info from server */
|
||||
/* This assumes only one waveform will come back, also LP is unlikely */
|
||||
wave = 0;
|
||||
do {
|
||||
for (n=0; n < 3; )
|
||||
n += read(fd,ack+n,3-n);
|
||||
ack[3] = '\0';
|
||||
if (strcmp(ack,"WV\n") == 0) { /* receive a waveform */
|
||||
ast_log(LOG_DEBUG,"Festival WV command\n");
|
||||
waveform = socket_receive_file_to_buff(fd,&filesize);
|
||||
res = send_waveform_to_channel(chan,waveform,filesize, intstr);
|
||||
free(waveform);
|
||||
break;
|
||||
}
|
||||
else if (strcmp(ack,"LP\n") == 0) { /* receive an s-expr */
|
||||
ast_log(LOG_DEBUG,"Festival LP command\n");
|
||||
waveform = socket_receive_file_to_buff(fd,&filesize);
|
||||
waveform[filesize]='\0';
|
||||
ast_log(LOG_WARNING,"Festival returned LP : %s\n",waveform);
|
||||
free(waveform);
|
||||
} else if (strcmp(ack,"ER\n") == 0) { /* server got an error */
|
||||
ast_log(LOG_WARNING,"Festival returned ER\n");
|
||||
res=-1;
|
||||
break;
|
||||
}
|
||||
} while (strcmp(ack,"OK\n") != 0);
|
||||
close(fd);
|
||||
ast_destroy(cfg);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
|
||||
return ast_register_application(app, festival_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
119
apps/app_flash.c
Normal file
119
apps/app_flash.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* App to flash a zap trunk
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/image.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <sys/ioctl.h>
|
||||
#ifdef __linux__
|
||||
#include <linux/zaptel.h>
|
||||
#else
|
||||
#include <zaptel.h>
|
||||
#endif /* __linux__ */
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Flash zap trunk application";
|
||||
|
||||
static char *app = "Flash";
|
||||
|
||||
static char *synopsis = "Flashes a Zap Trunk";
|
||||
|
||||
static char *descrip =
|
||||
" Flash(): Sends a flash on a zap trunk. This is only a hack for\n"
|
||||
"people who want to perform transfers and such via AGI and is generally\n"
|
||||
"quite useless otherwise. Returns 0 on success or -1 if this is not\n"
|
||||
"a zap trunk\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static inline int zt_wait_event(int fd)
|
||||
{
|
||||
/* Avoid the silly zt_waitevent which ignores a bunch of events */
|
||||
int i,j=0;
|
||||
i = ZT_IOMUX_SIGEVENT;
|
||||
if (ioctl(fd, ZT_IOMUX, &i) == -1) return -1;
|
||||
if (ioctl(fd, ZT_GETEVENT, &j) == -1) return -1;
|
||||
return j;
|
||||
}
|
||||
|
||||
static int flash_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = -1;
|
||||
int x;
|
||||
struct localuser *u;
|
||||
struct zt_params ztp;
|
||||
LOCAL_USER_ADD(u);
|
||||
if (!strcasecmp(chan->type, "Zap")) {
|
||||
memset(&ztp, 0, sizeof(ztp));
|
||||
res = ioctl(chan->fds[0], ZT_GET_PARAMS, &ztp);
|
||||
if (!res) {
|
||||
if (ztp.sigtype & __ZT_SIG_FXS) {
|
||||
x = ZT_FLASH;
|
||||
res = ioctl(chan->fds[0], ZT_HOOK, &x);
|
||||
if (!res || (errno == EINPROGRESS)) {
|
||||
if (res) {
|
||||
/* Wait for the event to finish */
|
||||
zt_wait_event(chan->fds[0]);
|
||||
}
|
||||
res = ast_safe_sleep(chan, 1000);
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Flashed channel %s\n", chan->name);
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Unable to flash channel %s: %s\n", chan->name, strerror(errno));
|
||||
} else
|
||||
ast_log(LOG_WARNING, "%s is not an FXO Channel\n", chan->name);
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Unable to get parameters of %s: %s\n", chan->name, strerror(errno));
|
||||
} else
|
||||
ast_log(LOG_WARNING, "%s is not a Zap channel\n", chan->name);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, flash_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
91
apps/app_forkcdr.c
Normal file
91
apps/app_forkcdr.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Fork CDR application
|
||||
* Copyright Anthony Minessale anthmct@yahoo.com
|
||||
* Development of this app Sponsered/Funded by TAAN Softworks Corp
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/cdr.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
static char *tdesc = "Fork The CDR into 2 separate entities.";
|
||||
static char *app = "ForkCDR";
|
||||
static char *synopsis =
|
||||
"Forks the Call Data Record";
|
||||
static char *descrip =
|
||||
" ForkCDR(): Causes the Call Data Record to fork an additional\n"
|
||||
"cdr record starting from the time of the fork call\n";
|
||||
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
|
||||
static void ast_cdr_clone(struct ast_cdr *cdr) {
|
||||
struct ast_cdr *newcdr = ast_cdr_alloc();
|
||||
memcpy(newcdr,cdr,sizeof(struct ast_cdr));
|
||||
newcdr->next = NULL;
|
||||
ast_cdr_append(cdr,newcdr);
|
||||
gettimeofday(&newcdr->start, NULL);
|
||||
memset(&newcdr->answer, 0, sizeof(newcdr->answer));
|
||||
ast_cdr_add_flag(cdr,AST_CDR_FLAG_CHILD|AST_CDR_FLAG_LOCKED);
|
||||
}
|
||||
|
||||
static void ast_cdr_fork(struct ast_channel *chan) {
|
||||
if(chan && chan->cdr) {
|
||||
ast_cdr_clone(chan->cdr);
|
||||
}
|
||||
}
|
||||
|
||||
static int forkcdr_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
ast_cdr_fork(chan);
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, forkcdr_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
146
apps/app_getcpeid.c
Normal file
146
apps/app_getcpeid.c
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Execute arbitrary system commands
|
||||
*
|
||||
* Copyright (C) 1999-2005, Digium
|
||||
*
|
||||
* Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/adsi.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Get ADSI CPE ID";
|
||||
|
||||
static char *app = "GetCPEID";
|
||||
|
||||
static char *synopsis = "Get ADSI CPE ID";
|
||||
|
||||
static char *descrip =
|
||||
" GetCPEID: Obtains and displays ADSI CPE ID and other information in order\n"
|
||||
"to properly setup zapata.conf for on-hook operations.\n"
|
||||
"Returns -1 on hangup only.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int cpeid_setstatus(struct ast_channel *chan, char *stuff[], int voice)
|
||||
{
|
||||
int justify[5] = { ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_JUST_LEFT, ADSI_JUST_LEFT };
|
||||
char *tmp[5];
|
||||
int x;
|
||||
for (x=0;x<4;x++)
|
||||
tmp[x] = stuff[x];
|
||||
tmp[4] = NULL;
|
||||
return adsi_print(chan, tmp, justify, voice);
|
||||
}
|
||||
|
||||
static int cpeid_exec(struct ast_channel *chan, void *idata)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
unsigned char cpeid[4];
|
||||
int gotgeometry = 0;
|
||||
int gotcpeid = 0;
|
||||
int width, height, buttons;
|
||||
char data[4][80];
|
||||
char *stuff[4];
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
stuff[0] = data[0];
|
||||
stuff[1] = data[1];
|
||||
stuff[2] = data[2];
|
||||
stuff[3] = data[3];
|
||||
memset(data, 0, sizeof(data));
|
||||
strncpy(stuff[0], "** CPE Info **", sizeof(data[0]) - 1);
|
||||
strncpy(stuff[1], "Identifying CPE...", sizeof(data[1]) - 1);
|
||||
strncpy(stuff[2], "Please wait...", sizeof(data[2]) - 1);
|
||||
res = adsi_load_session(chan, NULL, 0, 1);
|
||||
if (res > 0) {
|
||||
cpeid_setstatus(chan, stuff, 0);
|
||||
res = adsi_get_cpeid(chan, cpeid, 0);
|
||||
if (res > 0) {
|
||||
gotcpeid = 1;
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Got CPEID of '%02x:%02x:%02x:%02x' on '%s'\n", cpeid[0], cpeid[1], cpeid[2], cpeid[3], chan->name);
|
||||
}
|
||||
if (res > -1) {
|
||||
strncpy(stuff[1], "Measuring CPE...", sizeof(data[1]) - 1);
|
||||
strncpy(stuff[2], "Please wait...", sizeof(data[2]) - 1);
|
||||
cpeid_setstatus(chan, stuff, 0);
|
||||
res = adsi_get_cpeinfo(chan, &width, &height, &buttons, 0);
|
||||
if (res > -1) {
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "CPE has %d lines, %d columns, and %d buttons on '%s'\n", height, width, buttons, chan->name);
|
||||
gotgeometry = 1;
|
||||
}
|
||||
}
|
||||
if (res > -1) {
|
||||
if (gotcpeid)
|
||||
snprintf(stuff[1], sizeof(data[1]), "CPEID: %02x:%02x:%02x:%02x", cpeid[0], cpeid[1], cpeid[2], cpeid[3]);
|
||||
else
|
||||
strncpy(stuff[1], "CPEID Unknown", sizeof(data[1]) - 1);
|
||||
if (gotgeometry)
|
||||
snprintf(stuff[2], sizeof(data[2]), "Geom: %dx%d, %d buttons", width, height, buttons);
|
||||
else
|
||||
strncpy(stuff[2], "Geometry unknown", sizeof(data[2]) - 1);
|
||||
strncpy(stuff[3], "Press # to exit", sizeof(data[3]) - 1);
|
||||
cpeid_setstatus(chan, stuff, 1);
|
||||
for(;;) {
|
||||
res = ast_waitfordigit(chan, 1000);
|
||||
if (res < 0)
|
||||
break;
|
||||
if (res == '#') {
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
adsi_unload_session(chan);
|
||||
}
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, cpeid_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
224
apps/app_groupcount.c
Normal file
224
apps/app_groupcount.c
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Group Manipulation Applications
|
||||
*
|
||||
* Copyright (c) 2004 Digium
|
||||
*
|
||||
* Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/utils.h>
|
||||
|
||||
static char *tdesc = "Group Management Routines";
|
||||
|
||||
static char *app_group_count = "GetGroupCount";
|
||||
static char *app_group_set = "SetGroup";
|
||||
static char *app_group_check = "CheckGroup";
|
||||
|
||||
static char *group_count_synopsis = "GetGroupCount([groupname][@category])";
|
||||
static char *group_set_synopsis = "SetGroup(groupname[@category])";
|
||||
static char *group_check_synopsis = "CheckGroup(max[@category])";
|
||||
|
||||
static char *group_count_descrip =
|
||||
"GetGroupCount([group][@category])\n"
|
||||
" Calculates the group count for the specified group, or uses\n"
|
||||
"the current channel's group if not specifed (and non-empty).\n"
|
||||
"Stores result in GROUPCOUNT. Always returns 0.\n";
|
||||
|
||||
static char *group_set_descrip =
|
||||
"SetGroup(group)\n"
|
||||
" Sets the channel group to the specified value. Equivalent to\n"
|
||||
"SetVar(GROUP=group). Always returns 0.\n";
|
||||
|
||||
static char *group_check_descrip =
|
||||
"CheckGroup(max)\n"
|
||||
" Checks that the current number of total channels in the\n"
|
||||
"current channel's group does not exceed 'max'. If the number\n"
|
||||
"does not exceed 'max', we continue to the next step. If the\n"
|
||||
"number does in fact exceed max, if priority n+101 exists, then\n"
|
||||
"execution continues at that step, otherwise -1 is returned.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
#define DEFAULT_CATEGORY "GROUP"
|
||||
|
||||
static int group_get_count(char *group, char *category)
|
||||
{
|
||||
struct ast_channel *chan;
|
||||
int count = 0;
|
||||
char *test;
|
||||
if (group && !ast_strlen_zero(group)) {
|
||||
chan = ast_channel_walk_locked(NULL);
|
||||
while(chan) {
|
||||
test = pbx_builtin_getvar_helper(chan, category);
|
||||
if (test && !strcasecmp(test, group))
|
||||
count++;
|
||||
ast_mutex_unlock(&chan->lock);
|
||||
chan = ast_channel_walk_locked(chan);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static int group_count_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
int count;
|
||||
struct localuser *u;
|
||||
char *group=NULL;
|
||||
char *cat = NULL;
|
||||
char ret[80]="";
|
||||
char tmp[256]="";
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
/* Check and parse arguments */
|
||||
if (data && !ast_strlen_zero(data)) {
|
||||
strncpy(tmp, data, sizeof(tmp) - 1);
|
||||
group = tmp;
|
||||
cat = strchr(tmp, '@');
|
||||
if (cat) {
|
||||
*cat = '\0';
|
||||
cat++;
|
||||
}
|
||||
}
|
||||
if (cat)
|
||||
snprintf(ret, sizeof(ret), "GROUP_%s", cat);
|
||||
else
|
||||
strncpy(ret, DEFAULT_CATEGORY, sizeof(ret) - 1);
|
||||
|
||||
if (!group || ast_strlen_zero(group)) {
|
||||
group = pbx_builtin_getvar_helper(chan, ret);
|
||||
}
|
||||
count = group_get_count(group, ret);
|
||||
snprintf(ret, sizeof(ret), "%d", count);
|
||||
pbx_builtin_setvar_helper(chan, "GROUPCOUNT", ret);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int group_set_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
char ret[80] = "";
|
||||
char tmp[256] = "";
|
||||
char *cat=NULL, *group=NULL;
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
/* Check and parse arguments */
|
||||
if (data && !ast_strlen_zero(data)) {
|
||||
strncpy(tmp, data, sizeof(tmp) - 1);
|
||||
group = tmp;
|
||||
cat = strchr(tmp, '@');
|
||||
if (cat) {
|
||||
*cat = '\0';
|
||||
cat++;
|
||||
}
|
||||
}
|
||||
if (cat)
|
||||
snprintf(ret, sizeof(ret), "GROUP_%s", cat);
|
||||
else
|
||||
strncpy(ret, DEFAULT_CATEGORY, sizeof(ret) - 1);
|
||||
|
||||
if (group && !ast_strlen_zero(group)) {
|
||||
pbx_builtin_setvar_helper(chan, ret, group);
|
||||
} else
|
||||
ast_log(LOG_WARNING, "SetGroup requires an argument (group name)\n");
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int group_check_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
int max, count;
|
||||
struct localuser *u;
|
||||
char ret[80] = "";
|
||||
char tmp[256] = "";
|
||||
char *cat, *group;
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
if (data && !ast_strlen_zero(data)) {
|
||||
strncpy(tmp, data, sizeof(tmp) - 1);
|
||||
group = tmp;
|
||||
cat = strchr(tmp, '@');
|
||||
if (cat) {
|
||||
*cat = '\0';
|
||||
cat++;
|
||||
}
|
||||
if ((sscanf((char *)tmp, "%i", &max) == 1) && (max > -1)) {
|
||||
if (cat)
|
||||
snprintf(ret, sizeof(ret), "GROUP_%s", cat);
|
||||
else
|
||||
strncpy(ret, DEFAULT_CATEGORY, sizeof(ret) - 1);
|
||||
|
||||
count = group_get_count(pbx_builtin_getvar_helper(chan, ret), ret);
|
||||
if (count > max) {
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority += 100;
|
||||
else
|
||||
res = -1;
|
||||
}
|
||||
} else
|
||||
ast_log(LOG_WARNING, "CheckGroup requires a positive integer argument (max)\n");
|
||||
} else
|
||||
ast_log(LOG_WARNING, "CheckGroup requires an argument(max)\n");
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
res = ast_unregister_application(app_group_count);
|
||||
res |= ast_unregister_application(app_group_set);
|
||||
res |= ast_unregister_application(app_group_check);
|
||||
return res;
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
int res;
|
||||
res = ast_register_application(app_group_count, group_count_exec, group_count_synopsis, group_count_descrip);
|
||||
res |= ast_register_application(app_group_set, group_set_exec, group_set_synopsis, group_set_descrip);
|
||||
res |= ast_register_application(app_group_check, group_check_exec, group_check_synopsis, group_check_descrip);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
169
apps/app_hasnewvoicemail.c
Normal file
169
apps/app_hasnewvoicemail.c
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* HasVoicemail application
|
||||
* Changes Copyright (c) 2004 Todd Freeman <freeman@andrews.edu>
|
||||
*
|
||||
* 95% based on HasNewVoicemail by:
|
||||
*
|
||||
* Copyright (c) 2003 Tilghman Lesher. All rights reserved.
|
||||
*
|
||||
* Tilghman Lesher <asterisk-hasnewvoicemail-app@the-tilghman.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "../astconf.h"
|
||||
|
||||
static char *tdesc = "Indicator for whether a voice mailbox has messages in a given folder.";
|
||||
static char *app_hasvoicemail = "HasVoicemail";
|
||||
static char *hasvoicemail_synopsis = "Conditionally branches to priority + 101";
|
||||
static char *hasvoicemail_descrip =
|
||||
"HasVoicemail(vmbox[@context][:folder][|varname])\n"
|
||||
" Branches to priority + 101, if there is voicemail in folder indicated."
|
||||
" Optionally sets <varname> to the number of messages in that folder."
|
||||
" Assumes folder of INBOX if not specified.\n";
|
||||
|
||||
static char *app_hasnewvoicemail = "HasNewVoicemail";
|
||||
static char *hasnewvoicemail_synopsis = "Conditionally branches to priority + 101";
|
||||
static char *hasnewvoicemail_descrip =
|
||||
"HasNewVoicemail(vmbox[@context][|varname])\n"
|
||||
" Branches to priority + 101, if there is voicemail in folder INBOX."
|
||||
" Optionally sets <varname> to the number of messages in that folder.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int hasvoicemail_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
char vmpath[256], *temps, *input, *varname = NULL, *vmbox, *vmfolder = "INBOX", *context = "default";
|
||||
DIR *vmdir;
|
||||
struct dirent *vment;
|
||||
int vmcount = 0;
|
||||
|
||||
if (!data) {
|
||||
ast_log(LOG_WARNING, "HasVoicemail requires an argument (vm-box[@context][:folder]|varname)\n");
|
||||
return -1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
input = ast_strdupa((char *)data);
|
||||
if (input) {
|
||||
temps = input;
|
||||
if ((temps = strsep(&input, "|"))) {
|
||||
if (input && !ast_strlen_zero(input))
|
||||
varname = input;
|
||||
input = temps;
|
||||
}
|
||||
if ((temps = strsep(&input, ":"))) {
|
||||
if (input && !ast_strlen_zero(input))
|
||||
vmfolder = input;
|
||||
input = temps;
|
||||
}
|
||||
if ((vmbox = strsep(&input, "@")))
|
||||
if (input && !ast_strlen_zero(input))
|
||||
context = input;
|
||||
if (!vmbox)
|
||||
vmbox = input;
|
||||
|
||||
snprintf(vmpath,sizeof(vmpath), "%s/voicemail/%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR, context, vmbox, vmfolder);
|
||||
if (!(vmdir = opendir(vmpath))) {
|
||||
ast_log(LOG_NOTICE, "Voice mailbox %s at %s does not exist\n", vmbox, vmpath);
|
||||
} else {
|
||||
|
||||
/* No matter what the format of VM, there will always be a .txt file for each message. */
|
||||
while ((vment = readdir(vmdir)))
|
||||
if (!strncmp(vment->d_name + 7,".txt",4))
|
||||
vmcount++;
|
||||
closedir(vmdir);
|
||||
}
|
||||
/* Set the count in the channel variable */
|
||||
if (varname) {
|
||||
char tmp[12];
|
||||
snprintf(tmp, sizeof(tmp), "%d", vmcount);
|
||||
pbx_builtin_setvar_helper(chan, varname, tmp);
|
||||
}
|
||||
|
||||
if (vmcount > 0) {
|
||||
/* Branch to the next extension */
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid)) {
|
||||
chan->priority += 100;
|
||||
} else
|
||||
ast_log(LOG_WARNING, "VM box %s@%s has new voicemail, but extension %s, priority %d doesn't exist\n", vmbox, context, chan->exten, chan->priority + 101);
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_ERROR, "Out of memory error\n");
|
||||
}
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
res = ast_unregister_application(app_hasvoicemail);
|
||||
res |= ast_unregister_application(app_hasnewvoicemail);
|
||||
return res;
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
int res;
|
||||
res = ast_register_application(app_hasvoicemail, hasvoicemail_exec, hasvoicemail_synopsis, hasvoicemail_descrip);
|
||||
res |= ast_register_application(app_hasnewvoicemail, hasvoicemail_exec, hasnewvoicemail_synopsis, hasnewvoicemail_descrip);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
196
apps/app_ices.c
Normal file
196
apps/app_ices.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Stream to an icecast server via ICES (see contrib/asterisk-ices.xml)
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/frame.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include "../astconf.h"
|
||||
|
||||
#define ICES "/usr/bin/ices"
|
||||
#define LOCAL_ICES "/usr/local/bin/ices"
|
||||
|
||||
static char *tdesc = "Encode and Stream via icecast and ices";
|
||||
|
||||
static char *app = "ICES";
|
||||
|
||||
static char *synopsis = "Encode and stream using 'ices'";
|
||||
|
||||
static char *descrip =
|
||||
" ICES(config.xml) Streams to an icecast server using ices\n"
|
||||
"(available separately). A configuration file must be supplied\n"
|
||||
"for ices (see examples/asterisk-ices.conf). Returns -1 on\n"
|
||||
"hangup or 0 otherwise.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int icesencode(char *filename, int fd)
|
||||
{
|
||||
int res;
|
||||
int x;
|
||||
res = fork();
|
||||
if (res < 0)
|
||||
ast_log(LOG_WARNING, "Fork failed\n");
|
||||
if (res)
|
||||
return res;
|
||||
dup2(fd, STDIN_FILENO);
|
||||
for (x=STDERR_FILENO + 1;x<256;x++) {
|
||||
if ((x != STDIN_FILENO) && (x != STDOUT_FILENO))
|
||||
close(x);
|
||||
}
|
||||
/* Most commonly installed in /usr/local/bin */
|
||||
execl(ICES, "ices", filename, (char *)NULL);
|
||||
/* But many places has it in /usr/bin */
|
||||
execl(LOCAL_ICES, "ices", filename, (char *)NULL);
|
||||
/* As a last-ditch effort, try to use PATH */
|
||||
execlp("ices", "ices", filename, (char *)NULL);
|
||||
ast_log(LOG_WARNING, "Execute of ices failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int ices_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
int fds[2];
|
||||
int ms = -1;
|
||||
int pid = -1;
|
||||
int flags;
|
||||
int oreadformat;
|
||||
struct timeval last;
|
||||
struct ast_frame *f;
|
||||
char filename[256]="";
|
||||
char *c;
|
||||
last.tv_usec = 0;
|
||||
last.tv_sec = 0;
|
||||
if (!data || !strlen(data)) {
|
||||
ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n");
|
||||
return -1;
|
||||
}
|
||||
if (pipe(fds)) {
|
||||
ast_log(LOG_WARNING, "Unable to create pipe\n");
|
||||
return -1;
|
||||
}
|
||||
flags = fcntl(fds[1], F_GETFL);
|
||||
fcntl(fds[1], F_SETFL, flags | O_NONBLOCK);
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
ast_stopstream(chan);
|
||||
|
||||
if (chan->_state != AST_STATE_UP)
|
||||
res = ast_answer(chan);
|
||||
|
||||
if (res) {
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
ast_log(LOG_WARNING, "Answer failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
oreadformat = chan->readformat;
|
||||
res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
|
||||
if (res < 0) {
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
|
||||
return -1;
|
||||
}
|
||||
if (((char *)data)[0] == '/')
|
||||
strncpy(filename, (char *)data, sizeof(filename) - 1);
|
||||
else
|
||||
snprintf(filename, sizeof(filename), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, (char *)data);
|
||||
/* Placeholder for options */
|
||||
c = strchr(filename, '|');
|
||||
if (c)
|
||||
*c = '\0';
|
||||
res = icesencode(filename, fds[0]);
|
||||
close(fds[0]);
|
||||
if (res >= 0) {
|
||||
pid = res;
|
||||
for (;;) {
|
||||
/* Wait for audio, and stream */
|
||||
ms = ast_waitfor(chan, -1);
|
||||
if (ms < 0) {
|
||||
ast_log(LOG_DEBUG, "Hangup detected\n");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
f = ast_read(chan);
|
||||
if (!f) {
|
||||
ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
if (f->frametype == AST_FRAME_VOICE) {
|
||||
res = write(fds[1], f->data, f->datalen);
|
||||
if (res < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
ast_log(LOG_WARNING, "Write failed to pipe: %s\n", strerror(errno));
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ast_frfree(f);
|
||||
}
|
||||
}
|
||||
close(fds[1]);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
if (pid > -1)
|
||||
kill(pid, SIGKILL);
|
||||
if (!res && oreadformat)
|
||||
ast_set_read_format(chan, oreadformat);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, ices_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
89
apps/app_image.c
Normal file
89
apps/app_image.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* App to transmit an image
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/image.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Image Transmission Application";
|
||||
|
||||
static char *app = "SendImage";
|
||||
|
||||
static char *synopsis = "Send an image file";
|
||||
|
||||
static char *descrip =
|
||||
" SendImage(filename): Sends an image on a channel. If the channel\n"
|
||||
"does not support image transport, and there exists a step with\n"
|
||||
"priority n + 101, then execution will continue at that step.\n"
|
||||
"Otherwise, execution will continue at the next priority level.\n"
|
||||
"SendImage only returns 0 if the image was sent correctly or if\n"
|
||||
"the channel does not support image transport, and -1 otherwise.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int sendimage_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
struct localuser *u;
|
||||
if (!data || !strlen((char *)data)) {
|
||||
ast_log(LOG_WARNING, "SendImage requires an argument (filename)\n");
|
||||
return -1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
if (!ast_supports_images(chan)) {
|
||||
/* Does not support transport */
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority += 100;
|
||||
return 0;
|
||||
}
|
||||
res = ast_send_image(chan, data);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, sendimage_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
110
apps/app_intercom.c
Executable file → Normal file
110
apps/app_intercom.c
Executable file → Normal file
@@ -11,6 +11,7 @@
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/frame.h>
|
||||
#include <asterisk/logger.h>
|
||||
@@ -23,12 +24,22 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <linux/soundcard.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <linux/soundcard.h>
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <sys/soundcard.h>
|
||||
#else
|
||||
#include <soundcard.h>
|
||||
#endif
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#define DEV_DSP "/dev/audio"
|
||||
#else
|
||||
#define DEV_DSP "/dev/dsp"
|
||||
#endif
|
||||
|
||||
/* Number of 32 byte buffers -- each buffer is 2 ms */
|
||||
#define BUFFER_SIZE 32
|
||||
@@ -37,34 +48,40 @@ static char *tdesc = "Intercom using /dev/dsp for output";
|
||||
|
||||
static char *app = "Intercom";
|
||||
|
||||
static char *synopsis = "(Obsolete) Send to Intercom";
|
||||
static char *descrip =
|
||||
" Intercom(): Sends the user to the intercom (i.e. /dev/dsp). This program\n"
|
||||
"is generally considered obselete by the chan_oss module. Returns 0 if the\n"
|
||||
"user exits with a DTMF tone, or -1 if they hangup.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static pthread_mutex_t sound_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
AST_MUTEX_DEFINE_STATIC(sound_lock);
|
||||
static int sound = -1;
|
||||
|
||||
static int write_audio(short *data, int len)
|
||||
{
|
||||
int res;
|
||||
struct audio_buf_info info;
|
||||
pthread_mutex_lock(&sound_lock);
|
||||
ast_mutex_lock(&sound_lock);
|
||||
if (sound < 0) {
|
||||
ast_log(LOG_WARNING, "Sound device closed?\n");
|
||||
pthread_mutex_unlock(&sound_lock);
|
||||
ast_mutex_unlock(&sound_lock);
|
||||
return -1;
|
||||
}
|
||||
if (ioctl(sound, SNDCTL_DSP_GETOSPACE, &info)) {
|
||||
ast_log(LOG_WARNING, "Unable to read output space\n");
|
||||
pthread_mutex_unlock(&sound_lock);
|
||||
ast_mutex_unlock(&sound_lock);
|
||||
return -1;
|
||||
}
|
||||
res = write(sound, data, len);
|
||||
pthread_mutex_unlock(&sound_lock);
|
||||
ast_mutex_unlock(&sound_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int create_audio()
|
||||
static int create_audio(void)
|
||||
{
|
||||
int fmt, desired, res, fd;
|
||||
fd = open(DEV_DSP, O_WRONLY);
|
||||
@@ -116,48 +133,44 @@ static int intercom_exec(struct ast_channel *chan, void *data)
|
||||
int res = 0;
|
||||
struct localuser *u;
|
||||
struct ast_frame *f;
|
||||
struct ast_channel *trans;
|
||||
if (!data) {
|
||||
ast_log(LOG_WARNING, "Playback requires an argument (filename)\n");
|
||||
int oreadformat;
|
||||
LOCAL_USER_ADD(u);
|
||||
/* Remember original read format */
|
||||
oreadformat = chan->readformat;
|
||||
/* Set mode to signed linear */
|
||||
res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to set format to signed linear on channel %s\n", chan->name);
|
||||
return -1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
/* See if we need a translator */
|
||||
if (!(chan->format & AST_FORMAT_SLINEAR))
|
||||
trans = ast_translator_create(chan, AST_FORMAT_SLINEAR, AST_DIRECTION_IN);
|
||||
else
|
||||
trans = chan;
|
||||
if (trans) {
|
||||
/* Read packets from the channel */
|
||||
while(!res) {
|
||||
res = ast_waitfor(trans, -1);
|
||||
if (res > 0) {
|
||||
res = 0;
|
||||
f = ast_read(trans);
|
||||
if (f) {
|
||||
if (f->frametype == AST_FRAME_DTMF) {
|
||||
ast_frfree(f);
|
||||
break;
|
||||
} else {
|
||||
if (f->frametype == AST_FRAME_VOICE) {
|
||||
if (f->subclass == AST_FORMAT_SLINEAR) {
|
||||
res = write_audio(f->data, f->datalen);
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
} else
|
||||
ast_log(LOG_DEBUG, "Unable to handle non-signed linear frame (%d)\n", f->subclass);
|
||||
}
|
||||
}
|
||||
/* Read packets from the channel */
|
||||
while(!res) {
|
||||
res = ast_waitfor(chan, -1);
|
||||
if (res > 0) {
|
||||
res = 0;
|
||||
f = ast_read(chan);
|
||||
if (f) {
|
||||
if (f->frametype == AST_FRAME_DTMF) {
|
||||
ast_frfree(f);
|
||||
} else
|
||||
res = -1;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
if (f->frametype == AST_FRAME_VOICE) {
|
||||
if (f->subclass == AST_FORMAT_SLINEAR) {
|
||||
res = write_audio(f->data, f->datalen);
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
} else
|
||||
ast_log(LOG_DEBUG, "Unable to handle non-signed linear frame (%d)\n", f->subclass);
|
||||
}
|
||||
}
|
||||
ast_frfree(f);
|
||||
} else
|
||||
res = -1;
|
||||
}
|
||||
if (trans != chan)
|
||||
ast_translator_destroy(trans);
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Unable to build translator to signed linear format on '%s'\n", chan->name);
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
if (!res)
|
||||
ast_set_read_format(chan, oreadformat);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -173,7 +186,7 @@ int load_module(void)
|
||||
{
|
||||
if (create_audio())
|
||||
return -1;
|
||||
return ast_register_application(app, intercom_exec);
|
||||
return ast_register_application(app, intercom_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
@@ -187,3 +200,8 @@ int usecount(void)
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
|
||||
114
apps/app_lookupblacklist.c
Normal file
114
apps/app_lookupblacklist.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* App to lookup the callerid number, and see if it is blacklisted
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/image.h>
|
||||
#include <asterisk/callerid.h>
|
||||
#include <asterisk/astdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Look up Caller*ID name/number from blacklist database";
|
||||
|
||||
static char *app = "LookupBlacklist";
|
||||
|
||||
static char *synopsis = "Look up Caller*ID name/number from blacklist database";
|
||||
|
||||
static char *descrip =
|
||||
" LookupBlacklist: Looks up the Caller*ID number on the active\n"
|
||||
"channel in the Asterisk database (family 'blacklist'). If the\n"
|
||||
"number is found, and if there exists a priority n + 101,\n"
|
||||
"where 'n' is the priority of the current instance, then the\n"
|
||||
"channel will be setup to continue at that priority level.\n"
|
||||
"Otherwise, it returns 0. Does nothing if no Caller*ID was received on the\n"
|
||||
"channel.\n"
|
||||
"Example: database put blacklist <name/number> 1\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int
|
||||
lookupblacklist_exec (struct ast_channel *chan, void *data)
|
||||
{
|
||||
char old_cid[144] = "", *num, *name;
|
||||
char blacklist[1];
|
||||
char shrunknum[64] = "";
|
||||
struct localuser *u;
|
||||
int bl = 0;
|
||||
|
||||
LOCAL_USER_ADD (u);
|
||||
if (chan->callerid)
|
||||
{
|
||||
strncpy (old_cid, chan->callerid, sizeof (old_cid) - 1);
|
||||
ast_callerid_parse (old_cid, &name, &num);
|
||||
if (num)
|
||||
strncpy (shrunknum, num, sizeof (shrunknum) - 1);
|
||||
else
|
||||
num = shrunknum;
|
||||
|
||||
ast_shrink_phone_number (shrunknum);
|
||||
if (!ast_db_get ("blacklist", shrunknum, blacklist, sizeof (blacklist)))
|
||||
{
|
||||
if (option_verbose > 2)
|
||||
ast_log(LOG_NOTICE, "Blacklisted number %s found\n",shrunknum);
|
||||
bl = 1;
|
||||
}
|
||||
else if (!ast_db_get ("blacklist", name, blacklist, sizeof (blacklist)))
|
||||
{
|
||||
if (option_verbose > 2)
|
||||
ast_log (LOG_NOTICE,"Blacklisted name \"%s\" found\n",name);
|
||||
bl = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (bl && ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority+=100;
|
||||
LOCAL_USER_REMOVE (u);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unload_module (void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application (app);
|
||||
}
|
||||
|
||||
int load_module (void)
|
||||
{
|
||||
return ast_register_application (app, lookupblacklist_exec, synopsis,descrip);
|
||||
}
|
||||
|
||||
char *description (void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount (void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT (res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key ()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
111
apps/app_lookupcidname.c
Normal file
111
apps/app_lookupcidname.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* App to set callerid name from database, based on directory number
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/image.h>
|
||||
#include <asterisk/callerid.h>
|
||||
#include <asterisk/astdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Look up CallerID Name from local database";
|
||||
|
||||
static char *app = "LookupCIDName";
|
||||
|
||||
static char *synopsis = "Look up CallerID Name from local database";
|
||||
|
||||
static char *descrip =
|
||||
" LookupCIDName: Looks up the Caller*ID number on the active\n"
|
||||
"channel in the Asterisk database (family 'cidname') and sets the\n"
|
||||
"Caller*ID name. Does nothing if no Caller*ID was received on the\n"
|
||||
"channel. This is useful if you do not subscribe to Caller*ID\n"
|
||||
"name delivery, or if you want to change the names on some incoming\n"
|
||||
"calls. Always returns 0.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int
|
||||
lookupcidname_exec (struct ast_channel *chan, void *data)
|
||||
{
|
||||
char old_cid[144] = "", *num, *name;
|
||||
char new_cid[144];
|
||||
char dbname[64];
|
||||
char shrunknum[64] = "";
|
||||
struct localuser *u;
|
||||
|
||||
LOCAL_USER_ADD (u);
|
||||
if (chan->callerid)
|
||||
{
|
||||
strncpy (old_cid, chan->callerid, sizeof (old_cid) - 1);
|
||||
ast_callerid_parse (old_cid, &name, &num); /* this destroys the original string */
|
||||
if (num) /* It's possible to get an empty number */
|
||||
strncpy (shrunknum, num, sizeof (shrunknum) - 1);
|
||||
else
|
||||
num = shrunknum;
|
||||
ast_shrink_phone_number (shrunknum);
|
||||
if (!ast_db_get ("cidname", shrunknum, dbname, sizeof (dbname)))
|
||||
{
|
||||
snprintf (new_cid, sizeof (new_cid), "\"%s\" <%s>", dbname, num);
|
||||
ast_set_callerid (chan, new_cid, 0);
|
||||
if (option_verbose > 2)
|
||||
ast_verbose (VERBOSE_PREFIX_3 "Changed Caller*ID to %s\n",
|
||||
new_cid);
|
||||
}
|
||||
|
||||
}
|
||||
LOCAL_USER_REMOVE (u);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
unload_module (void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application (app);
|
||||
}
|
||||
|
||||
int
|
||||
load_module (void)
|
||||
{
|
||||
return ast_register_application (app, lookupcidname_exec, synopsis,
|
||||
descrip);
|
||||
}
|
||||
|
||||
char *
|
||||
description (void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int
|
||||
usecount (void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT (res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *
|
||||
key ()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
253
apps/app_macro.c
Normal file
253
apps/app_macro.c
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Macro Implementation
|
||||
*
|
||||
* Copyright (C) 2003, Digium
|
||||
*
|
||||
* Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_ARGS 80
|
||||
|
||||
static char *tdesc = "Extension Macros";
|
||||
|
||||
static char *descrip =
|
||||
" Macro(macroname|arg1|arg2...): Executes a macro using the context\n"
|
||||
"'macro-<macroname>', jumping to the 's' extension of that context and\n"
|
||||
"executing each step, then returning when the steps end. The calling\n"
|
||||
"extension, context, and priority are stored in ${MACRO_EXTEN}, \n"
|
||||
"${MACRO_CONTEXT} and ${MACRO_PRIORITY} respectively. Arguments become\n"
|
||||
"${ARG1}, ${ARG2}, etc in the macro context. Macro returns -1 if\n"
|
||||
"any step in the macro returns -1, and 0 otherwise. If you Goto out\n"
|
||||
"of the Macro context, the Macro will terminate and control will be return\n"
|
||||
"at the location of the Goto. Otherwise if ${MACRO_OFFSET} is set at\n"
|
||||
"termination, Macro will attempt to continue at priority\n"
|
||||
"MACRO_OFFSET + N + 1 if such a step exists, and N + 1 otherwise.\n";
|
||||
|
||||
static char *app = "Macro";
|
||||
|
||||
static char *synopsis = "Macro Implementation";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int macro_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
char tmp[256] = "";
|
||||
char *cur, *rest;
|
||||
char *macro;
|
||||
char fullmacro[80];
|
||||
char varname[80];
|
||||
char *oldargs[MAX_ARGS + 1] = { NULL, };
|
||||
int argc, x;
|
||||
int res=0;
|
||||
char oldexten[256]="";
|
||||
int oldpriority;
|
||||
char pc[80];
|
||||
char oldcontext[256] = "";
|
||||
char *offsets;
|
||||
int offset;
|
||||
int setmacrocontext=0;
|
||||
|
||||
char *save_macro_exten;
|
||||
char *save_macro_context;
|
||||
char *save_macro_priority;
|
||||
char *save_macro_offset;
|
||||
|
||||
if (!data || ast_strlen_zero(data)) {
|
||||
ast_log(LOG_WARNING, "Invalid Macro incantation\n");
|
||||
return 0;
|
||||
}
|
||||
strncpy(tmp, data, sizeof(tmp) - 1);
|
||||
rest = tmp;
|
||||
macro = strsep(&rest, "|");
|
||||
if (!macro || ast_strlen_zero(macro)) {
|
||||
ast_log(LOG_WARNING, "Invalid macro name specified\n");
|
||||
return 0;
|
||||
}
|
||||
snprintf(fullmacro, sizeof(fullmacro), "macro-%s", macro);
|
||||
if (!ast_exists_extension(chan, fullmacro, "s", 1, chan->callerid)) {
|
||||
if (!ast_context_find(fullmacro))
|
||||
ast_log(LOG_WARNING, "No such context '%s' for macro '%s'\n", fullmacro, macro);
|
||||
else
|
||||
ast_log(LOG_WARNING, "Context '%s' for macro '%s' lacks 's' extension, priority 1\n", fullmacro, macro);
|
||||
return 0;
|
||||
}
|
||||
/* Save old info */
|
||||
oldpriority = chan->priority;
|
||||
strncpy(oldexten, chan->exten, sizeof(oldexten) - 1);
|
||||
strncpy(oldcontext, chan->context, sizeof(oldcontext) - 1);
|
||||
if (ast_strlen_zero(chan->macrocontext)) {
|
||||
strncpy(chan->macrocontext, chan->context, sizeof(chan->macrocontext) - 1);
|
||||
strncpy(chan->macroexten, chan->exten, sizeof(chan->macroexten) - 1);
|
||||
chan->macropriority = chan->priority;
|
||||
setmacrocontext=1;
|
||||
}
|
||||
argc = 1;
|
||||
/* Save old macro variables */
|
||||
save_macro_exten = pbx_builtin_getvar_helper(chan, "MACRO_EXTEN");
|
||||
if (save_macro_exten) save_macro_exten = strdup(save_macro_exten);
|
||||
pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", oldexten);
|
||||
|
||||
save_macro_context = pbx_builtin_getvar_helper(chan, "MACRO_CONTEXT");
|
||||
if (save_macro_context) save_macro_context = strdup(save_macro_context);
|
||||
pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", oldcontext);
|
||||
|
||||
save_macro_priority = pbx_builtin_getvar_helper(chan, "MACRO_PRIORITY");
|
||||
if (save_macro_priority) save_macro_priority = strdup(save_macro_priority);
|
||||
snprintf(pc, sizeof(pc), "%d", oldpriority);
|
||||
pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", pc);
|
||||
|
||||
save_macro_offset = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET");
|
||||
if (save_macro_offset) save_macro_offset = strdup(save_macro_offset);
|
||||
pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", NULL);
|
||||
|
||||
/* Setup environment for new run */
|
||||
chan->exten[0] = 's';
|
||||
chan->exten[1] = '\0';
|
||||
strncpy(chan->context, fullmacro, sizeof(chan->context) - 1);
|
||||
chan->priority = 1;
|
||||
|
||||
while((cur = strsep(&rest, "|")) && (argc < MAX_ARGS)) {
|
||||
/* Save copy of old arguments if we're overwriting some, otherwise
|
||||
let them pass through to the other macro */
|
||||
snprintf(varname, sizeof(varname), "ARG%d", argc);
|
||||
oldargs[argc] = pbx_builtin_getvar_helper(chan, varname);
|
||||
if (oldargs[argc])
|
||||
oldargs[argc] = strdup(oldargs[argc]);
|
||||
pbx_builtin_setvar_helper(chan, varname, cur);
|
||||
argc++;
|
||||
}
|
||||
while(ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->callerid)) {
|
||||
if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->callerid))) {
|
||||
/* Something bad happened, or a hangup has been requested. */
|
||||
if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
|
||||
(res == '*') || (res == '#')) {
|
||||
/* Just return result as to the previous application as if it had been dialed */
|
||||
ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
|
||||
break;
|
||||
}
|
||||
switch(res) {
|
||||
case AST_PBX_KEEPALIVE:
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE in macro %s on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
|
||||
else if (option_verbose > 1)
|
||||
ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE in macro '%s' on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
|
||||
goto out;
|
||||
break;
|
||||
default:
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
|
||||
else if (option_verbose > 1)
|
||||
ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (strcasecmp(chan->context, fullmacro)) {
|
||||
if (option_verbose > 1)
|
||||
ast_verbose(VERBOSE_PREFIX_2 "Channel '%s' jumping out of macro '%s'\n", chan->name, macro);
|
||||
break;
|
||||
}
|
||||
/* don't stop executing extensions when we're in "h" */
|
||||
if (chan->_softhangup && strcasecmp(oldexten,"h")) {
|
||||
ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n",
|
||||
chan->exten, chan->priority);
|
||||
goto out;
|
||||
}
|
||||
chan->priority++;
|
||||
}
|
||||
out:
|
||||
for (x=1;x<argc;x++) {
|
||||
/* Restore old arguments and delete ours */
|
||||
snprintf(varname, sizeof(varname), "ARG%d", x);
|
||||
if (oldargs[x]) {
|
||||
pbx_builtin_setvar_helper(chan, varname, oldargs[x]);
|
||||
free(oldargs[x]);
|
||||
} else {
|
||||
pbx_builtin_setvar_helper(chan, varname, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore macro variables */
|
||||
pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten);
|
||||
if (save_macro_exten) free(save_macro_exten);
|
||||
pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context);
|
||||
if (save_macro_context) free(save_macro_context);
|
||||
pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority);
|
||||
if (save_macro_priority) free(save_macro_priority);
|
||||
if (setmacrocontext) {
|
||||
chan->macrocontext[0] = '\0';
|
||||
chan->macroexten[0] = '\0';
|
||||
chan->macropriority = 0;
|
||||
}
|
||||
|
||||
if (!strcasecmp(chan->context, fullmacro)) {
|
||||
/* If we're leaving the macro normally, restore original information */
|
||||
chan->priority = oldpriority;
|
||||
strncpy(chan->context, oldcontext, sizeof(chan->context) - 1);
|
||||
if (!(chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO)) {
|
||||
/* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */
|
||||
strncpy(chan->exten, oldexten, sizeof(chan->exten) - 1);
|
||||
if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) {
|
||||
/* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue
|
||||
normally if there is any problem */
|
||||
if (sscanf(offsets, "%d", &offset) == 1) {
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + offset + 1, chan->callerid)) {
|
||||
chan->priority += offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset);
|
||||
if (save_macro_offset) free(save_macro_offset);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, macro_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
1575
apps/app_meetme.c
Normal file
1575
apps/app_meetme.c
Normal file
File diff suppressed because it is too large
Load Diff
148
apps/app_milliwatt.c
Normal file
148
apps/app_milliwatt.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Digital Milliwatt Test
|
||||
*
|
||||
* Copyright (C) 2002, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
static char *tdesc = "Digital Milliwatt (mu-law) Test Application";
|
||||
|
||||
static char *app = "Milliwatt";
|
||||
|
||||
static char *synopsis = "Generate a Constant 1000Hz tone at 0dbm (mu-law)";
|
||||
|
||||
static char *descrip =
|
||||
"Milliwatt(): Generate a Constant 1000Hz tone at 0dbm (mu-law)\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static char digital_milliwatt[] = {0x1e,0x0b,0x0b,0x1e,0x9e,0x8b,0x8b,0x9e} ;
|
||||
|
||||
static void *milliwatt_alloc(struct ast_channel *chan, void *params)
|
||||
{
|
||||
int *indexp;
|
||||
indexp = malloc(sizeof(int));
|
||||
if (indexp == NULL) return(NULL);
|
||||
*indexp = 0;
|
||||
return(indexp);
|
||||
}
|
||||
|
||||
static void milliwatt_release(struct ast_channel *chan, void *data)
|
||||
{
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
|
||||
static int milliwatt_generate(struct ast_channel *chan, void *data, int len, int samples)
|
||||
{
|
||||
struct ast_frame wf;
|
||||
unsigned char waste[AST_FRIENDLY_OFFSET];
|
||||
unsigned char buf[640];
|
||||
int i,*indexp = (int *) data;
|
||||
|
||||
if (len > sizeof(buf))
|
||||
{
|
||||
ast_log(LOG_WARNING,"Only doing %d bytes (%d bytes requested)\n",(int)sizeof(buf),len);
|
||||
len = sizeof(buf);
|
||||
}
|
||||
waste[0] = 0; /* make compiler happy */
|
||||
wf.frametype = AST_FRAME_VOICE;
|
||||
wf.subclass = AST_FORMAT_ULAW;
|
||||
wf.offset = AST_FRIENDLY_OFFSET;
|
||||
wf.mallocd = 0;
|
||||
wf.data = buf;
|
||||
wf.datalen = len;
|
||||
wf.samples = wf.datalen;
|
||||
wf.src = "app_milliwatt";
|
||||
wf.delivery.tv_sec = 0;
|
||||
wf.delivery.tv_usec = 0;
|
||||
/* create a buffer containing the digital milliwatt pattern */
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
buf[i] = digital_milliwatt[(*indexp)++];
|
||||
*indexp &= 7;
|
||||
}
|
||||
if (ast_write(chan,&wf) < 0)
|
||||
{
|
||||
ast_log(LOG_WARNING,"Failed to write frame to '%s': %s\n",chan->name,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ast_generator milliwattgen =
|
||||
{
|
||||
alloc: milliwatt_alloc,
|
||||
release: milliwatt_release,
|
||||
generate: milliwatt_generate,
|
||||
} ;
|
||||
|
||||
static int milliwatt_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
|
||||
struct localuser *u;
|
||||
LOCAL_USER_ADD(u);
|
||||
ast_set_write_format(chan, AST_FORMAT_ULAW);
|
||||
ast_set_read_format(chan, AST_FORMAT_ULAW);
|
||||
if (chan->_state != AST_STATE_UP)
|
||||
{
|
||||
ast_answer(chan);
|
||||
}
|
||||
if (ast_activate_generator(chan,&milliwattgen,"milliwatt") < 0)
|
||||
{
|
||||
ast_log(LOG_WARNING,"Failed to activate generator on '%s'\n",chan->name);
|
||||
return -1;
|
||||
}
|
||||
while(!ast_safe_sleep(chan, 10000));
|
||||
ast_deactivate_generator(chan);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, milliwatt_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
214
apps/app_mp3.c
Executable file → Normal file
214
apps/app_mp3.c
Executable file → Normal file
@@ -3,14 +3,15 @@
|
||||
*
|
||||
* Silly application to play an MP3 file -- uses mpg123
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
* Copyright (C) 1999-2004, Digium, Inc.
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
* Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
@@ -24,15 +25,22 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define LOCAL_MPG_123 "/usr/local/bin/mpg123"
|
||||
#define MPG_123 "/usr/bin/mpg123"
|
||||
|
||||
static char *tdesc = "Silly MP3 Application";
|
||||
|
||||
static char *app = "MP3Player";
|
||||
|
||||
static char *synopsis = "Play an MP3 file or stream";
|
||||
|
||||
static char *descrip =
|
||||
" MP3Player(location) Executes mpg123 to play the given location\n"
|
||||
"which typically would be a filename or a URL. Returns -1 on\n"
|
||||
"hangup or 0 otherwise. User can exit by pressing any key\n.";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
@@ -40,41 +48,69 @@ LOCAL_USER_DECL;
|
||||
static int mp3play(char *filename, int fd)
|
||||
{
|
||||
int res;
|
||||
int x;
|
||||
res = fork();
|
||||
if (res < 0)
|
||||
ast_log(LOG_WARNING, "Fork failed\n");
|
||||
if (res)
|
||||
return res;
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
for (x=0;x<256;x++) {
|
||||
if (x != STDOUT_FILENO)
|
||||
close(x);
|
||||
}
|
||||
/* Execute mpg123, but buffer if it's a net connection */
|
||||
if (strncmp(filename, "http://", 7))
|
||||
execl(MPG_123, MPG_123, "-q", "-s", "-b", "1024", "--mono", "-r", "8000", filename, NULL);
|
||||
else
|
||||
execl(MPG_123, MPG_123, "-q", "-s", "--mono", "-r", "8000", filename, NULL);
|
||||
if (!strncasecmp(filename, "http://", 7)) {
|
||||
/* Most commonly installed in /usr/local/bin */
|
||||
execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
|
||||
/* But many places has it in /usr/bin */
|
||||
execl(MPG_123, "mpg123", "-q", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
|
||||
/* As a last-ditch effort, try to use PATH */
|
||||
execlp("mpg123", "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
|
||||
}
|
||||
else {
|
||||
/* Most commonly installed in /usr/local/bin */
|
||||
execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
|
||||
/* But many places has it in /usr/bin */
|
||||
execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
|
||||
/* As a last-ditch effort, try to use PATH */
|
||||
execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
|
||||
}
|
||||
ast_log(LOG_WARNING, "Execute of mpg123 failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int timed_read(int fd, void *data, int datalen, int timeout)
|
||||
{
|
||||
int res;
|
||||
struct pollfd fds[1];
|
||||
fds[0].fd = fd;
|
||||
fds[0].events = POLLIN;
|
||||
res = poll(fds, 1, timeout);
|
||||
if (res < 1) {
|
||||
ast_log(LOG_NOTICE, "Poll timed out/errored out with %d\n", res);
|
||||
return -1;
|
||||
}
|
||||
return read(fd, data, datalen);
|
||||
|
||||
}
|
||||
|
||||
static int mp3_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
struct ast_channel *trans;
|
||||
int fds[2];
|
||||
int rfds[2];
|
||||
int ms = -1;
|
||||
int pid;
|
||||
int us;
|
||||
struct timeval tv;
|
||||
struct timeval last;
|
||||
int pid = -1;
|
||||
int owriteformat;
|
||||
int timeout = 2000;
|
||||
struct timeval now, next;
|
||||
struct ast_frame *f;
|
||||
struct myframe {
|
||||
struct ast_frame f;
|
||||
char offset[AST_FRIENDLY_OFFSET];
|
||||
char frdata[160];
|
||||
short frdata[160];
|
||||
} myf;
|
||||
last.tv_usec = 0;
|
||||
last.tv_sec = 0;
|
||||
if (!data) {
|
||||
ast_log(LOG_WARNING, "MP3 Playback requires an argument (filename)\n");
|
||||
return -1;
|
||||
@@ -85,28 +121,81 @@ static int mp3_exec(struct ast_channel *chan, void *data)
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
ast_stopstream(chan);
|
||||
if (chan->format & AST_FORMAT_SLINEAR)
|
||||
trans = chan;
|
||||
else
|
||||
trans = ast_translator_create(chan, AST_FORMAT_SLINEAR, AST_DIRECTION_OUT);
|
||||
if (trans) {
|
||||
res = mp3play((char *)data, fds[1]);
|
||||
if (res >= 0) {
|
||||
pid = res;
|
||||
/* Order is important -- there's almost always going to be mp3... we want to prioritize the
|
||||
user */
|
||||
rfds[0] = trans->fd;
|
||||
rfds[1] = fds[0];
|
||||
for (;;) {
|
||||
CHECK_BLOCKING(trans);
|
||||
res = ast_waitfor_n_fd(rfds, 2, &ms);
|
||||
trans->blocking = 0;
|
||||
if (res < 1) {
|
||||
|
||||
owriteformat = chan->writeformat;
|
||||
res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
res = mp3play((char *)data, fds[1]);
|
||||
if (!strncasecmp((char *)data, "http://", 7)) {
|
||||
timeout = 10000;
|
||||
}
|
||||
/* Wait 1000 ms first */
|
||||
next = now;
|
||||
next.tv_sec += 1;
|
||||
if (res >= 0) {
|
||||
pid = res;
|
||||
/* Order is important -- there's almost always going to be mp3... we want to prioritize the
|
||||
user */
|
||||
for (;;) {
|
||||
gettimeofday(&now, NULL);
|
||||
ms = (next.tv_sec - now.tv_sec) * 1000;
|
||||
ms += (next.tv_usec - now.tv_usec) / 1000;
|
||||
#if 0
|
||||
printf("ms: %d\n", ms);
|
||||
#endif
|
||||
if (ms <= 0) {
|
||||
#if 0
|
||||
{
|
||||
static struct timeval last;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
printf("Since last: %ld\n", (tv.tv_sec - last.tv_sec) * 1000 + (tv.tv_usec - last.tv_usec) / 1000);
|
||||
last = tv;
|
||||
}
|
||||
#endif
|
||||
res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata), timeout);
|
||||
if (res > 0) {
|
||||
myf.f.frametype = AST_FRAME_VOICE;
|
||||
myf.f.subclass = AST_FORMAT_SLINEAR;
|
||||
myf.f.datalen = res;
|
||||
myf.f.samples = res / 2;
|
||||
myf.f.mallocd = 0;
|
||||
myf.f.offset = AST_FRIENDLY_OFFSET;
|
||||
myf.f.src = __PRETTY_FUNCTION__;
|
||||
myf.f.delivery.tv_sec = 0;
|
||||
myf.f.delivery.tv_usec = 0;
|
||||
myf.f.data = myf.frdata;
|
||||
if (ast_write(chan, &myf.f) < 0) {
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_DEBUG, "No more mp3\n");
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
next.tv_usec += res / 2 * 125;
|
||||
if (next.tv_usec >= 1000000) {
|
||||
next.tv_usec -= 1000000;
|
||||
next.tv_sec++;
|
||||
}
|
||||
#if 0
|
||||
printf("Next: %d\n", ms);
|
||||
#endif
|
||||
} else {
|
||||
ms = ast_waitfor(chan, ms);
|
||||
if (ms < 0) {
|
||||
ast_log(LOG_DEBUG, "Hangup detected\n");
|
||||
res = -1;
|
||||
break;
|
||||
} else if (res == trans->fd) {
|
||||
f = ast_read(trans);
|
||||
}
|
||||
if (ms) {
|
||||
f = ast_read(chan);
|
||||
if (!f) {
|
||||
ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
|
||||
res = -1;
|
||||
@@ -119,53 +208,17 @@ static int mp3_exec(struct ast_channel *chan, void *data)
|
||||
break;
|
||||
}
|
||||
ast_frfree(f);
|
||||
} else if (res == fds[0]) {
|
||||
gettimeofday(&tv, NULL);
|
||||
if (last.tv_sec || last.tv_usec) {
|
||||
/* We should wait at least a frame length */
|
||||
us = sizeof(myf.frdata) / 16 * 1000;
|
||||
/* Subtract 1,000,000 us for each second late we've passed */
|
||||
us -= (tv.tv_sec - last.tv_sec) * 1000000;
|
||||
/* And one for each us late we've passed */
|
||||
us -= (tv.tv_usec - last.tv_usec);
|
||||
/* Sleep that long if needed */
|
||||
if (us > 0)
|
||||
usleep(us);
|
||||
}
|
||||
last = tv;
|
||||
res = read(fds[0], myf.frdata, sizeof(myf.frdata));
|
||||
if (res > 0) {
|
||||
myf.f.frametype = AST_FRAME_VOICE;
|
||||
myf.f.subclass = AST_FORMAT_SLINEAR;
|
||||
myf.f.datalen = res;
|
||||
myf.f.timelen = res / 16;
|
||||
myf.f.mallocd = 0;
|
||||
myf.f.offset = AST_FRIENDLY_OFFSET;
|
||||
myf.f.src = __PRETTY_FUNCTION__;
|
||||
myf.f.data = myf.frdata;
|
||||
if (ast_write(trans, &myf.f) < 0) {
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_DEBUG, "No more mp3\n");
|
||||
res = 0;
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_DEBUG, "HuhHHH?\n");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
kill(pid, SIGTERM);
|
||||
}
|
||||
if (trans != chan)
|
||||
ast_translator_destroy(trans);
|
||||
} else
|
||||
ast_log(LOG_WARNING, "No translator channel available\n");
|
||||
}
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
if (pid > -1)
|
||||
kill(pid, SIGKILL);
|
||||
if (!res && owriteformat)
|
||||
ast_set_write_format(chan, owriteformat);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -177,7 +230,7 @@ int unload_module(void)
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, mp3_exec);
|
||||
return ast_register_application(app, mp3_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
@@ -191,3 +244,8 @@ int usecount(void)
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
|
||||
229
apps/app_nbscat.c
Normal file
229
apps/app_nbscat.c
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Silly application to play an NBScat file -- uses nbscat8k
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/frame.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define LOCAL_NBSCAT "/usr/local/bin/nbscat8k"
|
||||
#define NBSCAT "/usr/bin/nbscat8k"
|
||||
|
||||
static char *tdesc = "Silly NBS Stream Application";
|
||||
|
||||
static char *app = "NBScat";
|
||||
|
||||
static char *synopsis = "Play an NBS local stream";
|
||||
|
||||
static char *descrip =
|
||||
" NBScat: Executes nbscat to listen to the local NBS stream.\n"
|
||||
"Returns -1 on\n hangup or 0 otherwise. User can exit by \n"
|
||||
"pressing any key\n.";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int NBScatplay(int fd)
|
||||
{
|
||||
int res;
|
||||
int x;
|
||||
res = fork();
|
||||
if (res < 0)
|
||||
ast_log(LOG_WARNING, "Fork failed\n");
|
||||
if (res)
|
||||
return res;
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
for (x=0;x<256;x++) {
|
||||
if (x != STDOUT_FILENO)
|
||||
close(x);
|
||||
}
|
||||
/* Most commonly installed in /usr/local/bin */
|
||||
execl(NBSCAT, "nbscat8k", "-d", (char *)NULL);
|
||||
execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL);
|
||||
ast_log(LOG_WARNING, "Execute of nbscat8k failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int timed_read(int fd, void *data, int datalen)
|
||||
{
|
||||
int res;
|
||||
struct pollfd fds[1];
|
||||
fds[0].fd = fd;
|
||||
fds[0].events = POLLIN;
|
||||
res = poll(fds, 1, 2000);
|
||||
if (res < 1) {
|
||||
ast_log(LOG_NOTICE, "Selected timed out/errored out with %d\n", res);
|
||||
return -1;
|
||||
}
|
||||
return read(fd, data, datalen);
|
||||
|
||||
}
|
||||
|
||||
static int NBScat_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
int fds[2];
|
||||
int ms = -1;
|
||||
int pid = -1;
|
||||
int owriteformat;
|
||||
struct timeval now, next;
|
||||
struct ast_frame *f;
|
||||
struct myframe {
|
||||
struct ast_frame f;
|
||||
char offset[AST_FRIENDLY_OFFSET];
|
||||
short frdata[160];
|
||||
} myf;
|
||||
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) {
|
||||
ast_log(LOG_WARNING, "Unable to create socketpair\n");
|
||||
return -1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
ast_stopstream(chan);
|
||||
|
||||
owriteformat = chan->writeformat;
|
||||
res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = NBScatplay(fds[1]);
|
||||
/* Wait 1000 ms first */
|
||||
next = now;
|
||||
next.tv_sec += 1;
|
||||
if (res >= 0) {
|
||||
pid = res;
|
||||
/* Order is important -- there's almost always going to be mp3... we want to prioritize the
|
||||
user */
|
||||
for (;;) {
|
||||
gettimeofday(&now, NULL);
|
||||
ms = (next.tv_sec - now.tv_sec) * 1000;
|
||||
ms += (next.tv_usec - now.tv_usec) / 1000;
|
||||
#if 0
|
||||
printf("ms: %d\n", ms);
|
||||
#endif
|
||||
if (ms <= 0) {
|
||||
#if 0
|
||||
{
|
||||
static struct timeval last;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
printf("Since last: %ld\n", (tv.tv_sec - last.tv_sec) * 1000 + (tv.tv_usec - last.tv_usec) / 1000);
|
||||
last = tv;
|
||||
}
|
||||
#endif
|
||||
res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata));
|
||||
if (res > 0) {
|
||||
myf.f.frametype = AST_FRAME_VOICE;
|
||||
myf.f.subclass = AST_FORMAT_SLINEAR;
|
||||
myf.f.datalen = res;
|
||||
myf.f.samples = res / 2;
|
||||
myf.f.mallocd = 0;
|
||||
myf.f.offset = AST_FRIENDLY_OFFSET;
|
||||
myf.f.src = __PRETTY_FUNCTION__;
|
||||
myf.f.delivery.tv_sec = 0;
|
||||
myf.f.delivery.tv_usec = 0;
|
||||
myf.f.data = myf.frdata;
|
||||
if (ast_write(chan, &myf.f) < 0) {
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_DEBUG, "No more mp3\n");
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
next.tv_usec += res / 2 * 125;
|
||||
if (next.tv_usec >= 1000000) {
|
||||
next.tv_usec -= 1000000;
|
||||
next.tv_sec++;
|
||||
}
|
||||
#if 0
|
||||
printf("Next: %d\n", ms);
|
||||
#endif
|
||||
} else {
|
||||
ms = ast_waitfor(chan, ms);
|
||||
if (ms < 0) {
|
||||
ast_log(LOG_DEBUG, "Hangup detected\n");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
if (ms) {
|
||||
f = ast_read(chan);
|
||||
if (!f) {
|
||||
ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
if (f->frametype == AST_FRAME_DTMF) {
|
||||
ast_log(LOG_DEBUG, "User pressed a key\n");
|
||||
ast_frfree(f);
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
ast_frfree(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
if (pid > -1)
|
||||
kill(pid, SIGKILL);
|
||||
if (!res && owriteformat)
|
||||
ast_set_write_format(chan, owriteformat);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, NBScat_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
277
apps/app_osplookup.c
Normal file
277
apps/app_osplookup.c
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Time of day - Report the time of day
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <asterisk/causes.h>
|
||||
#include <asterisk/astosp.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static char *tdesc = "OSP Lookup";
|
||||
|
||||
static char *app = "OSPLookup";
|
||||
static char *app2 = "OSPNext";
|
||||
static char *app3 = "OSPFinish";
|
||||
|
||||
static char *synopsis = "Lookup number in OSP";
|
||||
static char *synopsis2 = "Lookup next OSP entry";
|
||||
static char *synopsis3 = "Record OSP entry";
|
||||
|
||||
static char *descrip =
|
||||
" OSPLookup(exten[|provider[|options]]): Looks up an extension via OSP and sets\n"
|
||||
"the variables, where 'n' is the number of the result beginning with 1:\n"
|
||||
" ${OSPTECH}: The technology to use for the call\n"
|
||||
" ${OSPDEST}: The destination to use for the call\n"
|
||||
" ${OSPTOKEN}: The actual OSP token as a string\n"
|
||||
" ${OSPHANDLE}: The OSP Handle for anything remaining\n"
|
||||
" ${OSPRESULTS}: The number of OSP results total remaining\n"
|
||||
"\n"
|
||||
"If the lookup was *not* successful and there exists a priority n + 101,\n"
|
||||
"then that priority will be taken next.\n" ;
|
||||
|
||||
static char *descrip2 =
|
||||
" OSPNext: Looks up the next OSP Destination for ${OSPHANDLE}\n"
|
||||
"See OSPLookup for more information\n"
|
||||
"\n"
|
||||
"If the lookup was *not* successful and there exists a priority n + 101,\n"
|
||||
"then that priority will be taken next.\n" ;
|
||||
|
||||
static char *descrip3 =
|
||||
" OSPFinish(status): Records call state for ${OSPHANDLE}, according to\n"
|
||||
"status, which should be one of BUSY, CONGESTION, ANSWER, NOANSWER, or NOCHANAVAIL\n"
|
||||
"or coincidentally, just what the Dial application stores in its ${DIALSTATUS}\n"
|
||||
"\n"
|
||||
"If the finishing was *not* successful and there exists a priority n + 101,\n"
|
||||
"then that priority will be taken next.\n" ;
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int str2cause(char *cause)
|
||||
{
|
||||
if (!strcasecmp(cause, "BUSY"))
|
||||
return AST_CAUSE_BUSY;
|
||||
if (!strcasecmp(cause, "CONGESTION"))
|
||||
return AST_CAUSE_CONGESTION;
|
||||
if (!strcasecmp(cause, "ANSWER"))
|
||||
return AST_CAUSE_NORMAL;
|
||||
if (!strcasecmp(cause, "CANCEL"))
|
||||
return AST_CAUSE_NORMAL;
|
||||
if (!strcasecmp(cause, "NOANSWER"))
|
||||
return AST_CAUSE_NOANSWER;
|
||||
if (!strcasecmp(cause, "NOCHANAVAIL"))
|
||||
return AST_CAUSE_CONGESTION;
|
||||
ast_log(LOG_WARNING, "Unknown cause '%s', using NORMAL\n", cause);
|
||||
return AST_CAUSE_NORMAL;
|
||||
}
|
||||
|
||||
static int osplookup_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
char *temp;
|
||||
char *provider, *opts=NULL;
|
||||
struct ast_osp_result result;
|
||||
if (!data || ast_strlen_zero(data) || !(temp = ast_strdupa(data))) {
|
||||
ast_log(LOG_WARNING, "OSPLookup requires an argument (extension)\n");
|
||||
return -1;
|
||||
}
|
||||
provider = strchr(temp, '|');
|
||||
if (provider) {
|
||||
*provider = '\0';
|
||||
provider++;
|
||||
opts = strchr(provider, '|');
|
||||
if (opts) {
|
||||
*opts = '\0';
|
||||
opts++;
|
||||
}
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
ast_log(LOG_DEBUG, "Whoo hoo, looking up OSP on '%s' via '%s'\n", temp, provider ? provider : "<default>");
|
||||
if ((res = ast_osp_lookup(chan, provider, temp, chan->callerid, &result)) > 0) {
|
||||
char tmp[80];
|
||||
snprintf(tmp, sizeof(tmp), "%d", result.handle);
|
||||
pbx_builtin_setvar_helper(chan, "OSPHANDLE", tmp);
|
||||
pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
|
||||
pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
|
||||
pbx_builtin_setvar_helper(chan, "OSPTOKEN", result.token);
|
||||
snprintf(tmp, sizeof(tmp), "%d", result.numresults);
|
||||
pbx_builtin_setvar_helper(chan, "OSPRESULTS", tmp);
|
||||
} else {
|
||||
if (!res)
|
||||
ast_log(LOG_NOTICE, "OSP Lookup failed for '%s' (provider '%s')\n", temp, provider ? provider : "<default>");
|
||||
else
|
||||
ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Lookup for '%s' (provider '%s')!\n", chan->name, temp, provider ? provider : "<default>" );
|
||||
}
|
||||
if (!res) {
|
||||
/* Look for a "busy" place */
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority += 100;
|
||||
} else if (res > 0)
|
||||
res = 0;
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int ospnext_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
char *temp;
|
||||
int cause;
|
||||
struct ast_osp_result result;
|
||||
if (!data || ast_strlen_zero(data)) {
|
||||
ast_log(LOG_WARNING, "OSPNext should have an argument (cause)\n");
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
cause = str2cause((char *)data);
|
||||
temp = pbx_builtin_getvar_helper(chan, "OSPHANDLE");
|
||||
result.handle = -1;
|
||||
if (temp && strlen(temp) && (sscanf(temp, "%i", &result.handle) == 1) && (result.handle > -1)) {
|
||||
if ((res = ast_osp_next(&result, cause)) > 0) {
|
||||
char tmp[80];
|
||||
snprintf(tmp, sizeof(tmp), "%d", result.handle);
|
||||
pbx_builtin_setvar_helper(chan, "OSPHANDLE", tmp);
|
||||
pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
|
||||
pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
|
||||
pbx_builtin_setvar_helper(chan, "OSPTOKEN", result.token);
|
||||
snprintf(tmp, sizeof(tmp), "%d", result.numresults);
|
||||
pbx_builtin_setvar_helper(chan, "OSPRESULTS", tmp);
|
||||
}
|
||||
} else {
|
||||
if (!res) {
|
||||
if (result.handle < 0)
|
||||
ast_log(LOG_NOTICE, "OSP Lookup Next failed for handle '%d'\n", result.handle);
|
||||
else
|
||||
ast_log(LOG_DEBUG, "No OSP handle specified\n");
|
||||
} else
|
||||
ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Next!\n", chan->name);
|
||||
}
|
||||
if (!res) {
|
||||
/* Look for a "busy" place */
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority += 100;
|
||||
} else if (res > 0)
|
||||
res = 0;
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int ospfinished_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
char *temp;
|
||||
int cause;
|
||||
time_t start=0, duration=0;
|
||||
struct ast_osp_result result;
|
||||
if (!data || ast_strlen_zero(data)) {
|
||||
ast_log(LOG_WARNING, "OSPFinish should have an argument (cause)\n");
|
||||
}
|
||||
if (chan->cdr) {
|
||||
start = chan->cdr->answer.tv_sec;
|
||||
if (start)
|
||||
duration = time(NULL) - start;
|
||||
else
|
||||
duration = 0;
|
||||
} else
|
||||
ast_log(LOG_WARNING, "OSPFinish called on channel '%s' with no CDR!\n", chan->name);
|
||||
LOCAL_USER_ADD(u);
|
||||
cause = str2cause((char *)data);
|
||||
temp = pbx_builtin_getvar_helper(chan, "OSPHANDLE");
|
||||
result.handle = -1;
|
||||
if (temp && strlen(temp) && (sscanf(temp, "%i", &result.handle) == 1) && (result.handle > -1)) {
|
||||
if (!ast_osp_terminate(result.handle, cause, start, duration)) {
|
||||
pbx_builtin_setvar_helper(chan, "OSPHANDLE", "");
|
||||
res = 1;
|
||||
}
|
||||
} else {
|
||||
if (!res) {
|
||||
if (result.handle > -1)
|
||||
ast_log(LOG_NOTICE, "OSP Finish failed for handle '%d'\n", result.handle);
|
||||
else
|
||||
ast_log(LOG_DEBUG, "No OSP handle specified\n");
|
||||
} else
|
||||
ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Terminate!\n", chan->name);
|
||||
}
|
||||
if (!res) {
|
||||
/* Look for a "busy" place */
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority += 100;
|
||||
} else if (res > 0)
|
||||
res = 0;
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
res = ast_unregister_application(app3);
|
||||
res |= ast_unregister_application(app2);
|
||||
res |= ast_unregister_application(app);
|
||||
return res;
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
int res;
|
||||
res = ast_register_application(app, osplookup_exec, synopsis, descrip);
|
||||
if (res)
|
||||
return(res);
|
||||
res = ast_register_application(app2, ospnext_exec, synopsis2, descrip2);
|
||||
if (res)
|
||||
return(res);
|
||||
res = ast_register_application(app3, ospfinished_exec, synopsis3, descrip3);
|
||||
if (res)
|
||||
return(res);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int reload(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
|
||||
253
apps/app_parkandannounce.c
Normal file
253
apps/app_parkandannounce.c
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* ParkAndAnnounce application for Asterisk
|
||||
* Author: Ben Miller <bgmiller@dccinc.com>
|
||||
* With TONS of help from Mark!
|
||||
*
|
||||
* Asterisk is Copyrighted as follows
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/features.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/say.h>
|
||||
#include <asterisk/lock.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Call Parking and Announce Application";
|
||||
|
||||
static char *app = "ParkAndAnnounce";
|
||||
|
||||
static char *synopsis = "Park and Announce";
|
||||
|
||||
static char *descrip =
|
||||
" ParkAndAnnounce(announce:template|timeout|dial|[return_context]):\n"
|
||||
"Park a call into the parkinglot and announce the call over the console.\n"
|
||||
"announce template: colon separated list of files to announce, the word PARKED\n"
|
||||
" will be replaced by a say_digits of the ext the call is parked in\n"
|
||||
"timeout: time in seconds before the call returns into the return context.\n"
|
||||
"dial: The app_dial style resource to call to make the announcement. Console/dsp calls the console.\n"
|
||||
"return_context: the goto style label to jump the call back into after timeout. default=prio+1\n";
|
||||
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int parkandannounce_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
char *return_context;
|
||||
int l, lot, timeout = 0, dres;
|
||||
char *working, *context, *exten, *priority, *dial, *dialtech, *dialstr;
|
||||
char *template, *tpl_working, *tpl_current;
|
||||
char *tmp[100];
|
||||
int looptemp=0,i=0;
|
||||
char *s,*orig_s;
|
||||
|
||||
struct ast_channel *dchan;
|
||||
int outstate;
|
||||
|
||||
struct localuser *u;
|
||||
if(!data || (data && !strlen(data))) {
|
||||
ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce:template|timeout|dial|[return_context])\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
l=strlen(data)+2;
|
||||
orig_s=malloc(l);
|
||||
if(!orig_s) {
|
||||
ast_log(LOG_WARNING, "Out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
s=orig_s;
|
||||
strncpy(s,data,l);
|
||||
|
||||
template=strsep(&s,"|");
|
||||
if(! template) {
|
||||
ast_log(LOG_WARNING, "PARK: An announce template must be defined\n");
|
||||
free(orig_s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(s) {
|
||||
timeout = atoi(strsep(&s, "|"));
|
||||
timeout *= 1000;
|
||||
}
|
||||
dial=strsep(&s, "|");
|
||||
if(!dial) {
|
||||
ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or Zap/g1/5551212\n");
|
||||
free(orig_s);
|
||||
return -1;
|
||||
} else {
|
||||
dialtech=strsep(&dial, "/");
|
||||
dialstr=dial;
|
||||
ast_verbose( VERBOSE_PREFIX_3 "Dial Tech,String: (%s,%s)\n", dialtech,dialstr);
|
||||
}
|
||||
|
||||
return_context = s;
|
||||
|
||||
if(return_context != NULL) {
|
||||
/* set the return context. Code borrowed from the Goto builtin */
|
||||
|
||||
working = return_context;
|
||||
context = strsep(&working, "|");
|
||||
exten = strsep(&working, "|");
|
||||
if(!exten) {
|
||||
/* Only a priority in this one */
|
||||
priority = context;
|
||||
exten = NULL;
|
||||
context = NULL;
|
||||
} else {
|
||||
priority = strsep(&working, "|");
|
||||
if(!priority) {
|
||||
/* Only an extension and priority in this one */
|
||||
priority = exten;
|
||||
exten = context;
|
||||
context = NULL;
|
||||
}
|
||||
}
|
||||
if(atoi(priority) < 0) {
|
||||
ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority);
|
||||
free(orig_s);
|
||||
return -1;
|
||||
}
|
||||
/* At this point we have a priority and maybe an extension and a context */
|
||||
chan->priority = atoi(priority);
|
||||
if(exten && strcasecmp(exten, "BYEXTENSION"))
|
||||
strncpy(chan->exten, exten, sizeof(chan->exten)-1);
|
||||
if(context)
|
||||
strncpy(chan->context, context, sizeof(chan->context)-1);
|
||||
} else { /* increment the priority by default*/
|
||||
chan->priority++;
|
||||
}
|
||||
|
||||
|
||||
if(option_verbose > 2) {
|
||||
ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->callerid);
|
||||
if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->callerid)) {
|
||||
ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n");
|
||||
}
|
||||
}
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
/* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout
|
||||
before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */
|
||||
|
||||
ast_masq_park_call(chan, NULL, timeout, &lot);
|
||||
|
||||
res=-1;
|
||||
|
||||
ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context);
|
||||
|
||||
/* Now place the call to the extention */
|
||||
|
||||
dchan = ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, dialstr,30000, &outstate, chan->callerid);
|
||||
|
||||
if(dchan) {
|
||||
if(dchan->_state == AST_STATE_UP) {
|
||||
if(option_verbose > 3)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", dchan->name);
|
||||
} else {
|
||||
if(option_verbose > 3)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", dchan->name);
|
||||
ast_log(LOG_WARNING, "PARK: Channel %s was never answered for the announce.\n", dchan->name);
|
||||
ast_hangup(dchan);
|
||||
free(orig_s);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
|
||||
free(orig_s);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ast_stopstream(dchan);
|
||||
|
||||
/* now we have the call placed and are ready to play stuff to it */
|
||||
|
||||
ast_verbose(VERBOSE_PREFIX_4 "Announce Template:%s\n", template);
|
||||
|
||||
tpl_working = template;
|
||||
tpl_current=strsep(&tpl_working, ":");
|
||||
|
||||
while(tpl_current && looptemp < sizeof(tmp)) {
|
||||
tmp[looptemp]=tpl_current;
|
||||
looptemp++;
|
||||
tpl_current=strsep(&tpl_working,":");
|
||||
}
|
||||
|
||||
for(i=0; i<looptemp; i++) {
|
||||
ast_verbose(VERBOSE_PREFIX_4 "Announce:%s\n", tmp[i]);
|
||||
if(!strcmp(tmp[i], "PARKED")) {
|
||||
ast_say_digits(dchan, lot, "", dchan->language);
|
||||
} else {
|
||||
dres = ast_streamfile(dchan, tmp[i], dchan->language);
|
||||
if(!dres) {
|
||||
dres = ast_waitstream(dchan, "");
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], dchan->name);
|
||||
dres = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ast_stopstream(dchan);
|
||||
ast_hangup(dchan);
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
free(orig_s);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
/* return ast_register_application(app, park_exec); */
|
||||
return ast_register_application(app, parkandannounce_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
57
apps/app_playback.c
Executable file → Normal file
57
apps/app_playback.c
Executable file → Normal file
@@ -11,20 +11,34 @@
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
static char *tdesc = "Trivial Playback Application";
|
||||
|
||||
static char *app = "Playback";
|
||||
|
||||
static char *synopsis = "Play a file";
|
||||
|
||||
static char *descrip =
|
||||
" Playback(filename[|option]): Plays back a given filename (do not put\n"
|
||||
"extension). Options may also be included following a pipe symbol. The 'skip'\n"
|
||||
"option causes the playback of the message to be skipped if the channel\n"
|
||||
"is not in the 'up' state (i.e. it hasn't been answered yet. If 'skip' is \n"
|
||||
"specified, the application will return immediately should the channel not be\n"
|
||||
"off hook. Otherwise, unless 'noanswer' is specified, the channel channel will\n"
|
||||
"be answered before the sound is played. Not all channels support playing\n"
|
||||
"messages while still hook. Returns -1 if the channel was hung up, or if the\n"
|
||||
"file does not exist. Returns 0 otherwise.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
@@ -33,18 +47,42 @@ static int playback_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
struct localuser *u;
|
||||
if (!data) {
|
||||
char tmp[256];
|
||||
char *options;
|
||||
int option_skip=0;
|
||||
int option_noanswer = 0;
|
||||
char *stringp;
|
||||
if (!data || ast_strlen_zero((char *)data)) {
|
||||
ast_log(LOG_WARNING, "Playback requires an argument (filename)\n");
|
||||
return -1;
|
||||
}
|
||||
strncpy(tmp, (char *)data, sizeof(tmp)-1);
|
||||
stringp=tmp;
|
||||
strsep(&stringp, "|");
|
||||
options = strsep(&stringp, "|");
|
||||
if (options && !strcasecmp(options, "skip"))
|
||||
option_skip = 1;
|
||||
if (options && !strcasecmp(options, "noanswer"))
|
||||
option_noanswer = 1;
|
||||
LOCAL_USER_ADD(u);
|
||||
if (chan->state != AST_STATE_UP)
|
||||
res = ast_answer(chan);
|
||||
if (chan->_state != AST_STATE_UP) {
|
||||
if (option_skip) {
|
||||
/* At the user's option, skip if the line is not up */
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return 0;
|
||||
} else if (!option_noanswer)
|
||||
/* Otherwise answer unless we're supposed to send this while on-hook */
|
||||
res = ast_answer(chan);
|
||||
}
|
||||
if (!res) {
|
||||
ast_stopstream(chan);
|
||||
res = ast_streamfile(chan, (char *)data, chan->language);
|
||||
if (!res)
|
||||
res = ast_streamfile(chan, tmp, chan->language);
|
||||
if (!res)
|
||||
res = ast_waitstream(chan, "");
|
||||
else {
|
||||
ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
|
||||
res = 0;
|
||||
}
|
||||
ast_stopstream(chan);
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
@@ -59,7 +97,7 @@ int unload_module(void)
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, playback_exec);
|
||||
return ast_register_application(app, playback_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
@@ -73,3 +111,8 @@ int usecount(void)
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
|
||||
170
apps/app_privacy.c
Normal file
170
apps/app_privacy.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Block all calls without Caller*ID, require phone # to be entered
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/image.h>
|
||||
#include <asterisk/callerid.h>
|
||||
#include <asterisk/app.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define PRIV_CONFIG "privacy.conf"
|
||||
|
||||
static char *tdesc = "Require phone number to be entered, if no CallerID sent";
|
||||
|
||||
static char *app = "PrivacyManager";
|
||||
|
||||
static char *synopsis = "Require phone number to be entered, if no CallerID sent";
|
||||
|
||||
static char *descrip =
|
||||
" PrivacyManager: If no Caller*ID is sent, PrivacyManager answers the\n"
|
||||
"channel and asks the caller to enter their 10 digit phone number.\n"
|
||||
"The caller is given 3 attempts. If after 3 attempts, they do not enter\n"
|
||||
"their 10 digit phone number, and if there exists a priority n + 101,\n"
|
||||
"where 'n' is the priority of the current instance, then the\n"
|
||||
"channel will be setup to continue at that priority level.\n"
|
||||
"Otherwise, it returns 0. Does nothing if Caller*ID was received on the\n"
|
||||
"channel.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int
|
||||
privacy_exec (struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
int retries;
|
||||
int maxretries = 3;
|
||||
int x;
|
||||
char *s;
|
||||
char phone[10];
|
||||
char new_cid[144];
|
||||
struct localuser *u;
|
||||
struct ast_config *cfg;
|
||||
|
||||
LOCAL_USER_ADD (u);
|
||||
if (chan->callerid)
|
||||
{
|
||||
if (option_verbose > 2)
|
||||
ast_verbose (VERBOSE_PREFIX_3 "CallerID Present: Skipping\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Answer the channel if it is not already*/
|
||||
if (chan->_state != AST_STATE_UP) {
|
||||
res = ast_answer(chan);
|
||||
if (res) {
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/*Read in the config file*/
|
||||
cfg = ast_load(PRIV_CONFIG);
|
||||
|
||||
|
||||
/*Play unidentified call*/
|
||||
res = ast_safe_sleep(chan, 1000);
|
||||
if (!res)
|
||||
res = ast_streamfile(chan, "privacy-unident", chan->language);
|
||||
if (!res)
|
||||
res = ast_waitstream(chan, "");
|
||||
|
||||
if (cfg && (s = ast_variable_retrieve(cfg, "general", "maxretries"))) {
|
||||
if (sscanf(s, "%d", &x) == 1) {
|
||||
maxretries = x;
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Invalid max retries argument\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*Ask for 10 digit number, give 3 attempts*/
|
||||
for (retries = 0; retries < maxretries; retries++) {
|
||||
if (!res)
|
||||
res = ast_app_getdata(chan, "privacy-prompt", phone, sizeof(phone), 0);
|
||||
if (res < 0)
|
||||
break;
|
||||
|
||||
/*Make sure we get 10 digits*/
|
||||
if (strlen(phone) == 10)
|
||||
break;
|
||||
else {
|
||||
res = ast_streamfile(chan, "privacy-incorrect", chan->language);
|
||||
if (!res)
|
||||
res = ast_waitstream(chan, "");
|
||||
}
|
||||
}
|
||||
|
||||
/*Got a number, play sounds and send them on their way*/
|
||||
if ((retries < maxretries) && !res) {
|
||||
res = ast_streamfile(chan, "privacy-thankyou", chan->language);
|
||||
if (!res)
|
||||
res = ast_waitstream(chan, "");
|
||||
snprintf (new_cid, sizeof (new_cid), "\"%s\" <%s>", "Privacy Manager", phone);
|
||||
ast_set_callerid (chan, new_cid, 0);
|
||||
if (option_verbose > 2)
|
||||
ast_verbose (VERBOSE_PREFIX_3 "Changed Caller*ID to %s\n",new_cid);
|
||||
} else {
|
||||
/*Send the call to n+101 priority, where n is the current priority*/
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority+=100;
|
||||
}
|
||||
if (cfg)
|
||||
ast_destroy(cfg);
|
||||
}
|
||||
|
||||
LOCAL_USER_REMOVE (u);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
unload_module (void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application (app);
|
||||
}
|
||||
|
||||
int
|
||||
load_module (void)
|
||||
{
|
||||
return ast_register_application (app, privacy_exec, synopsis,
|
||||
descrip);
|
||||
}
|
||||
|
||||
char *
|
||||
description (void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int
|
||||
usecount (void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT (res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *
|
||||
key ()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
394
apps/app_qcall.c
Normal file
394
apps/app_qcall.c
Normal file
@@ -0,0 +1,394 @@
|
||||
/** @file app_qcall.c
|
||||
*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Call back a party and connect them to a running pbx thread
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*
|
||||
* Call a user from a file contained within a queue (/var/spool/asterisk/qcall)
|
||||
*
|
||||
* The queue is a directory containing files with the call request information
|
||||
* as a single line of text as follows:
|
||||
*
|
||||
* Dialstring Caller-ID Extension Maxsecs [Identifier] [Required-response]
|
||||
*
|
||||
* Dialstring -- A Dial String (The number to be called) in the
|
||||
* format Technology/Number, such IAX/mysys/1234 or Zap/g1/1234
|
||||
*
|
||||
* Caller-ID -- A Standard nomalized representation of the Caller-ID of
|
||||
* the number being dialed (generally 10 digits in the US). Leave as
|
||||
* "asreceived" to use the default Caller*ID
|
||||
*
|
||||
* Extension -- The Extension (optionally Extension@context) that the
|
||||
* user should be "transferred" to after acceptance of the call.
|
||||
*
|
||||
* Maxsecs -- The Maximum time of the call in seconds. Specify 0 for infinite.
|
||||
*
|
||||
* Identifier -- The "Identifier" of the request. This is used to determine
|
||||
* the names of the audio prompt files played. The first prompt, the one that
|
||||
* asks for the input, is just the exact string specified as the identifier.
|
||||
* The second prompt, the one that is played after the correct input is given,
|
||||
* (generally a "thank you" recording), is the specified string with "-ok"
|
||||
* added to the end. So, if you specify "foo" as the identifier, your first
|
||||
* prompt file that will be played will be "foo" and the second one will be
|
||||
* "foo-ok". If omitted no prompt is given
|
||||
*
|
||||
* Required-Response (Optional) -- Specify a digit string to be used as the
|
||||
* acceptance "code" if you desire it to be something other then "1". This
|
||||
* can be used to implement some sort of PIN or security system. It may be
|
||||
* more then a single character.
|
||||
*
|
||||
* NOTE: It is important to remember that the process that creates these
|
||||
* files needs keep and maintain a write lock (using flock with the LOCK_EX
|
||||
* option) when writing these files.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/file.h>
|
||||
#include "../astconf.h"
|
||||
|
||||
static char qdir[255];
|
||||
static char *tdesc = "Call from Queue";
|
||||
static pthread_t qcall_thread;
|
||||
static int debug = 0;
|
||||
STANDARD_LOCAL_USER;
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
#define OLDESTOK 14400 /* not any more then this number of secs old */
|
||||
#define INITIALONE 1 /* initial wait before the first one in secs */
|
||||
#define NEXTONE 600 /* wait before trying it again in secs */
|
||||
#define MAXWAITFORANSWER 45000 /* max call time before answer */
|
||||
/* define either one or both of these two if your application requires it */
|
||||
#if 0
|
||||
#define ACCTCODE "SOMETHING" /* Account code */
|
||||
#define AMAFLAGS AST_CDR_BILLING /* AMA flags */
|
||||
#endif
|
||||
/* define this if you want to have a particular CLID display on the user's
|
||||
phone when they receive the call */
|
||||
#if 0
|
||||
#define OURCLID "2564286275" /* The callerid to be displayed when calling */
|
||||
#endif
|
||||
|
||||
static void *qcall_do(void *arg);
|
||||
|
||||
static void *qcall(void *ignore)
|
||||
{
|
||||
pthread_t dialer_thread;
|
||||
DIR *dirp;
|
||||
FILE *fp;
|
||||
struct dirent *dp;
|
||||
char fname[80];
|
||||
struct stat mystat;
|
||||
time_t t;
|
||||
void *arg;
|
||||
pthread_attr_t attr;
|
||||
|
||||
time(&t);
|
||||
if (debug) printf("@@@@ qcall starting at %s",ctime(&t));
|
||||
for(;;)
|
||||
{
|
||||
time(&t);
|
||||
dirp = opendir(qdir);
|
||||
if (!dirp)
|
||||
{
|
||||
perror("app_qcall:Cannot open queue directory");
|
||||
break;
|
||||
}
|
||||
while((dp = readdir(dirp)) != NULL)
|
||||
{
|
||||
if (dp->d_name[0] == '.') continue;
|
||||
snprintf(fname, sizeof(fname), "%s/%s", qdir, dp->d_name);
|
||||
if (stat(fname,&mystat) == -1)
|
||||
{
|
||||
perror("app_qcall:stat");
|
||||
fprintf(stderr,"%s\n",fname);
|
||||
continue;
|
||||
}
|
||||
/* if not a regular file, skip it */
|
||||
if ((mystat.st_mode & S_IFMT) != S_IFREG) continue;
|
||||
/* if not yet .... */
|
||||
if (mystat.st_atime == mystat.st_mtime)
|
||||
{ /* first time */
|
||||
if ((mystat.st_atime + INITIALONE) > t)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{ /* already looked at once */
|
||||
if ((mystat.st_atime + NEXTONE) > t) continue;
|
||||
}
|
||||
/* if too old */
|
||||
if (mystat.st_mtime < (t - OLDESTOK))
|
||||
{
|
||||
/* kill it, its too old */
|
||||
unlink(fname);
|
||||
continue;
|
||||
}
|
||||
/* "touch" file's access time */
|
||||
fp = fopen(fname,"r");
|
||||
if (fp) fclose(fp);
|
||||
/* make a copy of the filename string, so that we
|
||||
may go on and use the buffer */
|
||||
arg = (void *) strdup(fname);
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
if (ast_pthread_create(&dialer_thread,&attr,qcall_do,arg) == -1)
|
||||
{
|
||||
perror("qcall: Cannot create thread");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
sleep(1);
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
/* single thread with one file (request) to dial */
|
||||
static void *qcall_do(void *arg)
|
||||
{
|
||||
char fname[300] = "";
|
||||
char dialstr[300];
|
||||
char extstr[300];
|
||||
char ident[300] = "";
|
||||
char reqinp[300] = "";
|
||||
char buf[300];
|
||||
char clid[300],*tele,*context;
|
||||
FILE *fp;
|
||||
int ms = MAXWAITFORANSWER,maxsecs;
|
||||
struct ast_channel *channel;
|
||||
time_t t;
|
||||
|
||||
/* get the filename from the arg */
|
||||
strncpy(fname,(char *)arg, sizeof(fname) - 1);
|
||||
free(arg);
|
||||
time(&t);
|
||||
fp = fopen(fname,"r");
|
||||
if (!fp) /* if cannot open request file */
|
||||
{
|
||||
perror("qcall_do:fopen");
|
||||
fprintf(stderr,"%s\n",fname);
|
||||
unlink(fname);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
/* lock the file */
|
||||
if (flock(fileno(fp),LOCK_EX) == -1)
|
||||
{
|
||||
perror("qcall_do:flock");
|
||||
fprintf(stderr,"%s\n",fname);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
/* default required input for acknowledgement */
|
||||
reqinp[0] = '1';
|
||||
reqinp[1] = '\0';
|
||||
/* default no ident */
|
||||
ident[0] = '\0'; /* default no ident */
|
||||
if (fscanf(fp,"%s %s %s %d %s %s",dialstr,clid,
|
||||
extstr,&maxsecs,ident,reqinp) < 4)
|
||||
{
|
||||
fprintf(stderr,"qcall_do:file line invalid in file %s:\n",fname);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
flock(fileno(fp),LOCK_UN);
|
||||
fclose(fp);
|
||||
tele = strchr(dialstr,'/');
|
||||
if (!tele)
|
||||
{
|
||||
fprintf(stderr,"qcall_do:Dial number must be in format tech/number\n");
|
||||
unlink(fname);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
*tele++ = 0;
|
||||
channel = ast_request(dialstr,AST_FORMAT_SLINEAR,tele);
|
||||
if (channel)
|
||||
{
|
||||
ast_set_read_format(channel,AST_FORMAT_SLINEAR);
|
||||
ast_set_write_format(channel,AST_FORMAT_SLINEAR);
|
||||
#ifdef OURCLID
|
||||
if (channel->callerid)
|
||||
free(channel->callerid);
|
||||
channel->callerid = strdup(OURCLID);
|
||||
if (channel->ani)
|
||||
free(channel->ani);
|
||||
channel->ani = strdup(OURCLID);
|
||||
#endif
|
||||
channel->whentohangup = 0;
|
||||
channel->appl = "AppQcall";
|
||||
channel->data = "(Outgoing Line)";
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Qcall initiating call to %s/%s on %s (%s)\n",
|
||||
dialstr,tele,channel->name,fname);
|
||||
ast_call(channel,tele,MAXWAITFORANSWER);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"qcall_do:Sorry unable to obtain channel\n");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
if (strcasecmp(clid, "asreceived")) {
|
||||
if (channel->callerid) free(channel->callerid);
|
||||
channel->callerid = NULL;
|
||||
if (channel->ani) free(channel->ani);
|
||||
channel->ani = NULL;
|
||||
}
|
||||
if (channel->_state == AST_STATE_UP)
|
||||
if (debug) printf("@@@@ Autodial:Line is Up\n");
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Qcall waiting for answer on %s\n",
|
||||
channel->name);
|
||||
while(ms > 0){
|
||||
struct ast_frame *f;
|
||||
ms = ast_waitfor(channel,ms);
|
||||
f = ast_read(channel);
|
||||
if (!f)
|
||||
{
|
||||
if (debug) printf("@@@@ qcall_do:Hung Up\n");
|
||||
unlink(fname);
|
||||
break;
|
||||
}
|
||||
if (f->frametype == AST_FRAME_CONTROL)
|
||||
{
|
||||
if (f->subclass == AST_CONTROL_HANGUP)
|
||||
{
|
||||
if (debug) printf("@@@@ qcall_do:Hung Up\n");
|
||||
unlink(fname);
|
||||
ast_frfree(f);
|
||||
break;
|
||||
}
|
||||
if (f->subclass == AST_CONTROL_ANSWER)
|
||||
{
|
||||
if (debug) printf("@@@@ qcall_do:Phone Answered\n");
|
||||
if (channel->_state == AST_STATE_UP)
|
||||
{
|
||||
unlink(fname);
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Qcall got answer on %s\n",
|
||||
channel->name);
|
||||
usleep(1500000);
|
||||
if (strlen(ident)) {
|
||||
ast_streamfile(channel,ident,0);
|
||||
if (ast_readstring(channel,buf,strlen(reqinp),10000,5000,"#"))
|
||||
{
|
||||
ast_stopstream(channel);
|
||||
if (debug) printf("@@@@ qcall_do: timeout or hangup in dtmf read\n");
|
||||
ast_frfree(f);
|
||||
break;
|
||||
}
|
||||
ast_stopstream(channel);
|
||||
if (strcmp(buf,reqinp)) /* if not match */
|
||||
{
|
||||
if (debug) printf("@@@@ qcall_do: response (%s) does not match required (%s)\n",buf,reqinp);
|
||||
ast_frfree(f);
|
||||
break;
|
||||
}
|
||||
ast_frfree(f);
|
||||
}
|
||||
/* okay, now we go for it */
|
||||
context = strchr(extstr,'@');
|
||||
if (!context) context = "default";
|
||||
else *context++ = 0;
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Qcall got accept, now putting through to %s@%s on %s\n",
|
||||
extstr,context,channel->name);
|
||||
if (strlen(ident)) {
|
||||
strncat(ident,"-ok", sizeof(ident) - strlen(ident) - 1);
|
||||
/* if file existent, play it */
|
||||
if (!ast_streamfile(channel,ident,0))
|
||||
{
|
||||
ast_waitstream(channel,"");
|
||||
ast_stopstream(channel);
|
||||
}
|
||||
}
|
||||
if (strcasecmp(clid, "asreceived")) {
|
||||
channel->callerid = strdup(clid);
|
||||
channel->ani = strdup(clid);
|
||||
}
|
||||
channel->language[0] = 0;
|
||||
channel->dnid = strdup(extstr);
|
||||
#ifdef AMAFLAGS
|
||||
channel->amaflags = AMAFLAGS;
|
||||
#endif
|
||||
#ifdef ACCTCODE
|
||||
strncpy(channel->accountcode, ACCTCODE, sizeof(chan->accountcode) - 1);
|
||||
#else
|
||||
channel->accountcode[0] = 0;
|
||||
#endif
|
||||
if (maxsecs) /* if finite length call */
|
||||
{
|
||||
time(&channel->whentohangup);
|
||||
channel->whentohangup += maxsecs;
|
||||
}
|
||||
strncpy(channel->exten, extstr, sizeof(channel->exten) - 1);
|
||||
strncpy(channel->context, context, sizeof(channel->context) - 1);
|
||||
channel->priority = 1;
|
||||
if(debug) printf("Caller ID is %s\n", channel->callerid);
|
||||
ast_pbx_run(channel);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
}
|
||||
else if(f->subclass==AST_CONTROL_RINGING)
|
||||
if (debug) printf("@@@@ qcall_do:Phone Ringing end\n");
|
||||
}
|
||||
ast_frfree(f);
|
||||
}
|
||||
ast_hangup(channel);
|
||||
if (debug) printf("@@@@ qcall_do:Hung up channel\n");
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
snprintf(qdir, sizeof(qdir), "%s/%s", ast_config_AST_SPOOL_DIR, "qcall");
|
||||
mkdir(qdir,0760);
|
||||
ast_pthread_create(&qcall_thread,NULL,qcall,NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
2487
apps/app_queue.c
Normal file
2487
apps/app_queue.c
Normal file
File diff suppressed because it is too large
Load Diff
127
apps/app_random.c
Normal file
127
apps/app_random.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Random application
|
||||
*
|
||||
* Copyright (c) 2003-2004 Tilghman Lesher. All rights reserved.
|
||||
*
|
||||
* Tilghman Lesher <asterisk__app_random__20040111@the-tilghman.com>
|
||||
*
|
||||
* This code is released by the author with no restrictions on usage or distribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static char *tdesc = "Random goto";
|
||||
|
||||
static char *app_random = "Random";
|
||||
|
||||
static char *random_synopsis = "Conditionally branches, based upon a probability";
|
||||
|
||||
static char *random_descrip =
|
||||
"Random([probability]:[[context|]extension|]priority)\n"
|
||||
" probability := INTEGER in the range 1 to 100\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int random_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
|
||||
char *s;
|
||||
char *exten, *pri, *context;
|
||||
char *prob;
|
||||
int probint, priorityint;
|
||||
|
||||
if (!data) {
|
||||
ast_log(LOG_WARNING, "Random requires an argument ([probability]:[[context|]extension|]priority)\n");
|
||||
return -1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
s = ast_strdupa((void *) data);
|
||||
|
||||
prob = strsep(&s,":");
|
||||
if ((!prob) || (sscanf(prob, "%d", &probint) != 1))
|
||||
probint = 0;
|
||||
|
||||
if ((random() % 100) + probint > 100) {
|
||||
context = strsep(&s, "|");
|
||||
exten = strsep(&s, "|");
|
||||
if (!exten) {
|
||||
/* Only a priority */
|
||||
pri = context;
|
||||
exten = NULL;
|
||||
context = NULL;
|
||||
} else {
|
||||
pri = strsep(&s, "|");
|
||||
if (!pri) {
|
||||
pri = exten;
|
||||
exten = context;
|
||||
context = NULL;
|
||||
}
|
||||
}
|
||||
if (!pri) {
|
||||
ast_log(LOG_WARNING, "No label specified\n");
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return -1;
|
||||
} else if (sscanf(pri, "%d", &priorityint) != 1) {
|
||||
ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", pri);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return -1;
|
||||
}
|
||||
/* At this point we have a priority and */
|
||||
/* maybe an extension and a context */
|
||||
chan->priority = priorityint - 1;
|
||||
if (exten && strcasecmp(exten, "BYEXTENSION"))
|
||||
strncpy(chan->exten, exten, sizeof(chan->exten)-1);
|
||||
if (context)
|
||||
strncpy(chan->context, context, sizeof(chan->context)-1);
|
||||
if (option_verbose > 2)
|
||||
ast_verbose( VERBOSE_PREFIX_3 "Random branches to (%s,%s,%d)\n",
|
||||
chan->context,chan->exten, chan->priority+1);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app_random);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app_random, random_exec, random_synopsis, random_descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
144
apps/app_read.c
Normal file
144
apps/app_read.c
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Trivial application to read a variable
|
||||
*
|
||||
* Copyright (C) 2003, Digium
|
||||
*
|
||||
* Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/app.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Read Variable Application";
|
||||
|
||||
static char *app = "Read";
|
||||
|
||||
static char *synopsis = "Read a variable";
|
||||
|
||||
static char *descrip =
|
||||
" Read(variable[|filename][|maxdigits][|option])\n\n"
|
||||
"Reads a #-terminated string of digits from the user in to the given variable,\n"
|
||||
"optionally playing a given filename first.\n"
|
||||
" maxdigits -- maximum acceptable number of digits. Stops reading after\n"
|
||||
" maxdigits have been entered (without requiring the user to\n"
|
||||
" press the '#' key).\n"
|
||||
" Defaults to 0 - no limit - wait for the user press the '#' key.\n"
|
||||
" Any value below 0 means the same. Max accepted value is 255.\n"
|
||||
" option -- may be 'skip' to return immediately if the line is not up,\n"
|
||||
" or 'noanswer' to read digits even if the line is not up.\n\n"
|
||||
"Returns -1 on hangup or error and 0 otherwise.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int read_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
struct localuser *u;
|
||||
char tmp[256];
|
||||
char argdata[256] = "";
|
||||
char *varname;
|
||||
char *filename;
|
||||
char *stringp;
|
||||
char *maxdigitstr;
|
||||
char *options;
|
||||
int option_skip = 0;
|
||||
int option_noanswer = 0;
|
||||
int maxdigits=255;
|
||||
if (!data || ast_strlen_zero((char *)data)) {
|
||||
ast_log(LOG_WARNING, "Read requires an argument (variable)\n");
|
||||
return -1;
|
||||
}
|
||||
strncpy(argdata, (char *)data, sizeof(argdata)-1);
|
||||
stringp=argdata;
|
||||
varname = strsep(&stringp, "|");
|
||||
filename = strsep(&stringp, "|");
|
||||
maxdigitstr = strsep(&stringp,"|");
|
||||
options = strsep(&stringp, "|");
|
||||
if (options && !strcasecmp(options, "skip"))
|
||||
option_skip = 1;
|
||||
if (options && !strcasecmp(options, "noanswer"))
|
||||
option_noanswer = 1;
|
||||
if (!(filename) || ast_strlen_zero(filename))
|
||||
filename = NULL;
|
||||
if (maxdigitstr) {
|
||||
maxdigits = atoi(maxdigitstr);
|
||||
if ((maxdigits<1) || (maxdigits>255)) {
|
||||
maxdigits = 255;
|
||||
} else
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Accepting a maximum of %i digits.\n", maxdigits);
|
||||
}
|
||||
if (!(varname) || ast_strlen_zero(varname)) {
|
||||
ast_log(LOG_WARNING, "Read requires an variable name\n");
|
||||
return -1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
if (chan->_state != AST_STATE_UP) {
|
||||
if (option_skip) {
|
||||
/* At the user's option, skip if the line is not up */
|
||||
pbx_builtin_setvar_helper(chan, varname, "\0");
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return 0;
|
||||
} else if (!option_noanswer) {
|
||||
/* Otherwise answer unless we're supposed to read while on-hook */
|
||||
res = ast_answer(chan);
|
||||
}
|
||||
}
|
||||
if (!res) {
|
||||
ast_stopstream(chan);
|
||||
res = ast_app_getdata(chan, filename, tmp, maxdigits, 0);
|
||||
if (res > -1) {
|
||||
pbx_builtin_setvar_helper(chan, varname, tmp);
|
||||
ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp);
|
||||
res = 0;
|
||||
} else {
|
||||
ast_verbose(VERBOSE_PREFIX_3 "User disconnected\n");
|
||||
}
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, read_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
340
apps/app_record.c
Normal file
340
apps/app_record.c
Normal file
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Trivial application to record a sound file
|
||||
*
|
||||
* Copyright (C) 2001, Linux Support Services, Inc.
|
||||
*
|
||||
* Matthew Fredrickson <creslin@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/dsp.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Trivial Record Application";
|
||||
|
||||
static char *app = "Record";
|
||||
|
||||
static char *synopsis = "Record to a file";
|
||||
|
||||
static char *descrip =
|
||||
" Record(filename:format|silence[|maxduration][|option])\n\n"
|
||||
"Records from the channel into a given filename. If the file exists it will\n"
|
||||
"be overwritten.\n"
|
||||
"- 'format' is the format of the file type to be recorded (wav, gsm, etc).\n"
|
||||
"- 'silence' is the number of seconds of silence to allow before returning.\n"
|
||||
"- 'maxduration' is the maximum recording duration in seconds. If missing\n"
|
||||
"or 0 there is no maximum.\n"
|
||||
"- 'option' may be 'skip' to return immediately if the line is not up,\n"
|
||||
"or 'noanswer' to attempt to record even if the line is not up.\n\n"
|
||||
"If filename contains '%d', these characters will be replaced with a number\n"
|
||||
"incremented by one each time the file is recorded. \n\n"
|
||||
"Formats: g723, g729, gsm, h263, ulaw, alaw, vox, wav, WAV\n\n"
|
||||
"User can press '#' to terminate the recording and continue to the next priority.\n\n"
|
||||
"Returns -1 when the user hangs up.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int record_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
int count = 0;
|
||||
int percentflag = 0;
|
||||
char fil[256];
|
||||
char tmp[256];
|
||||
char ext[10];
|
||||
char *vdata;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
struct ast_filestream *s = '\0';
|
||||
struct localuser *u;
|
||||
struct ast_frame *f = NULL;
|
||||
|
||||
struct ast_dsp *sildet = NULL; /* silence detector dsp */
|
||||
int totalsilence = 0;
|
||||
int dspsilence = 0;
|
||||
int silence = 0; /* amount of silence to allow */
|
||||
int gotsilence = 0; /* did we timeout for silence? */
|
||||
char silencestr[5];
|
||||
char durationstr[8];
|
||||
int maxduration = 0; /* max duration of recording */
|
||||
int gottimeout = 0; /* did we timeout for maxduration exceeded? */
|
||||
time_t timeout = 0;
|
||||
char option[16];
|
||||
int option_skip = 0;
|
||||
int option_noanswer = 0;
|
||||
int rfmt = 0;
|
||||
int flags;
|
||||
char *end=NULL;
|
||||
char *p=NULL;
|
||||
|
||||
|
||||
|
||||
/* The next few lines of code parse out the filename and header from the input string */
|
||||
if (!data) { /* no data implies no filename or anything is present */
|
||||
ast_log(LOG_WARNING, "Record requires an argument (filename)\n");
|
||||
return -1;
|
||||
}
|
||||
vdata = ast_strdupa(data);
|
||||
|
||||
p = vdata;
|
||||
while(p && (p=strchr(p,':'))) {
|
||||
end=p;
|
||||
if(!strcasecmp(end,":end")) {
|
||||
*end='\0';
|
||||
end++;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
end=NULL;
|
||||
}
|
||||
|
||||
|
||||
for (; vdata[i] && (vdata[i] != ':') && (vdata[i] != '|'); i++ ) {
|
||||
if ((vdata[i] == '%') && (vdata[i+1] == 'd')) {
|
||||
percentflag = 1; /* the wildcard is used */
|
||||
}
|
||||
if (j < sizeof(fil) - 1)
|
||||
fil[j++] = vdata[i];
|
||||
}
|
||||
fil[j] = '\0';
|
||||
|
||||
if (vdata[i] != ':') {
|
||||
ast_log(LOG_WARNING, "No extension found\n");
|
||||
return -1;
|
||||
}
|
||||
i++;
|
||||
|
||||
j = 0;
|
||||
for (; vdata[i] && (vdata[i] != '|'); i++)
|
||||
if (j < sizeof(ext) - 1)
|
||||
ext[j++] = vdata[i];
|
||||
ext[j] = '\0';
|
||||
|
||||
if (vdata[i] == '|')
|
||||
i++;
|
||||
|
||||
j = 0;
|
||||
for (; vdata[i] && (vdata[i] != '|'); i++)
|
||||
if (j < sizeof(silencestr) - 1)
|
||||
silencestr[j++] = vdata[i];
|
||||
silencestr[j] = '\0';
|
||||
|
||||
if (j > 0) {
|
||||
silence = atoi(silencestr);
|
||||
if (silence > 0)
|
||||
silence *= 1000;
|
||||
}
|
||||
|
||||
if (vdata[i] == '|')
|
||||
i++;
|
||||
|
||||
j = 0;
|
||||
for (; vdata[i] && (vdata[i] != '|'); i++)
|
||||
if (j < sizeof(durationstr) - 1)
|
||||
durationstr[j++] = vdata[i];
|
||||
durationstr[j] = '\0';
|
||||
|
||||
if (j > 0)
|
||||
maxduration = atoi(durationstr);
|
||||
|
||||
if (vdata[i] == '|')
|
||||
i++;
|
||||
|
||||
j = 0;
|
||||
for (; vdata[i] && (vdata[i] != '|'); i++)
|
||||
if (j < sizeof(option) - 1)
|
||||
option[j++] = vdata[i];
|
||||
option[j] = '\0';
|
||||
|
||||
if (!strcasecmp(option, "skip"))
|
||||
option_skip = 1;
|
||||
if (!strcasecmp(option, "noanswer"))
|
||||
option_noanswer = 1;
|
||||
|
||||
/* done parsing */
|
||||
|
||||
|
||||
/* these are to allow the use of the %d in the config file for a wild card of sort to
|
||||
create a new file with the inputed name scheme */
|
||||
if (percentflag) {
|
||||
do {
|
||||
snprintf(tmp, sizeof(tmp), fil, count);
|
||||
count++;
|
||||
} while ( ast_fileexists(tmp, ext, chan->language) != -1 );
|
||||
pbx_builtin_setvar_helper(chan, "RECORDED_FILE", tmp);
|
||||
} else
|
||||
strncpy(tmp, fil, sizeof(tmp)-1);
|
||||
/* end of routine mentioned */
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
if (chan->_state != AST_STATE_UP) {
|
||||
if (option_skip) {
|
||||
/* At the user's option, skip if the line is not up */
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return 0;
|
||||
} else if (!option_noanswer) {
|
||||
/* Otherwise answer unless we're supposed to record while on-hook */
|
||||
res = ast_answer(chan);
|
||||
}
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
/* Some code to play a nice little beep to signify the start of the record operation */
|
||||
res = ast_streamfile(chan, "beep", chan->language);
|
||||
if (!res) {
|
||||
res = ast_waitstream(chan, "");
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", chan->name);
|
||||
}
|
||||
ast_stopstream(chan);
|
||||
|
||||
/* The end of beep code. Now the recording starts */
|
||||
|
||||
|
||||
if (silence > 0) {
|
||||
rfmt = chan->readformat;
|
||||
res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
|
||||
return -1;
|
||||
}
|
||||
sildet = ast_dsp_new();
|
||||
if (!sildet) {
|
||||
ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
|
||||
return -1;
|
||||
}
|
||||
ast_dsp_set_threshold(sildet, 256);
|
||||
}
|
||||
|
||||
|
||||
flags = end ? O_CREAT|O_APPEND|O_WRONLY : O_CREAT|O_TRUNC|O_WRONLY;
|
||||
s = ast_writefile( tmp, ext, NULL, flags , 0, 0644);
|
||||
|
||||
|
||||
if (s) {
|
||||
if (maxduration > 0)
|
||||
timeout = time(NULL) + (time_t)maxduration;
|
||||
|
||||
while (ast_waitfor(chan, -1) > -1) {
|
||||
if (maxduration > 0 && time(NULL) > timeout) {
|
||||
gottimeout = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
f = ast_read(chan);
|
||||
if (!f) {
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
if (f->frametype == AST_FRAME_VOICE) {
|
||||
res = ast_writestream(s, f);
|
||||
|
||||
if (res) {
|
||||
ast_log(LOG_WARNING, "Problem writing frame\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (silence > 0) {
|
||||
dspsilence = 0;
|
||||
ast_dsp_silence(sildet, f, &dspsilence);
|
||||
if (dspsilence) {
|
||||
totalsilence = dspsilence;
|
||||
} else {
|
||||
totalsilence = 0;
|
||||
}
|
||||
if (totalsilence > silence) {
|
||||
/* Ended happily with silence */
|
||||
ast_frfree(f);
|
||||
gotsilence = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (f->frametype == AST_FRAME_VIDEO) {
|
||||
res = ast_writestream(s, f);
|
||||
|
||||
if (res) {
|
||||
ast_log(LOG_WARNING, "Problem writing frame\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((f->frametype == AST_FRAME_DTMF) &&
|
||||
(f->subclass == '#')) {
|
||||
ast_frfree(f);
|
||||
break;
|
||||
}
|
||||
ast_frfree(f);
|
||||
}
|
||||
if (!f) {
|
||||
ast_log(LOG_DEBUG, "Got hangup\n");
|
||||
res = -1;
|
||||
}
|
||||
|
||||
if (gotsilence) {
|
||||
ast_stream_rewind(s, silence-1000);
|
||||
ast_truncstream(s);
|
||||
} else if (!gottimeout) {
|
||||
/* Strip off the last 1/4 second of it */
|
||||
ast_stream_rewind(s, 250);
|
||||
ast_truncstream(s);
|
||||
}
|
||||
ast_closestream(s);
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Could not create file %s\n", fil);
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
if ((silence > 0) && rfmt) {
|
||||
res = ast_set_read_format(chan, rfmt);
|
||||
if (res)
|
||||
ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
|
||||
if (sildet)
|
||||
ast_dsp_free(sildet);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, record_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
4137
apps/app_rpt.c
Normal file
4137
apps/app_rpt.c
Normal file
File diff suppressed because it is too large
Load Diff
141
apps/app_sayunixtime.c
Normal file
141
apps/app_sayunixtime.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* SayUnixTime application
|
||||
*
|
||||
* Copyright (c) 2003 Tilghman Lesher. All rights reserved.
|
||||
*
|
||||
* Tilghman Lesher <app_sayunixtime__200309@the-tilghman.com>
|
||||
*
|
||||
* This code is released by the author with no restrictions on usage.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/say.h>
|
||||
|
||||
|
||||
static char *tdesc = "Say time";
|
||||
|
||||
static char *app_sayunixtime = "SayUnixTime";
|
||||
static char *app_datetime = "DateTime";
|
||||
|
||||
static char *sayunixtime_synopsis = "Says a specified time in a custom format";
|
||||
|
||||
static char *sayunixtime_descrip =
|
||||
"SayUnixTime([unixtime][|[timezone][|format]])\n"
|
||||
" unixtime: time, in seconds since Jan 1, 1970. May be negative.\n"
|
||||
" defaults to now.\n"
|
||||
" timezone: timezone, see /usr/share/zoneinfo for a list.\n"
|
||||
" defaults to machine default.\n"
|
||||
" format: a format the time is to be said in. See voicemail.conf.\n"
|
||||
" defaults to \"ABdY 'digits/at' IMp\"\n"
|
||||
" Returns 0 or -1 on hangup.\n";
|
||||
static char *datetime_descrip =
|
||||
"DateTime([unixtime][|[timezone][|format]])\n"
|
||||
" unixtime: time, in seconds since Jan 1, 1970. May be negative.\n"
|
||||
" defaults to now.\n"
|
||||
" timezone: timezone, see /usr/share/zoneinfo for a list.\n"
|
||||
" defaults to machine default.\n"
|
||||
" format: a format the time is to be said in. See voicemail.conf.\n"
|
||||
" defaults to \"ABdY 'digits/at' IMp\"\n"
|
||||
" Returns 0 or -1 on hangup.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int sayunixtime_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
char *s,*zone=NULL,*timec;
|
||||
time_t unixtime;
|
||||
char *format = "ABdY 'digits/at' IMp";
|
||||
struct timeval tv;
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
gettimeofday(&tv,NULL);
|
||||
unixtime = (time_t)tv.tv_sec;
|
||||
|
||||
if (data) {
|
||||
s = data;
|
||||
s = ast_strdupa(s);
|
||||
if (s) {
|
||||
timec = strsep(&s,"|");
|
||||
if ((timec) && (*timec != '\0')) {
|
||||
long timein;
|
||||
if (sscanf(timec,"%ld",&timein) == 1) {
|
||||
unixtime = (time_t)timein;
|
||||
}
|
||||
}
|
||||
if (s) {
|
||||
zone = strsep(&s,"|");
|
||||
if (zone && (*zone == '\0'))
|
||||
zone = NULL;
|
||||
if (s) {
|
||||
format = s;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_ERROR, "Out of memory error\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (chan->_state != AST_STATE_UP) {
|
||||
res = ast_answer(chan);
|
||||
}
|
||||
if (!res)
|
||||
res = ast_say_date_with_format(chan, unixtime, AST_DIGIT_ANY, chan->language, format, zone);
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
res = ast_unregister_application(app_sayunixtime);
|
||||
if (! res)
|
||||
return ast_unregister_application(app_datetime);
|
||||
else
|
||||
return res;
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
int res;
|
||||
res = ast_register_application(app_sayunixtime, sayunixtime_exec, sayunixtime_synopsis, sayunixtime_descrip);
|
||||
if (! res)
|
||||
return ast_register_application(app_datetime, sayunixtime_exec, sayunixtime_synopsis, datetime_descrip);
|
||||
else
|
||||
return res;
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
84
apps/app_senddtmf.c
Normal file
84
apps/app_senddtmf.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* App to send DTMF digits
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <asterisk/app.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Send DTMF digits Application";
|
||||
|
||||
static char *app = "SendDTMF";
|
||||
|
||||
static char *synopsis = "Sends arbitrary DTMF digits";
|
||||
|
||||
static char *descrip =
|
||||
" SendDTMF(digits): Sends DTMF digits on a channel. \n"
|
||||
" Accepted digits: 0-9, *#abcd\n"
|
||||
" Returns 0 on success or -1 on a hangup.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int senddtmf_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
struct localuser *u;
|
||||
char *digits = data;
|
||||
|
||||
if (!digits || ast_strlen_zero(digits)) {
|
||||
ast_log(LOG_WARNING, "SendDTMF requires an argument (digits or *#aAbBcCdD)\n");
|
||||
return -1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
res = ast_dtmf_stream(chan,NULL,digits,250);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, senddtmf_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
94
apps/app_sendtext.c
Normal file
94
apps/app_sendtext.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* App to transmit a text message
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/image.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Send Text Applications";
|
||||
|
||||
static char *app = "SendText";
|
||||
|
||||
static char *synopsis = "Send a Text Message";
|
||||
|
||||
static char *descrip =
|
||||
" SendText(text): Sends text to client. If the client\n"
|
||||
"does not support text transport, and there exists a step with\n"
|
||||
"priority n + 101, then execution will continue at that step.\n"
|
||||
"Otherwise, execution will continue at the next priority level.\n"
|
||||
"SendText only returns 0 if the text was sent correctly or if\n"
|
||||
"the channel does not support text transport, and -1 otherwise.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int sendtext_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
struct localuser *u;
|
||||
if (!data || !strlen((char *)data)) {
|
||||
ast_log(LOG_WARNING, "SendText requires an argument (text)\n");
|
||||
return -1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
ast_mutex_lock(&chan->lock);
|
||||
if (!chan->pvt->send_text) {
|
||||
ast_mutex_unlock(&chan->lock);
|
||||
/* Does not support transport */
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority += 100;
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return 0;
|
||||
}
|
||||
ast_mutex_unlock(&chan->lock);
|
||||
res = ast_sendtext(chan, (char *)data);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, sendtext_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
159
apps/app_setcallerid.c
Normal file
159
apps/app_setcallerid.c
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* App to set callerid
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/image.h>
|
||||
#include <asterisk/callerid.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *app2 = "SetCallerPres";
|
||||
|
||||
static char *synopsis2 = "Set CallerID Presentation";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static struct {
|
||||
int val;
|
||||
char *name;
|
||||
} preses[] = {
|
||||
{ AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "allowed_not_screened" },
|
||||
{ AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen" },
|
||||
{ AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen" },
|
||||
{ AST_PRES_ALLOWED_NETWORK_NUMBER, "allowed" },
|
||||
{ AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED , "prohib_not_screened" },
|
||||
{ AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen" },
|
||||
{ AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen" },
|
||||
{ AST_PRES_PROHIB_NETWORK_NUMBER, "prohib" },
|
||||
{ AST_PRES_NUMBER_NOT_AVAILABLE, "unavailable" },
|
||||
};
|
||||
|
||||
static char *descrip2 =
|
||||
" SetCallerPres(presentation): Set Caller*ID presentation on\n"
|
||||
"a call to a new value. Sets ANI as well if a flag is used.\n"
|
||||
"Always returns 0. Valid presentations are:\n"
|
||||
"\n"
|
||||
" allowed_not_screened : Presentation Allowed, Not Screened\n"
|
||||
" allowed_passed_screen : Presentation Allowed, Passed Screen\n"
|
||||
" allowed_failed_screen : Presentation Allowed, Failed Screen\n"
|
||||
" allowed : Presentation Allowed, Network Number\n"
|
||||
" prohib_not_screened : Presentation Prohibited, Not Screened\n"
|
||||
" prohib_passed_screen : Presentation Prohibited, Passed Screen\n"
|
||||
" prohib_failed_screen : Presentation Prohibited, Failed Screen\n"
|
||||
" prohib : Presentation Prohibited, Network Number\n"
|
||||
" unavailable : Number Unavailable\n"
|
||||
"\n"
|
||||
;
|
||||
|
||||
static int setcallerid_pres_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
char tmp[256] = "";
|
||||
struct localuser *u;
|
||||
int x;
|
||||
char *opts;
|
||||
int pres = -1;
|
||||
if (data)
|
||||
strncpy(tmp, (char *)data, sizeof(tmp) - 1);
|
||||
opts = strchr(tmp, '|');
|
||||
if (opts) {
|
||||
*opts = '\0';
|
||||
opts++;
|
||||
}
|
||||
for (x=0;x<sizeof(preses) / sizeof(preses[0]);x++) {
|
||||
if (!strcasecmp(preses[x].name, tmp)) {
|
||||
pres = preses[x].val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pres < 0) {
|
||||
ast_log(LOG_WARNING, "'%s' is not a valid presentation (see 'show application SetCallerPres')\n", tmp);
|
||||
return 0;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
chan->callingpres = pres;
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char *tdesc = "Set CallerID Application";
|
||||
|
||||
static char *app = "SetCallerID";
|
||||
|
||||
static char *synopsis = "Set CallerID";
|
||||
|
||||
static char *descrip =
|
||||
" SetCallerID(clid[|a]): Set Caller*ID on a call to a new\n"
|
||||
"value. Sets ANI as well if a flag is used. Always returns 0\n";
|
||||
|
||||
static int setcallerid_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
char tmp[256] = "";
|
||||
struct localuser *u;
|
||||
char *opt;
|
||||
int anitoo = 0;
|
||||
if (data)
|
||||
strncpy(tmp, (char *)data, sizeof(tmp) - 1);
|
||||
opt = strchr(tmp, '|');
|
||||
if (opt) {
|
||||
*opt = '\0';
|
||||
opt++;
|
||||
if (*opt == 'a')
|
||||
anitoo = 1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
ast_set_callerid(chan, strlen(tmp) ? tmp : NULL, anitoo);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
ast_unregister_application(app2);
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
ast_register_application(app2, setcallerid_pres_exec, synopsis2, descrip2);
|
||||
return ast_register_application(app, setcallerid_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
165
apps/app_setcdruserfield.c
Normal file
165
apps/app_setcdruserfield.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Applictions connected with CDR engine
|
||||
*
|
||||
* Copyright (C) 2003, Digium
|
||||
*
|
||||
* Justin Huff <jjhuff@mspin.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/cdr.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/manager.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static char *tdesc = "CDR user field apps";
|
||||
|
||||
static char *setcdruserfield_descrip =
|
||||
"[Synopsis]\n"
|
||||
"SetCDRUserField(value)\n\n"
|
||||
"[Description]\n"
|
||||
"SetCDRUserField(value): Set the CDR 'user field' to value\n"
|
||||
" The Call Data Record (CDR) user field is an extra field you\n"
|
||||
" can use for data not stored anywhere else in the record.\n"
|
||||
" CDR records can be used for billing or storing other arbitrary data\n"
|
||||
" (I.E. telephone survey responses)\n"
|
||||
" Also see AppendCDRUserField().\n"
|
||||
" Always returns 0\n";
|
||||
|
||||
|
||||
static char *setcdruserfield_app = "SetCDRUserField";
|
||||
static char *setcdruserfield_synopsis = "Set the CDR user field";
|
||||
|
||||
static char *appendcdruserfield_descrip =
|
||||
"[Synopsis]\n"
|
||||
"AppendCDRUserField(value)\n\n"
|
||||
"[Description]\n"
|
||||
"AppendCDRUserField(value): Append value to the CDR user field\n"
|
||||
" The Call Data Record (CDR) user field is an extra field you\n"
|
||||
" can use for data not stored anywhere else in the record.\n"
|
||||
" CDR records can be used for billing or storing other arbitrary data\n"
|
||||
" (I.E. telephone survey responses)\n"
|
||||
" Also see SetCDRUserField().\n"
|
||||
" Always returns 0\n";
|
||||
|
||||
static char *appendcdruserfield_app = "AppendCDRUserField";
|
||||
static char *appendcdruserfield_synopsis = "Append to the CDR user field";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int action_setcdruserfield(struct mansession *s, struct message *m)
|
||||
{
|
||||
struct ast_channel *c = NULL;
|
||||
char *userfield = astman_get_header(m, "UserField");
|
||||
char *channel = astman_get_header(m, "Channel");
|
||||
char *append = astman_get_header(m, "Append");
|
||||
|
||||
if (ast_strlen_zero(channel)) {
|
||||
astman_send_error(s, m, "No Channel specified");
|
||||
return 0;
|
||||
}
|
||||
if (ast_strlen_zero(userfield)) {
|
||||
astman_send_error(s, m, "No UserField specified");
|
||||
return 0;
|
||||
}
|
||||
c = ast_channel_walk_locked(NULL);
|
||||
while (c) {
|
||||
if (!strcasecmp(c->name, channel))
|
||||
break;
|
||||
ast_mutex_unlock(&c->lock);
|
||||
c = ast_channel_walk_locked(c);
|
||||
}
|
||||
if (!c) {
|
||||
astman_send_error(s, m, "No such channel");
|
||||
return 0;
|
||||
}
|
||||
if (ast_true(append))
|
||||
ast_cdr_appenduserfield(c, userfield);
|
||||
else
|
||||
ast_cdr_setuserfield(c, userfield);
|
||||
ast_mutex_unlock(&c->lock);
|
||||
astman_send_ack(s, m, "CDR Userfield Set");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setcdruserfield_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
struct localuser *u;
|
||||
int res = 0;
|
||||
|
||||
LOCAL_USER_ADD(u)
|
||||
if (chan->cdr && data)
|
||||
{
|
||||
ast_cdr_setuserfield(chan, (char*)data);
|
||||
}
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int appendcdruserfield_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
struct localuser *u;
|
||||
int res = 0;
|
||||
|
||||
LOCAL_USER_ADD(u)
|
||||
if (chan->cdr && data)
|
||||
{
|
||||
ast_cdr_appenduserfield(chan, (char*)data);
|
||||
}
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
res = ast_unregister_application(setcdruserfield_app);
|
||||
res |= ast_unregister_application(appendcdruserfield_app);
|
||||
ast_manager_unregister("SetCDRUserField");
|
||||
return res;
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
int res;
|
||||
res = ast_register_application(setcdruserfield_app, setcdruserfield_exec, setcdruserfield_synopsis, setcdruserfield_descrip);
|
||||
res |= ast_register_application(appendcdruserfield_app, appendcdruserfield_exec, appendcdruserfield_synopsis, appendcdruserfield_descrip);
|
||||
ast_manager_register("SetCDRUserField", EVENT_FLAG_CALL, action_setcdruserfield, "Set the CDR UserField");
|
||||
return res;
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
107
apps/app_setcidname.c
Normal file
107
apps/app_setcidname.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* App to set callerid
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/image.h>
|
||||
#include <asterisk/callerid.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Set CallerID Name";
|
||||
|
||||
static char *app = "SetCIDName";
|
||||
|
||||
static char *synopsis = "Set CallerID Name";
|
||||
|
||||
static char *descrip =
|
||||
" SetCIDName(cname[|a]): Set Caller*ID Name on a call to a new\n"
|
||||
"value, while preserving the original Caller*ID number. This is\n"
|
||||
"useful for providing additional information to the called\n"
|
||||
"party. Sets ANI as well if a flag is used. Always returns 0\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int setcallerid_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
char tmp[256] = "";
|
||||
char oldcid[256] = "", *l, *n;
|
||||
char newcid[256] = "";
|
||||
struct localuser *u;
|
||||
char *opt;
|
||||
int anitoo = 0;
|
||||
if (data)
|
||||
strncpy(tmp, (char *)data, sizeof(tmp) - 1);
|
||||
opt = strchr(tmp, '|');
|
||||
if (opt) {
|
||||
*opt = '\0';
|
||||
opt++;
|
||||
if (*opt == 'a')
|
||||
anitoo = 1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
if (chan->callerid) {
|
||||
strncpy(oldcid, chan->callerid, sizeof(oldcid) - 1);
|
||||
ast_callerid_parse(oldcid, &n, &l);
|
||||
n = tmp;
|
||||
if (!ast_strlen_zero(n)) {
|
||||
if (l && !ast_strlen_zero(l))
|
||||
snprintf(newcid, sizeof(newcid), "\"%s\" <%s>", n, l);
|
||||
else
|
||||
strncpy(newcid, tmp, sizeof(newcid) - 1);
|
||||
} else if (l && !ast_strlen_zero(l)) {
|
||||
strncpy(newcid, l, sizeof(newcid) - 1);
|
||||
}
|
||||
} else
|
||||
strncpy(newcid, tmp, sizeof(newcid) - 1);
|
||||
ast_set_callerid(chan, !ast_strlen_zero(newcid) ? newcid : NULL, anitoo);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, setcallerid_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
108
apps/app_setcidnum.c
Normal file
108
apps/app_setcidnum.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* App to set callerid
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
* Oliver Daudey <traveler@xs4all.nl>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/image.h>
|
||||
#include <asterisk/callerid.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Set CallerID Number";
|
||||
|
||||
static char *app = "SetCIDNum";
|
||||
|
||||
static char *synopsis = "Set CallerID Number";
|
||||
|
||||
static char *descrip =
|
||||
" SetCIDNum(cnum[|a]): Set Caller*ID Number on a call to a new\n"
|
||||
"value, while preserving the original Caller*ID name. This is\n"
|
||||
"useful for providing additional information to the called\n"
|
||||
"party. Sets ANI as well if a flag is used. Always returns 0\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int setcallerid_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
char tmp[256] = "";
|
||||
char oldcid[256] = "", *l, *n;
|
||||
char newcid[256] = "";
|
||||
struct localuser *u;
|
||||
char *opt;
|
||||
int anitoo = 0;
|
||||
if (data)
|
||||
strncpy(tmp, (char *)data, sizeof(tmp) - 1);
|
||||
opt = strchr(tmp, '|');
|
||||
if (opt) {
|
||||
*opt = '\0';
|
||||
opt++;
|
||||
if (*opt == 'a')
|
||||
anitoo = 1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
if (chan->callerid) {
|
||||
strncpy(oldcid, chan->callerid, sizeof(oldcid) - 1);
|
||||
ast_callerid_parse(oldcid, &n, &l);
|
||||
l = tmp;
|
||||
if (!ast_strlen_zero(l)) {
|
||||
if (n && !ast_strlen_zero(n))
|
||||
snprintf(newcid, sizeof(newcid), "\"%s\" <%s>", n, l);
|
||||
else
|
||||
strncpy(newcid, tmp, sizeof(newcid) - 1);
|
||||
} else if (n && !ast_strlen_zero(n)) {
|
||||
strncpy(newcid, n, sizeof(newcid) - 1);
|
||||
}
|
||||
} else
|
||||
strncpy(newcid, tmp, sizeof(newcid) - 1);
|
||||
ast_set_callerid(chan, !ast_strlen_zero(newcid) ? newcid : NULL, anitoo);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, setcallerid_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
16
apps/app_skel.c
Executable file → Normal file
16
apps/app_skel.c
Executable file → Normal file
@@ -16,17 +16,16 @@
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
static char *tdesc = "Trivial skeleton Application";
|
||||
|
||||
static char *app = "skel";
|
||||
static char *synopsis =
|
||||
" This is a skeleton application that shows you the basic structure to create your\n"
|
||||
"own asterisk applications.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
@@ -54,7 +53,7 @@ int unload_module(void)
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, skel_exec);
|
||||
return ast_register_application(app, skel_exec, synopsis, tdesc);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
@@ -68,3 +67,8 @@ int usecount(void)
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
|
||||
1236
apps/app_sms.c
Normal file
1236
apps/app_sms.c
Normal file
File diff suppressed because it is too large
Load Diff
89
apps/app_softhangup.c
Normal file
89
apps/app_softhangup.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* SoftHangup application
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *synopsis = "Soft Hangup Application";
|
||||
|
||||
static char *tdesc = "Hangs up the requested channel";
|
||||
|
||||
static char *desc = " SoftHangup(Technology/resource)\n"
|
||||
"Hangs up the requested channel. Always returns 0\n";
|
||||
|
||||
static char *app = "SoftHangup";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int softhangup_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
struct localuser *u;
|
||||
struct ast_channel *c=NULL;
|
||||
if (!data) {
|
||||
ast_log(LOG_WARNING, "SoftHangup requires an argument (Technology/resource)\n");
|
||||
return 0;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
c = ast_channel_walk_locked(NULL);
|
||||
while (c) {
|
||||
if (!strcasecmp(c->name, data)) {
|
||||
ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
|
||||
ast_mutex_unlock(&c->lock);
|
||||
break;
|
||||
}
|
||||
ast_mutex_unlock(&c->lock);
|
||||
c = ast_channel_walk_locked(c);
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, softhangup_exec, synopsis, desc);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
562
apps/app_sql_postgres.c
Normal file
562
apps/app_sql_postgres.c
Normal file
@@ -0,0 +1,562 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Connect to PostgreSQL
|
||||
*
|
||||
* Copyright (C) 2002, Christos Ricudis
|
||||
*
|
||||
* Christos Ricudis <ricudis@itc.auth.gr>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/linkedlists.h>
|
||||
#include <asterisk/chanvars.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "libpq-fe.h"
|
||||
|
||||
#define EXTRA_LOG 0
|
||||
|
||||
|
||||
static char *tdesc = "Simple PostgreSQL Interface";
|
||||
|
||||
static char *app = "PGSQL";
|
||||
|
||||
static char *synopsis = "Do several SQLy things";
|
||||
|
||||
static char *descrip =
|
||||
"PGSQL(): Do several SQLy things\n"
|
||||
"Syntax:\n"
|
||||
" PGSQL(Connect var option-string)\n"
|
||||
" Connects to a database. Option string contains standard PostgreSQL\n"
|
||||
" parameters like host=, dbname=, user=. Connection identifer returned\n"
|
||||
" in ${var}\n"
|
||||
" PGSQL(Query var ${connection_identifier} query-string)\n"
|
||||
" Executes standard SQL query contained in query-string using established\n"
|
||||
" connection identified by ${connection_identifier}. Reseult of query is\n"
|
||||
" is stored in ${var}.\n"
|
||||
" PGSQL(Fetch statusvar ${result_identifier} var1 var2 ... varn)\n"
|
||||
" Fetches a single row from a result set contained in ${result_identifier}.\n"
|
||||
" Assigns returned fields to ${var1} ... ${varn}. ${statusvar} is set TRUE\n"
|
||||
" if additional rows exist in reseult set.\n"
|
||||
" PGSQL(Clear ${result_identifier})\n"
|
||||
" Frees memory and datastructures associated with result set.\n"
|
||||
" PGSQL(Disconnect ${connection_identifier})\n"
|
||||
" Disconnects from named connection to PostgreSQL.\n" ;
|
||||
|
||||
/*
|
||||
|
||||
Syntax of SQL commands :
|
||||
|
||||
Connect var option-string
|
||||
|
||||
Connects to a database using the option-string and stores the
|
||||
connection identifier in ${var}
|
||||
|
||||
|
||||
Query var ${connection_identifier} query-string
|
||||
|
||||
Submits query-string to database backend and stores the result
|
||||
identifier in ${var}
|
||||
|
||||
|
||||
Fetch statusvar ${result_identifier} var1 var2 var3 ... varn
|
||||
|
||||
Fetches a row from the query and stores end-of-table status in
|
||||
${statusvar} and columns in ${var1}..${varn}
|
||||
|
||||
|
||||
Clear ${result_identifier}
|
||||
|
||||
Clears data structures associated with ${result_identifier}
|
||||
|
||||
|
||||
Disconnect ${connection_identifier}
|
||||
|
||||
Disconnects from named connection
|
||||
|
||||
|
||||
EXAMPLES OF USE :
|
||||
|
||||
exten => s,2,PGSQL(Connect connid host=localhost user=asterisk dbname=credit)
|
||||
exten => s,3,PGSQL(Query resultid ${connid} SELECT username,credit FROM credit WHERE callerid=${CALLERIDNUM})
|
||||
exten => s,4,PGSQL(Fetch fetchid ${resultid} datavar1 datavar2)
|
||||
exten => s,5,GotoIf(${fetchid}?6:8)
|
||||
exten => s,6,Festival("User ${datavar1} currently has credit balance of ${datavar2} dollars.")
|
||||
exten => s,7,Goto(s,4)
|
||||
exten => s,8,PGSQL(Clear ${resultid})
|
||||
exten => s,9,PGSQL(Disconnect ${connid})
|
||||
|
||||
*/
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
#define AST_PGSQL_ID_DUMMY 0
|
||||
#define AST_PGSQL_ID_CONNID 1
|
||||
#define AST_PGSQL_ID_RESID 2
|
||||
#define AST_PGSQL_ID_FETCHID 3
|
||||
|
||||
struct ast_PGSQL_id {
|
||||
int identifier_type; /* 0=dummy, 1=connid, 2=resultid */
|
||||
int identifier;
|
||||
void *data;
|
||||
AST_LIST_ENTRY(ast_PGSQL_id) entries;
|
||||
} *ast_PGSQL_id;
|
||||
|
||||
AST_LIST_HEAD(PGSQLidshead,ast_PGSQL_id) PGSQLidshead;
|
||||
|
||||
static void *find_identifier(int identifier,int identifier_type) {
|
||||
struct PGSQLidshead *headp;
|
||||
struct ast_PGSQL_id *i;
|
||||
void *res=NULL;
|
||||
int found=0;
|
||||
|
||||
headp=&PGSQLidshead;
|
||||
|
||||
if (AST_LIST_LOCK(headp)) {
|
||||
ast_log(LOG_WARNING,"Unable to lock identifiers list\n");
|
||||
} else {
|
||||
AST_LIST_TRAVERSE(headp,i,entries) {
|
||||
if ((i->identifier==identifier) && (i->identifier_type==identifier_type)) {
|
||||
found=1;
|
||||
res=i->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
ast_log(LOG_WARNING,"Identifier %d, identifier_type %d not found in identifier list\n",identifier,identifier_type);
|
||||
}
|
||||
AST_LIST_UNLOCK(headp);
|
||||
}
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
static int add_identifier(int identifier_type,void *data) {
|
||||
struct ast_PGSQL_id *i,*j;
|
||||
struct PGSQLidshead *headp;
|
||||
int maxidentifier=0;
|
||||
|
||||
headp=&PGSQLidshead;
|
||||
i=NULL;
|
||||
j=NULL;
|
||||
|
||||
if (AST_LIST_LOCK(headp)) {
|
||||
ast_log(LOG_WARNING,"Unable to lock identifiers list\n");
|
||||
return(-1);
|
||||
} else {
|
||||
i=malloc(sizeof(struct ast_PGSQL_id));
|
||||
AST_LIST_TRAVERSE(headp,j,entries) {
|
||||
if (j->identifier>maxidentifier) {
|
||||
maxidentifier=j->identifier;
|
||||
}
|
||||
}
|
||||
|
||||
i->identifier=maxidentifier+1;
|
||||
i->identifier_type=identifier_type;
|
||||
i->data=data;
|
||||
AST_LIST_INSERT_HEAD(headp,i,entries);
|
||||
AST_LIST_UNLOCK(headp);
|
||||
}
|
||||
return(i->identifier);
|
||||
}
|
||||
|
||||
static int del_identifier(int identifier,int identifier_type) {
|
||||
struct ast_PGSQL_id *i;
|
||||
struct PGSQLidshead *headp;
|
||||
int found=0;
|
||||
|
||||
headp=&PGSQLidshead;
|
||||
|
||||
if (AST_LIST_LOCK(headp)) {
|
||||
ast_log(LOG_WARNING,"Unable to lock identifiers list\n");
|
||||
} else {
|
||||
AST_LIST_TRAVERSE(headp,i,entries) {
|
||||
if ((i->identifier==identifier) &&
|
||||
(i->identifier_type==identifier_type)) {
|
||||
AST_LIST_REMOVE(headp,i,ast_PGSQL_id,entries);
|
||||
free(i);
|
||||
found=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
AST_LIST_UNLOCK(headp);
|
||||
}
|
||||
|
||||
if (found==0) {
|
||||
ast_log(LOG_WARNING,"Could not find identifier %d, identifier_type %d in list to delete\n",identifier,identifier_type);
|
||||
return(-1);
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
static int aPGSQL_connect(struct ast_channel *chan, void *data) {
|
||||
|
||||
char *s1;
|
||||
char s[100] = "";
|
||||
char *optionstring;
|
||||
char *var;
|
||||
int l;
|
||||
int res;
|
||||
PGconn *karoto;
|
||||
int id;
|
||||
char *stringp=NULL;
|
||||
|
||||
|
||||
res=0;
|
||||
l=strlen(data)+2;
|
||||
s1=malloc(l);
|
||||
strncpy(s1, data, l -1);
|
||||
stringp=s1;
|
||||
strsep(&stringp," "); // eat the first token, we already know it :P
|
||||
var=strsep(&stringp," ");
|
||||
optionstring=strsep(&stringp,"\n");
|
||||
|
||||
karoto = PQconnectdb(optionstring);
|
||||
if (PQstatus(karoto) == CONNECTION_BAD) {
|
||||
ast_log(LOG_WARNING,"Connection to database using '%s' failed. postgress reports : %s\n", optionstring,
|
||||
PQerrorMessage(karoto));
|
||||
res=-1;
|
||||
} else {
|
||||
ast_log(LOG_WARNING,"adding identifier\n");
|
||||
id=add_identifier(AST_PGSQL_ID_CONNID,karoto);
|
||||
snprintf(s, sizeof(s), "%d", id);
|
||||
pbx_builtin_setvar_helper(chan,var,s);
|
||||
}
|
||||
|
||||
free(s1);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aPGSQL_query(struct ast_channel *chan, void *data) {
|
||||
|
||||
|
||||
char *s1,*s2,*s3,*s4;
|
||||
char s[100] = "";
|
||||
char *querystring;
|
||||
char *var;
|
||||
int l;
|
||||
int res,nres;
|
||||
PGconn *karoto;
|
||||
PGresult *PGSQLres;
|
||||
int id,id1;
|
||||
char *stringp=NULL;
|
||||
|
||||
|
||||
res=0;
|
||||
l=strlen(data)+2;
|
||||
s1=malloc(l);
|
||||
s2=malloc(l);
|
||||
strncpy(s1, data, l - 1);
|
||||
stringp=s1;
|
||||
strsep(&stringp," "); // eat the first token, we already know it :P
|
||||
s3=strsep(&stringp," ");
|
||||
while (1) { // ugly trick to make branches with break;
|
||||
var=s3;
|
||||
s4=strsep(&stringp," ");
|
||||
id=atoi(s4);
|
||||
querystring=strsep(&stringp,"\n");
|
||||
if ((karoto=find_identifier(id,AST_PGSQL_ID_CONNID))==NULL) {
|
||||
ast_log(LOG_WARNING,"Invalid connection identifier %d passed in aPGSQL_query\n",id);
|
||||
res=-1;
|
||||
break;
|
||||
}
|
||||
PGSQLres=PQexec(karoto,querystring);
|
||||
if (PGSQLres==NULL) {
|
||||
ast_log(LOG_WARNING,"aPGSQL_query: Connection Error (connection identifier = %d, error message : %s)\n",id,PQerrorMessage(karoto));
|
||||
res=-1;
|
||||
break;
|
||||
}
|
||||
if (PQresultStatus(PGSQLres) == PGRES_BAD_RESPONSE ||
|
||||
PQresultStatus(PGSQLres) == PGRES_NONFATAL_ERROR ||
|
||||
PQresultStatus(PGSQLres) == PGRES_FATAL_ERROR) {
|
||||
ast_log(LOG_WARNING,"aPGSQL_query: Query Error (connection identifier : %d, error message : %s)\n",id,PQcmdStatus(PGSQLres));
|
||||
res=-1;
|
||||
break;
|
||||
}
|
||||
nres=PQnfields(PGSQLres);
|
||||
id1=add_identifier(AST_PGSQL_ID_RESID,PGSQLres);
|
||||
snprintf(s, sizeof(s), "%d", id1);
|
||||
pbx_builtin_setvar_helper(chan,var,s);
|
||||
break;
|
||||
}
|
||||
|
||||
free(s1);
|
||||
free(s2);
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
|
||||
static int aPGSQL_fetch(struct ast_channel *chan, void *data) {
|
||||
|
||||
char *s1,*s2,*fetchid_var,*s4,*s5,*s6,*s7;
|
||||
char s[100];
|
||||
char *var;
|
||||
int l;
|
||||
int res;
|
||||
PGresult *PGSQLres;
|
||||
int id,id1,i,j,fnd;
|
||||
int *lalares=NULL;
|
||||
int nres;
|
||||
struct ast_var_t *variables;
|
||||
struct varshead *headp;
|
||||
char *stringp=NULL;
|
||||
|
||||
headp=&chan->varshead;
|
||||
|
||||
res=0;
|
||||
l=strlen(data)+2;
|
||||
s7=NULL;
|
||||
s1=malloc(l);
|
||||
s2=malloc(l);
|
||||
strncpy(s1, data, l - 1);
|
||||
stringp=s1;
|
||||
strsep(&stringp," "); // eat the first token, we already know it :P
|
||||
fetchid_var=strsep(&stringp," ");
|
||||
while (1) { // ugly trick to make branches with break;
|
||||
var=fetchid_var; // fetchid
|
||||
fnd=0;
|
||||
|
||||
AST_LIST_TRAVERSE(headp,variables,entries) {
|
||||
if (strncasecmp(ast_var_name(variables),fetchid_var,strlen(fetchid_var))==0) {
|
||||
s7=ast_var_value(variables);
|
||||
fnd=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fnd==0) {
|
||||
s7="0";
|
||||
pbx_builtin_setvar_helper(chan,fetchid_var,s7);
|
||||
}
|
||||
|
||||
s4=strsep(&stringp," ");
|
||||
id=atoi(s4); // resultid
|
||||
if ((PGSQLres=find_identifier(id,AST_PGSQL_ID_RESID))==NULL) {
|
||||
ast_log(LOG_WARNING,"Invalid result identifier %d passed in aPGSQL_fetch\n",id);
|
||||
res=-1;
|
||||
break;
|
||||
}
|
||||
id=atoi(s7); //fetchid
|
||||
if ((lalares=find_identifier(id,AST_PGSQL_ID_FETCHID))==NULL) {
|
||||
i=0; // fetching the very first row
|
||||
} else {
|
||||
i=*lalares;
|
||||
free(lalares);
|
||||
del_identifier(id,AST_PGSQL_ID_FETCHID); // will re-add it a bit later
|
||||
}
|
||||
|
||||
if (i<PQntuples(PGSQLres)) {
|
||||
nres=PQnfields(PGSQLres);
|
||||
ast_log(LOG_WARNING,"ast_PGSQL_fetch : nres = %d i = %d ;\n",nres,i);
|
||||
for (j=0;j<nres;j++) {
|
||||
s5=strsep(&stringp," ");
|
||||
if (s5==NULL) {
|
||||
ast_log(LOG_WARNING,"ast_PGSQL_fetch : More tuples (%d) than variables (%d)\n",nres,j);
|
||||
break;
|
||||
}
|
||||
s6=PQgetvalue(PGSQLres,i,j);
|
||||
if (s6==NULL) {
|
||||
ast_log(LOG_WARNING,"PWgetvalue(res,%d,%d) returned NULL in ast_PGSQL_fetch\n",i,j);
|
||||
break;
|
||||
}
|
||||
ast_log(LOG_WARNING,"===setting variable '%s' to '%s'\n",s5,s6);
|
||||
pbx_builtin_setvar_helper(chan,s5,s6);
|
||||
}
|
||||
lalares=malloc(sizeof(int));
|
||||
*lalares = ++i; // advance to the next row
|
||||
id1 = add_identifier(AST_PGSQL_ID_FETCHID,lalares);
|
||||
} else {
|
||||
ast_log(LOG_WARNING,"ast_PGSQL_fetch : EOF\n");
|
||||
id1 = 0; // no more rows
|
||||
}
|
||||
snprintf(s, sizeof(s), "%d", id1);
|
||||
ast_log(LOG_WARNING,"Setting var '%s' to value '%s'\n",fetchid_var,s);
|
||||
pbx_builtin_setvar_helper(chan,fetchid_var,s);
|
||||
break;
|
||||
}
|
||||
|
||||
free(s1);
|
||||
free(s2);
|
||||
return(res);
|
||||
}
|
||||
|
||||
static int aPGSQL_reset(struct ast_channel *chan, void *data) {
|
||||
|
||||
char *s1,*s3;
|
||||
int l;
|
||||
PGconn *karoto;
|
||||
int id;
|
||||
char *stringp=NULL;
|
||||
|
||||
|
||||
l=strlen(data)+2;
|
||||
s1=malloc(l);
|
||||
strncpy(s1, data, l - 1);
|
||||
stringp=s1;
|
||||
strsep(&stringp," "); // eat the first token, we already know it :P
|
||||
s3=strsep(&stringp," ");
|
||||
id=atoi(s3);
|
||||
if ((karoto=find_identifier(id,AST_PGSQL_ID_CONNID))==NULL) {
|
||||
ast_log(LOG_WARNING,"Invalid connection identifier %d passed in aPGSQL_reset\n",id);
|
||||
} else {
|
||||
PQreset(karoto);
|
||||
}
|
||||
free(s1);
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
static int aPGSQL_clear(struct ast_channel *chan, void *data) {
|
||||
|
||||
char *s1,*s3;
|
||||
int l;
|
||||
PGresult *karoto;
|
||||
int id;
|
||||
char *stringp=NULL;
|
||||
|
||||
|
||||
l=strlen(data)+2;
|
||||
s1=malloc(l);
|
||||
strncpy(s1, data, l - 1);
|
||||
stringp=s1;
|
||||
strsep(&stringp," "); // eat the first token, we already know it :P
|
||||
s3=strsep(&stringp," ");
|
||||
id=atoi(s3);
|
||||
if ((karoto=find_identifier(id,AST_PGSQL_ID_RESID))==NULL) {
|
||||
ast_log(LOG_WARNING,"Invalid result identifier %d passed in aPGSQL_clear\n",id);
|
||||
} else {
|
||||
PQclear(karoto);
|
||||
del_identifier(id,AST_PGSQL_ID_RESID);
|
||||
}
|
||||
free(s1);
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int aPGSQL_disconnect(struct ast_channel *chan, void *data) {
|
||||
|
||||
char *s1,*s3;
|
||||
int l;
|
||||
PGconn *karoto;
|
||||
int id;
|
||||
char *stringp=NULL;
|
||||
|
||||
|
||||
l=strlen(data)+2;
|
||||
s1=malloc(l);
|
||||
strncpy(s1, data, l - 1);
|
||||
stringp=s1;
|
||||
strsep(&stringp," "); // eat the first token, we already know it :P
|
||||
s3=strsep(&stringp," ");
|
||||
id=atoi(s3);
|
||||
if ((karoto=find_identifier(id,AST_PGSQL_ID_CONNID))==NULL) {
|
||||
ast_log(LOG_WARNING,"Invalid connection identifier %d passed in aPGSQL_disconnect\n",id);
|
||||
} else {
|
||||
PQfinish(karoto);
|
||||
del_identifier(id,AST_PGSQL_ID_CONNID);
|
||||
}
|
||||
free(s1);
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
static int aPGSQL_debug(struct ast_channel *chan, void *data) {
|
||||
ast_log(LOG_WARNING,"Debug : %s\n",(char *)data);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int PGSQL_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
struct localuser *u;
|
||||
int result;
|
||||
|
||||
#if EXTRA_LOG
|
||||
printf("PRSQL_exec: data=%s\n",(char*)data);
|
||||
#endif
|
||||
|
||||
if (!data) {
|
||||
ast_log(LOG_WARNING, "APP_PGSQL requires an argument (see manual)\n");
|
||||
return -1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
result=0;
|
||||
|
||||
if (strncasecmp("connect",data,strlen("connect"))==0) {
|
||||
result=(aPGSQL_connect(chan,data));
|
||||
} else if (strncasecmp("query",data,strlen("query"))==0) {
|
||||
result=(aPGSQL_query(chan,data));
|
||||
} else if (strncasecmp("fetch",data,strlen("fetch"))==0) {
|
||||
result=(aPGSQL_fetch(chan,data));
|
||||
} else if (strncasecmp("reset",data,strlen("reset"))==0) {
|
||||
result=(aPGSQL_reset(chan,data));
|
||||
} else if (strncasecmp("clear",data,strlen("clear"))==0) {
|
||||
result=(aPGSQL_clear(chan,data));
|
||||
} else if (strncasecmp("debug",data,strlen("debug"))==0) {
|
||||
result=(aPGSQL_debug(chan,data));
|
||||
} else if (strncasecmp("disconnect",data,strlen("disconnect"))==0) {
|
||||
result=(aPGSQL_disconnect(chan,data));
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Unknown APP_PGSQL argument : %s\n",(char *)data);
|
||||
result=-1;
|
||||
}
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
struct PGSQLidshead *headp;
|
||||
|
||||
headp=&PGSQLidshead;
|
||||
|
||||
AST_LIST_HEAD_INIT(headp);
|
||||
return ast_register_application(app, PGSQL_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
97
apps/app_striplsd.c
Normal file
97
apps/app_striplsd.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Skeleton application
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Strip trailing digits";
|
||||
|
||||
static char *descrip =
|
||||
" StripLSD(count): Strips the trailing 'count' digits from the channel's\n"
|
||||
"associated extension. For example, the number 5551212 when stripped with a\n"
|
||||
"count of 4 would be changed to 555. This app always returns 0, and the PBX\n"
|
||||
"will continue processing at the next priority for the *new* extension.\n"
|
||||
" So, for example, if priority 3 of 5551212 is StripLSD 4, the next step\n"
|
||||
"executed will be priority 4 of 555. If you switch into an extension which\n"
|
||||
"has no first step, the PBX will treat it as though the user dialed an\n"
|
||||
"invalid extension.\n";
|
||||
|
||||
static char *app = "StripLSD";
|
||||
|
||||
static char *synopsis = "Strip Least Significant Digits";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int striplsd_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
char newexten[AST_MAX_EXTENSION] = "";
|
||||
int maxbytes = 0;
|
||||
int stripcount = 0;
|
||||
int extlen = strlen(chan->exten);
|
||||
|
||||
maxbytes = sizeof(newexten) - 1;
|
||||
if (data) {
|
||||
stripcount = atoi(data);
|
||||
}
|
||||
if (!stripcount) {
|
||||
ast_log(LOG_DEBUG, "Ignoring, since number of digits to strip is 0\n");
|
||||
return 0;
|
||||
}
|
||||
if (extlen > stripcount) {
|
||||
if (extlen - stripcount <= maxbytes) {
|
||||
maxbytes = extlen - stripcount;
|
||||
}
|
||||
strncpy(newexten, chan->exten, maxbytes);
|
||||
}
|
||||
strncpy(chan->exten, newexten, sizeof(chan->exten)-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, striplsd_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
134
apps/app_substring.c
Normal file
134
apps/app_substring.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Skeleton application
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "(Deprecated) Save substring digits in a given variable";
|
||||
|
||||
static char *descrip =
|
||||
" (Deprecated, use ${variable:a:b} instead)\n"
|
||||
"\n"
|
||||
" SubString(variable=string_of_digits|count1|count2): Assigns the substring\n"
|
||||
"of string_of_digits to a given variable. Parameter count1 may be positive\n"
|
||||
"or negative. If it's positive then we skip the first count1 digits from the\n"
|
||||
"left. If it's negative, we move count1 digits counting from the end of\n"
|
||||
"the string to the left. Parameter count2 implies how many digits we are\n"
|
||||
"taking from the point that count1 placed us. If count2 is negative, then\n"
|
||||
"that many digits are omitted from the end.\n"
|
||||
"For example:\n"
|
||||
"exten => _NXXXXXX,1,SubString,test=2564286161|0|3\n"
|
||||
"assigns the area code (3 first digits) to variable test.\n"
|
||||
"exten => _NXXXXXX,1,SubString,test=2564286161|-7|7\n"
|
||||
"assigns the last 7 digits to variable test.\n"
|
||||
"exten => _NXXXXXX,1,SubString,test=2564286161|0|-4\n"
|
||||
"assigns all but the last 4 digits to variable test.\n"
|
||||
"If there are no parameters it'll return with -1.\n"
|
||||
"If there wrong parameters it go on and return with 0\n";
|
||||
|
||||
static char *app = "SubString";
|
||||
|
||||
static char *synopsis = "(Deprecated) Save substring digits in a given variable";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int substring_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
char newexten[AST_MAX_EXTENSION] = "";
|
||||
char *count1, *count2;
|
||||
char *first, *second, *stringp;
|
||||
|
||||
stringp=alloca(strlen(data)+1);
|
||||
ast_log(LOG_WARNING, "The use of Substring application is deprecated. Please use ${variable:a:b} instead\n");
|
||||
strncpy(stringp,data,strlen(data));
|
||||
if (strchr(stringp,'|')&&strchr(stringp,'=')) {
|
||||
int icount1,icount2;
|
||||
first=strsep(&stringp,"=");
|
||||
second=strsep(&stringp,"|");
|
||||
count1=strsep(&stringp,"|");
|
||||
count2=strsep(&stringp,"\0");
|
||||
if (!first || !second || !count1 || !count2) {
|
||||
ast_log(LOG_DEBUG, "Ignoring, since there is no argument: variable or string or count1 or count2\n");
|
||||
return 0;
|
||||
}
|
||||
icount1=atoi(count1);
|
||||
icount2=atoi(count2);
|
||||
if (icount2<0) {
|
||||
icount2 = icount2 + strlen(second);
|
||||
}
|
||||
if (abs(icount1)>strlen(second)) {
|
||||
ast_log(LOG_WARNING, "Limiting count1 parameter because it exceeds the length of the string\n");
|
||||
if (icount1>=0)
|
||||
icount1=strlen(second);
|
||||
else
|
||||
icount1=0;
|
||||
}
|
||||
if ((icount1<0 && icount2>-icount1) || (icount1>=0 && icount1+icount2>strlen(second))) {
|
||||
ast_log(LOG_WARNING, "Limiting count2 parameter because it exceeds the length of the string\n");
|
||||
if (icount1>=0)
|
||||
icount2=strlen(second)-icount1;
|
||||
else
|
||||
icount2=strlen(second)+icount1;
|
||||
}
|
||||
if (first&&second) {
|
||||
if (icount1>=0)
|
||||
strncpy(newexten,second+icount1,icount2);
|
||||
else
|
||||
strncpy(newexten,second+strlen(second)+icount1,icount2);
|
||||
pbx_builtin_setvar_helper(chan,first,newexten);
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_DEBUG, "Ignoring, no parameters\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, substring_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
69
apps/app_system.c
Executable file → Normal file
69
apps/app_system.c
Executable file → Normal file
@@ -3,54 +3,76 @@
|
||||
*
|
||||
* Execute arbitrary system commands
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
* Copyright (C) 1999-2004, Digium, Inc.
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
* Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/app.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
static char *tdesc = "Generic System() application";
|
||||
|
||||
static char *app = "System";
|
||||
|
||||
static char *app2 = "TrySystem";
|
||||
|
||||
static char *synopsis = "Execute a system command";
|
||||
|
||||
static char *synopsis2 = "Try executing a system command";
|
||||
|
||||
static char *descrip =
|
||||
" System(command): Executes a command by using system(). Returns -1 on\n"
|
||||
"failure to execute the specified command. If the command itself executes\n"
|
||||
"but is in error, and if there exists a priority n + 101, where 'n' is the\n"
|
||||
"priority of the current instance, then the channel will be setup to\n"
|
||||
"continue at that priority level. Otherwise, System returns 0.\n";
|
||||
|
||||
static char *descrip2 =
|
||||
" TrySystem(command): Executes a command by using system(). Returns 0\n"
|
||||
"on any situation. If the command itself executes but is in error, and if\n"
|
||||
"there exists a priority n + 101, where 'n' is the priority of the current\n"
|
||||
"instance, then the channel will be setup to continue at that\n"
|
||||
"priority level. Otherwise, System returns 0.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int skel_exec(struct ast_channel *chan, void *data)
|
||||
static int system_exec_helper(struct ast_channel *chan, void *data, int failmode)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
if (!data) {
|
||||
ast_log(LOG_WARNING, "System requires an argument(command)\n");
|
||||
return -1;
|
||||
return failmode;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
/* Do our thing here */
|
||||
res = system((char *)data);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to execute '%s'\n", data);
|
||||
res = -1;
|
||||
res = ast_safe_system((char *)data);
|
||||
if ((res < 0) && (errno != ECHILD)) {
|
||||
ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
|
||||
res = failmode;
|
||||
} else if (res == 127) {
|
||||
ast_log(LOG_WARNING, "Unable to execute '%s'\n", data);
|
||||
res = -1;
|
||||
ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
|
||||
res = failmode;
|
||||
} else {
|
||||
if (res && ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101))
|
||||
if (res < 0)
|
||||
res = 0;
|
||||
if (res && ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority+=100;
|
||||
res = 0;
|
||||
}
|
||||
@@ -58,15 +80,27 @@ static int skel_exec(struct ast_channel *chan, void *data)
|
||||
return res;
|
||||
}
|
||||
|
||||
static int system_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
return system_exec_helper(chan, data, -1);
|
||||
}
|
||||
|
||||
static int trysystem_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
return system_exec_helper(chan, data, 0);
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
ast_unregister_application(app2);
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, skel_exec);
|
||||
ast_register_application(app2, trysystem_exec, synopsis2, descrip2);
|
||||
return ast_register_application(app, system_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
@@ -80,3 +114,8 @@ int usecount(void)
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
|
||||
218
apps/app_talkdetect.c
Normal file
218
apps/app_talkdetect.c
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Playback a file with audio detect
|
||||
*
|
||||
* Copyright (C) 2004, Digium, Inc.
|
||||
*
|
||||
* Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <asterisk/dsp.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Playback with Talk Detection";
|
||||
|
||||
static char *app = "BackgroundDetect";
|
||||
|
||||
static char *synopsis = "Background a file with talk detect";
|
||||
|
||||
static char *descrip =
|
||||
" BackgroundDetect(filename[|sil[|min|[max]]]): Plays back a given\n"
|
||||
"filename, waiting for interruption from a given digit (the digit must\n"
|
||||
"start the beginning of a valid extension, or it will be ignored).\n"
|
||||
"During the playback of the file, audio is monitored in the receive\n"
|
||||
"direction, and if a period of non-silence which is greater than 'min' ms\n"
|
||||
"yet less than 'max' ms is followed by silence for at least 'sil' ms then\n"
|
||||
"the audio playback is aborted and processing jumps to the 'talk' extension\n"
|
||||
"if available. If unspecified, sil, min, and max default to 1000, 100, and\n"
|
||||
"infinity respectively. Returns -1 on hangup, and 0 on successful playback\n"
|
||||
"completion with no exit conditions.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int background_detect_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
struct localuser *u;
|
||||
char tmp[256];
|
||||
char *options;
|
||||
char *stringp;
|
||||
struct ast_frame *fr;
|
||||
int notsilent=0;
|
||||
struct timeval start = { 0, 0}, end = {0, 0};
|
||||
int sil = 1000;
|
||||
int min = 100;
|
||||
int max = -1;
|
||||
int x;
|
||||
int origrformat=0;
|
||||
struct ast_dsp *dsp;
|
||||
if (!data || ast_strlen_zero((char *)data)) {
|
||||
ast_log(LOG_WARNING, "BackgroundDetect requires an argument (filename)\n");
|
||||
return -1;
|
||||
}
|
||||
strncpy(tmp, (char *)data, sizeof(tmp)-1);
|
||||
stringp=tmp;
|
||||
strsep(&stringp, "|");
|
||||
options = strsep(&stringp, "|");
|
||||
if (options) {
|
||||
if ((sscanf(options, "%d", &x) == 1) && (x > 0))
|
||||
sil = x;
|
||||
options = strsep(&stringp, "|");
|
||||
if (options) {
|
||||
if ((sscanf(options, "%d", &x) == 1) && (x > 0))
|
||||
min = x;
|
||||
options = strsep(&stringp, "|");
|
||||
if (options) {
|
||||
if ((sscanf(options, "%d", &x) == 1) && (x > 0))
|
||||
max = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
ast_log(LOG_DEBUG, "Preparing detect of '%s', sil=%d,min=%d,max=%d\n",
|
||||
tmp, sil, min, max);
|
||||
LOCAL_USER_ADD(u);
|
||||
if (chan->_state != AST_STATE_UP) {
|
||||
/* Otherwise answer unless we're supposed to send this while on-hook */
|
||||
res = ast_answer(chan);
|
||||
}
|
||||
if (!res) {
|
||||
origrformat = chan->readformat;
|
||||
if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)))
|
||||
ast_log(LOG_WARNING, "Unable to set read format to linear!\n");
|
||||
}
|
||||
if (!(dsp = ast_dsp_new())) {
|
||||
ast_log(LOG_WARNING, "Unable to allocate DSP!\n");
|
||||
res = -1;
|
||||
}
|
||||
if (!res) {
|
||||
ast_stopstream(chan);
|
||||
res = ast_streamfile(chan, tmp, chan->language);
|
||||
if (!res) {
|
||||
while(chan->stream) {
|
||||
res = ast_sched_wait(chan->sched);
|
||||
if ((res < 0) && !chan->timingfunc) {
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
if (res < 0)
|
||||
res = 1000;
|
||||
res = ast_waitfor(chan, res);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_WARNING, "Waitfor failed on %s\n", chan->name);
|
||||
break;
|
||||
} else if (res > 0) {
|
||||
fr = ast_read(chan);
|
||||
if (!fr) {
|
||||
res = -1;
|
||||
break;
|
||||
} else if (fr->frametype == AST_FRAME_DTMF) {
|
||||
char t[2];
|
||||
t[0] = fr->subclass;
|
||||
t[1] = '\0';
|
||||
if (ast_canmatch_extension(chan, chan->context, t, 1, chan->callerid)) {
|
||||
/* They entered a valid extension, or might be anyhow */
|
||||
res = fr->subclass;
|
||||
ast_frfree(fr);
|
||||
break;
|
||||
}
|
||||
} else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR)) {
|
||||
int totalsilence;
|
||||
int ms;
|
||||
res = ast_dsp_silence(dsp, fr, &totalsilence);
|
||||
if (res && (totalsilence > sil)) {
|
||||
/* We've been quiet a little while */
|
||||
if (notsilent) {
|
||||
/* We had heard some talking */
|
||||
gettimeofday(&end, NULL);
|
||||
ms = (end.tv_sec - start.tv_sec) * 1000;
|
||||
ms += (end.tv_usec - start.tv_usec) / 1000;
|
||||
ms -= sil;
|
||||
if (ms < 0)
|
||||
ms = 0;
|
||||
if ((ms > min) && ((max < 0) || (ms < max))) {
|
||||
ast_log(LOG_DEBUG, "Found qualified token of %d ms\n", ms);
|
||||
if (ast_exists_extension(chan, chan->context, "talk", 1, chan->callerid)) {
|
||||
strncpy(chan->exten, "talk", sizeof(chan->exten) -1 );
|
||||
chan->priority = 0;
|
||||
}
|
||||
res = 0;
|
||||
ast_frfree(fr);
|
||||
break;
|
||||
} else
|
||||
ast_log(LOG_DEBUG, "Found unqualified token of %d ms\n", ms);
|
||||
notsilent = 0;
|
||||
}
|
||||
} else {
|
||||
if (!notsilent) {
|
||||
/* Heard some audio, mark the begining of the token */
|
||||
gettimeofday(&start, NULL);
|
||||
ast_log(LOG_DEBUG, "Start of voice token!\n");
|
||||
notsilent = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ast_frfree(fr);
|
||||
}
|
||||
ast_sched_runq(chan->sched);
|
||||
}
|
||||
ast_stopstream(chan);
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
if (res > -1) {
|
||||
if (origrformat && ast_set_read_format(chan, origrformat)) {
|
||||
ast_log(LOG_WARNING, "Failed to restore read format for %s to %s\n",
|
||||
chan->name, ast_getformatname(origrformat));
|
||||
}
|
||||
}
|
||||
if (dsp)
|
||||
ast_dsp_free(dsp);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, background_detect_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
473
apps/app_test.c
Normal file
473
apps/app_test.c
Normal file
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Applications to test connection and produce report in text file
|
||||
*
|
||||
* Copyright (C) 2004, Digium, Inc.
|
||||
*
|
||||
* Mark Spencer <markster@digium.com>
|
||||
* Russell Bryant <russelb@clemson.edu>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/app.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "../astconf.h"
|
||||
|
||||
|
||||
static char *tdesc = "Interface Test Application";
|
||||
|
||||
static char *tests_descrip =
|
||||
"TestServer(): Perform test server function and write call report.\n"
|
||||
"Results stored in /var/log/asterisk/testreports/<testid>-server.txt";
|
||||
static char *tests_app = "TestServer";
|
||||
static char *tests_synopsis = "Execute Interface Test Server";
|
||||
|
||||
static char *testc_descrip =
|
||||
"TestClient(testid): Executes test client with given testid.\n"
|
||||
"Results stored in /var/log/asterisk/testreports/<testid>-client.txt";
|
||||
|
||||
static char *testc_app = "TestClient";
|
||||
static char *testc_synopsis = "Execute Interface Test Client";
|
||||
|
||||
static int measurenoise(struct ast_channel *chan, int ms, char *who)
|
||||
{
|
||||
int res=0;
|
||||
int mssofar;
|
||||
int noise=0;
|
||||
int samples=0;
|
||||
int x;
|
||||
short *foo;
|
||||
struct timeval start, tv;
|
||||
struct ast_frame *f;
|
||||
int rformat;
|
||||
rformat = chan->readformat;
|
||||
if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
|
||||
ast_log(LOG_NOTICE, "Unable to set to linear mode!\n");
|
||||
return -1;
|
||||
}
|
||||
gettimeofday(&start, NULL);
|
||||
for(;;) {
|
||||
gettimeofday(&tv, NULL);
|
||||
mssofar = (tv.tv_sec - start.tv_sec) * 1000;
|
||||
mssofar += (tv.tv_usec - start.tv_usec) / 1000;
|
||||
if (mssofar > ms)
|
||||
break;
|
||||
res = ast_waitfor(chan, ms - mssofar);
|
||||
if (res < 1)
|
||||
break;
|
||||
f = ast_read(chan);
|
||||
if (!f) {
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
if ((f->frametype == AST_FRAME_VOICE) && (f->subclass == AST_FORMAT_SLINEAR)) {
|
||||
foo = (short *)f->data;
|
||||
for (x=0;x<f->samples;x++) {
|
||||
noise += abs(foo[x]);
|
||||
samples++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rformat) {
|
||||
if (ast_set_read_format(chan, rformat)) {
|
||||
ast_log(LOG_NOTICE, "Unable to restore original format!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (res < 0)
|
||||
return res;
|
||||
if (!samples) {
|
||||
ast_log(LOG_NOTICE, "No samples were received from the other side!\n");
|
||||
return -1;
|
||||
}
|
||||
ast_log(LOG_DEBUG, "%s: Noise: %d, samples: %d, avg: %d\n", who, noise, samples, noise / samples);
|
||||
return (noise / samples);
|
||||
}
|
||||
|
||||
static int sendnoise(struct ast_channel *chan, int ms)
|
||||
{
|
||||
int res;
|
||||
res = ast_tonepair_start(chan, 1537, 2195, ms, 8192);
|
||||
if (!res) {
|
||||
res = ast_waitfordigit(chan, ms);
|
||||
ast_tonepair_stop(chan);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int testclient_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
struct localuser *u;
|
||||
int res = 0;
|
||||
char *testid=data;
|
||||
char fn[80];
|
||||
char serverver[80];
|
||||
FILE *f;
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
/* Check for test id */
|
||||
if (!testid || ast_strlen_zero(testid)) {
|
||||
ast_log(LOG_WARNING, "TestClient requires an argument - the test id\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (chan->_state != AST_STATE_UP)
|
||||
res = ast_answer(chan);
|
||||
|
||||
/* Wait a few just to be sure things get started */
|
||||
res = ast_safe_sleep(chan, 3000);
|
||||
/* Transmit client version */
|
||||
if (!res)
|
||||
res = ast_dtmf_stream(chan, NULL, "8378*1#", 0);
|
||||
ast_log(LOG_DEBUG, "Transmit client version\n");
|
||||
|
||||
/* Read server version */
|
||||
ast_log(LOG_DEBUG, "Read server version\n");
|
||||
if (!res)
|
||||
res = ast_app_getdata(chan, NULL, serverver, sizeof(serverver) - 1, 0);
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
ast_log(LOG_DEBUG, "server version: %s\n", serverver);
|
||||
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
|
||||
if (!res)
|
||||
res = ast_safe_sleep(chan, 1000);
|
||||
/* Send test id */
|
||||
if (!res)
|
||||
res = ast_dtmf_stream(chan, NULL, testid, 0);
|
||||
if (!res)
|
||||
res = ast_dtmf_stream(chan, NULL, "#", 0);
|
||||
ast_log(LOG_DEBUG, "send test identifier: %s\n", testid);
|
||||
|
||||
if ((res >=0) && (!ast_strlen_zero(testid))) {
|
||||
/* Make the directory to hold the test results in case it's not there */
|
||||
snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR);
|
||||
mkdir(fn, 0777);
|
||||
snprintf(fn, sizeof(fn), "%s/testresults/%s-client.txt", ast_config_AST_LOG_DIR, testid);
|
||||
if ((f = fopen(fn, "w+"))) {
|
||||
setlinebuf(f);
|
||||
fprintf(f, "CLIENTCHAN: %s\n", chan->name);
|
||||
fprintf(f, "CLIENTTEST ID: %s\n", testid);
|
||||
fprintf(f, "ANSWER: PASS\n");
|
||||
res = 0;
|
||||
|
||||
if (!res) {
|
||||
/* Step 1: Wait for "1" */
|
||||
ast_log(LOG_DEBUG, "TestClient: 2. Wait DTMF 1\n");
|
||||
res = ast_waitfordigit(chan, 3000);
|
||||
fprintf(f, "WAIT DTMF 1: %s\n", (res != '1') ? "FAIL" : "PASS");
|
||||
if (res == '1')
|
||||
res = 0;
|
||||
else
|
||||
res = -1;
|
||||
}
|
||||
if (!res)
|
||||
res = ast_safe_sleep(chan, 1000);
|
||||
if (!res) {
|
||||
/* Step 2: Send "2" */
|
||||
ast_log(LOG_DEBUG, "TestClient: 2. Send DTMF 2\n");
|
||||
res = ast_dtmf_stream(chan, NULL, "2", 0);
|
||||
fprintf(f, "SEND DTMF 2: %s\n", (res < 0) ? "FAIL" : "PASS");
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
}
|
||||
if (!res) {
|
||||
/* Step 3: Wait one second */
|
||||
ast_log(LOG_DEBUG, "TestClient: 3. Wait one second\n");
|
||||
res = ast_safe_sleep(chan, 1000);
|
||||
fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
}
|
||||
if (!res) {
|
||||
/* Step 4: Measure noise */
|
||||
ast_log(LOG_DEBUG, "TestClient: 4. Measure noise\n");
|
||||
res = measurenoise(chan, 5000, "TestClient");
|
||||
fprintf(f, "MEASURENOISE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
}
|
||||
if (!res) {
|
||||
/* Step 5: Wait for "4" */
|
||||
ast_log(LOG_DEBUG, "TestClient: 5. Wait DTMF 4\n");
|
||||
res = ast_waitfordigit(chan, 3000);
|
||||
fprintf(f, "WAIT DTMF 4: %s\n", (res != '4') ? "FAIL" : "PASS");
|
||||
if (res == '4')
|
||||
res = 0;
|
||||
else
|
||||
res = -1;
|
||||
}
|
||||
if (!res) {
|
||||
/* Step 6: Transmit tone noise */
|
||||
ast_log(LOG_DEBUG, "TestClient: 6. Transmit tone\n");
|
||||
res = sendnoise(chan, 6000);
|
||||
fprintf(f, "SENDTONE: %s\n", (res < 0) ? "FAIL" : "PASS");
|
||||
}
|
||||
if (!res || (res == '5')) {
|
||||
/* Step 7: Wait for "5" */
|
||||
ast_log(LOG_DEBUG, "TestClient: 7. Wait DTMF 5\n");
|
||||
if (!res)
|
||||
res = ast_waitfordigit(chan, 3000);
|
||||
fprintf(f, "WAIT DTMF 5: %s\n", (res != '5') ? "FAIL" : "PASS");
|
||||
if (res == '5')
|
||||
res = 0;
|
||||
else
|
||||
res = -1;
|
||||
}
|
||||
if (!res) {
|
||||
/* Step 8: Wait one second */
|
||||
ast_log(LOG_DEBUG, "TestClient: 8. Wait one second\n");
|
||||
res = ast_safe_sleep(chan, 1000);
|
||||
fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
}
|
||||
if (!res) {
|
||||
/* Step 9: Measure noise */
|
||||
ast_log(LOG_DEBUG, "TestClient: 6. Measure tone\n");
|
||||
res = measurenoise(chan, 4000, "TestClient");
|
||||
fprintf(f, "MEASURETONE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
}
|
||||
if (!res) {
|
||||
/* Step 10: Send "7" */
|
||||
ast_log(LOG_DEBUG, "TestClient: 7. Send DTMF 7\n");
|
||||
res = ast_dtmf_stream(chan, NULL, "7", 0);
|
||||
fprintf(f, "SEND DTMF 7: %s\n", (res < 0) ? "FAIL" : "PASS");
|
||||
if (res > 0)
|
||||
res =0;
|
||||
}
|
||||
if (!res) {
|
||||
/* Step 11: Wait for "8" */
|
||||
ast_log(LOG_DEBUG, "TestClient: 11. Wait DTMF 8\n");
|
||||
res = ast_waitfordigit(chan, 3000);
|
||||
fprintf(f, "WAIT DTMF 8: %s\n", (res != '8') ? "FAIL" : "PASS");
|
||||
if (res == '8')
|
||||
res = 0;
|
||||
else
|
||||
res = -1;
|
||||
}
|
||||
if (!res) {
|
||||
/* Step 12: Hangup! */
|
||||
ast_log(LOG_DEBUG, "TestClient: 12. Hangup\n");
|
||||
}
|
||||
|
||||
ast_log(LOG_DEBUG, "-- TEST COMPLETE--\n");
|
||||
fprintf(f, "-- END TEST--\n");
|
||||
fclose(f);
|
||||
res = -1;
|
||||
} else
|
||||
res = -1;
|
||||
} else {
|
||||
ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", chan->name);
|
||||
res = -1;
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int testserver_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
struct localuser *u;
|
||||
int res = 0;
|
||||
char testid[80]="";
|
||||
char fn[80];
|
||||
FILE *f;
|
||||
LOCAL_USER_ADD(u);
|
||||
if (chan->_state != AST_STATE_UP)
|
||||
res = ast_answer(chan);
|
||||
/* Read version */
|
||||
ast_log(LOG_DEBUG, "Read client version\n");
|
||||
if (!res)
|
||||
res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0);
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
ast_log(LOG_DEBUG, "client version: %s\n", testid);
|
||||
ast_log(LOG_DEBUG, "Transmit server version\n");
|
||||
res = ast_safe_sleep(chan, 1000);
|
||||
if (!res)
|
||||
res = ast_dtmf_stream(chan, NULL, "8378*1#", 0);
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
|
||||
if (!res)
|
||||
res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0);
|
||||
ast_log(LOG_DEBUG, "read test identifier: %s\n", testid);
|
||||
/* Check for sneakyness */
|
||||
if (strchr(testid, '/'))
|
||||
res = -1;
|
||||
if ((res >=0) && (!ast_strlen_zero(testid))) {
|
||||
/* Got a Test ID! Whoo hoo! */
|
||||
/* Make the directory to hold the test results in case it's not there */
|
||||
snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR);
|
||||
mkdir(fn, 0777);
|
||||
snprintf(fn, sizeof(fn), "%s/testresults/%s-server.txt", ast_config_AST_LOG_DIR, testid);
|
||||
if ((f = fopen(fn, "w+"))) {
|
||||
setlinebuf(f);
|
||||
fprintf(f, "SERVERCHAN: %s\n", chan->name);
|
||||
fprintf(f, "SERVERTEST ID: %s\n", testid);
|
||||
fprintf(f, "ANSWER: PASS\n");
|
||||
ast_log(LOG_DEBUG, "Processing Test ID '%s'\n", testid);
|
||||
res = ast_safe_sleep(chan, 1000);
|
||||
if (!res) {
|
||||
/* Step 1: Send "1" */
|
||||
ast_log(LOG_DEBUG, "TestServer: 1. Send DTMF 1\n");
|
||||
res = ast_dtmf_stream(chan, NULL, "1", 0);
|
||||
fprintf(f, "SEND DTMF 1: %s\n", (res < 0) ? "FAIL" : "PASS");
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
}
|
||||
if (!res) {
|
||||
/* Step 2: Wait for "2" */
|
||||
ast_log(LOG_DEBUG, "TestServer: 2. Wait DTMF 2\n");
|
||||
res = ast_waitfordigit(chan, 3000);
|
||||
fprintf(f, "WAIT DTMF 2: %s\n", (res != '2') ? "FAIL" : "PASS");
|
||||
if (res == '2')
|
||||
res = 0;
|
||||
else
|
||||
res = -1;
|
||||
}
|
||||
if (!res) {
|
||||
/* Step 3: Measure noise */
|
||||
ast_log(LOG_DEBUG, "TestServer: 3. Measure noise\n");
|
||||
res = measurenoise(chan, 6000, "TestServer");
|
||||
fprintf(f, "MEASURENOISE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
}
|
||||
if (!res) {
|
||||
/* Step 4: Send "4" */
|
||||
ast_log(LOG_DEBUG, "TestServer: 4. Send DTMF 4\n");
|
||||
res = ast_dtmf_stream(chan, NULL, "4", 0);
|
||||
fprintf(f, "SEND DTMF 4: %s\n", (res < 0) ? "FAIL" : "PASS");
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
/* Step 5: Wait one second */
|
||||
ast_log(LOG_DEBUG, "TestServer: 5. Wait one second\n");
|
||||
res = ast_safe_sleep(chan, 1000);
|
||||
fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
/* Step 6: Measure noise */
|
||||
ast_log(LOG_DEBUG, "TestServer: 6. Measure tone\n");
|
||||
res = measurenoise(chan, 4000, "TestServer");
|
||||
fprintf(f, "MEASURETONE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
/* Step 7: Send "5" */
|
||||
ast_log(LOG_DEBUG, "TestServer: 7. Send DTMF 5\n");
|
||||
res = ast_dtmf_stream(chan, NULL, "5", 0);
|
||||
fprintf(f, "SEND DTMF 5: %s\n", (res < 0) ? "FAIL" : "PASS");
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
/* Step 8: Transmit tone noise */
|
||||
ast_log(LOG_DEBUG, "TestServer: 8. Transmit tone\n");
|
||||
res = sendnoise(chan, 6000);
|
||||
fprintf(f, "SENDTONE: %s\n", (res < 0) ? "FAIL" : "PASS");
|
||||
}
|
||||
|
||||
if (!res || (res == '7')) {
|
||||
/* Step 9: Wait for "7" */
|
||||
ast_log(LOG_DEBUG, "TestServer: 9. Wait DTMF 7\n");
|
||||
if (!res)
|
||||
res = ast_waitfordigit(chan, 3000);
|
||||
fprintf(f, "WAIT DTMF 7: %s\n", (res != '7') ? "FAIL" : "PASS");
|
||||
if (res == '7')
|
||||
res = 0;
|
||||
else
|
||||
res = -1;
|
||||
}
|
||||
if (!res)
|
||||
res = ast_safe_sleep(chan, 1000);
|
||||
if (!res) {
|
||||
/* Step 10: Send "8" */
|
||||
ast_log(LOG_DEBUG, "TestServer: 10. Send DTMF 8\n");
|
||||
res = ast_dtmf_stream(chan, NULL, "8", 0);
|
||||
fprintf(f, "SEND DTMF 8: %s\n", (res < 0) ? "FAIL" : "PASS");
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
}
|
||||
if (!res) {
|
||||
/* Step 11: Wait for hangup to arrive! */
|
||||
ast_log(LOG_DEBUG, "TestServer: 11. Waiting for hangup\n");
|
||||
res = ast_safe_sleep(chan, 10000);
|
||||
fprintf(f, "WAIT HANGUP: %s\n", (res < 0) ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
ast_log(LOG_DEBUG, "-- TEST COMPLETE--\n");
|
||||
fprintf(f, "-- END TEST--\n");
|
||||
fclose(f);
|
||||
res = -1;
|
||||
} else
|
||||
res = -1;
|
||||
} else {
|
||||
ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", chan->name);
|
||||
res = -1;
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
ast_unregister_application(testc_app);
|
||||
return ast_unregister_application(tests_app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
ast_register_application(testc_app, testclient_exec, testc_synopsis, testc_descrip);
|
||||
return ast_register_application(tests_app, testserver_exec, tests_synopsis, tests_descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key(void)
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
91
apps/app_transfer.c
Normal file
91
apps/app_transfer.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Transfer a caller
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Transfer";
|
||||
|
||||
static char *app = "Transfer";
|
||||
|
||||
static char *synopsis = "Transfer caller to remote extension";
|
||||
|
||||
static char *descrip =
|
||||
" Transfer(exten): Requests the remote caller be transferred to\n"
|
||||
"a given extension. Returns -1 on hangup, or 0 on completion\n"
|
||||
"regardless of whether the transfer was successful. If the transfer\n"
|
||||
"was *not* supported or successful and there exists a priority n + 101,\n"
|
||||
"then that priority will be taken next.\n" ;
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int transfer_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
struct localuser *u;
|
||||
if (!data || !strlen(data)) {
|
||||
ast_log(LOG_WARNING, "Transfer requires an argument (destination)\n");
|
||||
res = 1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
if (!res) {
|
||||
res = ast_transfer(chan, data);
|
||||
}
|
||||
if (!res) {
|
||||
/* Look for a "busy" place */
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority += 100;
|
||||
}
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, transfer_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
145
apps/app_txtcidname.c
Normal file
145
apps/app_txtcidname.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Caller*id name lookup - Look up the caller's name via DNS
|
||||
*
|
||||
* Copyright (C) 1999-2004, Digium
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/enum.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static char *tdesc = "TXTCIDName";
|
||||
|
||||
static char *app = "TXTCIDName";
|
||||
|
||||
static char *synopsis = "Lookup caller name from TXT record";
|
||||
|
||||
static char *descrip =
|
||||
" TXTLookup(CallerID): Looks up a Caller Name via DNS and sets\n"
|
||||
"the variable 'TXTCIDNAME'. TXTCIDName will either be blank\n"
|
||||
"or return the value found in the TXT record in DNS.\n" ;
|
||||
|
||||
#define ENUM_CONFIG "enum.conf"
|
||||
|
||||
static char h323driver[80] = "";
|
||||
#define H323DRIVERDEFAULT "H323"
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int txtcidname_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=0;
|
||||
char tech[80];
|
||||
char txt[256] = "";
|
||||
char dest[80];
|
||||
|
||||
struct localuser *u;
|
||||
if (!data || !strlen(data)) {
|
||||
ast_log(LOG_WARNING, "TXTCIDName requires an argument (extension)\n");
|
||||
res = 1;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
if (!res) {
|
||||
res = ast_get_txt(chan, data, dest, sizeof(dest), tech, sizeof(tech), txt, sizeof(txt));
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
/* Parse it out */
|
||||
if (res > 0) {
|
||||
if (!ast_strlen_zero(txt)) {
|
||||
pbx_builtin_setvar_helper(chan, "TXTCIDNAME", txt);
|
||||
#if 0
|
||||
ast_log(LOG_DEBUG, "TXTCIDNAME got '%s'\n", txt);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (!res) {
|
||||
/* Look for a "busy" place */
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority += 100;
|
||||
} else if (res > 0)
|
||||
res = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
static int load_config(void)
|
||||
{
|
||||
struct ast_config *cfg;
|
||||
char *s;
|
||||
|
||||
cfg = ast_load(ENUM_CONFIG);
|
||||
if (cfg) {
|
||||
if (!(s=ast_variable_retrieve(cfg, "general", "h323driver"))) {
|
||||
strncpy(h323driver, H323DRIVERDEFAULT, sizeof(h323driver) - 1);
|
||||
} else {
|
||||
strncpy(h323driver, s, sizeof(h323driver) - 1);
|
||||
}
|
||||
ast_destroy(cfg);
|
||||
return 0;
|
||||
}
|
||||
ast_log(LOG_NOTICE, "No ENUM Config file, using defaults\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
int res;
|
||||
res = ast_register_application(app, txtcidname_exec, synopsis, descrip);
|
||||
if (res)
|
||||
return(res);
|
||||
if ((res=load_config())) {
|
||||
return(res);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int reload(void)
|
||||
{
|
||||
return(load_config());
|
||||
}
|
||||
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
|
||||
139
apps/app_url.c
Normal file
139
apps/app_url.c
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* App to transmit a URL
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/image.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Send URL Applications";
|
||||
|
||||
static char *app = "SendURL";
|
||||
|
||||
static char *synopsis = "Send a URL";
|
||||
|
||||
static char *descrip =
|
||||
" SendURL(URL[|option]): Requests client go to URL. If the client\n"
|
||||
"does not support html transport, and there exists a step with\n"
|
||||
"priority n + 101, then execution will continue at that step.\n"
|
||||
"Otherwise, execution will continue at the next priority level.\n"
|
||||
"SendURL only returns 0 if the URL was sent correctly or if\n"
|
||||
"the channel does not support HTML transport, and -1 otherwise.\n"
|
||||
"If the option 'wait' is specified, execution will wait for an\n"
|
||||
"acknowledgement that the URL has been loaded before continuing\n"
|
||||
"and will return -1 if the peer is unable to load the URL\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int sendurl_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
struct localuser *u;
|
||||
char tmp[256];
|
||||
char *options;
|
||||
int option_wait=0;
|
||||
struct ast_frame *f;
|
||||
char *stringp=NULL;
|
||||
if (!data || !strlen((char *)data)) {
|
||||
ast_log(LOG_WARNING, "SendURL requires an argument (URL)\n");
|
||||
return -1;
|
||||
}
|
||||
strncpy(tmp, (char *)data, sizeof(tmp)-1);
|
||||
stringp=tmp;
|
||||
strsep(&stringp, "|");
|
||||
options = strsep(&stringp, "|");
|
||||
if (options && !strcasecmp(options, "wait"))
|
||||
option_wait = 1;
|
||||
LOCAL_USER_ADD(u);
|
||||
if (!ast_channel_supports_html(chan)) {
|
||||
/* Does not support transport */
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority += 100;
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return 0;
|
||||
}
|
||||
res = ast_channel_sendurl(chan, tmp);
|
||||
if (res > -1) {
|
||||
if (option_wait) {
|
||||
for(;;) {
|
||||
/* Wait for an event */
|
||||
res = ast_waitfor(chan, -1);
|
||||
if (res < 0)
|
||||
break;
|
||||
f = ast_read(chan);
|
||||
if (!f) {
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
if (f->frametype == AST_FRAME_HTML) {
|
||||
switch(f->subclass) {
|
||||
case AST_HTML_LDCOMPLETE:
|
||||
res = 0;
|
||||
ast_frfree(f);
|
||||
goto out;
|
||||
break;
|
||||
case AST_HTML_NOSUPPORT:
|
||||
/* Does not support transport */
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
|
||||
chan->priority += 100;
|
||||
res = 0;
|
||||
goto out;
|
||||
break;
|
||||
default:
|
||||
ast_log(LOG_WARNING, "Don't know what to do with HTML subclass %d\n", f->subclass);
|
||||
};
|
||||
}
|
||||
ast_frfree(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, sendurl_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
106
apps/app_userevent.c
Normal file
106
apps/app_userevent.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* UserEvent application -- send manager event
|
||||
*
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/manager.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Custom User Event Application";
|
||||
|
||||
static char *app = "UserEvent";
|
||||
|
||||
static char *synopsis = "Send an arbitrary event to the manager interface";
|
||||
|
||||
static char *descrip =
|
||||
" UserEvent(eventname[|body]): Sends an arbitrary event to the\n"
|
||||
"manager interface, with an optional body representing additional\n"
|
||||
"arguments. The format of the event will be:\n"
|
||||
" Event: UserEvent<specified event name>\n"
|
||||
" Channel: <channel name>\n"
|
||||
" Uniqueid: <call uniqueid>\n"
|
||||
" [body]\n"
|
||||
"If the body is not specified, only Event, Channel, and Uniqueid fields\n"
|
||||
"will be present. Returns 0.";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int userevent_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
struct localuser *u;
|
||||
char info[512];
|
||||
char eventname[512];
|
||||
char *eventbody;
|
||||
|
||||
if (!data || !strlen(data)) {
|
||||
ast_log(LOG_WARNING, "UserEvent requires an argument (eventname|optional event body)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION-1);
|
||||
snprintf(eventname, sizeof(eventname), "UserEvent%s", info);
|
||||
eventbody = strchr(eventname, '|');
|
||||
if (eventbody) {
|
||||
*eventbody = '\0';
|
||||
eventbody++;
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
if(eventbody) {
|
||||
ast_log(LOG_DEBUG, "Sending user event: %s, %s\n", eventname, eventbody);
|
||||
manager_event(EVENT_FLAG_USER, eventname,
|
||||
"Channel: %s\r\nUniqueid: %s\r\n%s\r\n",
|
||||
chan->name, chan->uniqueid, eventbody);
|
||||
} else {
|
||||
ast_log(LOG_DEBUG, "Sending user event: %s\n", eventname);
|
||||
manager_event(EVENT_FLAG_USER, eventname,
|
||||
"Channel: %s\r\nUniqueid: %s\r\n", chan->name, chan->uniqueid);
|
||||
}
|
||||
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, userevent_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
110
apps/app_verbose.c
Normal file
110
apps/app_verbose.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Verbose application
|
||||
*
|
||||
* Copyright (c) 2004 Tilghman Lesher. All rights reserved.
|
||||
*
|
||||
* Tilghman Lesher <app_verbose_v001@the-tilghman.com>
|
||||
*
|
||||
* This code is released by the author with no restrictions on usage.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
|
||||
|
||||
static char *tdesc = "Send verbose output";
|
||||
|
||||
static char *app_verbose = "Verbose";
|
||||
|
||||
static char *verbose_synopsis = "Send arbitrary text to verbose output";
|
||||
|
||||
static char *verbose_descrip =
|
||||
"Verbose([<level>|]<message>)\n"
|
||||
" level must be an integer value. If not specified, defaults to 0."
|
||||
" Always returns 0.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int verbose_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
char *vtext;
|
||||
int vsize;
|
||||
|
||||
if (data) {
|
||||
vtext = ast_strdupa((char *)data);
|
||||
if (vtext) {
|
||||
char *tmp = strsep(&vtext, "|,");
|
||||
if (vtext) {
|
||||
if (sscanf(tmp, "%d", &vsize) != 1) {
|
||||
vsize = 0;
|
||||
ast_log(LOG_WARNING, "'%s' is not a verboser number\n", vtext);
|
||||
}
|
||||
} else {
|
||||
vtext = tmp;
|
||||
vsize = 0;
|
||||
}
|
||||
if (option_verbose >= vsize) {
|
||||
switch (vsize) {
|
||||
case 0:
|
||||
ast_verbose("%s\n", vtext);
|
||||
break;
|
||||
case 1:
|
||||
ast_verbose(VERBOSE_PREFIX_1 "%s\n", vtext);
|
||||
break;
|
||||
case 2:
|
||||
ast_verbose(VERBOSE_PREFIX_2 "%s\n", vtext);
|
||||
break;
|
||||
case 3:
|
||||
ast_verbose(VERBOSE_PREFIX_3 "%s\n", vtext);
|
||||
break;
|
||||
default:
|
||||
ast_verbose(VERBOSE_PREFIX_4 "%s\n", vtext);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_ERROR, "Out of memory\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app_verbose);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app_verbose, verbose_exec, verbose_synopsis, verbose_descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
5132
apps/app_voicemail.c
Executable file → Normal file
5132
apps/app_voicemail.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
129
apps/app_waitforring.c
Normal file
129
apps/app_waitforring.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Wait for Ring Application
|
||||
*
|
||||
* Copyright (C) 2003, Digium
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *synopsis = "Wait for Ring Application";
|
||||
|
||||
static char *tdesc = "Waits until first ring after time";
|
||||
|
||||
static char *desc = " WaitForRing(timeout)\n"
|
||||
"Returns 0 after waiting at least timeout seconds. and\n"
|
||||
"only after the next ring has completed. Returns 0 on\n"
|
||||
"success or -1 on hangup\n";
|
||||
|
||||
static char *app = "WaitForRing";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int waitforring_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
struct localuser *u;
|
||||
struct ast_frame *f;
|
||||
int res = 0;
|
||||
int ms;
|
||||
if (!data || (sscanf(data, "%d", &ms) != 1)) {
|
||||
ast_log(LOG_WARNING, "WaitForRing requires an argument (minimum seconds)\n");
|
||||
return 0;
|
||||
}
|
||||
ms *= 1000;
|
||||
LOCAL_USER_ADD(u);
|
||||
while(ms > 0) {
|
||||
ms = ast_waitfor(chan, ms);
|
||||
if (ms < 0) {
|
||||
res = ms;
|
||||
break;
|
||||
}
|
||||
if (ms > 0) {
|
||||
f = ast_read(chan);
|
||||
if (!f) {
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Got a ring but still waiting for timeout\n");
|
||||
}
|
||||
ast_frfree(f);
|
||||
}
|
||||
}
|
||||
/* Now we're really ready for the ring */
|
||||
if (!res) {
|
||||
ms = 99999999;
|
||||
while(ms > 0) {
|
||||
ms = ast_waitfor(chan, ms);
|
||||
if (ms < 0) {
|
||||
res = ms;
|
||||
break;
|
||||
}
|
||||
if (ms > 0) {
|
||||
f = ast_read(chan);
|
||||
if (!f) {
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Got a ring after the timeout\n");
|
||||
ast_frfree(f);
|
||||
break;
|
||||
}
|
||||
ast_frfree(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, waitforring_exec, synopsis, desc);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
115
apps/app_zapateller.c
Normal file
115
apps/app_zapateller.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Playback the special information tone to get rid of telemarketers
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *tdesc = "Block Telemarketers with Special Information Tone";
|
||||
|
||||
static char *app = "Zapateller";
|
||||
|
||||
static char *synopsis = "Block telemarketers with SIT";
|
||||
|
||||
static char *descrip =
|
||||
" Zapateller(options): Generates special information tone to block\n"
|
||||
"telemarketers from calling you. Returns 0 normally or -1 on hangup.\n"
|
||||
"Options is a pipe-delimited list of options. The following options\n"
|
||||
"are available: 'answer' causes the line to be answered before playing\n"
|
||||
"the tone, 'nocallerid' causes Zapateller to only play the tone if there\n"
|
||||
"is no callerid information available. Options should be separated by |\n"
|
||||
"characters\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
static int zapateller_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
struct localuser *u;
|
||||
int answer = 0, nocallerid = 0;
|
||||
char *c;
|
||||
char *stringp=NULL;
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
stringp=data;
|
||||
c = strsep(&stringp, "|");
|
||||
while(c && strlen(c)) {
|
||||
if (!strcasecmp(c, "answer"))
|
||||
answer = 1;
|
||||
else if (!strcasecmp(c, "nocallerid"))
|
||||
nocallerid = 1;
|
||||
|
||||
c = strsep(&stringp, "|");
|
||||
}
|
||||
|
||||
ast_stopstream(chan);
|
||||
if (chan->_state != AST_STATE_UP) {
|
||||
|
||||
if (answer)
|
||||
res = ast_answer(chan);
|
||||
if (!res) {
|
||||
res = ast_safe_sleep(chan, 500);
|
||||
}
|
||||
}
|
||||
if (chan->callerid && nocallerid) {
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
if (!res)
|
||||
res = ast_tonepair(chan, 950, 0, 330, 0);
|
||||
if (!res)
|
||||
res = ast_tonepair(chan, 1400, 0, 330, 0);
|
||||
if (!res)
|
||||
res = ast_tonepair(chan, 1800, 0, 330, 0);
|
||||
if (!res)
|
||||
res = ast_tonepair(chan, 0, 0, 1000, 0);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, zapateller_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
310
apps/app_zapbarge.c
Normal file
310
apps/app_zapbarge.c
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Zap Barge support
|
||||
*
|
||||
* Copyright (C) 2003, Digium
|
||||
*
|
||||
* Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*
|
||||
* Special thanks to comphealth.com for sponsoring this
|
||||
* GPL application.
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/app.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/cli.h>
|
||||
#include <asterisk/say.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/zaptel.h>
|
||||
#else
|
||||
#include <zaptel.h>
|
||||
#endif /* __linux__ */
|
||||
|
||||
static char *tdesc = "Barge in on Zap channel application";
|
||||
|
||||
static char *app = "ZapBarge";
|
||||
|
||||
static char *synopsis = "Barge in (monitor) Zap channel";
|
||||
|
||||
static char *descrip =
|
||||
" ZapBarge([channel]): Barges in on a specified zap\n"
|
||||
"channel or prompts if one is not specified. Returns\n"
|
||||
"-1 when caller user hangs up and is independent of the\n"
|
||||
"state of the channel being monitored.";
|
||||
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
|
||||
#define CONF_SIZE 160
|
||||
|
||||
static int careful_write(int fd, unsigned char *data, int len)
|
||||
{
|
||||
int res;
|
||||
while(len) {
|
||||
res = write(fd, data, len);
|
||||
if (res < 1) {
|
||||
if (errno != EAGAIN) {
|
||||
ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno));
|
||||
return -1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
len -= res;
|
||||
data += res;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int conf_run(struct ast_channel *chan, int confno, int confflags)
|
||||
{
|
||||
int fd;
|
||||
struct zt_confinfo ztc;
|
||||
struct ast_frame *f;
|
||||
struct ast_channel *c;
|
||||
struct ast_frame fr;
|
||||
int outfd;
|
||||
int ms;
|
||||
int nfds;
|
||||
int res;
|
||||
int flags;
|
||||
int retryzap;
|
||||
int origfd;
|
||||
int ret = -1;
|
||||
|
||||
ZT_BUFFERINFO bi;
|
||||
char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
|
||||
char *buf = __buf + AST_FRIENDLY_OFFSET;
|
||||
|
||||
/* Set it into U-law mode (write) */
|
||||
if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name);
|
||||
goto outrun;
|
||||
}
|
||||
|
||||
/* Set it into U-law mode (read) */
|
||||
if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name);
|
||||
goto outrun;
|
||||
}
|
||||
ast_indicate(chan, -1);
|
||||
retryzap = strcasecmp(chan->type, "Zap");
|
||||
zapretry:
|
||||
origfd = chan->fds[0];
|
||||
if (retryzap) {
|
||||
fd = open("/dev/zap/pseudo", O_RDWR);
|
||||
if (fd < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
|
||||
goto outrun;
|
||||
}
|
||||
/* Make non-blocking */
|
||||
flags = fcntl(fd, F_GETFL);
|
||||
if (flags < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
goto outrun;
|
||||
}
|
||||
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
|
||||
ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
goto outrun;
|
||||
}
|
||||
/* Setup buffering information */
|
||||
memset(&bi, 0, sizeof(bi));
|
||||
bi.bufsize = CONF_SIZE;
|
||||
bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
|
||||
bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
|
||||
bi.numbufs = 4;
|
||||
if (ioctl(fd, ZT_SET_BUFINFO, &bi)) {
|
||||
ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
goto outrun;
|
||||
}
|
||||
nfds = 1;
|
||||
} else {
|
||||
/* XXX Make sure we're not running on a pseudo channel XXX */
|
||||
fd = chan->fds[0];
|
||||
nfds = 0;
|
||||
}
|
||||
memset(&ztc, 0, sizeof(ztc));
|
||||
/* Check to see if we're in a conference... */
|
||||
ztc.chan = 0;
|
||||
if (ioctl(fd, ZT_GETCONF, &ztc)) {
|
||||
ast_log(LOG_WARNING, "Error getting conference\n");
|
||||
close(fd);
|
||||
goto outrun;
|
||||
}
|
||||
if (ztc.confmode) {
|
||||
/* Whoa, already in a conference... Retry... */
|
||||
if (!retryzap) {
|
||||
ast_log(LOG_DEBUG, "Zap channel is in a conference already, retrying with pseudo\n");
|
||||
retryzap = 1;
|
||||
goto zapretry;
|
||||
}
|
||||
}
|
||||
memset(&ztc, 0, sizeof(ztc));
|
||||
/* Add us to the conference */
|
||||
ztc.chan = 0;
|
||||
ztc.confno = confno;
|
||||
ztc.confmode = ZT_CONF_MONITORBOTH;
|
||||
|
||||
if (ioctl(fd, ZT_SETCONF, &ztc)) {
|
||||
ast_log(LOG_WARNING, "Error setting conference\n");
|
||||
close(fd);
|
||||
goto outrun;
|
||||
}
|
||||
ast_log(LOG_DEBUG, "Placed channel %s in ZAP channel %d monitor\n", chan->name, confno);
|
||||
|
||||
for(;;) {
|
||||
outfd = -1;
|
||||
ms = -1;
|
||||
c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
|
||||
if (c) {
|
||||
if (c->fds[0] != origfd) {
|
||||
if (retryzap) {
|
||||
/* Kill old pseudo */
|
||||
close(fd);
|
||||
}
|
||||
ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n");
|
||||
retryzap = 0;
|
||||
goto zapretry;
|
||||
}
|
||||
f = ast_read(c);
|
||||
if (!f)
|
||||
break;
|
||||
if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) {
|
||||
ret = 0;
|
||||
break;
|
||||
} else if (fd != chan->fds[0]) {
|
||||
if (f->frametype == AST_FRAME_VOICE) {
|
||||
if (f->subclass == AST_FORMAT_ULAW) {
|
||||
/* Carefully write */
|
||||
careful_write(fd, f->data, f->datalen);
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Huh? Got a non-ulaw (%d) frame in the conference\n", f->subclass);
|
||||
}
|
||||
}
|
||||
ast_frfree(f);
|
||||
} else if (outfd > -1) {
|
||||
res = read(outfd, buf, CONF_SIZE);
|
||||
if (res > 0) {
|
||||
memset(&fr, 0, sizeof(fr));
|
||||
fr.frametype = AST_FRAME_VOICE;
|
||||
fr.subclass = AST_FORMAT_ULAW;
|
||||
fr.datalen = res;
|
||||
fr.samples = res;
|
||||
fr.data = buf;
|
||||
fr.offset = AST_FRIENDLY_OFFSET;
|
||||
if (ast_write(chan, &fr) < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno));
|
||||
/* break; */
|
||||
}
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
if (fd != chan->fds[0])
|
||||
close(fd);
|
||||
else {
|
||||
/* Take out of conference */
|
||||
/* Add us to the conference */
|
||||
ztc.chan = 0;
|
||||
ztc.confno = 0;
|
||||
ztc.confmode = 0;
|
||||
if (ioctl(fd, ZT_SETCONF, &ztc)) {
|
||||
ast_log(LOG_WARNING, "Error setting conference\n");
|
||||
}
|
||||
}
|
||||
|
||||
outrun:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int conf_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=-1;
|
||||
struct localuser *u;
|
||||
int retrycnt = 0;
|
||||
int confflags = 0;
|
||||
int confno = 0;
|
||||
char confstr[80] = "";
|
||||
|
||||
if (data && !ast_strlen_zero(data)) {
|
||||
if ((sscanf(data, "Zap/%d", &confno) != 1) &&
|
||||
(sscanf(data, "%d", &confno) != 1)) {
|
||||
ast_log(LOG_WARNING, "ZapBarge Argument (if specified) must be a channel number, not '%s'\n", (char *)data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
if (chan->_state != AST_STATE_UP)
|
||||
ast_answer(chan);
|
||||
|
||||
while(!confno && (++retrycnt < 4)) {
|
||||
/* Prompt user for conference number */
|
||||
confstr[0] = '\0';
|
||||
res = ast_app_getdata(chan, "conf-getchannel",confstr, sizeof(confstr) - 1, 0);
|
||||
if (res <0) goto out;
|
||||
if (sscanf(confstr, "%d", &confno) != 1)
|
||||
confno = 0;
|
||||
}
|
||||
if (confno) {
|
||||
/* XXX Should prompt user for pin if pin is required XXX */
|
||||
/* Run the conference */
|
||||
res = conf_run(chan, confno, confflags);
|
||||
}
|
||||
out:
|
||||
/* Do the conference */
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, conf_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
246
apps/app_zapras.c
Normal file
246
apps/app_zapras.c
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Execute an ISDN RAS
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#ifdef __linux__
|
||||
#include <sys/signal.h>
|
||||
#else
|
||||
#include <signal.h>
|
||||
#endif /* __linux__ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
/* Need some zaptel help here */
|
||||
#ifdef __linux__
|
||||
#include <linux/zaptel.h>
|
||||
#else
|
||||
#include <zaptel.h>
|
||||
#endif /* __linux__ */
|
||||
|
||||
static char *tdesc = "Zap RAS Application";
|
||||
|
||||
static char *app = "ZapRAS";
|
||||
|
||||
static char *synopsis = "Executes Zaptel ISDN RAS application";
|
||||
|
||||
static char *descrip =
|
||||
" ZapRAS(args): Executes a RAS server using pppd on the given channel.\n"
|
||||
"The channel must be a clear channel (i.e. PRI source) and a Zaptel\n"
|
||||
"channel to be able to use this function (No modem emulation is included).\n"
|
||||
"Your pppd must be patched to be zaptel aware. Arguments should be\n"
|
||||
"separated by | characters. Always returns -1.\n";
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
#define PPP_MAX_ARGS 32
|
||||
#define PPP_EXEC "/usr/sbin/pppd"
|
||||
|
||||
static pid_t spawn_ras(struct ast_channel *chan, char *args)
|
||||
{
|
||||
pid_t pid;
|
||||
int x;
|
||||
char *c;
|
||||
|
||||
char *argv[PPP_MAX_ARGS];
|
||||
int argc = 0;
|
||||
char *stringp=NULL;
|
||||
|
||||
/* Start by forking */
|
||||
pid = fork();
|
||||
if (pid)
|
||||
return pid;
|
||||
|
||||
/* Execute RAS on File handles */
|
||||
dup2(chan->fds[0], STDIN_FILENO);
|
||||
|
||||
/* Close other file descriptors */
|
||||
for (x=STDERR_FILENO + 1;x<1024;x++)
|
||||
close(x);
|
||||
|
||||
/* Restore original signal handlers */
|
||||
for (x=0;x<NSIG;x++)
|
||||
signal(x, SIG_DFL);
|
||||
|
||||
/* Reset all arguments */
|
||||
memset(argv, 0, sizeof(argv));
|
||||
|
||||
/* First argument is executable, followed by standard
|
||||
arguments for zaptel PPP */
|
||||
argv[argc++] = PPP_EXEC;
|
||||
argv[argc++] = "nodetach";
|
||||
|
||||
/* And all the other arguments */
|
||||
stringp=args;
|
||||
c = strsep(&stringp, "|");
|
||||
while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
|
||||
argv[argc++] = c;
|
||||
c = strsep(&stringp, "|");
|
||||
}
|
||||
|
||||
argv[argc++] = "plugin";
|
||||
argv[argc++] = "zaptel.so";
|
||||
argv[argc++] = "stdin";
|
||||
|
||||
#if 0
|
||||
for (x=0;x<argc;x++) {
|
||||
fprintf(stderr, "Arg %d: %s\n", x, argv[x]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Finally launch PPP */
|
||||
execv(PPP_EXEC, argv);
|
||||
fprintf(stderr, "Failed to exec PPPD!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void run_ras(struct ast_channel *chan, char *args)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
int res;
|
||||
int signalled = 0;
|
||||
struct zt_bufferinfo savebi;
|
||||
int x;
|
||||
|
||||
res = ioctl(chan->fds[0], ZT_GET_BUFINFO, &savebi);
|
||||
if(res) {
|
||||
ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name);
|
||||
return;
|
||||
}
|
||||
|
||||
pid = spawn_ras(chan, args);
|
||||
if (pid < 0) {
|
||||
ast_log(LOG_WARNING, "Failed to spawn RAS\n");
|
||||
} else {
|
||||
for (;;) {
|
||||
res = wait4(pid, &status, WNOHANG, NULL);
|
||||
if (!res) {
|
||||
/* Check for hangup */
|
||||
if (chan->_softhangup && !signalled) {
|
||||
ast_log(LOG_DEBUG, "Channel '%s' hungup. Signalling RAS at %d to die...\n", chan->name, pid);
|
||||
kill(pid, SIGTERM);
|
||||
signalled=1;
|
||||
}
|
||||
/* Try again */
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
if (res < 0) {
|
||||
ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno));
|
||||
}
|
||||
if (option_verbose > 2) {
|
||||
if (WIFEXITED(status)) {
|
||||
ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status));
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with signal %d\n",
|
||||
chan->name, WTERMSIG(status));
|
||||
} else {
|
||||
ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated weirdly.\n", chan->name);
|
||||
}
|
||||
}
|
||||
/* Throw back into audio mode */
|
||||
x = 1;
|
||||
ioctl(chan->fds[0], ZT_AUDIOMODE, &x);
|
||||
|
||||
/* Restore saved values */
|
||||
res = ioctl(chan->fds[0], ZT_SET_BUFINFO, &savebi);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int zapras_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=-1;
|
||||
char args[256];
|
||||
struct localuser *u;
|
||||
ZT_PARAMS ztp;
|
||||
|
||||
if (!data)
|
||||
data = "";
|
||||
LOCAL_USER_ADD(u);
|
||||
strncpy(args, data, sizeof(args) - 1);
|
||||
/* Answer the channel if it's not up */
|
||||
if (chan->_state != AST_STATE_UP)
|
||||
ast_answer(chan);
|
||||
if (strcasecmp(chan->type, "Zap")) {
|
||||
/* If it's not a zap channel, we're done. Wait a couple of
|
||||
seconds and then hangup... */
|
||||
if (option_verbose > 1)
|
||||
ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a Zap channel\n", chan->name);
|
||||
sleep(2);
|
||||
} else {
|
||||
memset(&ztp, 0, sizeof(ztp));
|
||||
if (ioctl(chan->fds[0], ZT_GET_PARAMS, &ztp)) {
|
||||
ast_log(LOG_WARNING, "Unable to get zaptel parameters\n");
|
||||
} else if (ztp.sigtype != ZT_SIG_CLEAR) {
|
||||
if (option_verbose > 1)
|
||||
ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a clear channel\n", chan->name);
|
||||
} else {
|
||||
/* Everything should be okay. Run PPP. */
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Starting RAS on %s\n", chan->name);
|
||||
/* Execute RAS */
|
||||
run_ras(chan, args);
|
||||
}
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, zapras_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
368
apps/app_zapscan.c
Normal file
368
apps/app_zapscan.c
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Zap Scanner
|
||||
*
|
||||
* Copyright (C) 2003, Digium
|
||||
*
|
||||
* Modified from app_zapbarge by David Troy <dave@toad.net>
|
||||
*
|
||||
* Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*
|
||||
* Special thanks to comphealth.com for sponsoring this
|
||||
* GPL application.
|
||||
*/
|
||||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/app.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/cli.h>
|
||||
#include <asterisk/say.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/zaptel.h>
|
||||
#else
|
||||
#include <zaptel.h>
|
||||
#endif /* __linux__ */
|
||||
|
||||
static char *tdesc = "Scan Zap channels application";
|
||||
|
||||
static char *app = "ZapScan";
|
||||
|
||||
static char *synopsis = "Scan Zap channels to monitor calls";
|
||||
|
||||
static char *descrip =
|
||||
" ZapScan allows a call center manager to monitor Zap channels in\n"
|
||||
"a convenient way. Use '#' to select the next channel and use '*' to exit\n";
|
||||
|
||||
|
||||
STANDARD_LOCAL_USER;
|
||||
|
||||
LOCAL_USER_DECL;
|
||||
|
||||
|
||||
#define CONF_SIZE 160
|
||||
|
||||
static struct ast_channel *get_zap_channel_locked(int num) {
|
||||
struct ast_channel *c=NULL;
|
||||
char name[80];
|
||||
|
||||
snprintf(name,sizeof(name),"Zap/%d-1",num);
|
||||
c = ast_channel_walk_locked(NULL);
|
||||
while(c) {
|
||||
if (!strcasecmp(c->name, name)) {
|
||||
break;
|
||||
}
|
||||
ast_mutex_unlock(&c->lock);
|
||||
c = ast_channel_walk_locked(c);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static int careful_write(int fd, unsigned char *data, int len)
|
||||
{
|
||||
int res;
|
||||
while(len) {
|
||||
res = write(fd, data, len);
|
||||
if (res < 1) {
|
||||
if (errno != EAGAIN) {
|
||||
ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno));
|
||||
return -1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
len -= res;
|
||||
data += res;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int conf_run(struct ast_channel *chan, int confno, int confflags)
|
||||
{
|
||||
int fd;
|
||||
struct zt_confinfo ztc;
|
||||
struct ast_frame *f;
|
||||
struct ast_channel *c;
|
||||
struct ast_frame fr;
|
||||
int outfd;
|
||||
int ms;
|
||||
int nfds;
|
||||
int res;
|
||||
int flags;
|
||||
int retryzap;
|
||||
int origfd;
|
||||
int ret = -1;
|
||||
char input[4];
|
||||
int ic=0;
|
||||
|
||||
ZT_BUFFERINFO bi;
|
||||
char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
|
||||
char *buf = __buf + AST_FRIENDLY_OFFSET;
|
||||
|
||||
/* Set it into U-law mode (write) */
|
||||
if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name);
|
||||
goto outrun;
|
||||
}
|
||||
|
||||
/* Set it into U-law mode (read) */
|
||||
if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name);
|
||||
goto outrun;
|
||||
}
|
||||
ast_indicate(chan, -1);
|
||||
retryzap = strcasecmp(chan->type, "Zap");
|
||||
zapretry:
|
||||
origfd = chan->fds[0];
|
||||
if (retryzap) {
|
||||
fd = open("/dev/zap/pseudo", O_RDWR);
|
||||
if (fd < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
|
||||
goto outrun;
|
||||
}
|
||||
/* Make non-blocking */
|
||||
flags = fcntl(fd, F_GETFL);
|
||||
if (flags < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
goto outrun;
|
||||
}
|
||||
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
|
||||
ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
goto outrun;
|
||||
}
|
||||
/* Setup buffering information */
|
||||
memset(&bi, 0, sizeof(bi));
|
||||
bi.bufsize = CONF_SIZE;
|
||||
bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
|
||||
bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
|
||||
bi.numbufs = 4;
|
||||
if (ioctl(fd, ZT_SET_BUFINFO, &bi)) {
|
||||
ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
goto outrun;
|
||||
}
|
||||
nfds = 1;
|
||||
} else {
|
||||
/* XXX Make sure we're not running on a pseudo channel XXX */
|
||||
fd = chan->fds[0];
|
||||
nfds = 0;
|
||||
}
|
||||
memset(&ztc, 0, sizeof(ztc));
|
||||
/* Check to see if we're in a conference... */
|
||||
ztc.chan = 0;
|
||||
if (ioctl(fd, ZT_GETCONF, &ztc)) {
|
||||
ast_log(LOG_WARNING, "Error getting conference\n");
|
||||
close(fd);
|
||||
goto outrun;
|
||||
}
|
||||
if (ztc.confmode) {
|
||||
/* Whoa, already in a conference... Retry... */
|
||||
if (!retryzap) {
|
||||
ast_log(LOG_DEBUG, "Zap channel is in a conference already, retrying with pseudo\n");
|
||||
retryzap = 1;
|
||||
goto zapretry;
|
||||
}
|
||||
}
|
||||
memset(&ztc, 0, sizeof(ztc));
|
||||
/* Add us to the conference */
|
||||
ztc.chan = 0;
|
||||
ztc.confno = confno;
|
||||
ztc.confmode = ZT_CONF_MONITORBOTH;
|
||||
|
||||
if (ioctl(fd, ZT_SETCONF, &ztc)) {
|
||||
ast_log(LOG_WARNING, "Error setting conference\n");
|
||||
close(fd);
|
||||
goto outrun;
|
||||
}
|
||||
ast_log(LOG_DEBUG, "Placed channel %s in ZAP channel %d monitor\n", chan->name, confno);
|
||||
|
||||
for(;;) {
|
||||
outfd = -1;
|
||||
ms = -1;
|
||||
c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
|
||||
if (c) {
|
||||
if (c->fds[0] != origfd) {
|
||||
if (retryzap) {
|
||||
/* Kill old pseudo */
|
||||
close(fd);
|
||||
}
|
||||
ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n");
|
||||
retryzap = 0;
|
||||
goto zapretry;
|
||||
}
|
||||
f = ast_read(c);
|
||||
if (!f)
|
||||
break;
|
||||
if(f->frametype == AST_FRAME_DTMF) {
|
||||
if(f->subclass == '#') {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
else if (f->subclass == '*') {
|
||||
ret = -1;
|
||||
break;
|
||||
|
||||
}
|
||||
else {
|
||||
input[ic++] = f->subclass;
|
||||
}
|
||||
if(ic == 3) {
|
||||
input[ic++] = '\0';
|
||||
ic=0;
|
||||
ret = atoi(input);
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Zapscan: change channel to %d\n",ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fd != chan->fds[0]) {
|
||||
if (f->frametype == AST_FRAME_VOICE) {
|
||||
if (f->subclass == AST_FORMAT_ULAW) {
|
||||
/* Carefully write */
|
||||
careful_write(fd, f->data, f->datalen);
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Huh? Got a non-ulaw (%d) frame in the conference\n", f->subclass);
|
||||
}
|
||||
}
|
||||
ast_frfree(f);
|
||||
} else if (outfd > -1) {
|
||||
res = read(outfd, buf, CONF_SIZE);
|
||||
if (res > 0) {
|
||||
memset(&fr, 0, sizeof(fr));
|
||||
fr.frametype = AST_FRAME_VOICE;
|
||||
fr.subclass = AST_FORMAT_ULAW;
|
||||
fr.datalen = res;
|
||||
fr.samples = res;
|
||||
fr.data = buf;
|
||||
fr.offset = AST_FRIENDLY_OFFSET;
|
||||
if (ast_write(chan, &fr) < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno));
|
||||
/* break; */
|
||||
}
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
if (fd != chan->fds[0])
|
||||
close(fd);
|
||||
else {
|
||||
/* Take out of conference */
|
||||
/* Add us to the conference */
|
||||
ztc.chan = 0;
|
||||
ztc.confno = 0;
|
||||
ztc.confmode = 0;
|
||||
if (ioctl(fd, ZT_SETCONF, &ztc)) {
|
||||
ast_log(LOG_WARNING, "Error setting conference\n");
|
||||
}
|
||||
}
|
||||
|
||||
outrun:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int conf_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
int res=-1;
|
||||
struct localuser *u;
|
||||
int confflags = 0;
|
||||
int confno = 0;
|
||||
char confstr[80] = "", *tmp;
|
||||
struct ast_channel *tempchan = NULL, *lastchan = NULL,*ichan = NULL;
|
||||
struct ast_frame *f;
|
||||
int input=0;
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
if (chan->_state != AST_STATE_UP)
|
||||
ast_answer(chan);
|
||||
|
||||
for (;;) {
|
||||
if (ast_waitfor(chan, 100) < 0)
|
||||
break;
|
||||
|
||||
f = ast_read(chan);
|
||||
if (!f)
|
||||
break;
|
||||
if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*')) {
|
||||
ast_frfree(f);
|
||||
break;
|
||||
}
|
||||
ast_frfree(f);
|
||||
ichan = NULL;
|
||||
if(input) {
|
||||
ichan = get_zap_channel_locked(input);
|
||||
input = 0;
|
||||
}
|
||||
|
||||
tempchan = ichan ? ichan : ast_channel_walk_locked(tempchan);
|
||||
|
||||
|
||||
if ( !tempchan && !lastchan )
|
||||
break;
|
||||
if ( tempchan && tempchan->type && (!strcmp(tempchan->type, "Zap")) && (tempchan != chan) ) {
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Zap channel %s is in-use, monitoring...\n", tempchan->name);
|
||||
strncpy(confstr, tempchan->name, sizeof(confstr) - 1);
|
||||
ast_mutex_unlock(&tempchan->lock);
|
||||
if ((tmp = strchr(confstr,'-'))) {
|
||||
*tmp = '\0';
|
||||
}
|
||||
confno = atoi(strchr(confstr,'/') + 1);
|
||||
ast_stopstream(chan);
|
||||
ast_say_number(chan, confno, AST_DIGIT_ANY, chan->language, (char *) NULL);
|
||||
res = conf_run(chan, confno, confflags);
|
||||
if (res<0) break;
|
||||
input = res;
|
||||
} else if (tempchan)
|
||||
ast_mutex_unlock(&tempchan->lock);
|
||||
lastchan = tempchan;
|
||||
}
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return res;
|
||||
}
|
||||
|
||||
int unload_module(void)
|
||||
{
|
||||
STANDARD_HANGUP_LOCALUSERS;
|
||||
return ast_unregister_application(app);
|
||||
}
|
||||
|
||||
int load_module(void)
|
||||
{
|
||||
return ast_register_application(app, conf_exec, synopsis, descrip);
|
||||
}
|
||||
|
||||
char *description(void)
|
||||
{
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
int res;
|
||||
STANDARD_USECOUNT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *key()
|
||||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
|
||||
287
apps/enter.h
Normal file
287
apps/enter.h
Normal file
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* U-law 8-bit audio data
|
||||
*
|
||||
* Source: enter.raw
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer and Linux Support Services
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License
|
||||
*
|
||||
*/
|
||||
|
||||
static unsigned char enter[] = {
|
||||
0xba, 0xba, 0xb0, 0xa6, 0xa9, 0xb8, 0xfe, 0x46, 0x42, 0x46,
|
||||
0x4a, 0xfe, 0xac, 0xa2, 0x9f, 0x9f, 0xa8, 0xb8, 0x3b, 0x29,
|
||||
0x35, 0x4a, 0xfe, 0xc1, 0xad, 0xa2, 0xad, 0xc5, 0x4e, 0x68,
|
||||
0x68, 0xe7, 0xb8, 0xb0, 0xb2, 0xc1, 0xc1, 0xb0, 0xae, 0xcd,
|
||||
0xfe, 0xfe, 0xcd, 0xcd, 0xfe, 0x68, 0xd3, 0xb2, 0xae, 0xab,
|
||||
0xb2, 0xfe, 0x35, 0x31, 0xdb, 0xac, 0xab, 0xaf, 0xab, 0xaa,
|
||||
0xb4, 0x68, 0x3b, 0x39, 0x3f, 0x68, 0xb4, 0xa8, 0xa8, 0xb0,
|
||||
0xbc, 0xbc, 0xc5, 0x3f, 0x31, 0x37, 0xfe, 0xc1, 0xbc, 0xb0,
|
||||
0xa5, 0xa2, 0xa8, 0xaf, 0xbe, 0x3b, 0x28, 0x26, 0x3d, 0xbc,
|
||||
0xb0, 0xae, 0xa2, 0x9f, 0xa2, 0xfe, 0x29, 0x24, 0x29, 0x4a,
|
||||
0xc5, 0xaa, 0xa8, 0xa9, 0xa8, 0xa5, 0xa7, 0xdb, 0x2c, 0x27,
|
||||
0x2d, 0x4a, 0xfe, 0xdb, 0xb2, 0xa2, 0x9f, 0x9f, 0xae, 0xe7,
|
||||
0x2c, 0x22, 0x2b, 0xfe, 0xba, 0xb0, 0xaa, 0x9f, 0xa3, 0xb0,
|
||||
0x5c, 0x33, 0x33, 0x39, 0x5c, 0xdb, 0xc1, 0xb4, 0xb0, 0xaa,
|
||||
0xad, 0xba, 0x54, 0x46, 0xfe, 0xe7, 0xfe, 0x54, 0xe7, 0xaf,
|
||||
0xa6, 0xa7, 0xb0, 0xfe, 0x46, 0x39, 0x5c, 0xe7, 0xdb, 0xfe,
|
||||
0xba, 0xac, 0xa8, 0xc5, 0x46, 0x33, 0x54, 0xc5, 0xae, 0xad,
|
||||
0xb2, 0xc1, 0xcd, 0xc1, 0xbc, 0xfe, 0x3f, 0x37, 0xfe, 0xb4,
|
||||
0xb6, 0xcd, 0xdb, 0xc1, 0xb0, 0xb6, 0xcd, 0x4e, 0x39, 0x37,
|
||||
0xfe, 0xb0, 0xab, 0xa9, 0xa9, 0xa9, 0xb0, 0x5c, 0x29, 0x25,
|
||||
0x31, 0xfe, 0xc1, 0xb4, 0xae, 0xab, 0xab, 0xb2, 0xcd, 0x3b,
|
||||
0x2a, 0x2c, 0x54, 0xb4, 0xb4, 0xba, 0xb2, 0xa3, 0x9f, 0xa8,
|
||||
0xfe, 0x33, 0x27, 0x2a, 0x39, 0xfe, 0xc1, 0xbe, 0xb0, 0xa2,
|
||||
0x9f, 0xb0, 0x33, 0x22, 0x25, 0x46, 0xc1, 0xb8, 0xb0, 0xab,
|
||||
0xa8, 0xa8, 0xb0, 0xbe, 0x42, 0x2c, 0x2e, 0x4a, 0xfe, 0x5c,
|
||||
0xfe, 0xb4, 0xa8, 0xa8, 0xba, 0xfe, 0x4a, 0x39, 0x39, 0x46,
|
||||
0xfe, 0xbc, 0xaf, 0xa5, 0xa5, 0xae, 0x68, 0x37, 0x4a, 0xfe,
|
||||
0xfe, 0x4a, 0x4a, 0xd3, 0xb0, 0xb0, 0xc1, 0x5c, 0x46, 0x46,
|
||||
0xd3, 0xb6, 0xbe, 0x54, 0x54, 0xc9, 0xab, 0xae, 0xc5, 0x46,
|
||||
0x4a, 0xfe, 0xcd, 0xc9, 0xcd, 0xe7, 0xe7, 0xc9, 0xb4, 0xc5,
|
||||
0x4a, 0x2c, 0x37, 0xc1, 0xb0, 0xb2, 0xb4, 0xb2, 0xb6, 0xdb,
|
||||
0xfe, 0x4a, 0x46, 0x3f, 0x68, 0xba, 0xb2, 0xba, 0xc5, 0xb6,
|
||||
0xb2, 0xcd, 0x33, 0x2e, 0x39, 0x68, 0xfe, 0xe7, 0xba, 0xaf,
|
||||
0xa7, 0xa7, 0xad, 0xe7, 0x2d, 0x25, 0x2f, 0xd3, 0xbe, 0xcd,
|
||||
0xc5, 0xac, 0xa6, 0xac, 0xfe, 0x3b, 0x2c, 0x2d, 0x3d, 0xc1,
|
||||
0xb4, 0xbe, 0xcd, 0xaf, 0xa5, 0xa8, 0xe7, 0x31, 0x2f, 0x39,
|
||||
0x46, 0x5c, 0xdb, 0xbc, 0xba, 0xaf, 0xa9, 0xad, 0xfe, 0x2f,
|
||||
0x2d, 0xba, 0xad, 0xba, 0xfe, 0x3d, 0x42, 0x5c, 0xc9, 0xc1,
|
||||
0xcd, 0xfe, 0xc1, 0xae, 0xa6, 0xcd, 0x33, 0x25, 0x3b, 0xdb,
|
||||
0xb0, 0xb6, 0xb8, 0xb6, 0xb4, 0xb8, 0xba, 0xfe, 0x3d, 0x37,
|
||||
0xfe, 0xba, 0xc1, 0x54, 0x54, 0xd3, 0xb0, 0xb4, 0xe7, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xd3, 0xb6, 0xa9, 0xa7, 0xba,
|
||||
0x3d, 0x35, 0xfe, 0xc1, 0xcd, 0x4a, 0x54, 0xbe, 0xb2, 0xb8,
|
||||
0xfe, 0x46, 0x3b, 0xfe, 0xba, 0xab, 0xc5, 0x46, 0x3b, 0xbc,
|
||||
0xaa, 0xab, 0xd3, 0x68, 0xfe, 0xd3, 0xcd, 0xdb, 0x54, 0x3d,
|
||||
0x4a, 0xbc, 0xac, 0xb4, 0x3f, 0x2e, 0x3d, 0xba, 0xb0, 0xb8,
|
||||
0xba, 0xb6, 0xba, 0xcd, 0xfe, 0xfe, 0x5c, 0x54, 0xc9, 0xb4,
|
||||
0xbe, 0x54, 0x54, 0xcd, 0xb6, 0xc9, 0x46, 0x54, 0xcd, 0xc5,
|
||||
0xdb, 0xfe, 0xfe, 0xc1, 0xae, 0xa9, 0xac, 0xfe, 0x35, 0x2e,
|
||||
0xfe, 0xba, 0xc1, 0x5c, 0xfe, 0xb6, 0xaa, 0xb0, 0xe7, 0x35,
|
||||
0x2e, 0x39, 0xc1, 0xac, 0xb0, 0xfe, 0xfe, 0xbc, 0xa6, 0xac,
|
||||
0xc1, 0x42, 0x46, 0x54, 0xfe, 0xfe, 0xfe, 0xfe, 0xc9, 0xae,
|
||||
0xa9, 0xb0, 0x54, 0x35, 0x37, 0xfe, 0xd3, 0xd3, 0xb8, 0xae,
|
||||
0xab, 0xb6, 0xe7, 0xfe, 0xfe, 0x68, 0xfe, 0xfe, 0xfe, 0x4e,
|
||||
0xfe, 0xb0, 0xac, 0xb8, 0xfe, 0xfe, 0xc1, 0xb6, 0xc5, 0x46,
|
||||
0x3d, 0xe7, 0xb4, 0xa7, 0xab, 0xbc, 0x3f, 0x37, 0x54, 0xba,
|
||||
0xcd, 0x54, 0x42, 0xc5, 0xae, 0xac, 0xc9, 0x46, 0x3d, 0x54,
|
||||
0xba, 0xb0, 0xb0, 0xfe, 0x5c, 0xcd, 0xb0, 0xb0, 0xc9, 0x54,
|
||||
0x54, 0xfe, 0xfe, 0xfe, 0xfe, 0xe7, 0xcd, 0xc1, 0xba, 0xc5,
|
||||
0xfe, 0x42, 0x46, 0xfe, 0xc5, 0xba, 0xb2, 0xa7, 0xa7, 0xb0,
|
||||
0xfe, 0x3d, 0x4a, 0x5c, 0xfe, 0xfe, 0xfe, 0xe7, 0xbc, 0xb0,
|
||||
0xae, 0xc5, 0x4e, 0x39, 0xfe, 0xc5, 0xbe, 0xfe, 0x54, 0xc9,
|
||||
0xa9, 0xa2, 0xa5, 0xbc, 0x3b, 0x2f, 0x35, 0xfe, 0xc9, 0xfe,
|
||||
0xfe, 0xc5, 0xa9, 0xa6, 0xb0, 0x54, 0x31, 0x31, 0x3f, 0xd3,
|
||||
0xbc, 0xc1, 0xcd, 0xb8, 0xae, 0xa8, 0xb4, 0xd3, 0x54, 0x4e,
|
||||
0x5c, 0x54, 0xfe, 0xdb, 0xba, 0xb4, 0xb4, 0xba, 0xcd, 0x5c,
|
||||
0x3d, 0x3f, 0x54, 0xfe, 0xcd, 0xaf, 0xa8, 0xac, 0xc5, 0xfe,
|
||||
0xfe, 0xe7, 0xdb, 0xfe, 0xfe, 0xfe, 0xe7, 0xb8, 0xaf, 0xb0,
|
||||
0xe7, 0x42, 0x4a, 0xcd, 0xbc, 0xdb, 0x46, 0x68, 0xcd, 0xb0,
|
||||
0xab, 0xbc, 0xfe, 0x3d, 0x46, 0xfe, 0xb8, 0xbc, 0xd3, 0xd3,
|
||||
0xb6, 0xb0, 0xb6, 0x5c, 0x3b, 0x35, 0x54, 0xdb, 0xba, 0xb4,
|
||||
0xc1, 0xc9, 0xc1, 0xba, 0xc9, 0x5c, 0x3d, 0x46, 0xfe, 0xcd,
|
||||
0xc5, 0xb8, 0xae, 0xaf, 0xb4, 0xd3, 0x54, 0x3d, 0x35, 0x46,
|
||||
0xfe, 0xdb, 0xbc, 0xb2, 0xa9, 0xab, 0xba, 0x3f, 0x31, 0x39,
|
||||
0xfe, 0xe7, 0xdb, 0xcd, 0xb8, 0xae, 0xab, 0xac, 0xe7, 0x3d,
|
||||
0x2d, 0x3f, 0xfe, 0xdb, 0xfe, 0xfe, 0xbc, 0xaa, 0xa8, 0xb0,
|
||||
0xfe, 0x31, 0x2d, 0x3d, 0xdb, 0xc5, 0xcd, 0xc9, 0xb4, 0xa8,
|
||||
0xad, 0xc5, 0x46, 0x39, 0x3f, 0x5c, 0xfe, 0xd3, 0xc5, 0xc1,
|
||||
0xb6, 0xb0, 0xbc, 0x68, 0x46, 0x4e, 0xe7, 0xfe, 0x5c, 0xfe,
|
||||
0xc1, 0xaf, 0xb0, 0xb8, 0xe7, 0x5c, 0x5c, 0xfe, 0xe7, 0xfe,
|
||||
0xfe, 0xe7, 0xb0, 0xab, 0xb2, 0x4a, 0x37, 0x3f, 0xcd, 0xbe,
|
||||
0xc1, 0xe7, 0xe7, 0xd3, 0xb6, 0xb4, 0xc9, 0x3b, 0x33, 0x4a,
|
||||
0xba, 0xb4, 0xc5, 0xfe, 0xc9, 0xb6, 0xb4, 0xcd, 0xfe, 0x3b,
|
||||
0x3b, 0xfe, 0xc1, 0xb6, 0xc5, 0xc5, 0xb8, 0xb0, 0xba, 0x4a,
|
||||
0x31, 0x35, 0x68, 0xcd, 0xc5, 0xba, 0xb4, 0xb0, 0xb0, 0xba,
|
||||
0x5c, 0x35, 0x2f, 0x4e, 0xd3, 0xc1, 0xdb, 0xd3, 0xb4, 0xa9,
|
||||
0xab, 0xcd, 0x3b, 0x2f, 0x35, 0xfe, 0xd3, 0xd3, 0xdb, 0xbc,
|
||||
0xad, 0xa4, 0xb0, 0xfe, 0x2d, 0x2f, 0x3f, 0xe7, 0xe7, 0xe7,
|
||||
0xcd, 0xb4, 0xaf, 0xad, 0xc5, 0x3d, 0x31, 0x3d, 0xe7, 0xd3,
|
||||
0xe7, 0xe7, 0xc1, 0xaf, 0xad, 0xb6, 0xfe, 0x4a, 0x42, 0x54,
|
||||
0xfe, 0x68, 0xfe, 0xd3, 0xb2, 0xae, 0xb4, 0xfe, 0x42, 0x4e,
|
||||
0xcd, 0xc5, 0xcd, 0xdb, 0xc9, 0xb4, 0xb0, 0xb6, 0xfe, 0x3b,
|
||||
0x42, 0xe7, 0xb0, 0xb8, 0xcd, 0xfe, 0xc9, 0xb6, 0xb8, 0xfe,
|
||||
0x42, 0x3d, 0xfe, 0xc1, 0xb0, 0xba, 0xd3, 0xfe, 0xc1, 0xb0,
|
||||
0xb6, 0xfe, 0x3b, 0x3f, 0xe7, 0xba, 0xb8, 0xbc, 0xc5, 0xc1,
|
||||
0xc1, 0xcd, 0xfe, 0x3b, 0x37, 0xfe, 0xc1, 0xb4, 0xb6, 0xb8,
|
||||
0xb6, 0xb8, 0xc5, 0x5c, 0x3f, 0x46, 0xfe, 0xcd, 0xc5, 0xcd,
|
||||
0xcd, 0xc1, 0xb2, 0xb2, 0xfe, 0x3f, 0x35, 0x54, 0xdb, 0xc1,
|
||||
0xcd, 0xcd, 0xbc, 0xaf, 0xac, 0xb6, 0x54, 0x35, 0x31, 0x68,
|
||||
0xba, 0xb8, 0xcd, 0xdb, 0xc9, 0xb2, 0xb4, 0xc9, 0x46, 0x39,
|
||||
0x42, 0xdb, 0xbc, 0xbc, 0xcd, 0xcd, 0xbe, 0xb2, 0xb8, 0xe7,
|
||||
0x54, 0x46, 0xfe, 0xfe, 0xdb, 0xc9, 0xc5, 0xbe, 0xbe, 0xc9,
|
||||
0xfe, 0x5c, 0x5c, 0xfe, 0xd3, 0xcd, 0xcd, 0xc5, 0xb6, 0xb2,
|
||||
0xc5, 0x68, 0x4e, 0xfe, 0xc5, 0xc1, 0xcd, 0x68, 0x5c, 0xe7,
|
||||
0xb8, 0xb6, 0xd3, 0x4a, 0x46, 0xfe, 0xbc, 0xb8, 0xc1, 0xe7,
|
||||
0xe7, 0xc1, 0xb4, 0xbe, 0xfe, 0x3f, 0x3f, 0xfe, 0xba, 0xb2,
|
||||
0xba, 0xe7, 0xfe, 0xcd, 0xcd, 0xfe, 0x4e, 0x46, 0xfe, 0xc5,
|
||||
0xb8, 0xb2, 0xba, 0xc1, 0xcd, 0xd3, 0xe7, 0xfe, 0x5c, 0x5c,
|
||||
0xfe, 0xe7, 0xc5, 0xbe, 0xb6, 0xba, 0xc5, 0xfe, 0x3f, 0x3f,
|
||||
0x54, 0xfe, 0xd3, 0xc1, 0xbc, 0xb6, 0xb0, 0xb0, 0xd3, 0x54,
|
||||
0x39, 0x46, 0xfe, 0xc1, 0xcd, 0xe7, 0xe7, 0xc5, 0xb8, 0xb4,
|
||||
0xd3, 0x54, 0x37, 0x42, 0xdb, 0xbe, 0xc1, 0xd3, 0xcd, 0xb8,
|
||||
0xb0, 0xb0, 0xcd, 0x4a, 0x3b, 0x42, 0xe7, 0xc5, 0xbe, 0xcd,
|
||||
0xe7, 0xd3, 0xc5, 0xcd, 0xfe, 0x54, 0x54, 0x68, 0xe7, 0xc5,
|
||||
0xc1, 0xc1, 0xcd, 0xcd, 0xc9, 0xc9, 0xcd, 0xe7, 0xfe, 0xfe,
|
||||
0xfe, 0xe7, 0xc5, 0xbe, 0xc1, 0xfe, 0x5c, 0x5c, 0xfe, 0xcd,
|
||||
0xcd, 0xcd, 0xdb, 0xd3, 0xc1, 0xbc, 0xbe, 0xfe, 0x4e, 0x54,
|
||||
0xcd, 0xb6, 0xb8, 0xd3, 0x5c, 0x5c, 0xfe, 0xc5, 0xc9, 0xfe,
|
||||
0x46, 0x4a, 0xe7, 0xb4, 0xb6, 0xc5, 0xfe, 0xe7, 0xcd, 0xc9,
|
||||
0xdb, 0xfe, 0x4e, 0x68, 0xd3, 0xb6, 0xb2, 0xbc, 0xfe, 0x68,
|
||||
0xfe, 0xfe, 0x68, 0x54, 0x68, 0xe7, 0xc5, 0xbc, 0xb8, 0xbe,
|
||||
0xcd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xd3, 0xd3, 0xcd,
|
||||
0xc1, 0xb8, 0xbc, 0xdb, 0x4e, 0x42, 0x4a, 0xfe, 0xc9, 0xc1,
|
||||
0xcd, 0xd3, 0xcd, 0xba, 0xb8, 0xcd, 0x46, 0x3b, 0xfe, 0xc9,
|
||||
0xba, 0xcd, 0xe7, 0xfe, 0xd3, 0xc1, 0xba, 0xdb, 0x54, 0x3d,
|
||||
0x68, 0xd3, 0xbc, 0xcd, 0xfe, 0xfe, 0xc5, 0xbe, 0xc1, 0xe7,
|
||||
0x54, 0x4a, 0xfe, 0xc9, 0xc1, 0xcd, 0xfe, 0xfe, 0xd3, 0xd3,
|
||||
0xd3, 0xfe, 0xe7, 0xe7, 0xe7, 0xdb, 0xd3, 0xe7, 0xe7, 0xe7,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xcd, 0xc9, 0xdb, 0xfe, 0xfe, 0xdb,
|
||||
0xbe, 0xc9, 0xfe, 0x5c, 0xfe, 0xc9, 0xbc, 0xbe, 0xdb, 0x68,
|
||||
0x5c, 0xdb, 0xc5, 0xd3, 0x54, 0x46, 0xfe, 0xbc, 0xb2, 0xb8,
|
||||
0xdb, 0x68, 0x68, 0xe7, 0xcd, 0xdb, 0x5c, 0x54, 0xfe, 0xc1,
|
||||
0xb8, 0xc1, 0xe7, 0xfe, 0xfe, 0xe7, 0xe7, 0xfe, 0xfe, 0xfe,
|
||||
0xd3, 0xc5, 0xc1, 0xc5, 0xcd, 0xd3, 0xe7, 0xfe, 0x54, 0x4e,
|
||||
0xfe, 0xd3, 0xcd, 0xd3, 0xd3, 0xc5, 0xc1, 0xc1, 0xe7, 0x5c,
|
||||
0x4e, 0x5c, 0xd3, 0xc1, 0xcd, 0xfe, 0xfe, 0xcd, 0xba, 0xba,
|
||||
0xe7, 0x4a, 0x4a, 0x68, 0xcd, 0xc5, 0xcd, 0xfe, 0xfe, 0xcd,
|
||||
0xb8, 0xc1, 0xe7, 0x4e, 0x5c, 0xe7, 0xc1, 0xc9, 0xdb, 0xfe,
|
||||
0xe7, 0xc9, 0xc5, 0xd3, 0xfe, 0x68, 0xfe, 0xdb, 0xd3, 0xe7,
|
||||
0xfe, 0xfe, 0xcd, 0xc9, 0xcd, 0xd3, 0xd3, 0xd3, 0xcd, 0xe7,
|
||||
0xfe, 0xfe, 0xe7, 0xc5, 0xc5, 0xe7, 0x68, 0x68, 0xe7, 0xc1,
|
||||
0xc5, 0xfe, 0x5c, 0xfe, 0xd3, 0xc1, 0xd3, 0xfe, 0x68, 0xe7,
|
||||
0xc5, 0xb6, 0xc5, 0xe7, 0x68, 0xfe, 0xcd, 0xc5, 0xe7, 0xfe,
|
||||
0x54, 0xfe, 0xc9, 0xc5, 0xdb, 0xfe, 0xfe, 0xfe, 0xd3, 0xd3,
|
||||
0xfe, 0xfe, 0xfe, 0xcd, 0xc1, 0xc1, 0xc9, 0xd3, 0xd3, 0xe7,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xe7, 0xd3, 0xdb, 0xe7, 0xe7, 0xd3,
|
||||
0xcd, 0xd3, 0xfe, 0xfe, 0xfe, 0xcd, 0xc5, 0xd3, 0xe7, 0xe7,
|
||||
0xc9, 0xbc, 0xbe, 0xe7, 0x68, 0x4a, 0xfe, 0xdb, 0xcd, 0xfe,
|
||||
0xfe, 0xfe, 0xcd, 0xc1, 0xc9, 0xfe, 0x54, 0x5c, 0xe7, 0xc9,
|
||||
0xc5, 0xe7, 0xfe, 0xfe, 0xcd, 0xc5, 0xc5, 0xe7, 0xfe, 0xfe,
|
||||
0xfe, 0xe7, 0xe7, 0xfe, 0xfe, 0xdb, 0xd3, 0xd3, 0xdb, 0xe7,
|
||||
0xfe, 0xfe, 0xe7, 0xe7, 0xdb, 0xd3, 0xc9, 0xd3, 0xe7, 0xfe,
|
||||
0xfe, 0xd3, 0xd3, 0xdb, 0xfe, 0xfe, 0xfe, 0xd3, 0xcd, 0xcd,
|
||||
0xfe, 0xfe, 0xe7, 0xc9, 0xc5, 0xd3, 0xfe, 0xfe, 0xfe, 0xcd,
|
||||
0xc9, 0xd3, 0xfe, 0xfe, 0xfe, 0xdb, 0xc9, 0xcd, 0xe7, 0xfe,
|
||||
0xe7, 0xcd, 0xcd, 0xe7, 0xfe, 0xfe, 0xe7, 0xd3, 0xc5, 0xcd,
|
||||
0xe7, 0xfe, 0xfe, 0xfe, 0xdb, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xe7, 0xcd, 0xcd, 0xd3, 0xe7, 0xe7, 0xe7, 0xe7, 0xfe, 0xfe,
|
||||
0xe7, 0xe7, 0xdb, 0xc9, 0xc1, 0xc5, 0xfe, 0x5c, 0x68, 0xfe,
|
||||
0xd3, 0xdb, 0xe7, 0xe7, 0xe7, 0xd3, 0xc5, 0xcd, 0xe7, 0x68,
|
||||
0xfe, 0xe7, 0xcd, 0xd3, 0xe7, 0xfe, 0xe7, 0xcd, 0xc1, 0xc1,
|
||||
0xdb, 0xfe, 0x54, 0xfe, 0xe7, 0xcd, 0xe7, 0xfe, 0xe7, 0xd3,
|
||||
0xcd, 0xd3, 0xe7, 0xfe, 0xfe, 0xfe, 0xcd, 0xc5, 0xcd, 0xfe,
|
||||
0xfe, 0xe7, 0xcd, 0xd3, 0xdb, 0xe7, 0xfe, 0xfe, 0xfe, 0xe7,
|
||||
0xd3, 0xd3, 0xe7, 0xfe, 0xe7, 0xe7, 0xe7, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xdb, 0xc5, 0xc1, 0xd3, 0xfe, 0xfe, 0xfe, 0xd3, 0xc9,
|
||||
0xcd, 0xe7, 0xfe, 0xfe, 0xd3, 0xcd, 0xdb, 0xfe, 0x5c, 0xfe,
|
||||
0xcd, 0xc9, 0xd3, 0xfe, 0xfe, 0xfe, 0xd3, 0xc9, 0xcd, 0xfe,
|
||||
0x68, 0xfe, 0xd3, 0xc1, 0xc1, 0xdb, 0xfe, 0xfe, 0xe7, 0xe7,
|
||||
0xfe, 0xfe, 0x68, 0xfe, 0xe7, 0xc5, 0xc9, 0xdb, 0xfe, 0xfe,
|
||||
0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xdb, 0xc5, 0xc5,
|
||||
0xd3, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xe7, 0xe7, 0xfe, 0xfe,
|
||||
0xc9, 0xc1, 0xc5, 0xfe, 0x54, 0x5c, 0xfe, 0xcd, 0xc5, 0xcd,
|
||||
0xfe, 0xfe, 0xdb, 0xc5, 0xc9, 0xfe, 0x5c, 0x68, 0xfe, 0xcd,
|
||||
0xcd, 0xfe, 0xfe, 0xfe, 0xe7, 0xc5, 0xc1, 0xd3, 0xfe, 0xfe,
|
||||
0xdb, 0xc9, 0xc5, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xfe,
|
||||
0xfe, 0xfe, 0xe7, 0xcd, 0xcd, 0xdb, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xe7, 0xd3, 0xcd, 0xd3, 0xfe, 0xfe, 0xdb, 0xcd, 0xd3, 0xe7,
|
||||
0xfe, 0xfe, 0xfe, 0xdb, 0xcd, 0xd3, 0xe7, 0xfe, 0xd3, 0xc5,
|
||||
0xc9, 0xfe, 0x5c, 0x54, 0xfe, 0xcd, 0xc1, 0xcd, 0xe7, 0xfe,
|
||||
0xfe, 0xd3, 0xcd, 0xfe, 0x54, 0x5c, 0xe7, 0xc1, 0xc1, 0xd3,
|
||||
0xfe, 0xfe, 0xe7, 0xd3, 0xd3, 0xe7, 0xfe, 0xfe, 0xfe, 0xcd,
|
||||
0xc5, 0xcd, 0xd3, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xe7, 0xd3, 0xcd, 0xc9, 0xcd, 0xe7, 0xfe, 0xfe, 0xfe, 0xdb,
|
||||
0xc9, 0xcd, 0xe7, 0xfe, 0xe7, 0xc9, 0xc5, 0xdb, 0xfe, 0x5c,
|
||||
0xfe, 0xe7, 0xcd, 0xcd, 0xe7, 0xfe, 0xe7, 0xc5, 0xc1, 0xd3,
|
||||
0xfe, 0x5c, 0xfe, 0xcd, 0xc5, 0xcd, 0xe7, 0xfe, 0xfe, 0xe7,
|
||||
0xd3, 0xe7, 0xfe, 0xfe, 0xe7, 0xcd, 0xcd, 0xdb, 0xfe, 0xfe,
|
||||
0xfe, 0xe7, 0xe7, 0xe7, 0xe7, 0xfe, 0xe7, 0xdb, 0xcd, 0xd3,
|
||||
0xd3, 0xdb, 0xfe, 0xfe, 0xfe, 0xfe, 0xdb, 0xd3, 0xdb, 0xe7,
|
||||
0xe7, 0xdb, 0xd3, 0xe7, 0xfe, 0xfe, 0xfe, 0xe7, 0xc9, 0xc5,
|
||||
0xcd, 0xe7, 0xfe, 0xdb, 0xd3, 0xe7, 0xfe, 0x68, 0xfe, 0xe7,
|
||||
0xcd, 0xcd, 0xd3, 0xfe, 0xfe, 0xe7, 0xdb, 0xe7, 0xfe, 0x68,
|
||||
0xfe, 0xdb, 0xfe, 0x68, 0xbe, 0xb2, 0xae, 0xab, 0xb2, 0xfe,
|
||||
0x2f, 0x31, 0xdb, 0xac, 0xad, 0xaf, 0xab, 0xab, 0xb4, 0x68,
|
||||
0x37, 0x39, 0x3f, 0xe7, 0xb4, 0xa8, 0xaa, 0xb0, 0xbc, 0xbc,
|
||||
0xc5, 0x3f, 0x31, 0x3d, 0xfe, 0xc1, 0xb8, 0xb0, 0xa5, 0xa2,
|
||||
0xa8, 0xaf, 0xdb, 0x3b, 0x28, 0x2a, 0x3d, 0xbc, 0xb0, 0xaa,
|
||||
0xa2, 0x9f, 0xab, 0xfe, 0x29, 0x24, 0x29, 0x4a, 0xb4, 0xaa,
|
||||
0xa8, 0xa9, 0xa8, 0xa5, 0xac, 0xdb, 0x2c, 0x27, 0x35, 0x4a,
|
||||
0xfe, 0xcd, 0xb2, 0xa2, 0x9f, 0x9f, 0xae, 0x4e, 0x2c, 0x22,
|
||||
0x33, 0xfe, 0xba, 0xb0, 0xa6, 0x9f, 0xa3, 0xbc, 0x5c, 0x33,
|
||||
0x31, 0x39, 0x5c, 0xcd, 0xc1, 0xb4, 0xad, 0xaa, 0xad, 0xcd,
|
||||
0x54, 0x46, 0xfe, 0xe7, 0xfe, 0x54, 0xc5, 0xaf, 0xa6, 0xa9,
|
||||
0xb0, 0xfe, 0x3d, 0x39, 0x5c, 0xdb, 0xdb, 0xfe, 0xba, 0xac,
|
||||
0xa8, 0xc5, 0x39, 0x33, 0x54, 0xb8, 0xae, 0xad, 0xb8, 0xc1,
|
||||
0xcd, 0xbe, 0xbc, 0xfe, 0x39, 0x37, 0xfe, 0xb4, 0xba, 0xcd,
|
||||
0xdb, 0xb8, 0xb0, 0xb6, 0xfe, 0x4e, 0x39, 0x3d, 0xfe, 0xb0,
|
||||
0xaa, 0xa9, 0xa9, 0xaa, 0xb0, 0x5c, 0x29, 0x28, 0x31, 0xfe,
|
||||
0xba, 0xb4, 0xae, 0xab, 0xab, 0xb2, 0xfe, 0x3b, 0x2a, 0x2f,
|
||||
0x54, 0xb4, 0xb4, 0xba, 0xb2, 0xa3, 0x9f, 0xa8, 0xfe, 0x2c,
|
||||
0x27, 0x2a, 0x46, 0xfe, 0xc1, 0xbc, 0xb0, 0xa2, 0xa2, 0xb0,
|
||||
0x33, 0x22, 0x2b, 0x46, 0xc1, 0xb4, 0xb0, 0xab, 0xa8, 0xa8,
|
||||
0xb0, 0xdb, 0x42, 0x2c, 0x33, 0x4a, 0xfe, 0x5c, 0xdb, 0xb4,
|
||||
0xa8, 0xad, 0xba, 0xfe, 0x46, 0x39, 0x39, 0x4a, 0xfe, 0xbc,
|
||||
0xab, 0xa5, 0xa5, 0xb8, 0x68, 0x37, 0x4a, 0xe7, 0xfe, 0x4a,
|
||||
0x5c, 0xd3, 0xb0, 0xb2, 0xc1, 0x5c, 0x42, 0x46, 0xd3, 0xb4,
|
||||
0xbe, 0x54, 0x54, 0xb6, 0xab, 0xae, 0xe7, 0x46, 0x4a, 0xfe,
|
||||
0xcd, 0xc9, 0xd3, 0xe7, 0xe7, 0xbe, 0xb4, 0xc5, 0x37, 0x2c,
|
||||
0x37, 0xc1, 0xb0, 0xb2, 0xb4, 0xb2, 0xb6, 0xdb, 0x54, 0x4a,
|
||||
0x46, 0x42, 0x68, 0xba, 0xb2, 0xba, 0xc5, 0xb6, 0xb6, 0xcd,
|
||||
0x33, 0x2f, 0x39, 0x68, 0xfe, 0xe7, 0xba, 0xac, 0xa7, 0xa7,
|
||||
0xb2, 0xe7, 0x2d, 0x25, 0x2f, 0xd3, 0xbe, 0xd3, 0xc5, 0xac,
|
||||
0xa6, 0xac, 0xfe, 0x33, 0x2c, 0x2d, 0x54, 0xc1, 0xb4, 0xcd,
|
||||
0xcd, 0xaf, 0xa4, 0xa8, 0xe7, 0x31, 0x31, 0x39, 0x46, 0xfe,
|
||||
0xdb, 0xbc, 0xb6, 0xaf, 0xa9, 0xb2, 0xfe, 0x2f, 0xfe, 0xba,
|
||||
0xad, 0xba, 0x4e, 0x3d, 0x42, 0xfe, 0xc9, 0xc1, 0xe7, 0xfe,
|
||||
0xc1, 0xa9, 0xa6, 0xcd, 0x2a, 0x25, 0x3b, 0xbc, 0xb0, 0xb6,
|
||||
0xb8, 0xb4, 0xb4, 0xb8, 0xc1, 0xfe, 0x3d, 0x3d, 0xfe, 0xba,
|
||||
0xd3, 0x54, 0x54, 0xbe, 0xb0, 0xb4, 0xe7, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xc5, 0xb6, 0xa9, 0xaa, 0xba, 0x3d, 0x39,
|
||||
0xfe, 0xc1, 0xfe, 0x4a, 0x54, 0xbe, 0xb2, 0xb8, 0xfe, 0x3d,
|
||||
0x3b, 0xfe, 0xb0, 0xab, 0xc5, 0x39, 0x3b, 0xbc, 0xa7, 0xab,
|
||||
0xd3, 0x68, 0xfe, 0xd3, 0xcd, 0xfe, 0x54, 0x3d, 0xfe, 0xbc,
|
||||
0xac, 0xc9, 0x3f, 0x2e, 0xfe, 0xba, 0xb0, 0xba, 0xba, 0xb6,
|
||||
0xba, 0xd3, 0xfe, 0xfe, 0x5c, 0x54, 0xc9, 0xb4, 0xbe, 0x54,
|
||||
0x68, 0xcd, 0xb6, 0xfe, 0x46, 0x54, 0xcd, 0xc5, 0xdb, 0xfe,
|
||||
0xe7, 0xc1, 0xae, 0xa8, 0xac, 0xfe, 0x2e, 0x2e, 0xfe, 0xb6,
|
||||
0xc1, 0x5c, 0xe7, 0xb6, 0xaa, 0xb0, 0x54, 0x35, 0x2e, 0x4a,
|
||||
0xc1, 0xac, 0xbc, 0xfe, 0xfe, 0xaf, 0xa6, 0xac, 0xfe, 0x42,
|
||||
0x46, 0x5c, 0xfe, 0xfe, 0xfe, 0xe7, 0xc9, 0xae, 0xa9, 0xb0,
|
||||
0x54, 0x31, 0x37, 0xfe, 0xd3, 0xd3, 0xb8, 0xac, 0xab, 0xb6,
|
||||
0xe7, 0xfe, 0xfe, 0x68, 0xfe, 0xfe, 0xfe, 0x54, 0xfe, 0xb0,
|
||||
0xae, 0xb8, 0xfe, 0xe7, 0xc1, 0xb6, 0xe7, 0x46, 0x3d, 0xe7,
|
||||
0xae, 0xa7, 0xab, 0xdb, 0x3f, 0x37, 0xfe, 0xba, 0xcd, 0x3f,
|
||||
0x42, 0xc5, 0xab, 0xac, 0xc9, 0x46, 0x3d, 0x54, 0xba, 0xad,
|
||||
0xb0, 0xfe, 0x68, 0xcd, 0xb0, 0xb0, 0xc9, 0x54, 0x54, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xe7, 0xcd, 0xbe, 0xba, 0xc5, 0x68, 0x42,
|
||||
0x46, 0xe7, 0xc5, 0xba, 0xaf, 0xa7, 0xa7, 0xbc, 0xfe, 0x3d,
|
||||
0x4a, 0x68, 0xfe, 0xfe, 0xfe, 0xe7, 0xbc, 0xaf, 0xae, 0xc5,
|
||||
0x3d, 0x39, 0xfe, 0xbc, 0xbe, 0xfe, 0x68, 0xc9, 0xa9, 0xa2,
|
||||
0xaa, 0xbc, 0x3b, 0x2d, 0x35, 0xfe, 0xcd, 0xfe, 0xfe, 0xb4,
|
||||
0xa9, 0xa6, 0xbc, 0x54, 0x31, 0x31, 0x54, 0xd3, 0xbc, 0xc5,
|
||||
0xcd, 0xb8, 0xab, 0xa8, 0xb4, 0xfe, 0x54, 0x4e, 0x68, 0x54,
|
||||
0xfe, 0xc9, 0xba, 0xb4, 0xb4, 0xba, 0xcd, 0x5c, 0x3b, 0x3f,
|
||||
0x54, 0xfe, 0xcd, 0xaf, 0xa8, 0xac, 0xc5, 0x68, 0xfe, 0xe7,
|
||||
0xdb, 0xfe, 0xfe, 0xfe, 0xcd, 0xb8, 0xaf, 0xb6, 0xe7, 0x42,
|
||||
0x5c, 0xcd, 0xbc, 0xfe, 0x46, 0x68, 0xba, 0xb0, 0xab, 0xbc,
|
||||
0x54, 0x3d, 0x46, 0xc9, 0xb8, 0xbc, 0xdb, 0xd3, 0xb6, 0xb0,
|
||||
0xb6, 0x5c, 0x37, 0x35, 0x54, 0xc9, 0xba, 0xb4, 0xc1, 0xc9,
|
||||
0xc1, 0xba, 0xe7, 0x5c, 0x3d, 0x54, 0xfe, 0xcd, 0xc5, 0xb8,
|
||||
0xae, 0xaf, 0xb4, 0xd3, 0x54, 0x3b, 0x35, 0x46, 0xfe, 0xdb,
|
||||
0xbc, 0xaf, 0xa9, 0xab, 0xd3, 0x3f, 0x31, 0x3f, 0xfe, 0xe7,
|
||||
0xdb, 0xcd, 0xb8, 0xae, 0xaa, 0xac, 0xe7, 0x33, 0x2d, 0x3f,
|
||||
0xd3, 0xdb, 0xfe, 0xfe, 0xbc, 0xaa, 0xa9, 0xb0, 0xfe, 0x31,
|
||||
0x2f, 0x3d, 0xdb, 0xc5, 0xcd, 0xc9, 0xae, 0xa8, 0xad, 0xfe,
|
||||
0x46, 0x39, 0x46, 0x5c, 0xfe, 0xcd, 0xc5, 0xc1, 0xb6, 0xb0,
|
||||
0xbc, 0x68, 0x42, 0x4e, 0xe7, 0xfe, 0x5c, 0xfe, 0xb6, 0xaf,
|
||||
0xb0, 0xc5, 0xe7, 0x5c, 0x5c, 0xfe, 0xe7, 0xfe, 0x68, 0xe7,
|
||||
0xb0, 0xac, 0xb2, 0x4a, 0x35, 0x3f, 0xcd, 0xbc, 0xc1, 0xe7,
|
||||
0xe7, 0xd3, 0xb6, 0xb4, 0xfe, 0x3b, 0x33, 0xfe, 0xba, 0xb4,
|
||||
0xd3, 0xfe, 0xc9, 0xb4, 0xb4, 0xcd, 0x4a, 0x3b, 0x3b, 0xfe,
|
||||
0xb8, 0xb6, 0xc5, 0xc5, 0xb8, 0xb0, 0xcd, 0x4a, 0x31, 0x3b,
|
||||
0x68, 0xcd, 0xc1, 0xba, 0xb4, 0xb0, 0xb0, 0xba, 0x5c, 0x2f,
|
||||
0x2f, 0x4e, 0xc9, 0xc1, 0xdb, 0xc9, 0xb4 };
|
||||
207
apps/leave.h
Normal file
207
apps/leave.h
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* U-law 8-bit audio data
|
||||
*
|
||||
* Source: leave.raw
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer and Linux Support Services
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License
|
||||
*
|
||||
*/
|
||||
|
||||
static unsigned char leave[] = {
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xc1, 0x3d,
|
||||
0x42, 0x46, 0x3f, 0x3f, 0x46, 0x3f, 0x4e, 0xba, 0xbe, 0xbe,
|
||||
0xbc, 0xba, 0xbe, 0xc5, 0xb6, 0x2e, 0x2c, 0x33, 0x2f, 0x2e,
|
||||
0x2f, 0x33, 0x2b, 0x54, 0xac, 0xb0, 0xb0, 0xad, 0xaf, 0xb0,
|
||||
0xae, 0xcd, 0x3b, 0x2f, 0x31, 0x2e, 0x2f, 0x31, 0x2e, 0x46,
|
||||
0xc5, 0xaf, 0xb0, 0xaf, 0xae, 0xaf, 0xaf, 0xb0, 0xfe, 0x2d,
|
||||
0x31, 0x31, 0x2e, 0x31, 0x2f, 0x31, 0xfe, 0xae, 0xaf, 0xaf,
|
||||
0xae, 0xb0, 0xae, 0xaf, 0xfe, 0xdb, 0x2e, 0x2e, 0x31, 0x31,
|
||||
0x2d, 0x2e, 0xdb, 0x68, 0xaf, 0xad, 0xb0, 0xb0, 0xae, 0xaf,
|
||||
0x5c, 0xe7, 0x39, 0x2d, 0x31, 0x31, 0x31, 0x2d, 0xfe, 0xfe,
|
||||
0x68, 0xad, 0xaf, 0xb0, 0xaf, 0xac, 0xbc, 0xfe, 0xd3, 0x2f,
|
||||
0x2e, 0x33, 0x31, 0x2d, 0x4e, 0xdb, 0xfe, 0xfe, 0xac, 0xaf,
|
||||
0xb0, 0xac, 0xb6, 0x68, 0xe7, 0xdb, 0x2e, 0x2f, 0x35, 0x2f,
|
||||
0x31, 0xe7, 0xe7, 0x68, 0xad, 0xac, 0xb0, 0xae, 0xac, 0xfe,
|
||||
0xfe, 0xdb, 0xfe, 0x2d, 0x33, 0x31, 0x2e, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xbc, 0xaf, 0xb0, 0xad, 0xfe, 0xfe, 0xfe, 0xe7, 0x5c,
|
||||
0x2e, 0x33, 0x2e, 0x35, 0xe7, 0xfe, 0xfe, 0xfe, 0xad, 0xb0,
|
||||
0xaf, 0xc1, 0xfe, 0xe7, 0xfe, 0xe7, 0x3d, 0x31, 0x2f, 0x37,
|
||||
0xe7, 0xfe, 0xfe, 0xe7, 0xfe, 0xaf, 0xad, 0xbe, 0xfe, 0xdb,
|
||||
0xfe, 0xfe, 0xdb, 0x35, 0x2d, 0x39, 0xdb, 0xfe, 0xfe, 0xdb,
|
||||
0xfe, 0xfe, 0xad, 0xaf, 0xfe, 0xfe, 0xe7, 0x68, 0xfe, 0xd3,
|
||||
0x2e, 0x2c, 0xdb, 0xdb, 0x2c, 0x35, 0xd3, 0x68, 0xaf, 0xad,
|
||||
0xb0, 0xb0, 0xad, 0xba, 0x68, 0xe7, 0xe7, 0x2e, 0x2f, 0x33,
|
||||
0x31, 0x2d, 0xdb, 0xd3, 0x5c, 0xae, 0xaa, 0xe7, 0x68, 0xaa,
|
||||
0xe7, 0xfe, 0xdb, 0xe7, 0xfe, 0xe7, 0xd3, 0x2d, 0xfe, 0xdb,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xc5, 0xfe, 0xe7, 0xe7,
|
||||
0xfe, 0xfe, 0xe7, 0xe7, 0x3b, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xc5, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xe7, 0xfe, 0x3b,
|
||||
0xdb, 0xfe, 0xfe, 0xfe, 0xe7, 0xfe, 0xfe, 0xb0, 0xfe, 0xfe,
|
||||
0xe7, 0xfe, 0xfe, 0xfe, 0xdb, 0x2e, 0x5c, 0xdb, 0xfe, 0xfe,
|
||||
0xe7, 0xe7, 0x68, 0xb0, 0xbe, 0x68, 0xe7, 0xe7, 0xfe, 0xfe,
|
||||
0xdb, 0x39, 0x2f, 0xdb, 0xfe, 0xfe, 0xe7, 0xe7, 0xfe, 0xbe,
|
||||
0xaf, 0xe7, 0x68, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0x33, 0x33,
|
||||
0xdb, 0xfe, 0xfe, 0xdb, 0xe7, 0xfe, 0xb0, 0xb0, 0xfe, 0xfe,
|
||||
0xe7, 0xfe, 0xfe, 0xfe, 0x35, 0x33, 0xe7, 0xe7, 0xfe, 0xe7,
|
||||
0xe7, 0xfe, 0xb0, 0xb2, 0xb0, 0xfe, 0xfe, 0xe7, 0xfe, 0xe7,
|
||||
0x46, 0x35, 0x35, 0x3f, 0xe7, 0xfe, 0xe7, 0xfe, 0xb2, 0xb0,
|
||||
0xb2, 0xb0, 0xfe, 0xfe, 0xfe, 0xfe, 0x42, 0x35, 0x37, 0x33,
|
||||
0xe7, 0xfe, 0xfe, 0xfe, 0xb8, 0xb0, 0xb6, 0xb0, 0xba, 0xfe,
|
||||
0xfe, 0xe7, 0xe7, 0x33, 0x39, 0x39, 0x33, 0xe7, 0xdb, 0xfe,
|
||||
0xe7, 0xb0, 0xb4, 0xb6, 0xb0, 0xcd, 0xfe, 0xe7, 0xe7, 0x33,
|
||||
0x39, 0x3b, 0x33, 0x46, 0xd3, 0xfe, 0xfe, 0xb0, 0xb2, 0xb6,
|
||||
0xb4, 0xb0, 0xfe, 0xfe, 0xdb, 0x35, 0x37, 0x39, 0x39, 0x35,
|
||||
0x37, 0xdb, 0x68, 0xcd, 0xb2, 0xb6, 0xb6, 0xb4, 0xb4, 0x68,
|
||||
0xe7, 0x42, 0x37, 0x3b, 0x3b, 0x39, 0x37, 0xdb, 0xfe, 0xcd,
|
||||
0xb2, 0xb6, 0xb6, 0xb6, 0xb2, 0xb4, 0xfe, 0x54, 0x37, 0x3b,
|
||||
0x39, 0x3b, 0x3b, 0x39, 0xe7, 0xfe, 0xb6, 0xb6, 0xb6, 0xb4,
|
||||
0xb6, 0xb6, 0xbc, 0xfe, 0x3f, 0x3b, 0x3b, 0x39, 0x3b, 0x3b,
|
||||
0x39, 0xe7, 0xb6, 0xb8, 0xb8, 0xb6, 0xb8, 0xb8, 0xb4, 0xfe,
|
||||
0x3b, 0x3d, 0x3d, 0x3b, 0x39, 0x3d, 0x3b, 0x39, 0xbe, 0xb8,
|
||||
0xba, 0xb8, 0xb6, 0xb8, 0xba, 0xb4, 0xfe, 0x39, 0x3f, 0x3d,
|
||||
0x3b, 0x3d, 0x3f, 0x39, 0xdb, 0xb4, 0xba, 0xb8, 0xb6, 0xb8,
|
||||
0xbc, 0xb4, 0xba, 0x39, 0x42, 0x3f, 0x3d, 0x3d, 0x3f, 0x3f,
|
||||
0x3b, 0xb8, 0xb6, 0xbc, 0xb8, 0xb8, 0xba, 0xbc, 0xb8, 0xe7,
|
||||
0x3d, 0x42, 0x3f, 0x3d, 0x3f, 0x42, 0x3d, 0xfe, 0xb8, 0xbc,
|
||||
0xbc, 0xba, 0xba, 0xbc, 0xba, 0xe7, 0x3d, 0x3f, 0x42, 0x3f,
|
||||
0x3f, 0x42, 0x42, 0xfe, 0xfe, 0xbc, 0xbc, 0xbe, 0xbc, 0xbe,
|
||||
0xbc, 0xc5, 0xe7, 0x68, 0x42, 0x46, 0x42, 0x46, 0x42, 0x46,
|
||||
0xfe, 0xfe, 0xbc, 0xbe, 0xbe, 0xbe, 0xbc, 0xc5, 0xfe, 0xdb,
|
||||
0x46, 0x46, 0x4a, 0x4a, 0x46, 0x46, 0xe7, 0xfe, 0xd3, 0xbe,
|
||||
0xc9, 0xc9, 0xc5, 0xc5, 0xe7, 0xdb, 0xd3, 0x4a, 0x4e, 0x54,
|
||||
0x4e, 0x4e, 0xfe, 0x5c, 0x54, 0xd3, 0xcd, 0xd3, 0xd3, 0xcd,
|
||||
0xd3, 0xd3, 0xcd, 0xfe, 0x5c, 0x68, 0x5c, 0x5c, 0x5c, 0x68,
|
||||
0x5c, 0x5c, 0xcd, 0xcd, 0xd3, 0xcd, 0xdb, 0xe7, 0xe7, 0xdb,
|
||||
0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xe7,
|
||||
0xfe, 0x5c, 0x5c, 0xfe, 0xfe, 0xfe, 0xfe, 0x46, 0x35, 0x35,
|
||||
0x37, 0x39, 0x3b, 0x39, 0x35, 0x33, 0x35, 0x5c, 0xd3, 0xcd,
|
||||
0xdb, 0xfe, 0xfe, 0xd3, 0xb0, 0xb0, 0xb0, 0xb4, 0xb4, 0xb6,
|
||||
0xb2, 0xb0, 0xb0, 0xb6, 0xcd, 0x5c, 0x68, 0xfe, 0xfe, 0xfe,
|
||||
0x3b, 0x33, 0x35, 0x37, 0x39, 0x3b, 0x39, 0x37, 0x35, 0x35,
|
||||
0x3f, 0xdb, 0xcd, 0xcd, 0xdb, 0xfe, 0xe7, 0xc5, 0xb0, 0xb0,
|
||||
0xb2, 0xb6, 0xb6, 0xb6, 0xb2, 0xb0, 0xb0, 0xcd, 0x5c, 0x5c,
|
||||
0xfe, 0xe7, 0xe7, 0xfe, 0x35, 0x35, 0x35, 0x39, 0x3b, 0x3b,
|
||||
0x39, 0x35, 0x33, 0x39, 0xdb, 0xcd, 0xd3, 0xe7, 0xfe, 0xfe,
|
||||
0xba, 0xb0, 0xb0, 0xb2, 0xb4, 0xb6, 0xb6, 0xb4, 0xb2, 0xb0,
|
||||
0xb4, 0xc9, 0x5c, 0x68, 0xfe, 0xfe, 0x5c, 0x3b, 0x35, 0x37,
|
||||
0x39, 0x3b, 0x3b, 0x3b, 0x39, 0x37, 0x37, 0x3d, 0xe7, 0xcd,
|
||||
0xdb, 0xfe, 0xe7, 0xbe, 0xb2, 0xb2, 0xb4, 0xb4, 0xb6, 0xb6,
|
||||
0xb6, 0xb4, 0xb0, 0xb0, 0xc5, 0x5c, 0x5c, 0xfe, 0xe7, 0xe7,
|
||||
0x4e, 0x35, 0x35, 0x37, 0x3b, 0x3b, 0x3b, 0x39, 0x37, 0x37,
|
||||
0x3b, 0xe7, 0xc9, 0xcd, 0xe7, 0xfe, 0xd3, 0xb4, 0xb2, 0xb2,
|
||||
0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb4, 0xb2, 0xb4, 0xc1, 0x68,
|
||||
0x68, 0xfe, 0xfe, 0x42, 0x39, 0x37, 0x39, 0x3b, 0x3b, 0x3b,
|
||||
0x3b, 0x3b, 0x39, 0x37, 0x3b, 0xfe, 0xd3, 0xdb, 0xfe, 0xcd,
|
||||
0xb4, 0xb2, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb4, 0xb2,
|
||||
0xb2, 0xc1, 0x5c, 0x5c, 0xfe, 0xfe, 0xfe, 0x3d, 0x37, 0x37,
|
||||
0x39, 0x3b, 0x3b, 0x3b, 0x3b, 0x37, 0x37, 0x39, 0xfe, 0xcd,
|
||||
0xd3, 0xfe, 0xfe, 0xc1, 0xb2, 0xb2, 0xb4, 0xb6, 0xb6, 0xb6,
|
||||
0xb6, 0xb6, 0xb6, 0xb4, 0xb4, 0xbc, 0x68, 0xfe, 0xfe, 0xfe,
|
||||
0x3b, 0x39, 0x39, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x39,
|
||||
0x39, 0x3b, 0xfe, 0xdb, 0xe7, 0xfe, 0xbc, 0xb6, 0xb6, 0xb6,
|
||||
0xb8, 0xb6, 0xb6, 0xb6, 0xb8, 0xb6, 0xb4, 0xb4, 0xbc, 0xfe,
|
||||
0x68, 0xfe, 0xe7, 0x5c, 0x3b, 0x39, 0x39, 0x3b, 0x3b, 0x3b,
|
||||
0x3d, 0x3d, 0x3b, 0x39, 0x3b, 0x68, 0xdb, 0xdb, 0xfe, 0xe7,
|
||||
0xb8, 0xb6, 0xb6, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb6,
|
||||
0xb4, 0xb6, 0xdb, 0x68, 0xfe, 0xfe, 0x46, 0x3b, 0x3b, 0x3b,
|
||||
0x3d, 0x3d, 0x3b, 0x3d, 0x3d, 0x3d, 0x3d, 0x3b, 0x3b, 0x5c,
|
||||
0xdb, 0xdb, 0xc9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
|
||||
0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xbc, 0xcd, 0xfe, 0xfe, 0x3d,
|
||||
0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3b, 0x3d, 0x3d, 0x3d, 0x3d,
|
||||
0x3b, 0x3d, 0x46, 0xfe, 0xe7, 0xe7, 0xc5, 0xb8, 0xb8, 0xb8,
|
||||
0xba, 0xba, 0xb8, 0xb8, 0xba, 0xba, 0xb8, 0xb8, 0xb8, 0xcd,
|
||||
0xfe, 0xfe, 0x68, 0x3f, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
|
||||
0x3d, 0x3d, 0x3f, 0x3f, 0x3d, 0x3b, 0x4a, 0xfe, 0xdb, 0xbc,
|
||||
0xb8, 0xba, 0xba, 0xba, 0xba, 0xb8, 0xb8, 0xb8, 0xba, 0xba,
|
||||
0xba, 0xba, 0xba, 0xc5, 0xfe, 0x54, 0x3f, 0x3f, 0x3f, 0x3f,
|
||||
0x3f, 0x3f, 0x3d, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x42,
|
||||
0xfe, 0xe7, 0xdb, 0xbc, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
|
||||
0xba, 0xba, 0xbc, 0xba, 0xba, 0xba, 0xc5, 0xfe, 0xfe, 0x4e,
|
||||
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x42,
|
||||
0x42, 0x42, 0x3f, 0x46, 0xfe, 0xcd, 0xb8, 0xba, 0xbc, 0xbc,
|
||||
0xbc, 0xba, 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xba, 0xb8,
|
||||
0xbe, 0xfe, 0x42, 0x3d, 0x3f, 0x42, 0x42, 0x42, 0x3f, 0x3f,
|
||||
0x3f, 0x42, 0x42, 0x42, 0x42, 0x3f, 0x3f, 0x68, 0xdb, 0xc5,
|
||||
0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xba, 0xba, 0xba, 0xbc, 0xbc,
|
||||
0xbc, 0xbc, 0xba, 0xc1, 0xfe, 0xfe, 0x3f, 0x42, 0x46, 0x46,
|
||||
0x46, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x46, 0x42, 0x3f,
|
||||
0x42, 0x68, 0xbe, 0xba, 0xbc, 0xbe, 0xbe, 0xbe, 0xbc, 0xbc,
|
||||
0xbc, 0xbc, 0xbe, 0xc1, 0xbe, 0xbc, 0xba, 0xbe, 0x68, 0x3f,
|
||||
0x42, 0x46, 0x4a, 0x4a, 0x46, 0x42, 0x42, 0x42, 0x46, 0x46,
|
||||
0x46, 0x46, 0x42, 0x42, 0x68, 0xd3, 0xbc, 0xbc, 0xbe, 0xc1,
|
||||
0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc1, 0xbe, 0xbe,
|
||||
0xc1, 0xfe, 0x4e, 0x42, 0x46, 0x4a, 0x4a, 0x4a, 0x46, 0x46,
|
||||
0x46, 0x46, 0x4a, 0x4a, 0x4a, 0x46, 0x46, 0x68, 0xdb, 0xbe,
|
||||
0xbe, 0xc1, 0xc5, 0xc1, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xc1,
|
||||
0xc5, 0xc5, 0xbe, 0xbc, 0xc1, 0x4e, 0x46, 0x46, 0x4a, 0x4e,
|
||||
0x4e, 0x4a, 0x46, 0x46, 0x46, 0x4a, 0x4a, 0x4e, 0x4a, 0x46,
|
||||
0x46, 0xfe, 0xbe, 0xbe, 0xc1, 0xc9, 0xc5, 0xc5, 0xc1, 0xc1,
|
||||
0xc1, 0xc1, 0xc5, 0xc5, 0xc5, 0xc5, 0xbe, 0xc1, 0xfe, 0x4a,
|
||||
0x4a, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4a, 0x4a, 0x4a, 0x4e,
|
||||
0x54, 0x4e, 0x4a, 0x4a, 0x4e, 0xcd, 0xc1, 0xc5, 0xc5, 0xc9,
|
||||
0xc5, 0xc5, 0xc5, 0xc5, 0xc9, 0xcd, 0xcd, 0xcd, 0xcd, 0xc9,
|
||||
0xc9, 0xd3, 0x68, 0x54, 0x5c, 0x68, 0x68, 0x68, 0x5c, 0x5c,
|
||||
0x5c, 0x5c, 0x5c, 0x68, 0x68, 0x5c, 0x54, 0x5c, 0xdb, 0xcd,
|
||||
0xcd, 0xdb, 0xdb, 0xdb, 0xdb, 0xd3, 0xd3, 0xe7, 0xe7, 0xe7,
|
||||
0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe };
|
||||
BIN
apps/rpt_flow.pdf
Normal file
BIN
apps/rpt_flow.pdf
Normal file
Binary file not shown.
880
ast_expr.y
Normal file
880
ast_expr.y
Normal file
@@ -0,0 +1,880 @@
|
||||
%{
|
||||
/* Written by Pace Willisson (pace@blitz.com)
|
||||
* and placed in the public domain.
|
||||
*
|
||||
* Largely rewritten by J.T. Conklin (jtc@wimsey.com)
|
||||
*
|
||||
* $FreeBSD: src/bin/expr/expr.y,v 1.16 2000/07/22 10:59:36 se Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <regex.h>
|
||||
#include <limits.h>
|
||||
#include <asterisk/ast_expr.h>
|
||||
#include <asterisk/logger.h>
|
||||
|
||||
#ifdef LONG_LONG_MIN
|
||||
#define QUAD_MIN LONG_LONG_MIN
|
||||
#endif
|
||||
#ifdef LONG_LONG_MAX
|
||||
#define QUAD_MAX LONG_LONG_MAX
|
||||
#endif
|
||||
|
||||
# if ! defined(QUAD_MIN)
|
||||
# define QUAD_MIN (-0x7fffffffffffffffL-1)
|
||||
# endif
|
||||
# if ! defined(QUAD_MAX)
|
||||
# define QUAD_MAX (0x7fffffffffffffffL)
|
||||
# endif
|
||||
|
||||
#define YYPARSE_PARAM kota
|
||||
#define YYLEX_PARAM kota
|
||||
|
||||
/* #define ast_log fprintf
|
||||
#define LOG_WARNING stderr */
|
||||
|
||||
enum valtype {
|
||||
integer, numeric_string, string
|
||||
} ;
|
||||
|
||||
struct val {
|
||||
enum valtype type;
|
||||
union {
|
||||
char *s;
|
||||
quad_t i;
|
||||
} u;
|
||||
} ;
|
||||
|
||||
struct parser_control {
|
||||
struct val *result;
|
||||
int pipa;
|
||||
char *arg_orig;
|
||||
char *argv;
|
||||
char *ptrptr;
|
||||
int firsttoken;
|
||||
} ;
|
||||
|
||||
static int chk_div __P((quad_t, quad_t));
|
||||
static int chk_minus __P((quad_t, quad_t, quad_t));
|
||||
static int chk_plus __P((quad_t, quad_t, quad_t));
|
||||
static int chk_times __P((quad_t, quad_t, quad_t));
|
||||
static void free_value __P((struct val *));
|
||||
static int is_zero_or_null __P((struct val *));
|
||||
static int isstring __P((struct val *));
|
||||
static struct val *make_integer __P((quad_t));
|
||||
static struct val *make_str __P((const char *));
|
||||
static struct val *op_and __P((struct val *, struct val *));
|
||||
static struct val *op_colon __P((struct val *, struct val *));
|
||||
static struct val *op_div __P((struct val *, struct val *));
|
||||
static struct val *op_eq __P((struct val *, struct val *));
|
||||
static struct val *op_ge __P((struct val *, struct val *));
|
||||
static struct val *op_gt __P((struct val *, struct val *));
|
||||
static struct val *op_le __P((struct val *, struct val *));
|
||||
static struct val *op_lt __P((struct val *, struct val *));
|
||||
static struct val *op_minus __P((struct val *, struct val *));
|
||||
static struct val *op_ne __P((struct val *, struct val *));
|
||||
static struct val *op_or __P((struct val *, struct val *));
|
||||
static struct val *op_plus __P((struct val *, struct val *));
|
||||
static struct val *op_rem __P((struct val *, struct val *));
|
||||
static struct val *op_times __P((struct val *, struct val *));
|
||||
static quad_t to_integer __P((struct val *));
|
||||
static void to_string __P((struct val *));
|
||||
|
||||
/* uh, if I want to predeclare yylex with a YYLTYPE, I have to predeclare the yyltype... sigh */
|
||||
typedef struct yyltype
|
||||
{
|
||||
int first_line;
|
||||
int first_column;
|
||||
|
||||
int last_line;
|
||||
int last_column;
|
||||
} yyltype;
|
||||
|
||||
# define YYLTYPE yyltype
|
||||
# define YYLTYPE_IS_TRIVIAL 1
|
||||
|
||||
static int ast_yyerror __P((const char *,YYLTYPE *, struct parser_control *));
|
||||
|
||||
#define ast_yyerror(x) ast_yyerror(x,&yyloc,kota)
|
||||
|
||||
%}
|
||||
|
||||
%pure-parser
|
||||
%locations
|
||||
/* %debug for when you are having big problems */
|
||||
|
||||
/* %name-prefix="ast_yy" */
|
||||
|
||||
%union
|
||||
{
|
||||
struct val *val;
|
||||
}
|
||||
|
||||
%{
|
||||
static int ast_yylex __P((YYSTYPE *, YYLTYPE *, struct parser_control *));
|
||||
%}
|
||||
|
||||
|
||||
%left <val> '|'
|
||||
%left <val> '&'
|
||||
%left <val> '=' '>' '<' GE LE NE
|
||||
%left <val> '+' '-'
|
||||
%left <val> '*' '/' '%'
|
||||
%left <val> ':'
|
||||
|
||||
%token <val> TOKEN
|
||||
%type <val> start expr
|
||||
|
||||
%%
|
||||
|
||||
start: expr { ((struct parser_control *)kota)->result = $$; }
|
||||
;
|
||||
|
||||
expr: TOKEN
|
||||
| '(' expr ')' { $$ = $2; @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr '|' expr { $$ = op_or ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr '&' expr { $$ = op_and ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr '=' expr { $$ = op_eq ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr '>' expr { $$ = op_gt ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr '<' expr { $$ = op_lt ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr GE expr { $$ = op_ge ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr LE expr { $$ = op_le ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr NE expr { $$ = op_ne ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr '+' expr { $$ = op_plus ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr '-' expr { $$ = op_minus ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr '*' expr { $$ = op_times ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr '/' expr { $$ = op_div ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr '%' expr { $$ = op_rem ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
| expr ':' expr { $$ = op_colon ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
|
||||
;
|
||||
|
||||
|
||||
%%
|
||||
|
||||
static struct val *
|
||||
make_integer (i)
|
||||
quad_t i;
|
||||
{
|
||||
struct val *vp;
|
||||
|
||||
vp = (struct val *) malloc (sizeof (*vp));
|
||||
if (vp == NULL) {
|
||||
ast_log(LOG_WARNING, "malloc() failed\n");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
vp->type = integer;
|
||||
vp->u.i = i;
|
||||
return vp;
|
||||
}
|
||||
|
||||
static struct val *
|
||||
make_str (s)
|
||||
const char *s;
|
||||
{
|
||||
struct val *vp;
|
||||
size_t i;
|
||||
int isint;
|
||||
|
||||
vp = (struct val *) malloc (sizeof (*vp));
|
||||
if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) {
|
||||
ast_log(LOG_WARNING,"malloc() failed\n");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
for(i = 1, isint = isdigit(s[0]) || s[0] == '-';
|
||||
isint && i < strlen(s);
|
||||
i++)
|
||||
{
|
||||
if(!isdigit(s[i]))
|
||||
isint = 0;
|
||||
}
|
||||
|
||||
if (isint)
|
||||
vp->type = numeric_string;
|
||||
else
|
||||
vp->type = string;
|
||||
|
||||
return vp;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
free_value (vp)
|
||||
struct val *vp;
|
||||
{
|
||||
if (vp==NULL) {
|
||||
return;
|
||||
}
|
||||
if (vp->type == string || vp->type == numeric_string)
|
||||
free (vp->u.s);
|
||||
free (vp);
|
||||
}
|
||||
|
||||
|
||||
static quad_t
|
||||
to_integer (vp)
|
||||
struct val *vp;
|
||||
{
|
||||
quad_t i;
|
||||
|
||||
if (vp == NULL) {
|
||||
ast_log(LOG_WARNING,"vp==NULL in to_integer()\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (vp->type == integer)
|
||||
return 1;
|
||||
|
||||
if (vp->type == string)
|
||||
return 0;
|
||||
|
||||
/* vp->type == numeric_string, make it numeric */
|
||||
errno = 0;
|
||||
i = strtoq(vp->u.s, (char**)NULL, 10);
|
||||
if (errno != 0) {
|
||||
free(vp->u.s);
|
||||
ast_log(LOG_WARNING,"overflow\n");
|
||||
return(0);
|
||||
}
|
||||
free (vp->u.s);
|
||||
vp->u.i = i;
|
||||
vp->type = integer;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
to_string (vp)
|
||||
struct val *vp;
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if (vp->type == string || vp->type == numeric_string)
|
||||
return;
|
||||
|
||||
tmp = malloc ((size_t)25);
|
||||
if (tmp == NULL) {
|
||||
ast_log(LOG_WARNING,"malloc() failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf (tmp, "%lld", (long long)vp->u.i);
|
||||
vp->type = string;
|
||||
vp->u.s = tmp;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
isstring (vp)
|
||||
struct val *vp;
|
||||
{
|
||||
/* only TRUE if this string is not a valid integer */
|
||||
return (vp->type == string);
|
||||
}
|
||||
|
||||
static int
|
||||
ast_yylex (YYSTYPE *lvalp, YYLTYPE *yylloc, struct parser_control *karoto)
|
||||
{
|
||||
char *p=0;
|
||||
char *t1=0;
|
||||
char savep = 0;
|
||||
char *savepp = 0;
|
||||
|
||||
if (karoto->firsttoken==1) {
|
||||
t1 = karoto->argv;
|
||||
karoto->firsttoken = 0;
|
||||
} else {
|
||||
t1 = karoto->ptrptr;
|
||||
}
|
||||
|
||||
while(*t1 && *t1 == ' ' ) /* we can remove worries about leading/multiple spaces being present */
|
||||
t1++;
|
||||
karoto->ptrptr = t1;
|
||||
yylloc->first_column = t1 - karoto->argv;
|
||||
|
||||
while( *t1 && *t1 != ' ' && *t1 != '"') /* find the next space or quote */
|
||||
t1++;
|
||||
if( *t1 == ' ' )
|
||||
{
|
||||
*t1 = 0;
|
||||
p = karoto->ptrptr;
|
||||
karoto->ptrptr = t1+1;
|
||||
yylloc->last_column = t1 - karoto->argv;
|
||||
}
|
||||
else if (*t1 == '"' )
|
||||
{
|
||||
/* opening quote. find the closing quote */
|
||||
char *t2=t1+1;
|
||||
while( *t2 && *t2 != '"')
|
||||
t2++;
|
||||
if( *t2 == '"' )
|
||||
{
|
||||
if( *(t2+1) == ' ' || *(t2+1) == 0 )
|
||||
{
|
||||
if( *(t2+1) )
|
||||
{
|
||||
*(t2+1) = 0;
|
||||
karoto->ptrptr = t2+2;
|
||||
}
|
||||
else
|
||||
{
|
||||
karoto->ptrptr = t2+1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* hmmm. what if another token is here? */
|
||||
/* maybe we can insert a space? */
|
||||
savep = *(t2+1);
|
||||
savepp = t2+1;
|
||||
*(t2+1) = 0;
|
||||
karoto->ptrptr = t2+1;
|
||||
}
|
||||
p = t1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* NOT GOOD -- no closing quote! */
|
||||
p = t1;
|
||||
karoto->ptrptr = t2;
|
||||
}
|
||||
yylloc->last_column = t2 - karoto->argv;
|
||||
}
|
||||
else if( *t1 == 0 )
|
||||
{
|
||||
if( t1 != karoto->ptrptr )
|
||||
{
|
||||
/* this is the last token */
|
||||
p = karoto->ptrptr;
|
||||
karoto->ptrptr = t1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we are done. That was quick */
|
||||
p = karoto->ptrptr;
|
||||
yylloc->last_column = t1 - karoto->argv;
|
||||
}
|
||||
}
|
||||
if( *p == 0 )
|
||||
p = 0;
|
||||
|
||||
if (p==NULL) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
if (strlen (p) == 1) {
|
||||
if (strchr ("|&=<>+-*/%:()", *p))
|
||||
return (*p);
|
||||
} else if (strlen (p) == 2 && p[1] == '=') {
|
||||
switch (*p) {
|
||||
case '>': return (GE);
|
||||
case '<': return (LE);
|
||||
case '!': return (NE);
|
||||
}
|
||||
}
|
||||
|
||||
lvalp->val = make_str (p);
|
||||
if( savep )
|
||||
{
|
||||
*savepp = savep; /* restore the null terminated string */
|
||||
savepp = 0;
|
||||
savep = 0;
|
||||
}
|
||||
return (TOKEN);
|
||||
}
|
||||
|
||||
static int
|
||||
is_zero_or_null (vp)
|
||||
struct val *vp;
|
||||
{
|
||||
if (vp->type == integer) {
|
||||
return (vp->u.i == 0);
|
||||
} else {
|
||||
return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0));
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
char *ast_expr (char *arg)
|
||||
{
|
||||
struct parser_control karoto;
|
||||
|
||||
char *kota;
|
||||
char *pirouni;
|
||||
|
||||
kota=strdup(arg);
|
||||
karoto.result = NULL;
|
||||
karoto.firsttoken=1;
|
||||
karoto.argv=kota;
|
||||
karoto.arg_orig = arg;
|
||||
/* ast_yydebug = 1; */
|
||||
|
||||
ast_yyparse ((void *)&karoto);
|
||||
|
||||
free(kota);
|
||||
|
||||
if (karoto.result==NULL) {
|
||||
pirouni=strdup("0");
|
||||
return(pirouni);
|
||||
} else {
|
||||
if (karoto.result->type == integer) {
|
||||
pirouni=malloc(256);
|
||||
sprintf (pirouni,"%lld", (long long)karoto.result->u.i);
|
||||
}
|
||||
else {
|
||||
pirouni=strdup(karoto.result->u.s);
|
||||
}
|
||||
free(karoto.result);
|
||||
}
|
||||
return(pirouni);
|
||||
}
|
||||
|
||||
#ifdef STANDALONE
|
||||
|
||||
int main(int argc,char **argv) {
|
||||
char *s;
|
||||
|
||||
s=ast_expr(argv[1]);
|
||||
|
||||
printf("=====%s======\n",s);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#undef ast_yyerror
|
||||
#define ast_yyerror(x) ast_yyerror(x, YYLTYPE *yylloc, struct parser_control *karoto)
|
||||
|
||||
static int
|
||||
ast_yyerror (const char *s)
|
||||
{
|
||||
char spacebuf[8000]; /* best safe than sorry */
|
||||
char spacebuf2[8000]; /* best safe than sorry */
|
||||
int i=0;
|
||||
spacebuf[0] = 0;
|
||||
|
||||
if( yylloc->first_column > 7990 ) /* if things get out of whack, why crash? */
|
||||
yylloc->first_column = 7990;
|
||||
if( yylloc->last_column > 7990 )
|
||||
yylloc->last_column = 7990;
|
||||
for(i=0;i<yylloc->first_column;i++) spacebuf[i] = ' ';
|
||||
for( ;i<yylloc->last_column;i++) spacebuf[i] = '^';
|
||||
spacebuf[i] = 0;
|
||||
|
||||
for(i=0;i<karoto->ptrptr-karoto->argv;i++) spacebuf2[i] = ' ';
|
||||
spacebuf2[i++]='^';
|
||||
spacebuf2[i]= 0;
|
||||
|
||||
ast_log(LOG_WARNING,"ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n%s\n",s,
|
||||
karoto->arg_orig,spacebuf,spacebuf2);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static struct val *
|
||||
op_or (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
if (is_zero_or_null (a)) {
|
||||
free_value (a);
|
||||
return (b);
|
||||
} else {
|
||||
free_value (b);
|
||||
return (a);
|
||||
}
|
||||
}
|
||||
|
||||
static struct val *
|
||||
op_and (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
if (is_zero_or_null (a) || is_zero_or_null (b)) {
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return (make_integer ((quad_t)0));
|
||||
} else {
|
||||
free_value (b);
|
||||
return (a);
|
||||
}
|
||||
}
|
||||
|
||||
static struct val *
|
||||
op_eq (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
struct val *r;
|
||||
|
||||
if (isstring (a) || isstring (b)) {
|
||||
to_string (a);
|
||||
to_string (b);
|
||||
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) == 0));
|
||||
} else {
|
||||
(void)to_integer(a);
|
||||
(void)to_integer(b);
|
||||
r = make_integer ((quad_t)(a->u.i == b->u.i));
|
||||
}
|
||||
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct val *
|
||||
op_gt (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
struct val *r;
|
||||
|
||||
if (isstring (a) || isstring (b)) {
|
||||
to_string (a);
|
||||
to_string (b);
|
||||
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) > 0));
|
||||
} else {
|
||||
(void)to_integer(a);
|
||||
(void)to_integer(b);
|
||||
r = make_integer ((quad_t)(a->u.i > b->u.i));
|
||||
}
|
||||
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct val *
|
||||
op_lt (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
struct val *r;
|
||||
|
||||
if (isstring (a) || isstring (b)) {
|
||||
to_string (a);
|
||||
to_string (b);
|
||||
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) < 0));
|
||||
} else {
|
||||
(void)to_integer(a);
|
||||
(void)to_integer(b);
|
||||
r = make_integer ((quad_t)(a->u.i < b->u.i));
|
||||
}
|
||||
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct val *
|
||||
op_ge (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
struct val *r;
|
||||
|
||||
if (isstring (a) || isstring (b)) {
|
||||
to_string (a);
|
||||
to_string (b);
|
||||
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) >= 0));
|
||||
} else {
|
||||
(void)to_integer(a);
|
||||
(void)to_integer(b);
|
||||
r = make_integer ((quad_t)(a->u.i >= b->u.i));
|
||||
}
|
||||
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct val *
|
||||
op_le (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
struct val *r;
|
||||
|
||||
if (isstring (a) || isstring (b)) {
|
||||
to_string (a);
|
||||
to_string (b);
|
||||
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) <= 0));
|
||||
} else {
|
||||
(void)to_integer(a);
|
||||
(void)to_integer(b);
|
||||
r = make_integer ((quad_t)(a->u.i <= b->u.i));
|
||||
}
|
||||
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct val *
|
||||
op_ne (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
struct val *r;
|
||||
|
||||
if (isstring (a) || isstring (b)) {
|
||||
to_string (a);
|
||||
to_string (b);
|
||||
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) != 0));
|
||||
} else {
|
||||
(void)to_integer(a);
|
||||
(void)to_integer(b);
|
||||
r = make_integer ((quad_t)(a->u.i != b->u.i));
|
||||
}
|
||||
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
chk_plus (a, b, r)
|
||||
quad_t a, b, r;
|
||||
{
|
||||
/* sum of two positive numbers must be positive */
|
||||
if (a > 0 && b > 0 && r <= 0)
|
||||
return 1;
|
||||
/* sum of two negative numbers must be negative */
|
||||
if (a < 0 && b < 0 && r >= 0)
|
||||
return 1;
|
||||
/* all other cases are OK */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct val *
|
||||
op_plus (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
struct val *r;
|
||||
|
||||
if (!to_integer (a)) {
|
||||
ast_log(LOG_WARNING,"non-numeric argument\n");
|
||||
if (!to_integer (b)) {
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
return make_integer(0);
|
||||
} else {
|
||||
free_value(a);
|
||||
return (b);
|
||||
}
|
||||
} else if (!to_integer(b)) {
|
||||
free_value(b);
|
||||
return (a);
|
||||
}
|
||||
|
||||
r = make_integer (/*(quad_t)*/(a->u.i + b->u.i));
|
||||
if (chk_plus (a->u.i, b->u.i, r->u.i)) {
|
||||
ast_log(LOG_WARNING,"overflow\n");
|
||||
}
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
chk_minus (a, b, r)
|
||||
quad_t a, b, r;
|
||||
{
|
||||
/* special case subtraction of QUAD_MIN */
|
||||
if (b == QUAD_MIN) {
|
||||
if (a >= 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
/* this is allowed for b != QUAD_MIN */
|
||||
return chk_plus (a, -b, r);
|
||||
}
|
||||
|
||||
static struct val *
|
||||
op_minus (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
struct val *r;
|
||||
|
||||
if (!to_integer (a)) {
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
if (!to_integer (b)) {
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
return make_integer(0);
|
||||
} else {
|
||||
r = make_integer(0 - b->u.i);
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
return (r);
|
||||
}
|
||||
} else if (!to_integer(b)) {
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
free_value(b);
|
||||
return (a);
|
||||
}
|
||||
|
||||
r = make_integer (/*(quad_t)*/(a->u.i - b->u.i));
|
||||
if (chk_minus (a->u.i, b->u.i, r->u.i)) {
|
||||
ast_log(LOG_WARNING, "overflow\n");
|
||||
}
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
chk_times (a, b, r)
|
||||
quad_t a, b, r;
|
||||
{
|
||||
/* special case: first operand is 0, no overflow possible */
|
||||
if (a == 0)
|
||||
return 0;
|
||||
/* cerify that result of division matches second operand */
|
||||
if (r / a != b)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct val *
|
||||
op_times (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
struct val *r;
|
||||
|
||||
if (!to_integer (a) || !to_integer (b)) {
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
return(make_integer(0));
|
||||
}
|
||||
|
||||
r = make_integer (/*(quad_t)*/(a->u.i * b->u.i));
|
||||
if (chk_times (a->u.i, b->u.i, r->u.i)) {
|
||||
ast_log(LOG_WARNING, "overflow\n");
|
||||
}
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return (r);
|
||||
}
|
||||
|
||||
static int
|
||||
chk_div (a, b)
|
||||
quad_t a, b;
|
||||
{
|
||||
/* div by zero has been taken care of before */
|
||||
/* only QUAD_MIN / -1 causes overflow */
|
||||
if (a == QUAD_MIN && b == -1)
|
||||
return 1;
|
||||
/* everything else is OK */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct val *
|
||||
op_div (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
struct val *r;
|
||||
|
||||
if (!to_integer (a)) {
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
return make_integer(0);
|
||||
} else if (!to_integer (b)) {
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
return make_integer(INT_MAX);
|
||||
}
|
||||
|
||||
if (b->u.i == 0) {
|
||||
ast_log(LOG_WARNING, "division by zero\n");
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
return make_integer(INT_MAX);
|
||||
}
|
||||
|
||||
r = make_integer (/*(quad_t)*/(a->u.i / b->u.i));
|
||||
if (chk_div (a->u.i, b->u.i)) {
|
||||
ast_log(LOG_WARNING, "overflow\n");
|
||||
}
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct val *
|
||||
op_rem (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
struct val *r;
|
||||
|
||||
if (!to_integer (a) || !to_integer (b)) {
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
return make_integer(0);
|
||||
}
|
||||
|
||||
if (b->u.i == 0) {
|
||||
ast_log(LOG_WARNING, "div by zero\n");
|
||||
free_value(a);
|
||||
return (b);
|
||||
}
|
||||
|
||||
r = make_integer (/*(quad_t)*/(a->u.i % b->u.i));
|
||||
/* chk_rem necessary ??? */
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct val *
|
||||
op_colon (a, b)
|
||||
struct val *a, *b;
|
||||
{
|
||||
regex_t rp;
|
||||
regmatch_t rm[2];
|
||||
char errbuf[256];
|
||||
int eval;
|
||||
struct val *v;
|
||||
|
||||
/* coerce to both arguments to strings */
|
||||
to_string(a);
|
||||
to_string(b);
|
||||
|
||||
/* compile regular expression */
|
||||
if ((eval = regcomp (&rp, b->u.s, REG_EXTENDED)) != 0) {
|
||||
regerror (eval, &rp, errbuf, sizeof(errbuf));
|
||||
ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
return make_str("");
|
||||
}
|
||||
|
||||
/* compare string against pattern */
|
||||
/* remember that patterns are anchored to the beginning of the line */
|
||||
if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 && rm[0].rm_so == 0) {
|
||||
if (rm[1].rm_so >= 0) {
|
||||
*(a->u.s + rm[1].rm_eo) = '\0';
|
||||
v = make_str (a->u.s + rm[1].rm_so);
|
||||
|
||||
} else {
|
||||
v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
|
||||
}
|
||||
} else {
|
||||
if (rp.re_nsub == 0) {
|
||||
v = make_integer ((quad_t)0);
|
||||
} else {
|
||||
v = make_str ("");
|
||||
}
|
||||
}
|
||||
|
||||
/* free arguments and pattern buffer */
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
regfree (&rp);
|
||||
|
||||
return v;
|
||||
}
|
||||
32
astconf.h
Normal file
32
astconf.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* General Definitions for Asterisk top level program
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License
|
||||
*/
|
||||
|
||||
#ifndef _ASTCONF_H
|
||||
#define _ASTCONF_H
|
||||
|
||||
#define AST_CONFIG_MAX_PATH 255
|
||||
|
||||
extern char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH];
|
||||
extern char ast_config_AST_CONFIG_FILE[AST_CONFIG_MAX_PATH];
|
||||
extern char ast_config_AST_MODULE_DIR[AST_CONFIG_MAX_PATH];
|
||||
extern char ast_config_AST_SPOOL_DIR[AST_CONFIG_MAX_PATH];
|
||||
extern char ast_config_AST_VAR_DIR[AST_CONFIG_MAX_PATH];
|
||||
extern char ast_config_AST_LOG_DIR[AST_CONFIG_MAX_PATH];
|
||||
extern char ast_config_AST_AGI_DIR[AST_CONFIG_MAX_PATH];
|
||||
extern char ast_config_AST_DB[AST_CONFIG_MAX_PATH];
|
||||
extern char ast_config_AST_KEY_DIR[AST_CONFIG_MAX_PATH];
|
||||
extern char ast_config_AST_PID[AST_CONFIG_MAX_PATH];
|
||||
extern char ast_config_AST_SOCKET[AST_CONFIG_MAX_PATH];
|
||||
extern char ast_config_AST_RUN_DIR[AST_CONFIG_MAX_PATH];
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user