From: drowe67 Date: Mon, 18 Jan 2010 03:06:38 +0000 (+0000) Subject: changing name to avoid clash with existing project. X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=7ccebeeab390e11690382553e4ce562d2bf539f1;p=freetel-svn-tracking.git changing name to avoid clash with existing project. git-svn-id: https://svn.code.sf.net/p/freetel/code@131 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/easy-asterisk-gui/COPYING b/easy-asterisk-gui/COPYING deleted file mode 100644 index d60c31a9..00000000 --- a/easy-asterisk-gui/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/easy-asterisk-gui/Makefile b/easy-asterisk-gui/Makefile deleted file mode 100644 index 400f535e..00000000 --- a/easy-asterisk-gui/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# Makefile -# David Rowe 1 Jan 2010 -# -# Makefile for Easy Asterisk GUI -# -# 1/ Download files to development box for testing: -# -# usage: make HOST=test.machine.ip|hostname test -# make HOST=192.168.1.150 test -# make HOST=boris test -# -# 2/ Create static copy of web pages from HOST for static demo -# -# usage: make HOST=test.machine.ip static - -test: - rcp cgi-bin/*.html cgi-bin/*.sh cgi-bin/*.pl cgi-bin/*.js cgi-bin/*.css \ - cgi-bin/*.png root@$(HOST):/www - rcp etc/asterisk/*.conf root@$(HOST):/etc/asterisk - -.PHONY : static -static: - # generate static pages - - rm -Rf static; mkdir static; cd static; \ - wget -rEk --header="Cookie: loggedin=1" http://$(HOST)/phones.sh - - # modify links to non-existent scripts on static demo - - sed -i "s,http://$(HOST)/set_network.sh,network.sh.html," static/$(HOST)/network.sh.html - sed -i "s,http://$(HOST)/set_ring.sh,phones.sh.html," static/$(HOST)/phones.sh.html - sed -i "s,http://$(HOST)/set_voiplines.sh,voiplines.sh.html," static/$(HOST)/voiplines.sh.html - - diff --git a/easy-asterisk-gui/README.txt b/easy-asterisk-gui/README.txt deleted file mode 100644 index 5a9c7636..00000000 --- a/easy-asterisk-gui/README.txt +++ /dev/null @@ -1,227 +0,0 @@ -Mini Asterisk -============= - -A simple, light weight GUI for Asterisk. - -image::/images/ip04/mini.png["Mini Asterisk Demo", link="mini/phones.sh.html"] - -Click on the screen shot above for an on line demo. - -[[intro]] -Introduction ------------- - -Mini Asterisk is a simple Web GUI for Asterisk with comprehensive tool -tip documentation and a learning curve of a few minutes. Analog ports -and IP Phones are automatically detected, and no knowledge of Asterisk -configuration is required. - -Mini Asterisk is "unfeatured" - many of the Asterisk options are not -available. Instead it tries to make very basic, very common Asterisk -installations fast and simple, for example: - -* An Asterisk server running on your home gateway/firewall/server. - You want to connect a few IP Phones and make cheap phones calls - using VOIP. An Asterisk distro on a CD is a possibility but you - don't want to dedicate a full PC just for Asterisk. You don't - really want to learn obscure dial plan syntax and yet another conf - file format. - -* A small office that already has an old analog phone system. You - want to keep your current analog lines for incoming calls, but - install 8 IP Phones and use VOIP for outgoing calls. You know - enough to set up a DSL router but don't want to rely on "the Phone - Guy" or "The Computer Guy" at $100/hr to maintain your phone - system. - -* You are a "Phone Guy" who doesn't understand Linux and Asterisk but - you want to install IP-PBXes. - -[[why]] -Why Another Asterisk GUI? -------------------------- - -There are http://www.voip-info.org/wiki/view/Asterisk+GUI[a lot of -Asterisk GUIs] out there already. So why do we need another one? - -Well I needed an Asterisk GUI that was very easy to use for the -link:ip04.html[IP0X devices] I sell. Something that would lower the -technical skill required to install and maintain an Asterisk Phone -system. Something my wife and kids could use. - -I was also interested in exploring the ease-of-use meme, as we have -been discussing it a lot on the http://villagetelco.org[Village Telco] -project. Just how easy can we make Asterisk to use? So I scratched -the itch. - -Mini Asterisk has the following features that make it reasonably -unique. They may be good or bad features depending on your point of -view! - -* Mini Asterisk is "un-featured" - it hides many of the advanced - Asterisk features in the interest of simple and fast configuration. - -* Light weight so it can run on embedded boxes like the IP0X family. - No SQL database or PHP or LAMP. Only a basic web server and a very - basic perl are required (e.g. microperl - no CPAN libraries). - -* Works directly on extensions.conf and sip.conf, but honors any edits - you make to these files. So all the powerful Asterisk features are - available in the background. - -* Doesn't use AJAX or the built-in Asterisk web server or users.conf - magic. Plain old HTML, a little Java-script and CGIs written in - shell script and Perl. - -* Doesn't use the Asterisk programming "model". For example you don't - have to understand what a dial-plan is, much less understand how to - code one. Plain English terms are used instead, for example "Phones - and Phone lines". Terms like Asterisk, Linux, SIP, Zap/1 don't even - get a mention. - -* Extensive tool tip documentation. No manual. - -* Doesn't require a dedicated PC, not installed from an ISO CD. So - you can use it as a GUI for Asterisk on a little SOHO Linux box that - is also your firewall, server etc. - -* Mini Asterisk tells you when something is wrong, for example you get - a warning if your Phone System can't see the Internet. - -* Extensive pre-configuration of extensions.conf and sip.conf, - pre-selected phone numbers, SIP trunks are selected from a pull-down - menu (except they are called VOIP lines). Analog ports are auto - detected, at least on the IP0X. This makes adding IP phones very - fast and simple. - -[[status]] -Status ------- - -Alpha: - -* Works on IP0X. -* Not tested on x86. Several IP0X features are n/a for x86 and should be - disabled when the x86 (or non-IP0X) platform is detected. -* Needs feedback from real users to see how useful the concept is and what - (un)features need to be added. -* Need a few more (un)features to be added, and Voip Line screen - populated with more ITSPs. -* But quite useable as it stands. - -[[notes]] -Implementation Notes --------------------- - -Mini Asterisk is written for the -http://rowetel.com/ucasterisk/ip04.html[IP0X embedded Asterisk] -hardware but will also run on x86 and probably many other platforms. - -Mini Asterisk has been written to be compatible with regular Asterisk -conf file configuration. Just leave the conf file lines with -"mini-asterisk" comments alone. The Asterisk conf files -extensions.conf and sip.conf are directly modified by Mini Asterisk, -but changes are limited to the "mini-asterisk" lines. - -For Auto-detection of Zap ports Mini Asterisk looks at -/etc/zapata.conf, so you may need this set up correctly for your -analog hardware. On the IP0X this happens automatically. - -[[install]] -Installation ------------- - -Note: this process may overwrite your Asterisk extensions.conf and -sip.conf files - back them up if you have an existing Asterisk -installation that you want to keep. The IP0X ipkg does attempt to -backup the modified conf files to *.bak but no guarantees.... - -However once mini-asterisk is installed it should honor any manual -changes made to extensions.conf and sip.conf. - -IP0X Installation -~~~~~~~~~~~~~~~~~ - -Installation instructions for IP0X boxes running link:baps.html[BAPS], -with some version of Asterisk and Zaptel installed. - -------------------------------------------------------------------- -root~> ipkg install mini-asterisk -------------------------------------------------------------------- - -x86 Installation -~~~~~~~~~~~~~~~~ - -. You need a web server, Asterisk and some sort of Perl installed -(very basic Perl installation is fine). Configure your web server to -run CGIs (.sh and .pl) from /www (lighttpd config instructions below). -Mini Asterisk expects all files (shell, perl, html etc) to be in the -same directory. If you find this painful please <>. - -. The process below places the web files in /www, you may like to -place the files somewhere else like /www/asterisk. One of the files -is named index.html so make sure you don't overwrite an existing -index.html. - -. Login as root to install the Mini Asterisk files: -+ -Remember to backup your existing extensions.conf & sip.conf in -/etc/asterisk -+ -------------------------------------------------------------------- -# cd ~ -# svn co https://freetel.svn.sourceforge.net/svnroot/freetel/mini-asterisk-gui -# ./update_revision.sh -# cp mini-asterisk-gui/etc/asterisk/* /etc/asterisk -# cp mini-asterisk-gui/cgi-bin/* /www -# cd /etc/asterisk -# cp extensions.conf extensions.conf.def -# cp sip.conf sip.conf.def -# mv etc/asterisk/users.conf etc/asterisk/users.conf.bak -------------------------------------------------------------------- -+ -The final step above may not be required on your machine if you don't -have a users.conf. The .def copies are required by the "reset -defaults" feature on the admin screen. - -. Switch off the internal Asterisk web server by editing -/etc/asterisk.httpd.conf. Make sure the enabled line reads like this: - - enabled=no -+ -Then stop and restart Asterisk. - -. I use lighttpd as the web server, the /etc/lighttpd.conf lines -required are: -+ -------------------------------------------------------------------- -cgi.assign = ( ".sh" => "/bin/sh",".pl" => "/usr/sbin/microperl" ) -------------------------------------------------------------------- - -[[contribute]] -Contributions -------------- - -I welcome sip.conf entries for your favourite ITSP (VOIP service) to -help populate the Provider field of the -link:mini/voiplines.sh.html[Voip Line Screen]. - -[[support]] -Support -------- - -Comments, features request, bugs please let me know using Free -Telephony Project http://www.rowetel.com/ucasterisk/#support[Support]. - -[[source]] -Source Code ------------ - -Browse: - -http://freetel.svn.sourceforge.net/viewvc/freetel/mini-asterisk-gui/[http://freetel.svn.sourceforge.net/viewvc/freetel/mini-asterisk-gui/] - -Check Out: - - $ svn co https://freetel.svn.sourceforge.net/svnroot/freetel/mini-asterisk-gui - diff --git a/easy-asterisk-gui/cgi-bin/about.sh b/easy-asterisk-gui/cgi-bin/about.sh deleted file mode 100644 index 8ca97111..00000000 --- a/easy-asterisk-gui/cgi-bin/about.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/bin/sh -# about.sh -# David Rowe 7 Jan 2010 -# About screen for Mini Asterisk GUI - -# check we are logged in - -echo $HTTP_COOKIE | grep "loggedin" > /dev/null -if [ $? -eq 1 ]; then - echo "" - echo "" - echo '' - echo "" - echo "" - exit -fi - -# Construct the web page ------------------------------- - -cat < - - -EOF - -cat << EOF - -Mini Asterisk - About -EOF - -cat tooltips.html -echo '' -cat banner.html -echo " " -cat menu.html -cat < - -
- -EOF -echo ' ' -echo ' ' -echo ' ' -echo ' ' - -more=`echo "$QUERY_STRING" | grep -oe "more=[^&?]*" | sed -n "s/more=//p"` -if [ $more -eq 1 ]; then - echo -else - echo " " - echo ' '; -cat < - - -

About

Mini Asterisk Revision: 122
 
Brought to you by the Free Telephony Project
 
More
- - -EOF -exit -fi - -echo "  " -echo "

cat /proc/version

" -echo " " -cat /proc/version -echo " " - -which ipkg >> /dev/null -if [ $? -eq 0 ]; then - echo "  " - echo "

ipkg list_installed

" - echo " " - ipkg list_installed | tr '\n' '#' | sed -n 's/\#/
/pg' - echo " " -fi - -echo "  " -echo "

cat /proc/loadavg

" -echo " " -cat /proc/loadavg -echo " " - -echo "  " -echo "

uptime

" -echo " " -uptime -echo " " - -echo "  " -echo "

cat /proc/meminfo

" -echo " " -cat /proc/meminfo | tr '\n' '#' | sed -n 's/\#/
/pg' -echo " " - -echo "  " -echo "

cat /proc/cmdline

" -echo " " -cat /proc/cmdline -echo " " - -echo "  " -echo "

cat /proc/cpuinfo

" -echo " " -cat /proc/cpuinfo -echo " " - -if [ -f /proc/mtd ]; then - echo "  " - echo "

cat /proc/mtd

" - echo " " - cat /proc/mtd | tr '\n' '#' | sed -n 's/\#/
/pg' - echo " " -fi - -if [ -f /proc/yaffs ]; then - echo "  " - echo "

cat /proc/yaffs

" - echo " " - cat /proc/yaffs | tr '\n' '#' | sed -n 's/\#/
/pg' - echo " " -fi - -echo "  " -echo ' Less'; - -cat < - - - - - - - - -EOF - diff --git a/easy-asterisk-gui/cgi-bin/admin.sh b/easy-asterisk-gui/cgi-bin/admin.sh deleted file mode 100644 index 9b309178..00000000 --- a/easy-asterisk-gui/cgi-bin/admin.sh +++ /dev/null @@ -1,145 +0,0 @@ -#!/bin/sh -# admin.sh -# David Rowe 7 Jan 2010 -# Admin screen for Mini Asterisk GUI - -# check we are logged in - -echo $HTTP_COOKIE | grep "loggedin" > /dev/null -if [ $? -eq 1 ]; then - echo "" - echo "" - echo '' - echo "" - echo "" - exit -fi - -# set password CGI ----------------------------------------------- - -echo "$QUERY_STRING" | grep -oe "pass=" > /dev/null -if [ $? -eq 0 ]; then - pass=`echo "$QUERY_STRING" | grep -oe "pass=[^&?]*" | sed -n "s/pass=//p"` - passwd_cmdline $pass -fi - -# restart CGI ---------------------------------------------------- - -echo "$QUERY_STRING" | grep -oe "restart=1" > /dev/null -if [ $? -eq 0 ]; then - -# kill cookie to log out. This ensures hitting refresh wont run -# the restart process again - -cat < -Mini Asterisk - Restart - - -

Restarting...come back in 1 minute

- -EOF -reboot -fi - -# set defaults CGI ---------------------------------------------------- - -echo "$QUERY_STRING" | grep -oe "defaults=1" > /dev/null -if [ $? -eq 0 ]; then - cp /etc/asterisk/extensions.conf.def /etc/asterisk/extensions.conf - cp /etc/asterisk/sip.conf.def /etc/asterisk/sip.conf - asterisk -rx "sip reload" 2>/dev/null 1 > /dev/null - asterisk -rx "dialplan reload" 2>/dev/null 1 > /dev/null -fi - -# Construct the web page ------------------------------- - -cat < - - -EOF - -cat << EOF - -Mini Asterisk - Admin -EOF - -cat tooltips.html -echo '' -cat banner.html -echo " " -cat menu.html -cat < - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 

Admin

 

Change Phone System Password

New Password:
 
Default password is uClinux
 

Restart Phone System

-
- - -
-
 

Reset Phone System Defaults

-
- - -
-
 

Upgrade Mini Asterisk

-
- - -
 

Install New Firmware

- -
Firmware URL:
- - - - - - - - - -EOF - diff --git a/easy-asterisk-gui/cgi-bin/at-530.html b/easy-asterisk-gui/cgi-bin/at-530.html deleted file mode 100644 index 686fb703..00000000 --- a/easy-asterisk-gui/cgi-bin/at-530.html +++ /dev/null @@ -1,15 +0,0 @@ -
    -
  1. Connect the WAN port of the AT-530 to your network, it will boot and obtain an IP via DHCP. -
  2. Find the IP of the phone by pressing the Sysinfo button a few times. -
  3. Open another browser window. Go to the phones IP, for example http://192.168.1.160 -
  4. Login to the phone using the username/password admin/admin. -
  5. Optional: set a static IP using the WAN menu (I like static IPs for SIP phones). -
  6. Go to the phone SIP Config menu. -
  7. Set Register Server Address to your Phone System IP Address. -
  8. Set Register Username to the phone number (e.g. 6011). -
  9. Also set Register Password to the phone number (e.g. 6011) and -the Phone Number to the phone number (e.g. 6011). -
  10. Check the Enable Register box. -
  11. Then click on Apply. -
  12. On your browser refresh this page to see if the phone is connected to your phone system. -
diff --git a/easy-asterisk-gui/cgi-bin/banner.html b/easy-asterisk-gui/cgi-bin/banner.html deleted file mode 100644 index 02889097..00000000 --- a/easy-asterisk-gui/cgi-bin/banner.html +++ /dev/null @@ -1 +0,0 @@ -

 

diff --git a/easy-asterisk-gui/cgi-bin/cross.png b/easy-asterisk-gui/cgi-bin/cross.png deleted file mode 100644 index 05baecdb..00000000 Binary files a/easy-asterisk-gui/cgi-bin/cross.png and /dev/null differ diff --git a/easy-asterisk-gui/cgi-bin/faq.html b/easy-asterisk-gui/cgi-bin/faq.html deleted file mode 100644 index dd6258e5..00000000 --- a/easy-asterisk-gui/cgi-bin/faq.html +++ /dev/null @@ -1,16 +0,0 @@ -
    - -
  1. Transfer a Call - -
  2. Answer a call on another ringing phone: If you hear another phone ringing and -want to answer the call on your phone, just pick up your phone and -dial *8. Note an IP phone can pick up a call on a ringing IP phone -but not an Analog phone. An Analog pohone can pick up another -ringing Analog phone but not an IP phone. - -
- -

Resources and Links

-
    -
  1. A good book on Asterisk is Asterisk - The Future of Telephony -
diff --git a/easy-asterisk-gui/cgi-bin/faq.sh b/easy-asterisk-gui/cgi-bin/faq.sh deleted file mode 100644 index d4ccf5d0..00000000 --- a/easy-asterisk-gui/cgi-bin/faq.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/sh -# faq.sh -# David Rowe 7 Jan 2010 -# FAQ screen for Mini Asterisk GUI - -# check we are logged in - -echo $HTTP_COOKIE | grep "loggedin" > /dev/null -if [ $? -eq 1 ]; then - echo "" - echo "" - echo '' - echo "" - echo "" - exit -fi - -# Construct the web page ------------------------------- - -cat < - - -EOF - -cat << EOF - -Mini Asterisk - FAQ -EOF - -cat tooltips.html -echo '' -cat banner.html -echo " " -cat menu.html -cat < - -
- - -

FAQ

-EOF -cat faq.html -cat <
- - - - - - - - -EOF - diff --git a/easy-asterisk-gui/cgi-bin/index.html b/easy-asterisk-gui/cgi-bin/index.html deleted file mode 100644 index 8514560b..00000000 --- a/easy-asterisk-gui/cgi-bin/index.html +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/easy-asterisk-gui/cgi-bin/ipphones.js b/easy-asterisk-gui/cgi-bin/ipphones.js deleted file mode 100644 index 9c50ceac..00000000 --- a/easy-asterisk-gui/cgi-bin/ipphones.js +++ /dev/null @@ -1,3 +0,0 @@ -function localInit() { -} - diff --git a/easy-asterisk-gui/cgi-bin/ipphones.pl b/easy-asterisk-gui/cgi-bin/ipphones.pl deleted file mode 100644 index 87f279f3..00000000 --- a/easy-asterisk-gui/cgi-bin/ipphones.pl +++ /dev/null @@ -1,88 +0,0 @@ -#!usr/bin/perl -# ipphones.pl -# David Rowe 6 Jan 2010 -# -# Text processing for the ipphones screen - -$ipaddress = $ARGV[0]; -$more = $ARGV[1]; - -# Slurp up SIP extension (Sip) data from extensions.conf - -my %ip = (); # ip extension keyed on sip.conf name - -open EXT, "/etc/asterisk/extensions.conf"; -while () { - if (/.*=>[ ]*([0-9]*),1.*SIP\/([0-9]*)\)/) { - $ip{$2} = $1; - #print "'$1' '$2' $ip{$2}\n"; - } -} -close EXT; - -my %sip = (); # SIP IP phone status keyed on sip.conf names - # if no entry we can't see IP phone device -my %voip = (); # SIP trunks status keyed on sip.conf names - # if no entry we can't see SIP trunk -my %ipad = (); # IP address of SIP device keyed on sip.conf names - -open SIP, "sipshowpeers.txt"; -while () { - if (/^([0-9]*)[\s\/].*(OK)/) { - $sip{$1} = $2; - #print "'$1' '$2' $sip{$1}\n"; - $e = $1; - if (/\s([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) { - $ipad{$e} = $1; - #print "'$1'\n"; - } - } - if (/^(voip[0-9]*)[\s\/].*(OK)/) { - $voip{$1} = $2; - #print "'$1' '$2' $voip{$1}\n"; - $e = $1; - if (/\s([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) { - $ipad{$e} = $1; - #print "'$1'\n"; - } - } -} - -close SIP; - -# print list of IP phones with connection status - -$unconnected = 0; -foreach $e (sort keys %ip) { - if ($sip{$e} eq "OK") { - $icon = "\"Connected\""; - $tooltip_status = "onMouseOver=\"popUp(event,'ipphones_connected')\" onmouseout=\"popUp(event,'ipphones_connected')\""; - $comment=$ipad{$e}; - $tooltip_ext = "onMouseOver=\"popUp(event,'phone_ext')\" onmouseout=\"popUp(event,'phone_ext')\""; - $tooltip_ip = "onMouseOver=\"popUp(event,'phone_ipphone_ip')\" onmouseout=\"popUp(event,'phone_ipphone_ip')\""; - $unconnected = 0; - } - else { - $unconnected = $unconnected + 1; - $icon = "\"Not"; - $tooltip_status = "onMouseOver=\"popUp(event,'ipphones_notconnected')\" onmouseout=\"popUp(event,'ipphones_notconnected')\""; - $comment="Available"; - $tooltip_id = "iphones_$e"; - print "
Configure your IP phone with username/password $e/$e, SIP Server IP $ipaddress
"; - $tooltip_ext = "onMouseOver=\"popUp(event,'$tooltip_id')\" onmouseout=\"popUp(event,'$tooltip_id')\""; - $tooltip_ip = ""; - } - - if ($more == 1 || ($unconnected < 5)) { - print "$e$comment$icon\n"; - } -} - -if ($more == 0) { - print 'More'; -} -else { - print 'Less'; -} - - diff --git a/easy-asterisk-gui/cgi-bin/ipphones.sh b/easy-asterisk-gui/cgi-bin/ipphones.sh deleted file mode 100644 index 2ce904b1..00000000 --- a/easy-asterisk-gui/cgi-bin/ipphones.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/sh -# dashboard.sh -# David Rowe 6 Jan 2010 -# Dashboard screen for Mini Asterisk GUI - -# check we are logged in - -echo $HTTP_COOKIE | grep "loggedin" > /dev/null -if [ $? -eq 1 ]; then - echo "" - echo "" - echo '' - echo "" - echo "" - exit -fi - -more=`echo "$QUERY_STRING" | grep -oe "more=[^&?]*" | sed -n "s/more=//p"` -ipaddress=`ifconfig eth0 | sed -n 's/.*inet addr:\(.*\) Bcast.*/\1/p'` - -# Construct the web page ------------------------------- - -cat < - - -EOF - -echo "" - -cat << EOF - -Mini Asterisk - IP Phones - -EOF - -cat tooltips.html -echo '' -cat banner.html -echo " " -cat menu.html -cat < - -
- - - -EOF -echo "" - - # use perl to construct list of IP phones for us - asterisk "-rx sip show peers" 2>/dev/null > sipshowpeers.txt - ./ipphones.pl $ipaddress $more - -cat < - -

 
How to Configure IP Phones

-

1. Atcom AT-530

-EOF -cat at-530.html -cat < - - -

IP Phones

Phone System IP Address:$ipaddress
 
- - -EOF - diff --git a/easy-asterisk-gui/cgi-bin/login.sh b/easy-asterisk-gui/cgi-bin/login.sh deleted file mode 100644 index 0ae903a8..00000000 --- a/easy-asterisk-gui/cgi-bin/login.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/sh -# login.sh -# David Rowe 4 Jan 2010 -# CGI for Mini Asterisk login GUI - -pass=`echo "$QUERY_STRING" | grep -oe "pass=[^&?]*" | sed -n "s/pass=//p"` - -echo $QUERY_STRING | grep pass > /dev/null -if [ $? -eq 1 ]; then - # Display form ------------------------------- - - cat < - - -EOF - cat << EOF - - Mini Asterisk - Login -
- - - - - - - -

Login

Password:
Default password is uClinux
-
- -EOF -else - testuser root $pass - if [ $? -eq 0 ]; then - - # login sucessful - echo "Content-type: text/html" - echo "Set-Cookie: loggedin=1" - echo "" - echo "" - echo "Mini Asterisk - Login" - echo '' - echo "" - echo "" - echo "Please wait a few seconds....." - echo "" - - # load mini asterisk conf files in case this is our first login - - asterisk -rx "sip reload" 2>/dev/null 1 > /dev/null - asterisk -rx "dialplan reload" 2>/dev/null 1 > /dev/null - - else - # login failed - cat < - - Mini Asterisk - Login - - - Please wait a few seconds..... - - - -EOF - fi -fi - diff --git a/easy-asterisk-gui/cgi-bin/logout.sh b/easy-asterisk-gui/cgi-bin/logout.sh deleted file mode 100644 index d4306c96..00000000 --- a/easy-asterisk-gui/cgi-bin/logout.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# logout.sh -# David Rowe 4 Jan 2010 -# CGI for Mini Asterisk logout GUI - -cat <Mini Asterisk - Logout -Change your password, reset the default settings, upgrade software -
Connect the phone system to your network and the Internet
-
Lists your phones and phone lines
-
Set up your IP phones
-
Boring information like software version numbers
-
Frequently asked questions and links to further information
-
I think you can work this one out....
-
Set up your VOIP phone line
- - - - - - - - - - - - - - - - - - - - - - - - - - - -

 

About
Admin
FAQ
IP Phones
Logout
Phone System
Network
VOIP Line
- diff --git a/easy-asterisk-gui/cgi-bin/network.js b/easy-asterisk-gui/cgi-bin/network.js deleted file mode 100644 index 108bf01b..00000000 --- a/easy-asterisk-gui/cgi-bin/network.js +++ /dev/null @@ -1,76 +0,0 @@ -var script_path = "cgi-bin/"; - -function doStatic() { - $('ipaddress').disabled = 0; - $('netmask').disabled = 0; - $('gateway').disabled = 0; - $('dns').disabled = 0; -} - -function doDHCP() { - $('ipaddress').disabled = 1; - $('netmask').disabled = 1; - $('gateway').disabled = 1; - $('dns').disabled = 1; -} - -// http://moblog.bradleyit.com/2009/06/javascript-ip-address-validation.html - -function isIP(obj) { - var ary = obj.value.split("."); - var ip = true; - - for (var i=0; i<4; i++) { - ip = (!ary[i].match(/^\d{1,3}$/) || (Number(ary[i]) > 255)) ? false : ip; - } - - if (ip) - ip = (ary.length == 4); - - if (!ip) { - // the value is NOT a valid IP address - obj.style.background = "red"; - obj.select(); - } - else { obj.style.background = ""; } // the value IS a valid IP address - - return ip; -} - -function localInit() { - - if (init_dhcp == "yes") { - $('dhcp').checked = true; - $('ipaddress').disabled = 1; - $('netmask').disabled = 1; - $('gateway').disabled = 1; - $('dns').disabled = 1; - } - else { - $('static').checked = true; - $('ipaddress').disabled = 0; - $('netmask').disabled = 0; - $('gateway').disabled = 0; - $('dns').disabled = 0; - } - $('ipaddress').value = init_ipaddress; - $('netmask').value = init_netmask; - $('gateway').value = init_gateway; - $('dns').value = init_dns; - $('backdoor').value = init_backdoor; - if (init_internet == "yes") - $('internet').innerHTML = 'tick'; - else - $('internet').innerHTML = 'tick'; - -} - -function validate_form(form) -{ - var valid = true; - - if ($('dhcp').checked == false) - valid = isIP(form.ipaddress) && isIP(form.ipaddress) && isIP(form.gateway) && isIP(form.dns); - - return valid; -} diff --git a/easy-asterisk-gui/cgi-bin/network.sh b/easy-asterisk-gui/cgi-bin/network.sh deleted file mode 100644 index 268425ba..00000000 --- a/easy-asterisk-gui/cgi-bin/network.sh +++ /dev/null @@ -1,150 +0,0 @@ -#!/bin/sh -# network.sh -# David Rowe 4 Jan 2010 -# CGI for Mini Asterisk network GUI - -# check we are logged in - -echo $HTTP_COOKIE | grep "loggedin" > /dev/null -if [ $? -eq 1 ]; then - echo "" - echo "" - echo '' - echo "" - echo "" - exit -fi - -grok_network=0 - -if [ -f /etc/rc.d/S10network ]; then - grok_network=1 - dhcp=yes - ipaddress=`ifconfig eth0 | sed -n 's/.*inet addr:\(.*\) Bcast.*/\1/p'` - netmask=`ifconfig eth0 | sed -n 's/.*Mask:\(.*\)\s*/\1/p'` - gateway=`route -n | awk '/^0.0.0.0/ {print $2}'` - dns=`cat /etc/resolv.conf | awk '/^nameserver/ {print $2}'` -fi - -if [ -f /etc/rc.d/S10network-static ] -then - grok_network=1 - dhcp=no - ipaddress=`sed -n 's/IPADDRESS="\(.*\)"/\1/p' /etc/init.d/network-static` - netmask=`sed -n 's/NETMASK="\(.*\)"/\1/p' /etc/init.d/network-static` - gateway=`sed -n 's/GATEWAY="\(.*\)"/\1/p' /etc/init.d/network-static` - dns=`sed -n 's/DNS="\(.*\)"/\1/p' /etc/init.d/network-static` -fi - -# if we don't understand this machines network config then bail - -if [ $groknetwork -eq 0 ]; then -cat << EOF - -Mini Asterisk - Network -EOF - -cat tooltips.html -echo '' -cat banner.html -echo " " -cat menu.html -cat < -
- - - -

