Compare commits

..

106 Commits

Author SHA1 Message Date
Kevin P. Fleming
30be887c79 remove extraneous svn:executable properties
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/0.1.12@7221 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2005-11-29 18:24:39 +00:00
Kevin P. Fleming
3dace6b301 automatic tag renames
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/0.1.12@7201 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2005-11-27 17:18:34 +00:00
Admin Commit
f6234c6912 This commit was manufactured by cvs2svn to create tag 'v0-1-12'.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/v0-1-12@477 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-30 17:04:04 +00:00
Mark Spencer
dcb600ff3b Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@476 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-30 17:04:04 +00:00
Mark Spencer
80555f6587 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@475 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-29 22:09:03 +00:00
Mark Spencer
bab0cfd263 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@474 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-29 21:46:57 +00:00
Mark Spencer
8c63834523 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@473 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-29 17:58:48 +00:00
Mark Spencer
13f34c3518 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@472 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-28 20:34:46 +00:00
Mark Spencer
3eb85f722f Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@471 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-28 18:46:01 +00:00
Mark Spencer
ee40af15ad Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@470 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-28 15:21:23 +00:00
Mark Spencer
ceab2dfcf9 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@469 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-28 15:15:11 +00:00
Mark Spencer
7336b021e8 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@468 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-28 02:08:32 +00:00
Mark Spencer
afd122b895 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@467 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-24 17:59:56 +00:00
Mark Spencer
747f8e9238 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@466 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-21 14:22:52 +00:00
Mark Spencer
123613853b Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@465 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-21 01:40:13 +00:00
Mark Spencer
9086941a86 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@464 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-20 16:46:34 +00:00
Mark Spencer
4a8dc28b52 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@463 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-19 22:46:52 +00:00
Mark Spencer
ed6b4c821e Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@462 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-19 02:35:40 +00:00
Mark Spencer
ede7bca2a7 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@461 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-16 16:06:38 +00:00
Mark Spencer
738689ea86 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@460 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-14 15:50:42 +00:00
Mark Spencer
faa9890ff2 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@459 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-14 15:35:24 +00:00
Mark Spencer
e055bb6e86 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@458 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-06 22:47:34 +00:00
Mark Spencer
b824677a2a Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@457 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-06-05 05:00:08 +00:00
Mark Spencer
11fefdc37c Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@456 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-31 16:25:56 +00:00
Mark Spencer
f18ffcb4b7 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@455 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-30 17:38:34 +00:00
Mark Spencer
919b935980 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@454 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-30 01:40:29 +00:00
Mark Spencer
5b44727583 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@453 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-30 01:34:15 +00:00
Mark Spencer
44ec0d02a2 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@452 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-27 23:15:47 +00:00
Mark Spencer
a734901dee Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@451 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-18 02:35:06 +00:00
Mark Spencer
c75c3e8bc2 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@450 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-17 14:33:10 +00:00
Mark Spencer
2a2f2c2c04 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@449 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-15 21:29:26 +00:00
Mark Spencer
b3abeb59d3 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@448 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-14 14:43:52 +00:00
Mark Spencer
75a75233da Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@447 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-14 03:17:45 +00:00
Mark Spencer
d5930d1fe8 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@446 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-13 22:29:39 +00:00
Mark Spencer
04cde57a77 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@445 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-12 15:08:37 +00:00
Mark Spencer
218fdfa3e5 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@444 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-12 11:48:14 +00:00
Mark Spencer
0f77c05d85 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@443 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-12 03:01:27 +00:00
Mark Spencer
ce47c7f2c7 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@442 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-11 23:51:59 +00:00
Mark Spencer
fc8c05165a Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@441 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-11 17:26:19 +00:00
Mark Spencer
62099ea6b9 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@440 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-10 14:41:21 +00:00
Mark Spencer
c918ef0f40 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@439 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-10 00:08:26 +00:00
Mark Spencer
b1f7ca718e Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@438 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-09 16:55:13 +00:00
Mark Spencer
c0a63a9c86 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@437 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-04 21:06:49 +00:00
Mark Spencer
61cf4e2668 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@436 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-05-03 04:02:31 +00:00
Mark Spencer
b78dc9e0f6 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@435 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-04-23 19:05:55 +00:00
Mark Spencer
afdafc85ce Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@434 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-04-22 15:14:18 +00:00
Mark Spencer
34c34980c6 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@433 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-04-19 21:17:35 +00:00
Mark Spencer
a4cb6c34d3 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@432 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-04-09 00:49:07 +00:00
Mark Spencer
7e81dc97e5 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@431 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-04-08 22:15:15 +00:00
Mark Spencer
7417052303 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@430 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-04-08 21:42:26 +00:00
Mark Spencer
7d19251487 Version 0.1.12 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@429 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-04-04 04:55:16 +00:00
Mark Spencer
f683340aa5 Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@427 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-03-15 14:58:01 +00:00
Mark Spencer
bc1141dfff Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@426 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-03-11 14:30:21 +00:00
Mark Spencer
f62f33ce93 Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@425 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-03-11 02:00:09 +00:00
Mark Spencer
4b75f411fc Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@424 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-03-10 20:26:16 +00:00
Mark Spencer
aec202cbdb Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-03-10 17:14:13 +00:00
Mark Spencer
edcd34976e Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@422 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-03-08 23:48:42 +00:00
Mark Spencer
3214cf6ba9 Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@421 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-03-07 16:49:49 +00:00
Mark Spencer
3f06397045 Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@420 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-03-06 23:49:00 +00:00
Mark Spencer
51a5499532 Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-03-05 23:57:31 +00:00
Mark Spencer
5f53621223 Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-03-05 15:59:01 +00:00
Mark Spencer
4a792f6c7c Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@417 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-03-01 16:54:59 +00:00
Mark Spencer
60811d944f Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@416 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-02-19 20:14:14 +00:00
Mark Spencer
493945c224 Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@415 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-02-19 16:56:30 +00:00
Mark Spencer
bc740c86fd Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@414 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-02-18 20:25:25 +00:00
Mark Spencer
21b5e17de5 Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@413 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-02-16 19:23:59 +00:00
Mark Spencer
6c1cfa8b83 Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@412 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-02-11 04:25:04 +00:00
Mark Spencer
3957344c83 Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@411 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-02-08 12:47:18 +00:00
Mark Spencer
2ac5d0b1aa Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@410 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-01-25 21:55:56 +00:00
Mark Spencer
42b068e43e Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@409 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-01-23 20:56:52 +00:00
Mark Spencer
239b43d953 Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@408 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-01-17 21:39:57 +00:00
Mark Spencer
31fcc5dbed Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@407 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-01-17 14:37:17 +00:00
Mark Spencer
c36135eebf Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@406 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-01-13 18:51:27 +00:00
Mark Spencer
0cbb5dd731 Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@405 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-01-13 15:11:01 +00:00
Mark Spencer
cf4fe25d62 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@403 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-01-10 12:14:50 +00:00
Mark Spencer
f3140658b4 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@402 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-01-07 22:34:22 +00:00
Mark Spencer
4494a6d2f4 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@401 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2002-01-07 02:01:04 +00:00
Mark Spencer
09634dde46 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@400 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-12-29 21:48:24 +00:00
Mark Spencer
31c31a718c Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@399 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-12-29 18:04:21 +00:00
Mark Spencer
f2784d97fd Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@398 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-12-27 11:07:33 +00:00
Mark Spencer
c27ef7f85c Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-12-25 23:27:38 +00:00
Mark Spencer
eb97d576eb Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@396 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-12-25 21:12:07 +00:00
Mark Spencer
54e1f06913 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@395 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-12-20 15:21:47 +00:00
Mark Spencer
0051d20a04 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@394 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-12-10 21:47:23 +00:00
Mark Spencer
473cbda85c Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@393 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-12-09 07:08:11 +00:00
Mark Spencer
a0e2c58919 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@392 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-12-09 00:41:43 +00:00
Mark Spencer
eac24165f7 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@391 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-12-08 16:51:03 +00:00
Mark Spencer
3a8facf06d Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@390 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-12-07 22:57:34 +00:00
Mark Spencer
42a1f82af3 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-11-24 15:15:01 +00:00
Mark Spencer
5da86a5290 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@388 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-11-10 20:31:39 +00:00
Mark Spencer
364f873573 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@387 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-11-10 18:09:19 +00:00
Mark Spencer
54df359acc Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@386 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-11-10 02:55:10 +00:00
Mark Spencer
1983a179c9 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@385 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-11-06 17:34:13 +00:00
Mark Spencer
aefb1f6b06 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@384 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-11-02 01:22:37 +00:00
Mark Spencer
277e550a07 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@383 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-11-01 20:00:54 +00:00
Mark Spencer
e2a5bf3445 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@382 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-11-01 14:03:04 +00:00
Mark Spencer
2ff8edf07b Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@381 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-10-31 17:05:44 +00:00
Mark Spencer
55b33a9ef9 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@380 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-10-31 15:28:08 +00:00
Mark Spencer
0327bf310f Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@379 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-10-30 14:44:25 +00:00
Mark Spencer
036770fe92 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@378 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-10-24 17:48:37 +00:00
Mark Spencer
0235e1fe05 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@377 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-10-24 17:10:36 +00:00
Mark Spencer
a07f2c930b Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@376 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-10-18 16:47:57 +00:00
Mark Spencer
39b383b353 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@375 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-10-18 15:38:46 +00:00
Mark Spencer
e13bb52a79 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@374 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-10-18 15:27:19 +00:00
Mark Spencer
12135c8167 Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@373 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-10-18 15:18:45 +00:00
Mark Spencer
dbd257811b Version 0.1.10 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@372 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2001-10-17 15:04:18 +00:00
205 changed files with 25527 additions and 3037 deletions

4
BUGS
View File

@@ -10,6 +10,10 @@
three way call up, the parties in the three way cannot hear one another
in the general case.
* No auto-reload in chan_zap yet
* Must be able to call park with flash-hook transfer
======================================================================
Short report on the voicemail system
======================================================================

53
CHANGES
View File

@@ -1,3 +1,56 @@
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

21
CREDITS
View File

@@ -1,17 +1,20 @@
=== 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)
=== DEVELOPMENT SUPPORT ===
I'd like to thank the following companies for helping fund development of
Asterisk:
* Celera Networks - US Digital
* Adtran, Inc.
Pilosoft, Inc. - for supporting ADSI development in Asterisk
GFS - for supporting ALSA development
Telesthetic - for supporting SIP development
=== HARDWARE DONORS ===
* Thanks to QuickNet Technologies for their donation of an Internet
PhoneJack and Linejack card to the project. (http://www.quicknet.net)
=== MISCELLANEOUS PATCHES ===
Oliver Daudey - ISDN4Linux fixes
=== OTHER SOURCE CODE IN ASTERISK ===

55
HARDWARE Normal file
View File

@@ -0,0 +1,55 @@
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
==========================
-- Linux Support Services, Inc. (Primary author of Asterisk)
http://www.linux-support.net, http://store.yahoo.com/asteriskpbx
* Wildcard X100P - Single FXO interface connects to Loopstart phone
line
* Wildcard T400P - Quad T1 interface connects to four T1/PRI
interfaces. Supports RBS and PRI voice and PPP, FR, and HDLC data.
* Wildcard E400P - Quad E1 interface connects to four E1/PRI (or PRA)
interfaces. Supports PRA/PRI, EuroISDN voice and PPP, FR, HDLC data.
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

View File

@@ -11,7 +11,6 @@
# the GNU General Public License
#
.EXPORT_ALL_VARIABLES:
INSTALL_PREFIX=
@@ -22,14 +21,20 @@ AGI_DIR=$(INSTALL_PREFIX)/var/lib/asterisk/agi-bin
# Pentium Pro Optimize
#PROC=i686
# Pentium Optimize
PROC=i586
#PROC=i586
#PROC=k6
#PROC=ppc
PROC=$(shell uname -m)
DEBUG=-g #-pg
INCLUDE=-Iinclude -I../include
#CFLAGS=-pipe -Wall -Wmissing-prototypes -Wmissing-declarations -O6 $(DEBUG) $(INCLUDE) -D_REENTRANT -Werror
CFLAGS=-pipe -Wall -Wmissing-prototypes -Wmissing-declarations -O6 $(DEBUG) $(INCLUDE) -D_REENTRANT
CFLAGS=-pipe -Wall -Wmissing-prototypes -Wmissing-declarations -O6 $(DEBUG) $(INCLUDE) -D_REENTRANT -D_GNU_SOURCE
#CFLAGS+=-Werror
CFLAGS+=$(shell if $(CC) -march=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=$(PROC)"; fi)
CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi)
ASTERISKVERSION=$(shell if [ -f .version ]; then cat .version; fi)
HTTPDIR=$(shell if [ -d /var/www ]; then echo "/var/www"; else echo "/home/httpd"; fi)
RPMVERSION=$(shell sed 's/[-\/:]/_/g' .version)
CFLAGS+=-DASTERISK_VERSION=\"$(ASTERISKVERSION)\"
# Optional debugging parameters
@@ -37,11 +42,12 @@ CFLAGS+= -DDO_CRASH -DDEBUG_THREADS
# Uncomment next one to enable ast_frame tracing (for debugging)
#CLFAGS+= -DTRACE_FRAMES
CFLAGS+=# -fomit-frame-pointer
SUBDIRS=channels pbx apps codecs formats agi
LIBS=-ldl -lpthread -lreadline -lncurses -lm
SUBDIRS=res channels pbx apps codecs formats agi cdr
LIBS=-ldl -lpthread -lreadline -lncurses -lm #-lnjamd
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 \
ulaw.o callerid.o fskmodem.o image.o app.o asterisk.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 asterisk.o
CC=gcc
INSTALL=install
@@ -59,10 +65,12 @@ all: asterisk subdirs
_version:
if [ -d CVS ] && ! [ -f .version ]; then echo "CVS-`date +"%D-%T"`" > .version; fi
.version: _version
build.h:
./make_build_h
asterisk: _version build.h $(OBJS)
asterisk: .version build.h $(OBJS)
gcc -o asterisk -rdynamic $(OBJS) $(LIBS)
subdirs:
@@ -78,9 +86,10 @@ datafiles: all
for x in sounds/digits/*; do \
install $$x $(INSTALL_PREFIX)/var/lib/asterisk/sounds/digits ; \
done
for x in sounds/vm-* sounds/transfer* sounds/pbx-* sounds/ss-* sounds/beep* sounds/dir-*; do \
for x in sounds/vm-* sounds/transfer* sounds/pbx-* sounds/ss-* sounds/beep* sounds/dir-* sounds/conf-*; do \
install $$x $(INSTALL_PREFIX)/var/lib/asterisk/sounds ; \
done
mkdir -p $(INSTALL_PREFIX)/var/lib/asterisk/mohmp3
mkdir -p $(INSTALL_PREFIX)/var/lib/asterisk/images
for x in images/*.jpg; do \
install $$x $(INSTALL_PREFIX)/var/lib/asterisk/images ; \
@@ -90,7 +99,10 @@ datafiles: all
install: all datafiles
mkdir -p $(MODULES_DIR)
mkdir -p $(INSTALL_PREFIX)/usr/sbin
mkdir -p $(INSTALL_PREFIX)/etc/asterisk
install -m 755 asterisk $(INSTALL_PREFIX)/usr/sbin/
install -m 755 astgenkey $(INSTALL_PREFIX)/usr/sbin/
install -m 755 safe_asterisk $(INSTALL_PREFIX)/usr/sbin/
for x in $(SUBDIRS); do $(MAKE) -C $$x install || exit 1 ; done
install -d $(INSTALL_PREFIX)/usr/include/asterisk
install include/asterisk/*.h $(INSTALL_PREFIX)/usr/include/asterisk
@@ -99,6 +111,9 @@ install: all datafiles
rm -f $(INSTALL_PREFIX)/usr/lib/asterisk/modules/chan_ixj.so
rm -f $(INSTALL_PREFIX)/usr/lib/asterisk/modules/chan_tor.so
mkdir -p $(INSTALL_PREFIX)/var/lib/asterisk/sounds
mkdir -p $(INSTALL_PREFIX)/var/log/asterisk/cdr-csv
mkdir -p $(INSTALL_PREFIX)/var/lib/asterisk/keys
install -m 644 keys/iaxtel.pub $(INSTALL_PREFIX)/var/lib/asterisk/keys
( cd $(INSTALL_PREFIX)/var/lib/asterisk/sounds ; ln -s ../../../spool/asterisk/vm . )
@echo " +---- Asterisk Installation Complete -------+"
@echo " + +"
@@ -121,7 +136,15 @@ install: all datafiles
@echo " + **Note** This requires that you have +"
@echo " + doxygen installed on your local system +"
@echo " +-------------------------------------------+"
samples: all datafiles
adsi: all
mkdir -p /etc/asterisk
for x in configs/*.adsi; do \
if ! [ -f $(INSTALL_PREFIX)/etc/asterisk/$$x ]; then \
install -m 644 $$x $(INSTALL_PREFIX)/etc/asterisk/`basename $$x` ; \
fi ; \
done
samples: all datafiles adsi
mkdir -p $(INSTALL_PREFIX)/etc/asterisk
for x in configs/*.sample; do \
if [ -f $(INSTALL_PREFIX)/etc/asterisk/`basename $$x .sample` ]; then \
@@ -132,6 +155,9 @@ samples: all datafiles
for x in sounds/demo-*; do \
install $$x $(INSTALL_PREFIX)/var/lib/asterisk/sounds; \
done
for x in sounds/*.mp3; do \
install $$x $(INSTALL_PREFIX)/var/lib/asterisk/mohmp3 ; \
done
mkdir -p $(INSTALL_PREFIX)/var/spool/asterisk/vm/1234/INBOX
:> $(INSTALL_PREFIX)/var/lib/asterisk/sounds/vm/1234/unavail.gsm
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isunavail; do \
@@ -142,6 +168,24 @@ samples: all datafiles
cat $(INSTALL_PREFIX)/var/lib/asterisk/sounds/$$x.gsm >> $(INSTALL_PREFIX)/var/lib/asterisk/sounds/vm/1234/busy.gsm ; \
done
webvmail:
@[ -d $(HTTPDIR) ] || ( echo "No HTTP directory" && exit 1 )
@[ -d $(HTTPDIR)/html ] || ( echo "No http directory" && exit 1 )
@[ -d $(HTTPDIR)/cgi-bin ] || ( echo "No cgi-bin directory" && exit 1 )
install -m 4755 -o root -g root vmail.cgi $(HTTPDIR)/cgi-bin/vmail.cgi
mkdir -p $(HTTPDIR)/html/_asterisk
for x in images/*.gif; do \
install -m 644 $$x $(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 " +-------------------------------------------+"
mailbox:
./addmailbox
@@ -164,3 +208,13 @@ __rpm: _version
progdocs:
doxygen asterisk-ng-doxygen
config:
if [ -d /etc/rc.d/init.d ]; then \
install -m 755 init.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

8
README
View File

@@ -32,6 +32,9 @@ 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 excemption 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.
@@ -48,9 +51,10 @@ as well.
First, be sure you've got supported hardware. To use Asterisk right now,
you will need one of the following:
* Adtran Atlas 800 Plus
* QuickNet Internet PhoneJack
* All Wildcard (tm) products from LSS (www.linux-support.net)
* 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)

14
README.cdr Normal file
View File

@@ -0,0 +1,14 @@
Asterisk now generates Call Detail Records. See include/asterisk/cdr.h for
all the fields which are recorded. By default, records in comma-separated
values will be created in /var/log/asterisk/cdr-csv. You can specify
account codes and AMA (Automated Machine Accounting) flags on a per-channel
(Zaptel et al) or per-user (IAX) basis to help with accounting. Look
at the top of cdr/cdr_csv.c to see the format for the records.
ONE IMPORTANT NOTE: If you are trying to collect records on IAX to IAX calls
you need to be aware that by default, IAX will attempt to transfer calls
in this situation (if DTMF is not required). When the transfer is completed
the call is dumped from the middle machine and thus the call detail records
will report a short call time. If you want detailed records you must
turn off IAX transfer, but unless your servers are very close together, you
will definitely get a latency hit from doing so.

326
README.iax Normal file
View File

@@ -0,0 +1,326 @@
Inter-Asterisk eXchange Protocol
================================
INTRODUCTION
------------
This document is intended as an introduction to the Inter-Asterisk
eXchange (or simply IAX) protocol. It provides both a theoretical
background and practical information on its use.
WHY IAX
-------
The first question most people are thinking at this point is "Why do you
need another VoIP protocol? Why didn't you just use SIP or H.323?"
Well, the answer is a fairly complicated one, but in a nutshell it's like
this... Asterisk is intended as a very flexible and powerful
communications tool. As such, the primary feature we need from a VoIP
protocol is the ability to meet our own goals with Asterisk, and one with
enough flexibility that we could use it as a kind of laboratory for
inventing and implementing new concepts in the field. Neither H.323 or
SIP fit the roles we needed, so we developed our own protocol, which,
while not standards based, provides a number of advantages over both SIP
and H.323, some of which are:
* Interoperability with NAT/PAT/Masquerade firewalls
IAX seamlessly interoperates through all sorts of NAT and PAT
and other firewalls, including the ability to place and
receive calls, and transfer calls to other stations.
* High performance, low overhead protocol
When running on low-bandwidth connections, or when running
large numbers of calls, optimized bandwidth utilization is
imperitive. IAX uses only 4 bytes of overhead
* Internationalization support
IAX transmits language information, so that remote PBX
content can be delivered in the native language of the
calling party.
* Remote dialplan polling
IAX allows a PBX or IP phone to poll the availability of a
number from a remote server. This allows PBX dialplans to
be centralized.
* Flexible authentication
IAX supports cleartext, md5, and RSA authentication,
providing flexible security models for outgoing calls and
registration services.
* Multimedia protocol
IAX supports the transmission of voice, video, images, text,
HTML, DTMF, and URL's. Voice menus can be presented in both
audibly and visually.
* Call statistic gathering
IAX gathers statistics about network performance (including
latency and jitter, as well as providing end-to-end latency
measurement.
* Call parameter communication
Caller*ID, requested extension, requested context, etc are
all communicated through the call.
* Single socket design
IAX's single socket design allows up to 32768 calls to be
multiplexed.
While we value the importance of standards based (i.e. SIP) call handling,
hopefully this will provide a reasonable explanation of why we developed
IAX rather than starting with SIP.
CONFIG FILE CONVENTIONS
-----------------------
Lines beginning with '>' represent lines which might appear in an actual
configuration file. The '>' is used to help separate them from the
descriptive text and should not actually be included in the file itself.
Lines within []'s by themselves represent section labels within the
configuration file. like this:
> [mysection]
Options are set using the "=" sign, for example
> myoption = value
Sometimes an option will have a number of discrete values which it can
take. In that case, in the documentation, the options will be listed
within square brackets (the "[" and "]" ones) separated by the pipe symbol
("|"). For example:
> myoption = [value1|value2|value3]
means the option "myoption" can be assigned a value of "value1", "value2",
or "value3".
Objects, or pseudo-objects are instantiated using the "=>" construct. For
example:
> myobject => parameter
creates an object called "myobject" with some parameter whose definition
would be specific to that object. Note that the config file parser
considers "=>" and "=" to be equivalent and their use is purely to make
configuration files more readable and easier to "humanly parse".
The comment character in Asterisk configuration files is the semicolon
";". The reason it is not "#" is because the "#" symbol can be used as
parts of extensions and it didn't seem like a good idea to have to escape
it.
IAX CONFIGURATION IN ASTERISK
-----------------------------
Like everything else in Asterisk, IAX's configuration lies in
/etc/asterisk -- specifically /etc/asterisk/iax.conf
The IAX configuration file is a collection of sections, each of which
(with the exception of the "general" section) represents an entity within
the IAX scope.
------------
The first section is typically the "general" section. In this area,
a number of parameters which affect the entire system are configured.
Specifically, the default codecs, port and address, jitter behavior, TOS
bits, and registrations.
The first line of the "general" section is always:
> [general]
Following the first line are a number of other possibilities:
> port = <portnum>
This sets the port that IAX will bind to. The default IAX port number is
5036. It is recommended that this value not be altered in general.
> bindaddr = <ipaddr>
This allows you to bind IAX to a specific local IP address instead of
binding to all addresses. This could be used to enhance security if, for
example, you only wanted IAX to be available to users on your LAN.
> bandwidth = [low|medium|high]
The bandwidth selection initializes the codec selection to appropriate
values for given bandwidths. The "high" selection enables all codecs and
is recommended only for 10Mbps or higher connections. The "medium"
bandwidth eliminates signed linear, Mu-law and A-law codecs, leaving only
the codecs which are 32kbps and smaller (with MP3 as a special case). It
can be used with broadband connections if desired. "low" eliminates ADPCM
and MP3 formats, leaving only the G.723.1, GSM, and LPC10.
> allow = [gsm|lpc10|g723.1|adpcm|ulaw|alaw|mp3|slinear|all]
> disallow = [gsm|lpc10|g723.1|adpcm|ulaw|alaw|mp3|slinear|all]
The "allow" and "disallow" allow you to fine tune the codec selection
beyond the initial bandwidth selection on a codec-by-codec basis.
The recommended configuration is to select "low" bandwidth and then
disallow the LPC10 codec just because it doesn't sound very good.
> jitterbuffer = [yes|no]
> dropcount = <dropamount>
> maxjitterbuffer = <max>
> maxexcessbuffer = <max>
These parameters control the operation of the jitter buffer. The
jitterbuffer should always be enabled unless you expect all your
connections to be over a LAN. The drop count is the maximum number of
voice packets to allow to drop (out of 100). Useful values are 3-10. The
maxjitterbuffer is the maximum amount of jitter buffer to permit to be
used. The "maxexcessbuffer" is the maximum amount of excess jitter buffer
that is permitted before the jitter buffer is slowly shrunk to eliminate
latency.
> accountcode = <code>
> amaflags = [default|omit|billing|documentation]
These parameters affect call detail record generation. The first sets the
account code for records received with IAX. The account code can be
overridden on a per-user basis for incoming calls (see below). The
amaflags controls how the record is labeled ("omit" causes no record to be
written. "billing" and "documentation" label the records as billing or
documentation records respectively, and "default" selects the system
default.
> tos = [lowdelay|throughput|reliability|mincost|none]
IAX can optionally set the TOS (Type of Service) bits to specified values
to help improve performance in routing. The recommended value is
"lowdelay", which many routers (including any Linux routers with 2.4
kernels that have not been altered with ip tables) will give priority to
these packets, improving voice quality.
> register => <name>[:<secret>]@<host>[:port]
Any number of registery entries may be instantiated in the general
section. Registration allows Asterisk to notify a remote Asterisk server
(with a fixed address) what our current address is. In order for
registration to work, the remote Asterisk server will need to have a
dynamic peer entry with the same name (and secret if provided).
The name is a required field, and is the remote peer name that we wish to
identify ourselves as. A secret may be provided as well. The secret is
generally a shared password between the local server and the remote
server. However, if the secret is in square brackets ([]'s) then it is
interpreted as the name of a key to use. In that case, the local Asterisk
server must have the *private* key (/var/lib/asterisk/keys/<name>.key) and
the remote server will have to have the corresponding public key.
The "host" is a required field and is the hostname or IP address of the
remote Asterisk server. The port specification is optional and is by
default 5036 if not specified.
-------------
The following sections, after "general" define either users, peers or
friends. A "user" is someone who connects to us. A "peer" is someone
that we connect to. A "friend" is simply shorthand for creating a "user"
and "peer" with identical parameters (i.e. someone who can contact us and
who we contact).
> [identifier]
The section begins with the identifier in square brackets. The identifier
should be an alphanumeric string.
> type = [user|peer|friend]
This line tells Asterisk how to interpret this entity. Users are things
that connect to us, while peers are people we connect to, and a friend is
shorthand for creating a user and a peer with identical information
----------------
User fields:
> context = <context>
One or more context lines may be specified in a user, thus giving the user
access to place calls in the given contexts. Contexts are used by
Asterisk to divide dialing plans into logical units each with the ability
to have numbers interpreted differently, have their own security model,
auxilliary switch handling, and include other contexts. Most users are
given access to the default context. Trusted users could be given access
to the local context for example.
> permit = <ipaddr>/<netmask>
> deny = <ipaddr>/<netmask>
Permit and deny rules may be applied to users, allowing them to connect
from certain IP addresses and not others. The permit and deny rules are
interpreted in sequence and all are evaluated on a given IP address, with
the final result being the decision. For example:
> permit = 0.0.0.0/0.0.0.0
> deny = 192.168.0.0/255.255.255.0
would deny anyone in 192.168.0.0 with a netmask of 24 bits (class C),
whereas:
> deny = 192.168.0.0/255.255.255.0
> permit = 0.0.0.0/0.0.0.0
would not deny anyone since the final rule would permit anyone, thsu
overriding the denial.
If no permit/deny rules are listed, it is assumed that someone may connect
from anywhere.
> callerid = <callerid>
You may override the Caller*ID information passed by a user to you (if
they choose to send it) in order that it always be accurate from the
perspective of your server.
> auth = [md5|plaintext|rsa]
You may select which authentication methods are permitted to be used by
the user to authenticate to us. Multiple methods may be specified,
separated by commas. If md5 or plaintext authentication is selected, a
secret must be provided. If RSA authentication is specified, then one or
more key names must be specifed with "inkeys"
If no secret is specified and no authentication method is specified, then
no authentication will be required.
> secret = <secret>
The "secret" line specifies the shared secret for md5 and plaintext
authentication methods. It is never suggested to use plaintext except in
some cases for debugging.
> inkeys = key1[:key2...]
The "inkeys" line specifies which keys we can use to authenticate the
remote peer. If the peer's challenge passes with any of the given keys,
then we accept its authentication. The key files live in
/var/lib/asterisk/keys/<name>.pub and are *public keys*. Public keys are
not typically DES3 encrypted and thus do not usually need initialization.
---------------
Peer configuration
> allow = [gsm|lpc10|g723.1|adpcm|ulaw|alaw|mp3|slinear|all]
> disallow = [gsm|lpc10|g723.1|adpcm|ulaw|alaw|mp3|slinear|all]
The "allow" and "disallow" may be used to enable or disable specific codec
support on a per-peer basis.
> host = [<ipaddr>|dynamic]
The host line specifies the hostname or IP address of the remote host, or
may be the word "dynamic" signifying that the host will register with us
(see register => in the general section above).
> defaultip = <ipaddr>
If the host uses dynamic registration, Asterisk may still be given a
default IP address to use when dynamic registration has not been performed
or has timed out.

View File

@@ -36,3 +36,6 @@ include => default
exten => 6123,Dial,Tor/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.

116
acl.c Normal file
View File

@@ -0,0 +1,116 @@
/*
* 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 <pthread.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 <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#define AST_SENSE_DENY 0
#define AST_SENSE_ALLOW 1
struct ast_ha {
/* Host access rule */
struct in_addr netaddr;
struct in_addr netmask;
int sense;
struct ast_ha *next;
};
void ast_free_ha(struct ast_ha *ha)
{
struct ast_ha *hal;
while(ha) {
hal = ha;
ha = ha->next;
free(hal);
}
}
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;
struct ast_ha *prev = NULL;
struct ast_ha *ret;
ret = path;
while(path) {
prev = path;
path = path->next;
}
if (ha) {
strtok(stuff, "/");
nm = strtok(NULL, "/");
if (!nm)
nm = "255.255.255.255";
if (!inet_aton(stuff, &ha->netaddr)) {
ast_log(LOG_WARNING, "%s not a valid IP\n", stuff);
free(ha);
return NULL;
}
if (!inet_aton(nm, &ha->netmask)) {
ast_log(LOG_WARNING, "%s not a valid netmask\n", nm);
free(ha);
return NULL;
}
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;
}
return NULL;
}
int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin)
{
/* Start optimistic */
int res = AST_SENSE_ALLOW;
while(ha) {
/* 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;
hp = gethostbyname(value);
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;
}

85
alaw.c Normal file
View 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);
}
}

View File

@@ -11,9 +11,13 @@
# the GNU General Public License
#
#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_intercom.so app_mp3.so \
app_system.so app_echo.so app_record.so app_image.so app_url.so app_disa.so \
app_agi.so
app_agi.so app_qcall.so app_adsiprog.so app_getcpeid.so app_milliwatt.so \
app_zapateller.so
APPS+=$(shell if [ -f /usr/include/zap.h ]; then echo "app_zapras.so app_meetme.so" ; fi)
CFLAGS+=

1567
apps/app_adsiprog.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -161,6 +161,21 @@ static void setup_env(struct ast_channel *chan, char *request, int fd)
fdprintf(fd, "\n");
}
static int handle_answer(struct ast_channel *chan, int fd, int argc, char *argv[])
{
int res;
res = 0;
if (chan->state != AST_STATE_UP) {
/* Answer the chan */
res = ast_answer(chan);
}
fdprintf(fd, "200 result=%d\n", res);
if (res >= 0)
return RESULT_SUCCESS;
else
return RESULT_FAILURE;
}
static int handle_waitfordigit(struct ast_channel *chan, int fd, int argc, char *argv[])
{
int res;
@@ -182,6 +197,13 @@ static int handle_sendtext(struct ast_channel *chan, int fd, int argc, char *arg
int res;
if (argc != 3)
return RESULT_SHOWUSAGE;
/* At the moment, the parser (perhaps broken) returns with
the last argument PLUS the newline at the end of the input
buffer. This probably needs to be fixed, but I wont do that
because other stuff may break as a result. The right way
would probably be to strip off the trailing newline before
parsing, then here, add a newline at the end of the string
before sending it to ast_sendtext --DUDE */
res = ast_sendtext(chan, argv[2]);
fdprintf(fd, "200 result=%d\n", res);
if (res >= 0)
@@ -190,13 +212,49 @@ static int handle_sendtext(struct ast_channel *chan, int fd, int argc, char *arg
return RESULT_FAILURE;
}
static int handle_recvchar(struct ast_channel *chan, int fd, int argc, char *argv[])
{
int res;
if (argc != 3)
return RESULT_SHOWUSAGE;
res = ast_recvchar(chan,atoi(argv[2]));
if (res == 0) {
fdprintf(fd, "200 result=%d (timeout)\n", res);
return RESULT_SUCCESS;
}
if (res > 0) {
fdprintf(fd, "200 result=%d\n", res);
return RESULT_SUCCESS;
}
else {
fdprintf(fd, "200 result=%d (hangup)\n", res);
return RESULT_FAILURE;
}
}
static int handle_tddmode(struct ast_channel *chan, int fd, int argc, char *argv[])
{
int res,x;
if (argc != 3)
return RESULT_SHOWUSAGE;
if (!strncasecmp(argv[2],"on",2)) x = 1; else x = 0;
if (!strncasecmp(argv[2],"mate",4)) x = 2;
if (!strncasecmp(argv[2],"tdd",3)) x = 1;
res = ast_channel_setoption(chan,AST_OPTION_TDD,&x,sizeof(char),0);
fdprintf(fd, "200 result=%d\n", res);
if (res >= 0)
return RESULT_SUCCESS;
else
return RESULT_FAILURE;
}
static int handle_sendimage(struct ast_channel *chan, int fd, int argc, char *argv[])
{
int res;
if (argc != 3)
return RESULT_SHOWUSAGE;
res = ast_send_image(chan, argv[2]);
if (!chan->softhangup)
if (!ast_check_hangup(chan))
res = 0;
fdprintf(fd, "200 result=%d\n", res);
if (res >= 0)
@@ -219,7 +277,7 @@ static int handle_streamfile(struct ast_channel *chan, int fd, int argc, char *a
return RESULT_FAILURE;
}
res = ast_waitstream(chan, argv[3]);
ast_stopstream(chan);
fdprintf(fd, "200 result=%d\n", res);
if (res >= 0)
return RESULT_SUCCESS;
@@ -235,7 +293,23 @@ static int handle_saynumber(struct ast_channel *chan, int fd, int argc, char *ar
return RESULT_SHOWUSAGE;
if (sscanf(argv[2], "%i", &num) != 1)
return RESULT_SHOWUSAGE;
res = ast_say_number(chan, num, chan->language);
res = ast_say_number(chan, num, AST_DIGIT_ANY, chan->language);
fdprintf(fd, "200 result=%d\n", res);
if (res >= 0)
return RESULT_SUCCESS;
else
return RESULT_FAILURE;
}
static int handle_saydigits(struct ast_channel *chan, int fd, int argc, char *argv[])
{
int res;
int num;
if (argc != 4)
return RESULT_SHOWUSAGE;
if (sscanf(argv[2], "%i", &num) != 1)
return RESULT_SHOWUSAGE;
res = ast_say_digit_str(chan, argv[2], AST_DIGIT_ANY, chan->language);
fdprintf(fd, "200 result=%d\n", res);
if (res >= 0)
return RESULT_SUCCESS;
@@ -272,7 +346,7 @@ static int handle_setcontext(struct ast_channel *chan, int fd, int argc, char *a
if (argc != 3)
return RESULT_SHOWUSAGE;
strncpy(chan->context, argv[2], sizeof(chan->context));
strncpy(chan->context, argv[2], sizeof(chan->context)-1);
fdprintf(fd, "200 result=0\n");
return RESULT_SUCCESS;
}
@@ -281,7 +355,7 @@ static int handle_setextension(struct ast_channel *chan, int fd, int argc, char
{
if (argc != 3)
return RESULT_SHOWUSAGE;
strncpy(chan->exten, argv[2], sizeof(chan->exten));
strncpy(chan->exten, argv[2], sizeof(chan->exten)-1);
fdprintf(fd, "200 result=0\n");
return RESULT_SUCCESS;
}
@@ -435,6 +509,11 @@ static int handle_recordfile(struct ast_channel *chan, int fd, int argc, char *a
return RESULT_SUCCESS;
}
static char usage_answer[] =
" Usage: ANSWER\n"
" Answers channel if not already in answer state. Returns -1 on\n"
" channel failure, or 0 if successful.\n";
static char usage_waitfordigit[] =
" Usage: WAIT FOR DIGIT <timeout>\n"
" Waits up to 'timeout' seconds for channel to receive a DTMF digit.\n"
@@ -450,6 +529,19 @@ static char usage_sendtext[] =
" consisting of greater than one word should be placed in quotes since the\n"
" command only accepts a single argument.\n";
static char usage_recvchar[] =
" Usage: RECEIVE CHAR <timeout>\n"
" Receives a character of text on a channel. Specify timeout to be the\n"
" maximum time to wait for input in milliseconds, or 0 for infinite. Most channels\n"
" do not support the reception of text. Returns the decimal value of the character\n"
" if one is received, or 0 if the channel does not support text reception. Returns\n"
" -1 only on error/hangup.\n";
static char usage_tddmode[] =
" Usage: TDD MODE <on|off>\n"
" Enable/Disable TDD transmission/reception on a channel. Returns 1 if\n"
" successful, or 0 if channel is not TDD-capable.\n";
static char usage_sendimage[] =
" Usage: SEND IMAGE <image>\n"
" Sends the given image on a channel. Most channels do not support the\n"
@@ -473,6 +565,13 @@ static char usage_saynumber[] =
" being pressed, or the ASCII numerical value of the digit if one was pressed or\n"
" -1 on error/hangup.\n";
static char usage_saydigits[] =
" Usage: SAY DIGITS <number> <escape digits>\n"
" Say a given digit string, returning early if any of the given DTMF digits\n"
" are received on the channel. Returns 0 if playback completes without a digit\n"
" being pressed, or the ASCII numerical value of the digit if one was pressed or\n"
" -1 on error/hangup.\n";
static char usage_getdata[] =
" Usage: GET DATA <file to be streamed> [timeout] [max digits]\n"
" Stream the given file, and recieve DTMF data. Returns the digits recieved\n"
@@ -498,10 +597,15 @@ static char usage_recordfile[] =
" -1 for no timeout\n";
agi_command commands[] = {
{ { "answer", NULL }, handle_answer, "Asserts answer", usage_answer },
{ { "answer\n", NULL }, handle_answer, "Asserts answer", usage_answer },
{ { "wait", "for", "digit", NULL }, handle_waitfordigit, "Waits for a digit to be pressed", usage_waitfordigit },
{ { "send", "text", NULL }, handle_sendtext, "Sends text to channels supporting it", usage_sendtext },
{ { "receive", "char", NULL }, handle_recvchar, "Receives text from channels supporting it", usage_recvchar },
{ { "tdd", "mode", NULL }, handle_tddmode, "Sends text to channels supporting it", usage_tddmode },
{ { "stream", "file", NULL }, handle_streamfile, "Sends audio file on channel", usage_streamfile },
{ { "send", "image", NULL }, handle_sendimage, "Sends images to channels supporting it", usage_sendimage },
{ { "say", "digits", NULL }, handle_saydigits, "Says a given digit string", usage_saydigits },
{ { "say", "number", NULL }, handle_saynumber, "Says a given number", usage_saynumber },
{ { "get", "data", NULL }, handle_getdata, "Gets data on a channel", usage_getdata },
{ { "set", "context", NULL }, handle_setcontext, "Sets channel context", usage_setcontext },
@@ -677,6 +781,10 @@ static int run_agi(struct ast_channel *chan, char *request, int *fds, int pid)
pid = -1;
break;
}
/* get rid of trailing newline, if any */
if (*buf && buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0;
returnstatus |= agi_handle_command(chan, fds[1], buf);
/* If the handle_command returns -1, we need to stop */
if (returnstatus < 0) {
@@ -709,13 +817,14 @@ static int agi_exec(struct ast_channel *chan, void *data)
}
strncpy(tmp, data, sizeof(tmp));
strncpy(tmp, data, sizeof(tmp)-1);
strtok(tmp, "|");
args = strtok(NULL, "|");
ringy = strtok(NULL,"|");
if (!args)
args = "";
LOCAL_USER_ADD(u);
#if 0
/* Answer if need be */
if (chan->state != AST_STATE_UP) {
if (ringy) { /* if for ringing first */
@@ -728,6 +837,7 @@ static int agi_exec(struct ast_channel *chan, void *data)
return -1;
}
}
#endif
res = launch_script(tmp, args, fds, &pid);
if (!res) {
res = run_agi(chan, tmp, fds, pid);

View 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>
@@ -19,6 +20,8 @@
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/say.h>
#include <asterisk/parking.h>
#include <asterisk/musiconhold.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
@@ -31,18 +34,14 @@
#include <pthread.h>
static char *tdesc = "Dialing/Parking Application";
static char *tdesc = "Dialing Application";
static char *app = "Dial";
static char *parkedcall = "ParkedCall";
static char *synopsis = "Place an call and connect to the current channel";
static char *registrar = "app_dial";
static char *descrip =
" Dial(Technology/resource[&Technology2/resource2...][|timeout][|transfer]):\n"
" Dial(Technology/resource[&Technology2/resource2...][|timeout][|options]):\n"
"Requests one or more channels and places specified outgoing calls on them.\n"
"As soon as a channel answers, the Dial app will answer the originating\n"
"channel (if it needs to be answered) and will bridge a call with the channel\n"
@@ -57,26 +56,14 @@ static char *descrip =
"no-answer).\n"
" This application returns -1 if the originating channel hangs up, or if the\n"
"call is bridged and either of the parties in the bridge terminate the call.\n"
"The transfer string may contain a 't' to allow the called user transfer a\n"
"call or 'T' to allow the calling user to transfer the call.\n"
"The option string may contain zero or more of the following characters:\n"
" 't' -- allow the called user transfer the calling user\n"
" 'T' -- to allow the calling user to transfer the call.\n"
" 'r' -- indicate ringing to the calling party, pass no audio until answered.\n"
" 'm' -- provide hold music to the calling party until answered.\n"
" In addition to transferring the call, a call may be parked and then picked\n"
"up by another user.\n";
/* No more than 45 seconds parked before you do something with them */
static int parkingtime = 45000;
/* Context for which parking is made accessible */
static char parking_con[AST_MAX_EXTENSION] = "parkedcalls";
/* Extension you type to park the call */
static char parking_ext[AST_MAX_EXTENSION] = "700";
/* First available extension for parking */
static int parking_start = 701;
/* Last available extension for parking */
static int parking_stop = 750;
/* We define a customer "local user" structure because we
use it not only for keeping track of what is in use but
also for keeping track of who we're dialing. */
@@ -85,177 +72,13 @@ struct localuser {
struct ast_channel *chan;
int stillgoing;
int allowredirect;
int ringbackonly;
int musiconhold;
struct localuser *next;
};
struct parkeduser {
struct ast_channel *chan;
struct timeval start;
int parkingnum;
/* Where to go if our parking time expires */
char context[AST_MAX_EXTENSION];
char exten[AST_MAX_EXTENSION];
int priority;
struct parkeduser *next;
};
static struct parkeduser *parkinglot;
static pthread_mutex_t parking_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_t parking_thread;
LOCAL_USER_DECL;
static int bridge_call(struct ast_channel *chan, struct ast_channel *peer, int allowredirect);
static int park_call(struct ast_channel *chan, struct ast_channel *peer)
{
/* We put the user in the parking list, then wake up the parking thread to be sure it looks
after these channels too */
struct parkeduser *pu, *cur;
int x;
pu = malloc(sizeof(struct parkeduser));
if (pu) {
ast_pthread_mutex_lock(&parking_lock);
for (x=parking_start;x<=parking_stop;x++) {
cur = parkinglot;
while(cur) {
if (cur->parkingnum == x)
break;
cur = cur->next;
}
if (!cur)
break;
}
if (x <= parking_stop) {
pu->chan = chan;
gettimeofday(&pu->start, NULL);
pu->parkingnum = x;
/* Remember what had been dialed, so that if the parking
expires, we try to come back to the same place */
strncpy(pu->context, chan->context, sizeof(pu->context));
strncpy(pu->exten, chan->exten, sizeof(pu->exten));
pu->priority = chan->priority;
pu->next = parkinglot;
parkinglot = pu;
ast_pthread_mutex_unlock(&parking_lock);
/* Wake up the (presumably select()ing) thread */
pthread_kill(parking_thread, SIGURG);
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "Parked %s on %d\n", pu->chan->name, pu->parkingnum);
ast_say_digits(peer, pu->parkingnum, peer->language);
return 0;
} else {
ast_log(LOG_WARNING, "No more parking spaces\n");
free(pu);
ast_pthread_mutex_unlock(&parking_lock);
return -1;
}
} else {
ast_log(LOG_WARNING, "Out of memory\n");
return -1;
}
return 0;
}
static void *do_parking_thread(void *ignore)
{
int ms, tms, max;
struct parkeduser *pu, *pl, *pt = NULL;
struct timeval tv;
struct ast_frame *f;
int x;
fd_set rfds, efds;
fd_set nrfds, nefds;
FD_ZERO(&rfds);
FD_ZERO(&efds);
for (;;) {
ms = -1;
max = -1;
ast_pthread_mutex_lock(&parking_lock);
pl = NULL;
pu = parkinglot;
gettimeofday(&tv, NULL);
FD_ZERO(&nrfds);
FD_ZERO(&nefds);
while(pu) {
tms = (tv.tv_sec - pu->start.tv_sec) * 1000 + (tv.tv_usec - pu->start.tv_usec) / 1000;
if (tms > parkingtime) {
/* They've been waiting too long, send them back to where they came. Theoretically they
should have their original extensions and such, but we copy to be on the safe side */
strncpy(pu->chan->exten, pu->exten, sizeof(pu->chan->exten));
strncpy(pu->chan->context, pu->context, sizeof(pu->chan->context));
pu->chan->priority = pu->priority;
/* Start up the PBX, or hang them up */
if (ast_pbx_start(pu->chan)) {
ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", pu->chan->name);
ast_hangup(pu->chan);
}
/* And take them out of the parking lot */
if (pl)
pl->next = pu->next;
else
parkinglot = pu->next;
pt = pu;
pu = pu->next;
free(pt);
} else {
for (x=0;x<AST_MAX_FDS;x++) {
if ((pu->chan->fds[x] > -1) && (FD_ISSET(pu->chan->fds[x], &rfds) || FD_ISSET(pu->chan->fds[x], &efds))) {
if (FD_ISSET(pu->chan->fds[x], &efds))
pu->chan->exception = 1;
pu->chan->fdno = x;
/* See if they need servicing */
f = ast_read(pu->chan);
if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
/* There's a problem, hang them up*/
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "%s got tired of being parked\n", pu->chan->name);
ast_hangup(pu->chan);
/* And take them out of the parking lot */
if (pl)
pl->next = pu->next;
else
parkinglot = pu->next;
pt = pu;
pu = pu->next;
free(pt);
break;
} else {
/* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
ast_frfree(f);
goto std; /* XXX Ick: jumping into an else statement??? XXX */
}
}
}
if (x >= AST_MAX_FDS) {
/* Keep this one for next one */
std: FD_SET(pu->chan->fds[x], &nrfds);
FD_SET(pu->chan->fds[x], &nefds);
/* Keep track of our longest wait */
if ((tms < ms) || (ms < 0))
ms = tms;
if (pu->chan->fds[x] > max)
max = pu->chan->fds[x];
pl = pu;
pu = pu->next;
}
}
}
ast_pthread_mutex_unlock(&parking_lock);
rfds = nrfds;
efds = nefds;
tv.tv_sec = ms / 1000;
tv.tv_usec = (ms % 1000) * 1000;
/* Wait for something to happen */
select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL);
pthread_testcancel();
}
return NULL; /* Never reached */
}
static void hanguptree(struct localuser *outgoing, struct ast_channel *exception)
{
/* Hang up a tree of stuff */
@@ -285,6 +108,8 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
struct ast_channel *watchers[MAX];
int pos;
int single;
int moh=0;
int ringind=0;
struct ast_channel *winner;
single = (outgoing && !outgoing->next);
@@ -294,6 +119,16 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
ast_channel_make_compatible(outgoing->chan, in);
}
if (outgoing) {
moh = outgoing->musiconhold;
ringind = outgoing->ringbackonly;
if (outgoing->musiconhold) {
ast_moh_start(in, NULL);
} else if (outgoing->ringbackonly) {
ast_indicate(in, AST_CONTROL_RINGING);
}
}
while(*to && !peer) {
o = outgoing;
found = -1;
@@ -344,12 +179,16 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name);
o->stillgoing = 0;
if (in->cdr)
ast_cdr_busy(in->cdr);
numbusies++;
break;
case AST_CONTROL_CONGESTION:
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "%s is circuit-busy\n", o->chan->name);
o->stillgoing = 0;
if (in->cdr)
ast_cdr_busy(in->cdr);
numbusies++;
break;
case AST_CONTROL_RINGING:
@@ -366,10 +205,12 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
default:
ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
}
} else if (single && (f->frametype == AST_FRAME_VOICE)) {
} else if (single && (f->frametype == AST_FRAME_VOICE) &&
!(outgoing->ringbackonly || outgoing->musiconhold)) {
if (ast_write(in, f))
ast_log(LOG_WARNING, "Unable to forward frame\n");
} else if (single && (f->frametype == AST_FRAME_IMAGE)) {
} else if (single && (f->frametype == AST_FRAME_IMAGE) &&
!(outgoing->ringbackonly || outgoing->musiconhold)) {
if (ast_write(in, f))
ast_log(LOG_WARNING, "Unable to forward image\n");
}
@@ -397,181 +238,16 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
if (!*to && (option_verbose > 2))
ast_verbose( VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
}
if (moh) {
ast_moh_stop(in);
} else if (ringind) {
ast_indicate(in, -1);
}
return peer;
}
static int bridge_call(struct ast_channel *chan, struct ast_channel *peer, int allowredirect)
{
/* Copy voice back and forth between the two channels. Give the peer
the ability to transfer calls with '#<extension' syntax. */
int len;
struct ast_frame *f;
struct ast_channel *who;
char newext[256], *ptr;
int res;
struct ast_option_header *aoh;
/* Answer if need be */
if (chan->state != AST_STATE_UP) {
if (ast_answer(chan))
return -1;
}
peer->appl = "Bridged Call";
peer->data = chan->name;
for (;;) {
res = ast_channel_bridge(chan, peer, allowredirect ? AST_BRIDGE_DTMF_CHANNEL_1 : 0, &f, &who);
if (res < 0) {
ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
return -1;
}
if (!f || ((f->frametype == AST_FRAME_CONTROL) && ((f->subclass == AST_CONTROL_HANGUP) || (f->subclass == AST_CONTROL_BUSY) ||
(f->subclass == AST_CONTROL_CONGESTION)))) {
res = -1;
break;
}
if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RINGING)) {
if (who == chan)
ast_indicate(peer, AST_CONTROL_RINGING);
else
ast_indicate(chan, AST_CONTROL_RINGING);
}
if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_OPTION)) {
aoh = f->data;
/* Forward option Requests */
if (aoh && (aoh->flag == AST_OPTION_FLAG_REQUEST)) {
if (who == chan)
ast_channel_setoption(peer, ntohs(aoh->option), aoh->data, f->datalen - sizeof(struct ast_option_header), 0);
else
ast_channel_setoption(chan, ntohs(aoh->option), aoh->data, f->datalen - sizeof(struct ast_option_header), 0);
}
}
if ((f->frametype == AST_FRAME_DTMF) && (who == peer) && allowredirect &&
(f->subclass == '#')) {
memset(newext, 0, sizeof(newext));
ptr = newext;
/* Transfer */
if ((res=ast_streamfile(peer, "pbx-transfer", chan->language)))
break;
if ((res=ast_waitstream(peer, AST_DIGIT_ANY)) < 0)
break;
ast_stopstream(peer);
if (res > 0) {
/* If they've typed a digit already, handle it */
newext[0] = res;
ptr++;
len --;
}
res = 0;
while(strlen(newext) < sizeof(newext - 1)) {
res = ast_waitfordigit(peer, 3000);
if (res < 1)
break;
*(ptr++) = res;
if (!ast_canmatch_extension(peer, peer->context, newext, 1, peer->callerid) ||
ast_exists_extension(peer, peer->context, newext, 1, peer->callerid)) {
res = 0;
break;
}
}
if (res)
break;
if (!strcmp(newext, parking_ext)) {
if (!park_call(chan, peer)) {
/* We return non-zero, but tell the PBX not to hang the channel when
the thread dies -- We have to be careful now though. We are responsible for
hanging up the channel, else it will never be hung up! */
res=AST_PBX_KEEPALIVE;
break;
} else {
ast_log(LOG_WARNING, "Unable to park call %s\n", chan->name);
}
/* XXX Maybe we should have another message here instead of invalid extension XXX */
} else if (ast_exists_extension(chan, peer->context, newext, 1, peer->callerid)) {
/* Set the channel's new extension, since it exists, using peer context */
strncpy(chan->exten, newext, sizeof(chan->exten));
strncpy(chan->context, peer->context, sizeof(chan->context));
chan->priority = 0;
ast_frfree(f);
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Transferring %s to '%s' (context %s) priority 1\n", chan->name, chan->exten, chan->context);
res=0;
break;
} else {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Unable to find extension '%s' in context %s\n", newext, peer->context);
}
res = ast_streamfile(peer, "pbx-invalid", chan->language);
if (res)
break;
res = ast_waitstream(peer, AST_DIGIT_ANY);
ast_stopstream(peer);
res = 0;
} else {
#if 1
ast_log(LOG_DEBUG, "Read from %s (%d,%d)\n", who->name, f->frametype, f->subclass);
#endif
}
}
return res;
}
static int park_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
struct ast_channel *peer=NULL;
struct parkeduser *pu, *pl=NULL;
int park;
if (!data) {
ast_log(LOG_WARNING, "Park requires an argument (extension number)\n");
return -1;
}
LOCAL_USER_ADD(u);
park = atoi((char *)data);
ast_pthread_mutex_lock(&parking_lock);
pu = parkinglot;
while(pu) {
if (pu->parkingnum == park) {
if (pl)
pl->next = pu->next;
else
parkinglot = pu->next;
break;
}
pu = pu->next;
}
ast_pthread_mutex_unlock(&parking_lock);
if (pu) {
peer = pu->chan;
free(pu);
}
if (peer) {
res = ast_channel_make_compatible(chan, peer);
if (res < 0) {
ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
ast_hangup(peer);
return -1;
}
/* This runs sorta backwards, since we give the incoming channel control, as if it
were the person called. */
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to parked call %d\n", chan->name, park);
res = bridge_call(peer, chan, 1);
/* Simulate the PBX hanging up */
if (res != AST_PBX_KEEPALIVE)
ast_hangup(peer);
return -1;
} else {
/* XXX Play a message XXX */
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Channel %s tried to talk to non-existant parked call %d\n", chan->name, park);
res = -1;
}
LOCAL_USER_REMOVE(u);
return res;
}
static int dial_exec(struct ast_channel *chan, void *data)
{
int res=-1;
@@ -599,7 +275,7 @@ static int dial_exec(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "Out of memory\n");
return -1;
}
strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION);
strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION-1);
peers = info;
if (peers) {
timeout = strchr(info, '|');
@@ -641,14 +317,19 @@ static int dial_exec(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "Out of memory\n");
goto out;
}
if (transfer && (strchr(transfer, 't')))
tmp->allowredirect = 1;
else
tmp->allowredirect = 0;
strncpy(numsubst, number, sizeof(numsubst));
memset(tmp, 0, sizeof(struct localuser));
if (transfer) {
if (strchr(transfer, 't'))
tmp->allowredirect = 1;
if (strchr(transfer, 'r'))
tmp->ringbackonly = 1;
if (strchr(transfer, 'm'))
tmp->musiconhold = 1;
}
strncpy(numsubst, number, sizeof(numsubst)-1);
/* If we're dialing by extension, look at the extension to know what to dial */
if ((newnum = strstr(numsubst, "BYEXTENSION"))) {
strncpy(restofit, newnum + strlen("BYEXTENSION"), sizeof(restofit));
strncpy(restofit, newnum + strlen("BYEXTENSION"), sizeof(restofit)-1);
snprintf(newnum, sizeof(numsubst) - (newnum - numsubst), "%s%s", chan->exten,restofit);
if (option_debug)
ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
@@ -657,19 +338,43 @@ static int dial_exec(struct ast_channel *chan, void *data)
tmp->chan = ast_request(tech, chan->nativeformats, numsubst);
if (!tmp->chan) {
/* If we can't, just go on to the next call */
ast_log(LOG_WARNING, "Unable to create channel of type '%s'\n", tech);
ast_log(LOG_NOTICE, "Unable to create channel of type '%s'\n", tech);
if (chan->cdr)
ast_cdr_busy(chan->cdr);
free(tmp);
cur = rest;
continue;
}
if (strlen(tmp->chan->call_forward)) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Forwarding call to '%s@%s'\n", tmp->chan->call_forward, tmp->chan->context);
/* Setup parameters */
strncpy(chan->exten, tmp->chan->call_forward, sizeof(chan->exten));
strncpy(chan->context, tmp->chan->context, sizeof(chan->context));
chan->priority = 0;
to = 0;
ast_hangup(tmp->chan);
free(tmp);
cur = rest;
break;
}
tmp->chan->appl = "AppDial";
tmp->chan->data = "(Outgoing Line)";
tmp->chan->whentohangup = 0;
if (tmp->chan->callerid)
free(tmp->chan->callerid);
if (tmp->chan->ani)
free(tmp->chan->ani);
if (chan->callerid)
tmp->chan->callerid = strdup(chan->callerid);
else
tmp->chan->callerid = NULL;
if (chan->ani)
tmp->chan->ani = strdup(chan->ani);
else
tmp->chan->ani = NULL;
/* Presense of ADSI CPE on outgoing channel follows ours */
tmp->chan->adsicpe = chan->adsicpe;
/* Place the call, but don't wait on the answer */
res = ast_call(tmp->chan, numsubst, 0);
if (res) {
@@ -715,6 +420,9 @@ static int dial_exec(struct ast_channel *chan, void *data)
conversation. */
hanguptree(outgoing, peer);
outgoing = NULL;
/* If appropriate, log that we have a destination channel */
if (chan->cdr)
ast_cdr_setdestchan(chan->cdr, peer->name);
/* Make sure channels are compatible */
res = ast_channel_make_compatible(chan, peer);
if (res < 0) {
@@ -730,7 +438,7 @@ static int dial_exec(struct ast_channel *chan, void *data)
int x = 2;
ast_channel_setoption(peer,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
}
res = bridge_call(chan, peer, allowredir);
res = ast_bridge_call(chan, peer, allowredir);
ast_hangup(peer);
}
out:
@@ -749,25 +457,7 @@ int unload_module(void)
int load_module(void)
{
int res;
int x;
struct ast_context *con;
char exten[AST_MAX_EXTENSION];
con = ast_context_find(parking_con);
if (!con) {
con = ast_context_create(parking_con, registrar);
if (!con) {
ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
return -1;
}
}
for(x=parking_start; x<=parking_stop;x++) {
snprintf(exten, sizeof(exten), "%d", x);
ast_add_extension2(con, 1, exten, 1, NULL, parkedcall, strdup(exten), free, registrar);
}
pthread_create(&parking_thread, NULL, do_parking_thread, NULL);
res = ast_register_application(parkedcall, park_exec, synopsis, descrip);
if (!res)
res = ast_register_application(app, dial_exec, synopsis, descrip);
res = ast_register_application(app, dial_exec, synopsis, descrip);
return res;
}

View 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>
@@ -131,7 +132,8 @@ static int do_directory(struct ast_channel *chan, struct ast_config *cfg, char *
memset(ext, 0, sizeof(ext));
ext[0] = digit;
res = 0;
if (ast_readstring(chan, ext + 1, NUMDIGITS, 3000, 3000, "#") < 0) res = -1;
if (ast_readstring(chan, ext + 1, NUMDIGITS - 1, 3000, 3000, "#") < 0) res = -1;
printf("Res: %d, ext: %s\n", res, ext);
if (!res) {
/* Search for all names which start with those digits */
v = ast_variable_browse(cfg, context);
@@ -166,13 +168,13 @@ static int do_directory(struct ast_channel *chan, struct ast_config *cfg, char *
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)) {
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 {
res = ast_say_digit_str(chan, v->name, chan->language);
res = ast_say_digit_str(chan, v->name, AST_DIGIT_ANY, chan->language);
}
ahem:
if (!res)
@@ -184,9 +186,9 @@ ahem:
ast_stopstream(chan);
if (res > -1) {
if (res == '1') {
strncpy(chan->exten, v->name, sizeof(chan->exten));
strncpy(chan->exten, v->name, sizeof(chan->exten)-1);
chan->priority = 0;
strncpy(chan->context, context, sizeof(chan->context));
strncpy(chan->context, context, sizeof(chan->context)-1);
res = 0;
break;
} else if (res == '*') {

View 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>
@@ -25,7 +26,9 @@
#include <pthread.h>
#include <sys/time.h>
#define TONE_BLOCK_SIZE 200
/*
#define TONE_BLOCK_SIZE 320
*/
static char *tdesc = "DISA (Direct Inward System Access) Application";
@@ -72,23 +75,21 @@ STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static float loudness=8192.0;
static float loudness=4096.0;
int firstdigittimeout = 10000; /* 10 seconds first digit timeout */
int digittimeout = 5000; /* 5 seconds subsequent digit timeout */
int firstdigittimeout = 20000; /* 20 seconds first digit timeout */
int digittimeout = 10000; /* 10 seconds subsequent digit timeout */
static void make_tone_block(unsigned char *data, float f1, float f2, int *x);
static void make_tone_block(unsigned char *data, float f1, float f2, int *x)
static void make_tone_block(unsigned char *data, float f1, float f2, int len, int *x)
{
int i;
float val;
for(i = 0; i < TONE_BLOCK_SIZE; i++)
for(i = 0; i < len; i++)
{
val = loudness * sin((f1 * 2.0 * M_PI * (*x))/8000.0);
val += loudness * sin((f2 * 2.0 * M_PI * (*x)++)/8000.0);
data[i] = ast_lin2mu[(int)val + 32768];
data[i] = AST_LIN2MU((int)val);
}
/* wrap back around from 8000 */
if (*x >= 8000) *x = 0;
@@ -108,13 +109,12 @@ static int disa_exec(struct ast_channel *chan, void *data)
{
int i,j,k,x;
struct localuser *u;
char tmp[256],exten[AST_MAX_EXTENSION];
unsigned char tone_block[TONE_BLOCK_SIZE],sil_block[TONE_BLOCK_SIZE];
char tmp[256],exten[AST_MAX_EXTENSION],acctcode[20];
unsigned char tone_block[640],sil_block[640];
char *ourcontext;
struct ast_frame *f,wf;
fd_set readfds;
int waitfor_notime;
struct timeval notime = { 0,0 }, lastout, now, lastdigittime;
struct timeval lastout, now, lastdigittime;
int res;
FILE *fp;
if (ast_set_write_format(chan,AST_FORMAT_ULAW))
@@ -129,12 +129,12 @@ static int disa_exec(struct ast_channel *chan, void *data)
}
lastout.tv_sec = lastout.tv_usec = 0;
/* make block of silence */
memset(sil_block,0x7f,TONE_BLOCK_SIZE);
memset(sil_block,0x7f,sizeof(sil_block));
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));
strncpy(tmp, (char *)data, sizeof(tmp)-1);
strtok(tmp, "|");
ourcontext = strtok(NULL, "|");
/* if context not specified, use "disa" */
@@ -165,33 +165,11 @@ static int disa_exec(struct ast_channel *chan, void *data)
((k) ? "extension" : "password"),chan->name);
goto reorder;
}
/* if first digit or ignore, send dialtone */
if ((!i) || (ast_ignore_pattern(ourcontext,exten) && k))
{
gettimeofday(&now,NULL);
if (lastout.tv_sec &&
(ms_diff(&now,&lastout) < 25)) continue;
lastout.tv_sec = now.tv_sec;
lastout.tv_usec = now.tv_usec;
wf.frametype = AST_FRAME_VOICE;
wf.subclass = AST_FORMAT_ULAW;
wf.offset = AST_FRIENDLY_OFFSET;
wf.mallocd = 0;
wf.data = tone_block;
wf.datalen = TONE_BLOCK_SIZE;
/* make this tone block */
make_tone_block(tone_block,350.0,440.0,&x);
wf.timelen = wf.datalen / 8;
if (ast_write(chan, &wf))
{
ast_log(LOG_WARNING, "DISA Failed to write frame on %s\n",chan->name);
LOCAL_USER_REMOVE(u);
return -1;
}
if ((res = ast_waitfor(chan, -1) < 0)) {
ast_log(LOG_DEBUG, "Waitfor returned %d\n", res);
continue;
}
waitfor_notime = notime.tv_usec + notime.tv_sec * 1000;
if (!ast_waitfor_nandfds(&chan, 1, &(chan->fds[0]), 1, NULL, NULL,
&waitfor_notime)) continue;
f = ast_read(chan);
if (f == NULL)
{
@@ -204,6 +182,27 @@ static int disa_exec(struct ast_channel *chan, void *data)
ast_frfree(f);
LOCAL_USER_REMOVE(u);
return -1;
}
if (f->frametype == AST_FRAME_VOICE) {
if (!i || (ast_ignore_pattern(ourcontext, exten) && k)) {
wf.frametype = AST_FRAME_VOICE;
wf.subclass = AST_FORMAT_ULAW;
wf.offset = AST_FRIENDLY_OFFSET;
wf.mallocd = 0;
wf.data = tone_block;
wf.datalen = f->datalen;
make_tone_block(tone_block, 350, 440, f->datalen, &x);
wf.timelen = wf.datalen / 8;
ast_frfree(f);
if (ast_write(chan, &wf))
{
ast_log(LOG_WARNING, "DISA Failed to write frame on %s\n",chan->name);
LOCAL_USER_REMOVE(u);
return -1;
}
} else
ast_frfree(f);
continue;
}
/* if not DTMF, just do it again */
if (f->frametype != AST_FRAME_DTMF)
@@ -211,8 +210,10 @@ static int disa_exec(struct ast_channel *chan, void *data)
ast_frfree(f);
continue;
}
j = f->subclass; /* save digit */
ast_frfree(f);
gettimeofday(&lastdigittime,NULL);
/* got a DTMF tone */
if (i < AST_MAX_EXTENSION) /* if still valid number of digits */
@@ -255,10 +256,14 @@ static int disa_exec(struct ast_channel *chan, void *data)
{
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_WARNING,"DISA on chan %s password is good\n",chan->name);
k = 1;
i = 0; /* re-set buffer pointer */
exten[sizeof(acctcode)] = 0;
strcpy(acctcode,exten);
exten[0] = 0;
ast_log(LOG_DEBUG,"Successful DISA log-in on chan %s\n",chan->name);
continue;
@@ -272,7 +277,9 @@ static int disa_exec(struct ast_channel *chan, void *data)
{
strcpy(chan->exten,exten);
strcpy(chan->context,ourcontext);
strcpy(chan->accountcode,acctcode);
chan->priority = 0;
ast_cdr_init(chan->cdr,chan);
LOCAL_USER_REMOVE(u);
return 0;
}
@@ -280,95 +287,46 @@ static int disa_exec(struct ast_channel *chan, void *data)
if (ast_canmatch_extension(chan,ourcontext,exten,1, chan->callerid)) continue;
}
reorder:
/* something is invalid, give em reorder forever */
x = 0;
k = 0; /* k = 0 means busy tone, k = 1 means silence) */
i = 0; /* Number of samples we've done */
for(;;)
{
for(i = 0; i < 10; i++)
{
do gettimeofday(&now,NULL);
while (lastout.tv_sec &&
(ms_diff(&now,&lastout) < 25)) ;
lastout.tv_sec = now.tv_sec;
lastout.tv_usec = now.tv_usec;
if (ast_waitfor(chan, -1) < 0)
break;
f = ast_read(chan);
if (!f)
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;
wf.datalen = TONE_BLOCK_SIZE;
/* make this tone block */
make_tone_block(tone_block,480.0,620.0,&x);
wf.datalen = f->datalen;
wf.timelen = wf.datalen / 8;
if (ast_write(chan, &wf))
if (k)
memset(tone_block, 0x7f, wf.datalen);
else
make_tone_block(tone_block,480.0, 620.0,wf.datalen, &x);
i += wf.datalen / 8;
if (i > 250) {
i = 0;
k = !k;
}
if (ast_write(chan, &wf))
{
ast_log(LOG_WARNING, "DISA Failed to write frame on %s\n",chan->name);
ast_log(LOG_WARNING, "DISA Failed to write frame on %s\n",chan->name);
LOCAL_USER_REMOVE(u);
return -1;
}
FD_ZERO(&readfds);
FD_SET(chan->fds[0],&readfds);
/* if no read avail, do send again */
if (select(chan->fds[0] + 1,&readfds,NULL,
NULL,&notime) < 1) continue;
/* read frame */
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;
}
ast_frfree(f);
}
for(i = 0; i < 10; i++)
{
do gettimeofday(&now,NULL);
while (lastout.tv_sec &&
(ms_diff(&now,&lastout) < 25)) ;
lastout.tv_sec = now.tv_sec;
lastout.tv_usec = now.tv_usec;
wf.frametype = AST_FRAME_VOICE;
wf.subclass = AST_FORMAT_ULAW;
wf.offset = AST_FRIENDLY_OFFSET;
wf.mallocd = 0;
wf.data = sil_block;
wf.datalen = TONE_BLOCK_SIZE;
wf.timelen = wf.datalen / 8;
if (ast_write(chan, &wf))
{
ast_log(LOG_WARNING, "DISA Failed to write frame on %s\n",chan->name);
LOCAL_USER_REMOVE(u);
return -1;
}
FD_ZERO(&readfds);
FD_SET(chan->fds[0],&readfds);
/* if no read avail, do send again */
if (select(chan->fds[0] + 1,&readfds,NULL,
NULL,&notime) < 1) continue;
/* read frame */
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;
}
ast_frfree(f);
}
ast_frfree(f);
}
LOCAL_USER_REMOVE(u);
return -1;
}
}