Network

Sorry - I can't edit the Network configuration on this machine
- - - - - - -EOF -fi - -if [ -f /etc/rc.d/S05network-backdoor ]; then - backdoor=`sed -n 's/IPADDRESS="\(.*\)"/\1/p' /etc/init.d/network-backdoor` -fi - -# See if we have Internet connectivity, first check dns as time outs can be very slow - -dns_packet_loss=`ping $dns -c 1 -q | sed -n 's/.*received, \(.*\)% packet loss/\1/p'` -internet="no"; -if [ $dns_packet_loss == "0" ]; then - packet_loss=`ping google.com -c 1 -q | sed -n 's/.*received, \(.*\)% packet loss/\1/p'` - if [ $packet_loss == "0" ]; then - internet="yes"; - fi -fi - -# Construct the web page ------------------------------- - -cat < - - -EOF - -echo "" - -cat << EOF - -Mini Asterisk - Network - -EOF - -cat tooltips.html -echo '' -cat banner.html -echo " " -cat menu.html -cat < - -
-
- - - - - - - - - - - - - - - - - - -

Network

StaticDHCP
IP Address:
Netmask:
Gateway:
DNS:
Emergency IP:
Internet Connection:
-  
- - - - - - - - - -EOF - diff --git a/easy-asterisk-gui/cgi-bin/phones.js b/easy-asterisk-gui/cgi-bin/phones.js deleted file mode 100644 index 74d6eaf1..00000000 --- a/easy-asterisk-gui/cgi-bin/phones.js +++ /dev/null @@ -1,7 +0,0 @@ -function localInit() { - if (init_internet == "yes") - $('internet').innerHTML = 'tick'; - else - $('internet').innerHTML = 'tick'; -} - diff --git a/easy-asterisk-gui/cgi-bin/phones.pl b/easy-asterisk-gui/cgi-bin/phones.pl deleted file mode 100644 index 56f3534c..00000000 --- a/easy-asterisk-gui/cgi-bin/phones.pl +++ /dev/null @@ -1,216 +0,0 @@ -#!/usr/bin/perl -# phones.pl -# David Rowe 5 Jan 2010 -# -# Text processing for the phones screen. - -$tool_tip = "onMouseOver=\"popUp(event,'network_internet')\" onmouseout=\"popUp(event,'network_internet')\""; - -# Slurp up analog port (Zap) data from extensions.conf - -my %analog = (); # analog extension keyed on zap port - -open EXT, "/etc/asterisk/extensions.conf"; -while () { - if (/.*=>[ ]*([0-9]*),1.*Zap\/([0-9]*)\)/) { - $analog{$2} = $1; - #print "'$1' '$2' $analog{$2}\n"; - } -} -close EXT; - -# Slurp up data on installed zaptel ports from /etc/zaptel.conf - -my %zap = (); # zaptel port type keyed on zap port - # (fxs/fxo or no entry if not live) -open ZAP, "/etc/zaptel.conf"; -while () { - if (/fxoks=(.*)/) { - @fxs = split(/,/, $1); - foreach (@fxs) { - $zap{$_} = "fxs"; - } - } - if (/fxsks=(.*)/) { - @fxo = split(/,/, $1); - foreach (@fxo) { - $zap{$_} = "fxo"; - } - } -} -close ZAP; - -# Slurp up SIP extension (Sip) data from extensions.conf - -my %ip = (); # ip extension keyed on sip.conf name - -open EXT, "/etc/asterisk/extensions.conf"; -while () { - if (/.*=>[ ]*([0-9]*),1.*Sip\/([0-9]*)\)/) { - $ip{$2} = $1; - #print "'$1' '$2' $ip{$2}\n"; - } -} -close EXT; - -# Determine which extenions are "Reception", i.e. set to ring on incoming -# calls - -my %zap_ring = (); # ring flag keyed on Zap port (1,2...) -my %sip_ring = (); # ring flag keyed on sip.cong ext name (6011,6012 etc) - -open EXT, "/etc/asterisk/extensions.conf"; -while () { - if (/s,1,Dial\((.*)\) ;; mini/) { - @ring = split(/&/, $1); - #print "'$1' '@ring'\n foreach:\n"; - foreach (@ring) { - #print " $_\n"; - if (/Zap\/([0-9]*)/) { - $zap_ring{$1} = 1; - #print "'$_' $1 \n"; - } - if (/SIP\/([0-9]*)/) { - $sip_ring{$1} = 1; - #print "'$_' $1 \n"; - } - } - } -} -close EXT; - - -# work out which IP phones are registered ----------------------------------- - -my %sip = (); # SIP IP phone status keyed on sip.conf names (6011,6012 etc) - # if no entry we can't see IP phone device -my %ipad = (); # IP address of SIP device keyed on sip.conf names - -open SIP, "sipshowpeers.txt"; -while () { - if (/^([0-9]*)[\s\/].*(OK)/) { - $sip{$1} = $2; - #print "'$1' '$2' $sip{$1}\n"; - $e = $1; - if (/\s([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) { - $ipad{$e} = $1; - #print "'$1'\n"; - } - } - - if (/^(.*)\/.*(OK)/) { - #$sip{$1} = $2; - #print "'$1' '$2' $sip{$1}\n"; - $e = $1; - if (/\s([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) { - $ipad{$e} = $1; - #print "'$1'\n"; - } - } -} - -close SIP; - -# Determine if Asterisk can see current voip line (SIP trunk) -# sipshowpeers.txt needs to be generated before calling this perl -# script - -my %voip = (); # SIP trunks status keyed on sip.conf stanza name/username - # if no entry we can't see SIP trunk - -open SIP, "sipshowregistry.txt"; -while () { - if (/^(.*):.*(Registered)/) { - $voip{$1} = $2; - #print "'$1' '$2' $voip{$1}\n"; - } -} - -close SIP; - -# start phones ringing form ------------------------------------------- - -print '
'; - -# print list of analog phones - -$tooltip_anphone = "onMouseOver=\"popUp(event,'phone_anphone')\" onmouseout=\"popUp(event,'phone_anphone')\""; -$tooltip_ext = "onMouseOver=\"popUp(event,'phone_ext')\" onmouseout=\"popUp(event,'phone_ext')\""; -$tooltip_port = "onMouseOver=\"popUp(event,'phone_port_phone')\" onmouseout=\"popUp(event,'phone_port_phone')\""; -$tooltip_reception = "onMouseOver=\"popUp(event,'phone_reception')\" onmouseout=\"popUp(event,'phone_reception')\""; - -foreach $a (sort keys %analog) { - if ($zap{$a} eq "fxs") { - $icon = "\"Analog"; - print "$analog{$a}Analog PhonePort $a"; - if ($zap_ring{$a} == 1) { - $checked = "checked"; - } - else { - $checked = ""; - } - print "Reception$icon\n"; - } -} - -# print list of IP phones - -$tooltip_ipphone = "onMouseOver=\"popUp(event,'phone_ipphone')\" onmouseout=\"popUp(event,'phone_ipphone')\""; -$tooltip_ipphone_ip = "onMouseOver=\"popUp(event,'phone_ipphone_ip')\" onmouseout=\"popUp(event,'phone_ipphone_ip')\""; -$tooltip_reception = "onMouseOver=\"popUp(event,'phone_reception')\" onmouseout=\"popUp(event,'phone_reception')\""; - -foreach $s (sort keys %sip) { - if ($sip{$s} eq "OK") { - $icon = "\"IP"; - print "$sIP Phone$ipad{$s}"; - if ($sip_ring{$s} == 1) { - $checked = "checked"; - } - else { - $checked = ""; - } - print "Reception$icon\n"; - } -} - -print ' '; -print ""; -print "Add IP Phone"; - -$tool_tip = "onMouseOver=\"popUp(event,'phone_lines')\" onmouseout=\"popUp(event,'phone_lines')\""; - -print ' '; -print "

Phone Lines

-"; - -print "
"; - -# print list of analog phone lines - -$tooltip_phoneline = "onMouseOver=\"popUp(event,'phone_phoneline')\" onmouseout=\"popUp(event,'phone_phoneline')\""; -$tooltip_port = "onMouseOver=\"popUp(event,'phone_port_line')\" onmouseout=\"popUp(event,'phone_port_line')\""; -$tooltip_line_prefix = "onMouseOver=\"popUp(event,'phone_line_prefix')\" onmouseout=\"popUp(event,'phone_line_prefix')\""; - -foreach $a (sort keys %analog) { - if ($zap{$a} eq "fxo") { - $icon = "\"Phone"; - print "0Analog LinePort $a$icon\n"; - } -} - -# print list of SIP VOIP trunks - -$tooltip_voipline = "onMouseOver=\"popUp(event,'phone_voipline')\" onmouseout=\"popUp(event,'phone_voipline')\""; -$tooltip_voipline_ip = "onMouseOver=\"popUp(event,'phone_voipline_ip')\" onmouseout=\"popUp(event,'phone_voipline_ip')\""; -$tooltip_voipline_prefix = "onMouseOver=\"popUp(event,'phone_voipline_prefix')\" onmouseout=\"popUp(event,'phone_voipline_prefix')\""; - -foreach $s (sort keys %voip) { - if ($voip{$s} eq "Registered") { - $icon = "\"VOIP"; - print "1VOIP Line$ipad{$s}$icon\n"; - } -} - -print ' '; -print ""; -print "Set Up VOIP Line"; diff --git a/easy-asterisk-gui/cgi-bin/phones.sh b/easy-asterisk-gui/cgi-bin/phones.sh deleted file mode 100644 index aa302f59..00000000 --- a/easy-asterisk-gui/cgi-bin/phones.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/bin/sh -# phones.sh -# David Rowe 4 Jan 2010 -# Phones screen for Mini Asterisk GUI - -# check we are logged in - -echo $HTTP_COOKIE | grep "loggedin" > /dev/null -if [ $? -eq 1 ]; then - echo "" - echo "" - echo '' - echo "" - echo "" - exit -fi - -# See if we have Internet connectivity, first check dns as time outs can be very slow - -dns=`cat /etc/resolv.conf | awk '/^nameserver/ {print $2}'` -dns_packet_loss=`ping $dns -c 1 -q | sed -n 's/.*received, \(.*\)% packet loss/\1/p'` -internet="no"; -if [ $dns_packet_loss == "0" ]; then - packet_loss=`ping google.com -c 1 -q | sed -n 's/.*received, \(.*\)% packet loss/\1/p'` - if [ $packet_loss == "0" ]; then - internet="yes"; - fi -fi - -ipaddress=`ifconfig eth0 | sed -n 's/.*inet addr:\(.*\) Bcast.*/\1/p'` - -# Construct the web page ------------------------------- - -cat < - - -EOF - -echo "" - -cat << EOF - -Mini Asterisk - Phones - -EOF - -cat tooltips.html -echo '' -cat banner.html -echo " " -cat menu.html -cat < - -
- - - - - - - - - -EOF -echo "" -cat < - - - - -EOF - -# use perl to construct list of phones and phone lines for us -asterisk "-rx sip show peers" 2>/dev/null > sipshowpeers.txt -./phones.pl - -cat< - - - - - -

Phone System

Internet Connection:
 
Phone System IP Address:$ipaddress
 

Phones