View 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>
@@ -44,8 +45,13 @@ static int echo_exec(struct ast_channel *chan, void *data)
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;
if (f->frametype == AST_FRAME_VOICE) {
if (ast_write(chan, f))
break;

149
apps/app_getcpeid.c Normal file
View File

@@ -0,0 +1,149 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Execute arbitrary system 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/adsi.h>
#include <asterisk/options.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.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 CPE ID and other information in order to\n"
"properly setup zapata.conf for on-hook operations. Returns -1 on hanup\n"
"only.";
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));
strcpy(stuff[0], "** CPE Info **");
strcpy(stuff[1], "Identifying CPE...");
strcpy(stuff[2], "Please wait...");
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) {
strcpy(stuff[1], "Measuring CPE...");
strcpy(stuff[2], "Please wait...");
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)
sprintf(stuff[1], "CPEID: %02x:%02x:%02x:%02x", cpeid[0], cpeid[1], cpeid[2], cpeid[3]);
else
strcpy(stuff[1], "CPEID Unknown");
if (gotgeometry)
sprintf(stuff[2], "Geom: %dx%d, %d buttons", width, height, buttons);
else
strcpy(stuff[2], "Geometry unknown");
strcpy(stuff[3], "Press # to exit");
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;
}

View 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>

View 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>
@@ -47,7 +48,7 @@ STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static pthread_mutex_t sound_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t sound_lock = AST_MUTEX_INITIALIZER;
static int sound = -1;
static int write_audio(short *data, int len)

501
apps/app_meetme.c Normal file
View File

@@ -0,0 +1,501 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Meet me conference bridge
*
* 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/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 <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <linux/zaptel.h>
static char *tdesc = "Simple MeetMe conference bridge";
static char *app = "MeetMe";
static char *app2 = "MeetMeCount";
static char *synopsis = "Simple MeetMe conference bridge";
static char *synopsis2 = "MeetMe participant count";
static char *descrip =
" MeetMe(confno): Enters the user into a specified MeetMe conference.\n"
"If the conference number is omitted, the user will be prompted to enter\n"
"one. This application always returns -1. A ZAPTEL INTERFACE MUST BE\n"
"INSTALLED FOR CONFERENCING FUNCTIONALITY.\n";
static char *descrip2 =
" MeetMe2(confno): Plays back the number of users in the specified MeetMe\n"
"conference. Returns 0 on success or -1 on a hangup. A ZAPTEL INTERFACE\n"
"MUST BE INSTALLED FOR CONFERENCING FUNCTIONALITY.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static struct conf {
char confno[80]; /* Conference */
int fd; /* Announcements fd */
int zapconf; /* Zaptel Conf # */
int users; /* Number of active users */
time_t start; /* Start time (s) */
struct conf *next;
} *confs;
static pthread_mutex_t conflock = AST_MUTEX_INITIALIZER;
#include "enter.h"
#include "leave.h"
#define ENTER 0
#define LEAVE 1
#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 void conf_play(struct conf *conf, int sound)
{
unsigned char *data;
int len;
ast_pthread_mutex_lock(&conflock);
switch(sound) {
case ENTER:
data = enter;
len = sizeof(enter);
break;
case LEAVE:
data = leave;
len = sizeof(leave);
break;
default:
data = NULL;
len = 0;
}
if (data)
careful_write(conf->fd, data, len);
pthread_mutex_unlock(&conflock);
}
static struct conf *build_conf(char *confno, int make)
{
struct conf *cnf;
struct zt_confinfo ztc;
ast_pthread_mutex_lock(&conflock);
cnf = confs;
while(cnf) {
if (!strcmp(confno, cnf->confno))
break;
cnf = cnf->next;
}
if (!cnf && make) {
cnf = malloc(sizeof(struct conf));
if (cnf) {
/* Make a new one */
memset(cnf, 0, sizeof(struct conf));
strncpy(cnf->confno, confno, sizeof(cnf->confno) - 1);
cnf->fd = open("/dev/zap/pseudo", O_RDWR);
if (cnf->fd < 0) {
ast_log(LOG_WARNING, "Unable to open pseudo channel\n");
free(cnf);
cnf = NULL;
goto cnfout;
}
memset(&ztc, 0, sizeof(ztc));
/* Setup a new zap conference */
ztc.chan = 0;
ztc.confno = -1;
ztc.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
if (ioctl(cnf->fd, ZT_SETCONF, &ztc)) {
ast_log(LOG_WARNING, "Error setting conference\n");
close(cnf->fd);
free(cnf);
cnf = NULL;
goto cnfout;
}
cnf->start = time(NULL);
cnf->zapconf = ztc.confno;
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Crated ZapTel conference %d for conference '%s'\n", cnf->zapconf, cnf->confno);
cnf->next = confs;
confs = cnf;
} else
ast_log(LOG_WARNING, "Out of memory\n");
}
cnfout:
if (cnf && make)
cnf->users++;
ast_pthread_mutex_unlock(&conflock);
return cnf;
}
static int confs_show(int fd, int argc, char **argv)
{
struct conf *conf;
int hr, min, sec;
time_t now;
now = time(NULL);
if (argc != 2)
return RESULT_SHOWUSAGE;
conf = confs;
if (!conf) {
ast_cli(fd, "No active conferences.\n");
return RESULT_SUCCESS;
}
ast_cli(fd, "Conf Num Parties Activity\n");
while(conf) {
hr = (now - conf->start) / 3600;
min = ((now - conf->start) % 3600) / 60;
sec = (now - conf->start) % 60;
ast_cli(fd, "%-12.12s %4.4d %02d:%02d:%02d\n",
conf->confno, conf->users, hr, min, sec);
conf = conf->next;
}
return RESULT_SUCCESS;
}
static char show_confs_usage[] =
"Usage: show conferences\n"
" Provides summary information on conferences with active\n"
" participation.\n";
static struct ast_cli_entry cli_show_confs = {
{ "show", "conferences", NULL }, confs_show,
"Show status of conferences", show_confs_usage, NULL };
static void conf_run(struct ast_channel *chan, struct conf *conf)
{
struct conf *prev=NULL, *cur;
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=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;
}
zapretry:
if (retryzap || strcasecmp(chan->type, "Zap")) {
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 = conf->zapconf;
ztc.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
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 conf %d\n", chan->name, conf->zapconf);
/* Run the conference enter tone... */
conf_play(conf, ENTER);
for(;;) {
outfd = -1;
ms = -1;
c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
if (c) {
f = ast_read(c);
if (!f)
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.timelen = res / 8;
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);
conf_play(conf, LEAVE);
outrun:
ast_pthread_mutex_lock(&conflock);
/* Clean up */
conf->users--;
if (!conf->users) {
/* No more users -- close this one out */
cur = confs;
while(cur) {
if (cur == conf) {
if (prev)
prev->next = conf->next;
else
confs = conf->next;
break;
}
prev = cur;
cur = cur->next;
}
if (!cur)
ast_log(LOG_WARNING, "Conference not found\n");
close(conf->fd);
free(conf);
}
pthread_mutex_unlock(&conflock);
}
static struct conf *find_conf(char *confno, int make)
{
struct ast_config *cfg;
struct ast_variable *var;
struct conf *cnf = NULL;
cfg = ast_load("meetme.conf");
if (!cfg) {
ast_log(LOG_WARNING, "No meetme.conf file :(\n");
return NULL;
}
var = ast_variable_browse(cfg, "rooms");
while(var) {
if (!strcasecmp(var->name, "conf") &&
!strcasecmp(var->value, confno)) {
/* Bingo it's a valid conference */
cnf = build_conf(confno, make);
break;
}
var = var->next;
}
if (!var) {
ast_log(LOG_DEBUG, "%s isn't a valid conference\n", confno);
}
ast_destroy(cfg);
return cnf;
}
static int count_exec(struct ast_channel *chan, void *data)
{
struct localuser *u;
int res = 0;
struct conf *conf;
int cnt;
if (!data || !strlen(data)) {
ast_log(LOG_WARNING, "MeetMeCount requires an argument (conference number)\n");
return -1;
}
LOCAL_USER_ADD(u);
conf = find_conf(data, 0);
if (conf)
cnt = conf->users;
else
cnt = 0;
if (chan->state != AST_STATE_UP)
ast_answer(chan);
res = ast_say_number(chan, cnt, "", chan->language);
LOCAL_USER_REMOVE(u);
return res;
}
static int conf_exec(struct ast_channel *chan, void *data)
{
int res=-1;
struct localuser *u;
char confno[80] = "";
int allowretry = 0;
int retrycnt = 0;
struct conf *cnf;
if (!data || !strlen(data)) {
allowretry = 1;
data = "";
}
LOCAL_USER_ADD(u);
if (chan->state != AST_STATE_UP)
ast_answer(chan);
retry:
/* Parse out the stuff */
strncpy(confno, data, sizeof(confno) - 1);
while(!strlen(confno) && (++retrycnt < 4)) {
/* Prompt user for conference number */
res = ast_app_getdata(chan, "conf-getconfno",confno, sizeof(confno) - 1, 0);
if (res <0) goto out;
}
if (strlen(confno)) {
/* Check the validity of the conference */
cnf = find_conf(confno, 1);
if (!cnf) {
res = ast_streamfile(chan, "conf-invalid", chan->language);
if (res < 0)
goto out;
if (!res)
res = ast_waitstream(chan, "");
res = -1;
if (allowretry) {
strcpy(confno, "");
goto retry;
}
} else {
/* Run the conference */
conf_run(chan, cnf);
res = -1;
}
}
out:
/* Do the conference */
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
ast_cli_unregister(&cli_show_confs);
ast_unregister_application(app2);
return ast_unregister_application(app);
}
int load_module(void)
{
ast_cli_register(&cli_show_confs);
ast_register_application(app2, count_exec, synopsis2, descrip2);
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;
}

148
apps/app_milliwatt.c Normal file
View 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 <pthread.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)
{
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",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.timelen = wf.datalen / 8;
wf.src = "app_milliwatt";
/* 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;
struct ast_frame *f;
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;
}

View 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>

View 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>
@@ -32,9 +33,11 @@ static char *descrip =
"extension). Options may also be included following a pipe symbol. The only\n"
"defined option at this time is 'skip', which causes the playback of the\n"
"message to be skipped if the channel is not in the 'up' state (i.e. it\n"
"hasn't been answered yet. If 'skip' is not specified, the channel will be\n"
"answered before the sound is played. Returns -1 if the channel was hung up,\n"
"or if the file does not exist. Returns 0 otherwise.\n";
"hasn't been answered yet. If 'skip' is specified, the application will\n"
"return immediately should the channel not be off hook. Otherwise, unless\n"
"'noanswer' is specified, the channel channel will be answered before the sound\n"
"is played. Not all channels support playing messages while on hook. Returns -1\n"
"if the channel was hung up, or if the file does not exist. Returns 0 otherwise.\n";
STANDARD_LOCAL_USER;
@@ -47,23 +50,26 @@ static int playback_exec(struct ast_channel *chan, void *data)
char tmp[256];
char *options;
int option_skip=0;
int option_noanswer = 0;
if (!data || !strlen((char *)data)) {
ast_log(LOG_WARNING, "Playback requires an argument (filename)\n");
return -1;
}
strncpy(tmp, (char *)data, sizeof(tmp));
strncpy(tmp, (char *)data, sizeof(tmp)-1);
strtok(tmp, "|");
options = strtok(NULL, "|");
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) {
if (option_skip) {
/* At the user's option, skip if the line is not up */
LOCAL_USER_REMOVE(u);
return 0;
} else
/* Otherwise answer */
} else if (!option_noanswer)
/* Otherwise answer unless we're supposed to send this while on-hook */
res = ast_answer(chan);
}
if (!res) {

384
apps/app_qcall.c Normal file
View File

@@ -0,0 +1,384 @@
/** @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/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 <pthread.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>
const char *qdir="/var/spool/asterisk/qcall";
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;
sprintf(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_ctime)
{ /* 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 (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],dialstr[300],extstr[300],ident[300],reqinp[300],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 */
strcpy(fname,(char *)arg);
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);
}
strcpy(reqinp,"1"); /* default required input for acknowledgement */
strcpy(ident, ""); /* 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)) {
strcat(ident,"-ok");
/* if file existant, 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
strcpy(channel->accountcode,ACCTCODE);
#else
channel->accountcode[0] = 0;
#endif
if (maxsecs) /* if finite length call */
{
time(&channel->whentohangup);
channel->whentohangup += maxsecs;
}
strcpy(channel->exten,extstr);
strcpy(channel->context,context);
channel->priority = 1;
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)
{
mkdir(qdir,0660);
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;
}

View 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>
@@ -51,7 +52,7 @@ static int record_exec(struct ast_channel *chan, void *data)
struct ast_filestream *s = '\0';
struct localuser *u;
struct ast_frame *f;
struct ast_frame *f = NULL;
vdata = data; /* explained above */
@@ -89,7 +90,7 @@ static int record_exec(struct ast_channel *chan, void *data)
count++;
} while ( ast_fileexists(tmp, ext, chan->language) != -1 );
} else
strncpy(tmp, fil, 256);
strncpy(tmp, fil, 256-1);
/* end of routine mentioned */
LOCAL_USER_ADD(u);
@@ -103,10 +104,8 @@ static int record_exec(struct ast_channel *chan, void *data)
/* 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) {
printf("Waiting on stream\n");
res = ast_waitstream(chan, "");
} else {
printf("streamfile failed\n");
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", chan->name);
}
ast_stopstream(chan);
@@ -114,8 +113,12 @@ static int record_exec(struct ast_channel *chan, void *data)
s = ast_writefile( tmp, ext, NULL, O_CREAT|O_TRUNC|O_WRONLY , 0, 0644);
if (s) {
while ((f = ast_read(chan))) {
while (ast_waitfor(chan, -1) > -1) {
f = ast_read(chan);
if (!f) {
res = -1;
break;
}
if (f->frametype == AST_FRAME_VOICE) {
res = ast_writestream(s, f);

View 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>
@@ -53,10 +54,10 @@ static int skel_exec(struct ast_channel *chan, void *data)
/* Do our thing here */
res = system((char *)data);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to execute '%s'\n", data);
ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
res = -1;
} else if (res == 127) {
ast_log(LOG_WARNING, "Unable to execute '%s'\n", data);
ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
res = -1;
} else {
if (res && ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))

View 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>
@@ -55,7 +56,7 @@ static int sendurl_exec(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "SendURL requires an argument (URL)\n");
return -1;
}
strncpy(tmp, (char *)data, sizeof(tmp));
strncpy(tmp, (char *)data, sizeof(tmp)-1);
strtok(tmp, "|");
options = strtok(NULL, "|");
if (options && !strcasecmp(options, "wait"))

File diff suppressed because it is too large Load Diff

91
apps/app_zapateller.c Normal file
View File

@@ -0,0 +1,91 @@
/*
* 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>
#include <pthread.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 telemarketers\n"
"from calling you. Returns 0 normally or -1 on hangup. Options is a pipe-delimited\n"
"list of options. The only supported option is 'answer' which will cause the line to\n"
"be answered before playing the tone";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int zapateller_exec(struct ast_channel *chan, void *data)
{
int res = 0;
struct localuser *u;
LOCAL_USER_ADD(u);
ast_stopstream(chan);
if (chan->state != AST_STATE_UP) {
if (data && !strcasecmp(data, "answer"))
res = ast_answer(chan);
if (!res) {
res = ast_safe_sleep(chan, 500);
}
}
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);
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;
}

238
apps/app_zapras.c Normal file
View File

@@ -0,0 +1,238 @@
/*
* 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>
#include <sys/signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
/* Need some zaptel help here */
#include <linux/zaptel.h>
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 emulcation 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;
/* 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 */
c = strtok(args, "|");
while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
argv[argc++] = c;
c = strtok(NULL, "|");
}
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 bi;
int x;
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);
/* Double check buffering too */
res = ioctl(chan->fds[0], ZT_GET_BUFINFO, &bi);
if (!res) {
/* XXX This is ZAP_BLOCKSIZE XXX */
bi.bufsize = 204;
bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
bi.numbufs = 4;
res = ioctl(chan->fds[0], ZT_SET_BUFINFO, &bi);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name);
}
} else
ast_log(LOG_WARNING, "Unable to check 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;
}

287
apps/enter.h Normal file
View 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
View 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 };

View File

@@ -1,161 +1,831 @@
# Here's the doxygen configuration file for the asterisk source
# code
# Doxyfile 1.2.10
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
# TAG = value [value, ...]
# For lists items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ")
# Doxygen configuration generated by Doxywizard version 0.1
#---------------------------------------------------------------------------
# General configuration options
#---------------------------------------------------------------------------
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = Asterisk
PROJECT_NUMBER = 0.1.8
OUTPUT_DIRECTORY = doc/
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = CVS
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = doc/api
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Brazilian, Chinese, Croatian, Czech, Danish, Dutch, Finnish, French,
# German, Hungarian, Italian, Japanese, Korean, Norwegian, Polish,
# Portuguese, Romanian, Russian, Slovak, Slovene, Spanish and Swedish.
OUTPUT_LANGUAGE = English
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = YES
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = NO
HIDE_UNDOC_MEMBERS = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
# If set to NO (the default) these class will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES = NO
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = NO
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = NO
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. It is allowed to use relative paths in the argument list.
STRIP_FROM_PATH =
# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.
INTERNAL_DOCS = NO
CLASS_DIAGRAMS = YES
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
# generate a class diagram (in Html and LaTeX) for classes with base or
# super classes. Setting the tag to NO turns the diagrams off.
CLASS_DIAGRAMS = NO
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = YES
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = NO
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
# file names in lower case letters. If set to YES upper case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# users are adviced to set this option to NO.
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
# (but less readable) file names. This can be useful is your file systems
# doesn't support long names like on DOS, Mac, or CD-ROM.
SHORT_NAMES = NO
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.
HIDE_SCOPE_NAMES = YES
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
VERBATIM_HEADERS = YES
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
# will put list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES = YES
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the JavaDoc
# comments will behave just like the Qt-style comments (thus requiring an
# explict @brief command for a brief description.
JAVADOC_AUTOBRIEF = NO
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# reimplements.
INHERIT_DOCS = YES
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
# will sort the (detailed) documentation of file and class members
# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS = YES
DISTRIBUTE_GROUP_DOC = YES
TAB_SIZE = 4
ENABLED_SECTIONS =
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES, then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
DISTRIBUTE_GROUP_DOC = NO
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
TAB_SIZE = 3
# The GENERATE_TODOLIST tag can be used to enable (YES) or
# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.
GENERATE_TODOLIST = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or
# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = NO
# The GENERATE_BUGLIST tag can be used to enable (YES) or
# disable (NO) the bug list. This list is created by putting \bug
# commands in the documentation.
GENERATE_BUGLIST = YES
# This tag can be used to specify a number of aliases that acts
# as commands in the documentation. An alias has the form "name=value".
# For example adding "sideeffect=\par Side Effects:\n" will allow you to
# put the command \sideeffect (or @sideeffect) in the documentation, which
# will result in a user defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.
ALIASES =
MAX_INITIALIZER_LINES = 30
OPTIMIZE_OUTPUT_FOR_C = NO
# The ENABLED_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
ENABLED_SECTIONS =
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
# the initial value of a variable or define consist of for it to appear in
# the documentation. If the initializer consists of more lines than specified
# here it will be hidden. Use a value of 0 to hide initializers completely.
# The appearance of the initializer of individual variables and defines in the
# documentation can be controlled using \showinitializer or \hideinitializer
# command in the documentation regardless of this setting.
MAX_INITIALIZER_LINES = 5
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C.
# For instance some of the names that are used will be different. The list
# of all members will be omitted, etc.
OPTIMIZE_OUTPUT_FOR_C = YES
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
# at the bottom of the documentation of classes and structs. If set to YES the
# list will mention the files that were used to generate the documentation.
SHOW_USED_FILES = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
QUIET = NO
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.
WARNINGS = YES
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.
WARN_IF_UNDOCUMENTED = YES
WARN_FORMAT = "$file:$line: $text"
# The WARN_FORMAT tag determines the format of the warning messages that
# doxygen can produce. The string should contain the $file, $line, and $text
# tags, which will be replaced by the file and line number from which the
# warning originated and the warning text.
WARN_FORMAT =
# The WARN_LOGFILE tag can be used to specify a file to which warning
# and error messages should be written. If left blank the output is written
# to stderr.
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = .
FILE_PATTERNS = *.h \
*.c
RECURSIVE = YES
# The INPUT tag can be used to specify the files and/or directories that contain
# documented source files. You may enter file names like "myfile.cpp" or
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = ./ include/asterisk
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
FILE_PATTERNS = *.c *.h
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = NO
# The EXCLUDE tag can be used to specify files and/or directories that should
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE =
# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories.
EXCLUDE_PATTERNS =
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
EXAMPLE_PATTERNS =
# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command <filter> <input-file>, where <filter>
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
# input file. Doxygen will then use the output that the filter program writes
# to standard output.
INPUT_FILTER =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will be used to filter the input files when producing source
# files to browse.
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
ALPHABETICAL_INDEX = YES
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
HTML_OUTPUT = html
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT =
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet
HTML_STYLESHEET =
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = NO
# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
# controls if a separate .chi index file is generated (YES) or that
# it should be included in the master .chm file (NO).
GENERATE_CHI = NO
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
# controls whether a binary table of contents is generated (YES) or a
# normal table of contents (NO) in the .chm file.
BINARY_TOC = NO
# The TOC_EXPAND flag can be set to YES to add extra items for group members
# to the contents of the Html help documentation and to the tree view.
TOC_EXPAND = NO
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.
DISABLE_INDEX = NO
# This tag can be used to set the number of enum values (range [1..20])
# that doxygen will group on one line in the generated HTML documentation.
ENUM_VALUES_PER_LINE = 4
# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
# generated containing a tree-like index structure (just like the one that
# is generated for HTML Help). For this to work a browser that supports
# JavaScript and frames is required (for instance Netscape 4.0+
# or Internet explorer 4.0+).
GENERATE_TREEVIEW = NO
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
# used to set the initial width (in pixels) of the frame in which the tree
# is shown.
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = YES
LATEX_OUTPUT = ps
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.
LATEX_OUTPUT =
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX = NO
PAPER_TYPE = a4
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, a4wide, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE = a4wide
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
# the generated latex document. The header should contain everything until
# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!
LATEX_HEADER =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS = NO
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = NO
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = YES
RTF_OUTPUT = rtf
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
# The RTF output is optimised for Word 97 and may not look very pretty with
# other RTF readers or editors.
GENERATE_RTF = NO
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.
RTF_OUTPUT =
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
# RTF documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_RTF = NO
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
# will contain hyperlink fields. The RTF file will
# contain links (just like the HTML output) instead of page references.
# This makes the output suitable for online browsing using WORD or other
# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assigments. You only have to provide
# replacements, missing definitions are set to their default value.
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an rtf document.
# Syntax is similar to doxygen's config file.
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.
MAN_OUTPUT =
# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION =
# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
# then it will generate one additional man file for each entity
# documented in the real man page(s). These additional files
# only source the real man page, but without them the man command
# would be unable to find the correct page. The default is NO.
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES Doxygen will
# generate an XML file that captures the structure of
# the code including all documentation. Note that this
# feature is still experimental and incomplete at the
# moment.
GENERATE_XML = NO
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = NO
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
# evaluate all C-preprocessor directives found in the sources and include
# files.
ENABLE_PREPROCESSING = YES
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
# names in the source code. If set to NO (the default) only conditional
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
MACRO_EXPANSION = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# in the INCLUDE_PATH (see below) will be search if a #include is found.
SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by
# the preprocessor.
INCLUDE_PATH =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.
INCLUDE_FILE_PATTERNS =
# The PREDEFINED tag can be used to specify one or more macro names that
# are defined before the preprocessor is started (similar to the -D option of
# gcc). The argument of the tag is a list of macros of the form: name
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed.
PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition.
EXPAND_AS_DEFINED =
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
#---------------------------------------------------------------------------
# The TAGFILES tag can be used to specify one or more tagfiles.
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS = NO
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
HAVE_DOT = NO
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz, a graph visualization
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = YES
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
# the CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.
COLLABORATION_GRAPH = YES
# If set to YES, the inheritance and collaboration graphs will show the
# relations between templates and their instances.
TEMPLATE_RELATIONS = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
# tags are set to YES then doxygen will generate a graph for each documented
# file showing the direct and indirect include dependencies of the file with
# other documented files.
INCLUDE_GRAPH = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
# documented header file showing the documented files that directly or
# indirectly include this file.
INCLUDED_BY_GRAPH = YES
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found on the path.
DOT_PATH =
# The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the
# \dotfile command).
DOTFILE_DIRS =
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_WIDTH = 1024
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_HEIGHT = 1024
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
# generate a legend page explaining the meaning of the various boxes and
# arrows in the dot generated graphs.
GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
# remove the intermedate dot files that are used to generate
# the various graphs.
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
CGI_NAME = search.cgi
CGI_URL = http://localhost/cgi-bin
DOC_URL = http://localhost/asterisk/documentation
DOC_ABSPATH = /var/www/html/asterisk/documentation
BIN_ABSPATH = /usr/local/bin
EXT_DOC_PATHS =
# The SEARCHENGINE tag specifies whether or not a search engine should be
# used. If set to NO the values of all tags below this one will be ignored.
SEARCHENGINE = NO
# The CGI_NAME tag should be the name of the CGI script that
# starts the search engine (doxysearch) with the correct parameters.
# A script with this name will be generated by doxygen.
CGI_NAME =
# The CGI_URL tag should be the absolute URL to the directory where the
# cgi binaries are located. See the documentation of your http daemon for
# details.
CGI_URL =
# The DOC_URL tag should be the absolute URL to the directory where the
# documentation is located. If left blank the absolute path to the
# documentation, with file:// prepended to it, will be used.
DOC_URL =
# The DOC_ABSPATH tag should be the absolute path to the directory where the
# documentation is located. If left blank the directory on the local machine
# will be used.
DOC_ABSPATH =
# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
# is installed.
BIN_ABSPATH =
# The EXT_DOC_PATHS tag can be used to specify one or more paths to
# documentation generated for other projects. This allows doxysearch to search
# the documentation for these projects as well.
EXT_DOC_PATHS =

View File

@@ -18,13 +18,17 @@
#include <asterisk/cli.h>
#include <asterisk/channel.h>
#include <asterisk/ulaw.h>
#include <asterisk/alaw.h>
#include <asterisk/callerid.h>
#include <asterisk/module.h>
#include <asterisk/image.h>
#include <asterisk/tdd.h>
#include <asterisk/term.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <sched.h>
#include <asterisk/io.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/un.h>
@@ -46,6 +50,8 @@ int option_console=0;
int option_highpriority=0;
int option_remote=0;
int option_exec=0;
int option_initcrypto=0;
int option_nocolor;
int fully_booted = 0;
static int ast_socket = -1; /* UNIX Socket for allowing remote control */
@@ -87,7 +93,7 @@ static void *netconsole(void *vconsole)
fd_set rfds;
if (gethostname(hostname, sizeof(hostname)))
strncpy(hostname, "<Unknown>", sizeof(hostname));
strncpy(hostname, "<Unknown>", sizeof(hostname)-1);
snprintf(tmp, sizeof(tmp), "%s/%d/%s\n", hostname, mainpid, ASTERISK_VERSION);
fdprint(con->fd, tmp);
for(;;) {
@@ -196,7 +202,7 @@ static int ast_makesocket(void)
}
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_LOCAL;
strncpy(sun.sun_path, AST_SOCKET, sizeof(sun.sun_path));
strncpy(sun.sun_path, AST_SOCKET, sizeof(sun.sun_path)-1);
res = bind(ast_socket, (struct sockaddr *)&sun, sizeof(sun));
if (res) {
ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", AST_SOCKET, strerror(errno));
@@ -227,7 +233,7 @@ static int ast_tryconnect(void)
}
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_LOCAL;
strncpy(sun.sun_path, AST_SOCKET, sizeof(sun.sun_path));
strncpy(sun.sun_path, AST_SOCKET, sizeof(sun.sun_path)-1);
res = connect(ast_consock, (struct sockaddr *)&sun, sizeof(sun));
if (res) {
close(ast_consock);
@@ -296,9 +302,55 @@ static int set_priority(int pri)
return 0;
}
static void quit_handler(int num)
static char *_argv[256];
static int shuttingdown = 0;
static void quit_handler(int num, int nice, int safeshutdown, int restart)
{
char filename[80] = "";
time_t s,e;
int x;
if (safeshutdown) {
shuttingdown = 1;
if (!nice) {
/* Begin shutdown routine, hanging up active channels */
ast_begin_shutdown(1);
if (option_verbose && option_console)
ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
time(&s);
for(;;) {
time(&e);
/* Wait up to 15 seconds for all channels to go away */
if ((e - s) > 15)
break;
if (!ast_active_channels())
break;
if (!shuttingdown)
break;
/* Sleep 1/10 of a second */
usleep(100000);
}
} else {
if (nice < 2)
ast_begin_shutdown(0);
if (option_verbose && option_console)
ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
for(;;) {
if (!ast_active_channels())
break;
if (!shuttingdown)
break;
sleep(1);
}
}
if (!shuttingdown) {
if (option_verbose && option_console)
ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
return;
}
}
if (option_console || option_remote) {
if (getenv("HOME"))
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
@@ -308,7 +360,7 @@ static void quit_handler(int num)
}
/* Called on exit */
if (option_verbose && option_console)
ast_verbose("Asterisk ending (%d).\n", num);
ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
else if (option_debug)
ast_log(LOG_DEBUG, "Asterisk ending (%d).\n", num);
if (ast_socket > -1)
@@ -317,18 +369,51 @@ static void quit_handler(int num)
close(ast_consock);
if (ast_socket > -1)
unlink(AST_SOCKET);
exit(0);
printf(term_quit());
if (restart) {
if (option_verbose || option_console)
ast_verbose("Preparing for Asterisk restart...\n");
/* Mark all FD's for closing on exec */
for (x=3;x<32768;x++) {
fcntl(x, F_SETFD, FD_CLOEXEC);
}
if (option_verbose || option_console)
ast_verbose("Restarting Asterisk NOW...\n");
execvp(_argv[0], _argv);
} else
exit(0);
}
static void __quit_handler(int num)
{
quit_handler(num, 0, 1, 0);
}
static pthread_t consolethread = -1;
static int fix_header(char *outbuf, int maxout, char **s, char *cmp)
{
if (!strncmp(*s, cmp, strlen(cmp))) {
*s += strlen(cmp);
term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
return 1;
}
return 0;
}
static void console_verboser(char *s, int pos, int replace, int complete)
{
char tmp[80];
/* Return to the beginning of the line */
if (!pos)
if (!pos) {
fprintf(stdout, "\r");
fprintf(stdout, s + pos);
if (fix_header(tmp, sizeof(tmp), &s, VERBOSE_PREFIX_4) ||
fix_header(tmp, sizeof(tmp), &s, VERBOSE_PREFIX_3) ||
fix_header(tmp, sizeof(tmp), &s, VERBOSE_PREFIX_2) ||
fix_header(tmp, sizeof(tmp), &s, VERBOSE_PREFIX_1))
fputs(tmp, stdout);
}
fputs(s + pos,stdout);
fflush(stdout);
if (complete)
/* Wake up a select()ing console */
@@ -337,6 +422,8 @@ static void console_verboser(char *s, int pos, int replace, int complete)
static void consolehandler(char *s)
{
printf(term_end());
fflush(stdout);
/* Called when readline data is available */
if (s && strlen(s))
add_history(s);
@@ -371,11 +458,11 @@ static void remoteconsolehandler(char *s)
else
system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
} else
strncpy(cmd, s, sizeof(cmd));
strncpy(cmd, s, sizeof(cmd)-1);
if (!strcasecmp(s, "help"))
fprintf(stdout, " !<command> Executes a given shell command\n");
if (!strcasecmp(s, "quit"))
quit_handler(0);
quit_handler(0, 0, 0, 0);
} else
fprintf(stdout, "\nUse \"quit\" to exit\n");
}
@@ -384,15 +471,88 @@ static char quit_help[] =
"Usage: quit\n"
" Exits Asterisk.\n";
static char shutdown_help[] =
"Usage: shutdown\n"
" Shuts down a running Asterisk PBX.\n";
static char abort_halt_help[] =
"Usage: abort shutdown\n"
" Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
" call operations.\n";
static char shutdown_now_help[] =
"Usage: shutdown now\n"
" Shuts down a running Asterisk immediately, hanging up all active calls .\n";
static char shutdown_gracefully_help[] =
"Usage: shutdown gracefully\n"
" Causes Asterisk to not accept new calls, and exit when all\n"
" active calls have terminated normally.\n";
static char restart_now_help[] =
"Usage: restart now\n"
" Causes Asterisk to hangup all calls and exec() itself performing a cold.\n"
" restart.\n";
static char restart_gracefully_help[] =
"Usage: restart gracefully\n"
" Causes Asterisk to stop accepting new calls and exec() itself performing a cold.\n"
" restart when all active calls have ended.\n";
static char restart_when_convenient_help[] =
"Usage: restart when convenient\n"
" Causes Asterisk to perform a cold restart when all active calls have ended.\n";
static int handle_quit(int fd, int argc, char *argv[])
{
if (argc != 1)
return RESULT_SHOWUSAGE;
quit_handler(0);
quit_handler(0, 0, 1, 0);
return RESULT_SUCCESS;
}
static int handle_shutdown_now(int fd, int argc, char *argv[])
{
if (argc != 2)
return RESULT_SHOWUSAGE;
quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */);
return RESULT_SUCCESS;
}
static int handle_shutdown_gracefully(int fd, int argc, char *argv[])
{
if (argc != 2)
return RESULT_SHOWUSAGE;
quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */);
return RESULT_SUCCESS;
}
static int handle_restart_now(int fd, int argc, char *argv[])
{
if (argc != 2)
return RESULT_SHOWUSAGE;
quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */);
return RESULT_SUCCESS;
}
static int handle_restart_gracefully(int fd, int argc, char *argv[])
{
if (argc != 2)
return RESULT_SHOWUSAGE;
quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */);
return RESULT_SUCCESS;
}
static int handle_restart_when_convenient(int fd, int argc, char *argv[])
{
if (argc != 3)
return RESULT_SHOWUSAGE;
quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */);
return RESULT_SUCCESS;
}
static int handle_abort_halt(int fd, int argc, char *argv[])
{
if (argc != 2)
return RESULT_SHOWUSAGE;
ast_cancel_shutdown();
shuttingdown = 0;
return RESULT_SUCCESS;
}
@@ -400,9 +560,15 @@ static int handle_quit(int fd, int argc, char *argv[])
#define ASTERISK_PROMPT2 "%s*CLI> "
static struct ast_cli_entry aborthalt = { { "abort", "halt", NULL }, handle_abort_halt, "Cancel a running halt", abort_halt_help };
static struct ast_cli_entry quit = { { "quit", NULL }, handle_quit, "Exit Asterisk", quit_help };
static struct ast_cli_entry astshutdown = { { "shutdown", NULL }, handle_quit, "Shut down an Asterisk PBX", shutdown_help };
static struct ast_cli_entry astshutdownnow = { { "shutdown", "now", NULL }, handle_shutdown_now, "Shut down Asterisk imediately", shutdown_now_help };
static struct ast_cli_entry astshutdowngracefully = { { "shutdown", "gracefully", NULL }, handle_shutdown_gracefully, "Gracefully shut down Asterisk", shutdown_gracefully_help };
static struct ast_cli_entry astrestartnow = { { "restart", "now", NULL }, handle_restart_now, "Restart Asterisk immediately", restart_now_help };
static struct ast_cli_entry astrestartgracefully = { { "restart", "gracefully", NULL }, handle_restart_gracefully, "Restart Asterisk gracefully", restart_gracefully_help };
static struct ast_cli_entry astrestartwhenconvenient= { { "restart", "when", "convenient", NULL }, handle_restart_when_convenient, "Restart Asterisk at empty call volume", restart_when_convenient_help };
static char *cli_generator(char *text, int state)
{
@@ -441,6 +607,8 @@ static void ast_remotecontrol(char * data)
char *cpid;
char *version;
int pid;
int lastclear=0;
int oldstatus=0;
char tmp[80];
read(ast_consock, buf, sizeof(buf));
if (data) {
@@ -465,8 +633,10 @@ static void ast_remotecontrol(char * data)
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
if (strlen(filename))
read_history(filename);
ast_cli_register(&quit);
ast_cli_register(&astshutdown);
ast_cli_register(&quit);
#if 0
ast_cli_register(&astshutdown);
#endif
rl_callback_handler_install(tmp, remoteconsolehandler);
rl_completion_entry_function = (Function *)console_cli_generator;
for(;;) {
@@ -499,6 +669,18 @@ static void ast_remotecontrol(char * data)
if (res < 1)
break;
buf[res] = 0;
/* If someone asks for a pass code, hide the password */
if (!memcmp(buf, ">>>>", 4)) {
printf("Ooh, i should hide password!\n");
if (!lastclear) {
oldstatus = ast_hide_password(STDIN_FILENO);
printf("Oldstatus = %d\n", oldstatus);
}
lastclear = 1;
} else if (lastclear) {
ast_restore_tty(STDIN_FILENO, oldstatus);
lastclear = 0;
}
if (!lastpos)
write(STDOUT_FILENO, "\r", 2);
write(STDOUT_FILENO, buf, res);
@@ -521,14 +703,27 @@ int main(int argc, char *argv[])
int pid;
char filename[80] = "";
char hostname[256];
char tmp[80];
char * xarg = NULL;
int x;
sigset_t sigs;
/* Remember original args for restart */
if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) {
fprintf(stderr, "Truncating argument size to %d\n", sizeof(_argv) / sizeof(_argv[0]) - 1);
argc = sizeof(_argv) / sizeof(_argv[0]) - 1;
}
for (x=0;x<argc;x++)
_argv[x] = argv[x];
_argv[x] = NULL;
if (gethostname(hostname, sizeof(hostname)))
strncpy(hostname, "<Unknown>", sizeof(hostname));
strncpy(hostname, "<Unknown>", sizeof(hostname)-1);
mainpid = getpid();
ast_ulaw_init();
ast_alaw_init();
callerid_init();
tdd_init();
if (getenv("HOME"))
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
/* Check if we're root */
@@ -537,7 +732,7 @@ int main(int argc, char *argv[])
exit(1);
}
/* Check for options */
while((c=getopt(argc, argv, "fdvqprcx:")) != EOF) {
while((c=getopt(argc, argv, "fdvqprcinx:")) != EOF) {
switch(c) {
case 'd':
option_debug++;
@@ -550,6 +745,9 @@ int main(int argc, char *argv[])
case 'f':
option_nofork++;
break;
case 'n':
option_nocolor++;
break;
case 'r':
option_remote++;
option_nofork++;
@@ -568,43 +766,56 @@ int main(int argc, char *argv[])
option_exec++;
xarg = optarg;
break;
case 'i':
option_initcrypto++;
break;
case '?':
exit(1);
}
}
term_init();
printf(term_end());
fflush(stdout);
if (ast_tryconnect()) {
/* One is already running */
if (option_remote) {
if (option_exec) {
ast_remotecontrol(xarg);
quit_handler(0);
quit_handler(0, 0, 0, 0);
exit(0);
}
printf(term_quit());
ast_register_verbose(console_verboser);
ast_verbose( "Asterisk " ASTERISK_VERSION ", Copyright (C) 1999-2001 Linux Support Services, Inc.\n");
ast_verbose( "Written by Mark Spencer <markster@linux-support.net>\n");
ast_verbose( "=========================================================================\n");
ast_remotecontrol(NULL);
quit_handler(0);
quit_handler(0, 0, 0, 0);
exit(0);
} else {
ast_log(LOG_ERROR, "Asterisk already running on %s. Use 'asterisk -r' to connect.\n", AST_SOCKET);
printf(term_quit());
exit(1);
}
} else if (option_remote || option_exec) {
ast_log(LOG_ERROR, "Unable to connect to remote asterisk\n");
printf(term_quit());
exit(1);
}
if (!option_verbose && !option_console && !option_debug) {
if (!option_verbose && !option_debug && !option_nofork && !option_console) {
pid = fork();
if (pid < 0) {
ast_log(LOG_ERROR, "Unable to fork(): %s\n", strerror(errno));
printf(term_quit());
exit(1);
}
if (pid)
exit(0);
}
ast_makesocket();
sigemptyset(&sigs);
sigaddset(&sigs, SIGHUP);
@@ -624,31 +835,48 @@ int main(int argc, char *argv[])
if (option_console && !option_verbose)
ast_verbose("[ Booting...");
signal(SIGURG, urg_handler);
signal(SIGINT, quit_handler);
signal(SIGTERM, quit_handler);
signal(SIGINT, __quit_handler);
signal(SIGTERM, __quit_handler);
signal(SIGHUP, hup_handler);
signal(SIGPIPE, pipe_handler);
if (set_priority(option_highpriority))
if (set_priority(option_highpriority)) {
printf(term_quit());
exit(1);
if (init_logger())
}
if (init_logger()) {
printf(term_quit());
exit(1);
if (ast_image_init())
}
if (ast_image_init()) {
printf(term_quit());
exit(1);
if (load_pbx())
}
if (load_pbx()) {
printf(term_quit());
exit(1);
if (load_modules())
}
if (load_modules()) {
printf(term_quit());
exit(1);
if (init_framer())
}
if (init_framer()) {
printf(term_quit());
exit(1);
}
/* We might have the option of showing a console, but for now just
do nothing... */
if (option_console && !option_verbose)
ast_verbose(" ]\n");
if (option_verbose || option_console)
ast_verbose( "Asterisk Ready.\n");
ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
fully_booted = 1;
pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
ast_cli_register(&astshutdown);
ast_cli_register(&astshutdownnow);
ast_cli_register(&astshutdowngracefully);
ast_cli_register(&astrestartnow);
ast_cli_register(&astrestartgracefully);
ast_cli_register(&astrestartwhenconvenient);
ast_cli_register(&aborthalt);
if (option_console) {
/* Console stuff now... */
/* Register our quit function */
@@ -660,21 +888,25 @@ int main(int argc, char *argv[])
consolethread = pthread_self();
if (strlen(filename))
read_history(filename);
rl_callback_handler_install(ASTERISK_PROMPT, consolehandler);
term_prompt(tmp, ASTERISK_PROMPT, sizeof(tmp));
rl_callback_handler_install(tmp, consolehandler);
rl_completion_entry_function = (Function *)cli_generator;
for(;;) {
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
res = select(STDIN_FILENO + 1, &rfds, NULL, NULL, NULL);
if (res > 0) {
printf(term_prep());
rl_callback_read_char();
printf(term_end());
fflush(stdout);
} else if (res < 1) {
rl_forced_update_display();
}
}
} else {
/* Do nothing */
/* Do nothing */
select(0,NULL,NULL,NULL,NULL);
}
return 0;

View File

@@ -23,6 +23,7 @@
#define AST_VAR_DIR "/var/lib/asterisk"
#define AST_LOG_DIR "/var/log/asterisk"
#define AST_AGI_DIR "/var/lib/asterisk/agi-bin"
#define AST_KEY_DIR "/var/lib/asterisk/keys"
#define AST_CONFIG_FILE "asterisk.conf"
@@ -37,4 +38,8 @@ extern int load_pbx(void);
extern int init_logger(void);
/* Provided by frame.c */
extern int init_framer(void);
/* Provided by logger.c */
extern int reload_logger(void);
/* Provided by term.c */
extern int term_init(void);
#endif

47
astgenkey Normal file
View File

@@ -0,0 +1,47 @@
#!/bin/sh
#
# Usage: astgenkey [ -q ] [keyname]
#
if [ "$1" = "-q" ]; then
QUIET='y'
KEY=$2
else
KEY=$1
fi
if [ "$QUIET" != 'y' ]; then
echo ""
echo "This script generates an RSA private and public key pair"
echo "in PEM format for use by Asterisk. You will be asked to"
echo "enter a passcode for your key multiple times. Please"
echo "enter the same code each time. The resulting files will"
echo "need to be moved to /var/lib/asterisk/keys if you want"
echo "to use them, and any private keys (.key files) will"
echo "need to be initialized at runtime either by running"
echo "Asterisk with the '-i' option, or with the 'init keys'"
echo "command once Asterisk is running."
echo ""
echo "Press ENTER to continue or ^C to cancel."
read BLAH
fi
while [ "$KEY" = "" ]; do
echo -n "Enter key name: "
read KEY
done
rm -f ${KEY}.key ${KEY}.pub
echo "Generating SSL key '$KEY': "
openssl genrsa -out ${KEY}.key -des3 1024
openssl rsa -in ${KEY}.key -pubout -out ${KEY}.pub
if [ -f "${KEY}.key" ] && [ -f "${KEY}.pub" ]; then
if [ "$QUIET" != 'y' ]; then
echo "Key creation successful."
echo "Public key: ${KEY}.pub"
echo "Private key: ${KEY}.key"
fi
else
echo "Unknown error creating keys."
fi

View File

@@ -43,8 +43,9 @@ struct callerid_state {
int len;
};
static float dr[4], di[4];
static float clidsb = 8000.0 / 1200.0;
float cid_dr[4], cid_di[4];
float clidsb = 8000.0 / 1200.0;
#define CALLERID_SPACE 2200.0 /* 2200 hz for "0" */
#define CALLERID_MARK 1200.0 /* 1200 hz for "1" */
@@ -52,10 +53,10 @@ static float clidsb = 8000.0 / 1200.0;
void callerid_init(void)
{
/* Initialize stuff for inverse FFT */
dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0);
di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0);
cid_dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
cid_di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
cid_dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0);
cid_di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0);
}
struct callerid_state *callerid_new(void)
@@ -98,21 +99,23 @@ void callerid_get(struct callerid_state *cid, char **name, char **number, int *f
*number = cid->number;
}
int ast_callerid_gen_cas(unsigned char *outbuf, int len)
int ast_gen_cas(unsigned char *outbuf, int sendsas, int len)
{
int pos = 0;
int cnt;
int saslen=2400;
if (len < saslen)
return -1;
while(saslen) {
cnt = saslen;
if (cnt > sizeof(sas))
cnt = sizeof(sas);
memcpy(outbuf + pos, sas, cnt);
pos += cnt;
len -= cnt;
saslen -= cnt;
if (sendsas) {
if (len < saslen)
return -1;
while(saslen) {
cnt = saslen;
if (cnt > sizeof(sas))
cnt = sizeof(sas);
memcpy(outbuf + pos, sas, cnt);
pos += cnt;
len -= cnt;
saslen -= cnt;
}
}
while(len) {
cnt = len;
@@ -142,7 +145,7 @@ int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len)
memcpy(buf, cid->oldstuff, cid->oldlen);
mylen += cid->oldlen/2;
for (x=0;x<len;x++)
buf[x+cid->oldlen/2] = ast_mulaw[ubuf[x]];
buf[x+cid->oldlen/2] = AST_MULAW(ubuf[x]);
while(mylen >= 80) {
olen = mylen;
res = fsk_serie(&cid->fskd, buf, &mylen, &b);
@@ -239,7 +242,7 @@ int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len)
}
} else {
/* SDMF */
strncpy(cid->number, cid->rawdata + 8, sizeof(cid->number));
strncpy(cid->number, cid->rawdata + 8, sizeof(cid->number)-1);
}
/* Update flags */
cid->flags = 0;
@@ -346,57 +349,6 @@ static void callerid_genmsg(char *msg, int size, char *number, char *name, int f
}
static inline float callerid_getcarrier(float *cr, float *ci, int bit)
{
/* Move along. There's nothing to see here... */
float t;
t = *cr * dr[bit] - *ci * di[bit];
*ci = *cr * di[bit] + *ci * dr[bit];
*cr = t;
t = 2.0 - (*cr * *cr + *ci * *ci);
*cr *= t;
*ci *= t;
return *cr;
}
#define PUT_BYTE(a) do { \
*(buf++) = (a); \
bytes++; \
} while(0)
#define PUT_AUDIO_SAMPLE(y) do { \
int index = (short)(rint(8192.0 * (y))); \
*(buf++) = ast_lin2mu[index + 32768]; \
bytes++; \
} while(0)
#define PUT_CLID_MARKMS do { \
int x; \
for (x=0;x<8;x++) \
PUT_AUDIO_SAMPLE(callerid_getcarrier(&cr, &ci, 1)); \
} while(0)
#define PUT_CLID_BAUD(bit) do { \
while(scont < clidsb) { \
PUT_AUDIO_SAMPLE(callerid_getcarrier(&cr, &ci, bit)); \
scont += 1.0; \
} \
scont -= clidsb; \
} while(0)
#define PUT_CLID(byte) do { \
int z; \
unsigned char b = (byte); \
PUT_CLID_BAUD(0); /* Start bit */ \
for (z=0;z<8;z++) { \
PUT_CLID_BAUD(b & 1); \
b >>= 1; \
} \
PUT_CLID_BAUD(1); /* Stop bit */ \
} while(0);
int callerid_generate(unsigned char *buf, char *number, char *name, int flags, int callwaiting)
{
int bytes=0;
@@ -486,7 +438,7 @@ int ast_callerid_parse(char *instr, char **name, char **location)
return 0;
}
} else {
strncpy(tmp, instr, sizeof(tmp));
strncpy(tmp, instr, sizeof(tmp)-1);
ast_shrink_phone_number(tmp);
if (ast_isphonenumber(tmp)) {
/* Assume it's just a location */
@@ -508,7 +460,7 @@ static int __ast_callerid_generate(unsigned char *buf, char *callerid, int callw
char *n, *l;
if (!callerid)
return callerid_generate(buf, NULL, NULL, 0, callwaiting);
strncpy(tmp, callerid, sizeof(tmp));
strncpy(tmp, callerid, sizeof(tmp)-1);
if (ast_callerid_parse(tmp, &n, &l)) {
ast_log(LOG_WARNING, "Unable to parse '%s' into CallerID name & number\n", callerid);
return callerid_generate(buf, NULL, NULL, 0, callwaiting);

313
cdr.c Normal file
View File

@@ -0,0 +1,313 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Call Detail Record API
*
* 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.
*
* Includes code and algorithms from the Zapata library.
*
*/
#include <asterisk/lock.h>
#include <asterisk/channel.h>
#include <asterisk/cdr.h>
#include <asterisk/logger.h>
#include <asterisk/callerid.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
int ast_default_amaflags = AST_CDR_DOCUMENTATION;
char ast_default_accountcode[20] = "";
static pthread_mutex_t cdrlock = AST_MUTEX_INITIALIZER;
static struct ast_cdr_beitem {
char name[20];
char desc[80];
ast_cdrbe be;
struct ast_cdr_beitem *next;
} *bes = NULL;
/*
* We do a lot of checking here in the CDR code to try to be sure we don't ever let a CDR slip
* through our fingers somehow. If someone allocates a CDR, it must be completely handled normally
* or a WARNING shall be logged, so that we can best keep track of any escape condition where the CDR
* isn't properly generated and posted.
*/
int ast_cdr_register(char *name, char *desc, ast_cdrbe be)
{
struct ast_cdr_beitem *i;
if (!name)
return -1;
if (!be) {
ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
return -1;
}
ast_pthread_mutex_lock(&cdrlock);
i = bes;
while(i) {
if (!strcasecmp(name, i->name))
break;
i = i->next;
}
ast_pthread_mutex_unlock(&cdrlock);
if (i) {
ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
return -1;
}
i = malloc(sizeof(struct ast_cdr_beitem));
if (!i)
return -1;
memset(i, 0, sizeof(struct ast_cdr_beitem));
strncpy(i->name, name, sizeof(i->name) - 1);
strncpy(i->desc, desc, sizeof(i->desc) - 1);
i->be = be;
ast_pthread_mutex_lock(&cdrlock);
i->next = bes;
bes = i;
ast_pthread_mutex_unlock(&cdrlock);
return 0;
}
void ast_cdr_unregister(char *name)
{
struct ast_cdr_beitem *i, *prev = NULL;
ast_pthread_mutex_lock(&cdrlock);
i = bes;
while(i) {
if (!strcasecmp(name, i->name)) {
if (prev)
prev->next = i->next;
else
bes = i->next;
break;
}
i = i->next;
}
ast_pthread_mutex_unlock(&cdrlock);
if (i)
free(i);
}
void ast_cdr_free(struct ast_cdr *cdr)
{
char *chan;
if (cdr) {
chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
if (!cdr->posted)
ast_log(LOG_WARNING, "CDR on channel '%s' not posted\n", chan);
if (!cdr->end.tv_sec && !cdr->end.tv_usec)
ast_log(LOG_WARNING, "CDR on channel '%s' lacks end\n", chan);
if (!cdr->start.tv_sec && !cdr->start.tv_usec)
ast_log(LOG_WARNING, "CDR on channel '%s' lacks start\n", chan);
free(cdr);
}
}
struct ast_cdr *ast_cdr_alloc(void)
{
struct ast_cdr *cdr;
cdr = malloc(sizeof(struct ast_cdr));
if (cdr) {
memset(cdr, 0, sizeof(struct ast_cdr));
}
return cdr;
}
void ast_cdr_start(struct ast_cdr *cdr)
{
char *chan;
if (cdr) {
chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
if (cdr->posted)
ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
if (cdr->start.tv_sec || cdr->start.tv_usec)
ast_log(LOG_WARNING, "CDR on channel '%s' already started\n", chan);
gettimeofday(&cdr->start, NULL);
}
}
void ast_cdr_answer(struct ast_cdr *cdr)
{
char *chan;
if (cdr) {
chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
if (cdr->posted)
ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
if (cdr->disposition < AST_CDR_ANSWERED)
cdr->disposition = AST_CDR_ANSWERED;
if (!cdr->answer.tv_sec && !cdr->answer.tv_usec) {
gettimeofday(&cdr->answer, NULL);
}
}
}
void ast_cdr_busy(struct ast_cdr *cdr)
{
char *chan;
if (cdr) {
chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
if (cdr->posted)
ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
if (cdr->disposition < AST_CDR_BUSY)
cdr->disposition = AST_CDR_BUSY;
}
}
void ast_cdr_setdestchan(struct ast_cdr *cdr, char *chann)
{
char *chan;
if (cdr) {
chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
if (cdr->posted)
ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
strncpy(cdr->dstchannel, chann, sizeof(cdr->dstchannel) - 1);
}
}
void ast_cdr_setapp(struct ast_cdr *cdr, char *app, char *data)
{
char *chan;
if (cdr) {
chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
if (cdr->posted)
ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
if (!app)
app = "";
strncpy(cdr->lastapp, app, sizeof(cdr->lastapp) - 1);
if (!data)
data = "";
strncpy(cdr->lastdata, data, sizeof(cdr->lastdata) - 1);
}
}
int ast_cdr_init(struct ast_cdr *cdr, struct ast_channel *c)
{
char *chan;
char *num, *name;
char tmp[AST_MAX_EXTENSION];
if (cdr) {
chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
if (strlen(cdr->channel))
ast_log(LOG_WARNING, "CDR already initialized on '%s'\n", chan);
strncpy(cdr->channel, c->name, sizeof(cdr->channel) - 1);
/* Grab source from ANI or normal Caller*ID */
if (c->ani)
strncpy(tmp, c->ani, sizeof(tmp) - 1);
else if (c->callerid)
strncpy(tmp, c->callerid, sizeof(tmp) - 1);
if (c->callerid)
strncpy(cdr->clid, c->callerid, sizeof(cdr->clid) - 1);
name = NULL;
num = NULL;
ast_callerid_parse(tmp, &name, &num);
if (num) {
ast_shrink_phone_number(num);
strncpy(cdr->src, num, sizeof(cdr->src) - 1);
}
if (c->state == AST_STATE_UP)
cdr->disposition = AST_CDR_ANSWERED;
else
cdr->disposition = AST_CDR_NOANSWER;
if (c->amaflags)
cdr->amaflags = c->amaflags;
else
cdr->amaflags = ast_default_amaflags;
strncpy(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode) - 1);
/* Destination information */
strncpy(cdr->dst, c->exten, sizeof(cdr->dst) - 1);
strncpy(cdr->dcontext, c->context, sizeof(cdr->dcontext) - 1);
}
return 0;
}
void ast_cdr_end(struct ast_cdr *cdr)
{
char *chan;
if (cdr) {
chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
if (cdr->posted)
ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
if (!cdr->start.tv_sec && !cdr->start.tv_usec)
ast_log(LOG_WARNING, "CDR on channel '%s' has not started\n", chan);
if (!cdr->end.tv_sec && !cdr->end.tv_usec)
gettimeofday(&cdr->end, NULL);
}
}
char *ast_cdr_disp2str(int disposition)
{
switch (disposition) {
case AST_CDR_NOANSWER:
return "NO ANSWER";
case AST_CDR_BUSY:
return "BUSY";
case AST_CDR_ANSWERED:
return "ANSWERED";
default:
return "UNKNOWN";
}
}
char *ast_cdr_flags2str(int flag)
{
switch(flag) {
case AST_CDR_OMIT:
return "OMIT";
case AST_CDR_BILLING:
return "BILLING";
case AST_CDR_DOCUMENTATION:
return "DOCUMENTATION";
}
return "Unknown";
}
int ast_cdr_amaflags2int(char *flag)
{
if (!strcasecmp(flag, "default"))
return 0;
if (!strcasecmp(flag, "omit"))
return AST_CDR_OMIT;
if (!strcasecmp(flag, "billing"))
return AST_CDR_BILLING;
if (!strcasecmp(flag, "documentation"))
return AST_CDR_DOCUMENTATION;
return -1;
}
void ast_cdr_post(struct ast_cdr *cdr)
{
char *chan;
struct ast_cdr_beitem *i;
if (cdr) {
chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
if (cdr->posted)
ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
if (!cdr->end.tv_sec && !cdr->end.tv_usec)
ast_log(LOG_WARNING, "CDR on channel '%s' lacks end\n", chan);
if (!cdr->start.tv_sec && !cdr->start.tv_usec)
ast_log(LOG_WARNING, "CDR on channel '%s' lacks start\n", chan);
cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec + (cdr->end.tv_usec - cdr->start.tv_usec) / 1000000;
if (cdr->answer.tv_sec || cdr->answer.tv_usec) {
cdr->billsec = cdr->end.tv_sec - cdr->answer.tv_sec + (cdr->end.tv_usec - cdr->answer.tv_usec) / 1000000;
} else
cdr->billsec = 0;
cdr->posted = 1;
ast_pthread_mutex_lock(&cdrlock);
i = bes;
while(i) {
i->be(cdr);
i = i->next;
}
ast_pthread_mutex_unlock(&cdrlock);
}
}

43
cdr/Makefile Normal file
View File

@@ -0,0 +1,43 @@
#
# Asterisk -- A telephony toolkit for Linux.
#
# Makefile for CDR backends (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
#
MODS=cdr_csv.so
CFLAGS+=
#
# MySQL stuff... Autoconf anyone??
#
MODS+=$(shell if [ -d /usr/lib/mysql ] || \
[`ls /usr/lib/libmysqlclient.so* 2>/dev/null | wc -l` -gt 0 ] || \
[`ls /usr/local/lib/libmysqlclient.so* 2>/dev/null | wc -l` -gt 0 ] \
; then echo "cdr_mysql.so" ; fi)
CFLAGS+=$(shell if [ -d /usr/include/mysql ]; then echo "-I/usr/include/mysql"; fi)
CFLAGS+=$(shell if [ -d /usr/local/include/mysql ]; then echo "-I/usr/local/include/mysql"; fi)
MLFLAGS=
MLFLAGS+=$(shell if [ -d /usr/lib/mysql ]; then echo "-L/usr/lib/mysql"; fi)
MLFLAGS+=$(shell if [ -d /usr/local/lib/mysql ]; then echo "-L/usr/local/lib/mysql"; fi)
all: $(MODS)
install: all
for x in $(MODS); do $(INSTALL) -m 755 $$x $(MODULES_DIR) ; done
clean:
rm -f *.so *.o
%.so : %.o
$(CC) -shared -Xlinker -x -o $@ $<
cdr_mysql.so: cdr_mysql.o
$(CC) -shared -Xlinker -x -o $@ $< -lmysqlclient $(MLFLAGS)

253
cdr/cdr_csv.c Normal file
View File

@@ -0,0 +1,253 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Comma Separated Value CDR records.
*
* 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.
*
* Includes code and algorithms from the Zapata library.
*
*/
#include <asterisk/channel.h>
#include <asterisk/cdr.h>
#include <asterisk/module.h>
#include <asterisk/logger.h>
#include "../asterisk.h"
#define CSV_LOG_DIR AST_LOG_DIR "/cdr-csv"
#define CSV_MASTER CSV_LOG_DIR "/Master.csv"
#define DATE_FORMAT "%Y-%m-%d %T"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
/* The values are as follows:
"accountcode",
"source",
"destination",
"destination context",
"callerid",
"channel",
"destination channel", (if applicable)
"last application",
"last app argument",
"start time",
"answer time",
"end time",
duration,
billable seconds,
"disposition",
"amaflags",
*/
static char *desc = "Comma Separated Values CDR Backend";
static char *name = "csv";
static FILE *mf = NULL;
static int append_string(char *buf, char *s, int len)
{
int pos = strlen(buf);
int spos = 0;
int error = 0;
if (pos >= len - 4)
return -1;
buf[pos++] = '\"';
error = -1;
while(pos < len - 3) {
if (!s[spos]) {
error = 0;
break;
}
if (s[spos] == '\"')
buf[pos++] = '\"';
buf[pos++] = s[spos];
spos++;
}
buf[pos++] = '\"';
buf[pos++] = ',';
buf[pos++] = '\0';
return error;
}
static int append_int(char *buf, int s, int len)
{
char tmp[32];
int pos = strlen(buf);
snprintf(tmp, sizeof(tmp), "%d", s);
if (pos + strlen(tmp) > len - 3)
return -1;
strncat(buf, tmp, len);
pos = strlen(buf);
buf[pos++] = ',';
buf[pos++] = '\0';
return 0;
}
static int append_date(char *buf, struct timeval tv, int len)
{
char tmp[80];
struct tm *tm;
time_t t;
t = tv.tv_sec;
if (strlen(buf) > len - 3)
return -1;
if (!tv.tv_sec && !tv.tv_usec) {
strncat(buf, ",", len);
return 0;
}
tm = localtime(&t);
strftime(tmp, sizeof(tmp), DATE_FORMAT, tm);
return append_string(buf, tmp, len);
}
static int build_csv_record(char *buf, int len, struct ast_cdr *cdr)
{
buf[0] = '\0';
/* Account code */
append_string(buf, cdr->accountcode, len);
/* Source */
append_string(buf, cdr->src, len);
/* Destination */
append_string(buf, cdr->dst, len);
/* Destination context */
append_string(buf, cdr->dcontext, len);
/* Caller*ID */
append_string(buf, cdr->clid, len);
/* Channel */
append_string(buf, cdr->channel, len);
/* Destination Channel */
append_string(buf, cdr->dstchannel, len);
/* Last Application */
append_string(buf, cdr->lastapp, len);
/* Last Data */
append_string(buf, cdr->lastdata, len);
/* Start Time */
append_date(buf, cdr->start, len);
/* Answer Time */
append_date(buf, cdr->answer, len);
/* End Time */
append_date(buf, cdr->end, len);
/* Duration */
append_int(buf, cdr->duration, len);
/* Billable seconds */
append_int(buf, cdr->billsec, len);
/* Disposition */
append_string(buf, ast_cdr_disp2str(cdr->disposition), len);
/* AMA Flags */
append_string(buf, ast_cdr_flags2str(cdr->amaflags), len);
/* If we hit the end of our buffer, log an error */
if (strlen(buf) < len - 5) {
/* Trim off trailing comma */
buf[strlen(buf) - 1] = '\0';
strncat(buf, "\n", len);
return 0;
}
return -1;
}
static int writefile(char *s, char *acc)
{
char tmp[256];
FILE *f;
if (strchr(acc, '/') || (acc[0] == '.')) {
ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n", acc);
return -1;
}
snprintf(tmp, sizeof(tmp), "%s/%s.csv", CSV_LOG_DIR, acc);
f = fopen(tmp, "a");
if (!f)
return -1;
fputs(s, f);
fclose(f);
return 0;
}
static int csv_log(struct ast_cdr *cdr)
{
/* Make sure we have a big enough buf */
char buf[1024];
#if 0
printf("[CDR] %s ('%s' -> '%s') Dur: %ds Bill: %ds Disp: %s Flags: %s Account: [%s]\n", cdr->channel, cdr->src, cdr->dst, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), cdr->accountcode);
#endif
if (build_csv_record(buf, sizeof(buf), cdr)) {
ast_log(LOG_WARNING, "Unable to create CSV record in %d bytes. CDR not recorded!\n", sizeof(buf));
} else {
/* because of the absolutely unconditional need for the
highest reliability possible in writing billing records,
we open write and close the log file each time */
mf = fopen(CSV_MASTER, "a");
if (!mf) {
ast_log(LOG_ERROR, "Unable to re-open master file %s\n", CSV_MASTER);
}
if (mf) {
fputs(buf, mf);
fflush(mf); /* be particularly anal here */
fclose(mf);
mf = NULL;
}
if (strlen(cdr->accountcode)) {
if (writefile(buf, cdr->accountcode))
ast_log(LOG_WARNING, "Unable to write CSV record to account file '%s'\n", cdr->accountcode);
}
}
return 0;
}
char *description(void)
{
return desc;
}
int unload_module(void)
{
if (mf)
fclose(mf);
ast_cdr_unregister(name);
return 0;
}
int load_module(void)
{
int res;
res = ast_cdr_register(name, desc, csv_log);
if (res) {
ast_log(LOG_ERROR, "Unable to register CSV CDR handling\n");
if (mf)
fclose(mf);
}
return res;
}
int reload(void)
{
return 0;
}
int usecount(void)
{
return 0;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

240
cdr/cdr_mysql.c Normal file
View File

@@ -0,0 +1,240 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* MySQL CDR logger
*
* James Sharp <jsharp@psychoses.org>
*
* This program is free software, distributed under the terms of
* the GNU General Public License.
*
*/
#include <asterisk/config.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/cdr.h>
#include <asterisk/module.h>
#include <asterisk/logger.h>
#include "../asterisk.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <mysql.h>
#define DATE_FORMAT "%Y-%m-%d %T"
static char *desc = "MySQL CDR Backend";
static char *name = "mysql";
static char *config = "cdr_mysql.conf";
static MYSQL *mysql;
static int mysql_log(struct ast_cdr *cdr)
{
struct tm *tm;
struct timeval *tv;
struct timezone *tz;
char *sqlcmd, *timestr;
time_t t;
tv = (struct timeval *)malloc(sizeof(struct timeval));
tz = (struct timezone *)malloc(sizeof(struct timezone));
sqlcmd = (char *)malloc(2048);
timestr = (char*)malloc(128);
memset(sqlcmd,0,2048);
gettimeofday(tv,tz);
t = tv->tv_sec;
tm = localtime(&t);
strftime(timestr,128,DATE_FORMAT,tm);
ast_log(LOG_DEBUG,"cdr_mysql: inserting a CDR record.\n");
sprintf(sqlcmd,"insert into cdr values ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%i,%i,%i,%i,'%s')",timestr,cdr->clid,cdr->src, cdr->dst, cdr->dcontext,cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata,cdr->duration,cdr->billsec,cdr->disposition,cdr->amaflags, cdr->accountcode);
ast_log(LOG_DEBUG,"cdr_mysql: SQL command as follows: %s\n",sqlcmd);
if (mysql_real_query(mysql,sqlcmd,strlen(sqlcmd)))
{
ast_log(LOG_ERROR,"Failed to insert into database.");
free(sqlcmd);
return -1;
}
free(sqlcmd);
return 0;
}
char *description(void)
{
return desc;
}
int unload_module(void)
{
mysql_close(mysql);
ast_cdr_unregister(name);
return 0;
}
int load_module(void)
{
int res;
struct ast_config *cfg;
struct ast_variable *var;
char *hostname, *dbname, *dbuser, *password;
cfg = ast_load(config);
if (!cfg) {
ast_log(LOG_WARNING, "Unable to load config for mysql CDR's: %s\n", config);
return 0;
}
var = ast_variable_browse(cfg, "global");
if (!var) {
/* nothing configured */
return 0;
}
hostname = ast_variable_retrieve(cfg,"global","hostname");
dbname = ast_variable_retrieve(cfg,"global","dbname");
dbuser = ast_variable_retrieve(cfg,"global","user");
password = ast_variable_retrieve(cfg,"global","password");
ast_log(LOG_DEBUG,"cdr_mysql: got hostname of %s\n",hostname);
ast_log(LOG_DEBUG,"cdr_mysql: got user of %s\n",dbuser);
ast_log(LOG_DEBUG,"cdr_mysql: got dbname of %s\n",dbname);
ast_log(LOG_DEBUG,"cdr_mysql: got password of %s\n",password);
if (hostname == NULL)
{
ast_log(LOG_ERROR,"Database server hostname not specified.\n");
return -1;
}
if (dbuser == NULL)
{
ast_log(LOG_ERROR,"Database dbuser not specified.\n");
return -1;
}
if (dbname == NULL)
{
ast_log(LOG_ERROR,"Database dbname not specified.\n");
return -1;
}
if (password == NULL)
{
ast_log(LOG_ERROR,"Database password not specified.\n");
return -1;
}
mysql = mysql_init(NULL);
mysql = mysql_real_connect(mysql, hostname, dbuser, password, dbname, 0, NULL, 0);
if (mysql == NULL) {
ast_log(LOG_ERROR, "Failed to connect to mysql database.\n");
return -1;
} else {
ast_log(LOG_DEBUG,"Successfully connected to MySQL database.\n");
}
res = ast_cdr_register(name, desc, mysql_log);
if (res) {
ast_log(LOG_ERROR, "Unable to register MySQL CDR handling\n");
}
return res;
}
int reload(void)
{
struct ast_config *cfg;
struct ast_variable *var;
char *hostname, *dbname, *password, *dbuser;
mysql_close(mysql);
cfg = ast_load(config);
if (!cfg) {
ast_log(LOG_WARNING, "Unable to load MySQL CDR config %s\n", config);
return 0;
}
var = ast_variable_browse(cfg, "global");
if (!var) {
/* nothing configured */
return 0;
}
hostname = ast_variable_retrieve(cfg,"global","hostname");
dbname = ast_variable_retrieve(cfg,"global","dbname");
dbuser = ast_variable_retrieve(cfg,"global","user");
password = ast_variable_retrieve(cfg,"global","password");
ast_log(LOG_DEBUG,"cdr_mysql: got hostname of %s\n",hostname);
ast_log(LOG_DEBUG,"cdr_mysql: got dbname of %s\n",dbname);
ast_log(LOG_DEBUG,"cdr_mysql: got dbuser of %s\n",dbuser);
ast_log(LOG_DEBUG,"cdr_mysql: got password of %s\n",password);
if (hostname == NULL)
{
ast_log(LOG_ERROR,"Database server hostname not specified.\n");
return -1;
}
if (dbname == NULL)
{
ast_log(LOG_ERROR,"Database dbname not specified.\n");
return -1;
}
if (dbuser == NULL)
{
ast_log(LOG_ERROR,"Database dbuser not specified.\n");
return -1;
}
if (password == NULL)
{
ast_log(LOG_ERROR,"Database password not specified.\n");
return -1;
}
mysql = mysql_init(NULL);
mysql = mysql_real_connect(mysql, hostname, dbuser, password, dbname, 0, NULL, 0);
if (mysql == NULL) {
ast_log(LOG_ERROR, "Failed to connect to mysql database.\n");
return -1;
} else {
ast_log(LOG_DEBUG,"Successfully connected to MySQL database.\n");
}
return 0;
}
int usecount(void)
{
return 0;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

570
channel.c
View File

@@ -18,7 +18,10 @@
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <asterisk/lock.h>
#include <unistd.h>
#include <math.h> /* For PI */
#include <asterisk/frame.h>
#include <asterisk/sched.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
@@ -27,6 +30,7 @@
#include <asterisk/file.h>
#include <asterisk/translate.h>
static int shutting_down = 0;
/* XXX Lock appropriately in more functions XXX */
@@ -61,7 +65,70 @@ struct ast_channel *channels = NULL;
/* Protect the channel list (highly unlikely that two things would change
it at the same time, but still! */
static pthread_mutex_t chlock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t chlock = AST_MUTEX_INITIALIZER;
int ast_check_hangup(struct ast_channel *chan)
{
time_t myt;
/* if soft hangup flag, return true */
if (chan->softhangup) return 1;
/* if no hangup scheduled, just return here */
if (!chan->whentohangup) return 0;
time(&myt); /* get current time */
/* return, if not yet */
if (chan->whentohangup > myt) return 0;
chan->softhangup = 1;
return 1;
}
void ast_begin_shutdown(int hangup)
{
struct ast_channel *c;
shutting_down = 1;
if (hangup) {
PTHREAD_MUTEX_LOCK(&chlock);
c = channels;
while(c) {
c->softhangup = 1;
c = c->next;
}
PTHREAD_MUTEX_UNLOCK(&chlock);
}
}
int ast_active_channels(void)
{
struct ast_channel *c;
int cnt = 0;
PTHREAD_MUTEX_LOCK(&chlock);
c = channels;
while(c) {
cnt++;
c = c->next;
}
PTHREAD_MUTEX_UNLOCK(&chlock);
return cnt;
}
void ast_cancel_shutdown(void)
{
shutting_down = 0;
}
int ast_shutting_down(void)
{
return shutting_down;
}
void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
{
time_t myt;
time(&myt);
chan->whentohangup = myt + offset;
return;
}
int ast_channel_register(char *type, char *description, int capabilities,
struct ast_channel *(*requester)(char *type, int format, void *data))
@@ -87,8 +154,8 @@ int ast_channel_register(char *type, char *description, int capabilities,
PTHREAD_MUTEX_UNLOCK(&chlock);
return -1;
}
strncpy(chan->type, type, sizeof(chan->type));
strncpy(chan->description, description, sizeof(chan->description));
strncpy(chan->type, type, sizeof(chan->type)-1);
strncpy(chan->description, description, sizeof(chan->description)-1);
chan->capabilities = capabilities;
chan->requester = requester;
chan->next = NULL;
@@ -164,11 +231,15 @@ int ast_best_codec(int fmts)
return 0;
}
struct ast_channel *ast_channel_alloc(void)
struct ast_channel *ast_channel_alloc(int needqueue)
{
struct ast_channel *tmp;
struct ast_channel_pvt *pvt;
int x;
int flags;
/* If shutting down, don't allocate any new channels */
if (shutting_down)
return NULL;
PTHREAD_MUTEX_LOCK(&chlock);
tmp = malloc(sizeof(struct ast_channel));
memset(tmp, 0, sizeof(struct ast_channel));
@@ -178,22 +249,43 @@ struct ast_channel *ast_channel_alloc(void)
memset(pvt, 0, sizeof(struct ast_channel_pvt));
tmp->sched = sched_context_create();
if (tmp->sched) {
for (x=0;x<AST_MAX_FDS;x++)
for (x=0;x<AST_MAX_FDS - 1;x++)
tmp->fds[x] = -1;
strncpy(tmp->name, "**Unknown**", sizeof(tmp->name));
tmp->pvt = pvt;
tmp->state = AST_STATE_DOWN;
tmp->stack = -1;
tmp->streamid = -1;
tmp->appl = NULL;
tmp->data = NULL;
pthread_mutex_init(&tmp->lock, NULL);
strncpy(tmp->context, "default", sizeof(tmp->context));
strncpy(tmp->language, defaultlanguage, sizeof(tmp->language));
strncpy(tmp->exten, "s", sizeof(tmp->exten));
tmp->priority=1;
tmp->next = channels;
channels= tmp;
if (needqueue &&
pipe(pvt->alertpipe)) {
ast_log(LOG_WARNING, "Alert pipe creation failed!\n");
free(pvt);
free(tmp);
tmp = NULL;
pvt = NULL;
} else {
/* Make sure we've got it done right if they don't */
if (needqueue) {
flags = fcntl(pvt->alertpipe[0], F_GETFL);
fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
flags = fcntl(pvt->alertpipe[1], F_GETFL);
fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
} else
pvt->alertpipe[0] = pvt->alertpipe[1] = -1;
/* Always watch the alertpipe */
tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0];
strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
tmp->pvt = pvt;
tmp->state = AST_STATE_DOWN;
tmp->stack = -1;
tmp->streamid = -1;
tmp->appl = NULL;
tmp->data = NULL;
ast_pthread_mutex_init(&tmp->lock);
strncpy(tmp->context, "default", sizeof(tmp->context)-1);
strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1);
strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
tmp->priority=1;
tmp->amaflags = ast_default_amaflags;
strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1);
tmp->next = channels;
channels= tmp;
}
} else {
ast_log(LOG_WARNING, "Unable to create schedule context\n");
free(tmp);
@@ -210,6 +302,56 @@ struct ast_channel *ast_channel_alloc(void)
return tmp;
}
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int lock)
{
struct ast_frame *f;
struct ast_frame *prev, *cur;
int blah = 1;
int qlen = 0;
f = ast_frdup(fin);
if (!f) {
ast_log(LOG_WARNING, "Unable to duplicate frame\n");
return -1;
}
if (lock)
ast_pthread_mutex_lock(&chan->lock);
prev = NULL;
cur = chan->pvt->readq;
while(cur) {
prev = cur;
cur = cur->next;
qlen++;
}
if (prev)
prev->next = f;
else
chan->pvt->readq = f;
if (chan->pvt->alertpipe[1] > -1) {
if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
ast_log(LOG_WARNING, "Unable to write to alert pipe, frametype/subclass %d/%d (qlen = %d): %s!\n",
f->frametype, f->subclass, qlen, strerror(errno));
}
if (qlen > 128) {
ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
}
if (lock)
ast_pthread_mutex_unlock(&chan->lock);
return 0;
}
int ast_queue_hangup(struct ast_channel *chan, int lock)
{
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
return ast_queue_frame(chan, &f, lock);
}
int ast_queue_control(struct ast_channel *chan, int control, int lock)
{
struct ast_frame f = { AST_FRAME_CONTROL, };
f.subclass = control;
return ast_queue_frame(chan, &f, lock);
}
int ast_channel_defer_dtmf(struct ast_channel *chan)
{
int pre = 0;
@@ -245,9 +387,28 @@ struct ast_channel *ast_channel_walk(struct ast_channel *prev)
}
int ast_safe_sleep(struct ast_channel *chan, int ms)
{
struct ast_frame *f;
while(ms > 0) {
ms = ast_waitfor(chan, ms);
if (ms <0)
return -1;
if (ms > 0) {
f = ast_read(chan);
if (!f)
return -1;
ast_frfree(f);
}
}
return 0;
}
void ast_channel_free(struct ast_channel *chan)
{
struct ast_channel *last=NULL, *cur;
int fd;
struct ast_frame *f, *fp;
PTHREAD_MUTEX_LOCK(&chlock);
cur = channels;
while(cur) {
@@ -276,7 +437,20 @@ void ast_channel_free(struct ast_channel *chan)
free(chan->dnid);
if (chan->callerid)
free(chan->callerid);
if (chan->ani)
free(chan->ani);
pthread_mutex_destroy(&chan->lock);
/* Close pipes if appropriate */
if ((fd = chan->pvt->alertpipe[0]) > -1)
close(fd);
if ((fd = chan->pvt->alertpipe[1]) > -1)
close(fd);
f = chan->pvt->readq;
while(f) {
fp = f;
f = f->next;
ast_frfree(fp);
}
free(chan->pvt);
free(chan);
PTHREAD_MUTEX_UNLOCK(&chlock);
@@ -330,6 +504,18 @@ int ast_hangup(struct ast_channel *chan)
ast_stopstream(chan);
if (chan->sched)
sched_context_destroy(chan->sched);
/* Clear any tone stuff remaining */
if (chan->generatordata)
chan->generator->release(chan, chan->generatordata);
chan->generatordata = NULL;
chan->generator = NULL;
if (chan->cdr) {
/* End the CDR if it hasn't already */
ast_cdr_end(chan->cdr);
/* Post and Free the CDR */
ast_cdr_post(chan->cdr);
ast_cdr_free(chan->cdr);
}
if (chan->blocking) {
ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
"is blocked by thread %ld in procedure %s! Expect a failure\n",
@@ -380,7 +566,7 @@ int ast_answer(struct ast_channel *chan)
{
int res = 0;
/* Stop if we're a zombie or need a soft hangup */
if (chan->zombie || chan->softhangup)
if (chan->zombie || ast_check_hangup(chan))
return -1;
switch(chan->state) {
case AST_STATE_RINGING:
@@ -388,6 +574,8 @@ int ast_answer(struct ast_channel *chan)
if (chan->pvt->answer)
res = chan->pvt->answer(chan);
chan->state = AST_STATE_UP;
if (chan->cdr)
ast_cdr_answer(chan->cdr);
return res;
break;
case AST_STATE_UP:
@@ -396,6 +584,29 @@ int ast_answer(struct ast_channel *chan)
return 0;
}
void ast_deactivate_generator(struct ast_channel *chan)
{
if (chan->generatordata) {
chan->generator->release(chan, chan->generatordata);
chan->generatordata = NULL;
chan->writeinterrupt = 0;
}
}
int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
{
if (chan->generatordata) {
chan->generator->release(chan, chan->generatordata);
chan->generatordata = NULL;
}
if ((chan->generatordata = gen->alloc(chan, params))) {
chan->generator = gen;
} else {
return -1;
}
return 0;
}
int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
{
/* Wait for x amount of time on a file descriptor to have input. */
@@ -473,9 +684,10 @@ struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds,
tv.tv_usec = (*ms % 1000) * 1000;
FD_ZERO(&rfds);
FD_ZERO(&efds);
for (x=0;x<n;x++) {
for (y=0;y<AST_MAX_FDS;y++) {
if (c[x]->fds[y] > 0) {
if (c[x]->fds[y] > -1) {
FD_SET(c[x]->fds[y], &rfds);
FD_SET(c[x]->fds[y], &efds);
if (c[x]->fds[y] > max)
@@ -501,8 +713,12 @@ struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds,
/* Simulate a timeout if we were interrupted */
if (errno != EINTR)
*ms = -1;
else
else {
/* Just an interrupt */
#if 0
*ms = 0;
#endif
}
return NULL;
}
@@ -557,7 +773,7 @@ char ast_waitfordigit(struct ast_channel *c, int ms)
struct ast_frame *f;
char result = 0;
/* Stop if we're a zombie or need a soft hangup */
if (c->zombie || c->softhangup)
if (c->zombie || ast_check_hangup(c))
return -1;
/* Wait for a digit, no more than ms milliseconds total. */
while(ms && !result) {
@@ -581,12 +797,13 @@ char ast_waitfordigit(struct ast_channel *c, int ms)
struct ast_frame *ast_read(struct ast_channel *chan)
{
struct ast_frame *f = NULL;
int blah;
static struct ast_frame null_frame =
{
AST_FRAME_NULL,
};
pthread_mutex_lock(&chan->lock);
ast_pthread_mutex_lock(&chan->lock);
if (chan->masq) {
if (ast_do_masquerade(chan)) {
ast_log(LOG_WARNING, "Failed to perform masquerade\n");
@@ -598,11 +815,11 @@ struct ast_frame *ast_read(struct ast_channel *chan)
}
/* Stop if we're a zombie or need a soft hangup */
if (chan->zombie || chan->softhangup) {
if (chan->zombie || ast_check_hangup(chan)) {
pthread_mutex_unlock(&chan->lock);
return NULL;
}
if (!chan->deferdtmf && strlen(chan->dtmfq)) {
/* We have DTMF that has been deferred. Return it now */
chan->dtmff.frametype = AST_FRAME_DTMF;
@@ -613,19 +830,35 @@ struct ast_frame *ast_read(struct ast_channel *chan)
return &chan->dtmff;
}
chan->blocker = pthread_self();
if (chan->exception) {
if (chan->pvt->exception)
f = chan->pvt->exception(chan);
/* Read and ignore anything on the alertpipe, but read only
one sizeof(blah) per frame that we send from it */
if (chan->pvt->alertpipe[0] > -1) {
read(chan->pvt->alertpipe[0], &blah, sizeof(blah));
}
/* Check for pending read queue */
if (chan->pvt->readq) {
f = chan->pvt->readq;
chan->pvt->readq = f->next;
/* Interpret hangup and return NULL */
if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))
f = NULL;
} else {
chan->blocker = pthread_self();
if (chan->exception) {
if (chan->pvt->exception)
f = chan->pvt->exception(chan);
else
ast_log(LOG_WARNING, "Exception flag set, but no exception handler\n");
/* Clear the exception flag */
chan->exception = 0;
} else
if (chan->pvt->read)
f = chan->pvt->read(chan);
else
ast_log(LOG_WARNING, "Exception flag set, but no exception handler\n");
/* Clear the exception flag */
chan->exception = 0;
} else
if (chan->pvt->read)
f = chan->pvt->read(chan);
else
ast_log(LOG_WARNING, "No read routine on channel %s\n", chan);
ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
}
if (f && (f->frametype == AST_FRAME_VOICE)) {
if (chan->pvt->readtrans) {
f = ast_translate(chan->pvt->readtrans, f, 1);
@@ -633,18 +866,41 @@ struct ast_frame *ast_read(struct ast_channel *chan)
f = &null_frame;
}
}
/* Make sure we always return NULL in the future */
if (!f)
if (!f) {
chan->softhangup = 1;
else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) {
/* End the CDR if appropriate */
if (chan->cdr)
ast_cdr_end(chan->cdr);
} else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) {
if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
else
ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
f = &null_frame;
} else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
/* Answer the CDR */
chan->state = AST_STATE_UP;
ast_cdr_answer(chan->cdr);
}
pthread_mutex_unlock(&chan->lock);
/* Run any generator sitting on the line */
if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) {
/* Mask generator data temporarily */
void *tmp;
int res;
tmp = chan->generatordata;
chan->generatordata = NULL;
res = chan->generator->generate(chan, tmp, f->datalen);
chan->generatordata = tmp;
if (res) {
ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
ast_deactivate_generator(chan);
}
}
return f;
}
@@ -652,7 +908,7 @@ int ast_indicate(struct ast_channel *chan, int condition)
{
int res = -1;
/* Stop if we're a zombie or need a soft hangup */
if (chan->zombie || chan->softhangup)
if (chan->zombie || ast_check_hangup(chan))
return -1;
if (chan->pvt->indicate) {
res = chan->pvt->indicate(chan, condition);
@@ -663,11 +919,40 @@ int ast_indicate(struct ast_channel *chan, int condition)
return res;
}
int ast_recvchar(struct ast_channel *chan, int timeout)
{
int res,ourto,c;
struct ast_frame *f;
ourto = timeout;
for(;;)
{
if (ast_check_hangup(chan)) return -1;
res = ast_waitfor(chan,ourto);
if (res <= 0) /* if timeout */
{
return 0;
}
ourto = res;
f = ast_read(chan);
if (f == NULL) return -1; /* if hangup */
if ((f->frametype == AST_FRAME_CONTROL) &&
(f->subclass == AST_CONTROL_HANGUP)) return -1; /* if hangup */
if (f->frametype == AST_FRAME_TEXT) /* if a text frame */
{
c = *((char *)f->data); /* get the data */
ast_frfree(f);
return(c);
}
ast_frfree(f);
}
}
int ast_sendtext(struct ast_channel *chan, char *text)
{
int res = 0;
/* Stop if we're a zombie or need a soft hangup */
if (chan->zombie || chan->softhangup)
if (chan->zombie || ast_check_hangup(chan))
return -1;
CHECK_BLOCKING(chan);
if (chan->pvt->send_text)
@@ -681,7 +966,7 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
int res = -1;
struct ast_frame *f;
/* Stop if we're a zombie or need a soft hangup */
if (chan->zombie || chan->softhangup)
if (chan->zombie || ast_check_hangup(chan))
return -1;
/* Handle any pending masquerades */
if (chan->masq) {
@@ -692,6 +977,12 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
}
if (chan->masqr)
return 0;
if (chan->generatordata) {
if (chan->writeinterrupt)
ast_deactivate_generator(chan);
else
return 0;
}
CHECK_BLOCKING(chan);
switch(fr->frametype) {
case AST_FRAME_CONTROL:
@@ -699,10 +990,13 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
break;
case AST_FRAME_DTMF:
if (chan->pvt->send_digit)
res = chan->pvt->send_digit(chan, fr->subclass);
break;
case AST_FRAME_TEXT:
if (chan->pvt->send_text)
res = chan->pvt->send_text(chan, (char *) fr->data);
break;
default:
if (chan->pvt->write) {
if (chan->pvt->writetrans) {
@@ -716,6 +1010,9 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
}
}
chan->blocking = 0;
/* Consider a write failure to force a soft hangup */
if (res < 0)
chan->softhangup = 1;
return res;
}
@@ -744,7 +1041,7 @@ int ast_set_write_format(struct ast_channel *chan, int fmts)
/* Build a translation path from the user write format to the raw writing format */
chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat);
if (option_debug)
ast_log(LOG_DEBUG, "Set channel %s to format %d\n", chan->name, chan->writeformat);
ast_log(LOG_DEBUG, "Set channel %s to write format %d\n", chan->name, chan->writeformat);
return 0;
}
@@ -772,6 +1069,8 @@ int ast_set_read_format(struct ast_channel *chan, int fmts)
ast_translator_free_path(chan->pvt->readtrans);
/* Build a translation path from the raw read format to the user reading format */
chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat);
if (option_debug)
ast_log(LOG_DEBUG, "Set channel %s to read format %d\n", chan->name, chan->readformat);
return 0;
}
@@ -817,8 +1116,8 @@ int ast_call(struct ast_channel *chan, char *addr, int timeout)
return anyway. */
int res = -1;
/* Stop if we're a zombie or need a soft hangup */
pthread_mutex_lock(&chan->lock);
if (!chan->zombie && !chan->softhangup)
ast_pthread_mutex_lock(&chan->lock);
if (!chan->zombie && !ast_check_hangup(chan))
if (chan->pvt->call)
res = chan->pvt->call(chan, addr, timeout);
pthread_mutex_unlock(&chan->lock);
@@ -831,7 +1130,7 @@ int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int fti
int to = ftimeout;
char d;
/* Stop if we're a zombie or need a soft hangup */
if (c->zombie || c->softhangup)
if (c->zombie || ast_check_hangup(c))
return -1;
if (!len)
return -1;
@@ -853,7 +1152,7 @@ int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int fti
}
if (!strchr(enders, d))
s[pos++] = d;
if (strchr(enders, d) || (pos >= len - 1)) {
if (strchr(enders, d) || (pos >= len)) {
s[pos]='\0';
return 0;
}
@@ -893,19 +1192,19 @@ int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *pe
chanf = chan->nativeformats;
res = ast_translator_best_choice(&peerf, &chanf);
if (res < 0) {
ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan, chan->nativeformats, peer, peer->nativeformats);
ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats);
return -1;
}
/* Set read format on channel */
res = ast_set_read_format(chan, peerf);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan, chanf);
ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf);
return -1;
}
/* Set write format on peer channel */
res = ast_set_write_format(peer, peerf);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer, peerf);
ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf);
return -1;
}
/* Now we go the other way */
@@ -913,19 +1212,19 @@ int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *pe
chanf = chan->nativeformats;
res = ast_translator_best_choice(&chanf, &peerf);
if (res < 0) {
ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer, peer->nativeformats, chan, chan->nativeformats);
ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats);
return -1;
}
/* Set writeformat on channel */
res = ast_set_write_format(chan, chanf);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan, chanf);
ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf);
return -1;
}
/* Set read format on peer channel */
res = ast_set_read_format(peer, chanf);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer, peerf);
ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf);
return -1;
}
return 0;
@@ -975,14 +1274,14 @@ static int ast_do_masquerade(struct ast_channel *original)
free_translation(original);
/* We need the clone's lock, too */
pthread_mutex_lock(&clone->lock);
ast_pthread_mutex_lock(&clone->lock);
/* Unlink the masquerade */
original->masq = NULL;
clone->masqr = NULL;
/* Copy the name from the clone channel */
strncpy(original->name, clone->name, sizeof(original->name));
strncpy(original->name, clone->name, sizeof(original->name)-1);
/* Mangle the name of the clone channel */
strncat(clone->name, "<MASQ>", sizeof(clone->name));
@@ -1019,6 +1318,8 @@ static int ast_do_masquerade(struct ast_channel *original)
/* Copy the FD's */
for (x=0;x<AST_MAX_FDS;x++)
original->fds[x] = clone->fds[x];
/* Presense of ADSI capable CPE follows clone */
original->adsicpe = clone->adsicpe;
/* Bridge remains the same */
/* CDR fields remain the same */
/* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
@@ -1096,7 +1397,7 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
int res;
int nativefailed=0;
/* Stop if we're a zombie or need a soft hangup */
if (c0->zombie || c0->softhangup || c1->zombie || c1->softhangup)
if (c0->zombie || ast_check_hangup(c0) || c1->zombie || ast_check_hangup(c1))
return -1;
if (c0->bridge) {
ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
@@ -1116,7 +1417,7 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
cs[1] = c1;
for (/* ever */;;) {
/* Stop if we're a zombie or need a soft hangup */
if (c0->zombie || c0->softhangup || c1->zombie || c1->softhangup) {
if (c0->zombie || ast_check_hangup(c0) || c1->zombie || ast_check_hangup(c1)) {
*fo = NULL;
if (who) *rc = who;
res = 0;
@@ -1125,6 +1426,8 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
if (c0->pvt->bridge &&
(c0->pvt->bridge == c1->pvt->bridge) && !nativefailed) {
/* Looks like they share a bridge code */
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) {
c0->bridge = NULL;
c1->bridge = NULL;
@@ -1138,7 +1441,8 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
}
if ((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) {
if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) &&
!(c0->generator || c1->generator)) {
if (ast_channel_make_compatible(c0, c1)) {
ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
return -1;
@@ -1196,10 +1500,14 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
last = who;
#endif
tackygoto:
if (who == c0)
ast_write(c1, f);
else
ast_write(c0, f);
/* Don't copy packets if there is a generator on either one, since they're
not supposed to be listening anyway */
if (!c0->generator && !c1->generator) {
if (who == c0)
ast_write(c1, f);
else
ast_write(c0, f);
}
}
ast_frfree(f);
} else
@@ -1233,3 +1541,137 @@ int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int
}
return 0;
}
struct tonepair_def {
int freq1;
int freq2;
int duration;
int vol;
};
struct tonepair_state {
float freq1;
float freq2;
float vol;
int duration;
int pos;
int origrfmt;
int origwfmt;
struct ast_frame f;
unsigned char offset[AST_FRIENDLY_OFFSET];
short data[4000];
};
static void tonepair_release(struct ast_channel *chan, void *params)
{
struct tonepair_state *ts = params;
if (chan) {
ast_set_write_format(chan, ts->origwfmt);
ast_set_read_format(chan, ts->origrfmt);
}
free(ts);
}
static void * tonepair_alloc(struct ast_channel *chan, void *params)
{
struct tonepair_state *ts;
struct tonepair_def *td = params;
ts = malloc(sizeof(struct tonepair_state));
if (!ts)
return NULL;
memset(ts, 0, sizeof(struct tonepair_state));
ts->origrfmt = chan->readformat;
ts->origwfmt = chan->writeformat;
if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
tonepair_release(NULL, ts);
ts = NULL;
} else if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (read)\n", chan->name);
ast_set_write_format(chan, ts->origwfmt);
tonepair_release(NULL, ts);
ts = NULL;
} else {
ts->freq1 = td->freq1;
ts->freq2 = td->freq2;
ts->duration = td->duration;
ts->vol = td->vol;
}
/* Let interrupts interrupt :) */
chan->writeinterrupt = 1;
return ts;
}
static int tonepair_generator(struct ast_channel *chan, void *data, int len)
{
struct tonepair_state *ts = data;
int x;
if (len > sizeof(ts->data) / 2 - 1) {
ast_log(LOG_WARNING, "Can't generate that much data!\n");
return -1;
}
memset(&ts->f, 0, sizeof(ts->f));
for (x=0;x<len/2;x++) {
ts->data[x] = ts->vol * (
sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) +
sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x))
);
}
ts->f.frametype = AST_FRAME_VOICE;
ts->f.subclass = AST_FORMAT_SLINEAR;
ts->f.datalen = len;
ts->f.timelen = len/8;
ts->f.offset = AST_FRIENDLY_OFFSET;
ts->f.data = ts->data;
ast_write(chan, &ts->f);
ts->pos += x;
if (ts->duration > 0) {
if (ts->pos >= ts->duration * 8)
return -1;
}
return 0;
}
static struct ast_generator tonepair = {
alloc: tonepair_alloc,
release: tonepair_release,
generate: tonepair_generator,
};
int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
{
struct tonepair_def d = { 0, };
d.freq1 = freq1;
d.freq2 = freq2;
d.duration = duration;
if (vol < 1)
d.vol = 8192;
else
d.vol = vol;
if (ast_activate_generator(chan, &tonepair, &d))
return -1;
return 0;
}
void ast_tonepair_stop(struct ast_channel *chan)
{
ast_deactivate_generator(chan);
}
int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
{
struct ast_frame *f;
int res;
if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
return res;
/* Give us some wiggle room */
while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
f = ast_read(chan);
if (f)
ast_frfree(f);
else
return -1;
}
return 0;
}