- - -EOF - diff --git a/easy-asterisk-gui/cgi-bin/prototype.js b/easy-asterisk-gui/cgi-bin/prototype.js deleted file mode 100644 index 0e85338b..00000000 --- a/easy-asterisk-gui/cgi-bin/prototype.js +++ /dev/null @@ -1,1781 +0,0 @@ -/* Prototype JavaScript framework, version 1.4.0 - * (c) 2005 Sam Stephenson - * - * Prototype is freely distributable under the terms of an MIT-style license. - * For details, see the Prototype web site: http://prototype.conio.net/ - * -/*--------------------------------------------------------------------------*/ - -var Prototype = { - Version: '1.4.0', - ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)', - - emptyFunction: function() {}, - K: function(x) {return x} -} - -var Class = { - create: function() { - return function() { - this.initialize.apply(this, arguments); - } - } -} - -var Abstract = new Object(); - -Object.extend = function(destination, source) { - for (property in source) { - destination[property] = source[property]; - } - return destination; -} - -Object.inspect = function(object) { - try { - if (object == undefined) return 'undefined'; - if (object == null) return 'null'; - return object.inspect ? object.inspect() : object.toString(); - } catch (e) { - if (e instanceof RangeError) return '...'; - throw e; - } -} - -Function.prototype.bind = function() { - var __method = this, args = $A(arguments), object = args.shift(); - return function() { - return __method.apply(object, args.concat($A(arguments))); - } -} - -Function.prototype.bindAsEventListener = function(object) { - var __method = this; - return function(event) { - return __method.call(object, event || window.event); - } -} - -Object.extend(Number.prototype, { - toColorPart: function() { - var digits = this.toString(16); - if (this < 16) return '0' + digits; - return digits; - }, - - succ: function() { - return this + 1; - }, - - times: function(iterator) { - $R(0, this, true).each(iterator); - return this; - } -}); - -var Try = { - these: function() { - var returnValue; - - for (var i = 0; i < arguments.length; i++) { - var lambda = arguments[i]; - try { - returnValue = lambda(); - break; - } catch (e) {} - } - - return returnValue; - } -} - -/*--------------------------------------------------------------------------*/ - -var PeriodicalExecuter = Class.create(); -PeriodicalExecuter.prototype = { - initialize: function(callback, frequency) { - this.callback = callback; - this.frequency = frequency; - this.currentlyExecuting = false; - - this.registerCallback(); - }, - - registerCallback: function() { - setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - onTimerEvent: function() { - if (!this.currentlyExecuting) { - try { - this.currentlyExecuting = true; - this.callback(); - } finally { - this.currentlyExecuting = false; - } - } - } -} - -/*--------------------------------------------------------------------------*/ - -function $() { - var elements = new Array(); - - for (var i = 0; i < arguments.length; i++) { - var element = arguments[i]; - if (typeof element == 'string') - element = document.getElementById(element); - - if (arguments.length == 1) - return element; - - elements.push(element); - } - - return elements; -} -Object.extend(String.prototype, { - stripTags: function() { - return this.replace(/<\/?[^>]+>/gi, ''); - }, - - stripScripts: function() { - return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); - }, - - extractScripts: function() { - var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); - var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); - return (this.match(matchAll) || []).map(function(scriptTag) { - return (scriptTag.match(matchOne) || ['', ''])[1]; - }); - }, - - evalScripts: function() { - return this.extractScripts().map(eval); - }, - - escapeHTML: function() { - var div = document.createElement('div'); - var text = document.createTextNode(this); - div.appendChild(text); - return div.innerHTML; - }, - - unescapeHTML: function() { - var div = document.createElement('div'); - div.innerHTML = this.stripTags(); - return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; - }, - - toQueryParams: function() { - var pairs = this.match(/^\??(.*)$/)[1].split('&'); - return pairs.inject({}, function(params, pairString) { - var pair = pairString.split('='); - params[pair[0]] = pair[1]; - return params; - }); - }, - - toArray: function() { - return this.split(''); - }, - - camelize: function() { - var oStringList = this.split('-'); - if (oStringList.length == 1) return oStringList[0]; - - var camelizedString = this.indexOf('-') == 0 - ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) - : oStringList[0]; - - for (var i = 1, len = oStringList.length; i < len; i++) { - var s = oStringList[i]; - camelizedString += s.charAt(0).toUpperCase() + s.substring(1); - } - - return camelizedString; - }, - - inspect: function() { - return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'"; - } -}); - -String.prototype.parseQuery = String.prototype.toQueryParams; - -var $break = new Object(); -var $continue = new Object(); - -var Enumerable = { - each: function(iterator) { - var index = 0; - try { - this._each(function(value) { - try { - iterator(value, index++); - } catch (e) { - if (e != $continue) throw e; - } - }); - } catch (e) { - if (e != $break) throw e; - } - }, - - all: function(iterator) { - var result = true; - this.each(function(value, index) { - result = result && !!(iterator || Prototype.K)(value, index); - if (!result) throw $break; - }); - return result; - }, - - any: function(iterator) { - var result = true; - this.each(function(value, index) { - if (result = !!(iterator || Prototype.K)(value, index)) - throw $break; - }); - return result; - }, - - collect: function(iterator) { - var results = []; - this.each(function(value, index) { - results.push(iterator(value, index)); - }); - return results; - }, - - detect: function (iterator) { - var result; - this.each(function(value, index) { - if (iterator(value, index)) { - result = value; - throw $break; - } - }); - return result; - }, - - findAll: function(iterator) { - var results = []; - this.each(function(value, index) { - if (iterator(value, index)) - results.push(value); - }); - return results; - }, - - grep: function(pattern, iterator) { - var results = []; - this.each(function(value, index) { - var stringValue = value.toString(); - if (stringValue.match(pattern)) - results.push((iterator || Prototype.K)(value, index)); - }) - return results; - }, - - include: function(object) { - var found = false; - this.each(function(value) { - if (value == object) { - found = true; - throw $break; - } - }); - return found; - }, - - inject: function(memo, iterator) { - this.each(function(value, index) { - memo = iterator(memo, value, index); - }); - return memo; - }, - - invoke: function(method) { - var args = $A(arguments).slice(1); - return this.collect(function(value) { - return value[method].apply(value, args); - }); - }, - - max: function(iterator) { - var result; - this.each(function(value, index) { - value = (iterator || Prototype.K)(value, index); - if (value >= (result || value)) - result = value; - }); - return result; - }, - - min: function(iterator) { - var result; - this.each(function(value, index) { - value = (iterator || Prototype.K)(value, index); - if (value <= (result || value)) - result = value; - }); - return result; - }, - - partition: function(iterator) { - var trues = [], falses = []; - this.each(function(value, index) { - ((iterator || Prototype.K)(value, index) ? - trues : falses).push(value); - }); - return [trues, falses]; - }, - - pluck: function(property) { - var results = []; - this.each(function(value, index) { - results.push(value[property]); - }); - return results; - }, - - reject: function(iterator) { - var results = []; - this.each(function(value, index) { - if (!iterator(value, index)) - results.push(value); - }); - return results; - }, - - sortBy: function(iterator) { - return this.collect(function(value, index) { - return {value: value, criteria: iterator(value, index)}; - }).sort(function(left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }).pluck('value'); - }, - - toArray: function() { - return this.collect(Prototype.K); - }, - - zip: function() { - var iterator = Prototype.K, args = $A(arguments); - if (typeof args.last() == 'function') - iterator = args.pop(); - - var collections = [this].concat(args).map($A); - return this.map(function(value, index) { - iterator(value = collections.pluck(index)); - return value; - }); - }, - - inspect: function() { - return '#'; - } -} - -Object.extend(Enumerable, { - map: Enumerable.collect, - find: Enumerable.detect, - select: Enumerable.findAll, - member: Enumerable.include, - entries: Enumerable.toArray -}); -var $A = Array.from = function(iterable) { - if (!iterable) return []; - if (iterable.toArray) { - return iterable.toArray(); - } else { - var results = []; - for (var i = 0; i < iterable.length; i++) - results.push(iterable[i]); - return results; - } -} - -Object.extend(Array.prototype, Enumerable); - -Array.prototype._reverse = Array.prototype.reverse; - -Object.extend(Array.prototype, { - _each: function(iterator) { - for (var i = 0; i < this.length; i++) - iterator(this[i]); - }, - - clear: function() { - this.length = 0; - return this; - }, - - first: function() { - return this[0]; - }, - - last: function() { - return this[this.length - 1]; - }, - - compact: function() { - return this.select(function(value) { - return value != undefined || value != null; - }); - }, - - flatten: function() { - return this.inject([], function(array, value) { - return array.concat(value.constructor == Array ? - value.flatten() : [value]); - }); - }, - - without: function() { - var values = $A(arguments); - return this.select(function(value) { - return !values.include(value); - }); - }, - - indexOf: function(object) { - for (var i = 0; i < this.length; i++) - if (this[i] == object) return i; - return -1; - }, - - reverse: function(inline) { - return (inline !== false ? this : this.toArray())._reverse(); - }, - - shift: function() { - var result = this[0]; - for (var i = 0; i < this.length - 1; i++) - this[i] = this[i + 1]; - this.length--; - return result; - }, - - inspect: function() { - return '[' + this.map(Object.inspect).join(', ') + ']'; - } -}); -var Hash = { - _each: function(iterator) { - for (key in this) { - var value = this[key]; - if (typeof value == 'function') continue; - - var pair = [key, value]; - pair.key = key; - pair.value = value; - iterator(pair); - } - }, - - keys: function() { - return this.pluck('key'); - }, - - values: function() { - return this.pluck('value'); - }, - - merge: function(hash) { - return $H(hash).inject($H(this), function(mergedHash, pair) { - mergedHash[pair.key] = pair.value; - return mergedHash; - }); - }, - - toQueryString: function() { - return this.map(function(pair) { - return pair.map(encodeURIComponent).join('='); - }).join('&'); - }, - - inspect: function() { - return '#'; - } -} - -function $H(object) { - var hash = Object.extend({}, object || {}); - Object.extend(hash, Enumerable); - Object.extend(hash, Hash); - return hash; -} -ObjectRange = Class.create(); -Object.extend(ObjectRange.prototype, Enumerable); -Object.extend(ObjectRange.prototype, { - initialize: function(start, end, exclusive) { - this.start = start; - this.end = end; - this.exclusive = exclusive; - }, - - _each: function(iterator) { - var value = this.start; - do { - iterator(value); - value = value.succ(); - } while (this.include(value)); - }, - - include: function(value) { - if (value < this.start) - return false; - if (this.exclusive) - return value < this.end; - return value <= this.end; - } -}); - -var $R = function(start, end, exclusive) { - return new ObjectRange(start, end, exclusive); -} - -var Ajax = { - getTransport: function() { - return Try.these( - function() {return new ActiveXObject('Msxml2.XMLHTTP')}, - function() {return new ActiveXObject('Microsoft.XMLHTTP')}, - function() {return new XMLHttpRequest()} - ) || false; - }, - - activeRequestCount: 0 -} - -Ajax.Responders = { - responders: [], - - _each: function(iterator) { - this.responders._each(iterator); - }, - - register: function(responderToAdd) { - if (!this.include(responderToAdd)) - this.responders.push(responderToAdd); - }, - - unregister: function(responderToRemove) { - this.responders = this.responders.without(responderToRemove); - }, - - dispatch: function(callback, request, transport, json) { - this.each(function(responder) { - if (responder[callback] && typeof responder[callback] == 'function') { - try { - responder[callback].apply(responder, [request, transport, json]); - } catch (e) {} - } - }); - } -}; - -Object.extend(Ajax.Responders, Enumerable); - -Ajax.Responders.register({ - onCreate: function() { - Ajax.activeRequestCount++; - }, - - onComplete: function() { - Ajax.activeRequestCount--; - } -}); - -Ajax.Base = function() {}; -Ajax.Base.prototype = { - setOptions: function(options) { - this.options = { - method: 'post', - asynchronous: true, - parameters: '' - } - Object.extend(this.options, options || {}); - }, - - responseIsSuccess: function() { - return this.transport.status == undefined - || this.transport.status == 0 - || (this.transport.status >= 200 && this.transport.status < 300); - }, - - responseIsFailure: function() { - return !this.responseIsSuccess(); - } -} - -Ajax.Request = Class.create(); -Ajax.Request.Events = - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; - -Ajax.Request.prototype = Object.extend(new Ajax.Base(), { - initialize: function(url, options) { - this.transport = Ajax.getTransport(); - this.setOptions(options); - this.request(url); - }, - - request: function(url) { - var parameters = this.options.parameters || ''; - if (parameters.length > 0) parameters += '&_='; - - try { - this.url = url; - if (this.options.method == 'get' && parameters.length > 0) - this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; - - Ajax.Responders.dispatch('onCreate', this, this.transport); - - this.transport.open(this.options.method, this.url, - this.options.asynchronous); - - if (this.options.asynchronous) { - this.transport.onreadystatechange = this.onStateChange.bind(this); - setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); - } - - this.setRequestHeaders(); - - var body = this.options.postBody ? this.options.postBody : parameters; - this.transport.send(this.options.method == 'post' ? body : null); - - } catch (e) { - this.dispatchException(e); - } - }, - - setRequestHeaders: function() { - var requestHeaders = - ['X-Requested-With', 'XMLHttpRequest', - 'X-Prototype-Version', Prototype.Version]; - - if (this.options.method == 'post') { - requestHeaders.push('Content-type', - 'application/x-www-form-urlencoded'); - - /* Force "Connection: close" for Mozilla browsers to work around - * a bug where XMLHttpReqeuest sends an incorrect Content-length - * header. See Mozilla Bugzilla #246651. - */ - if (this.transport.overrideMimeType) - requestHeaders.push('Connection', 'close'); - } - - if (this.options.requestHeaders) - requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); - - for (var i = 0; i < requestHeaders.length; i += 2) - this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); - }, - - onStateChange: function() { - var readyState = this.transport.readyState; - if (readyState != 1) - this.respondToReadyState(this.transport.readyState); - }, - - header: function(name) { - try { - return this.transport.getResponseHeader(name); - } catch (e) {} - }, - - evalJSON: function() { - try { - return eval(this.header('X-JSON')); - } catch (e) {} - }, - - evalResponse: function() { - try { - return eval(this.transport.responseText); - } catch (e) { - this.dispatchException(e); - } - }, - - respondToReadyState: function(readyState) { - var event = Ajax.Request.Events[readyState]; - var transport = this.transport, json = this.evalJSON(); - - if (event == 'Complete') { - try { - (this.options['on' + this.transport.status] - || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] - || Prototype.emptyFunction)(transport, json); - } catch (e) { - this.dispatchException(e); - } - - if ((this.header('Content-type') || '').match(/^text\/javascript/i)) - this.evalResponse(); - } - - try { - (this.options['on' + event] || Prototype.emptyFunction)(transport, json); - Ajax.Responders.dispatch('on' + event, this, transport, json); - } catch (e) { - this.dispatchException(e); - } - - /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ - if (event == 'Complete') - this.transport.onreadystatechange = Prototype.emptyFunction; - }, - - dispatchException: function(exception) { - (this.options.onException || Prototype.emptyFunction)(this, exception); - Ajax.Responders.dispatch('onException', this, exception); - } -}); - -Ajax.Updater = Class.create(); - -Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { - initialize: function(container, url, options) { - this.containers = { - success: container.success ? $(container.success) : $(container), - failure: container.failure ? $(container.failure) : - (container.success ? null : $(container)) - } - - this.transport = Ajax.getTransport(); - this.setOptions(options); - - var onComplete = this.options.onComplete || Prototype.emptyFunction; - this.options.onComplete = (function(transport, object) { - this.updateContent(); - onComplete(transport, object); - }).bind(this); - - this.request(url); - }, - - updateContent: function() { - var receiver = this.responseIsSuccess() ? - this.containers.success : this.containers.failure; - var response = this.transport.responseText; - - if (!this.options.evalScripts) - response = response.stripScripts(); - - if (receiver) { - if (this.options.insertion) { - new this.options.insertion(receiver, response); - } else { - Element.update(receiver, response); - } - } - - if (this.responseIsSuccess()) { - if (this.onComplete) - setTimeout(this.onComplete.bind(this), 10); - } - } -}); - -Ajax.PeriodicalUpdater = Class.create(); -Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { - initialize: function(container, url, options) { - this.setOptions(options); - this.onComplete = this.options.onComplete; - - this.frequency = (this.options.frequency || 2); - this.decay = (this.options.decay || 1); - - this.updater = {}; - this.container = container; - this.url = url; - - this.start(); - }, - - start: function() { - this.options.onComplete = this.updateComplete.bind(this); - this.onTimerEvent(); - }, - - stop: function() { - this.updater.onComplete = undefined; - clearTimeout(this.timer); - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - }, - - updateComplete: function(request) { - if (this.options.decay) { - this.decay = (request.responseText == this.lastText ? - this.decay * this.options.decay : 1); - - this.lastText = request.responseText; - } - this.timer = setTimeout(this.onTimerEvent.bind(this), - this.decay * this.frequency * 1000); - }, - - onTimerEvent: function() { - this.updater = new Ajax.Updater(this.container, this.url, this.options); - } -}); -document.getElementsByClassName = function(className, parentElement) { - var children = ($(parentElement) || document.body).getElementsByTagName('*'); - return $A(children).inject([], function(elements, child) { - if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) - elements.push(child); - return elements; - }); -} - -/*--------------------------------------------------------------------------*/ - -if (!window.Element) { - var Element = new Object(); -} - -Object.extend(Element, { - visible: function(element) { - return $(element).style.display != 'none'; - }, - - toggle: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - Element[Element.visible(element) ? 'hide' : 'show'](element); - } - }, - - hide: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - element.style.display = 'none'; - } - }, - - show: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - element.style.display = ''; - } - }, - - remove: function(element) { - element = $(element); - element.parentNode.removeChild(element); - }, - - update: function(element, html) { - $(element).innerHTML = html.stripScripts(); - setTimeout(function() {html.evalScripts()}, 10); - }, - - getHeight: function(element) { - element = $(element); - return element.offsetHeight; - }, - - classNames: function(element) { - return new Element.ClassNames(element); - }, - - hasClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).include(className); - }, - - addClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).add(className); - }, - - removeClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).remove(className); - }, - - // removes whitespace-only text node children - cleanWhitespace: function(element) { - element = $(element); - for (var i = 0; i < element.childNodes.length; i++) { - var node = element.childNodes[i]; - if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) - Element.remove(node); - } - }, - - empty: function(element) { - return $(element).innerHTML.match(/^\s*$/); - }, - - scrollTo: function(element) { - element = $(element); - var x = element.x ? element.x : element.offsetLeft, - y = element.y ? element.y : element.offsetTop; - window.scrollTo(x, y); - }, - - getStyle: function(element, style) { - element = $(element); - var value = element.style[style.camelize()]; - if (!value) { - if (document.defaultView && document.defaultView.getComputedStyle) { - var css = document.defaultView.getComputedStyle(element, null); - value = css ? css.getPropertyValue(style) : null; - } else if (element.currentStyle) { - value = element.currentStyle[style.camelize()]; - } - } - - if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) - if (Element.getStyle(element, 'position') == 'static') value = 'auto'; - - return value == 'auto' ? null : value; - }, - - setStyle: function(element, style) { - element = $(element); - for (name in style) - element.style[name.camelize()] = style[name]; - }, - - getDimensions: function(element) { - element = $(element); - if (Element.getStyle(element, 'display') != 'none') - return {width: element.offsetWidth, height: element.offsetHeight}; - - // All *Width and *Height properties give 0 on elements with display none, - // so enable the element temporarily - var els = element.style; - var originalVisibility = els.visibility; - var originalPosition = els.position; - els.visibility = 'hidden'; - els.position = 'absolute'; - els.display = ''; - var originalWidth = element.clientWidth; - var originalHeight = element.clientHeight; - els.display = 'none'; - els.position = originalPosition; - els.visibility = originalVisibility; - return {width: originalWidth, height: originalHeight}; - }, - - makePositioned: function(element) { - element = $(element); - var pos = Element.getStyle(element, 'position'); - if (pos == 'static' || !pos) { - element._madePositioned = true; - element.style.position = 'relative'; - // Opera returns the offset relative to the positioning context, when an - // element is position relative but top and left have not been defined - if (window.opera) { - element.style.top = 0; - element.style.left = 0; - } - } - }, - - undoPositioned: function(element) { - element = $(element); - if (element._madePositioned) { - element._madePositioned = undefined; - element.style.position = - element.style.top = - element.style.left = - element.style.bottom = - element.style.right = ''; - } - }, - - makeClipping: function(element) { - element = $(element); - if (element._overflow) return; - element._overflow = element.style.overflow; - if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') - element.style.overflow = 'hidden'; - }, - - undoClipping: function(element) { - element = $(element); - if (element._overflow) return; - element.style.overflow = element._overflow; - element._overflow = undefined; - } -}); - -var Toggle = new Object(); -Toggle.display = Element.toggle; - -/*--------------------------------------------------------------------------*/ - -Abstract.Insertion = function(adjacency) { - this.adjacency = adjacency; -} - -Abstract.Insertion.prototype = { - initialize: function(element, content) { - this.element = $(element); - this.content = content.stripScripts(); - - if (this.adjacency && this.element.insertAdjacentHTML) { - try { - this.element.insertAdjacentHTML(this.adjacency, this.content); - } catch (e) { - if (this.element.tagName.toLowerCase() == 'tbody') { - this.insertContent(this.contentFromAnonymousTable()); - } else { - throw e; - } - } - } else { - this.range = this.element.ownerDocument.createRange(); - if (this.initializeRange) this.initializeRange(); - this.insertContent([this.range.createContextualFragment(this.content)]); - } - - setTimeout(function() {content.evalScripts()}, 10); - }, - - contentFromAnonymousTable: function() { - var div = document.createElement('div'); - div.innerHTML = '' + this.content + '
'; - return $A(div.childNodes[0].childNodes[0].childNodes); - } -} - -var Insertion = new Object(); - -Insertion.Before = Class.create(); -Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { - initializeRange: function() { - this.range.setStartBefore(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.parentNode.insertBefore(fragment, this.element); - }).bind(this)); - } -}); - -Insertion.Top = Class.create(); -Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { - initializeRange: function() { - this.range.selectNodeContents(this.element); - this.range.collapse(true); - }, - - insertContent: function(fragments) { - fragments.reverse(false).each((function(fragment) { - this.element.insertBefore(fragment, this.element.firstChild); - }).bind(this)); - } -}); - -Insertion.Bottom = Class.create(); -Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { - initializeRange: function() { - this.range.selectNodeContents(this.element); - this.range.collapse(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.appendChild(fragment); - }).bind(this)); - } -}); - -Insertion.After = Class.create(); -Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { - initializeRange: function() { - this.range.setStartAfter(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.parentNode.insertBefore(fragment, - this.element.nextSibling); - }).bind(this)); - } -}); - -/*--------------------------------------------------------------------------*/ - -Element.ClassNames = Class.create(); -Element.ClassNames.prototype = { - initialize: function(element) { - this.element = $(element); - }, - - _each: function(iterator) { - this.element.className.split(/\s+/).select(function(name) { - return name.length > 0; - })._each(iterator); - }, - - set: function(className) { - this.element.className = className; - }, - - add: function(classNameToAdd) { - if (this.include(classNameToAdd)) return; - this.set(this.toArray().concat(classNameToAdd).join(' ')); - }, - - remove: function(classNameToRemove) { - if (!this.include(classNameToRemove)) return; - this.set(this.select(function(className) { - return className != classNameToRemove; - }).join(' ')); - }, - - toString: function() { - return this.toArray().join(' '); - } -} - -Object.extend(Element.ClassNames.prototype, Enumerable); -var Field = { - clear: function() { - for (var i = 0; i < arguments.length; i++) - $(arguments[i]).value = ''; - }, - - focus: function(element) { - $(element).focus(); - }, - - present: function() { - for (var i = 0; i < arguments.length; i++) - if ($(arguments[i]).value == '') return false; - return true; - }, - - select: function(element) { - $(element).select(); - }, - - activate: function(element) { - element = $(element); - element.focus(); - if (element.select) - element.select(); - } -} - -/*--------------------------------------------------------------------------*/ - -var Form = { - serialize: function(form) { - var elements = Form.getElements($(form)); - var queryComponents = new Array(); - - for (var i = 0; i < elements.length; i++) { - var queryComponent = Form.Element.serialize(elements[i]); - if (queryComponent) - queryComponents.push(queryComponent); - } - - return queryComponents.join('&'); - }, - - getElements: function(form) { - form = $(form); - var elements = new Array(); - - for (tagName in Form.Element.Serializers) { - var tagElements = form.getElementsByTagName(tagName); - for (var j = 0; j < tagElements.length; j++) - elements.push(tagElements[j]); - } - return elements; - }, - - getInputs: function(form, typeName, name) { - form = $(form); - var inputs = form.getElementsByTagName('input'); - - if (!typeName && !name) - return inputs; - - var matchingInputs = new Array(); - for (var i = 0; i < inputs.length; i++) { - var input = inputs[i]; - if ((typeName && input.type != typeName) || - (name && input.name != name)) - continue; - matchingInputs.push(input); - } - - return matchingInputs; - }, - - disable: function(form) { - var elements = Form.getElements(form); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - element.blur(); - element.disabled = 'true'; - } - }, - - enable: function(form) { - var elements = Form.getElements(form); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - element.disabled = ''; - } - }, - - findFirstElement: function(form) { - return Form.getElements(form).find(function(element) { - return element.type != 'hidden' && !element.disabled && - ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); - }); - }, - - focusFirstElement: function(form) { - Field.activate(Form.findFirstElement(form)); - }, - - reset: function(form) { - $(form).reset(); - } -} - -Form.Element = { - serialize: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - var parameter = Form.Element.Serializers[method](element); - - if (parameter) { - var key = encodeURIComponent(parameter[0]); - if (key.length == 0) return; - - if (parameter[1].constructor != Array) - parameter[1] = [parameter[1]]; - - return parameter[1].map(function(value) { - return key + '=' + encodeURIComponent(value); - }).join('&'); - } - }, - - getValue: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - var parameter = Form.Element.Serializers[method](element); - - if (parameter) - return parameter[1]; - } -} - -Form.Element.Serializers = { - input: function(element) { - switch (element.type.toLowerCase()) { - case 'submit': - case 'hidden': - case 'password': - case 'text': - return Form.Element.Serializers.textarea(element); - case 'checkbox': - case 'radio': - return Form.Element.Serializers.inputSelector(element); - } - return false; - }, - - inputSelector: function(element) { - if (element.checked) - return [element.name, element.value]; - }, - - textarea: function(element) { - return [element.name, element.value]; - }, - - select: function(element) { - return Form.Element.Serializers[element.type == 'select-one' ? - 'selectOne' : 'selectMany'](element); - }, - - selectOne: function(element) { - var value = '', opt, index = element.selectedIndex; - if (index >= 0) { - opt = element.options[index]; - value = opt.value; - if (!value && !('value' in opt)) - value = opt.text; - } - return [element.name, value]; - }, - - selectMany: function(element) { - var value = new Array(); - for (var i = 0; i < element.length; i++) { - var opt = element.options[i]; - if (opt.selected) { - var optValue = opt.value; - if (!optValue && !('value' in opt)) - optValue = opt.text; - value.push(optValue); - } - } - return [element.name, value]; - } -} - -/*--------------------------------------------------------------------------*/ - -var $F = Form.Element.getValue; - -/*--------------------------------------------------------------------------*/ - -Abstract.TimedObserver = function() {} -Abstract.TimedObserver.prototype = { - initialize: function(element, frequency, callback) { - this.frequency = frequency; - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - this.registerCallback(); - }, - - registerCallback: function() { - setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - onTimerEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - } -} - -Form.Element.Observer = Class.create(); -Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.Observer = Class.create(); -Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { - getValue: function() { - return Form.serialize(this.element); - } -}); - -/*--------------------------------------------------------------------------*/ - -Abstract.EventObserver = function() {} -Abstract.EventObserver.prototype = { - initialize: function(element, callback) { - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - if (this.element.tagName.toLowerCase() == 'form') - this.registerFormCallbacks(); - else - this.registerCallback(this.element); - }, - - onElementEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - }, - - registerFormCallbacks: function() { - var elements = Form.getElements(this.element); - for (var i = 0; i < elements.length; i++) - this.registerCallback(elements[i]); - }, - - registerCallback: function(element) { - if (element.type) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - Event.observe(element, 'click', this.onElementEvent.bind(this)); - break; - case 'password': - case 'text': - case 'textarea': - case 'select-one': - case 'select-multiple': - Event.observe(element, 'change', this.onElementEvent.bind(this)); - break; - } - } - } -} - -Form.Element.EventObserver = Class.create(); -Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.EventObserver = Class.create(); -Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { - getValue: function() { - return Form.serialize(this.element); - } -}); -if (!window.Event) { - var Event = new Object(); -} - -Object.extend(Event, { - KEY_BACKSPACE: 8, - KEY_TAB: 9, - KEY_RETURN: 13, - KEY_ESC: 27, - KEY_LEFT: 37, - KEY_UP: 38, - KEY_RIGHT: 39, - KEY_DOWN: 40, - KEY_DELETE: 46, - - element: function(event) { - return event.target || event.srcElement; - }, - - isLeftClick: function(event) { - return (((event.which) && (event.which == 1)) || - ((event.button) && (event.button == 1))); - }, - - pointerX: function(event) { - return event.pageX || (event.clientX + - (document.documentElement.scrollLeft || document.body.scrollLeft)); - }, - - pointerY: function(event) { - return event.pageY || (event.clientY + - (document.documentElement.scrollTop || document.body.scrollTop)); - }, - - stop: function(event) { - if (event.preventDefault) { - event.preventDefault(); - event.stopPropagation(); - } else { - event.returnValue = false; - event.cancelBubble = true; - } - }, - - // find the first node with the given tagName, starting from the - // node the event was triggered on; traverses the DOM upwards - findElement: function(event, tagName) { - var element = Event.element(event); - while (element.parentNode && (!element.tagName || - (element.tagName.toUpperCase() != tagName.toUpperCase()))) - element = element.parentNode; - return element; - }, - - observers: false, - - _observeAndCache: function(element, name, observer, useCapture) { - if (!this.observers) this.observers = []; - if (element.addEventListener) { - this.observers.push([element, name, observer, useCapture]); - element.addEventListener(name, observer, useCapture); - } else if (element.attachEvent) { - this.observers.push([element, name, observer, useCapture]); - element.attachEvent('on' + name, observer); - } - }, - - unloadCache: function() { - if (!Event.observers) return; - for (var i = 0; i < Event.observers.length; i++) { - Event.stopObserving.apply(this, Event.observers[i]); - Event.observers[i][0] = null; - } - Event.observers = false; - }, - - observe: function(element, name, observer, useCapture) { - var element = $(element); - useCapture = useCapture || false; - - if (name == 'keypress' && - (navigator.appVersion.match(/Konqueror|Safari|KHTML/) - || element.attachEvent)) - name = 'keydown'; - - this._observeAndCache(element, name, observer, useCapture); - }, - - stopObserving: function(element, name, observer, useCapture) { - var element = $(element); - useCapture = useCapture || false; - - if (name == 'keypress' && - (navigator.appVersion.match(/Konqueror|Safari|KHTML/) - || element.detachEvent)) - name = 'keydown'; - - if (element.removeEventListener) { - element.removeEventListener(name, observer, useCapture); - } else if (element.detachEvent) { - element.detachEvent('on' + name, observer); - } - } -}); - -/* prevent memory leaks in IE */ -Event.observe(window, 'unload', Event.unloadCache, false); -var Position = { - // set to true if needed, warning: firefox performance problems - // NOT neeeded for page scrolling, only if draggable contained in - // scrollable elements - includeScrollOffsets: false, - - // must be called before calling withinIncludingScrolloffset, every time the - // page is scrolled - prepare: function() { - this.deltaX = window.pageXOffset - || document.documentElement.scrollLeft - || document.body.scrollLeft - || 0; - this.deltaY = window.pageYOffset - || document.documentElement.scrollTop - || document.body.scrollTop - || 0; - }, - - realOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.scrollTop || 0; - valueL += element.scrollLeft || 0; - element = element.parentNode; - } while (element); - return [valueL, valueT]; - }, - - cumulativeOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - return [valueL, valueT]; - }, - - positionedOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - if (element) { - p = Element.getStyle(element, 'position'); - if (p == 'relative' || p == 'absolute') break; - } - } while (element); - return [valueL, valueT]; - }, - - offsetParent: function(element) { - if (element.offsetParent) return element.offsetParent; - if (element == document.body) return element; - - while ((element = element.parentNode) && element != document.body) - if (Element.getStyle(element, 'position') != 'static') - return element; - - return document.body; - }, - - // caches x/y coordinate pair to use with overlap - within: function(element, x, y) { - if (this.includeScrollOffsets) - return this.withinIncludingScrolloffsets(element, x, y); - this.xcomp = x; - this.ycomp = y; - this.offset = this.cumulativeOffset(element); - - return (y >= this.offset[1] && - y < this.offset[1] + element.offsetHeight && - x >= this.offset[0] && - x < this.offset[0] + element.offsetWidth); - }, - - withinIncludingScrolloffsets: function(element, x, y) { - var offsetcache = this.realOffset(element); - - this.xcomp = x + offsetcache[0] - this.deltaX; - this.ycomp = y + offsetcache[1] - this.deltaY; - this.offset = this.cumulativeOffset(element); - - return (this.ycomp >= this.offset[1] && - this.ycomp < this.offset[1] + element.offsetHeight && - this.xcomp >= this.offset[0] && - this.xcomp < this.offset[0] + element.offsetWidth); - }, - - // within must be called directly before - overlap: function(mode, element) { - if (!mode) return 0; - if (mode == 'vertical') - return ((this.offset[1] + element.offsetHeight) - this.ycomp) / - element.offsetHeight; - if (mode == 'horizontal') - return ((this.offset[0] + element.offsetWidth) - this.xcomp) / - element.offsetWidth; - }, - - clone: function(source, target) { - source = $(source); - target = $(target); - target.style.position = 'absolute'; - var offsets = this.cumulativeOffset(source); - target.style.top = offsets[1] + 'px'; - target.style.left = offsets[0] + 'px'; - target.style.width = source.offsetWidth + 'px'; - target.style.height = source.offsetHeight + 'px'; - }, - - page: function(forElement) { - var valueT = 0, valueL = 0; - - var element = forElement; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - - // Safari fix - if (element.offsetParent==document.body) - if (Element.getStyle(element,'position')=='absolute') break; - - } while (element = element.offsetParent); - - element = forElement; - do { - valueT -= element.scrollTop || 0; - valueL -= element.scrollLeft || 0; - } while (element = element.parentNode); - - return [valueL, valueT]; - }, - - clone: function(source, target) { - var options = Object.extend({ - setLeft: true, - setTop: true, - setWidth: true, - setHeight: true, - offsetTop: 0, - offsetLeft: 0 - }, arguments[2] || {}) - - // find page position of source - source = $(source); - var p = Position.page(source); - - // find coordinate system to use - target = $(target); - var delta = [0, 0]; - var parent = null; - // delta [0,0] will do fine with position: fixed elements, - // position:absolute needs offsetParent deltas - if (Element.getStyle(target,'position') == 'absolute') { - parent = Position.offsetParent(target); - delta = Position.page(parent); - } - - // correct by body offsets (fixes Safari) - if (parent == document.body) { - delta[0] -= document.body.offsetLeft; - delta[1] -= document.body.offsetTop; - } - - // set position - if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; - if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; - if(options.setWidth) target.style.width = source.offsetWidth + 'px'; - if(options.setHeight) target.style.height = source.offsetHeight + 'px'; - }, - - absolutize: function(element) { - element = $(element); - if (element.style.position == 'absolute') return; - Position.prepare(); - - var offsets = Position.positionedOffset(element); - var top = offsets[1]; - var left = offsets[0]; - var width = element.clientWidth; - var height = element.clientHeight; - - element._originalLeft = left - parseFloat(element.style.left || 0); - element._originalTop = top - parseFloat(element.style.top || 0); - element._originalWidth = element.style.width; - element._originalHeight = element.style.height; - - element.style.position = 'absolute'; - element.style.top = top + 'px';; - element.style.left = left + 'px';; - element.style.width = width + 'px';; - element.style.height = height + 'px';; - }, - - relativize: function(element) { - element = $(element); - if (element.style.position == 'relative') return; - Position.prepare(); - - element.style.position = 'relative'; - var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); - var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); - - element.style.top = top + 'px'; - element.style.left = left + 'px'; - element.style.height = element._originalHeight; - element.style.width = element._originalWidth; - } -} - -// Safari returns margins on body which is incorrect if the child is absolutely -// positioned. For performance reasons, redefine Position.cumulativeOffset for -// KHTML/WebKit only. -if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { - Position.cumulativeOffset = function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - if (element.offsetParent == document.body) - if (Element.getStyle(element, 'position') == 'absolute') break; - - element = element.offsetParent; - } while (element); - - return [valueL, valueT]; - } -} \ No newline at end of file diff --git a/easy-asterisk-gui/cgi-bin/set_network.sh b/easy-asterisk-gui/cgi-bin/set_network.sh deleted file mode 100644 index 5f65bf67..00000000 --- a/easy-asterisk-gui/cgi-bin/set_network.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/sh -# set_network.sh -# -# CGI to set network parameters of an IP0X. - -cat < - -set_network.sh - - -Please wait a few seconds..... - - - -EOF - -dhcp=`echo "$QUERY_STRING" | grep -oe "dhcp=[^&?]*" | sed -n "s/dhcp=//p"` -ipaddress=`echo "$QUERY_STRING" | grep -oe "ipaddress=[^&?]*" | sed -n "s/ipaddress=//p"` -netmask=`echo "$QUERY_STRING" | grep -oe "netmask=[^&?]*" | sed -n "s/netmask=//p"` -gateway=`echo "$QUERY_STRING" | grep -oe "gateway=[^&?]*" | sed -n "s/gateway=//p"` -dns=`echo "$QUERY_STRING" | grep -oe "dns=[^&?]*" | sed -n "s/dns=//p"` -backdoor=`echo "$QUERY_STRING" | grep -oe "backdoor=[^&?]*" | sed -n "s/backdoor=//p"` - -if [ $dhcp == "yes" ]; then - - # DHCP - - if [ -f /etc/rc.d/S10network-static ]; then - /etc/init.d/network-static disable - /etc/init.d/network-static stop - /etc/init.d/network enable - /etc/init.d/network start - else - # if already running restart service - /etc/init.d/network stop - /etc/init.d/network start - fi -fi - -if [ $dhcp == "no" ]; then - - # Static IP - - if [ -f /etc/rc.d/S10network ]; then - /etc/init.d/network stop - /etc/init.d/network disable - /etc/init.d/network-static enable - fi - - sed -i "s/DHCPD=.*/DHCPD=no/g" /etc/init.d/network-static - sed -i "s/IPADDRESS=.*/IPADDRESS=\"$ipaddress\"/g" /etc/init.d/network-static - sed -i "s/NETMASK=.*/NETMASK=\"$netmask\"/g" /etc/init.d/network-static - sed -i "s/GATEWAY=.*/GATEWAY=\"$gateway\"/g" /etc/init.d/network-static - sed -i "s/DNS=.*/DNS=\"$dns\"/g" /etc/init.d/network-static - /etc/init.d/network-static stop - /etc/init.d/network-static start -fi - -if [ -f /etc/rc.d/S05network-backdoor ]; then - sed -i "s/IPADDRESS=.*/IPADDRESS=\"$backdoor\"/g" /etc/init.d/network-backdoor - /etc/init.d/network-backdoor stop - /etc/init.d/network-backdoor start -fi diff --git a/easy-asterisk-gui/cgi-bin/set_ring.sh b/easy-asterisk-gui/cgi-bin/set_ring.sh deleted file mode 100644 index d9f2bd84..00000000 --- a/easy-asterisk-gui/cgi-bin/set_ring.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/sh -x -# set_ring.sh -# David Rowe 4 Jan 2010 -# CGI to set which extensions ring on uncoming calls - -# check we are logged in - -echo $HTTP_COOKIE | grep "loggedin" > /dev/null -if [ $? -eq 1 ]; then - echo "" - echo "" - echo '' - echo "" - echo "" - exit -fi - -# extract extensions to ring and reload extensions.conf - -a=`echo "$QUERY_STRING" | sed -n "s/=on*//pg" | sed -n 's,_,/,pg'` - -# escape & if present -echo "$a" | grep "&" >> /dev/null -if [ $? -eq 0 ]; then - a=`echo $a | sed -n "s/&/\\\\&/pg"` -fi - -sed -i "s_s,1,Dial(.*) ;; mini-asterisk_s,1,Dial($a) ;; mini-asterisk_" /etc/asterisk/extensions.conf -asterisk -rx "dialplan reload" 2>/dev/null 1 > /dev/null - -# bounce us back to Phones screen - -cat < - -Mini Asterisk - Set Ring - - -Please wait a few seconds..... -EOF -#echo $QUERY_STRING "
" -#echo "$QUERY_STRING" | sed -n "s/=on*//pg" | sed -n 's,_,/,pg' -#echo "
" -#echo $a - -cat < - - -EOF - diff --git a/easy-asterisk-gui/cgi-bin/set_voiplines.pl b/easy-asterisk-gui/cgi-bin/set_voiplines.pl deleted file mode 100644 index 2cee2e13..00000000 --- a/easy-asterisk-gui/cgi-bin/set_voiplines.pl +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/perl -# set_voiplines.pl -# David Rowe 12 Jan 2010 -# -# Replaces fields in sip.conf, outputs new sip.conf contents to stdout - -$user = $ARGV[0]; -$pass = $ARGV[1]; -$host = $ARGV[2]; -$stanza_new = $ARGV[3]; - -# We need to slurp up the mini asterisk provider and spit them -# back out. All must be commented out except for the one that -# is selected. Hopefully non-mini asterisk content of sip.conf -# won't be affected. - -open SIP, "/etc/asterisk/sip.conf"; -$provider = ""; -while () { - - # start of any new stanza switches off parsing. It may get - # switched back on below if it contains mini-asterisk - # keyword. This allows non-mini asterisk SIP stanzas to be - # included in sip.conf - - if (/\[/) { - $stanza = ""; - } - - # look for commented or uncommented mini asterisk provider stanza - - if (/\[(.*)\] .* mini-asterisk/) { - $stanza = $1; - } - - if ($stanza eq "") { - # we are not in an mini-asterisk provider stanza - - if (/;*register => (\S*)@(\S*).*;.*(mini-asterisk.*)/) { - # an mini-asterisk register line - - #print "XX stanza_new='$stanza_new' '$1' '$2' '$3'\n"; - - if ($2 eq $stanza_new) { - print "register => $user\@$stanza_new; $3\n"; - } - else { - print ";register => $1\@$2 ; $3\n"; - } - } - else { - # OK so this is a regular sip.conf line, just echo to stdout - print $_; - } - } - else { - # OK, we are in an mini-asterisk stanza - - # strip off any leading ";" - - $_ =~ s/^\;//; - - if ($stanza eq $stanza_new) { - - # this stanza should be uncommented - - if (/^user=/) { - print "user=$user\n"; - } - if (/^username=/) { - print "username=$user\n"; - } - elsif (/^fromuser=/) { - print "fromuser=$user\n"; - } - elsif (/^secret=/) { - print "secret=$pass\n"; - } - elsif (/^host=/) { - print "host=$host\n"; - } - else { - print $_; - } - } - else { - # comment out unused mini-asterisk stanzas - print ";$_"; - } - } - -} -close SIP; - diff --git a/easy-asterisk-gui/cgi-bin/set_voiplines.sh b/easy-asterisk-gui/cgi-bin/set_voiplines.sh deleted file mode 100644 index 3039a260..00000000 --- a/easy-asterisk-gui/cgi-bin/set_voiplines.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# set_voipline.sh -# # David Rowe 12 Jan 2010 -# -# CGI to set voip line parameters in sip.conf. - -# check we are logged in - -echo $HTTP_COOKIE | grep "loggedin" > /dev/null -if [ $? -eq 1 ]; then - echo "" - echo "" - echo '' - echo "" - echo "" - exit -fi - -user=`echo "$QUERY_STRING" | grep -oe "user=[^&?]*" | sed -n "s/user=//p"` -pass=`echo "$QUERY_STRING" | grep -oe "pass=[^&?]*" | sed -n "s/pass=//p"` -host=`echo "$QUERY_STRING" | grep -oe "host=[^&?]*" | sed -n "s/host=//p"` -stanza=`echo "$QUERY_STRING" | grep -oe "stanza=[^&?]*" | sed -n "s/stanza=//p"` - -# create new sip.conf with selected provider uncommented - -echo "set_voiplines.sh" $user $pass $host $stanza >> /tmp/log.txt -./set_voiplines.pl $user $pass $host $stanza > /etc/asterisk/sip.conf.new -mv /etc/asterisk/sip.conf /etc/asterisk/sip.conf.bak -mv /etc/asterisk/sip.conf.new /etc/asterisk/sip.conf - -# get asterisk to load changes - -asterisk -rx "sip reload" 2>/dev/null 1 > /dev/null - -cat < - -set_voiplines.sh - - -Please wait a few seconds..... - - - -EOF - diff --git a/easy-asterisk-gui/cgi-bin/tick.png b/easy-asterisk-gui/cgi-bin/tick.png deleted file mode 100644 index c155dff4..00000000 Binary files a/easy-asterisk-gui/cgi-bin/tick.png and /dev/null differ diff --git a/easy-asterisk-gui/cgi-bin/tooltip.css b/easy-asterisk-gui/cgi-bin/tooltip.css deleted file mode 100644 index f426356c..00000000 --- a/easy-asterisk-gui/cgi-bin/tooltip.css +++ /dev/null @@ -1,7 +0,0 @@ -.tip {font:12px/14px -Arial,Helvetica,sans-serif; border:solid 1px -#666666; width:270px; padding:1px; -position:absolute; z-index:100; -visibility:hidden; color:#333333; top:20px; -left:90px; background-color:#ffffcc; -layer-background-color:#ffffcc;} diff --git a/easy-asterisk-gui/cgi-bin/tooltip.js b/easy-asterisk-gui/cgi-bin/tooltip.js deleted file mode 100644 index 26142e8a..00000000 --- a/easy-asterisk-gui/cgi-bin/tooltip.js +++ /dev/null @@ -1,7 +0,0 @@ -// Extended Tooltip Javascript -// copyright 9th August 2002, 3rd July 2005, 24th August 2008 -// by Stephen Chapman, Felgall Pty Ltd - -// permission is granted to use this javascript provided that the below code is not altered -function pw() {return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth}; function mouseX(evt) {return evt.clientX ? evt.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) : evt.pageX;} function mouseY(evt) {return evt.clientY ? evt.clientY + (document.documentElement.scrollTop || document.body.scrollTop) : evt.pageY} function popUp(evt,oi) {if (document.getElementById) {var wp = pw(); dm = document.getElementById(oi); ds = dm.style; st = ds.visibility; if (dm.offsetWidth) ew = dm.offsetWidth; else if (dm.clip.width) ew = dm.clip.width; if (st == "visible" || st == "show") { ds.visibility = "hidden"; } else {tv = mouseY(evt) + 20; lv = mouseX(evt) - (ew/4); if (lv < 2) lv = 2; else if (lv + ew > wp) lv -= ew/2; lv += 'px';tv += 'px'; ds.left = lv; ds.top = tv; ds.visibility = "visible";}}} - diff --git a/easy-asterisk-gui/cgi-bin/tooltips.html b/easy-asterisk-gui/cgi-bin/tooltips.html deleted file mode 100644 index 91137b23..00000000 --- a/easy-asterisk-gui/cgi-bin/tooltips.html +++ /dev/null @@ -1,149 +0,0 @@ -
- A tick means your phone system can reach the Internet. You need the Internet for VOIP calls - and software upgrades. - If you have a problem reaching the Internet check your Network settings, in - particular Gateway and DNS.
- -
- Emergency backdoor IP. Useful if you get locked out of the main network connection, for - example due to DHCP problems on your network or a configuration mistake. - Write this number down somewhere!
- -
- If ticked this phone will ring when some one - calls the phone system from an outside Analog - or VOIP Line. More than one phone can be - ticked. You can answer a call on another - ringing phone by dialling *8 on your phone - - see FAQ for details.
- -
- Analog Phone: Normal telephone plugged into a port on your phone system. -
-
- IP Phone plugged into your network. -
-
- Analog Phone Line: Analog telephone line plugged into a port on your phone system. -
-
- VOIP Phone Line: Make and receive phone calls over the Internet. -
- -
- Important information about your Phone System.
- -
- The address of your Phone System - on your network. Use this address to connect - IP Phones to your Phone System.
- -
- List of phones connected to your Phone - System. You can connect Analog or IP Phones - to your system. When IP Phones are - configured correctly, they appear on this - list. If an IP phone is not configured - correctly, it will not appear on this list. - Analog phones require hardware to be - installed in your Phone system.
- -
- List of phone lines available. Phone lines - are used to make and receive outside calls. - You can use regular Analog phone lines or - VOIP. VOIP phone lines require an account - with an Internet Telephone Service Provider. - Analog phone lines require hardware to be - installed in your Phone System.
- -
- Dial this number to call this phone
- -
- Port (socket) on the rear of your Phone System. Plug the phone into this Port.
- -
- Port (socket) on the rear of your Phone - System. Plug the phone line into this - Port.
- -
- Dial 0 for an Analog outside line. For example to call 5551234 dial 05551234
- -
- IP Address of this phone on your network
- -
- IP Address of the VOIP Internet Telephone Service Provider
- -
- Dial 1 for a VOIP outside line. For example to call 5551234 dial 15551234
- -
- Instructions and help on adding a new IP phone
- -
- Instructions and help on VOIP Line set up
- -
- List of possible IP phones. For a new phone - choose any Available number. Refresh this - page to update
- -
- The IP phone is connected to your phone system and ready to use
- -
- No IP phone is connected. Either no IP phone - is present, or the IP phone has not been set - up.
- -
- A VOIP line allows you to make and receive - phones calls over the Internet. Normally a - VOIP line is provided by an Internet Telephony - Service Provider (ITSP). They will give you - an account, which includes the user and - password details that you can fill in below. - Refresh this page on your browser to see if - your VOIP line is working.
- -
- Your Internet Telephony Service Provider. - They will give you an account with a user name - and password.
- -
- Your account name with your Internet Telephony Service Provider
- -
- The password for your Internet Telephony Service Provider account
- -
- The Internet address of your Internet - Telephony Service Provider. This will usually - be filled in automatically.
- -
- A tick means you are connected to your - Internet Telephony Service Provider. Refresh - your browser to update.
- -
- Press this button to restart your phone - system. This is the same as turning the power - off and back on.
- -
- Press this button to the latest version of - Mini Asterisk. An Mini Asterisk upgrade - requires an Internet connection.
- -
- Enter the URL of a firmware update script. - This option can be used to install new - firmware on your Phone System. Installing new - firmware requires an Internet - connection.
- diff --git a/easy-asterisk-gui/cgi-bin/voiplines.js b/easy-asterisk-gui/cgi-bin/voiplines.js deleted file mode 100644 index 083838af..00000000 --- a/easy-asterisk-gui/cgi-bin/voiplines.js +++ /dev/null @@ -1,7 +0,0 @@ -function changeProvider() { - provider = $('provider').value; - $('user').value = users[provider]; - $('pass').value = passwords[provider]; - $('host').value = hosts[provider]; - $('stanza').value = stanzas[provider]; -} diff --git a/easy-asterisk-gui/cgi-bin/voiplines.pl b/easy-asterisk-gui/cgi-bin/voiplines.pl deleted file mode 100644 index d8ccdca8..00000000 --- a/easy-asterisk-gui/cgi-bin/voiplines.pl +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/perl -# voiplines.pl -# David Rowe 12 Jan 2010 -# -# Text processing for the voiplines screen - -# slurp up list of possible voip line providers -------------------------------- -# one of these will be currently selected - -open SIP, "/etc/asterisk/sip.conf"; -my $provider = ""; # current provider bring parsed in sip.conf -my @providers=(); # list of all providers -my %stanza = (); # stanza name keyed on provider -my %user = (); # user keyed on provider -my %pass = (); # password keyed on provider -my %host = (); # host name keyed on provider - -while () { - - # start of any stanza switches off parsing. It may get switched - # back on below if it contains mini-asterisk keyword. This allows - # non-mini asterisk SIP devices to be included in sip.conf - - if (/\[/) { - $provider = ""; - } - - # currently disabled mini-asterisk provider - - if (/^;\[(.*)\].* \"(.*)\" mini-asterisk/) { - push (@providers, $2); - $provider = $2; - $stanza{$2} = $1; - #print "'$1' '$2'\n"; - } - - # current mini-asterisk provider - - if (/^\[(.*)\].* \"(.*)\" mini-asterisk/) { - push (@providers, $2); - $provider = $2; - $provider_current = $2; - $stanza{$2} = $1; - #print "'$1' '$2'\n"; - } - - if ($provider ne "") { - #print $_; - - if (/^;*user=(.*)/) { - $user{$provider} = $1; - } - if (/^;*username=(.*)/) { - $user{$provider} = $1; - } - if (/^;*secret=(.*)/) { - $pass{$provider} = $1; - } - if (/^;*host=(.*)/) { - $host{$provider} = $1; - } - } - - $state = $next_state; -} -close SIP; - -# Determine if Asterisk can see current voip line (SIP trunk) -# sipshowpeers.txt needs to be generated before calling this perl -# script - -my %voip = (); # SIP trunks status keyed on sip.conf stanza name/username - # if no entry we can't see SIP trunk - -open SIP, "sipshowregistry.txt"; -while () { - if (/^(.*):.*(Registered)/) { - $voip{$1} = $2; - #print "'$1' '$2' $voip{$1}\n"; - } -} - -close SIP; - -# javascript to handle changing providers - -print "\n"; - -# generate form fields ------------------------------------------- - -$tt_provider = "onMouseOver=\"popUp(event,'voiplines_provider')\" onmouseout=\"popUp(event,'voiplines_provider')\""; -$tt_user = "onMouseOver=\"popUp(event,'voiplines_user')\" onmouseout=\"popUp(event,'voiplines_user')\""; -$tt_pass = "onMouseOver=\"popUp(event,'voiplines_pass')\" onmouseout=\"popUp(event,'voiplines_pass')\""; -$tt_host = "onMouseOver=\"popUp(event,'voiplines_host')\" onmouseout=\"popUp(event,'voiplines_host')\""; -$tt_status = "onMouseOver=\"popUp(event,'voiplines_status')\" onmouseout=\"popUp(event,'voiplines_status')\""; - -print "Provider\n"; -print "\n"; - -print "User:\n"; -print "Password:\n"; -print "Host:\n"; - -#print "\nXXX $provider_current $stanza{$provider_current} $voip{$stanza{$provider_current}}\n"; - -if ($voip{$stanza{$provider_current}} eq "Registered") { - $icon = "\"OK\""; -} -else { - $icon = "\"Not"; -} -print "Voip Line Status:$icon\n"; - -# hidden field to pass stanza with form - -print ""; diff --git a/easy-asterisk-gui/cgi-bin/voiplines.sh b/easy-asterisk-gui/cgi-bin/voiplines.sh deleted file mode 100644 index 9067ad49..00000000 --- a/easy-asterisk-gui/cgi-bin/voiplines.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh -# voiplines.sh -# David Rowe 12 Jan 2010 -# VOIP Line screen for Mini Asterisk GUI - -# check we are logged in - -echo $HTTP_COOKIE | grep "loggedin" > /dev/null -if [ $? -eq 1 ]; then - echo "" - echo "" - echo '' - echo "" - echo "" - exit -fi - -# See if we have can reach the VOIP Line provider - -asterisk "-rx sip show registry" 2>/dev/null > sipshowregistry.txt - -# Construct the web page ------------------------------- - -cat < - - - - -Mini Asterisk - VOIP Line -EOF - -cat tooltips.html -echo '' -cat banner.html -echo " " -cat menu.html -cat < - -
- - - - - -EOF - -./voiplines.pl - -cat < - - - - -
 