View File

@@ -11,17 +11,29 @@
# the GNU General Public License
#
CHANNEL_LIBS=chan_vofr.so chan_modem.so \
chan_modem_aopen.so chan_iax.so chan_oss.so \
CHANNEL_LIBS=chan_modem.so chan_iax.so chan_sip.so \
chan_modem_aopen.so chan_oss.so \
chan_modem_bestdata.so chan_modem_i4l.so
#
# If you really want VoFR you can have it :-P
#
#CHANNEL_LIBS+=chan_vofr
CHANNEL_LIBS+=$(shell [ -f /usr/include/linux/ixjuser.h ] && echo chan_phone.so)
CFLAGS+=-Wno-missing-prototypes -Wno-missing-declarations
CFLAGS+=$(shell [ ! -f /usr/include/linux/if_wanpipe.h ] && echo " -DOLD_SANGOMA_API")
CHANNEL_LIBS+=$(shell [ -f /usr/include/alsa/asoundlib.h ] && echo "chan_alsa.so")
CFLAGS+=$(shell [ -f /usr/lib/libpri.so.1 ] && echo " -DZAPATA_PRI")
CFLAGS+=$(shell [ -f alsa-monitor.h ] && echo " -DALSA_MONITOR")
ZAPPRI=$(shell [ -f /usr/lib/libpri.so.1 ] && echo "-lpri")
ALSA_SRC=chan_alsa.c
ALSA_SRC+=$(shell [ -f alsa-monitor.h ] && echo "alsa-monitor.h")
CFLAGS+=-DCRYPTO
CFLAGS+=#-DVOFRDUMPER
ZAPDIR=/usr/lib
@@ -30,11 +42,11 @@ CHANNEL_LIBS+=$(shell [ -f $(ZAPDIR)/libzap.a ] && echo "chan_zap.so")
CFLAGS+=$(shell [ -f $(ZAPDIR)/libzap.a ] && echo "-I$(ZAPDIR)")
all: $(CHANNEL_LIBS)
all: $(CHANNEL_LIBS)
clean:
rm -f *.so *.o
rm -f busy.h ringtone.h gentone
rm -f busy.h ringtone.h gentone gentone-ulaw
%.so : %.o
$(CC) -shared -Xlinker -x -o $@ $<
@@ -42,6 +54,9 @@ clean:
gentone: gentone.c
$(CC) -o gentone gentone.c -lm
gentone-ulaw: gentone-ulaw.c
$(CC) -o gentone-ulaw gentone-ulaw.c -lm
busy.h: gentone
./gentone busy 480 620
@@ -53,6 +68,11 @@ chan_oss.o: chan_oss.c busy.h ringtone.h
chan_zap.so: chan_zap.o
$(CC) -shared -Xlinker -x -o $@ $< $(ZAPPRI) -lzap -ltonezone
chan_alsa.o: $(ALSA_SRC)
chan_alsa.so: chan_alsa.o
$(CC) -shared -Xlinker -x -o $@ $< -lasound -lm -ldl
#chan_modem.so : chan_modem.o
# $(CC) -rdynamic -shared -Xlinker -x -o $@ $<

View File

@@ -80,7 +80,7 @@ struct vofr_hdr {
u_int8_t cid; /* Channel ID */
u_int8_t mod:4; /* Modulation */
u_int8_t remid:4; /* Remote ID */
#elif __BYTE__ORDER == __BIG_ENDIAN
#elif __BYTE_ORDER == __BIG_ENDIAN
u_int8_t ctag:4; /* Connect tag */
u_int8_t dtype:4; /* Data type */
u_int8_t vflags:4; /* Voice Routing Flags */

1113
channels/chan_alsa.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -14,6 +14,7 @@
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <asterisk/lock.h>
#include <asterisk/channel.h>
#include <asterisk/channel_pvt.h>
#include <asterisk/config.h>
@@ -64,14 +65,14 @@ static int baudrate = 115200;
static int stripmsd = 0;
static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
/* Protect the interface list (of ast_modem_pvt's) */
static pthread_mutex_t iflock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t iflock = AST_MUTEX_INITIALIZER;
/* Protect the monitoring thread, so only one process can kill or start it, and not
when it's doing something critical. */
static pthread_mutex_t monlock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t monlock = AST_MUTEX_INITIALIZER;
/* This is the thread for the monitor which checks for input on the channels
which are not currently in use. */
@@ -90,7 +91,7 @@ static int modem_digit(struct ast_channel *ast, char digit)
p = ast->pvt->pvt;
if (p->mc->dialdigit)
return p->mc->dialdigit(p, digit);
else ast_log(LOG_DEBUG, "Channel %s lacks digit dialing\n");
else ast_log(LOG_DEBUG, "Channel %s lacks digit dialing\n", ast->name);
return 0;
}
@@ -165,7 +166,7 @@ static int modem_call(struct ast_channel *ast, char *idest, int timeout)
struct ast_modem_pvt *p;
int ms = timeout;
char rdest[80], *where, dstr[100];
strncpy(rdest, idest, sizeof(rdest));
strncpy(rdest, idest, sizeof(rdest)-1);
strtok(rdest, ":");
where = strtok(NULL, ":");
if (!where) {
@@ -245,7 +246,7 @@ int ast_modem_read_response(struct ast_modem_pvt *p, int timeout)
do {
res = ast_waitfor_n_fd(&p->fd, 1, &timeout, NULL);
if (res < 0) {
strncpy(p->response, "(No Response)", sizeof(p->response));
strncpy(p->response, "(No Response)", sizeof(p->response)-1);
return -1;
}
/* get no more then buffer length */
@@ -257,7 +258,7 @@ int ast_modem_read_response(struct ast_modem_pvt *p, int timeout)
/* if nothing in buffer, go back into timeout stuff */
if (errno == EWOULDBLOCK) break;
/* return as error */
strncpy(p->response, "(No Response)", sizeof(p->response));
strncpy(p->response, "(No Response)", sizeof(p->response)-1);
return -1;
}
/* save char */
@@ -281,7 +282,7 @@ int ast_modem_read_response(struct ast_modem_pvt *p, int timeout)
}
}
} while(timeout > 0);
strncpy(p->response, "(No Response)", sizeof(p->response));
strncpy(p->response, "(No Response)", sizeof(p->response)-1);
return -1;
}
@@ -289,7 +290,7 @@ int ast_modem_expect(struct ast_modem_pvt *p, char *result, int timeout)
{
int res = -1;
timeout *= 1000;
strncpy(p->response, "(No Response)", sizeof(p->response));
strncpy(p->response, "(No Response)", sizeof(p->response)-1);
do {
res = ast_waitfor_n_fd(&p->fd, 1, &timeout, NULL);
if (res < 0) {
@@ -363,7 +364,7 @@ static int modem_setup(struct ast_modem_pvt *p, int baudrate)
ast_log(LOG_WARNING, "Modem did not provide identification\n");
return -1;
}
strncpy(identity, p->response, sizeof(identity));
strncpy(identity, p->response, sizeof(identity)-1);
ast_modem_trim(identity);
if (ast_modem_expect(p, "OK", ECHO_TIMEOUT)) {
ast_log(LOG_WARNING, "Modem did not provide identification\n");
@@ -411,6 +412,7 @@ static int modem_hangup(struct ast_channel *ast)
p->mc->init(p);
ast->state = AST_STATE_DOWN;
memset(p->cid, 0, sizeof(p->cid));
memset(p->dnid, 0, sizeof(p->dnid));
((struct ast_modem_pvt *)(ast->pvt->pvt))->owner = NULL;
ast_pthread_mutex_lock(&usecnt_lock);
usecnt--;
@@ -468,16 +470,25 @@ static struct ast_frame *modem_read(struct ast_channel *ast)
static int modem_write(struct ast_channel *ast, struct ast_frame *frame)
{
int res=0;
long flags;
struct ast_modem_pvt *p = ast->pvt->pvt;
/* Temporarily make non-blocking */
flags = fcntl(ast->fds[0], F_GETFL);
fcntl(ast->fds[0], F_SETFL, flags | O_NONBLOCK);
if (p->mc->write)
res = p->mc->write(p, frame);
/* Block again */
fcntl(ast->fds[0], F_SETFL, flags);
return 0;
}
struct ast_channel *ast_modem_new(struct ast_modem_pvt *i, int state)
{
struct ast_channel *tmp;
tmp = ast_channel_alloc();
tmp = ast_channel_alloc(1);
if (tmp) {
snprintf(tmp->name, sizeof(tmp->name), "Modem[%s]/%s", i->mc->name, i->dev + 5);
tmp->type = type;
@@ -493,11 +504,13 @@ struct ast_channel *ast_modem_new(struct ast_modem_pvt *i, int state)
tmp->pvt->answer = modem_answer;
tmp->pvt->read = modem_read;
tmp->pvt->write = modem_write;
strncpy(tmp->context, i->context, sizeof(tmp->context));
strncpy(tmp->context, i->context, sizeof(tmp->context)-1);
if (strlen(i->cid))
tmp->callerid = strdup(i->cid);
if (strlen(i->language))
strncpy(tmp->language,i->language, sizeof(tmp->language));
strncpy(tmp->language,i->language, sizeof(tmp->language)-1);
if (strlen(i->dnid))
strncpy(tmp->exten, i->dnid, sizeof(tmp->exten) - 1);
i->owner = tmp;
ast_pthread_mutex_lock(&usecnt_lock);
usecnt++;
@@ -677,9 +690,9 @@ static struct ast_modem_pvt *mkif(char *iface)
free(tmp);
return NULL;
}
strncpy(tmp->language, language, sizeof(tmp->language));
strncpy(tmp->msn, msn, sizeof(tmp->msn));
strncpy(tmp->dev, iface, sizeof(tmp->dev));
strncpy(tmp->language, language, sizeof(tmp->language)-1);
strncpy(tmp->msn, msn, sizeof(tmp->msn)-1);
strncpy(tmp->dev, iface, sizeof(tmp->dev)-1);
/* Maybe in the future we want to allow variable
serial settings */
stty(tmp);
@@ -691,18 +704,14 @@ static struct ast_modem_pvt *mkif(char *iface)
free(tmp);
return NULL;
}
#if 0
flags = fcntl(tmp->fd, F_GETFL);
fcntl(tmp->fd, F_SETFL, flags | O_NONBLOCK);
#endif
tmp->owner = NULL;
tmp->ministate = 0;
tmp->stripmsd = stripmsd;
tmp->dialtype = dialtype;
tmp->mode = gmode;
memset(tmp->cid, 0, sizeof(tmp->cid));
strncpy(tmp->context, context, sizeof(tmp->context));
strncpy(tmp->initstr, initstr, sizeof(tmp->initstr));
strncpy(tmp->context, context, sizeof(tmp->context)-1);
strncpy(tmp->initstr, initstr, sizeof(tmp->initstr)-1);
tmp->next = NULL;
tmp->obuflen = 0;
@@ -721,7 +730,7 @@ static struct ast_channel *modem_request(char *type, int format, void *data)
struct ast_modem_pvt *p;
struct ast_channel *tmp = NULL;
char dev[80];
strncpy(dev, (char *)data, sizeof(dev));
strncpy(dev, (char *)data, sizeof(dev)-1);
strtok(dev, ":");
oldformat = format;
/* Search for an unowned channel */
@@ -746,7 +755,7 @@ static struct ast_channel *modem_request(char *type, int format, void *data)
p = p->next;
}
if (!p)
ast_log(LOG_WARNING, "Requested device '%s' does not exist\n", p->dev);
ast_log(LOG_WARNING, "Requested device '%s' does not exist\n", dev);
ast_pthread_mutex_unlock(&iflock);
return tmp;
@@ -811,17 +820,17 @@ int load_module()
} else if (!strcasecmp(v->name, "stripmsd")) {
stripmsd = atoi(v->value);
} else if (!strcasecmp(v->name, "type")) {
strncpy(mtype, v->value, sizeof(mtype));
strncpy(mtype, v->value, sizeof(mtype)-1);
} else if (!strcasecmp(v->name, "initstr")) {
strncpy(initstr, v->value, sizeof(initstr));
strncpy(initstr, v->value, sizeof(initstr)-1);
} else if (!strcasecmp(v->name, "dialtype")) {
dialtype = toupper(v->value[0]);
} else if (!strcasecmp(v->name, "context")) {
strncpy(context, v->value, sizeof(context));
strncpy(context, v->value, sizeof(context)-1);
} else if (!strcasecmp(v->name, "msn")) {
strncpy(msn, v->value, sizeof(msn));
strncpy(msn, v->value, sizeof(msn)-1);
} else if (!strcasecmp(v->name, "language")) {
strncpy(language, v->value, sizeof(language));
strncpy(language, v->value, sizeof(language)-1);
}
v = v->next;
}

View File