VOIP Line

 
 
- - - - - - - - - -EOF - diff --git a/easy-asterisk-gui/etc/asterisk/extensions.conf b/easy-asterisk-gui/etc/asterisk/extensions.conf deleted file mode 100644 index 12868e74..00000000 --- a/easy-asterisk-gui/etc/asterisk/extensions.conf +++ /dev/null @@ -1,65 +0,0 @@ -; extensions.conf -; David Rowe 4 Jan 2010 -; - -; Designed for Mini Asterisk GUI. However you can hand modify as much -; as you like, as GUI scripts read/and write regular extensions.conf -; without messing with your custom dialplan - - -[general] -static = yes -writeprotect = no -autofallthrough = yes -clearglobalvars = no -priorityjumping = no - -[default] - -; Pre-configured analog extensions, depends on IP0X model and what modules -; are installed. Some of these may map to FXO ports - -exten => 6001,1,Dial(Zap/1) -exten => 6002,1,Dial(Zap/2) -exten => 6003,1,Dial(Zap/3) -exten => 6004,1,Dial(Zap/4) -exten => 6005,1,Dial(Zap/5) -exten => 6006,1,Dial(Zap/6) -exten => 6007,1,Dial(Zap/7) -exten => 6008,1,Dial(Zap/8) - -; Pre-configured SIP-phone extensions. Primary use case is multiple SIP -; extensions and FXO analog Ports - -exten => 6011,1,Dial(SIP/6011) -exten => 6012,1,Dial(SIP/6012) -exten => 6013,1,Dial(SIP/6013) -exten => 6014,1,Dial(SIP/6014) -exten => 6015,1,Dial(SIP/6015) -exten => 6016,1,Dial(SIP/6016) -exten => 6017,1,Dial(SIP/6017) -exten => 6018,1,Dial(SIP/6018) -exten => 6019,1,Dial(SIP/6019) -exten => 6020,1,Dial(SIP/6020) -exten => 6021,1,Dial(SIP/6021) -exten => 6022,1,Dial(SIP/6022) -exten => 6023,1,Dial(SIP/6023) -exten => 6024,1,Dial(SIP/6024) -exten => 6025,1,Dial(SIP/6025) -exten => 6026,1,Dial(SIP/6026) -exten => 6027,1,Dial(SIP/6027) -exten => 6028,1,Dial(SIP/6028) -exten => 6029,1,Dial(SIP/6029) -exten => 6030,1,Dial(SIP/6030) - -;; Pre-configured mini-asterisk outgoing Analog group - -exten => _0.,1,Dial(Zap/g1/${EXTEN:1}) - -;; Pre-configured mini-asterisk outgoing VOIP line - -exten => _1.,1,Dial(SIP/voip/${EXTEN:1}) - -;; Pre-configured incoming calls - -exten => s,1,Dial(SIP/6011) ;; mini-asterisk - don't remove this comment diff --git a/easy-asterisk-gui/etc/asterisk/sip.conf b/easy-asterisk-gui/etc/asterisk/sip.conf deleted file mode 100644 index ee3e1046..00000000 --- a/easy-asterisk-gui/etc/asterisk/sip.conf +++ /dev/null @@ -1,559 +0,0 @@ -; -; SIP Configuration example for Asterisk -; -; Syntax for specifying a SIP device in extensions.conf is -; SIP/devicename where devicename is defined in a section below. -; -; You may also use -; SIP/username@domain to call any SIP user on the Internet -; (Don't forget to enable DNS SRV records if you want to use this) -; -; If you define a SIP proxy as a peer below, you may call -; SIP/proxyhostname/user or SIP/user@proxyhostname -; where the proxyhostname is defined in a section below -; -; Useful CLI commands to check peers/users: -; sip show peers Show all SIP peers (including friends) -; sip show users Show all SIP users (including friends) -; sip show registry Show status of hosts we register with -; -; sip debug Show all SIP messages -; -; reload chan_sip.so Reload configuration file -; Active SIP peers will not be reconfigured -; - -[general] -context=default ; Default context for incoming calls -;allowguest=no ; Allow or reject guest calls (default is yes, this can also be set to 'osp' - ; if asterisk was compiled with OSP support. -;realm=mydomain.tld ; Realm for digest authentication - ; defaults to "asterisk" - ; Realms MUST be globally unique according to RFC 3261 - ; Set this to your host name or domain name -bindport=5060 ; UDP Port to bind to (SIP standard port is 5060) -bindaddr=0.0.0.0 ; IP address to bind to (0.0.0.0 binds to all) -srvlookup=yes ; Enable DNS SRV lookups on outbound calls - ; Note: Asterisk only uses the first host - ; in SRV records - ; Disabling DNS SRV lookups disables the - ; ability to place SIP calls based on domain - ; names to some other SIP users on the Internet - -;domain=mydomain.tld ; Set default domain for this host - ; If configured, Asterisk will only allow - ; INVITE and REFER to non-local domains - ; Use "sip show domains" to list local domains -;domain=mydomain.tld,mydomain-incoming - ; Add domain and configure incoming context - ; for external calls to this domain -;domain=1.2.3.4 ; Add IP address as local domain - ; You can have several "domain" settings -;allowexternalinvites=no ; Disable INVITE and REFER to non-local domains - ; Default is yes -;autodomain=yes ; Turn this on to have Asterisk add local host - ; name and local IP to domain list. -;pedantic=yes ; Enable slow, pedantic checking for Pingtel - ; and multiline formatted headers for strict - ; SIP compatibility (defaults to "no") -;tos=184 ; Set IP QoS to either a keyword or numeric val -;tos=lowdelay ; lowdelay,throughput,reliability,mincost,none -;maxexpiry=3600 ; Max length of incoming registration we allow -;defaultexpiry=120 ; Default length of incoming/outoing registration -;notifymimetype=text/plain ; Allow overriding of mime type in MWI NOTIFY -;checkmwi=10 ; Default time between mailbox checks for peers -;vmexten=voicemail ; dialplan extension to reach mailbox sets the - ; Message-Account in the MWI notify message - ; defaults to "asterisk" -;videosupport=yes ; Turn on support for SIP video -;recordhistory=yes ; Record SIP history by default - ; (see sip history / sip no history) - -;disallow=all ; First disallow all codecs -;allow=ulaw ; Allow codecs in order of preference -;allow=ilbc ; -;musicclass=default ; Sets the default music on hold class for all SIP calls - ; This may also be set for individual users/peers -;language=en ; Default language setting for all users/peers - ; This may also be set for individual users/peers -;relaxdtmf=yes ; Relax dtmf handling -;rtptimeout=60 ; Terminate call if 60 seconds of no RTP activity - ; when we're not on hold -;rtpholdtimeout=300 ; Terminate call if 300 seconds of no RTP activity - ; when we're on hold (must be > rtptimeout) -;trustrpid = no ; If Remote-Party-ID should be trusted -;sendrpid = yes ; If Remote-Party-ID should be sent -;progressinband=never ; If we should generate in-band ringing always - ; use 'never' to never use in-band signalling, even in cases - ; where some buggy devices might not render it -;useragent=Asterisk PBX ; Allows you to change the user agent string -;promiscredir = no ; If yes, allows 302 or REDIR to non-local SIP address - ; Note that promiscredir when redirects are made to the - ; local system will cause loops since SIP is incapable - ; of performing a "hairpin" call. -;usereqphone = no ; If yes, ";user=phone" is added to uri that contains - ; a valid phone number -;dtmfmode = rfc2833 ; Set default dtmfmode for sending DTMF. Default: rfc2833 - ; Other options: - ; info : SIP INFO messages - ; inband : Inband audio (requires 64 kbit codec -alaw, ulaw) - ; auto : Use rfc2833 if offered, inband otherwise - -;compactheaders = yes ; send compact sip headers. -;sipdebug = yes ; Turn on SIP debugging by default, from - ; the moment the channel loads this configuration -;subscribecontext = default ; Set a specific context for SUBSCRIBE requests - ; Useful to limit subscriptions to local extensions - ; Settable per peer/user also -;notifyringing = yes ; Notify subscriptions on RINGING state - -; -; If regcontext is specified, Asterisk will dynamically create and destroy a -; NoOp priority 1 extension for a given peer who registers or unregisters with -; us. The actual extension is the 'regexten' parameter of the registering -; peer or its name if 'regexten' is not provided. More than one regexten may -; be supplied if they are separated by '&'. Patterns may be used in regexten. -; -;regcontext=sipregistrations -; -; Asterisk can register as a SIP user agent to a SIP proxy (provider) -; Format for the register statement is: -; register => user[:secret[:authuser]]@host[:port][/extension] -; -; If no extension is given, the 's' extension is used. The extension needs to -; be defined in extensions.conf to be able to accept calls from this SIP proxy -; (provider). -; -; host is either a host name defined in DNS or the name of a section defined -; below. -; -; Examples: -; -;register => 1234:password@mysipprovider.com -; -; This will pass incoming calls to the 's' extension -; -; -;register => 2345:password@sip_proxy/1234 -; -; Register 2345 at sip provider 'sip_proxy'. Calls from this provider -; connect to local extension 1234 in extensions.conf, default context, -; unless you configure a [sip_proxy] section below, and configure a -; context. -; Tip 1: Avoid assigning hostname to a sip.conf section like [provider.com] -; Tip 2: Use separate type=peer and type=user sections for SIP providers -; (instead of type=friend) if you have calls in both directions - -;registertimeout=20 ; retry registration calls every 20 seconds (default) -;registerattempts=10 ; Number of registration attempts before we give up - ; 0 = continue forever, hammering the other server until it - ; accepts the registration - ; Default is 0 tries, continue forever -;callevents=no ; generate manager events when sip ua performs events (e.g. hold) - -; register mini-asterisk voip line providers here - -register => user@generic ; mini-asterisk - do not change this comment -;register => user@oeg ; mini-asterisk - do not change this comment - -;----------------------------------------- NAT SUPPORT ------------------------ -; The externip, externhost and localnet settings are used if you use Asterisk -; behind a NAT device to communicate with services on the outside. - -;externip = 200.201.202.203 ; Address that we're going to put in outbound SIP messages - ; if we're behind a NAT - - ; The externip and localnet is used - ; when registering and communicating with other proxies - ; that we're registered with -;externhost=foo.dyndns.net ; Alternatively you can specify an - ; external host, and Asterisk will - ; perform DNS queries periodically. Not - ; recommended for production - ; environments! Use externip instead -;externrefresh=10 ; How often to refresh externhost if - ; used - ; You may add multiple local networks. A reasonable set of defaults - ; are: -;localnet=192.168.0.0/255.255.0.0; All RFC 1918 addresses are local networks -;localnet=10.0.0.0/255.0.0.0 ; Also RFC1918 -;localnet=172.16.0.0/12 ; Another RFC1918 with CIDR notation -;localnet=169.254.0.0/255.255.0.0 ;Zero conf local network - -; The nat= setting is used when Asterisk is on a public IP, communicating with -; devices hidden behind a NAT device (broadband router). If you have one-way -; audio problems, you usually have problems with your NAT configuration or your -; firewall's support of SIP+RTP ports. You configure Asterisk choice of RTP -; ports for incoming audio in rtp.conf -; -;nat=no ; Global NAT settings (Affects all peers and users) - ; yes = Always ignore info and assume NAT - ; no = Use NAT mode only according to RFC3581 - ; never = Never attempt NAT mode or RFC3581 support - ; route = Assume NAT, don't send rport - ; (work around more UNIDEN bugs) - -;rtcachefriends=yes ; Cache realtime friends by adding them to the internal list - ; just like friends added from the config file only on a - ; as-needed basis? (yes|no) - -;rtupdate=yes ; Send registry updates to database using realtime? (yes|no) - ; If set to yes, when a SIP UA registers successfully, the ip address, - ; the origination port, the registration period, and the username of - ; the UA will be set to database via realtime. If not present, defaults to 'yes'. - -;rtautoclear=yes ; Auto-Expire friends created on the fly on the same schedule - ; as if it had just registered? (yes|no|) - ; If set to yes, when the registration expires, the friend will vanish from - ; the configuration until requested again. If set to an integer, - ; friends expire within this number of seconds instead of the - ; registration interval. - -;ignoreregexpire=yes ; Enabling this setting has two functions: - ; - ; For non-realtime peers, when their registration expires, the information - ; will _not_ be removed from memory or the Asterisk database; if you attempt - ; to place a call to the peer, the existing information will be used in spite - ; of it having expired - ; - ; For realtime peers, when the peer is retrieved from realtime storage, - ; the registration information will be used regardless of whether - ; it has expired or not; if it expires while the realtime peer is still in - ; memory (due to caching or other reasons), the information will not be - ; removed from realtime storage - -; Incoming INVITE and REFER messages can be matched against a list of 'allowed' -; domains, each of which can direct the call to a specific context if desired. -; By default, all domains are accepted and sent to the default context or the -; context associated with the user/peer placing the call. -; Domains can be specified using: -; domain=[,] -; Examples: -; domain=myasterisk.dom -; domain=customer.com,customer-context -; -; In addition, all the 'default' domains associated with a server should be -; added if incoming request filtering is desired. -; autodomain=yes -; -; To disallow requests for domains not serviced by this server: -; allowexternaldomains=no - -; fromdomain=mydomain.tld ; When making outbound SIP INVITEs to - ; non-peers, use your primary domain "identity" - ; for From: headers instead of just your IP - ; address. This is to be polite and - ; it may be a mandatory requirement for some - ; destinations which do not have a prior - ; account relationship with your server. - -[authentication] -; Global credentials for outbound calls, i.e. when a proxy challenges your -; Asterisk server for authentication. These credentials override -; any credentials in peer/register definition if realm is matched. -; -; This way, Asterisk can authenticate for outbound calls to other -; realms. We match realm on the proxy challenge and pick an set of -; credentials from this list -; Syntax: -; auth = :@ -; auth = #@ -; Example: -;auth=mark:topsecret@digium.com -; -; You may also add auth= statements to [peer] definitions -; Peer auth= override all other authentication settings if we match on realm - -;------------------------------------------------------------------------------ -; Users and peers have different settings available. Friends have all settings, -; since a friend is both a peer and a user -; -; User config options: Peer configuration: -; -------------------- ------------------- -; context context -; permit permit -; deny deny -; secret secret -; md5secret md5secret -; dtmfmode dtmfmode -; canreinvite canreinvite -; nat nat -; callgroup callgroup -; pickupgroup pickupgroup -; language language -; allow allow -; disallow disallow -; insecure insecure -; trustrpid trustrpid -; progressinband progressinband -; promiscredir promiscredir -; useclientcode useclientcode -; accountcode accountcode -; setvar setvar -; callerid callerid -; amaflags amaflags -; call-limit call-limit -; restrictcid restrictcid -; subscribecontext subscribecontext -; videosupport videosupport -; mailbox -; username -; template -; fromdomain -; regexten -; fromuser -; host -; port -; qualify -; defaultip -; rtptimeout -; rtpholdtimeout -; sendrpid - -;[sip_proxy] -; For incoming calls only. Example: FWD (Free World Dialup) -; We match on IP address of the proxy for incoming calls -; since we can not match on username (caller id) -;type=peer -;context=from-fwd -;host=fwd.pulver.com - -;[sip_proxy-out] -;type=peer ; we only want to call out, not be called -;secret=guessit -;username=yourusername ; Authentication user for outbound proxies -;fromuser=yourusername ; Many SIP providers require this! -;fromdomain=provider.sip.domain -;host=box.provider.com -;usereqphone=yes ; This provider requires ";user=phone" on URI -;call-limit=5 ; permit only 5 simultaneous outgoing calls to this peer - -;------------------------------------------------------------------------------ -; Definitions of locally connected SIP phones -; -; type = user a device that authenticates to us by "from" field to place calls -; type = peer a device we place calls to or that calls us and we match by host -; type = friend two configurations (peer+user) in one -; -; For local phones, type=friend works most of the time -; -; If you have one-way audio, you propably have NAT problems. -; If Asterisk is on a public IP, and the phone is inside of a NAT device -; you will need to configure nat option for those phones. -; Also, turn on qualify=yes to keep the nat session open - -;[grandstream1] -;type=friend -;context=from-sip ; Where to start in the dialplan when this phone calls -;callerid=John Doe <1234> ; Full caller ID, to override the phones config -;host=192.168.0.23 ; we have a static but private IP address - ; No registration allowed -;nat=no ; there is not NAT between phone and Asterisk -;canreinvite=yes ; allow RTP voice traffic to bypass Asterisk -;dtmfmode=info ; either RFC2833 or INFO for the BudgeTone -;call-limit=1 ; permit only 1 outgoing call and 1 incoming call at a time - ; from the phone to asterisk - ; (1 for the explicit peer, 1 for the explicit user, - ; remember that a friend equals 1 peer and 1 user in - ; memory) -;mailbox=1234@default ; mailbox 1234 in voicemail context "default" -;disallow=all ; need to disallow=all before we can use allow= -;allow=ulaw ; Note: In user sections the order of codecs - ; listed with allow= does NOT matter! -;allow=alaw -;allow=g723.1 ; Asterisk only supports g723.1 pass-thru! -;allow=g729 ; Pass-thru only unless g729 license obtained -;astdb=chan2ext/SIP/grandstream1=1234 ; ensures an astDB entry exists - - -;[xlite1] -; Turn off silence suppression in X-Lite ("Transmit Silence"=YES)! -; Note that Xlite sends NAT keep-alive packets, so qualify=yes is not needed -;type=friend -;regexten=1234 ; When they register, create extension 1234 -;callerid="Jane Smith" <5678> -;host=dynamic ; This device needs to register -;nat=yes ; X-Lite is behind a NAT router -;canreinvite=no ; Typically set to NO if behind NAT -;disallow=all -;allow=gsm ; GSM consumes far less bandwidth than ulaw -;allow=ulaw -;allow=alaw -;mailbox=1234@default,1233@default ; Subscribe to status of multiple mailboxes - - -;[snom] -;type=friend ; Friends place calls and receive calls -;context=from-sip ; Context for incoming calls from this user -;secret=blah -;subscribecontext=localextensions ; Only allow SUBSCRIBE for local extensions -;language=de ; Use German prompts for this user -;host=dynamic ; This peer register with us -;dtmfmode=inband ; Choices are inband, rfc2833, or info -;defaultip=192.168.0.59 ; IP used until peer registers -;mailbox=1234@context,2345 ; Mailbox(-es) for message waiting indicator -;vmexten=voicemail ; dialplan extension to reach mailbox - ; sets the Message-Account in the MWI notify message - ; defaults to global vmexten which defaults to "asterisk" -;restrictcid=yes ; To have the callerid restriced -> sent as ANI -;disallow=all -;allow=ulaw ; dtmfmode=inband only works with ulaw or alaw! - - -;[polycom] -;type=friend ; Friends place calls and receive calls -;context=from-sip ; Context for incoming calls from this user -;secret=blahpoly -;host=dynamic ; This peer register with us -;dtmfmode=rfc2833 ; Choices are inband, rfc2833, or info -;username=polly ; Username to use in INVITE until peer registers - ; Normally you do NOT need to set this parameter -;disallow=all -;allow=ulaw ; dtmfmode=inband only works with ulaw or alaw! -;progressinband=no ; Polycom phones don't work properly with "never" - - -;[pingtel] -;type=friend -;secret=blah -;host=dynamic -;insecure=port ; Allow matching of peer by IP address without matching port number -;insecure=invite ; Do not require authentication of incoming INVITEs -;insecure=port,invite ; (both) -;qualify=1000 ; Consider it down if it's 1 second to reply - ; Helps with NAT session - ; qualify=yes uses default value -;callgroup=1,3-4 ; We are in caller groups 1,3,4 -;pickupgroup=1,3-5 ; We can do call pick-p for call group 1,3,4,5 -;defaultip=192.168.0.60 ; IP address to use if peer has not registred - -;[cisco1] -;type=friend -;secret=blah -;qualify=200 ; Qualify peer is no more than 200ms away -;nat=yes ; This phone may be natted - ; Send SIP and RTP to the IP address that packet is - ; received from instead of trusting SIP headers -;host=dynamic ; This device registers with us -;canreinvite=no ; Asterisk by default tries to redirect the - ; RTP media stream (audio) to go directly from - ; the caller to the callee. Some devices do not - ; support this (especially if one of them is - ; behind a NAT). -;defaultip=192.168.0.4 ; IP address to use until registration -;username=goran ; Username to use when calling this device before registration - ; Normally you do NOT need to set this parameter -;setvar=CUSTID=5678 ; Channel variable to be set for all calls from this device - -; Pre-configured SIP extensions - -[6011] -type=friend -context=default -host=dynamic -secret=6011 -canreinvite=no -callerid=6011 -disallow=all -allow=ulaw,g729 -qualify=yes - -[6012] -type=friend -context=default -host=dynamic -secret=6012 -canreinvite=no -callerid=6012 -disallow=all -allow=ulaw,g729 - -[6013] -type=friend -context=default -host=dynamic -secret=6013 -canreinvite=no -callerid=6013 -disallow=all -allow=ulaw,g729 - -[6014] -type=friend -context=default -host=dynamic -secret=6014 -canreinvite=no -callerid=6014 -disallow=all -allow=ulaw,g729 - -[6015] -type=friend -context=default -host=dynamic -secret=6015 -canreinvite=no -callerid=6015 -disallow=all -allow=ulaw,g729 - -[6016] -type=friend -context=default -host=dynamic -secret=6016 -canreinvite=no -callerid=6016 -disallow=all -allow=ulaw,g729 - -[6017] -type=friend -context=default -host=dynamic -secret=6017 -canreinvite=no -callerid=6017 -disallow=all -allow=ulaw,g729 - -[6018] -type=friend -context=default -host=dynamic -secret=6018 -canreinvite=no -callerid=6018 -disallow=all -allow=ulaw,g729 - -; Pre-configured mini-asterisk SIP trunks - -[generic] ; "Generic" mini-asterisk do not remove this comment -type=friend -context=default -username=user -secret=password -host=192.168.1.28 -canreinvite=no -disallow=all -allow=ulaw,g729 -qualify=yes - -;[oeg] ; "OEG" mini-asterisk do not remove this comment -;host=voip.oeg.com.au -;secret=pass -;username=your user number -;fromdomain=voip.oeg.com.au -;fromuser=your user number -;insecure=port,invite -;type=friend -;disallow=all -;allow=g729,ulaw -;dtmfmod=rfc2833 -;qualify=yes -;canreinvite=no -;nat=yes -;context=default - diff --git a/easy-asterisk-gui/update_revision.sh b/easy-asterisk-gui/update_revision.sh deleted file mode 100755 index cd8e5055..00000000 --- a/easy-asterisk-gui/update_revision.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# update_revision.sh -# -# Sets correct Revision number in the about screen. Good idea to -# run this before installing - -ver=`svn info | grep Revision` -sed -i "s/Revision: [0-9]*/$ver/" cgi-bin/about.sh diff --git a/mini-asterisk-gui/COPYING b/mini-asterisk-gui/COPYING new file mode 100644 index 00000000..d60c31a9 --- /dev/null +++ b/mini-asterisk-gui/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/mini-asterisk-gui/Makefile b/mini-asterisk-gui/Makefile new file mode 100644 index 00000000..400f535e --- /dev/null +++ b/mini-asterisk-gui/Makefile @@ -0,0 +1,34 @@ +# Makefile +# David Rowe 1 Jan 2010 +# +# Makefile for Easy Asterisk GUI +# +# 1/ Download files to development box for testing: +# +# usage: make HOST=test.machine.ip|hostname test +# make HOST=192.168.1.150 test +# make HOST=boris test +# +# 2/ Create static copy of web pages from HOST for static demo +# +# usage: make HOST=test.machine.ip static + +test: + rcp cgi-bin/*.html cgi-bin/*.sh cgi-bin/*.pl cgi-bin/*.js cgi-bin/*.css \ + cgi-bin/*.png root@$(HOST):/www + rcp etc/asterisk/*.conf root@$(HOST):/etc/asterisk + +.PHONY : static +static: + # generate static pages + + rm -Rf static; mkdir static; cd static; \ + wget -rEk --header="Cookie: loggedin=1" http://$(HOST)/phones.sh + + # modify links to non-existent scripts on static demo + + sed -i "s,http://$(HOST)/set_network.sh,network.sh.html," static/$(HOST)/network.sh.html + sed -i "s,http://$(HOST)/set_ring.sh,phones.sh.html," static/$(HOST)/phones.sh.html + sed -i "s,http://$(HOST)/set_voiplines.sh,voiplines.sh.html," static/$(HOST)/voiplines.sh.html + + diff --git a/mini-asterisk-gui/README.txt b/mini-asterisk-gui/README.txt new file mode 100644 index 00000000..5a9c7636 --- /dev/null +++ b/mini-asterisk-gui/README.txt @@ -0,0 +1,227 @@ +Mini Asterisk +============= + +A simple, light weight GUI for Asterisk. + +image::/images/ip04/mini.png["Mini Asterisk Demo", link="mini/phones.sh.html"] + +Click on the screen shot above for an on line demo. + +[[intro]] +Introduction +------------ + +Mini Asterisk is a simple Web GUI for Asterisk with comprehensive tool +tip documentation and a learning curve of a few minutes. Analog ports +and IP Phones are automatically detected, and no knowledge of Asterisk +configuration is required. + +Mini Asterisk is "unfeatured" - many of the Asterisk options are not +available. Instead it tries to make very basic, very common Asterisk +installations fast and simple, for example: + +* An Asterisk server running on your home gateway/firewall/server. + You want to connect a few IP Phones and make cheap phones calls + using VOIP. An Asterisk distro on a CD is a possibility but you + don't want to dedicate a full PC just for Asterisk. You don't + really want to learn obscure dial plan syntax and yet another conf + file format. + +* A small office that already has an old analog phone system. You + want to keep your current analog lines for incoming calls, but + install 8 IP Phones and use VOIP for outgoing calls. You know + enough to set up a DSL router but don't want to rely on "the Phone + Guy" or "The Computer Guy" at $100/hr to maintain your phone + system. + +* You are a "Phone Guy" who doesn't understand Linux and Asterisk but + you want to install IP-PBXes. + +[[why]] +Why Another Asterisk GUI? +------------------------- + +There are http://www.voip-info.org/wiki/view/Asterisk+GUI[a lot of +Asterisk GUIs] out there already. So why do we need another one? + +Well I needed an Asterisk GUI that was very easy to use for the +link:ip04.html[IP0X devices] I sell. Something that would lower the +technical skill required to install and maintain an Asterisk Phone +system. Something my wife and kids could use. + +I was also interested in exploring the ease-of-use meme, as we have +been discussing it a lot on the http://villagetelco.org[Village Telco] +project. Just how easy can we make Asterisk to use? So I scratched +the itch. + +Mini Asterisk has the following features that make it reasonably +unique. They may be good or bad features depending on your point of +view! + +* Mini Asterisk is "un-featured" - it hides many of the advanced + Asterisk features in the interest of simple and fast configuration. + +* Light weight so it can run on embedded boxes like the IP0X family. + No SQL database or PHP or LAMP. Only a basic web server and a very + basic perl are required (e.g. microperl - no CPAN libraries). + +* Works directly on extensions.conf and sip.conf, but honors any edits + you make to these files. So all the powerful Asterisk features are + available in the background. + +* Doesn't use AJAX or the built-in Asterisk web server or users.conf + magic. Plain old HTML, a little Java-script and CGIs written in + shell script and Perl. + +* Doesn't use the Asterisk programming "model". For example you don't + have to understand what a dial-plan is, much less understand how to + code one. Plain English terms are used instead, for example "Phones + and Phone lines". Terms like Asterisk, Linux, SIP, Zap/1 don't even + get a mention. + +* Extensive tool tip documentation. No manual. + +* Doesn't require a dedicated PC, not installed from an ISO CD. So + you can use it as a GUI for Asterisk on a little SOHO Linux box that + is also your firewall, server etc. + +* Mini Asterisk tells you when something is wrong, for example you get + a warning if your Phone System can't see the Internet. + +* Extensive pre-configuration of extensions.conf and sip.conf, + pre-selected phone numbers, SIP trunks are selected from a pull-down + menu (except they are called VOIP lines). Analog ports are auto + detected, at least on the IP0X. This makes adding IP phones very + fast and simple. + +[[status]] +Status +------ + +Alpha: + +* Works on IP0X. +* Not tested on x86. Several IP0X features are n/a for x86 and should be + disabled when the x86 (or non-IP0X) platform is detected. +* Needs feedback from real users to see how useful the concept is and what + (un)features need to be added. +* Need a few more (un)features to be added, and Voip Line screen + populated with more ITSPs. +* But quite useable as it stands. + +[[notes]] +Implementation Notes +-------------------- + +Mini Asterisk is written for the +http://rowetel.com/ucasterisk/ip04.html[IP0X embedded Asterisk] +hardware but will also run on x86 and probably many other platforms. + +Mini Asterisk has been written to be compatible with regular Asterisk +conf file configuration. Just leave the conf file lines with +"mini-asterisk" comments alone. The Asterisk conf files +extensions.conf and sip.conf are directly modified by Mini Asterisk, +but changes are limited to the "mini-asterisk" lines. + +For Auto-detection of Zap ports Mini Asterisk looks at +/etc/zapata.conf, so you may need this set up correctly for your +analog hardware. On the IP0X this happens automatically. + +[[install]] +Installation +------------ + +Note: this process may overwrite your Asterisk extensions.conf and +sip.conf files - back them up if you have an existing Asterisk +installation that you want to keep. The IP0X ipkg does attempt to +backup the modified conf files to *.bak but no guarantees.... + +However once mini-asterisk is installed it should honor any manual +changes made to extensions.conf and sip.conf. + +IP0X Installation +~~~~~~~~~~~~~~~~~ + +Installation instructions for IP0X boxes running link:baps.html[BAPS], +with some version of Asterisk and Zaptel installed. + +------------------------------------------------------------------- +root~> ipkg install mini-asterisk +------------------------------------------------------------------- + +x86 Installation +~~~~~~~~~~~~~~~~ + +. You need a web server, Asterisk and some sort of Perl installed +(very basic Perl installation is fine). Configure your web server to +run CGIs (.sh and .pl) from /www (lighttpd config instructions below). +Mini Asterisk expects all files (shell, perl, html etc) to be in the +same directory. If you find this painful please <>. + +. The process below places the web files in /www, you may like to +place the files somewhere else like /www/asterisk. One of the files +is named index.html so make sure you don't overwrite an existing +index.html. + +. Login as root to install the Mini Asterisk files: ++ +Remember to backup your existing extensions.conf & sip.conf in +/etc/asterisk ++ +------------------------------------------------------------------- +# cd ~ +# svn co https://freetel.svn.sourceforge.net/svnroot/freetel/mini-asterisk-gui +# ./update_revision.sh +# cp mini-asterisk-gui/etc/asterisk/* /etc/asterisk +# cp mini-asterisk-gui/cgi-bin/* /www +# cd /etc/asterisk +# cp extensions.conf extensions.conf.def +# cp sip.conf sip.conf.def +# mv etc/asterisk/users.conf etc/asterisk/users.conf.bak +------------------------------------------------------------------- ++ +The final step above may not be required on your machine if you don't +have a users.conf. The .def copies are required by the "reset +defaults" feature on the admin screen. + +. Switch off the internal Asterisk web server by editing +/etc/asterisk.httpd.conf. Make sure the enabled line reads like this: + + enabled=no ++ +Then stop and restart Asterisk. + +. I use lighttpd as the web server, the /etc/lighttpd.conf lines +required are: ++ +------------------------------------------------------------------- +cgi.assign = ( ".sh" => "/bin/sh",".pl" => "/usr/sbin/microperl" ) +------------------------------------------------------------------- + +[[contribute]] +Contributions +------------- + +I welcome sip.conf entries for your favourite ITSP (VOIP service) to +help populate the Provider field of the +link:mini/voiplines.sh.html[Voip Line Screen]. + +[[support]] +Support +------- + +Comments, features request, bugs please let me know using Free +Telephony Project http://www.rowetel.com/ucasterisk/#support[Support]. + +[[source]] +Source Code +----------- + +Browse: + +http://freetel.svn.sourceforge.net/viewvc/freetel/mini-asterisk-gui/[http://freetel.svn.sourceforge.net/viewvc/freetel/mini-asterisk-gui/] + +Check Out: + + $ svn co https://freetel.svn.sourceforge.net/svnroot/freetel/mini-asterisk-gui + diff --git a/mini-asterisk-gui/cgi-bin/about.sh b/mini-asterisk-gui/cgi-bin/about.sh new file mode 100644 index 00000000..8ca97111 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/about.sh @@ -0,0 +1,140 @@ +#!/bin/sh +# about.sh +# David Rowe 7 Jan 2010 +# About screen for Mini Asterisk GUI + +# check we are logged in + +echo $HTTP_COOKIE | grep "loggedin" > /dev/null +if [ $? -eq 1 ]; then + echo "" + echo "" + echo '' + echo "" + echo "" + exit +fi + +# Construct the web page ------------------------------- + +cat < + + +EOF + +cat << EOF + +Mini Asterisk - About +EOF + +cat tooltips.html +echo '' +cat banner.html +echo " " +cat menu.html +cat < + +
+ +EOF +echo ' ' +echo ' ' +echo ' ' +echo ' ' + +more=`echo "$QUERY_STRING" | grep -oe "more=[^&?]*" | sed -n "s/more=//p"` +if [ $more -eq 1 ]; then + echo +else + echo " " + echo ' '; +cat < + + +

About

Mini Asterisk Revision: 122
 
Brought to you by the Free Telephony Project
 
More
+ + +EOF +exit +fi + +echo "  " +echo "

cat /proc/version

" +echo " " +cat /proc/version +echo " " + +which ipkg >> /dev/null +if [ $? -eq 0 ]; then + echo "  " + echo "

ipkg list_installed

" + echo " " + ipkg list_installed | tr '\n' '#' | sed -n 's/\#/
/pg' + echo " " +fi + +echo "  " +echo "

cat /proc/loadavg

" +echo " " +cat /proc/loadavg +echo " " + +echo "  " +echo "

uptime

" +echo " " +uptime +echo " " + +echo "  " +echo "

cat /proc/meminfo

" +echo " " +cat /proc/meminfo | tr '\n' '#' | sed -n 's/\#/
/pg' +echo " " + +echo "  " +echo "

cat /proc/cmdline

" +echo " " +cat /proc/cmdline +echo " " + +echo "  " +echo "

cat /proc/cpuinfo

" +echo " " +cat /proc/cpuinfo +echo " " + +if [ -f /proc/mtd ]; then + echo "  " + echo "

cat /proc/mtd

" + echo " " + cat /proc/mtd | tr '\n' '#' | sed -n 's/\#/
/pg' + echo " " +fi + +if [ -f /proc/yaffs ]; then + echo "  " + echo "

cat /proc/yaffs

" + echo " " + cat /proc/yaffs | tr '\n' '#' | sed -n 's/\#/
/pg' + echo " " +fi + +echo "  " +echo ' Less'; + +cat < + + + + + + + + +EOF + diff --git a/mini-asterisk-gui/cgi-bin/admin.sh b/mini-asterisk-gui/cgi-bin/admin.sh new file mode 100644 index 00000000..9b309178 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/admin.sh @@ -0,0 +1,145 @@ +#!/bin/sh +# admin.sh +# David Rowe 7 Jan 2010 +# Admin screen for Mini Asterisk GUI + +# check we are logged in + +echo $HTTP_COOKIE | grep "loggedin" > /dev/null +if [ $? -eq 1 ]; then + echo "" + echo "" + echo '' + echo "" + echo "" + exit +fi + +# set password CGI ----------------------------------------------- + +echo "$QUERY_STRING" | grep -oe "pass=" > /dev/null +if [ $? -eq 0 ]; then + pass=`echo "$QUERY_STRING" | grep -oe "pass=[^&?]*" | sed -n "s/pass=//p"` + passwd_cmdline $pass +fi + +# restart CGI ---------------------------------------------------- + +echo "$QUERY_STRING" | grep -oe "restart=1" > /dev/null +if [ $? -eq 0 ]; then + +# kill cookie to log out. This ensures hitting refresh wont run +# the restart process again + +cat < +Mini Asterisk - Restart + + +

Restarting...come back in 1 minute

+ +EOF +reboot +fi + +# set defaults CGI ---------------------------------------------------- + +echo "$QUERY_STRING" | grep -oe "defaults=1" > /dev/null +if [ $? -eq 0 ]; then + cp /etc/asterisk/extensions.conf.def /etc/asterisk/extensions.conf + cp /etc/asterisk/sip.conf.def /etc/asterisk/sip.conf + asterisk -rx "sip reload" 2>/dev/null 1 > /dev/null + asterisk -rx "dialplan reload" 2>/dev/null 1 > /dev/null +fi + +# Construct the web page ------------------------------- + +cat < + + +EOF + +cat << EOF + +Mini Asterisk - Admin +EOF + +cat tooltips.html +echo '' +cat banner.html +echo " " +cat menu.html +cat < + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 

Admin

 

Change Phone System Password

New Password:
 
Default password is uClinux
 

Restart Phone System

+
+ + +
+
 

Reset Phone System Defaults

+
+ + +
+
 

Upgrade Mini Asterisk

+
+ + +
 

Install New Firmware

+ +
Firmware URL:
+ + + + + + + + + +EOF + diff --git a/mini-asterisk-gui/cgi-bin/at-530.html b/mini-asterisk-gui/cgi-bin/at-530.html new file mode 100644 index 00000000..686fb703 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/at-530.html @@ -0,0 +1,15 @@ +
    +
  1. Connect the WAN port of the AT-530 to your network, it will boot and obtain an IP via DHCP. +
  2. Find the IP of the phone by pressing the Sysinfo button a few times. +
  3. Open another browser window. Go to the phones IP, for example http://192.168.1.160 +
  4. Login to the phone using the username/password admin/admin. +
  5. Optional: set a static IP using the WAN menu (I like static IPs for SIP phones). +
  6. Go to the phone SIP Config menu. +
  7. Set Register Server Address to your Phone System IP Address. +
  8. Set Register Username to the phone number (e.g. 6011). +
  9. Also set Register Password to the phone number (e.g. 6011) and +the Phone Number to the phone number (e.g. 6011). +
  10. Check the Enable Register box. +
  11. Then click on Apply. +
  12. On your browser refresh this page to see if the phone is connected to your phone system. +
diff --git a/mini-asterisk-gui/cgi-bin/banner.html b/mini-asterisk-gui/cgi-bin/banner.html new file mode 100644 index 00000000..02889097 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/banner.html @@ -0,0 +1 @@ +

 

diff --git a/mini-asterisk-gui/cgi-bin/cross.png b/mini-asterisk-gui/cgi-bin/cross.png new file mode 100644 index 00000000..05baecdb Binary files /dev/null and b/mini-asterisk-gui/cgi-bin/cross.png differ diff --git a/mini-asterisk-gui/cgi-bin/faq.html b/mini-asterisk-gui/cgi-bin/faq.html new file mode 100644 index 00000000..dd6258e5 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/faq.html @@ -0,0 +1,16 @@ +
    + +
  1. Transfer a Call + +
  2. Answer a call on another ringing phone: If you hear another phone ringing and +want to answer the call on your phone, just pick up your phone and +dial *8. Note an IP phone can pick up a call on a ringing IP phone +but not an Analog phone. An Analog pohone can pick up another +ringing Analog phone but not an IP phone. + +
+ +

Resources and Links

+
    +
  1. A good book on Asterisk is Asterisk - The Future of Telephony +
diff --git a/mini-asterisk-gui/cgi-bin/faq.sh b/mini-asterisk-gui/cgi-bin/faq.sh new file mode 100644 index 00000000..d4ccf5d0 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/faq.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# faq.sh +# David Rowe 7 Jan 2010 +# FAQ screen for Mini Asterisk GUI + +# check we are logged in + +echo $HTTP_COOKIE | grep "loggedin" > /dev/null +if [ $? -eq 1 ]; then + echo "" + echo "" + echo '' + echo "" + echo "" + exit +fi + +# Construct the web page ------------------------------- + +cat < + + +EOF + +cat << EOF + +Mini Asterisk - FAQ +EOF + +cat tooltips.html +echo '' +cat banner.html +echo " " +cat menu.html +cat < + +
+ + +

FAQ

+EOF +cat faq.html +cat <
+ + + + + + + + +EOF + diff --git a/mini-asterisk-gui/cgi-bin/index.html b/mini-asterisk-gui/cgi-bin/index.html new file mode 100644 index 00000000..8514560b --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/index.html @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/mini-asterisk-gui/cgi-bin/ipphones.js b/mini-asterisk-gui/cgi-bin/ipphones.js new file mode 100644 index 00000000..9c50ceac --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/ipphones.js @@ -0,0 +1,3 @@ +function localInit() { +} + diff --git a/mini-asterisk-gui/cgi-bin/ipphones.pl b/mini-asterisk-gui/cgi-bin/ipphones.pl new file mode 100644 index 00000000..87f279f3 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/ipphones.pl @@ -0,0 +1,88 @@ +#!usr/bin/perl +# ipphones.pl +# David Rowe 6 Jan 2010 +# +# Text processing for the ipphones screen + +$ipaddress = $ARGV[0]; +$more = $ARGV[1]; + +# Slurp up SIP extension (Sip) data from extensions.conf + +my %ip = (); # ip extension keyed on sip.conf name + +open EXT, "/etc/asterisk/extensions.conf"; +while () { + if (/.*=>[ ]*([0-9]*),1.*SIP\/([0-9]*)\)/) { + $ip{$2} = $1; + #print "'$1' '$2' $ip{$2}\n"; + } +} +close EXT; + +my %sip = (); # SIP IP phone status keyed on sip.conf names + # if no entry we can't see IP phone device +my %voip = (); # SIP trunks status keyed on sip.conf names + # if no entry we can't see SIP trunk +my %ipad = (); # IP address of SIP device keyed on sip.conf names + +open SIP, "sipshowpeers.txt"; +while () { + if (/^([0-9]*)[\s\/].*(OK)/) { + $sip{$1} = $2; + #print "'$1' '$2' $sip{$1}\n"; + $e = $1; + if (/\s([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) { + $ipad{$e} = $1; + #print "'$1'\n"; + } + } + if (/^(voip[0-9]*)[\s\/].*(OK)/) { + $voip{$1} = $2; + #print "'$1' '$2' $voip{$1}\n"; + $e = $1; + if (/\s([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) { + $ipad{$e} = $1; + #print "'$1'\n"; + } + } +} + +close SIP; + +# print list of IP phones with connection status + +$unconnected = 0; +foreach $e (sort keys %ip) { + if ($sip{$e} eq "OK") { + $icon = "\"Connected\""; + $tooltip_status = "onMouseOver=\"popUp(event,'ipphones_connected')\" onmouseout=\"popUp(event,'ipphones_connected')\""; + $comment=$ipad{$e}; + $tooltip_ext = "onMouseOver=\"popUp(event,'phone_ext')\" onmouseout=\"popUp(event,'phone_ext')\""; + $tooltip_ip = "onMouseOver=\"popUp(event,'phone_ipphone_ip')\" onmouseout=\"popUp(event,'phone_ipphone_ip')\""; + $unconnected = 0; + } + else { + $unconnected = $unconnected + 1; + $icon = "\"Not"; + $tooltip_status = "onMouseOver=\"popUp(event,'ipphones_notconnected')\" onmouseout=\"popUp(event,'ipphones_notconnected')\""; + $comment="Available"; + $tooltip_id = "iphones_$e"; + print "
Configure your IP phone with username/password $e/$e, SIP Server IP $ipaddress
"; + $tooltip_ext = "onMouseOver=\"popUp(event,'$tooltip_id')\" onmouseout=\"popUp(event,'$tooltip_id')\""; + $tooltip_ip = ""; + } + + if ($more == 1 || ($unconnected < 5)) { + print "$e$comment$icon\n"; + } +} + +if ($more == 0) { + print 'More'; +} +else { + print 'Less'; +} + + diff --git a/mini-asterisk-gui/cgi-bin/ipphones.sh b/mini-asterisk-gui/cgi-bin/ipphones.sh new file mode 100644 index 00000000..2ce904b1 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/ipphones.sh @@ -0,0 +1,76 @@ +#!/bin/sh +# dashboard.sh +# David Rowe 6 Jan 2010 +# Dashboard screen for Mini Asterisk GUI + +# check we are logged in + +echo $HTTP_COOKIE | grep "loggedin" > /dev/null +if [ $? -eq 1 ]; then + echo "" + echo "" + echo '' + echo "" + echo "" + exit +fi + +more=`echo "$QUERY_STRING" | grep -oe "more=[^&?]*" | sed -n "s/more=//p"` +ipaddress=`ifconfig eth0 | sed -n 's/.*inet addr:\(.*\) Bcast.*/\1/p'` + +# Construct the web page ------------------------------- + +cat < + + +EOF + +echo "" + +cat << EOF + +Mini Asterisk - IP Phones + +EOF + +cat tooltips.html +echo '' +cat banner.html +echo " " +cat menu.html +cat < + +
+ + + +EOF +echo "" + + # use perl to construct list of IP phones for us + asterisk "-rx sip show peers" 2>/dev/null > sipshowpeers.txt + ./ipphones.pl $ipaddress $more + +cat < + +

 
How to Configure IP Phones

+

1. Atcom AT-530

+EOF +cat at-530.html +cat < + + +

IP Phones

Phone System IP Address:$ipaddress
 
+ + +EOF + diff --git a/mini-asterisk-gui/cgi-bin/login.sh b/mini-asterisk-gui/cgi-bin/login.sh new file mode 100644 index 00000000..0ae903a8 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/login.sh @@ -0,0 +1,68 @@ +#!/bin/sh +# login.sh +# David Rowe 4 Jan 2010 +# CGI for Mini Asterisk login GUI + +pass=`echo "$QUERY_STRING" | grep -oe "pass=[^&?]*" | sed -n "s/pass=//p"` + +echo $QUERY_STRING | grep pass > /dev/null +if [ $? -eq 1 ]; then + # Display form ------------------------------- + + cat < + + +EOF + cat << EOF + + Mini Asterisk - Login +
+ + + + + + + +

Login

Password:
Default password is uClinux
+
+ +EOF +else + testuser root $pass + if [ $? -eq 0 ]; then + + # login sucessful + echo "Content-type: text/html" + echo "Set-Cookie: loggedin=1" + echo "" + echo "" + echo "Mini Asterisk - Login" + echo '' + echo "" + echo "" + echo "Please wait a few seconds....." + echo "" + + # load mini asterisk conf files in case this is our first login + + asterisk -rx "sip reload" 2>/dev/null 1 > /dev/null + asterisk -rx "dialplan reload" 2>/dev/null 1 > /dev/null + + else + # login failed + cat < + + Mini Asterisk - Login + + + Please wait a few seconds..... + + + +EOF + fi +fi + diff --git a/mini-asterisk-gui/cgi-bin/logout.sh b/mini-asterisk-gui/cgi-bin/logout.sh new file mode 100644 index 00000000..d4306c96 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/logout.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# logout.sh +# David Rowe 4 Jan 2010 +# CGI for Mini Asterisk logout GUI + +cat <Mini Asterisk - Logout +Change your password, reset the default settings, upgrade software +
Connect the phone system to your network and the Internet
+
Lists your phones and phone lines
+
Set up your IP phones
+
Boring information like software version numbers
+
Frequently asked questions and links to further information
+
I think you can work this one out....
+
Set up your VOIP phone line
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

 