@@ -16,7 +16,7 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <asterisk/lock.h>
#include <asterisk/vmodem.h>
#include <asterisk/module.h>
#include <asterisk/frame.h>
@@ -34,7 +34,7 @@ static char *breakcmd = "\0x10\0x03";
static char *desc = "A/Open (Rockwell Chipset) ITU-2 VoiceModem Driver";
int usecnt;
pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
static char *aopen_idents[] = {
/* Identify A/Open Modem */
@@ -54,7 +54,7 @@ static int aopen_setdev(struct ast_modem_pvt *p, int dev)
return -1;
}
ast_modem_trim(p->response);
strncpy(cmd, p->response, sizeof(cmd));
strncpy(cmd, p->response, sizeof(cmd)-1);
if (ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Modem did not respond properly\n");
return -1;
@@ -344,17 +344,17 @@ static char *aopen_identify(struct ast_modem_pvt *p)
char rev[80];
ast_modem_send(p, "AT#MDL?", 0);
ast_modem_read_response(p, 5);
strncpy(mdl, p->response, sizeof(mdl));
strncpy(mdl, p->response, sizeof(mdl)-1);
ast_modem_trim(mdl);
ast_modem_expect(p, "OK", 5);
ast_modem_send(p, "AT#MFR?", 0);
ast_modem_read_response(p, 5);
strncpy(mfr, p->response, sizeof(mfr));
strncpy(mfr, p->response, sizeof(mfr)-1);
ast_modem_trim(mfr);
ast_modem_expect(p, "OK", 5);
ast_modem_send(p, "AT#REV?", 0);
ast_modem_read_response(p, 5);
strncpy(rev, p->response, sizeof(rev));
strncpy(rev, p->response, sizeof(rev)-1);
ast_modem_trim(rev);
ast_modem_expect(p, "OK", 5);
snprintf(identity, sizeof(identity), "%s Model %s Revision %s", mfr, mdl, rev);

View File

@@ -17,7 +17,7 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <asterisk/lock.h>
#include <asterisk/vmodem.h>
#include <asterisk/module.h>
#include <asterisk/frame.h>
@@ -38,7 +38,7 @@ static char *breakcmd = "\020!";
static char *desc = "BestData (Conexant V.90 Chipset) VoiceModem Driver";
int usecnt;
pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
static char *bestdata_idents[] = {
/* Identify BestData Modem */
@@ -189,7 +189,7 @@ static struct ast_frame *bestdata_handle_escape(struct ast_modem_pvt *p, char es
char res[1000];
if (ast_modem_read_response(p, 5)) break;
strncpy(res, p->response, sizeof(res));
strncpy(res, p->response, sizeof(res)-1);
ast_modem_trim(res);
if (!strncmp(res,"\020.",2)) break;
if (!strncmp(res,"NAME",4)) strcpy(name,res + 7);
@@ -419,17 +419,17 @@ static char *bestdata_identify(struct ast_modem_pvt *p)
char rev[80];
ast_modem_send(p, "AT+FMM", 0);
ast_modem_read_response(p, 5);
strncpy(mdl, p->response, sizeof(mdl));
strncpy(mdl, p->response, sizeof(mdl)-1);
ast_modem_trim(mdl);
ast_modem_expect(p, "OK", 5);
ast_modem_send(p, "AT+FMI", 0);
ast_modem_read_response(p, 5);
strncpy(mfr, p->response, sizeof(mfr));
strncpy(mfr, p->response, sizeof(mfr)-1);
ast_modem_trim(mfr);
ast_modem_expect(p, "OK", 5);
ast_modem_send(p, "AT+FMR", 0);
ast_modem_read_response(p, 5);
strncpy(rev, p->response, sizeof(rev));
strncpy(rev, p->response, sizeof(rev)-1);
ast_modem_trim(rev);
ast_modem_expect(p, "OK", 5);
snprintf(identity, sizeof(identity), "%s Model %s Revision %s", mfr, mdl, rev);

View File

@@ -17,7 +17,7 @@
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <asterisk/lock.h>
#include <asterisk/vmodem.h>
#include <asterisk/module.h>
#include <asterisk/frame.h>
@@ -33,7 +33,7 @@ static char *breakcmd = "\0x10\0x14\0x10\0x3";
static char *desc = "ISDN4Linux Emulated Modem Driver";
int usecnt;
pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
static char *i4l_idents[] = {
/* Identify ISDN4Linux Driver */
@@ -58,7 +58,7 @@ static int i4l_setdev(struct ast_modem_pvt *p, int dev)
return -1;
}
ast_modem_trim(p->response);
strncpy(cmd, p->response, sizeof(cmd));
strncpy(cmd, p->response, sizeof(cmd)-1);
if (ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Modem did not respond properly\n");
return -1;
@@ -161,9 +161,9 @@ static int i4l_init(struct ast_modem_pvt *p)
ast_log(LOG_WARNING, "Unable to set to transparent mode\n");
return -1;
}
if (ast_modem_send(p, "ATS23=1", 0) ||
if (ast_modem_send(p, "ATS23=9", 0) ||
ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Unable to set to transparent mode\n");
ast_log(LOG_WARNING, "Unable to set to transparent/ringing mode\n");
return -1;
}
@@ -200,6 +200,10 @@ static struct ast_frame *i4l_handle_escape(struct ast_modem_pvt *p, char esc)
p->fr.frametype = AST_FRAME_CONTROL;
p->fr.subclass = AST_CONTROL_RING;
return &p->fr;
case 'I': /* Pseudo ringing */
p->fr.frametype = AST_FRAME_CONTROL;
p->fr.subclass = AST_CONTROL_RINGING;
return &p->fr;
case 'X': /* Pseudo connect */
p->fr.frametype = AST_FRAME_CONTROL;
p->fr.subclass = AST_CONTROL_ANSWER;
@@ -287,12 +291,17 @@ static struct ast_frame *i4l_read(struct ast_modem_pvt *p)
return i4l_handle_escape(p, 'b');
} else
if (!strncasecmp(result, "CALLER NUMBER: ", 15 )) {
strncpy(p->cid, result + 15, sizeof(p->cid));
strncpy(p->cid, result + 15, sizeof(p->cid)-1);
return i4l_handle_escape(p, 'R');
} else
if (!strcasecmp(result, "RINGING")) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "%s is ringing...\n", p->dev);
return i4l_handle_escape(p, 'I');
} else
if (!strncasecmp(result, "RING", 4)) {
if (result[4]=='/')
strncpy(p->dnid, result + 4, sizeof(p->dnid));
strncpy(p->dnid, result + 4, sizeof(p->dnid)-1);
return i4l_handle_escape(p, 'R');
} else
if (!strcasecmp(result, "NO CARRIER")) {
@@ -377,7 +386,7 @@ static struct ast_frame *i4l_read(struct ast_modem_pvt *p)
static int i4l_write(struct ast_modem_pvt *p, struct ast_frame *f)
{
#define MAX_WRITE_SIZE 512
#define MAX_WRITE_SIZE 1024
unsigned char result[MAX_WRITE_SIZE << 1];
unsigned char b;
int bpos=0, x;
@@ -407,8 +416,10 @@ static int i4l_write(struct ast_modem_pvt *p, struct ast_frame *f)
res = write(p->fd, result, bpos);
#endif
if (res < 1) {
ast_log(LOG_WARNING, "Failed to write buffer\n");
return -1;
if (errno != EAGAIN) {
ast_log(LOG_WARNING, "Failed to write buffer\n");
return -1;
}
}
#if 0
printf("Result of write is %d\n", res);
@@ -439,7 +450,7 @@ static void i4l_decusecnt()
static int i4l_answer(struct ast_modem_pvt *p)
{
if (ast_modem_send(p, "ATA", 0) ||
if (ast_modem_send(p, "ATA\r", 4) ||
ast_modem_expect(p, "VCON", 10)) {
ast_log(LOG_WARNING, "Unable to answer: %s", p->response);
return -1;

View File

@@ -15,6 +15,7 @@
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/frame.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
@@ -55,16 +56,11 @@
static struct timeval lasttime;
static int usecnt;
static int needanswer = 0;
static int needringing = 0;
static int needhangup = 0;
static int silencesuppression = 0;
static int silencethreshold = 1000;
static char digits[80] = "";
static char text2send[80] = "";
static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
static char *type = "Console";
static char *desc = "OSS Console Channel Driver";
@@ -75,9 +71,6 @@ static char context[AST_MAX_EXTENSION] = "default";
static char language[MAX_LANGUAGE] = "";
static char exten[AST_MAX_EXTENSION] = "s";
/* Command pipe */
static int cmd[2];
int hookstate=0;
static short silence[FRAME_SIZE] = {0, };
@@ -433,13 +426,18 @@ static int oss_text(struct ast_channel *c, char *text)
static int oss_call(struct ast_channel *c, char *dest, int timeout)
{
int res = 3;
struct ast_frame f = { 0, };
ast_verbose( " << Call placed to '%s' on console >> \n", dest);
if (autoanswer) {
ast_verbose( " << Auto-answered >> \n" );
needanswer = 1;
f.frametype = AST_FRAME_CONTROL;
f.subclass = AST_CONTROL_ANSWER;
ast_queue_frame(c, &f, 0);
} else {
ast_verbose( " << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
needringing = 1;
f.frametype = AST_FRAME_CONTROL;
f.subclass = AST_CONTROL_RINGING;
ast_queue_frame(c, &f, 0);
write(sndcmd[1], &res, sizeof(res));
}
return 0;
@@ -465,7 +463,7 @@ static int oss_answer(struct ast_channel *c)
static int oss_hangup(struct ast_channel *c)
{
int res;
int res = 0;
cursound = -1;
c->pvt->pvt = NULL;
oss.owner = NULL;
@@ -473,11 +471,15 @@ static int oss_hangup(struct ast_channel *c)
ast_pthread_mutex_lock(&usecnt_lock);
usecnt--;
ast_pthread_mutex_unlock(&usecnt_lock);
needhangup = 0;
needanswer = 0;
if (hookstate) {
res = 2;
write(sndcmd[1], &res, sizeof(res));
if (autoanswer) {
/* Assume auto-hangup too */
hookstate = 0;
} else {
/* Make congestion noise */
res = 2;
write(sndcmd[1], &res, sizeof(res));
}
}
return 0;
}
@@ -529,7 +531,7 @@ static int oss_write(struct ast_channel *chan, struct ast_frame *f)
return 0;
/* Stop any currently playing sound */
cursound = -1;
if (!full_duplex && (strlen(digits) || needhangup || needanswer)) {
if (!full_duplex) {
/* If we're half duplex, we have to switch to read mode
to honor immediate needs if necessary */
res = soundcard_setinput(1);
@@ -572,18 +574,11 @@ static struct ast_frame *oss_read(struct ast_channel *chan)
static char buf[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];
static int readpos = 0;
int res;
int b;
int nonull=0;
#if 0
ast_log(LOG_DEBUG, "oss_read()\n");
#endif
/* Acknowledge any pending cmd */
res = read(cmd[0], &b, sizeof(b));
if (res > 0)
nonull = 1;
f.frametype = AST_FRAME_NULL;
f.subclass = 0;
f.timelen = 0;
@@ -593,44 +588,6 @@ static struct ast_frame *oss_read(struct ast_channel *chan)
f.src = type;
f.mallocd = 0;
if (needringing) {
f.frametype = AST_FRAME_CONTROL;
f.subclass = AST_CONTROL_RINGING;
needringing = 0;
return &f;
}
if (needhangup) {
needhangup = 0;
return NULL;
}
if (strlen(text2send)) {
f.frametype = AST_FRAME_TEXT;
f.subclass = 0;
f.data = text2send;
f.datalen = strlen(text2send);
strcpy(text2send,"");
return &f;
}
if (strlen(digits)) {
f.frametype = AST_FRAME_DTMF;
f.subclass = digits[0];
for (res=0;res<strlen(digits);res++)
digits[res] = digits[res + 1];
return &f;
}
if (needanswer) {
needanswer = 0;
f.frametype = AST_FRAME_CONTROL;
f.subclass = AST_CONTROL_ANSWER;
chan->state = AST_STATE_UP;
return &f;
}
if (nonull)
return &f;
res = soundcard_setinput(0);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set input mode\n");
@@ -709,12 +666,11 @@ static int oss_indicate(struct ast_channel *chan, int cond)
static struct ast_channel *oss_new(struct chan_oss_pvt *p, int state)
{
struct ast_channel *tmp;
tmp = ast_channel_alloc();
tmp = ast_channel_alloc(1);
if (tmp) {
snprintf(tmp->name, sizeof(tmp->name), "OSS/%s", DEV_DSP + 5);
tmp->type = type;
tmp->fds[0] = sounddev;
tmp->fds[1] = cmd[0];
tmp->nativeformats = AST_FORMAT_SLINEAR;
tmp->pvt->pvt = p;
tmp->pvt->send_digit = oss_digit;
@@ -727,11 +683,11 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *p, int state)
tmp->pvt->indicate = oss_indicate;
tmp->pvt->fixup = oss_fixup;
if (strlen(p->context))
strncpy(tmp->context, p->context, sizeof(tmp->context));
strncpy(tmp->context, p->context, sizeof(tmp->context)-1);
if (strlen(p->exten))
strncpy(tmp->exten, p->exten, sizeof(tmp->exten));
strncpy(tmp->exten, p->exten, sizeof(tmp->exten)-1);
if (strlen(language))
strncpy(tmp->language, language, sizeof(tmp->language));
strncpy(tmp->language, language, sizeof(tmp->language)-1);
p->owner = tmp;
tmp->state = state;
ast_pthread_mutex_lock(&usecnt_lock);
@@ -813,6 +769,7 @@ static char autoanswer_usage[] =
static int console_answer(int fd, int argc, char *argv[])
{
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
if (argc != 1)
return RESULT_SHOWUSAGE;
if (!oss.owner) {
@@ -821,7 +778,7 @@ static int console_answer(int fd, int argc, char *argv[])
}
hookstate = 1;
cursound = -1;
needanswer++;
ast_queue_frame(oss.owner, &f, 1);
answer_sound();
return RESULT_SUCCESS;
}
@@ -833,6 +790,8 @@ static char sendtext_usage[] =
static int console_sendtext(int fd, int argc, char *argv[])
{
int tmparg = 1;
char text2send[256];
struct ast_frame f = { 0, };
if (argc < 1)
return RESULT_SHOWUSAGE;
if (!oss.owner) {
@@ -846,7 +805,13 @@ static int console_sendtext(int fd, int argc, char *argv[])
strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send));
strncat(text2send, " ", sizeof(text2send) - strlen(text2send));
}
needanswer++;
if (strlen(text2send)) {
f.frametype = AST_FRAME_TEXT;
f.subclass = 0;
f.data = text2send;
f.datalen = strlen(text2send);
ast_queue_frame(oss.owner, &f, 1);
}
return RESULT_SUCCESS;
}
@@ -864,8 +829,9 @@ static int console_hangup(int fd, int argc, char *argv[])
return RESULT_FAILURE;
}
hookstate = 0;
if (oss.owner)
needhangup++;
if (oss.owner) {
ast_queue_hangup(oss.owner, 1);
}
return RESULT_SUCCESS;
}
@@ -878,14 +844,16 @@ static int console_dial(int fd, int argc, char *argv[])
{
char tmp[256], *tmp2;
char *mye, *myc;
int b = 0;
int x;
struct ast_frame f = { AST_FRAME_DTMF, 0 };
if ((argc != 1) && (argc != 2))
return RESULT_SHOWUSAGE;
if (oss.owner) {
if (argc == 2) {
strncat(digits, argv[1], sizeof(digits) - strlen(digits));
/* Wake up the polling thread */
write(cmd[1], &b, sizeof(b));
for (x=0;x<strlen(argv[1]);x++) {
f.subclass = argv[1][x];
ast_queue_frame(oss.owner, &f, 1);
}
} else {
ast_cli(fd, "You're already in a call. You can use this only to dial digits until you hangup\n");
return RESULT_FAILURE;
@@ -895,7 +863,7 @@ static int console_dial(int fd, int argc, char *argv[])
mye = exten;
myc = context;
if (argc == 2) {
strncpy(tmp, argv[1], sizeof(tmp));
strncpy(tmp, argv[1], sizeof(tmp)-1);
strtok(tmp, "@");
tmp2 = strtok(NULL, "@");
if (strlen(tmp))
@@ -904,8 +872,8 @@ static int console_dial(int fd, int argc, char *argv[])
myc = tmp2;
}
if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
strncpy(oss.exten, mye, sizeof(oss.exten));
strncpy(oss.context, myc, sizeof(oss.context));
strncpy(oss.exten, mye, sizeof(oss.exten)-1);
strncpy(oss.context, myc, sizeof(oss.context)-1);
hookstate = 1;
oss_new(&oss, AST_STATE_UP);
} else
@@ -930,23 +898,15 @@ int load_module()
{
int res;
int x;
int flags;
struct ast_config *cfg = ast_load(config);
struct ast_variable *v;
res = pipe(cmd);
res = pipe(sndcmd);
if (res) {
ast_log(LOG_ERROR, "Unable to create pipe\n");
return -1;
}
flags = fcntl(cmd[0], F_GETFL);
fcntl(cmd[0], F_SETFL, flags | O_NONBLOCK);
flags = fcntl(cmd[1], F_GETFL);
fcntl(cmd[1], F_SETFL, flags | O_NONBLOCK);
res = soundcard_init();
if (res < 0) {
close(cmd[1]);
close(cmd[0]);
if (option_verbose > 1) {
ast_verbose(VERBOSE_PREFIX_2 "No sound card detected -- console channel will be unavailable\n");
ast_verbose(VERBOSE_PREFIX_2 "Turn off OSS support by adding 'noload=chan_oss.so' in /etc/asterisk/modules.conf\n");
@@ -972,11 +932,11 @@ int load_module()
else if (!strcasecmp(v->name, "silencethreshold"))
silencethreshold = atoi(v->value);
else if (!strcasecmp(v->name, "context"))
strncpy(context, v->value, sizeof(context));
strncpy(context, v->value, sizeof(context)-1);
else if (!strcasecmp(v->name, "language"))
strncpy(language, v->value, sizeof(language));
strncpy(language, v->value, sizeof(language)-1);
else if (!strcasecmp(v->name, "extension"))
strncpy(exten, v->value, sizeof(exten));
strncpy(exten, v->value, sizeof(exten)-1);
v=v->next;
}
ast_destroy(cfg);
@@ -993,10 +953,6 @@ int unload_module()
for (x=0;x<sizeof(myclis)/sizeof(struct ast_cli_entry); x++)
ast_cli_unregister(myclis + x);
close(sounddev);
if (cmd[0] > 0) {
close(cmd[0]);
close(cmd[1]);
}
if (sndcmd[0] > 0) {
close(sndcmd[0]);
close(sndcmd[1]);

View File

@@ -14,6 +14,7 @@
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <asterisk/lock.h>
#include <asterisk/channel.h>
#include <asterisk/channel_pvt.h>
#include <asterisk/config.h>
@@ -55,14 +56,14 @@ static int silencesupression = 0;
static int prefformat = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW;
static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
/* Protect the interface list (of phone_pvt's) */
static pthread_mutex_t iflock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t iflock = AST_MUTEX_INITIALIZER;
/* Protect the monitoring thread, so only one process can kill or start it, and not
when it's doing something critical. */
static pthread_mutex_t monlock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t monlock = AST_MUTEX_INITIALIZER;
/* This is the thread for the monitor which checks for input on the channels
which are not currently in use. */
@@ -140,7 +141,31 @@ static int phone_digit(struct ast_channel *ast, char digit)
static int phone_call(struct ast_channel *ast, char *dest, int timeout)
{
struct phone_pvt *p;
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_RINGING };
// CID stuff for the phonejack...
PHONE_CID cid;
time_t UtcTime;
struct tm *t;
if (ast->callerid) {
time(&UtcTime);
t = localtime(&UtcTime);
if(t != NULL) {
sprintf(cid.month, "%02d",(t->tm_mon + 1));
sprintf(cid.day, "%02d", t->tm_mday);
sprintf(cid.hour, "%02d", t->tm_hour);
sprintf(cid.min, "%02d", t->tm_min);
}
strcpy(cid.name, "Unknown");
sprintf(cid.number,"%s",ast->callerid);
}
p = ast->pvt->pvt;
if ((ast->state != AST_STATE_DOWN) && (ast->state != AST_STATE_RESERVED)) {
ast_log(LOG_WARNING, "phone_call called on %s, neither down nor reserved\n", ast->name);
return -1;
@@ -149,7 +174,9 @@ static int phone_call(struct ast_channel *ast, char *dest, int timeout)
ring the phone and wait for someone to answer */
if (option_debug)
ast_log(LOG_DEBUG, "Ringing %s on %s (%d)\n", dest, ast->name, ast->fds[0]);
ioctl(p->fd, PHONE_RING_START);
ioctl(p->fd, PHONE_RING_START,&cid);
ast_queue_frame(ast, &f, 0);
ast->state = AST_STATE_RINGING;
return 0;
}
@@ -336,7 +363,7 @@ static struct ast_frame *phone_exception(struct ast_channel *ast)
if (phonee.bits.pstn_ring)
ast_verbose("Unit is ringing\n");
if (phonee.bits.caller_id) {
ast_verbose("We have caller ID: %s\n");
ast_verbose("We have caller ID\n");
}
if (phonee.bits.pstn_wink)
ast_verbose("Detected Wink\n");
@@ -351,6 +378,7 @@ static struct ast_frame *phone_read(struct ast_channel *ast)
{
int res;
struct phone_pvt *p = ast->pvt->pvt;
/* Some nice norms */
p->fr.datalen = 0;
@@ -448,14 +476,13 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
char tmpbuf[4];
/* Write a frame of (presumably voice) data */
if (frame->frametype != AST_FRAME_VOICE) {
ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
ast_frfree(frame);
return -1;
if (frame->frametype != AST_FRAME_IMAGE)
ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
return 0;
}
if (!(frame->subclass &
(AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW))) {
ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
ast_frfree(frame);
return -1;
}
/* If we're not in up mode, go into up mode now */
@@ -560,17 +587,20 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
res = phone_write_buf(p, pos, expected, maxfr);
}
if (res != expected) {
if (res < 0)
ast_log(LOG_WARNING, "Write returned error (%s)\n", strerror(errno));
/*
* Card is in non-blocking mode now and it works well now, but there are
* lot of messages like this. So, this message is temporarily disabled.
*/
if (errno != EAGAIN) {
if (res < 0)
ast_log(LOG_WARNING, "Write returned error (%s)\n", strerror(errno));
/*
* Card is in non-blocking mode now and it works well now, but there are
* lot of messages like this. So, this message is temporarily disabled.
*/
#if 0
else
ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frame->datalen);
else
ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frame->datalen);
#endif
return -1;
return -1;
} else /* Pretend it worked */
res = expected;
}
sofar += res;
pos += res;
@@ -581,13 +611,15 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *context)
{
struct ast_channel *tmp;
tmp = ast_channel_alloc();
tmp = ast_channel_alloc(1);
if (tmp) {
snprintf(tmp->name, sizeof(tmp->name), "Phone/%s", i->dev + 5);
tmp->type = type;
tmp->fds[0] = i->fd;
/* XXX Switching formats silently causes kernel panics XXX */
tmp->nativeformats = prefformat;
tmp->pvt->rawreadformat = prefformat;
tmp->pvt->rawwriteformat = prefformat;
tmp->state = state;
if (state == AST_STATE_RING)
tmp->rings = 1;
@@ -599,11 +631,11 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte
tmp->pvt->read = phone_read;
tmp->pvt->write = phone_write;
tmp->pvt->exception = phone_exception;
strncpy(tmp->context, context, sizeof(tmp->context));
strncpy(tmp->context, context, sizeof(tmp->context)-1);
if (strlen(i->ext))
strncpy(tmp->exten, i->ext, sizeof(tmp->exten));
strncpy(tmp->exten, i->ext, sizeof(tmp->exten)-1);
if (strlen(i->language))
strncpy(tmp->language, i->language, sizeof(tmp->language));
strncpy(tmp->language, i->language, sizeof(tmp->language)-1);
if (strlen(i->callerid))
tmp->callerid = strdup(i->callerid);
i->owner = tmp;
@@ -911,7 +943,7 @@ static struct phone_pvt *mkif(char *iface, int mode, int txgain, int rxgain)
ast_log(LOG_DEBUG, "Unable to set port to PSTN\n");
} else {
if (ioctl(tmp->fd, IXJCTL_PORT, PORT_POTS))
ast_log(LOG_DEBUG, "Unable to set port to PSTN\n");
ast_log(LOG_DEBUG, "Unable to set port to POTS\n");
}
ioctl(tmp->fd, PHONE_PLAY_STOP);
ioctl(tmp->fd, PHONE_REC_STOP);
@@ -934,14 +966,14 @@ static struct phone_pvt *mkif(char *iface, int mode, int txgain, int rxgain)
tmp->lastinput = -1;
tmp->ministate = 0;
memset(tmp->ext, 0, sizeof(tmp->ext));
strncpy(tmp->language, language, sizeof(tmp->language));
strncpy(tmp->dev, iface, sizeof(tmp->dev));
strncpy(tmp->context, context, sizeof(tmp->context));
strncpy(tmp->language, language, sizeof(tmp->language)-1);
strncpy(tmp->dev, iface, sizeof(tmp->dev)-1);
strncpy(tmp->context, context, sizeof(tmp->context)-1);
tmp->next = NULL;
tmp->obuflen = 0;
tmp->dialtone = 0;
tmp->cpt = 0;
strncpy(tmp->callerid, callerid, sizeof(tmp->callerid));
strncpy(tmp->callerid, callerid, sizeof(tmp->callerid)-1);
tmp->txgain = txgain;
ioctl(tmp->fd, PHONE_PLAY_VOLUME, tmp->txgain);
tmp->rxgain = rxgain;
@@ -1044,9 +1076,9 @@ int load_module()
} else if (!strcasecmp(v->name, "silencesupression")) {
silencesupression = ast_true(v->value);
} else if (!strcasecmp(v->name, "language")) {
strncpy(language, v->value, sizeof(language));
strncpy(language, v->value, sizeof(language)-1);
} else if (!strcasecmp(v->name, "callerid")) {
strncpy(callerid, v->value, sizeof(callerid));
strncpy(callerid, v->value, sizeof(callerid)-1);
} else if (!strcasecmp(v->name, "mode")) {
if (!strncasecmp(v->value, "di", 2))
mode = MODE_DIALTONE;
@@ -1057,7 +1089,7 @@ int load_module()
else
ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value);
} else if (!strcasecmp(v->name, "context")) {
strncpy(context, v->value, sizeof(context));
strncpy(context, v->value, sizeof(context)-1);
} else if (!strcasecmp(v->name, "format")) {
if (!strcasecmp(v->value, "g723.1")) {
prefformat = AST_FORMAT_G723_1;
@@ -1088,7 +1120,7 @@ int load_module()
ast_pthread_mutex_unlock(&iflock);
/* Make sure we can register our Adtranphone channel type */
if (ast_channel_register(type, tdesc,
AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW, phone_request)) {
AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW, phone_request)) {
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
ast_destroy(cfg);
unload_module();

1951
channels/chan_sip.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -14,6 +14,7 @@
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <asterisk/lock.h>
#include <asterisk/channel.h>
#include <asterisk/channel_pvt.h>
#include <asterisk/config.h>
@@ -52,14 +53,14 @@ static char context[AST_MAX_EXTENSION] = "default";
static char language[MAX_LANGUAGE] = "";
static int usecnt =0;
static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
/* Protect the interface list (of vofr_pvt's) */
static pthread_mutex_t iflock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t iflock = AST_MUTEX_INITIALIZER;
/* Protect the monitoring thread, so only one process can kill or start it, and not
when it's doing something critical. */
static pthread_mutex_t monlock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t monlock = AST_MUTEX_INITIALIZER;
/* This is the thread for the monitor which checks for input on the channels
which are not currently in use. */
@@ -798,7 +799,7 @@ static int vofr_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
static struct ast_channel *vofr_new(struct vofr_pvt *i, int state)
{
struct ast_channel *tmp;
tmp = ast_channel_alloc();
tmp = ast_channel_alloc(0);
if (tmp) {
#ifdef OLD_SANGOMA_API
snprintf(tmp->name, sizeof(tmp->name), "AdtranVoFR/%s", i->sa.spkt_device);
@@ -823,13 +824,13 @@ static struct ast_channel *vofr_new(struct vofr_pvt *i, int state)
tmp->pvt->write = vofr_write;
tmp->pvt->fixup = vofr_fixup;
if (strlen(i->language))
strncpy(tmp->language, i->language, sizeof(tmp->language));
strncpy(tmp->language, i->language, sizeof(tmp->language)-1);
i->owner = tmp;
ast_pthread_mutex_lock(&usecnt_lock);
usecnt++;
ast_pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
strncpy(tmp->context, i->context, sizeof(tmp->context));
strncpy(tmp->context, i->context, sizeof(tmp->context)-1);
if (state != AST_STATE_DOWN) {
if (ast_pbx_start(tmp)) {
ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
@@ -1050,7 +1051,7 @@ static struct vofr_pvt *mkif(char *type, char *iface)
#ifdef OLD_SANGOMA_API
/* Prepare sockaddr for binding */
memset(&tmp->sa, 0, sizeof(tmp->sa));
strncpy(tmp->sa.spkt_device, iface, sizeof(tmp->sa.spkt_device));
strncpy(tmp->sa.spkt_device, iface, sizeof(tmp->sa.spkt_device)-1);
tmp->sa.spkt_protocol = htons(0x16);
tmp->sa.spkt_family = AF_PACKET;
if (bind(tmp->s, (struct sockaddr *)&tmp->sa, sizeof(struct sockaddr))) {
@@ -1059,8 +1060,8 @@ static struct vofr_pvt *mkif(char *type, char *iface)
memset(&tmp->sa, 0, sizeof(tmp->sa));
tmp->sa.sll_family = AF_WANPIPE;
tmp->sa.sll_protocol = htons(ETH_P_IP);
strncpy(tmp->sa.sll_device, iface, sizeof(tmp->sa.sll_device));
strncpy(tmp->sa.sll_card, "wanpipe1", sizeof(tmp->sa.sll_card));
strncpy(tmp->sa.sll_device, iface, sizeof(tmp->sa.sll_device)-1);
strncpy(tmp->sa.sll_card, "wanpipe1", sizeof(tmp->sa.sll_card)-1);
tmp->sa.sll_ifindex = 0;
if (bind(tmp->s, (struct sockaddr *)&tmp->sa, sizeof(struct wan_sockaddr_ll))) {
#endif
@@ -1088,8 +1089,8 @@ static struct vofr_pvt *mkif(char *type, char *iface)
tmp->dlcih = 0;
tmp->cid = 1;
tmp->ringgothangup = 0;
strncpy(tmp->language, language, sizeof(tmp->language));
strncpy(tmp->context, context, sizeof(tmp->context));
strncpy(tmp->language, language, sizeof(tmp->language)-1);
strncpy(tmp->context, context, sizeof(tmp->context)-1);
/* User terminations are game for outgoing connections */
if (!strcasecmp(type, "user"))
tmp->outgoing = 1;
@@ -1169,9 +1170,9 @@ int load_module()
return -1;
}
} else if (!strcasecmp(v->name, "context")) {
strncpy(context, v->value, sizeof(context));
strncpy(context, v->value, sizeof(context)-1);
} else if (!strcasecmp(v->name, "language")) {
strncpy(language, v->value, sizeof(language));
strncpy(language, v->value, sizeof(language)-1);
}
v = v->next;
}

File diff suppressed because it is too large Load Diff

157
channels/gentone-ulaw.c Normal file
View File

@@ -0,0 +1,157 @@
/* Generate a header file for a particular
single or double frequency */
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define CLIP 32635
#define BIAS 0x84
static float loudness=16384.0;
static int calc_samples(int freq)
{
int x, samples;
/* Calculate the number of samples at 8000hz sampling
we need to have this wave form */
samples = 8000;
/* Take out common 2's up to six times */
for (x=0;x<6;x++)
if (!(freq % 2)) {
freq /= 2;
samples /= 2;
}
/* Take out common 5's (up to three times */
for (x=0;x<3;x++)
if (!(freq % 5)) {
freq /= 5;
samples /=5;
}
/* No more common factors. */
return samples;
}
/*
** This routine converts from linear to ulaw
**
** Craig Reese: IDA/Supercomputing Research Center
** Joe Campbell: Department of Defense
** 29 September 1989
**
** References:
** 1) CCITT Recommendation G.711 (very difficult to follow)
** 2) "A New Digital Technique for Implementation of Any
** Continuous PCM Companding Law," Villeret, Michel,
** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
** 1973, pg. 11.12-11.17
** 3) MIL-STD-188-113,"Interoperability and Performance Standards
** for Analog-to_Digital Conversion Techniques,"
** 17 February 1987
**
** Input: Signed 16 bit linear sample
** Output: 8 bit ulaw sample
*/
#define ZEROTRAP /* turn on the trap as per the MIL-STD */
#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
#define CLIP 32635
static unsigned char linear2ulaw(short sample) {
static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
int sign, exponent, mantissa;
unsigned char ulawbyte;
/* Get the sample into sign-magnitude. */
sign = (sample >> 8) & 0x80; /* set aside the sign */
if (sign != 0) sample = -sample; /* get magnitude */
if (sample > CLIP) sample = CLIP; /* clip the magnitude */
/* Convert from 16 bit linear to ulaw. */
sample = sample + BIAS;
exponent = exp_lut[(sample >> 7) & 0xFF];
mantissa = (sample >> (exponent + 3)) & 0x0F;
ulawbyte = ~(sign | (exponent << 4) | mantissa);
#ifdef ZEROTRAP
if (ulawbyte == 0) ulawbyte = 0x02; /* optional CCITT trap */
#endif
return(ulawbyte);
}
int main(int argc, char *argv[])
{
FILE *f;
int freq1, freq2;
float wlen1, wlen2;
float val;
int x, samples1, samples2, samples=0;
char fn[256];
if (argc < 3) {
fprintf(stderr, "Usage: gensound <name> <freq1> [freq2]\n");
exit(1);
}
freq1 = atoi(argv[2]);
if (argc > 3)
freq2 = atoi(argv[3]);
else
freq2 = 0;
wlen1 = 8000.0/(float)freq1;
samples1 = calc_samples(freq1);
printf("Wavelength 1 (in samples): %10.5f\n", wlen1);
printf("Minimum samples (1): %d (%f.3 wavelengths)\n", samples1, samples1 / wlen1);
if (freq2) {
wlen2 = 8000.0/(float)freq2;
samples2 = calc_samples(freq2);
printf("Wavelength 1 (in samples): %10.5f\n", wlen2);
printf("Minimum samples (1): %d (%f.3 wavelengths)\n", samples2, samples2 / wlen2);
}
samples = samples1;
if (freq2) {
while(samples % samples2)
samples += samples1;
}
printf("Need %d samples\n", samples);
snprintf(fn, sizeof(fn), "%s.h", argv[1]);
if ((f = fopen(fn, "w"))) {
if (freq2)
fprintf(f, "/* %s: Generated from frequencies %d and %d \n"
" by gentone. %d samples */\n", fn, freq1, freq2, samples);
else
fprintf(f, "/* %s: Generated from frequency %d\n"
" by gentone. %d samples */\n", fn, freq1, samples);
fprintf(f, "static unsigned char %s[%d] = {\n\t", argv[1], samples);
for (x=0;x<samples;x++) {
val = loudness * sin((freq1 * 2.0 * M_PI * x)/8000.0);
if (freq2)
val += loudness * sin((freq2 * 2.0 * M_PI * x)/8000.0);
fprintf(f, "%3d, ", (int) linear2ulaw(val));
if (!((x+1) % 8))
fprintf(f, "\n\t");
}
if (x % 15)
fprintf(f, "\n");
fprintf(f, "};\n");
fclose(f);
printf("Wrote %s\n", fn);
} else {
fprintf(stderr, "Unable to open %s for writing\n", fn);
return 1;
}
return 0;
}

View File

@@ -69,10 +69,10 @@ int main(int argc, char *argv[])
if ((f = fopen(fn, "w"))) {
if (freq2)
fprintf(f, "/* %s: Generated from frequencies %d and %d \n"
" by gensound. %d samples */\n", fn, freq1, freq2, samples);
" by gentone. %d samples */\n", fn, freq1, freq2, samples);
else
fprintf(f, "/* %s: Generated from frequency %d\n"
" by gensound. %d samples */\n", fn, freq1, samples);
" by gentone. %d samples */\n", fn, freq1, samples);
fprintf(f, "static short %s[%d] = {\n\t", argv[1], samples);
for (x=0;x<samples;x++) {
val = loudness * sin((freq1 * 2.0 * M_PI * x)/8000.0);

View File

@@ -1,8 +1,8 @@
/******************************************************************************
$Id$
$Log$
Revision 1.10 1999/12/01 05:25:58 markster
Version 0.1.9 from FTP
Revision 1.13 1999/12/01 05:25:58 markster
Version 0.1.12 from FTP
Revision 1.1 1999/12/01 05:25:58 markster
Start on the Internet Phone Jack channel

33
cli.c
View File

@@ -43,7 +43,7 @@ void ast_cli(int fd, char *fmt, ...)
write(fd, stuff, strlen(stuff));
}
pthread_mutex_t clilock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t clilock = AST_MUTEX_INITIALIZER;
struct ast_cli_entry *helpers = NULL;
@@ -154,7 +154,7 @@ static int handle_unload(int fd, int argc, char *argv[])
#define MODLIST_FORMAT "%-20s %-40.40s %-10d\n"
#define MODLIST_FORMAT2 "%-20s %-40.40s %-10s\n"
static pthread_mutex_t climodentrylock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t climodentrylock = AST_MUTEX_INITIALIZER;
static int climodentryfd = -1;
static int modlist_modentry(char *module, char *description, int usecnt)
@@ -325,7 +325,7 @@ static char *complete_fn(char *line, char *word, int pos, int state)
if (pos != 1)
return NULL;
if (word[0] == '/')
strncpy(filename, word, sizeof(filename));
strncpy(filename, word, sizeof(filename)-1);
else
snprintf(filename, sizeof(filename), "%s/%s", AST_MODULE_DIR, word);
c = (char*)filename_completion_function(filename, state);
@@ -441,13 +441,17 @@ int ast_cli_unregister(struct ast_cli_entry *e)
cur = helpers;
while(cur) {
if (e == cur) {
/* Rewrite */
if (l)
l->next = e->next;
else
helpers = e->next;
e->next = NULL;
break;
if (e->inuse) {
ast_log(LOG_WARNING, "Can't remove command that is in use\n");
} else {
/* Rewrite */
if (l)
l->next = e->next;
else
helpers = e->next;
e->next = NULL;
break;
}
}
l = cur;
cur = cur->next;
@@ -719,6 +723,9 @@ int ast_cli_command(int fd, char *s)
if (x > 0) {
ast_pthread_mutex_lock(&clilock);
e = find_cli(argv, 0);
if (e)
e->inuse++;
ast_pthread_mutex_unlock(&clilock);
if (e) {
switch(e->handler(fd, x, argv)) {
case RESULT_SHOWUSAGE:
@@ -728,7 +735,11 @@ int ast_cli_command(int fd, char *s)
}
} else
ast_cli(fd, "No such command '%s' (type 'help' for help)\n", find_best(argv));
ast_pthread_mutex_unlock(&clilock);
if (e) {
ast_pthread_mutex_lock(&clilock);
e->inuse--;
ast_pthread_mutex_unlock(&clilock);
}
}
free(dup);
} else {

View File

@@ -25,10 +25,13 @@ CFLAGS+=
LIBG723=g723.1/libg723.a
LIBG723B=g723.1b/libg723b.a
LIBGSM=gsm/lib/libgsm.a
LIBGSM=$(shell if uname -m | grep -q 86; then echo gsm/lib/libgsm.a; else echo "-lgsm" ; fi)
LIBGSMT=$(shell if uname -m | grep -q 86; then echo gsm/lib/libgsm.a; fi)
LIBMP3=mp3/libmp3.a
LIBLPC10=lpc10/liblpc10.a
CODECS+=$(MODG723) codec_gsm.so codec_mp3_d.so codec_lpc10.so codec_adpcm.so codec_ulaw.so
CODECS+=$(MODG723) codec_gsm.so codec_mp3_d.so codec_lpc10.so \
codec_adpcm.so codec_ulaw.so codec_alaw.so codec_a_mu.so
all: $(CODECS)
@@ -43,7 +46,7 @@ clean:
$(LIBG723):
make -C g723.1 all
$(LIBGSM):
gsm/lib/libgsm.a:
make -C gsm lib/libgsm.a
$(LIBG723B):
@@ -64,7 +67,7 @@ codec_g723_1b.o : codec_g723_1.c
codec_g723_1b.so : codec_g723_1b.o $(LIBG723B)
$(CC) -shared -Xlinker -x -o $@ $< $(LIBG723B) -lm
codec_gsm.so: codec_gsm.o $(LIBGSM)
codec_gsm.so: codec_gsm.o $(LIBGSMT)
$(CC) -shared -Xlinker -x -o $@ $< $(LIBGSM)
codec_lpc10.so: codec_lpc10.o $(LIBLPC10)

326
codecs/codec_a_mu.c Normal file
View File

@@ -0,0 +1,326 @@
/* codec_a_mu.c - translate between alaw and ulaw directly
*
* Asterisk -- A telephony toolkit for Linux.
*
* Copyright (c) 2001 Linux Support Services, Inc. All rights reserved.
*
* 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/logger.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/channel.h>
#include <asterisk/alaw.h>
#include <asterisk/ulaw.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BUFFER_SIZE 8096 /* size for the translation buffers */
static pthread_mutex_t localuser_lock = AST_MUTEX_INITIALIZER;
static int localusecnt = 0;
static char *tdesc = "A-law and Mulaw direct Coder/Decoder";
static unsigned char mu2a[256];
static unsigned char a2mu[256];
/* Sample frame data (Mu data is okay) */
#include "ulaw_slin_ex.h"
/*
* Private workspace for translating signed linear signals to alaw.
*/
struct alaw_encoder_pvt
{
struct ast_frame f;
char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
unsigned char outbuf[BUFFER_SIZE]; /* Encoded alaw, two nibbles to a word */
int tail;
};
/*
* Private workspace for translating laws.
*/
struct ulaw_encoder_pvt
{
struct ast_frame f;
char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
unsigned char outbuf[BUFFER_SIZE]; /* Encoded ulaw values */
int tail;
};
static struct ast_translator_pvt *
alawtoulaw_new ()
{
struct ulaw_encoder_pvt *tmp;
tmp = malloc (sizeof (struct ulaw_encoder_pvt));
if (tmp)
{
memset(tmp, 0, sizeof(*tmp));
tmp->tail = 0;
localusecnt++;
ast_update_use_count ();
}
return (struct ast_translator_pvt *) tmp;
}
static struct ast_translator_pvt *
ulawtoalaw_new ()
{
struct alaw_encoder_pvt *tmp;
tmp = malloc (sizeof (struct alaw_encoder_pvt));
if (tmp)
{
memset(tmp, 0, sizeof(*tmp));
localusecnt++;
ast_update_use_count ();
tmp->tail = 0;
}
return (struct ast_translator_pvt *) tmp;
}
static int
alawtoulaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
{
struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
int x;
unsigned char *b;
if ((tmp->tail + f->datalen)> sizeof(tmp->outbuf)) {
ast_log(LOG_WARNING, "Out of buffer space\n");
return -1;
}
/* Reset ssindex and signal to frame's specified values */
b = f->data;
for (x=0;x<f->datalen;x++)
tmp->outbuf[tmp->tail + x] = a2mu[b[x]];
tmp->tail += f->datalen;
return 0;
}
static struct ast_frame *
alawtoulaw_frameout (struct ast_translator_pvt *pvt)
{
struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
if (!tmp->tail)
return NULL;
tmp->f.frametype = AST_FRAME_VOICE;
tmp->f.subclass = AST_FORMAT_ULAW;
tmp->f.datalen = tmp->tail;
tmp->f.timelen = tmp->tail / 8;
tmp->f.mallocd = 0;
tmp->f.offset = AST_FRIENDLY_OFFSET;
tmp->f.src = __PRETTY_FUNCTION__;
tmp->f.data = tmp->outbuf;
tmp->tail = 0;
return &tmp->f;
}
static int
ulawtoalaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
{
struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt;
int x;
unsigned char *s;
if (tmp->tail + f->datalen >= sizeof(tmp->outbuf))
{
ast_log (LOG_WARNING, "Out of buffer space\n");
return -1;
}
s = f->data;
for (x=0;x<f->datalen;x++)
tmp->outbuf[x+tmp->tail] = mu2a[s[x]];
tmp->tail += f->datalen;
return 0;
}
/*
* LinToalaw_FrameOut
* Convert a buffer of raw 16-bit signed linear PCM to a buffer
* of 4-bit alaw packed two to a byte (Big Endian).
*
* Results:
* Foo
*
* Side effects:
* Leftover inbuf data gets packed, tail gets updated.
*/
static struct ast_frame *
ulawtoalaw_frameout (struct ast_translator_pvt *pvt)
{
struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt;
if (tmp->tail) {
tmp->f.frametype = AST_FRAME_VOICE;
tmp->f.subclass = AST_FORMAT_ALAW;
tmp->f.timelen = tmp->tail / 8;
tmp->f.mallocd = 0;
tmp->f.offset = AST_FRIENDLY_OFFSET;
tmp->f.src = __PRETTY_FUNCTION__;
tmp->f.data = tmp->outbuf;
tmp->f.datalen = tmp->tail;
tmp->tail = 0;
return &tmp->f;
} else return NULL;
}
/*
* alawToLin_Sample
*/
static struct ast_frame *
alawtoulaw_sample ()
{
static struct ast_frame f;
f.frametype = AST_FRAME_VOICE;
f.subclass = AST_FORMAT_ALAW;
f.datalen = sizeof (ulaw_slin_ex);
f.timelen = sizeof(ulaw_slin_ex) / 8;
f.mallocd = 0;
f.offset = 0;
f.src = __PRETTY_FUNCTION__;
f.data = ulaw_slin_ex;
return &f;
}
static struct ast_frame *
ulawtoalaw_sample ()
{
static struct ast_frame f;
f.frametype = AST_FRAME_VOICE;
f.subclass = AST_FORMAT_ULAW;
f.datalen = sizeof (ulaw_slin_ex);
f.timelen = sizeof(ulaw_slin_ex) / 8;
f.mallocd = 0;
f.offset = 0;
f.src = __PRETTY_FUNCTION__;
f.data = ulaw_slin_ex;
return &f;
}
/*
* alaw_Destroy
* Destroys a private workspace.
*
* Results:
* It's gone!
*
* Side effects:
* None.
*/
static void
alaw_destroy (struct ast_translator_pvt *pvt)
{
free (pvt);
localusecnt--;
ast_update_use_count ();
}
/*
* The complete translator for alawToLin.
*/
static struct ast_translator alawtoulaw = {
"alawtoulaw",
AST_FORMAT_ALAW,
AST_FORMAT_ULAW,
alawtoulaw_new,
alawtoulaw_framein,
alawtoulaw_frameout,
alaw_destroy,
/* NULL */
alawtoulaw_sample
};
/*
* The complete translator for LinToalaw.
*/
static struct ast_translator ulawtoalaw = {
"ulawtoalaw",
AST_FORMAT_ULAW,
AST_FORMAT_ALAW,
ulawtoalaw_new,
ulawtoalaw_framein,
ulawtoalaw_frameout,
alaw_destroy,
/* NULL */
ulawtoalaw_sample
};
int
unload_module (void)
{
int res;
ast_pthread_mutex_lock (&localuser_lock);
res = ast_unregister_translator (&ulawtoalaw);
if (!res)
res = ast_unregister_translator (&alawtoulaw);
if (localusecnt)
res = -1;
ast_pthread_mutex_unlock (&localuser_lock);
return res;
}
int
load_module (void)
{
int res;
int x;
for (x=0;x<256;x++) {
mu2a[x] = AST_LIN2A(AST_MULAW(x));
a2mu[x] = AST_LIN2MU(AST_ALAW(x));
}
res = ast_register_translator (&alawtoulaw);
if (!res)
res = ast_register_translator (&ulawtoalaw);
else
ast_unregister_translator (&alawtoulaw);
return res;
}
/*
* Return a description of this module.
*/
char *
description (void)
{
return tdesc;
}
int
usecount (void)
{
int res;
STANDARD_USECOUNT (res);
return res;
}
char *
key ()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -13,6 +13,7 @@
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/logger.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
@@ -27,7 +28,7 @@
#define BUFFER_SIZE 8096 /* size for the translation buffers */
static pthread_mutex_t localuser_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t localuser_lock = AST_MUTEX_INITIALIZER;
static int localusecnt = 0;
static char *tdesc = "Adaptive Differential PCM Coder/Decoder";

379
codecs/codec_alaw.c Normal file
View File

@@ -0,0 +1,379 @@
/* codec_alaw.c - translate between signed linear and alaw
*
* Asterisk -- A telephony toolkit for Linux.
*
* Copyright (c) 2001 Linux Support Services, Inc. All rights reserved.
*
* 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/logger.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/channel.h>
#include <asterisk/alaw.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BUFFER_SIZE 8096 /* size for the translation buffers */
static pthread_mutex_t localuser_lock = AST_MUTEX_INITIALIZER;
static int localusecnt = 0;
static char *tdesc = "A-law Coder/Decoder";
/* Sample frame data (Mu data is okay) */
#include "slin_ulaw_ex.h"
#include "ulaw_slin_ex.h"
/*
* Private workspace for translating signed linear signals to alaw.
*/
struct alaw_encoder_pvt
{
struct ast_frame f;
char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
unsigned char outbuf[BUFFER_SIZE]; /* Encoded alaw, two nibbles to a word */
int tail;
};
/*
* Private workspace for translating alaw signals to signed linear.
*/
struct alaw_decoder_pvt
{
struct ast_frame f;
char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
short outbuf[BUFFER_SIZE]; /* Decoded signed linear values */
int tail;
};
/*
* alawToLin_New
* Create a new instance of alaw_decoder_pvt.
*
* Results:
* Returns a pointer to the new instance.
*
* Side effects:
* None.
*/
static struct ast_translator_pvt *
alawtolin_new ()
{
struct alaw_decoder_pvt *tmp;
tmp = malloc (sizeof (struct alaw_decoder_pvt));
if (tmp)
{
memset(tmp, 0, sizeof(*tmp));
tmp->tail = 0;
localusecnt++;
ast_update_use_count ();
}
return (struct ast_translator_pvt *) tmp;
}
/*
* LinToalaw_New
* Create a new instance of alaw_encoder_pvt.
*
* Results:
* Returns a pointer to the new instance.
*
* Side effects:
* None.
*/
static struct ast_translator_pvt *
lintoalaw_new ()
{
struct alaw_encoder_pvt *tmp;
tmp = malloc (sizeof (struct alaw_encoder_pvt));
if (tmp)
{
memset(tmp, 0, sizeof(*tmp));
localusecnt++;
ast_update_use_count ();
tmp->tail = 0;
}
return (struct ast_translator_pvt *) tmp;
}
/*
* alawToLin_FrameIn
* Fill an input buffer with packed 4-bit alaw values if there is room
* left.
*
* Results:
* Foo
*
* Side effects:
* tmp->tail is the number of packed values in the buffer.
*/
static int
alawtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
{
struct alaw_decoder_pvt *tmp = (struct alaw_decoder_pvt *) pvt;
int x;
unsigned char *b;
if ((tmp->tail + f->datalen) * 2 > sizeof(tmp->outbuf)) {
ast_log(LOG_WARNING, "Out of buffer space\n");
return -1;
}
/* Reset ssindex and signal to frame's specified values */
b = f->data;
for (x=0;x<f->datalen;x++)
tmp->outbuf[tmp->tail + x] = AST_ALAW(b[x]);
tmp->tail += f->datalen;
return 0;
}
/*
* alawToLin_FrameOut
* Convert 4-bit alaw encoded signals to 16-bit signed linear.
*
* Results:
* Converted signals are placed in tmp->f.data, tmp->f.datalen
* and tmp->f.timelen are calculated.
*
* Side effects:
* None.
*/
static struct ast_frame *
alawtolin_frameout (struct ast_translator_pvt *pvt)
{
struct alaw_decoder_pvt *tmp = (struct alaw_decoder_pvt *) pvt;
if (!tmp->tail)
return NULL;
tmp->f.frametype = AST_FRAME_VOICE;
tmp->f.subclass = AST_FORMAT_SLINEAR;
tmp->f.datalen = tmp->tail *2;
tmp->f.timelen = tmp->tail / 8;
tmp->f.mallocd = 0;
tmp->f.offset = AST_FRIENDLY_OFFSET;
tmp->f.src = __PRETTY_FUNCTION__;
tmp->f.data = tmp->outbuf;
tmp->tail = 0;
return &tmp->f;
}
/*
* LinToalaw_FrameIn
* Fill an input buffer with 16-bit signed linear PCM values.
*
* Results:
* None.
*
* Side effects:
* tmp->tail is number of signal values in the input buffer.
*/
static int
lintoalaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
{
struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt;
int x;
short *s;
if (tmp->tail + f->datalen/2 >= sizeof(tmp->outbuf))
{
ast_log (LOG_WARNING, "Out of buffer space\n");
return -1;
}
s = f->data;
for (x=0;x<f->datalen/2;x++)
tmp->outbuf[x+tmp->tail] = AST_LIN2A(s[x]);
tmp->tail += f->datalen/2;
return 0;
}
/*
* LinToalaw_FrameOut
* Convert a buffer of raw 16-bit signed linear PCM to a buffer
* of 4-bit alaw packed two to a byte (Big Endian).
*
* Results:
* Foo
*
* Side effects:
* Leftover inbuf data gets packed, tail gets updated.
*/
static struct ast_frame *
lintoalaw_frameout (struct ast_translator_pvt *pvt)
{
struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt;
if (tmp->tail) {
tmp->f.frametype = AST_FRAME_VOICE;
tmp->f.subclass = AST_FORMAT_ALAW;
tmp->f.timelen = tmp->tail / 8;
tmp->f.mallocd = 0;
tmp->f.offset = AST_FRIENDLY_OFFSET;
tmp->f.src = __PRETTY_FUNCTION__;
tmp->f.data = tmp->outbuf;
tmp->f.datalen = tmp->tail;
tmp->tail = 0;
return &tmp->f;
} else return NULL;
}
/*
* alawToLin_Sample
*/
static struct ast_frame *
alawtolin_sample ()
{
static struct ast_frame f;
f.frametype = AST_FRAME_VOICE;
f.subclass = AST_FORMAT_ALAW;
f.datalen = sizeof (ulaw_slin_ex);
f.timelen = sizeof(ulaw_slin_ex) / 8;
f.mallocd = 0;
f.offset = 0;
f.src = __PRETTY_FUNCTION__;
f.data = ulaw_slin_ex;
return &f;
}
/*
* LinToalaw_Sample
*/
static struct ast_frame *
lintoalaw_sample ()
{
static struct ast_frame f;
f.frametype = AST_FRAME_VOICE;
f.subclass = AST_FORMAT_SLINEAR;
f.datalen = sizeof (slin_ulaw_ex);
/* Assume 8000 Hz */
f.timelen = sizeof (slin_ulaw_ex) / 16;
f.mallocd = 0;
f.offset = 0;
f.src = __PRETTY_FUNCTION__;
f.data = slin_ulaw_ex;
return &f;
}
/*
* alaw_Destroy
* Destroys a private workspace.
*
* Results:
* It's gone!
*
* Side effects:
* None.
*/
static void
alaw_destroy (struct ast_translator_pvt *pvt)
{
free (pvt);
localusecnt--;
ast_update_use_count ();
}
/*
* The complete translator for alawToLin.
*/
static struct ast_translator alawtolin = {
"alawtolin",
AST_FORMAT_ALAW,
AST_FORMAT_SLINEAR,
alawtolin_new,
alawtolin_framein,
alawtolin_frameout,
alaw_destroy,
/* NULL */
alawtolin_sample
};
/*
* The complete translator for LinToalaw.
*/
static struct ast_translator lintoalaw = {
"lintoalaw",
AST_FORMAT_SLINEAR,
AST_FORMAT_ALAW,
lintoalaw_new,
lintoalaw_framein,
lintoalaw_frameout,
alaw_destroy,
/* NULL */
lintoalaw_sample
};
int
unload_module (void)
{
int res;
ast_pthread_mutex_lock (&localuser_lock);
res = ast_unregister_translator (&lintoalaw);
if (!res)
res = ast_unregister_translator (&alawtolin);
if (localusecnt)
res = -1;
ast_pthread_mutex_unlock (&localuser_lock);
return res;
}
int
load_module (void)
{
int res;
res = ast_register_translator (&alawtolin);
if (!res)
res = ast_register_translator (&lintoalaw);
else
ast_unregister_translator (&alawtolin);
return res;
}
/*
* Return a description of this module.
*/
char *
description (void)
{
return tdesc;
}
int
usecount (void)
{
int res;
STANDARD_USECOUNT (res);
return res;
}
char *
key ()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -54,7 +54,7 @@
#include "slin_g723_ex.h"
#include "g723_slin_ex.h"
static pthread_mutex_t localuser_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t localuser_lock = AST_MUTEX_INITIALIZER;
static int localusecnt=0;
#ifdef ANNEX_B

View File

@@ -19,6 +19,7 @@
#define TYPE_LOW 0x1
#define TYPE_MASK 0x3
#include <asterisk/lock.h>
#include <asterisk/translate.h>
#include <asterisk/module.h>
#include <asterisk/logger.h>
@@ -37,7 +38,7 @@
#include "slin_gsm_ex.h"
#include "gsm_slin_ex.h"
static pthread_mutex_t localuser_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t localuser_lock = AST_MUTEX_INITIALIZER;
static int localusecnt=0;
static char *tdesc = "GSM/PCM16 (signed linear) Codec Translator";

View File

@@ -17,6 +17,7 @@
*/
#include <asterisk/lock.h>
#include <asterisk/translate.h>
#include <asterisk/module.h>
#include <asterisk/logger.h>
@@ -42,7 +43,7 @@
#define LPC10_BYTES_IN_COMPRESSED_FRAME (LPC10_BITS_IN_COMPRESSED_FRAME + 7)/8
static pthread_mutex_t localuser_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t localuser_lock = AST_MUTEX_INITIALIZER;
static int localusecnt=0;
static char *tdesc = "LPC10 2.4kbps (signed linear) Voice Coder";

View File

@@ -14,6 +14,7 @@
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/translate.h>
#include <asterisk/module.h>
#include <asterisk/logger.h>
@@ -40,7 +41,7 @@
#define MAX_FRAME_SIZE 1441
#define MAX_OUTPUT_LEN 2304
static pthread_mutex_t localuser_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t localuser_lock = AST_MUTEX_INITIALIZER;
static int localusecnt=0;
static char *tdesc = "MP3/PCM16 (signed linear) Translator (Decoder only)";

View File

@@ -10,6 +10,7 @@
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/logger.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
@@ -25,7 +26,7 @@
#define BUFFER_SIZE 8096 /* size for the translation buffers */
static pthread_mutex_t localuser_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t localuser_lock = AST_MUTEX_INITIALIZER;
static int localusecnt = 0;
static char *tdesc = "Mu-law Coder/Decoder";
@@ -138,7 +139,7 @@ ulawtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
/* Reset ssindex and signal to frame's specified values */
b = f->data;
for (x=0;x<f->datalen;x++)
tmp->outbuf[tmp->tail + x] = ast_mulaw[b[x]];
tmp->outbuf[tmp->tail + x] = AST_MULAW(b[x]);
tmp->tail += f->datalen;
return 0;
@@ -200,7 +201,7 @@ lintoulaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
}
s = f->data;
for (x=0;x<f->datalen/2;x++)
tmp->outbuf[x+tmp->tail] = ast_lin2mu[s[x]+32768];
tmp->outbuf[x+tmp->tail] = AST_LIN2MU(s[x]);
tmp->tail += f->datalen/2;
return 0;
}

View File

@@ -22,7 +22,8 @@ LIB_TARGET_DIR = .
#
WARNINGS = -Wall -Wno-comment -Wno-error
CFLAGS = -O6 -mpentium -I$(LIB_TARGET_DIR) $(WARNINGS)
CFLAGS = -O6 -I$(LIB_TARGET_DIR) $(WARNINGS)
CFLAGS+= $(shell if uname -m | grep -q 86; then echo "-mpentium" ; fi)
LIB = $(LIB_TARGET_DIR)/liblpc10.a

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -79,8 +79,8 @@ static integer c__1 = 1;
/* ANALYS Version 55 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -246,8 +246,8 @@ static integer c__1 = 1;
real phi[100] /* was [10][10] */, psi[10];
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -277,8 +277,8 @@ static integer c__1 = 1;
/* Frame size, Prediction order, Pitch period */
/* Arguments to ANALYS */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -48,8 +48,8 @@ extern struct {
/* BSYNZ Version 54 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -144,8 +144,8 @@ extern struct {
real lpi0, hpi0;
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -175,8 +175,8 @@ extern struct {
/* Frame size, Prediction order, Pitch period */
/* Arguments */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -35,8 +35,8 @@ extern int chanrd_(integer *order, integer *ipitv, integer *irms, integer *irc,
/* CHANL Version 49 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int dcbias_(integer *len, real *speech, real *sigout);
/* DCBIAS Version 50 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -53,8 +53,8 @@ static integer c__2 = 2;
/* DECODE Version 54 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -188,8 +188,8 @@ static integer c__2 = 2;
integer ishift, errcnt, lsb;
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -219,8 +219,8 @@ static integer c__2 = 2;
/* Frame size, Prediction order, Pitch period */
/* Arguments */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -37,8 +37,8 @@ extern int deemp_(real *x, integer *n, struct lpc10_decoder_state *st);
/* DEEMP Version 48 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int difmag_(real *speech, integer *lpita, integer *tau, integer *ltau, in
/* DIFMAG Version 49 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -47,8 +47,8 @@ extern struct {
/* DYPTRK Version 52 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -136,8 +136,8 @@ extern struct {
/* Arguments */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -43,8 +43,8 @@ static integer c__2 = 2;
/* ENCODE Version 54 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -128,8 +128,8 @@ static integer c__2 = 2;
integer idel, nbit, i__, j, i2, i3, mrk;
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -151,8 +151,8 @@ static integer c__2 = 2;
/* Frame size, Prediction order, Pitch period */
/* Arguments */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int energy_(integer *len, real *speech, real *rms);
/* ENERGY Version 50 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int ham84_(integer *input, integer *output, integer *errcnt);
/* HAM84 Version 45G */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -39,8 +39,8 @@ extern int inithp100_(void);
/* HP100 Version 55 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int invert_(integer *order, real *phi, real *psi, real *rc);
/* INVERT Version 45G */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -91,8 +91,8 @@ extern int invert_(integer *order, real *phi, real *psi, real *rc);
/* Arguments */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int irc2pc_(real *rc, real *pc, integer *order, real *gprime, real *g2pas
/* IRC2PC Version 48 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -82,8 +82,8 @@ extern int irc2pc_(real *rc, real *pc, integer *order, real *gprime, real *g2pas
/* Arguments */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int ivfilt_(real *lpbuf, real *ivbuf, integer *len, integer *nsamp, real
/* IVFILT Version 48 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 00:20:06 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 00:20:06 markster
Version 0.1.12 from FTP
Revision 1.1 2000/01/05 00:20:06 markster
Add broken lpc10 code... It's not too far from working I don't think...

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -58,8 +58,8 @@ static integer c__10 = 10;
/* ***************************************************************** */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -113,8 +113,8 @@ static integer c__10 = 10;
real rms;
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -147,8 +147,8 @@ static integer c__10 = 10;
/* Frame size, Prediction order, Pitch period */
/* Arguments */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -50,8 +50,8 @@ static integer c__10 = 10;
/* ***************************************************************** */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -109,8 +109,8 @@ static integer c__10 = 10;
/* Arguments */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -45,8 +45,8 @@ struct {
/* ***************************************************************** */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -71,8 +71,8 @@ struct {
{
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -97,8 +97,8 @@ struct {
/* LPC Configuration parameters: */
/* Frame size, Prediction order, Pitch period */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int lpfilt_(real *inbuf, real *lpbuf, integer *len, integer *nsamp);
/* LPFILT Version 55 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern integer median_(integer *d1, integer *d2, integer *d3);
/* MEDIAN Version 45G */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int mload_(integer *order, integer *awins, integer *awinf, real *speech,
/* MLOAD Version 48 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -41,8 +41,8 @@ static real c_b2 = 1.f;
/* ONSET Version 49 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -143,8 +143,8 @@ static real c_b2 = 1.f;
/* Arguments */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -37,8 +37,8 @@ extern int pitsyn_(integer *order, integer *voice, integer *pitch, real *rms, re
/* PITSYN Version 53 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -143,8 +143,8 @@ extern int pitsyn_(integer *order, integer *voice, integer *pitch, real *rms, re
/* Arguments */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2001/04/12 21:27:53 markster
Version 0.1.9 from FTP
Revision 1.11 2001/04/12 21:27:53 markster
Version 0.1.12 from FTP
Revision 1.3 2001/04/12 21:27:53 markh
app_record now supports wildcards of sort so your output file is not overwritten every time it's run. File.h got a documentation update on the ast_fileexists to include the return call. Watch out for the placea.c placev.c code, it's updates have not been tested yet. Just a few parenthesis to make it compile nicer on newer gcc versions with all the -W flags set.
@@ -32,8 +32,8 @@ extern int placea_(integer *ipitch, integer *voibuf, integer *obound, integer *a
/* PLACEA Version 48 */
/* $Log$
* Revision 1.8 2001/04/12 21:27:53 markster
* Version 0.1.9 from FTP
* Revision 1.11 2001/04/12 21:27:53 markster
* Version 0.1.12 from FTP
*
/* Revision 1.3 2001/04/12 21:27:53 markh
/* app_record now supports wildcards of sort so your output file is not overwritten every time it's run. File.h got a documentation update on the ast_fileexists to include the return call. Watch out for the placea.c placev.c code, it's updates have not been tested yet. Just a few parenthesis to make it compile nicer on newer gcc versions with all the -W flags set.

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2001/04/12 21:27:53 markster
Version 0.1.9 from FTP
Revision 1.11 2001/04/12 21:27:53 markster
Version 0.1.12 from FTP
Revision 1.3 2001/04/12 21:27:53 markh
app_record now supports wildcards of sort so your output file is not overwritten every time it's run. File.h got a documentation update on the ast_fileexists to include the return call. Watch out for the placea.c placev.c code, it's updates have not been tested yet. Just a few parenthesis to make it compile nicer on newer gcc versions with all the -W flags set.
@@ -32,8 +32,8 @@ extern int placev_(integer *osbuf, integer *osptr, integer *oslen, integer *obou
/* PLACEV Version 48 */
/* $Log$
* Revision 1.8 2001/04/12 21:27:53 markster
* Version 0.1.9 from FTP
* Revision 1.11 2001/04/12 21:27:53 markster
* Version 0.1.12 from FTP
*
/* Revision 1.3 2001/04/12 21:27:53 markh
/* app_record now supports wildcards of sort so your output file is not overwritten every time it's run. File.h got a documentation update on the ast_fileexists to include the return call. Watch out for the placea.c placev.c code, it's updates have not been tested yet. Just a few parenthesis to make it compile nicer on newer gcc versions with all the -W flags set.

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.8 2000/01/05 08:20:39 markster
Version 0.1.9 from FTP
Revision 1.11 2000/01/05 08:20:39 markster
Version 0.1.12 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int preemp_(real *inbuf, real *pebuf, integer *nsamp, real *coef, real *z
/* PREEMP Version 55 */
/* $Log$
* Revision 1.8 2000/01/05 08:20:39 markster
* Version 0.1.9 from FTP
* Revision 1.11 2000/01/05 08:20:39 markster
* Version 0.1.12 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

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