About
Admin
FAQ
IP Phones
Logout
Phone System
Network
VOIP Line
+ diff --git a/mini-asterisk-gui/cgi-bin/network.js b/mini-asterisk-gui/cgi-bin/network.js new file mode 100644 index 00000000..108bf01b --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/network.js @@ -0,0 +1,76 @@ +var script_path = "cgi-bin/"; + +function doStatic() { + $('ipaddress').disabled = 0; + $('netmask').disabled = 0; + $('gateway').disabled = 0; + $('dns').disabled = 0; +} + +function doDHCP() { + $('ipaddress').disabled = 1; + $('netmask').disabled = 1; + $('gateway').disabled = 1; + $('dns').disabled = 1; +} + +// http://moblog.bradleyit.com/2009/06/javascript-ip-address-validation.html + +function isIP(obj) { + var ary = obj.value.split("."); + var ip = true; + + for (var i=0; i<4; i++) { + ip = (!ary[i].match(/^\d{1,3}$/) || (Number(ary[i]) > 255)) ? false : ip; + } + + if (ip) + ip = (ary.length == 4); + + if (!ip) { + // the value is NOT a valid IP address + obj.style.background = "red"; + obj.select(); + } + else { obj.style.background = ""; } // the value IS a valid IP address + + return ip; +} + +function localInit() { + + if (init_dhcp == "yes") { + $('dhcp').checked = true; + $('ipaddress').disabled = 1; + $('netmask').disabled = 1; + $('gateway').disabled = 1; + $('dns').disabled = 1; + } + else { + $('static').checked = true; + $('ipaddress').disabled = 0; + $('netmask').disabled = 0; + $('gateway').disabled = 0; + $('dns').disabled = 0; + } + $('ipaddress').value = init_ipaddress; + $('netmask').value = init_netmask; + $('gateway').value = init_gateway; + $('dns').value = init_dns; + $('backdoor').value = init_backdoor; + if (init_internet == "yes") + $('internet').innerHTML = 'tick'; + else + $('internet').innerHTML = 'tick'; + +} + +function validate_form(form) +{ + var valid = true; + + if ($('dhcp').checked == false) + valid = isIP(form.ipaddress) && isIP(form.ipaddress) && isIP(form.gateway) && isIP(form.dns); + + return valid; +} diff --git a/mini-asterisk-gui/cgi-bin/network.sh b/mini-asterisk-gui/cgi-bin/network.sh new file mode 100644 index 00000000..268425ba --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/network.sh @@ -0,0 +1,150 @@ +#!/bin/sh +# network.sh +# David Rowe 4 Jan 2010 +# CGI for Mini Asterisk network GUI + +# check we are logged in + +echo $HTTP_COOKIE | grep "loggedin" > /dev/null +if [ $? -eq 1 ]; then + echo "" + echo "" + echo '' + echo "" + echo "" + exit +fi + +grok_network=0 + +if [ -f /etc/rc.d/S10network ]; then + grok_network=1 + dhcp=yes + ipaddress=`ifconfig eth0 | sed -n 's/.*inet addr:\(.*\) Bcast.*/\1/p'` + netmask=`ifconfig eth0 | sed -n 's/.*Mask:\(.*\)\s*/\1/p'` + gateway=`route -n | awk '/^0.0.0.0/ {print $2}'` + dns=`cat /etc/resolv.conf | awk '/^nameserver/ {print $2}'` +fi + +if [ -f /etc/rc.d/S10network-static ] +then + grok_network=1 + dhcp=no + ipaddress=`sed -n 's/IPADDRESS="\(.*\)"/\1/p' /etc/init.d/network-static` + netmask=`sed -n 's/NETMASK="\(.*\)"/\1/p' /etc/init.d/network-static` + gateway=`sed -n 's/GATEWAY="\(.*\)"/\1/p' /etc/init.d/network-static` + dns=`sed -n 's/DNS="\(.*\)"/\1/p' /etc/init.d/network-static` +fi + +# if we don't understand this machines network config then bail + +if [ $groknetwork -eq 0 ]; then +cat << EOF + +Mini Asterisk - Network +EOF + +cat tooltips.html +echo '' +cat banner.html +echo " " +cat menu.html +cat < +
+ + + +

Network

Sorry - I can't edit the Network configuration on this machine
+ + + + + + +EOF +fi + +if [ -f /etc/rc.d/S05network-backdoor ]; then + backdoor=`sed -n 's/IPADDRESS="\(.*\)"/\1/p' /etc/init.d/network-backdoor` +fi + +# See if we have Internet connectivity, first check dns as time outs can be very slow + +dns_packet_loss=`ping $dns -c 1 -q | sed -n 's/.*received, \(.*\)% packet loss/\1/p'` +internet="no"; +if [ $dns_packet_loss == "0" ]; then + packet_loss=`ping google.com -c 1 -q | sed -n 's/.*received, \(.*\)% packet loss/\1/p'` + if [ $packet_loss == "0" ]; then + internet="yes"; + fi +fi + +# Construct the web page ------------------------------- + +cat < + + +EOF + +echo "" + +cat << EOF + +Mini Asterisk - Network + +EOF + +cat tooltips.html +echo '' +cat banner.html +echo " " +cat menu.html +cat < + +
+
+ + + + + + + + + + + + + + + + + + +

Network

StaticDHCP
IP Address:
Netmask:
Gateway:
DNS:
Emergency IP:
Internet Connection:
+  
+ + + + + + + + + +EOF + diff --git a/mini-asterisk-gui/cgi-bin/phones.js b/mini-asterisk-gui/cgi-bin/phones.js new file mode 100644 index 00000000..74d6eaf1 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/phones.js @@ -0,0 +1,7 @@ +function localInit() { + if (init_internet == "yes") + $('internet').innerHTML = 'tick'; + else + $('internet').innerHTML = 'tick'; +} + diff --git a/mini-asterisk-gui/cgi-bin/phones.pl b/mini-asterisk-gui/cgi-bin/phones.pl new file mode 100644 index 00000000..56f3534c --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/phones.pl @@ -0,0 +1,216 @@ +#!/usr/bin/perl +# phones.pl +# David Rowe 5 Jan 2010 +# +# Text processing for the phones screen. + +$tool_tip = "onMouseOver=\"popUp(event,'network_internet')\" onmouseout=\"popUp(event,'network_internet')\""; + +# Slurp up analog port (Zap) data from extensions.conf + +my %analog = (); # analog extension keyed on zap port + +open EXT, "/etc/asterisk/extensions.conf"; +while () { + if (/.*=>[ ]*([0-9]*),1.*Zap\/([0-9]*)\)/) { + $analog{$2} = $1; + #print "'$1' '$2' $analog{$2}\n"; + } +} +close EXT; + +# Slurp up data on installed zaptel ports from /etc/zaptel.conf + +my %zap = (); # zaptel port type keyed on zap port + # (fxs/fxo or no entry if not live) +open ZAP, "/etc/zaptel.conf"; +while () { + if (/fxoks=(.*)/) { + @fxs = split(/,/, $1); + foreach (@fxs) { + $zap{$_} = "fxs"; + } + } + if (/fxsks=(.*)/) { + @fxo = split(/,/, $1); + foreach (@fxo) { + $zap{$_} = "fxo"; + } + } +} +close ZAP; + +# Slurp up SIP extension (Sip) data from extensions.conf + +my %ip = (); # ip extension keyed on sip.conf name + +open EXT, "/etc/asterisk/extensions.conf"; +while () { + if (/.*=>[ ]*([0-9]*),1.*Sip\/([0-9]*)\)/) { + $ip{$2} = $1; + #print "'$1' '$2' $ip{$2}\n"; + } +} +close EXT; + +# Determine which extenions are "Reception", i.e. set to ring on incoming +# calls + +my %zap_ring = (); # ring flag keyed on Zap port (1,2...) +my %sip_ring = (); # ring flag keyed on sip.cong ext name (6011,6012 etc) + +open EXT, "/etc/asterisk/extensions.conf"; +while () { + if (/s,1,Dial\((.*)\) ;; mini/) { + @ring = split(/&/, $1); + #print "'$1' '@ring'\n foreach:\n"; + foreach (@ring) { + #print " $_\n"; + if (/Zap\/([0-9]*)/) { + $zap_ring{$1} = 1; + #print "'$_' $1 \n"; + } + if (/SIP\/([0-9]*)/) { + $sip_ring{$1} = 1; + #print "'$_' $1 \n"; + } + } + } +} +close EXT; + + +# work out which IP phones are registered ----------------------------------- + +my %sip = (); # SIP IP phone status keyed on sip.conf names (6011,6012 etc) + # if no entry we can't see IP phone device +my %ipad = (); # IP address of SIP device keyed on sip.conf names + +open SIP, "sipshowpeers.txt"; +while () { + if (/^([0-9]*)[\s\/].*(OK)/) { + $sip{$1} = $2; + #print "'$1' '$2' $sip{$1}\n"; + $e = $1; + if (/\s([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) { + $ipad{$e} = $1; + #print "'$1'\n"; + } + } + + if (/^(.*)\/.*(OK)/) { + #$sip{$1} = $2; + #print "'$1' '$2' $sip{$1}\n"; + $e = $1; + if (/\s([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) { + $ipad{$e} = $1; + #print "'$1'\n"; + } + } +} + +close SIP; + +# Determine if Asterisk can see current voip line (SIP trunk) +# sipshowpeers.txt needs to be generated before calling this perl +# script + +my %voip = (); # SIP trunks status keyed on sip.conf stanza name/username + # if no entry we can't see SIP trunk + +open SIP, "sipshowregistry.txt"; +while () { + if (/^(.*):.*(Registered)/) { + $voip{$1} = $2; + #print "'$1' '$2' $voip{$1}\n"; + } +} + +close SIP; + +# start phones ringing form ------------------------------------------- + +print '
'; + +# print list of analog phones + +$tooltip_anphone = "onMouseOver=\"popUp(event,'phone_anphone')\" onmouseout=\"popUp(event,'phone_anphone')\""; +$tooltip_ext = "onMouseOver=\"popUp(event,'phone_ext')\" onmouseout=\"popUp(event,'phone_ext')\""; +$tooltip_port = "onMouseOver=\"popUp(event,'phone_port_phone')\" onmouseout=\"popUp(event,'phone_port_phone')\""; +$tooltip_reception = "onMouseOver=\"popUp(event,'phone_reception')\" onmouseout=\"popUp(event,'phone_reception')\""; + +foreach $a (sort keys %analog) { + if ($zap{$a} eq "fxs") { + $icon = "\"Analog"; + print "$analog{$a}Analog PhonePort $a"; + if ($zap_ring{$a} == 1) { + $checked = "checked"; + } + else { + $checked = ""; + } + print "Reception$icon\n"; + } +} + +# print list of IP phones + +$tooltip_ipphone = "onMouseOver=\"popUp(event,'phone_ipphone')\" onmouseout=\"popUp(event,'phone_ipphone')\""; +$tooltip_ipphone_ip = "onMouseOver=\"popUp(event,'phone_ipphone_ip')\" onmouseout=\"popUp(event,'phone_ipphone_ip')\""; +$tooltip_reception = "onMouseOver=\"popUp(event,'phone_reception')\" onmouseout=\"popUp(event,'phone_reception')\""; + +foreach $s (sort keys %sip) { + if ($sip{$s} eq "OK") { + $icon = "\"IP"; + print "$sIP Phone$ipad{$s}"; + if ($sip_ring{$s} == 1) { + $checked = "checked"; + } + else { + $checked = ""; + } + print "Reception$icon\n"; + } +} + +print ' '; +print ""; +print "Add IP Phone"; + +$tool_tip = "onMouseOver=\"popUp(event,'phone_lines')\" onmouseout=\"popUp(event,'phone_lines')\""; + +print ' '; +print "

Phone Lines

+"; + +print "
"; + +# print list of analog phone lines + +$tooltip_phoneline = "onMouseOver=\"popUp(event,'phone_phoneline')\" onmouseout=\"popUp(event,'phone_phoneline')\""; +$tooltip_port = "onMouseOver=\"popUp(event,'phone_port_line')\" onmouseout=\"popUp(event,'phone_port_line')\""; +$tooltip_line_prefix = "onMouseOver=\"popUp(event,'phone_line_prefix')\" onmouseout=\"popUp(event,'phone_line_prefix')\""; + +foreach $a (sort keys %analog) { + if ($zap{$a} eq "fxo") { + $icon = "\"Phone"; + print "0Analog LinePort $a$icon\n"; + } +} + +# print list of SIP VOIP trunks + +$tooltip_voipline = "onMouseOver=\"popUp(event,'phone_voipline')\" onmouseout=\"popUp(event,'phone_voipline')\""; +$tooltip_voipline_ip = "onMouseOver=\"popUp(event,'phone_voipline_ip')\" onmouseout=\"popUp(event,'phone_voipline_ip')\""; +$tooltip_voipline_prefix = "onMouseOver=\"popUp(event,'phone_voipline_prefix')\" onmouseout=\"popUp(event,'phone_voipline_prefix')\""; + +foreach $s (sort keys %voip) { + if ($voip{$s} eq "Registered") { + $icon = "\"VOIP"; + print "1VOIP Line$ipad{$s}$icon\n"; + } +} + +print ' '; +print ""; +print "Set Up VOIP Line"; diff --git a/mini-asterisk-gui/cgi-bin/phones.sh b/mini-asterisk-gui/cgi-bin/phones.sh new file mode 100644 index 00000000..aa302f59 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/phones.sh @@ -0,0 +1,96 @@ +#!/bin/sh +# phones.sh +# David Rowe 4 Jan 2010 +# Phones screen for Mini Asterisk GUI + +# check we are logged in + +echo $HTTP_COOKIE | grep "loggedin" > /dev/null +if [ $? -eq 1 ]; then + echo "" + echo "" + echo '' + echo "" + echo "" + exit +fi + +# See if we have Internet connectivity, first check dns as time outs can be very slow + +dns=`cat /etc/resolv.conf | awk '/^nameserver/ {print $2}'` +dns_packet_loss=`ping $dns -c 1 -q | sed -n 's/.*received, \(.*\)% packet loss/\1/p'` +internet="no"; +if [ $dns_packet_loss == "0" ]; then + packet_loss=`ping google.com -c 1 -q | sed -n 's/.*received, \(.*\)% packet loss/\1/p'` + if [ $packet_loss == "0" ]; then + internet="yes"; + fi +fi + +ipaddress=`ifconfig eth0 | sed -n 's/.*inet addr:\(.*\) Bcast.*/\1/p'` + +# Construct the web page ------------------------------- + +cat < + + +EOF + +echo "" + +cat << EOF + +Mini Asterisk - Phones + +EOF + +cat tooltips.html +echo '' +cat banner.html +echo " " +cat menu.html +cat < + +
+ + + + + + + + + +EOF +echo "" +cat < + + + + +EOF + +# use perl to construct list of phones and phone lines for us +asterisk "-rx sip show peers" 2>/dev/null > sipshowpeers.txt +./phones.pl + +cat< + + + + + +

Phone System

Internet Connection:
 
Phone System IP Address:$ipaddress
 

Phones

+ + +EOF + diff --git a/mini-asterisk-gui/cgi-bin/prototype.js b/mini-asterisk-gui/cgi-bin/prototype.js new file mode 100644 index 00000000..0e85338b --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/prototype.js @@ -0,0 +1,1781 @@ +/* Prototype JavaScript framework, version 1.4.0 + * (c) 2005 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://prototype.conio.net/ + * +/*--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.4.0', + ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)', + + emptyFunction: function() {}, + K: function(x) {return x} +} + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Abstract = new Object(); + +Object.extend = function(destination, source) { + for (property in source) { + destination[property] = source[property]; + } + return destination; +} + +Object.inspect = function(object) { + try { + if (object == undefined) return 'undefined'; + if (object == null) return 'null'; + return object.inspect ? object.inspect() : object.toString(); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } +} + +Function.prototype.bind = function() { + var __method = this, args = $A(arguments), object = args.shift(); + return function() { + return __method.apply(object, args.concat($A(arguments))); + } +} + +Function.prototype.bindAsEventListener = function(object) { + var __method = this; + return function(event) { + return __method.call(object, event || window.event); + } +} + +Object.extend(Number.prototype, { + toColorPart: function() { + var digits = this.toString(16); + if (this < 16) return '0' + digits; + return digits; + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator) { + $R(0, this, true).each(iterator); + return this; + } +}); + +var Try = { + these: function() { + var returnValue; + + for (var i = 0; i < arguments.length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +} + +/*--------------------------------------------------------------------------*/ + +var PeriodicalExecuter = Class.create(); +PeriodicalExecuter.prototype = { + initialize: function(callback, frequency) { + this.callback = callback; + this.frequency = frequency; + this.currentlyExecuting = false; + + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting = true; + this.callback(); + } finally { + this.currentlyExecuting = false; + } + } + } +} + +/*--------------------------------------------------------------------------*/ + +function $() { + var elements = new Array(); + + for (var i = 0; i < arguments.length; i++) { + var element = arguments[i]; + if (typeof element == 'string') + element = document.getElementById(element); + + if (arguments.length == 1) + return element; + + elements.push(element); + } + + return elements; +} +Object.extend(String.prototype, { + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + stripScripts: function() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); + }, + + extractScripts: function() { + var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); + var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + }, + + evalScripts: function() { + return this.extractScripts().map(eval); + }, + + escapeHTML: function() { + var div = document.createElement('div'); + var text = document.createTextNode(this); + div.appendChild(text); + return div.innerHTML; + }, + + unescapeHTML: function() { + var div = document.createElement('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; + }, + + toQueryParams: function() { + var pairs = this.match(/^\??(.*)$/)[1].split('&'); + return pairs.inject({}, function(params, pairString) { + var pair = pairString.split('='); + params[pair[0]] = pair[1]; + return params; + }); + }, + + toArray: function() { + return this.split(''); + }, + + camelize: function() { + var oStringList = this.split('-'); + if (oStringList.length == 1) return oStringList[0]; + + var camelizedString = this.indexOf('-') == 0 + ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) + : oStringList[0]; + + for (var i = 1, len = oStringList.length; i < len; i++) { + var s = oStringList[i]; + camelizedString += s.charAt(0).toUpperCase() + s.substring(1); + } + + return camelizedString; + }, + + inspect: function() { + return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'"; + } +}); + +String.prototype.parseQuery = String.prototype.toQueryParams; + +var $break = new Object(); +var $continue = new Object(); + +var Enumerable = { + each: function(iterator) { + var index = 0; + try { + this._each(function(value) { + try { + iterator(value, index++); + } catch (e) { + if (e != $continue) throw e; + } + }); + } catch (e) { + if (e != $break) throw e; + } + }, + + all: function(iterator) { + var result = true; + this.each(function(value, index) { + result = result && !!(iterator || Prototype.K)(value, index); + if (!result) throw $break; + }); + return result; + }, + + any: function(iterator) { + var result = true; + this.each(function(value, index) { + if (result = !!(iterator || Prototype.K)(value, index)) + throw $break; + }); + return result; + }, + + collect: function(iterator) { + var results = []; + this.each(function(value, index) { + results.push(iterator(value, index)); + }); + return results; + }, + + detect: function (iterator) { + var result; + this.each(function(value, index) { + if (iterator(value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator) { + var results = []; + this.each(function(value, index) { + if (iterator(value, index)) + results.push(value); + }); + return results; + }, + + grep: function(pattern, iterator) { + var results = []; + this.each(function(value, index) { + var stringValue = value.toString(); + if (stringValue.match(pattern)) + results.push((iterator || Prototype.K)(value, index)); + }) + return results; + }, + + include: function(object) { + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inject: function(memo, iterator) { + this.each(function(value, index) { + memo = iterator(memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.collect(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (value >= (result || value)) + result = value; + }); + return result; + }, + + min: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (value <= (result || value)) + result = value; + }); + return result; + }, + + partition: function(iterator) { + var trues = [], falses = []; + this.each(function(value, index) { + ((iterator || Prototype.K)(value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value, index) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator) { + var results = []; + this.each(function(value, index) { + if (!iterator(value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(iterator) { + return this.collect(function(value, index) { + return {value: value, criteria: iterator(value, index)}; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + }, + + toArray: function() { + return this.collect(Prototype.K); + }, + + zip: function() { + var iterator = Prototype.K, args = $A(arguments); + if (typeof args.last() == 'function') + iterator = args.pop(); + + var collections = [this].concat(args).map($A); + return this.map(function(value, index) { + iterator(value = collections.pluck(index)); + return value; + }); + }, + + inspect: function() { + return '#'; + } +} + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray +}); +var $A = Array.from = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0; i < iterable.length; i++) + results.push(iterable[i]); + return results; + } +} + +Object.extend(Array.prototype, Enumerable); + +Array.prototype._reverse = Array.prototype.reverse; + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0; i < this.length; i++) + iterator(this[i]); + }, + + clear: function() { + this.length = 0; + return this; + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != undefined || value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(value.constructor == Array ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + indexOf: function(object) { + for (var i = 0; i < this.length; i++) + if (this[i] == object) return i; + return -1; + }, + + reverse: function(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + }, + + shift: function() { + var result = this[0]; + for (var i = 0; i < this.length - 1; i++) + this[i] = this[i + 1]; + this.length--; + return result; + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + } +}); +var Hash = { + _each: function(iterator) { + for (key in this) { + var value = this[key]; + if (typeof value == 'function') continue; + + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + merge: function(hash) { + return $H(hash).inject($H(this), function(mergedHash, pair) { + mergedHash[pair.key] = pair.value; + return mergedHash; + }); + }, + + toQueryString: function() { + return this.map(function(pair) { + return pair.map(encodeURIComponent).join('='); + }).join('&'); + }, + + inspect: function() { + return '#'; + } +} + +function $H(object) { + var hash = Object.extend({}, object || {}); + Object.extend(hash, Enumerable); + Object.extend(hash, Hash); + return hash; +} +ObjectRange = Class.create(); +Object.extend(ObjectRange.prototype, Enumerable); +Object.extend(ObjectRange.prototype, { + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + do { + iterator(value); + value = value.succ(); + } while (this.include(value)); + }, + + include: function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; + } +}); + +var $R = function(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +} + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')}, + function() {return new XMLHttpRequest()} + ) || false; + }, + + activeRequestCount: 0 +} + +Ajax.Responders = { + responders: [], + + _each: function(iterator) { + this.responders._each(iterator); + }, + + register: function(responderToAdd) { + if (!this.include(responderToAdd)) + this.responders.push(responderToAdd); + }, + + unregister: function(responderToRemove) { + this.responders = this.responders.without(responderToRemove); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (responder[callback] && typeof responder[callback] == 'function') { + try { + responder[callback].apply(responder, [request, transport, json]); + } catch (e) {} + } + }); + } +}; + +Object.extend(Ajax.Responders, Enumerable); + +Ajax.Responders.register({ + onCreate: function() { + Ajax.activeRequestCount++; + }, + + onComplete: function() { + Ajax.activeRequestCount--; + } +}); + +Ajax.Base = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + parameters: '' + } + Object.extend(this.options, options || {}); + }, + + responseIsSuccess: function() { + return this.transport.status == undefined + || this.transport.status == 0 + || (this.transport.status >= 200 && this.transport.status < 300); + }, + + responseIsFailure: function() { + return !this.responseIsSuccess(); + } +} + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = Object.extend(new Ajax.Base(), { + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + this.request(url); + }, + + request: function(url) { + var parameters = this.options.parameters || ''; + if (parameters.length > 0) parameters += '&_='; + + try { + this.url = url; + if (this.options.method == 'get' && parameters.length > 0) + this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; + + Ajax.Responders.dispatch('onCreate', this, this.transport); + + this.transport.open(this.options.method, this.url, + this.options.asynchronous); + + if (this.options.asynchronous) { + this.transport.onreadystatechange = this.onStateChange.bind(this); + setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); + } + + this.setRequestHeaders(); + + var body = this.options.postBody ? this.options.postBody : parameters; + this.transport.send(this.options.method == 'post' ? body : null); + + } catch (e) { + this.dispatchException(e); + } + }, + + setRequestHeaders: function() { + var requestHeaders = + ['X-Requested-With', 'XMLHttpRequest', + 'X-Prototype-Version', Prototype.Version]; + + if (this.options.method == 'post') { + requestHeaders.push('Content-type', + 'application/x-www-form-urlencoded'); + + /* Force "Connection: close" for Mozilla browsers to work around + * a bug where XMLHttpReqeuest sends an incorrect Content-length + * header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType) + requestHeaders.push('Connection', 'close'); + } + + if (this.options.requestHeaders) + requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); + + for (var i = 0; i < requestHeaders.length; i += 2) + this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState != 1) + this.respondToReadyState(this.transport.readyState); + }, + + header: function(name) { + try { + return this.transport.getResponseHeader(name); + } catch (e) {} + }, + + evalJSON: function() { + try { + return eval(this.header('X-JSON')); + } catch (e) {} + }, + + evalResponse: function() { + try { + return eval(this.transport.responseText); + } catch (e) { + this.dispatchException(e); + } + }, + + respondToReadyState: function(readyState) { + var event = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.evalJSON(); + + if (event == 'Complete') { + try { + (this.options['on' + this.transport.status] + || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(transport, json); + } catch (e) { + this.dispatchException(e); + } + + if ((this.header('Content-type') || '').match(/^text\/javascript/i)) + this.evalResponse(); + } + + try { + (this.options['on' + event] || Prototype.emptyFunction)(transport, json); + Ajax.Responders.dispatch('on' + event, this, transport, json); + } catch (e) { + this.dispatchException(e); + } + + /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ + if (event == 'Complete') + this.transport.onreadystatechange = Prototype.emptyFunction; + }, + + dispatchException: function(exception) { + (this.options.onException || Prototype.emptyFunction)(this, exception); + Ajax.Responders.dispatch('onException', this, exception); + } +}); + +Ajax.Updater = Class.create(); + +Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { + initialize: function(container, url, options) { + this.containers = { + success: container.success ? $(container.success) : $(container), + failure: container.failure ? $(container.failure) : + (container.success ? null : $(container)) + } + + this.transport = Ajax.getTransport(); + this.setOptions(options); + + var onComplete = this.options.onComplete || Prototype.emptyFunction; + this.options.onComplete = (function(transport, object) { + this.updateContent(); + onComplete(transport, object); + }).bind(this); + + this.request(url); + }, + + updateContent: function() { + var receiver = this.responseIsSuccess() ? + this.containers.success : this.containers.failure; + var response = this.transport.responseText; + + if (!this.options.evalScripts) + response = response.stripScripts(); + + if (receiver) { + if (this.options.insertion) { + new this.options.insertion(receiver, response); + } else { + Element.update(receiver, response); + } + } + + if (this.responseIsSuccess()) { + if (this.onComplete) + setTimeout(this.onComplete.bind(this), 10); + } + } +}); + +Ajax.PeriodicalUpdater = Class.create(); +Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { + initialize: function(container, url, options) { + this.setOptions(options); + this.onComplete = this.options.onComplete; + + this.frequency = (this.options.frequency || 2); + this.decay = (this.options.decay || 1); + + this.updater = {}; + this.container = container; + this.url = url; + + this.start(); + }, + + start: function() { + this.options.onComplete = this.updateComplete.bind(this); + this.onTimerEvent(); + }, + + stop: function() { + this.updater.onComplete = undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(request) { + if (this.options.decay) { + this.decay = (request.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = request.responseText; + } + this.timer = setTimeout(this.onTimerEvent.bind(this), + this.decay * this.frequency * 1000); + }, + + onTimerEvent: function() { + this.updater = new Ajax.Updater(this.container, this.url, this.options); + } +}); +document.getElementsByClassName = function(className, parentElement) { + var children = ($(parentElement) || document.body).getElementsByTagName('*'); + return $A(children).inject([], function(elements, child) { + if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) + elements.push(child); + return elements; + }); +} + +/*--------------------------------------------------------------------------*/ + +if (!window.Element) { + var Element = new Object(); +} + +Object.extend(Element, { + visible: function(element) { + return $(element).style.display != 'none'; + }, + + toggle: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + Element[Element.visible(element) ? 'hide' : 'show'](element); + } + }, + + hide: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = 'none'; + } + }, + + show: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = ''; + } + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + }, + + update: function(element, html) { + $(element).innerHTML = html.stripScripts(); + setTimeout(function() {html.evalScripts()}, 10); + }, + + getHeight: function(element) { + element = $(element); + return element.offsetHeight; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).include(className); + }, + + addClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).add(className); + }, + + removeClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).remove(className); + }, + + // removes whitespace-only text node children + cleanWhitespace: function(element) { + element = $(element); + for (var i = 0; i < element.childNodes.length; i++) { + var node = element.childNodes[i]; + if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) + Element.remove(node); + } + }, + + empty: function(element) { + return $(element).innerHTML.match(/^\s*$/); + }, + + scrollTo: function(element) { + element = $(element); + var x = element.x ? element.x : element.offsetLeft, + y = element.y ? element.y : element.offsetTop; + window.scrollTo(x, y); + }, + + getStyle: function(element, style) { + element = $(element); + var value = element.style[style.camelize()]; + if (!value) { + if (document.defaultView && document.defaultView.getComputedStyle) { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css.getPropertyValue(style) : null; + } else if (element.currentStyle) { + value = element.currentStyle[style.camelize()]; + } + } + + if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) + if (Element.getStyle(element, 'position') == 'static') value = 'auto'; + + return value == 'auto' ? null : value; + }, + + setStyle: function(element, style) { + element = $(element); + for (name in style) + element.style[name.camelize()] = style[name]; + }, + + getDimensions: function(element) { + element = $(element); + if (Element.getStyle(element, 'display') != 'none') + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = ''; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = 'none'; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (window.opera) { + element.style.top = 0; + element.style.left = 0; + } + } + }, + + undoPositioned: function(element) { + element = $(element); + if (element._madePositioned) { + element._madePositioned = undefined; + element.style.position = + element.style.top = + element.style.left = + element.style.bottom = + element.style.right = ''; + } + }, + + makeClipping: function(element) { + element = $(element); + if (element._overflow) return; + element._overflow = element.style.overflow; + if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') + element.style.overflow = 'hidden'; + }, + + undoClipping: function(element) { + element = $(element); + if (element._overflow) return; + element.style.overflow = element._overflow; + element._overflow = undefined; + } +}); + +var Toggle = new Object(); +Toggle.display = Element.toggle; + +/*--------------------------------------------------------------------------*/ + +Abstract.Insertion = function(adjacency) { + this.adjacency = adjacency; +} + +Abstract.Insertion.prototype = { + initialize: function(element, content) { + this.element = $(element); + this.content = content.stripScripts(); + + if (this.adjacency && this.element.insertAdjacentHTML) { + try { + this.element.insertAdjacentHTML(this.adjacency, this.content); + } catch (e) { + if (this.element.tagName.toLowerCase() == 'tbody') { + this.insertContent(this.contentFromAnonymousTable()); + } else { + throw e; + } + } + } else { + this.range = this.element.ownerDocument.createRange(); + if (this.initializeRange) this.initializeRange(); + this.insertContent([this.range.createContextualFragment(this.content)]); + } + + setTimeout(function() {content.evalScripts()}, 10); + }, + + contentFromAnonymousTable: function() { + var div = document.createElement('div'); + div.innerHTML = '' + this.content + '
'; + return $A(div.childNodes[0].childNodes[0].childNodes); + } +} + +var Insertion = new Object(); + +Insertion.Before = Class.create(); +Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { + initializeRange: function() { + this.range.setStartBefore(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, this.element); + }).bind(this)); + } +}); + +Insertion.Top = Class.create(); +Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(true); + }, + + insertContent: function(fragments) { + fragments.reverse(false).each((function(fragment) { + this.element.insertBefore(fragment, this.element.firstChild); + }).bind(this)); + } +}); + +Insertion.Bottom = Class.create(); +Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.appendChild(fragment); + }).bind(this)); + } +}); + +Insertion.After = Class.create(); +Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { + initializeRange: function() { + this.range.setStartAfter(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, + this.element.nextSibling); + }).bind(this)); + } +}); + +/*--------------------------------------------------------------------------*/ + +Element.ClassNames = Class.create(); +Element.ClassNames.prototype = { + initialize: function(element) { + this.element = $(element); + }, + + _each: function(iterator) { + this.element.className.split(/\s+/).select(function(name) { + return name.length > 0; + })._each(iterator); + }, + + set: function(className) { + this.element.className = className; + }, + + add: function(classNameToAdd) { + if (this.include(classNameToAdd)) return; + this.set(this.toArray().concat(classNameToAdd).join(' ')); + }, + + remove: function(classNameToRemove) { + if (!this.include(classNameToRemove)) return; + this.set(this.select(function(className) { + return className != classNameToRemove; + }).join(' ')); + }, + + toString: function() { + return this.toArray().join(' '); + } +} + +Object.extend(Element.ClassNames.prototype, Enumerable); +var Field = { + clear: function() { + for (var i = 0; i < arguments.length; i++) + $(arguments[i]).value = ''; + }, + + focus: function(element) { + $(element).focus(); + }, + + present: function() { + for (var i = 0; i < arguments.length; i++) + if ($(arguments[i]).value == '') return false; + return true; + }, + + select: function(element) { + $(element).select(); + }, + + activate: function(element) { + element = $(element); + element.focus(); + if (element.select) + element.select(); + } +} + +/*--------------------------------------------------------------------------*/ + +var Form = { + serialize: function(form) { + var elements = Form.getElements($(form)); + var queryComponents = new Array(); + + for (var i = 0; i < elements.length; i++) { + var queryComponent = Form.Element.serialize(elements[i]); + if (queryComponent) + queryComponents.push(queryComponent); + } + + return queryComponents.join('&'); + }, + + getElements: function(form) { + form = $(form); + var elements = new Array(); + + for (tagName in Form.Element.Serializers) { + var tagElements = form.getElementsByTagName(tagName); + for (var j = 0; j < tagElements.length; j++) + elements.push(tagElements[j]); + } + return elements; + }, + + getInputs: function(form, typeName, name) { + form = $(form); + var inputs = form.getElementsByTagName('input'); + + if (!typeName && !name) + return inputs; + + var matchingInputs = new Array(); + for (var i = 0; i < inputs.length; i++) { + var input = inputs[i]; + if ((typeName && input.type != typeName) || + (name && input.name != name)) + continue; + matchingInputs.push(input); + } + + return matchingInputs; + }, + + disable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.blur(); + element.disabled = 'true'; + } + }, + + enable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.disabled = ''; + } + }, + + findFirstElement: function(form) { + return Form.getElements(form).find(function(element) { + return element.type != 'hidden' && !element.disabled && + ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); + }); + }, + + focusFirstElement: function(form) { + Field.activate(Form.findFirstElement(form)); + }, + + reset: function(form) { + $(form).reset(); + } +} + +Form.Element = { + serialize: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) { + var key = encodeURIComponent(parameter[0]); + if (key.length == 0) return; + + if (parameter[1].constructor != Array) + parameter[1] = [parameter[1]]; + + return parameter[1].map(function(value) { + return key + '=' + encodeURIComponent(value); + }).join('&'); + } + }, + + getValue: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) + return parameter[1]; + } +} + +Form.Element.Serializers = { + input: function(element) { + switch (element.type.toLowerCase()) { + case 'submit': + case 'hidden': + case 'password': + case 'text': + return Form.Element.Serializers.textarea(element); + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element); + } + return false; + }, + + inputSelector: function(element) { + if (element.checked) + return [element.name, element.value]; + }, + + textarea: function(element) { + return [element.name, element.value]; + }, + + select: function(element) { + return Form.Element.Serializers[element.type == 'select-one' ? + 'selectOne' : 'selectMany'](element); + }, + + selectOne: function(element) { + var value = '', opt, index = element.selectedIndex; + if (index >= 0) { + opt = element.options[index]; + value = opt.value; + if (!value && !('value' in opt)) + value = opt.text; + } + return [element.name, value]; + }, + + selectMany: function(element) { + var value = new Array(); + for (var i = 0; i < element.length; i++) { + var opt = element.options[i]; + if (opt.selected) { + var optValue = opt.value; + if (!optValue && !('value' in opt)) + optValue = opt.text; + value.push(optValue); + } + } + return [element.name, value]; + } +} + +/*--------------------------------------------------------------------------*/ + +var $F = Form.Element.getValue; + +/*--------------------------------------------------------------------------*/ + +Abstract.TimedObserver = function() {} +Abstract.TimedObserver.prototype = { + initialize: function(element, frequency, callback) { + this.frequency = frequency; + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + } +} + +Form.Element.Observer = Class.create(); +Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer = Class.create(); +Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); + +/*--------------------------------------------------------------------------*/ + +Abstract.EventObserver = function() {} +Abstract.EventObserver.prototype = { + initialize: function(element, callback) { + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + if (this.element.tagName.toLowerCase() == 'form') + this.registerFormCallbacks(); + else + this.registerCallback(this.element); + }, + + onElementEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + }, + + registerFormCallbacks: function() { + var elements = Form.getElements(this.element); + for (var i = 0; i < elements.length; i++) + this.registerCallback(elements[i]); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + Event.observe(element, 'click', this.onElementEvent.bind(this)); + break; + case 'password': + case 'text': + case 'textarea': + case 'select-one': + case 'select-multiple': + Event.observe(element, 'change', this.onElementEvent.bind(this)); + break; + } + } + } +} + +Form.Element.EventObserver = Class.create(); +Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.EventObserver = Class.create(); +Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); +if (!window.Event) { + var Event = new Object(); +} + +Object.extend(Event, { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + + element: function(event) { + return event.target || event.srcElement; + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointerX: function(event) { + return event.pageX || (event.clientX + + (document.documentElement.scrollLeft || document.body.scrollLeft)); + }, + + pointerY: function(event) { + return event.pageY || (event.clientY + + (document.documentElement.scrollTop || document.body.scrollTop)); + }, + + stop: function(event) { + if (event.preventDefault) { + event.preventDefault(); + event.stopPropagation(); + } else { + event.returnValue = false; + event.cancelBubble = true; + } + }, + + // find the first node with the given tagName, starting from the + // node the event was triggered on; traverses the DOM upwards + findElement: function(event, tagName) { + var element = Event.element(event); + while (element.parentNode && (!element.tagName || + (element.tagName.toUpperCase() != tagName.toUpperCase()))) + element = element.parentNode; + return element; + }, + + observers: false, + + _observeAndCache: function(element, name, observer, useCapture) { + if (!this.observers) this.observers = []; + if (element.addEventListener) { + this.observers.push([element, name, observer, useCapture]); + element.addEventListener(name, observer, useCapture); + } else if (element.attachEvent) { + this.observers.push([element, name, observer, useCapture]); + element.attachEvent('on' + name, observer); + } + }, + + unloadCache: function() { + if (!Event.observers) return; + for (var i = 0; i < Event.observers.length; i++) { + Event.stopObserving.apply(this, Event.observers[i]); + Event.observers[i][0] = null; + } + Event.observers = false; + }, + + observe: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.attachEvent)) + name = 'keydown'; + + this._observeAndCache(element, name, observer, useCapture); + }, + + stopObserving: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.detachEvent)) + name = 'keydown'; + + if (element.removeEventListener) { + element.removeEventListener(name, observer, useCapture); + } else if (element.detachEvent) { + element.detachEvent('on' + name, observer); + } + } +}); + +/* prevent memory leaks in IE */ +Event.observe(window, 'unload', Event.unloadCache, false); +var Position = { + // set to true if needed, warning: firefox performance problems + // NOT neeeded for page scrolling, only if draggable contained in + // scrollable elements + includeScrollOffsets: false, + + // must be called before calling withinIncludingScrolloffset, every time the + // page is scrolled + prepare: function() { + this.deltaX = window.pageXOffset + || document.documentElement.scrollLeft + || document.body.scrollLeft + || 0; + this.deltaY = window.pageYOffset + || document.documentElement.scrollTop + || document.body.scrollTop + || 0; + }, + + realOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return [valueL, valueT]; + }, + + cumulativeOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [valueL, valueT]; + }, + + positionedOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + if (element) { + p = Element.getStyle(element, 'position'); + if (p == 'relative' || p == 'absolute') break; + } + } while (element); + return [valueL, valueT]; + }, + + offsetParent: function(element) { + if (element.offsetParent) return element.offsetParent; + if (element == document.body) return element; + + while ((element = element.parentNode) && element != document.body) + if (Element.getStyle(element, 'position') != 'static') + return element; + + return document.body; + }, + + // caches x/y coordinate pair to use with overlap + within: function(element, x, y) { + if (this.includeScrollOffsets) + return this.withinIncludingScrolloffsets(element, x, y); + this.xcomp = x; + this.ycomp = y; + this.offset = this.cumulativeOffset(element); + + return (y >= this.offset[1] && + y < this.offset[1] + element.offsetHeight && + x >= this.offset[0] && + x < this.offset[0] + element.offsetWidth); + }, + + withinIncludingScrolloffsets: function(element, x, y) { + var offsetcache = this.realOffset(element); + + this.xcomp = x + offsetcache[0] - this.deltaX; + this.ycomp = y + offsetcache[1] - this.deltaY; + this.offset = this.cumulativeOffset(element); + + return (this.ycomp >= this.offset[1] && + this.ycomp < this.offset[1] + element.offsetHeight && + this.xcomp >= this.offset[0] && + this.xcomp < this.offset[0] + element.offsetWidth); + }, + + // within must be called directly before + overlap: function(mode, element) { + if (!mode) return 0; + if (mode == 'vertical') + return ((this.offset[1] + element.offsetHeight) - this.ycomp) / + element.offsetHeight; + if (mode == 'horizontal') + return ((this.offset[0] + element.offsetWidth) - this.xcomp) / + element.offsetWidth; + }, + + clone: function(source, target) { + source = $(source); + target = $(target); + target.style.position = 'absolute'; + var offsets = this.cumulativeOffset(source); + target.style.top = offsets[1] + 'px'; + target.style.left = offsets[0] + 'px'; + target.style.width = source.offsetWidth + 'px'; + target.style.height = source.offsetHeight + 'px'; + }, + + page: function(forElement) { + var valueT = 0, valueL = 0; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent==document.body) + if (Element.getStyle(element,'position')=='absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } while (element = element.parentNode); + + return [valueL, valueT]; + }, + + clone: function(source, target) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || {}) + + // find page position of source + source = $(source); + var p = Position.page(source); + + // find coordinate system to use + target = $(target); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(target,'position') == 'absolute') { + parent = Position.offsetParent(target); + delta = Position.page(parent); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if(options.setWidth) target.style.width = source.offsetWidth + 'px'; + if(options.setHeight) target.style.height = source.offsetHeight + 'px'; + }, + + absolutize: function(element) { + element = $(element); + if (element.style.position == 'absolute') return; + Position.prepare(); + + var offsets = Position.positionedOffset(element); + var top = offsets[1]; + var left = offsets[0]; + var width = element.clientWidth; + var height = element.clientHeight; + + element._originalLeft = left - parseFloat(element.style.left || 0); + element._originalTop = top - parseFloat(element.style.top || 0); + element._originalWidth = element.style.width; + element._originalHeight = element.style.height; + + element.style.position = 'absolute'; + element.style.top = top + 'px';; + element.style.left = left + 'px';; + element.style.width = width + 'px';; + element.style.height = height + 'px';; + }, + + relativize: function(element) { + element = $(element); + if (element.style.position == 'relative') return; + Position.prepare(); + + element.style.position = 'relative'; + var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); + var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); + + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.height = element._originalHeight; + element.style.width = element._originalWidth; + } +} + +// Safari returns margins on body which is incorrect if the child is absolutely +// positioned. For performance reasons, redefine Position.cumulativeOffset for +// KHTML/WebKit only. +if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { + Position.cumulativeOffset = function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + if (element.offsetParent == document.body) + if (Element.getStyle(element, 'position') == 'absolute') break; + + element = element.offsetParent; + } while (element); + + return [valueL, valueT]; + } +} \ No newline at end of file diff --git a/mini-asterisk-gui/cgi-bin/set_network.sh b/mini-asterisk-gui/cgi-bin/set_network.sh new file mode 100644 index 00000000..5f65bf67 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/set_network.sh @@ -0,0 +1,64 @@ +#!/bin/sh +# set_network.sh +# +# CGI to set network parameters of an IP0X. + +cat < + +set_network.sh + + +Please wait a few seconds..... + + + +EOF + +dhcp=`echo "$QUERY_STRING" | grep -oe "dhcp=[^&?]*" | sed -n "s/dhcp=//p"` +ipaddress=`echo "$QUERY_STRING" | grep -oe "ipaddress=[^&?]*" | sed -n "s/ipaddress=//p"` +netmask=`echo "$QUERY_STRING" | grep -oe "netmask=[^&?]*" | sed -n "s/netmask=//p"` +gateway=`echo "$QUERY_STRING" | grep -oe "gateway=[^&?]*" | sed -n "s/gateway=//p"` +dns=`echo "$QUERY_STRING" | grep -oe "dns=[^&?]*" | sed -n "s/dns=//p"` +backdoor=`echo "$QUERY_STRING" | grep -oe "backdoor=[^&?]*" | sed -n "s/backdoor=//p"` + +if [ $dhcp == "yes" ]; then + + # DHCP + + if [ -f /etc/rc.d/S10network-static ]; then + /etc/init.d/network-static disable + /etc/init.d/network-static stop + /etc/init.d/network enable + /etc/init.d/network start + else + # if already running restart service + /etc/init.d/network stop + /etc/init.d/network start + fi +fi + +if [ $dhcp == "no" ]; then + + # Static IP + + if [ -f /etc/rc.d/S10network ]; then + /etc/init.d/network stop + /etc/init.d/network disable + /etc/init.d/network-static enable + fi + + sed -i "s/DHCPD=.*/DHCPD=no/g" /etc/init.d/network-static + sed -i "s/IPADDRESS=.*/IPADDRESS=\"$ipaddress\"/g" /etc/init.d/network-static + sed -i "s/NETMASK=.*/NETMASK=\"$netmask\"/g" /etc/init.d/network-static + sed -i "s/GATEWAY=.*/GATEWAY=\"$gateway\"/g" /etc/init.d/network-static + sed -i "s/DNS=.*/DNS=\"$dns\"/g" /etc/init.d/network-static + /etc/init.d/network-static stop + /etc/init.d/network-static start +fi + +if [ -f /etc/rc.d/S05network-backdoor ]; then + sed -i "s/IPADDRESS=.*/IPADDRESS=\"$backdoor\"/g" /etc/init.d/network-backdoor + /etc/init.d/network-backdoor stop + /etc/init.d/network-backdoor start +fi diff --git a/mini-asterisk-gui/cgi-bin/set_ring.sh b/mini-asterisk-gui/cgi-bin/set_ring.sh new file mode 100644 index 00000000..d9f2bd84 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/set_ring.sh @@ -0,0 +1,51 @@ +#!/bin/sh -x +# set_ring.sh +# David Rowe 4 Jan 2010 +# CGI to set which extensions ring on uncoming calls + +# check we are logged in + +echo $HTTP_COOKIE | grep "loggedin" > /dev/null +if [ $? -eq 1 ]; then + echo "" + echo "" + echo '' + echo "" + echo "" + exit +fi + +# extract extensions to ring and reload extensions.conf + +a=`echo "$QUERY_STRING" | sed -n "s/=on*//pg" | sed -n 's,_,/,pg'` + +# escape & if present +echo "$a" | grep "&" >> /dev/null +if [ $? -eq 0 ]; then + a=`echo $a | sed -n "s/&/\\\\&/pg"` +fi + +sed -i "s_s,1,Dial(.*) ;; mini-asterisk_s,1,Dial($a) ;; mini-asterisk_" /etc/asterisk/extensions.conf +asterisk -rx "dialplan reload" 2>/dev/null 1 > /dev/null + +# bounce us back to Phones screen + +cat < + +Mini Asterisk - Set Ring + + +Please wait a few seconds..... +EOF +#echo $QUERY_STRING "
" +#echo "$QUERY_STRING" | sed -n "s/=on*//pg" | sed -n 's,_,/,pg' +#echo "
" +#echo $a + +cat < + + +EOF + diff --git a/mini-asterisk-gui/cgi-bin/set_voiplines.pl b/mini-asterisk-gui/cgi-bin/set_voiplines.pl new file mode 100644 index 00000000..2cee2e13 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/set_voiplines.pl @@ -0,0 +1,94 @@ +#!/usr/bin/perl +# set_voiplines.pl +# David Rowe 12 Jan 2010 +# +# Replaces fields in sip.conf, outputs new sip.conf contents to stdout + +$user = $ARGV[0]; +$pass = $ARGV[1]; +$host = $ARGV[2]; +$stanza_new = $ARGV[3]; + +# We need to slurp up the mini asterisk provider and spit them +# back out. All must be commented out except for the one that +# is selected. Hopefully non-mini asterisk content of sip.conf +# won't be affected. + +open SIP, "/etc/asterisk/sip.conf"; +$provider = ""; +while () { + + # start of any new stanza switches off parsing. It may get + # switched back on below if it contains mini-asterisk + # keyword. This allows non-mini asterisk SIP stanzas to be + # included in sip.conf + + if (/\[/) { + $stanza = ""; + } + + # look for commented or uncommented mini asterisk provider stanza + + if (/\[(.*)\] .* mini-asterisk/) { + $stanza = $1; + } + + if ($stanza eq "") { + # we are not in an mini-asterisk provider stanza + + if (/;*register => (\S*)@(\S*).*;.*(mini-asterisk.*)/) { + # an mini-asterisk register line + + #print "XX stanza_new='$stanza_new' '$1' '$2' '$3'\n"; + + if ($2 eq $stanza_new) { + print "register => $user\@$stanza_new; $3\n"; + } + else { + print ";register => $1\@$2 ; $3\n"; + } + } + else { + # OK so this is a regular sip.conf line, just echo to stdout + print $_; + } + } + else { + # OK, we are in an mini-asterisk stanza + + # strip off any leading ";" + + $_ =~ s/^\;//; + + if ($stanza eq $stanza_new) { + + # this stanza should be uncommented + + if (/^user=/) { + print "user=$user\n"; + } + if (/^username=/) { + print "username=$user\n"; + } + elsif (/^fromuser=/) { + print "fromuser=$user\n"; + } + elsif (/^secret=/) { + print "secret=$pass\n"; + } + elsif (/^host=/) { + print "host=$host\n"; + } + else { + print $_; + } + } + else { + # comment out unused mini-asterisk stanzas + print ";$_"; + } + } + +} +close SIP; + diff --git a/mini-asterisk-gui/cgi-bin/set_voiplines.sh b/mini-asterisk-gui/cgi-bin/set_voiplines.sh new file mode 100644 index 00000000..3039a260 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/set_voiplines.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# set_voipline.sh +# # David Rowe 12 Jan 2010 +# +# CGI to set voip line parameters in sip.conf. + +# check we are logged in + +echo $HTTP_COOKIE | grep "loggedin" > /dev/null +if [ $? -eq 1 ]; then + echo "" + echo "" + echo '' + echo "" + echo "" + exit +fi + +user=`echo "$QUERY_STRING" | grep -oe "user=[^&?]*" | sed -n "s/user=//p"` +pass=`echo "$QUERY_STRING" | grep -oe "pass=[^&?]*" | sed -n "s/pass=//p"` +host=`echo "$QUERY_STRING" | grep -oe "host=[^&?]*" | sed -n "s/host=//p"` +stanza=`echo "$QUERY_STRING" | grep -oe "stanza=[^&?]*" | sed -n "s/stanza=//p"` + +# create new sip.conf with selected provider uncommented + +echo "set_voiplines.sh" $user $pass $host $stanza >> /tmp/log.txt +./set_voiplines.pl $user $pass $host $stanza > /etc/asterisk/sip.conf.new +mv /etc/asterisk/sip.conf /etc/asterisk/sip.conf.bak +mv /etc/asterisk/sip.conf.new /etc/asterisk/sip.conf + +# get asterisk to load changes + +asterisk -rx "sip reload" 2>/dev/null 1 > /dev/null + +cat < + +set_voiplines.sh + + +Please wait a few seconds..... + + + +EOF + diff --git a/mini-asterisk-gui/cgi-bin/tick.png b/mini-asterisk-gui/cgi-bin/tick.png new file mode 100644 index 00000000..c155dff4 Binary files /dev/null and b/mini-asterisk-gui/cgi-bin/tick.png differ diff --git a/mini-asterisk-gui/cgi-bin/tooltip.css b/mini-asterisk-gui/cgi-bin/tooltip.css new file mode 100644 index 00000000..f426356c --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/tooltip.css @@ -0,0 +1,7 @@ +.tip {font:12px/14px +Arial,Helvetica,sans-serif; border:solid 1px +#666666; width:270px; padding:1px; +position:absolute; z-index:100; +visibility:hidden; color:#333333; top:20px; +left:90px; background-color:#ffffcc; +layer-background-color:#ffffcc;} diff --git a/mini-asterisk-gui/cgi-bin/tooltip.js b/mini-asterisk-gui/cgi-bin/tooltip.js new file mode 100644 index 00000000..26142e8a --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/tooltip.js @@ -0,0 +1,7 @@ +// Extended Tooltip Javascript +// copyright 9th August 2002, 3rd July 2005, 24th August 2008 +// by Stephen Chapman, Felgall Pty Ltd + +// permission is granted to use this javascript provided that the below code is not altered +function pw() {return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth}; function mouseX(evt) {return evt.clientX ? evt.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) : evt.pageX;} function mouseY(evt) {return evt.clientY ? evt.clientY + (document.documentElement.scrollTop || document.body.scrollTop) : evt.pageY} function popUp(evt,oi) {if (document.getElementById) {var wp = pw(); dm = document.getElementById(oi); ds = dm.style; st = ds.visibility; if (dm.offsetWidth) ew = dm.offsetWidth; else if (dm.clip.width) ew = dm.clip.width; if (st == "visible" || st == "show") { ds.visibility = "hidden"; } else {tv = mouseY(evt) + 20; lv = mouseX(evt) - (ew/4); if (lv < 2) lv = 2; else if (lv + ew > wp) lv -= ew/2; lv += 'px';tv += 'px'; ds.left = lv; ds.top = tv; ds.visibility = "visible";}}} + diff --git a/mini-asterisk-gui/cgi-bin/tooltips.html b/mini-asterisk-gui/cgi-bin/tooltips.html new file mode 100644 index 00000000..91137b23 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/tooltips.html @@ -0,0 +1,149 @@ +
+ A tick means your phone system can reach the Internet. You need the Internet for VOIP calls + and software upgrades. + If you have a problem reaching the Internet check your Network settings, in + particular Gateway and DNS.
+ +
+ Emergency backdoor IP. Useful if you get locked out of the main network connection, for + example due to DHCP problems on your network or a configuration mistake. + Write this number down somewhere!
+ +
+ If ticked this phone will ring when some one + calls the phone system from an outside Analog + or VOIP Line. More than one phone can be + ticked. You can answer a call on another + ringing phone by dialling *8 on your phone - + see FAQ for details.
+ +
+ Analog Phone: Normal telephone plugged into a port on your phone system. +
+
+ IP Phone plugged into your network. +
+
+ Analog Phone Line: Analog telephone line plugged into a port on your phone system. +
+
+ VOIP Phone Line: Make and receive phone calls over the Internet. +
+ +
+ Important information about your Phone System.
+ +
+ The address of your Phone System + on your network. Use this address to connect + IP Phones to your Phone System.
+ +
+ List of phones connected to your Phone + System. You can connect Analog or IP Phones + to your system. When IP Phones are + configured correctly, they appear on this + list. If an IP phone is not configured + correctly, it will not appear on this list. + Analog phones require hardware to be + installed in your Phone system.
+ +
+ List of phone lines available. Phone lines + are used to make and receive outside calls. + You can use regular Analog phone lines or + VOIP. VOIP phone lines require an account + with an Internet Telephone Service Provider. + Analog phone lines require hardware to be + installed in your Phone System.
+ +
+ Dial this number to call this phone
+ +
+ Port (socket) on the rear of your Phone System. Plug the phone into this Port.
+ +
+ Port (socket) on the rear of your Phone + System. Plug the phone line into this + Port.
+ +
+ Dial 0 for an Analog outside line. For example to call 5551234 dial 05551234
+ +
+ IP Address of this phone on your network
+ +
+ IP Address of the VOIP Internet Telephone Service Provider
+ +
+ Dial 1 for a VOIP outside line. For example to call 5551234 dial 15551234
+ +
+ Instructions and help on adding a new IP phone
+ +
+ Instructions and help on VOIP Line set up
+ +
+ List of possible IP phones. For a new phone + choose any Available number. Refresh this + page to update
+ +
+ The IP phone is connected to your phone system and ready to use
+ +
+ No IP phone is connected. Either no IP phone + is present, or the IP phone has not been set + up.
+ +
+ A VOIP line allows you to make and receive + phones calls over the Internet. Normally a + VOIP line is provided by an Internet Telephony + Service Provider (ITSP). They will give you + an account, which includes the user and + password details that you can fill in below. + Refresh this page on your browser to see if + your VOIP line is working.
+ +
+ Your Internet Telephony Service Provider. + They will give you an account with a user name + and password.
+ +
+ Your account name with your Internet Telephony Service Provider
+ +
+ The password for your Internet Telephony Service Provider account
+ +
+ The Internet address of your Internet + Telephony Service Provider. This will usually + be filled in automatically.
+ +
+ A tick means you are connected to your + Internet Telephony Service Provider. Refresh + your browser to update.
+ +
+ Press this button to restart your phone + system. This is the same as turning the power + off and back on.
+ +
+ Press this button to the latest version of + Mini Asterisk. An Mini Asterisk upgrade + requires an Internet connection.
+ +
+ Enter the URL of a firmware update script. + This option can be used to install new + firmware on your Phone System. Installing new + firmware requires an Internet + connection.
+ diff --git a/mini-asterisk-gui/cgi-bin/voiplines.js b/mini-asterisk-gui/cgi-bin/voiplines.js new file mode 100644 index 00000000..083838af --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/voiplines.js @@ -0,0 +1,7 @@ +function changeProvider() { + provider = $('provider').value; + $('user').value = users[provider]; + $('pass').value = passwords[provider]; + $('host').value = hosts[provider]; + $('stanza').value = stanzas[provider]; +} diff --git a/mini-asterisk-gui/cgi-bin/voiplines.pl b/mini-asterisk-gui/cgi-bin/voiplines.pl new file mode 100644 index 00000000..d8ccdca8 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/voiplines.pl @@ -0,0 +1,136 @@ +#!/usr/bin/perl +# voiplines.pl +# David Rowe 12 Jan 2010 +# +# Text processing for the voiplines screen + +# slurp up list of possible voip line providers -------------------------------- +# one of these will be currently selected + +open SIP, "/etc/asterisk/sip.conf"; +my $provider = ""; # current provider bring parsed in sip.conf +my @providers=(); # list of all providers +my %stanza = (); # stanza name keyed on provider +my %user = (); # user keyed on provider +my %pass = (); # password keyed on provider +my %host = (); # host name keyed on provider + +while () { + + # start of any stanza switches off parsing. It may get switched + # back on below if it contains mini-asterisk keyword. This allows + # non-mini asterisk SIP devices to be included in sip.conf + + if (/\[/) { + $provider = ""; + } + + # currently disabled mini-asterisk provider + + if (/^;\[(.*)\].* \"(.*)\" mini-asterisk/) { + push (@providers, $2); + $provider = $2; + $stanza{$2} = $1; + #print "'$1' '$2'\n"; + } + + # current mini-asterisk provider + + if (/^\[(.*)\].* \"(.*)\" mini-asterisk/) { + push (@providers, $2); + $provider = $2; + $provider_current = $2; + $stanza{$2} = $1; + #print "'$1' '$2'\n"; + } + + if ($provider ne "") { + #print $_; + + if (/^;*user=(.*)/) { + $user{$provider} = $1; + } + if (/^;*username=(.*)/) { + $user{$provider} = $1; + } + if (/^;*secret=(.*)/) { + $pass{$provider} = $1; + } + if (/^;*host=(.*)/) { + $host{$provider} = $1; + } + } + + $state = $next_state; +} +close SIP; + +# Determine if Asterisk can see current voip line (SIP trunk) +# sipshowpeers.txt needs to be generated before calling this perl +# script + +my %voip = (); # SIP trunks status keyed on sip.conf stanza name/username + # if no entry we can't see SIP trunk + +open SIP, "sipshowregistry.txt"; +while () { + if (/^(.*):.*(Registered)/) { + $voip{$1} = $2; + #print "'$1' '$2' $voip{$1}\n"; + } +} + +close SIP; + +# javascript to handle changing providers + +print "\n"; + +# generate form fields ------------------------------------------- + +$tt_provider = "onMouseOver=\"popUp(event,'voiplines_provider')\" onmouseout=\"popUp(event,'voiplines_provider')\""; +$tt_user = "onMouseOver=\"popUp(event,'voiplines_user')\" onmouseout=\"popUp(event,'voiplines_user')\""; +$tt_pass = "onMouseOver=\"popUp(event,'voiplines_pass')\" onmouseout=\"popUp(event,'voiplines_pass')\""; +$tt_host = "onMouseOver=\"popUp(event,'voiplines_host')\" onmouseout=\"popUp(event,'voiplines_host')\""; +$tt_status = "onMouseOver=\"popUp(event,'voiplines_status')\" onmouseout=\"popUp(event,'voiplines_status')\""; + +print "Provider\n"; +print "\n"; + +print "User:\n"; +print "Password:\n"; +print "Host:\n"; + +#print "\nXXX $provider_current $stanza{$provider_current} $voip{$stanza{$provider_current}}\n"; + +if ($voip{$stanza{$provider_current}} eq "Registered") { + $icon = "\"OK\""; +} +else { + $icon = "\"Not"; +} +print "Voip Line Status:$icon\n"; + +# hidden field to pass stanza with form + +print ""; diff --git a/mini-asterisk-gui/cgi-bin/voiplines.sh b/mini-asterisk-gui/cgi-bin/voiplines.sh new file mode 100644 index 00000000..9067ad49 --- /dev/null +++ b/mini-asterisk-gui/cgi-bin/voiplines.sh @@ -0,0 +1,75 @@ +#!/bin/sh +# voiplines.sh +# David Rowe 12 Jan 2010 +# VOIP Line screen for Mini Asterisk GUI + +# check we are logged in + +echo $HTTP_COOKIE | grep "loggedin" > /dev/null +if [ $? -eq 1 ]; then + echo "" + echo "" + echo '' + echo "" + echo "" + exit +fi + +# See if we have can reach the VOIP Line provider + +asterisk "-rx sip show registry" 2>/dev/null > sipshowregistry.txt + +# Construct the web page ------------------------------- + +cat < + + + + +Mini Asterisk - VOIP Line +EOF + +cat tooltips.html +echo '' +cat banner.html +echo " " +cat menu.html +cat < + +
+ + + + + +EOF + +./voiplines.pl + +cat < + + + + +
 

VOIP Line

 
 
+ + + + + + + + + +EOF + diff --git a/mini-asterisk-gui/etc/asterisk/extensions.conf b/mini-asterisk-gui/etc/asterisk/extensions.conf new file mode 100644 index 00000000..12868e74 --- /dev/null +++ b/mini-asterisk-gui/etc/asterisk/extensions.conf @@ -0,0 +1,65 @@ +; extensions.conf +; David Rowe 4 Jan 2010 +; + +; Designed for Mini Asterisk GUI. However you can hand modify as much +; as you like, as GUI scripts read/and write regular extensions.conf +; without messing with your custom dialplan + + +[general] +static = yes +writeprotect = no +autofallthrough = yes +clearglobalvars = no +priorityjumping = no + +[default] + +; Pre-configured analog extensions, depends on IP0X model and what modules +; are installed. Some of these may map to FXO ports + +exten => 6001,1,Dial(Zap/1) +exten => 6002,1,Dial(Zap/2) +exten => 6003,1,Dial(Zap/3) +exten => 6004,1,Dial(Zap/4) +exten => 6005,1,Dial(Zap/5) +exten => 6006,1,Dial(Zap/6) +exten => 6007,1,Dial(Zap/7) +exten => 6008,1,Dial(Zap/8) + +; Pre-configured SIP-phone extensions. Primary use case is multiple SIP +; extensions and FXO analog Ports + +exten => 6011,1,Dial(SIP/6011) +exten => 6012,1,Dial(SIP/6012) +exten => 6013,1,Dial(SIP/6013) +exten => 6014,1,Dial(SIP/6014) +exten => 6015,1,Dial(SIP/6015) +exten => 6016,1,Dial(SIP/6016) +exten => 6017,1,Dial(SIP/6017) +exten => 6018,1,Dial(SIP/6018) +exten => 6019,1,Dial(SIP/6019) +exten => 6020,1,Dial(SIP/6020) +exten => 6021,1,Dial(SIP/6021) +exten => 6022,1,Dial(SIP/6022) +exten => 6023,1,Dial(SIP/6023) +exten => 6024,1,Dial(SIP/6024) +exten => 6025,1,Dial(SIP/6025) +exten => 6026,1,Dial(SIP/6026) +exten => 6027,1,Dial(SIP/6027) +exten => 6028,1,Dial(SIP/6028) +exten => 6029,1,Dial(SIP/6029) +exten => 6030,1,Dial(SIP/6030) + +;; Pre-configured mini-asterisk outgoing Analog group + +exten => _0.,1,Dial(Zap/g1/${EXTEN:1}) + +;; Pre-configured mini-asterisk outgoing VOIP line + +exten => _1.,1,Dial(SIP/voip/${EXTEN:1}) + +;; Pre-configured incoming calls + +exten => s,1,Dial(SIP/6011) ;; mini-asterisk - don't remove this comment diff --git a/mini-asterisk-gui/etc/asterisk/sip.conf b/mini-asterisk-gui/etc/asterisk/sip.conf new file mode 100644 index 00000000..ee3e1046 --- /dev/null +++ b/mini-asterisk-gui/etc/asterisk/sip.conf @@ -0,0 +1,559 @@ +; +; SIP Configuration example for Asterisk +; +; Syntax for specifying a SIP device in extensions.conf is +; SIP/devicename where devicename is defined in a section below. +; +; You may also use +; SIP/username@domain to call any SIP user on the Internet +; (Don't forget to enable DNS SRV records if you want to use this) +; +; If you define a SIP proxy as a peer below, you may call +; SIP/proxyhostname/user or SIP/user@proxyhostname +; where the proxyhostname is defined in a section below +; +; Useful CLI commands to check peers/users: +; sip show peers Show all SIP peers (including friends) +; sip show users Show all SIP users (including friends) +; sip show registry Show status of hosts we register with +; +; sip debug Show all SIP messages +; +; reload chan_sip.so Reload configuration file +; Active SIP peers will not be reconfigured +; + +[general] +context=default ; Default context for incoming calls +;allowguest=no ; Allow or reject guest calls (default is yes, this can also be set to 'osp' + ; if asterisk was compiled with OSP support. +;realm=mydomain.tld ; Realm for digest authentication + ; defaults to "asterisk" + ; Realms MUST be globally unique according to RFC 3261 + ; Set this to your host name or domain name +bindport=5060 ; UDP Port to bind to (SIP standard port is 5060) +bindaddr=0.0.0.0 ; IP address to bind to (0.0.0.0 binds to all) +srvlookup=yes ; Enable DNS SRV lookups on outbound calls + ; Note: Asterisk only uses the first host + ; in SRV records + ; Disabling DNS SRV lookups disables the + ; ability to place SIP calls based on domain + ; names to some other SIP users on the Internet + +;domain=mydomain.tld ; Set default domain for this host + ; If configured, Asterisk will only allow + ; INVITE and REFER to non-local domains + ; Use "sip show domains" to list local domains +;domain=mydomain.tld,mydomain-incoming + ; Add domain and configure incoming context + ; for external calls to this domain +;domain=1.2.3.4 ; Add IP address as local domain + ; You can have several "domain" settings +;allowexternalinvites=no ; Disable INVITE and REFER to non-local domains + ; Default is yes +;autodomain=yes ; Turn this on to have Asterisk add local host + ; name and local IP to domain list. +;pedantic=yes ; Enable slow, pedantic checking for Pingtel + ; and multiline formatted headers for strict + ; SIP compatibility (defaults to "no") +;tos=184 ; Set IP QoS to either a keyword or numeric val +;tos=lowdelay ; lowdelay,throughput,reliability,mincost,none +;maxexpiry=3600 ; Max length of incoming registration we allow +;defaultexpiry=120 ; Default length of incoming/outoing registration +;notifymimetype=text/plain ; Allow overriding of mime type in MWI NOTIFY +;checkmwi=10 ; Default time between mailbox checks for peers +;vmexten=voicemail ; dialplan extension to reach mailbox sets the + ; Message-Account in the MWI notify message + ; defaults to "asterisk" +;videosupport=yes ; Turn on support for SIP video +;recordhistory=yes ; Record SIP history by default + ; (see sip history / sip no history) + +;disallow=all ; First disallow all codecs +;allow=ulaw ; Allow codecs in order of preference +;allow=ilbc ; +;musicclass=default ; Sets the default music on hold class for all SIP calls + ; This may also be set for individual users/peers +;language=en ; Default language setting for all users/peers + ; This may also be set for individual users/peers +;relaxdtmf=yes ; Relax dtmf handling +;rtptimeout=60 ; Terminate call if 60 seconds of no RTP activity + ; when we're not on hold +;rtpholdtimeout=300 ; Terminate call if 300 seconds of no RTP activity + ; when we're on hold (must be > rtptimeout) +;trustrpid = no ; If Remote-Party-ID should be trusted +;sendrpid = yes ; If Remote-Party-ID should be sent +;progressinband=never ; If we should generate in-band ringing always + ; use 'never' to never use in-band signalling, even in cases + ; where some buggy devices might not render it +;useragent=Asterisk PBX ; Allows you to change the user agent string +;promiscredir = no ; If yes, allows 302 or REDIR to non-local SIP address + ; Note that promiscredir when redirects are made to the + ; local system will cause loops since SIP is incapable + ; of performing a "hairpin" call. +;usereqphone = no ; If yes, ";user=phone" is added to uri that contains + ; a valid phone number +;dtmfmode = rfc2833 ; Set default dtmfmode for sending DTMF. Default: rfc2833 + ; Other options: + ; info : SIP INFO messages + ; inband : Inband audio (requires 64 kbit codec -alaw, ulaw) + ; auto : Use rfc2833 if offered, inband otherwise + +;compactheaders = yes ; send compact sip headers. +;sipdebug = yes ; Turn on SIP debugging by default, from + ; the moment the channel loads this configuration +;subscribecontext = default ; Set a specific context for SUBSCRIBE requests + ; Useful to limit subscriptions to local extensions + ; Settable per peer/user also +;notifyringing = yes ; Notify subscriptions on RINGING state + +; +; If regcontext is specified, Asterisk will dynamically create and destroy a +; NoOp priority 1 extension for a given peer who registers or unregisters with +; us. The actual extension is the 'regexten' parameter of the registering +; peer or its name if 'regexten' is not provided. More than one regexten may +; be supplied if they are separated by '&'. Patterns may be used in regexten. +; +;regcontext=sipregistrations +; +; Asterisk can register as a SIP user agent to a SIP proxy (provider) +; Format for the register statement is: +; register => user[:secret[:authuser]]@host[:port][/extension] +; +; If no extension is given, the 's' extension is used. The extension needs to +; be defined in extensions.conf to be able to accept calls from this SIP proxy +; (provider). +; +; host is either a host name defined in DNS or the name of a section defined +; below. +; +; Examples: +; +;register => 1234:password@mysipprovider.com +; +; This will pass incoming calls to the 's' extension +; +; +;register => 2345:password@sip_proxy/1234 +; +; Register 2345 at sip provider 'sip_proxy'. Calls from this provider +; connect to local extension 1234 in extensions.conf, default context, +; unless you configure a [sip_proxy] section below, and configure a +; context. +; Tip 1: Avoid assigning hostname to a sip.conf section like [provider.com] +; Tip 2: Use separate type=peer and type=user sections for SIP providers +; (instead of type=friend) if you have calls in both directions + +;registertimeout=20 ; retry registration calls every 20 seconds (default) +;registerattempts=10 ; Number of registration attempts before we give up + ; 0 = continue forever, hammering the other server until it + ; accepts the registration + ; Default is 0 tries, continue forever +;callevents=no ; generate manager events when sip ua performs events (e.g. hold) + +; register mini-asterisk voip line providers here + +register => user@generic ; mini-asterisk - do not change this comment +;register => user@oeg ; mini-asterisk - do not change this comment + +;----------------------------------------- NAT SUPPORT ------------------------ +; The externip, externhost and localnet settings are used if you use Asterisk +; behind a NAT device to communicate with services on the outside. + +;externip = 200.201.202.203 ; Address that we're going to put in outbound SIP messages + ; if we're behind a NAT + + ; The externip and localnet is used + ; when registering and communicating with other proxies + ; that we're registered with +;externhost=foo.dyndns.net ; Alternatively you can specify an + ; external host, and Asterisk will + ; perform DNS queries periodically. Not + ; recommended for production + ; environments! Use externip instead +;externrefresh=10 ; How often to refresh externhost if + ; used + ; You may add multiple local networks. A reasonable set of defaults + ; are: +;localnet=192.168.0.0/255.255.0.0; All RFC 1918 addresses are local networks +;localnet=10.0.0.0/255.0.0.0 ; Also RFC1918 +;localnet=172.16.0.0/12 ; Another RFC1918 with CIDR notation +;localnet=169.254.0.0/255.255.0.0 ;Zero conf local network + +; The nat= setting is used when Asterisk is on a public IP, communicating with +; devices hidden behind a NAT device (broadband router). If you have one-way +; audio problems, you usually have problems with your NAT configuration or your +; firewall's support of SIP+RTP ports. You configure Asterisk choice of RTP +; ports for incoming audio in rtp.conf +; +;nat=no ; Global NAT settings (Affects all peers and users) + ; yes = Always ignore info and assume NAT + ; no = Use NAT mode only according to RFC3581 + ; never = Never attempt NAT mode or RFC3581 support + ; route = Assume NAT, don't send rport + ; (work around more UNIDEN bugs) + +;rtcachefriends=yes ; Cache realtime friends by adding them to the internal list + ; just like friends added from the config file only on a + ; as-needed basis? (yes|no) + +;rtupdate=yes ; Send registry updates to database using realtime? (yes|no) + ; If set to yes, when a SIP UA registers successfully, the ip address, + ; the origination port, the registration period, and the username of + ; the UA will be set to database via realtime. If not present, defaults to 'yes'. + +;rtautoclear=yes ; Auto-Expire friends created on the fly on the same schedule + ; as if it had just registered? (yes|no|) + ; If set to yes, when the registration expires, the friend will vanish from + ; the configuration until requested again. If set to an integer, + ; friends expire within this number of seconds instead of the + ; registration interval. + +;ignoreregexpire=yes ; Enabling this setting has two functions: + ; + ; For non-realtime peers, when their registration expires, the information + ; will _not_ be removed from memory or the Asterisk database; if you attempt + ; to place a call to the peer, the existing information will be used in spite + ; of it having expired + ; + ; For realtime peers, when the peer is retrieved from realtime storage, + ; the registration information will be used regardless of whether + ; it has expired or not; if it expires while the realtime peer is still in + ; memory (due to caching or other reasons), the information will not be + ; removed from realtime storage + +; Incoming INVITE and REFER messages can be matched against a list of 'allowed' +; domains, each of which can direct the call to a specific context if desired. +; By default, all domains are accepted and sent to the default context or the +; context associated with the user/peer placing the call. +; Domains can be specified using: +; domain=[,] +; Examples: +; domain=myasterisk.dom +; domain=customer.com,customer-context +; +; In addition, all the 'default' domains associated with a server should be +; added if incoming request filtering is desired. +; autodomain=yes +; +; To disallow requests for domains not serviced by this server: +; allowexternaldomains=no + +; fromdomain=mydomain.tld ; When making outbound SIP INVITEs to + ; non-peers, use your primary domain "identity" + ; for From: headers instead of just your IP + ; address. This is to be polite and + ; it may be a mandatory requirement for some + ; destinations which do not have a prior + ; account relationship with your server. + +[authentication] +; Global credentials for outbound calls, i.e. when a proxy challenges your +; Asterisk server for authentication. These credentials override +; any credentials in peer/register definition if realm is matched. +; +; This way, Asterisk can authenticate for outbound calls to other +; realms. We match realm on the proxy challenge and pick an set of +; credentials from this list +; Syntax: +; auth = :@ +; auth = #@ +; Example: +;auth=mark:topsecret@digium.com +; +; You may also add auth= statements to [peer] definitions +; Peer auth= override all other authentication settings if we match on realm + +;------------------------------------------------------------------------------ +; Users and peers have different settings available. Friends have all settings, +; since a friend is both a peer and a user +; +; User config options: Peer configuration: +; -------------------- ------------------- +; context context +; permit permit +; deny deny +; secret secret +; md5secret md5secret +; dtmfmode dtmfmode +; canreinvite canreinvite +; nat nat +; callgroup callgroup +; pickupgroup pickupgroup +; language language +; allow allow +; disallow disallow +; insecure insecure +; trustrpid trustrpid +; progressinband progressinband +; promiscredir promiscredir +; useclientcode useclientcode +; accountcode accountcode +; setvar setvar +; callerid callerid +; amaflags amaflags +; call-limit call-limit +; restrictcid restrictcid +; subscribecontext subscribecontext +; videosupport videosupport +; mailbox +; username +; template +; fromdomain +; regexten +; fromuser +; host +; port +; qualify +; defaultip +; rtptimeout +; rtpholdtimeout +; sendrpid + +;[sip_proxy] +; For incoming calls only. Example: FWD (Free World Dialup) +; We match on IP address of the proxy for incoming calls +; since we can not match on username (caller id) +;type=peer +;context=from-fwd +;host=fwd.pulver.com + +;[sip_proxy-out] +;type=peer ; we only want to call out, not be called +;secret=guessit +;username=yourusername ; Authentication user for outbound proxies +;fromuser=yourusername ; Many SIP providers require this! +;fromdomain=provider.sip.domain +;host=box.provider.com +;usereqphone=yes ; This provider requires ";user=phone" on URI +;call-limit=5 ; permit only 5 simultaneous outgoing calls to this peer + +;------------------------------------------------------------------------------ +; Definitions of locally connected SIP phones +; +; type = user a device that authenticates to us by "from" field to place calls +; type = peer a device we place calls to or that calls us and we match by host +; type = friend two configurations (peer+user) in one +; +; For local phones, type=friend works most of the time +; +; If you have one-way audio, you propably have NAT problems. +; If Asterisk is on a public IP, and the phone is inside of a NAT device +; you will need to configure nat option for those phones. +; Also, turn on qualify=yes to keep the nat session open + +;[grandstream1] +;type=friend +;context=from-sip ; Where to start in the dialplan when this phone calls +;callerid=John Doe <1234> ; Full caller ID, to override the phones config +;host=192.168.0.23 ; we have a static but private IP address + ; No registration allowed +;nat=no ; there is not NAT between phone and Asterisk +;canreinvite=yes ; allow RTP voice traffic to bypass Asterisk +;dtmfmode=info ; either RFC2833 or INFO for the BudgeTone +;call-limit=1 ; permit only 1 outgoing call and 1 incoming call at a time + ; from the phone to asterisk + ; (1 for the explicit peer, 1 for the explicit user, + ; remember that a friend equals 1 peer and 1 user in + ; memory) +;mailbox=1234@default ; mailbox 1234 in voicemail context "default" +;disallow=all ; need to disallow=all before we can use allow= +;allow=ulaw ; Note: In user sections the order of codecs + ; listed with allow= does NOT matter! +;allow=alaw +;allow=g723.1 ; Asterisk only supports g723.1 pass-thru! +;allow=g729 ; Pass-thru only unless g729 license obtained +;astdb=chan2ext/SIP/grandstream1=1234 ; ensures an astDB entry exists + + +;[xlite1] +; Turn off silence suppression in X-Lite ("Transmit Silence"=YES)! +; Note that Xlite sends NAT keep-alive packets, so qualify=yes is not needed +;type=friend +;regexten=1234 ; When they register, create extension 1234 +;callerid="Jane Smith" <5678> +;host=dynamic ; This device needs to register +;nat=yes ; X-Lite is behind a NAT router +;canreinvite=no ; Typically set to NO if behind NAT +;disallow=all +;allow=gsm ; GSM consumes far less bandwidth than ulaw +;allow=ulaw +;allow=alaw +;mailbox=1234@default,1233@default ; Subscribe to status of multiple mailboxes + + +;[snom] +;type=friend ; Friends place calls and receive calls +;context=from-sip ; Context for incoming calls from this user +;secret=blah +;subscribecontext=localextensions ; Only allow SUBSCRIBE for local extensions +;language=de ; Use German prompts for this user +;host=dynamic ; This peer register with us +;dtmfmode=inband ; Choices are inband, rfc2833, or info +;defaultip=192.168.0.59 ; IP used until peer registers +;mailbox=1234@context,2345 ; Mailbox(-es) for message waiting indicator +;vmexten=voicemail ; dialplan extension to reach mailbox + ; sets the Message-Account in the MWI notify message + ; defaults to global vmexten which defaults to "asterisk" +;restrictcid=yes ; To have the callerid restriced -> sent as ANI +;disallow=all +;allow=ulaw ; dtmfmode=inband only works with ulaw or alaw! + + +;[polycom] +;type=friend ; Friends place calls and receive calls +;context=from-sip ; Context for incoming calls from this user +;secret=blahpoly +;host=dynamic ; This peer register with us +;dtmfmode=rfc2833 ; Choices are inband, rfc2833, or info +;username=polly ; Username to use in INVITE until peer registers + ; Normally you do NOT need to set this parameter +;disallow=all +;allow=ulaw ; dtmfmode=inband only works with ulaw or alaw! +;progressinband=no ; Polycom phones don't work properly with "never" + + +;[pingtel] +;type=friend +;secret=blah +;host=dynamic +;insecure=port ; Allow matching of peer by IP address without matching port number +;insecure=invite ; Do not require authentication of incoming INVITEs +;insecure=port,invite ; (both) +;qualify=1000 ; Consider it down if it's 1 second to reply + ; Helps with NAT session + ; qualify=yes uses default value +;callgroup=1,3-4 ; We are in caller groups 1,3,4 +;pickupgroup=1,3-5 ; We can do call pick-p for call group 1,3,4,5 +;defaultip=192.168.0.60 ; IP address to use if peer has not registred + +;[cisco1] +;type=friend +;secret=blah +;qualify=200 ; Qualify peer is no more than 200ms away +;nat=yes ; This phone may be natted + ; Send SIP and RTP to the IP address that packet is + ; received from instead of trusting SIP headers +;host=dynamic ; This device registers with us +;canreinvite=no ; Asterisk by default tries to redirect the + ; RTP media stream (audio) to go directly from + ; the caller to the callee. Some devices do not + ; support this (especially if one of them is + ; behind a NAT). +;defaultip=192.168.0.4 ; IP address to use until registration +;username=goran ; Username to use when calling this device before registration + ; Normally you do NOT need to set this parameter +;setvar=CUSTID=5678 ; Channel variable to be set for all calls from this device + +; Pre-configured SIP extensions + +[6011] +type=friend +context=default +host=dynamic +secret=6011 +canreinvite=no +callerid=6011 +disallow=all +allow=ulaw,g729 +qualify=yes + +[6012] +type=friend +context=default +host=dynamic +secret=6012 +canreinvite=no +callerid=6012 +disallow=all +allow=ulaw,g729 + +[6013] +type=friend +context=default +host=dynamic +secret=6013 +canreinvite=no +callerid=6013 +disallow=all +allow=ulaw,g729 + +[6014] +type=friend +context=default +host=dynamic +secret=6014 +canreinvite=no +callerid=6014 +disallow=all +allow=ulaw,g729 + +[6015] +type=friend +context=default +host=dynamic +secret=6015 +canreinvite=no +callerid=6015 +disallow=all +allow=ulaw,g729 + +[6016] +type=friend +context=default +host=dynamic +secret=6016 +canreinvite=no +callerid=6016 +disallow=all +allow=ulaw,g729 + +[6017] +type=friend +context=default +host=dynamic +secret=6017 +canreinvite=no +callerid=6017 +disallow=all +allow=ulaw,g729 + +[6018] +type=friend +context=default +host=dynamic +secret=6018 +canreinvite=no +callerid=6018 +disallow=all +allow=ulaw,g729 + +; Pre-configured mini-asterisk SIP trunks + +[generic] ; "Generic" mini-asterisk do not remove this comment +type=friend +context=default +username=user +secret=password +host=192.168.1.28 +canreinvite=no +disallow=all +allow=ulaw,g729 +qualify=yes + +;[oeg] ; "OEG" mini-asterisk do not remove this comment +;host=voip.oeg.com.au +;secret=pass +;username=your user number +;fromdomain=voip.oeg.com.au +;fromuser=your user number +;insecure=port,invite +;type=friend +;disallow=all +;allow=g729,ulaw +;dtmfmod=rfc2833 +;qualify=yes +;canreinvite=no +;nat=yes +;context=default + diff --git a/mini-asterisk-gui/update_revision.sh b/mini-asterisk-gui/update_revision.sh new file mode 100755 index 00000000..cd8e5055 --- /dev/null +++ b/mini-asterisk-gui/update_revision.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# update_revision.sh +# +# Sets correct Revision number in the about screen. Good idea to +# run this before installing + +ver=`svn info | grep Revision` +sed -i "s/Revision: [0-9]*/$ver/" cgi-bin/about.sh